PDA

View Full Version : Linking Functions



ThinkTank
January 12th, 2014, 22:53
Having a bit of a mental block here.

How would I go about referencing a function within a control (in charsheet_main) that is only defined inside another control (in charsheet_toplevel)?

The two in question being:


<string_labeled name="race">
<anchored>
<to>classframe</to>
<position>insidetopleft</position>
<offset>15,17</offset>
<size>
<width>70</width>
<height>20</height>
</size>
</anchored>
<label>Race</label>
<static></static>
<script>

function onValueChanged()
if DataCommon.racedata[getValue()]~=nil then
window.phy_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].phy);
window.spd_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].spd);
window.str_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].str);
window.agi_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].agi);
window.prw_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].prw);
window.poi_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].poi);
window.int_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].int);
window.arc_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].arc);
window.per_score.setValue(DataCommon.racedata[getValue()]["Starting Stats"].per);


end
recalcStatMax();
end

function recalcStatMax()
if DataCommon.racedata[getValue()]~=nil then

local level=window.getDatabaseNode().getChild("level").getValue();

window.phy_max.setValue( DataCommon.racedata[getValue()][level].phy);
window.spd_max.setValue( DataCommon.racedata[getValue()][level].spd);
window.str_max.setValue( DataCommon.racedata[getValue()][level].str);
window.agi_max.setValue( DataCommon.racedata[getValue()][level].agi);
window.prw_max.setValue( DataCommon.racedata[getValue()][level].prw);
window.poi_max.setValue( DataCommon.racedata[getValue()][level].poi);
window.int_max.setValue( DataCommon.racedata[getValue()][level].int);
window.arc_max.setValue( DataCommon.racedata[getValue()][level].arc);
window.per_max.setValue( DataCommon.racedata[getValue()][level].per);

end
end

</script>


and:



<!-- XP -->
<basicnumber name="XP">
<anchored>
<to>overviewframe</to>
<position>insidetopleft</position>
<offset>180,12</offset>
<size>
<width>32</width>
<height>20</height>
</size>
</anchored>
<script>
function onInit()
onValueChanged();
end

oldLevel="Heroic";
function setOldLevel(level)
oldLevel=level;
end

function onValueChanged()
local xptotal=getValue();
local levelstring="Heroic";
if xptotal >= 50 then levelstring="Veteran"; end
if xptotal >= 100 then levelstring="Epic"; end
window.level.setValue(levelstring);
end

</script>
</basicnumber>

<stringfield name="level">
<anchored>
<to>XP</to>
<position>right</position>
<offset>0,-3</offset>
<size><width>60</width></size>
</anchored>
<script>
function onValueChanged()
???
end
</script>
<font>sheetlabel</font>
<static>Heroic</static>
<center/>
</stringfield>



respectivly.

Moon Wizard
January 13th, 2014, 01:08
If I'm assuming your code layout correctly:



function onValueChanged()
window.parentcontrol.window.race.recalcStatMax();
end


Regards,
JPG

ThinkTank
January 13th, 2014, 13:09
If I'm assuming your code layout correctly:



function onValueChanged()
window.parentcontrol.window.race.recalcStatMax();
end


Regards,
JPG

Thank you.

A nil value for parentcontrol when onValueChanged unfortunatly. :confused:

Trenloe
January 13th, 2014, 13:31
Without knowing the full control/window hierarchy I'm not sure, but try this: parentcontrol.window.race.recalcStatMax();

ThinkTank
January 13th, 2014, 13:46
Hope this gives a better idea of the hierarchy: https://pastebin.com/hGc3T3bt

The DB gives it as:

<id-00003>
<XP type="number">0</XP>
<level type="string">Heroic</level>
<race type="string">Human</race>

Would the race script be better moved to a lua file rather than attached to a string control?

Trenloe
January 13th, 2014, 13:56
I'm guessing that the charsheet_main windowclass is initiated in charsheet_toplevel.xml using <subwindow>? You don't include the whole file so I can't tell.

If so, have you tried what I suggested? parentcontrol.window.race.recalcStatMax();

ThinkTank
January 13th, 2014, 14:01
I'm guessing that the charsheet_main windowclass is initiated in charsheet_toplevel.xml using <subwindow>? You don't include the whole file so I can't tell.

If so, have you tried what I suggested? parentcontrol.window.race.recalcStatMax();

I did yes, again a nil value when onValueChanged.

Here are both full files:
https://pastebin.com/M28ga7Gx
https://pastebin.com/VpSsck7y

Trenloe
January 13th, 2014, 14:21
Ah, OK - you are trying to call the recalcStatMax() function in the <race> control within the subwindow "main" from the <charsheet> window. Which is actually the opposite of what you were saying in post #1! ;) No worries...

Try: window.main.subwindow.race.recalcStatMax();

ThinkTank
January 13th, 2014, 15:17
I guess Im terrible at explaining things :)

That looks like it worked, thanks.

ThinkTank
January 17th, 2014, 16:35
Out of intrest, are there set lines for moving up and down the hierarchy? window.main.subwindow certainly works for going from toplevel to the subwindows, but what would be the default for going between subwindows?

For example, would: window.parentcontrol.window.skills.skilllist.apply Filter();

Point the script toward the windowlist skilllist in the skills subwindow? (and then applyFilter)

Trenloe
January 17th, 2014, 16:46
You can absolutely move up and down the hierarchy. Exactly what is needed entirely depends on the control hierarchy within the individual window. The highest level is the containing window - which can contain controls, subwindow, windowlists, etc.. All of these elements are defined in the "Elements" section of the FG reference document: https://www.fantasygrounds.com/refdoc/

For information on what controls can be accessed via variables in a script see the "Script block scope" section of the Scripting page in the ruleset modification guide: https://www.fantasygrounds.com/modguide/scripting.xcp

p440
January 17th, 2014, 17:08
ok im someone helping him with this, heres the layout

the toplevel windowclass:
https://puu.sh/6oa9V.png

the skills windowclass:
https://puu.sh/6oa51.png

the goal is to applyFilter() the skilllist windowlist from a control in the abilities subwindow

window.parentcontrol.window.skills.skilllist.apply Filter(); nil field "skilllist"

p440
January 17th, 2014, 19:09
turns out i figured it out, .subwindow wasnt working before because the controls hadnt been initialized yet

it helped to draw up a diagram
https://puu.sh/6ogpt.png

it seems obvious now reading the docu but it wasnt so explicit that windows only hold controls and controls can hold windows but never are windows holding windows directly

Moon Wizard
January 17th, 2014, 19:52
Going up:
"window" is defined for all objects derived from "windowcontrol".
"windowlist" is defined for all windows embedded within windowlist controls.
"parentcontrol" is defined for all windows embedded within subwindow controls.

Going down:
"subwindow" is defined for all "subwindow" objects, and points to the windowinstance object it contains (if instantiated, see activate/fastinit tags)
Use getWindows() function to get all child windows of a "windowlist" object.
Every control name is defined for each windowinstance object within which it is instantiated. (If no name attribute defined, then the control is not accessible.)

Using these tags, you can traverse up/down the hierarchy.

Regards,
JPG