PDA

View Full Version : StringField setUnderline()



Valarian
October 2nd, 2011, 16:37
I'm trying to use the setUnderline(boolean) method to underline the skill names for The One Ring. This is working fine for the common skills, where I'm using a StringCOntrol with static text. However, it doesn't seem to work with a StringField to underline the value - which I'm using for weapon skills. Is the setUnderline method meant to work with StringField objects, or does it just work with static text?

Examples:


function onValueChanged()
window.awelabel.setUnderline(getState())
end

Above is the call to the setUnderline of the static stringcontrol from the checkbox.



function onInit()
setUnderline(window.awefavour.getState())
end

This is the reciprocal code for the skill label stringcontrol to set the underline when the tab is opened.

The weapon list item code is similar, but in an item windowclass for the weapon list. The name is also a stringfield rather than a stringcontrol.


function onValueChanged()
window.name.setUnderline(getState())
print("in OnValueChanged")
end

Again, I'm trying to set the underline on if the indicator is set. It's definitely going in to the code as I'm getting the debug comments.



function onInit()
setUnderline(window.weaponfavour.getState())
print("in OnInit")
end

And the reciprocal code in the name stringfield

Moon Wizard
October 3rd, 2011, 00:07
The function should be identical for both stringcontrol and stringfield, based on the code. Stringfield is actually derived from stringcontrol.

You might want to set some print statements for the getState() result to see if the return value is not what you expect.

Also, you might want to check out the Debug extension on the Downloads page. Once you turn on for a ruleset, it allows you to use Debug.chat and Debug.console to pass a list of variables to the chat window or console log, respectively.

Regards,
JPG

Valarian
October 3rd, 2011, 12:36
Thanks Moon Wizard, I'll give this a go tonight

Valarian
October 3rd, 2011, 18:42
Looks like the cross-referencing isn't working.
The onInit in the name stringfield doesn't recognise the one weaponfavour checkbox value set. All three weapons I have in the list are coming back as false.
The onValueChanged looks right in terms of the getState in the weaponfavour checkbox, but it's not setting the underline for the name stringfield.




Script Notice: in OnInit:
Script Notice: false
Script Notice: in OnInit:
Script Notice: false
Script Notice: in OnInit:
Script Notice: false
Script Notice: in OnValueChanged:
Script Notice: false
Script Notice: in OnValueChanged:
Script Notice: true
Script Notice: in OnValueChanged:
Script Notice: false
Script Notice: in OnValueChanged:
Script Notice: true


Now trying the debug extension to see if that sheds any light.

Valarian
October 3rd, 2011, 19:39
It's not making any more sense, even with Debug.

I've added these lines to the code:


Debug.console(window)
Debug.console(window.name)
Debug.console(window.weaponfavour)


Which produces this:



Runtime Notice: Reloading ruleset
Script Notice: in OnInit:
Script Notice: false
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,0,0,0 }
Script Notice: WINDOWCONTROL = { nil }
Script Notice: in OnInit:
Script Notice: false
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00002, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Short Sword, x,y,w,h = 0,0,0,0 }
Script Notice: WINDOWCONTROL = { nil }
Script Notice: in OnInit:
Script Notice: false
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00003, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Dagger, x,y,w,h = 0,0,0,0 }
Script Notice: WINDOWCONTROL = { nil }
Script Notice: in OnValueChanged:
Script Notice: false
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 406,295,467,35 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,10,110,15 }
Script Notice: WINDOWCONTROL = { nil }
Script Notice: in OnValueChanged:
Script Notice: true
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 406,295,467,35 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,10,110,15 }
Script Notice: WINDOWCONTROL = { nil }


It looks as though the checkbox is not being recognised. The value exists in the db.xml and the tick is working on screen.

EDIT: Looks like the nil value is a red-herring. Tried comparing to the common skills (which work) and I get nil for the checkbox there too.

Ikael
October 3rd, 2011, 20:01
Is the problem that your stringfield's onInit() function is not recognizing checkbox's value and rather always returns false? If this is the case, I recall facing similar issue and the problem was that checkbox is custom made, with own onInit function that actually initializes and binds it to datasource. Stringfield and stringcontrol seemed to behave differently when invoking onInit, like they would be called in different stages and that messed up the whole thing. Could you try out invoking checkboxes onInit at stringfield's onInit function?

Valarian
October 3rd, 2011, 20:18
I've now got it working with the correct Debug output. Possibly to do with initialisation order. Still no underlines though.

Now have, in the checkbox script area:


function onValueChanged()
window.name.setUnderline(getState())
print("in OnValueChanged:")
Debug.console(window)
Debug.console(window.name)
Debug.console(getState())
end

function onInit()
super.onInit()
window.name.setUnderline(getState())
print("in OnInit: ")
Debug.console(window)
Debug.console(window.name)
Debug.console(getState())
end


This produces:


Script Notice: in OnInit:
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,0,0,0 }
Script Notice: bTRUE
Script Notice: in OnInit:
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00002, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Short Sword, x,y,w,h = 0,0,0,0 }
Script Notice: bFALSE
Script Notice: in OnInit:
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00003, x,y,w,h = 0,0,0,0 }
Script Notice: STRINGCONTROL = { value = Dagger, x,y,w,h = 0,0,0,0 }
Script Notice: bFALSE
Script Notice: in OnValueChanged:
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 406,295,467,35 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,10,110,15 }
Script Notice: bFALSE
Script Notice: in OnValueChanged:
Script Notice: WINDOWINSTANCE = { class = charsheet_weaponlistitem, node = charsheet.id-00001.weaponlist.id-00001, x,y,w,h = 406,295,467,35 }
Script Notice: STRINGCONTROL = { value = Bow, x,y,w,h = 0,10,110,15 }
Script Notice: bTRUE


So, now all looks good in terms of output, but no underlines. Losing hair tonight. Something to do with the x,y,w,h coordinates I think, but what I have no idea. Might leave it for tonight.

Valarian
October 5th, 2011, 18:43
Still haven't got the underline to work properly, even though the Debug output looks correct.

I've tried putting a setUnderline script in the stringfield, to call the same method in the superclass. This doesn't seem to get called at all.


function setUnderline(state)
super.setUnderline(state)
print("in setUnderline")
Debug.console(state)
end


I've also tried placing an onInit function within the name stringfield. This should set the underline on for everything, no checking of conditions. The rest of the script code was disabled so that just this would run.


function onInit()
print("in OnInit for name")
setUnderline(true)
end


I'm coming to the conclusion that the setUnderline won't work at all for stringfield.

Moon Wizard
October 5th, 2011, 23:39
On the skills page in the 3.5E and 4E ruleset character sheets, the rulesets use a textline frame to denote underlining. Then the frame is set or cleared depending on whether the skill name is editable. (i.e. custom)

Check out charsheet/scripts/charsheet_skilllistitem.lua in the 3.5E ruleset.

I'll add a note to my to do list to check out setUnderline.

Thanks,
JPG

Valarian
October 6th, 2011, 04:47
Thanks, it's looking at the moment as if setUnderline is working only for static text stringcontrols. The setFrame won't work for me as there's no way to turn it off again.

The only way I can think of at the moment is a secondary invisible stringcontrol which has a frame and takes its value from the stringfield. Then display the stringcontrol instead of the stringfield if the favoured checkbox is ticked.

joshuha
October 6th, 2011, 18:10
I am suprised there is no way to remove a frame once set. I tried setFrame with nill,"", and even a framedef called none that was 0,0,0,0 and still nothing.

The only thing I can think of (which would be a pain) is that on onLoseFocus or something check if the getValue() is empty and then store the control coordinates and name, destroy() it and do a window.createControl to create it again. That seems excessive though.

Valarian
October 6th, 2011, 18:21
I've currently got it with a second, invisible, stringcontrol in the same place. I then hide the stringfield and display the stringcontrol when the weapon skill is favoured. Not as nice on the display and the drawback is you have to untick the favoured box before editing the weapon skill name.

Zeus
October 6th, 2011, 19:01
Not sure about removing a frame but I believe you should be able to spoof a blank frame by creating a 128x128px transparent image and assigning it to a frame definition. Then switch the frame to the transparent image using setFrame().

joshuha
October 6th, 2011, 20:09
For whatever reason, setFrame doesn't seem to do anything for me past the first instance of setting the frame. Whether by trying another already defined frame or trying Dr Z's method of a pure alpha image (didn't make the other one go away).

Moon Wizard
October 6th, 2011, 20:12
I'm using the setFrame calls extensively in the 3.5E and 4E rulesets to set/clear frames.

setFrame("rowshade");
setFrame(nil);

Regards,
JPG

joshuha
October 6th, 2011, 20:19
I'm using the setFrame calls extensively in the 3.5E and 4E rulesets to set/clear frames.

setFrame("rowshade");
setFrame(nil);

Regards,
JPG

On my end its not doing anything.

Stringfield script:


function onValueChanged()
if getValue() ~= nil or getValue() ~= "" then
setFrame("textline")
end
end

function onLoseFocus()
setFrame(nil)
Debug.chat("fired")
end


Its printing it fired but textline frame remains. Does it only work at a windowinstance level and not windowcontrol?

Zeus
October 6th, 2011, 20:53
I'm using the setFrame calls extensively in the 3.5E and 4E rulesets to set/clear frames.

setFrame("rowshade");
setFrame(nil);

Regards,
JPG

I maybe wrong here moon but those look like references to windowlist entry instances where shading of alternative row entries is applied using onListRearranged() etc.

I believe Joshuha's issue is specific to stringcontrol/fields and setFrame() not working correctly.

Here's the code:

<stringfield name="test">
<bounds>20,100,100,20</bounds>
<script>
function onValueChanged()
if getValue() ~= nil or getValue() ~= "" then
setFrame("textline")
end
end

function onLoseFocus()
setFrame(nil)
Debug.chat("fired")
end
</script>
</stringfield>

joshuha
October 6th, 2011, 21:19
Hmm Dr. Z pointed out to me on the FG chat some contention might be going on with onLoseFocus() which I was just using to test another point in code to reset it. Changing that to onDoubleClick() instead for testing works out fine. So it appears onValueChanged() is called as you enter the control and type stuff (I see the textline frame added) and then onLoseFocus is called as you click away but another call is made to onValueChanged as a final processor of some sort.

Anyways using this code should work Valarian:


<stringfield name="test">
<bounds>20,100,100,20</bounds>
<script>
function onValueChanged()
Debug.chat(string.len(getValue()))
if string.len(getValue()) ~= 0 then
setFrame("textline")
else
setFrame(nil)
Debug.chat("fired")
end
end

</script>
</stringfield>


Additionally, Dr Z suggested another method would be to change the fonts using similar logic above to something that is underlined.

Valarian
October 6th, 2011, 21:27
Thanks, but I have workaround for the moment. That is using the dummy control mentioned earlier.

The ideal is to use the setUnderline as I've got for the skills. The underline only places the line under the text, rather than the whole control.

joshuha
October 6th, 2011, 22:12
I know you have a workaround but I always like cleaner code :). You could try Dr. Z's suggestion of coming up with an underlined font and switch the setFrame to setFont. The other option would be to modify the control to the text size and thus the frame follows. This wouldn't work if you use anchoring though.



<stringfield name="test">
<bounds>20,100,100,20</bounds>
<script>
function onValueChanged()
if string.len(getValue()) ~= 0 then
x,y = getPosition()
w,h = getSize()
setStaticBounds(x,y,string.len(getValue())*5.5,h)
setFrame("textline")
else
setFrame(nil)
end
end
</script>
</stringfield>


A fixed width font works best but you could just play around with the multiplier to see if it fits the text.

Moon Wizard
October 18th, 2011, 19:44
I just tested the setUnderline function on my machine, and I was able to get it working on a standard stringfield control. I did a setUnderline(true) in onClickDown, and setUnderline(false) in onClickRelease.

Regards,
JPG