View Full Version : Problem designing combobox control
GrimmSpector
February 24th, 2016, 06:04
Working on a combobox, I've modified the basic comboboxc to be a downward opening combobox, but I'm having a couple issues, with the code below, it seems the width is 0; meanwhile if I give it an explicit anchored "to" tag, then it appears at whatever I set it's width leaf to. I think height is working ok, but I'm unsure. I seem to have to use the relative method of anchoring to ensure that my string_labeled items that sit beside it don't lose their ruler lines, and are in the right places.
When I do use the "to" method, the drop down list seems to only take up a portion of the width of the control, similar to the chat box drop down. Hopefully we can solve some of these issues, must be missing some part of the method.
My combobox control instance:
<comboboxcd name="phenotype">
<anchored>
<top parent="detailframe" anchor="top" relation="relative" offset="10" />
<left parent="detailframe" anchor="left" relation="relative" offset="30" />
<width>70</width>
<height>15</height>
</anchored>
<frame>
<name>tempmodsmall</name>
<offset>25,2,5,4</offset>
</frame>
<tooltip textres="char_tooltip_phenotype" />
<font>chatfont</font>
<listmaxsize>4</listmaxsize>
</comboboxcd>
And the original, followed by my slightly adjusted template:
<template name="comboboxc">
<simplestringc>
<frame>
<name>fieldlight</name>
<offset>7,5,7,5</offset>
</frame>
<readonly />
<listdirection mergerule="replace">up</listdirection>
<buttonoffset mergerule="replace">0,1</buttonoffset>
<script file="common/scripts/combobox.lua"/>
</simplestringc>
</template>
<template name="comboboxcd">
<simplestringc>
<frame>
<name>fieldlight</name>
<offset>7,5,7,5</offset>
</frame>
<readonly />
<listdirection mergerule="replace">down</listdirection>
<buttonoffset mergerule="replace">0,1</buttonoffset>
<script file="common/scripts/combobox.lua"/>
</simplestringc>
</template>
Moon Wizard
February 24th, 2016, 06:16
If you want the comboxc template to have the list items drop down as opposed to up, just add "<listdirection>down</listdirection>" to the control definition where you use comboboxc in your windowclass definition.
Regards,
JPG
GrimmSpector
February 24th, 2016, 06:49
I tried that, seems like I may have stuck it in the wrong place, as it didn't work.
But the real issue I'm having, is that when I define it's position with relations it seems to ignore the width parameter. Why is that?
Moon Wizard
February 24th, 2016, 08:28
It's because the width and height are not defined in the right spot.
From your example above, it should be: (note the size tag under anchored)
<comboboxcd name="phenotype">
<anchored>
<top parent="detailframe" anchor="top" relation="relative" offset="10" />
<left parent="detailframe" anchor="left" relation="relative" offset="30" />
<size>
<width>70</width>
<height>15</height>
</size>
</anchored>
<frame>
<name>tempmodsmall</name>
<offset>25,2,5,4</offset>
</frame>
<tooltip textres="char_tooltip_phenotype" />
<font>chatfont</font>
<listmaxsize>4</listmaxsize>
</comboboxcd>
More detail of the XML format can be found here:
https://www.fantasygrounds.com/refdoc/windowcontrol.xcp
Regards,
JPG
GrimmSpector
February 24th, 2016, 15:44
Heh, thanks, given how many controls I've done manual sizing on so far I shouldn't have made that mistake. Thanks very much.
When I do the drop direction I'd assume it should work if I overload it in the opening line: <comboxc listdirection="down" is that right?
Moon Wizard
February 24th, 2016, 16:53
Any information that is used by a template must be a child XML tag, since only child tags are accessible by template code, not tag attributes.
Regards,
JPG
GrimmSpector
February 24th, 2016, 18:00
Ah, thanks Moon Wizard, that helps.
Now I just have to decode enough of the lua to figure out how they're getting the values into the drop down, and what's assigned to the database for them, and we should be all good!
Moon Wizard
February 24th, 2016, 18:09
Check out the usage of the control in 3.5E and 5E rulesets to see how they're being used.
Cheers,
JPG
GrimmSpector
February 24th, 2016, 18:27
Alright, doing pretty well, but I'm trying to add items to the combobox list, and it doesn't seem to be working, here's the whole set of code, temporary as it is.
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Please see the license.html file included with this distribution for
attribution and copyright information.
-->
<root>
<windowclass name="charsheet_notes">
<sheetdata>
<frame_char name="detailframe">
<bounds>15,0,-29,80</bounds>
</frame_char>
<comboboxc name="phenotype">
<anchored>
<top parent="detailframe" anchor="top" relation="relative" offset="15" />
<left parent="detailframe" anchor="left" relation="relative" offset="40" />
<size>
<width>70</width>
<height>15</height>
</size>
</anchored>
<frame>
<name>tempmodsmall</name>
<offset>25,2,5,4</offset>
</frame>
<listdirection>down</listdirection>
<tooltip textres="char_tooltip_phenotype" />
<font>chatfont</font>
<listmaxsize>4</listmaxsize>
</comboboxc>
<!-- <string_labeled name="phenotype">
<anchored to="detailframe" position="insidetopleft" offset="15,10" width="100" height="20" />
<labelres>char_label_phenotype</labelres>
</string_labeled>
<right parent="entry" anchor="right" offset="45" />
<bottom parent="entry" anchor="top" relation="relative" offset="-5" />
<left parent="" anchor="center" offset="45" /> -->
<string_labeled name="gender">
<anchored to="detailframe" position="insidetopleft" offset="125,10" width="70" height="20" />
<labelres>char_label_gender</labelres>
</string_labeled>
<string_labeled name="age">
<anchored to="gender" position="right" offset="5,0" width="35" />
<labelres>char_label_age</labelres>
</string_labeled>
<string_labeled name="height">
<anchored to="age" position="right" offset="5,0" width="40" />
<labelres>char_label_height</labelres>
</string_labeled>
<stringcontrol name="height_label">
<anchored to="height" position="right" offset="2,0" />
<font>sheettext</font>
<static>cm</static>
</stringcontrol>
<string_labeled name="weight">
<anchored to="height_label" position="right" offset="5,0" width="40" />
<labelres>char_label_weight</labelres>
</string_labeled>
<stringcontrol name="weight_label">
<anchored to="weight" position="right" offset="2,0" />
<font>sheettext</font>
<static>kg</static>
</stringcontrol>
<string_labeled name="hair">
<anchored>
<top parent="phenotype" anchor="bottom" relation="relative" offset="10" />
<left parent="detailframe" anchor="left" relation="relative" offset="20" />
<size>
<width>60</width>
<height>20</height>
</size>
</anchored>
<labelres>char_label_hair</labelres>
</string_labeled>
<string_labeled name="eyes">
<anchored to="hair" position="right" offset="5,0" width="40" />
<labelres>char_label_eyes</labelres>
</string_labeled>
<string_labeled name="affiliation">
<anchored to="eyes" position="right" offset="5,0" width="70" />
<labelres>char_label_affiliation</labelres>
</string_labeled>
<string_labeled name="extra">
<anchored to="affiliation" position="right" offset="5,0" width="70" />
<labelres>char_label_extra</labelres>
</string_labeled>
<script>
function onInit()
local w = Interface.findWindow("charsheet_notes", "");
w.phenotype.clear();
w.phenotype.add("Test","Test");
end
</script>
</sheetdata>
</windowclass>
</root>
After looking at the "add" function from the combobox.lua, seems that it should be working fine, with a nil value being passed to the database as the value for the setting, and the text string being "String", but it doesn't seem to be getting setup.
What am I missing? There are no errors in console at any point, on load, change, etc.
Moon Wizard
February 24th, 2016, 21:01
Your script is using findWindow to find a window with a class of "charsheet_notes" and no database connection. It seems like you should be getting an error on the second line, since no window like this should exist. Since I'm assuming this is a PC sheet, it should be tied to a database node. Also, the findWindow function only returns top-level windows, such as the entire character sheet.
In some ways, the above information is irrelevant, since the findWindow is not required. You are already running the script within a windowinstance, so the named controls are directly accessible.
<script>
function onInit()
phenotype.clear();
phenotype.add("Test");
end
</script>
Regards,
JPG
GrimmSpector
February 24th, 2016, 21:15
Your script is using findWindow to find a window with a class of "charsheet_notes" and no database connection. It seems like you should be getting an error on the second line, since no window like this should exist. Since I'm assuming this is a PC sheet, it should be tied to a database node. Also, the findWindow function only returns top-level windows, such as the entire character sheet.
In some ways, the above information is irrelevant, since the findWindow is not required. You are already running the script within a windowinstance, so the named controls are directly accessible.
<script>
function onInit()
phenotype.clear();
phenotype.add("Test");
end
</script>
Regards,
JPG
Ah, thanks. However, now I get:
Ruleset Warning: Could not find template (script) in windowclass (charsheet_notes)
Which was not occuring before, I'm assuming the windowclass doesn't normally include a script tag? If it doesn't, I'm a bit confused as to where to put my script, I'm thinking if I move it into the combobox it would overload the existing script reference to combobox.lua, and wouldn't function...how can I most properly fix this?
Also, how would I specify a top level window with a database node properly?
Moon Wizard
February 24th, 2016, 22:47
The script tag should be inside the windowclass tag directly as a child, not inside the sheetdata tag which is why you are seeing that error. Make sure to review the XML for windowclass:
https://www.fantasygrounds.com/refdoc/windowclass.xcp
If you define a script for a control using a template (i.e. not a built-in control on the Developer Guide page, but part of CoreRPG or other ruleset), you can also put an additional onInit. However, in order to ensure that the base template onInit is called to perform the base template initialization, you will need to add "super.onInit();" as the first line of your new script tag for the control. Look at the "selectedskill" control in the "ps_skills" windowclass in the 3.5E ruleset for an example.
To request a top level window, you need to know the windowclass and database node you are looking for already. For example, to access the combat tracker in a CoreRPG derived ruleset, you would use Interface.findWindow("combattracker_host", "combattracker") where "combattracker_host" is the windowclass, and "combattracker" is the path in the database.
Regards,
JPG
GrimmSpector
February 24th, 2016, 22:51
The script tag should be inside the windowclass tag directly as a child, not inside the sheetdata tag which is why you are seeing that error. Make sure to review the XML for windowclass:
https://www.fantasygrounds.com/refdoc/windowclass.xcp
If you define a script for a control using a template (i.e. not a built-in control on the Developer Guide page, but part of CoreRPG or other ruleset), you can also put an additional onInit. However, in order to ensure that the base template onInit is called to perform the base template initialization, you will need to add "super.onInit();" as the first line of your new script tag for the control. Look at the "selectedskill" control in the "ps_skills" windowclass in the 3.5E ruleset for an example.
To request a top level window, you need to know the windowclass and database node you are looking for already. For example, to access the combat tracker in a CoreRPG derived ruleset, you would use Interface.findWindow("combattracker_host", "combattracker") where "combattracker_host" is the windowclass, and "combattracker" is the path in the database.
Regards,
JPG
Thought so, just like C# and similar languages for overloading, and overrides. Thanks again for all the information Moon Wizard, hope I'm not asking too many questions. I'll review the reference for the class again.
That makes sense, thank you, so the database nodes are treated just like any other class reference then, i.e. DB.combattrack.itemwithavaluehere. Thank you again!
GrimmSpector
February 26th, 2016, 03:43
Two more issues I'm having, and I'm guessing I'm simply missing it's location in the lua code, is adjusting the length of the control in such a way that the text in the drop down list is more to the left, is there a way to override this string without changing the position of the drop down frame itself?
Also and more important to me right this moment, the drop down list is quite wide, wider than the original control while the chat language drop-'up' is only as wide as the string area, which is less wide than the control. I know there must be a way to override this too, but am missing it. Hoping there's a way to do both of these in the xml that I'm simply missing. Any help would be super thanks!
Moon Wizard
February 26th, 2016, 04:29
There's a listoffset tag of:
<listoffset mergerule="replace">0,5</listoffset>
By default the X offset is 0, and the Y offset is 5 which is the default top/bottom frame offset for the default frame graphic.
If you want the text offset wider, you would have to redefine the "combobox_list" template, since that option isn't built into the base control
Cheers,
JPG
GrimmSpector
February 26th, 2016, 06:24
There's a listoffset tag of:
<listoffset mergerule="replace">0,5</listoffset>
By default the X offset is 0, and the Y offset is 5 which is the default top/bottom frame offset for the default frame graphic.
If you want the text offset wider, you would have to redefine the "combobox_list" template, since that option isn't built into the base control
Cheers,
JPG
So you're saying listoffset should let me modify the list itself, but the text inside the control is not something I can change directly. Ok I'll have to dig through that control and see if it's in the xml or the lua and what I can about making a new instance of it then I suppose. Just looks ugly with the big empty space on the left of the text!
GrimmSpector
February 26th, 2016, 06:36
More combobox excitement, why is this not working to set a default value? It looks like it's never even executing this piece of code, but by the looks of other similar controls, it should be.
<windowclass name="charsheet_notes">
<sheetdata>
<frame_char name="detailframe">
<bounds>15,5,-29,80</bounds>
</frame_char>
<combobox name="phenotype">
<anchored>
<top parent="detailframe" anchor="top" relation="relative" offset="15" />
<left parent="detailframe" anchor="left" relation="relative" offset="40" />
<size>
<width>100</width>
<height>15</height>
</size>
</anchored>
<frame>
<name>tempmodsmall</name>
<offset>25,2,0,4</offset>
</frame>
<listoffset>5,0</listoffset>
<buttonoffset>-5,1</buttonoffset>
<listdirection>down</listdirection>
<tooltip textres="char_tooltip_phenotype" />
<font>chatfont</font>
<listmaxsize>4</listmaxsize>
<script>
function onInit()
if not getValue() then
setValue("Human");
end
super.onInit();
end
</script>
</combobox>
Moon Wizard
February 26th, 2016, 22:27
My guess is that super.onInit() should go before any other initialization code. Also, the control initialization code happens before the window initialization code, so the "Human" value won't exist yet. You should set this "default" value in the window script code, just after you add the items to the list.
Regards,
JPG
GrimmSpector
February 27th, 2016, 02:36
the value human won't exist, you're right, but since I'm explicitly setting it with code it doesn't matter, it gets set anyways, and then when the code renders the control and sets the possible list values it becomes selected in the list.
I fixed it to work fine, and the init code works, though you're probably right, I probably should call the super first, but here's what I changed it to in case it helps anyone:
<script>
function onInit()
if getValue("") then
setValue("Human");
end
super.onInit();
end
</script>
Powered by vBulletin® Version 4.2.1 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.