PDA

View Full Version : relative placement



Varsuuk
February 10th, 2021, 03:51
I used a mechanism in a prior sheet where I duplicated a couple controls and based on an option setVisible/setEnabled one on and one off. This worked. The arrangement was all going to a specific anchor but with explicit offsets.

This time I was editing the NPC sheet of MoreCore (in a localized one in my extension) and I wanted to have 2 controls in same manner. Only this time the controls are relationship="relative".

I added one like so:



<number_column name="defence">
<anchored position="belowleft" offset="0,12" />
</number_column>

<number_column name="defenceASC">
<anchored >
<top parent="columnanchor" relation="current" />
</anchored>
<static>11</static>
</number_column>

followed by more labels and number_columns...

(the 11 was just to have a value to notice it is the topmost)

If I tried setting defense.isVisible(false), the whole layout shifts up and has controls on top of others.
Calling it early tonight, too tired. Hopefully clear head tomorrow or clear answers here will help me out :)

I'm not very good with these relative layouts. Any tips on how I need to edit this to get it to be in exactly same spot as defense but only one of the two visible

Trenloe
February 10th, 2021, 08:52
I can't comment in detail on that small snippet.

Using relational anchoring is incredibly powerful functionality, especially when some controls in the relation hierarchy are enabled/disabled or shown/hidden as it allows the controls to automatically shift their position. It's also very handy for resizable windows.

The defenceASC control is anchored to the columnanchor control using relational anchoring. The defence control is not. For relational anchoring the order of the controls in XML determines the order of the controls in the relation. If controls aren't in the relation then they have zero impact on the positioning of the relational anchor.

The control templates with column in their name usually have relational anchoring built in - to make it east to build up a window with a column of data. Think spells, feats, etc., and to a lesser extent NPCs - which use a mixture of column and normal positioning. So, looking at the two controls in the limited XML you provide - one is using relational anchoring, but is overriding the full anchoring defined in the number_column template, and defence is a number_column control (whose template has built in relational anchoring) but you're overriding that with a static anchor, which is going to screw up the template.

I don't know if that helps, without more XML, or full details of exactly what's happen (i.e. screenshots) I can't give more details.

Varsuuk
February 10th, 2021, 15:51
Damn - I typed it all up and hit a button and lost my tab... so shorter version:

The DB has 2 AC values, ascending and descending. Yes, I could have based it all on storing one and having display converters etc. I didn't do that.

So what I am looking to do is have 2 DB AC values one asc one desc and depending on options set in control panel we would display one value or the other.

I implemented it as keeping both values updated and making only one of the controls visible (and enabled) at a time in the Character Sheet and in the Combat Tracker. So I went and intended to do the same in the NPC sheet.

The "current" and explicit anchoring was me experimenting trying to get the control to sit on top of the other. It was a failed trial-error try. It was late night and I didn't see the obvious issue with that depending on which was visible and which was not. I plan to address it again earlier in the evening today if I do not get a solution idea offered here due to not having enough info perhaps or if the only suggestion is "don't do that" lol ;) then Ill redo the whole NPC sheet to not use relative for the upper part.


PS:
The "hit_die" code is MESSY because I was trying to have a string_column because I needed the control to be a string not number but that is outside scope of this question.


</script>
<sheetdata>
<anchor_column name="columnanchor" />

<label_column name="defence_label">
<static textres="ac_label" />
</label_column>

<number_column name="defence">
<anchored position="belowleft" offset="0,12" />
</number_column>

<number_column name="defenceASC">
<anchored >
<top parent="columnanchor" relation="current" />
</anchored>
<static>11</static>
</number_column>


<label_column_right name="thac0_label">
<anchored to="defence" />
<static textres="thac0_label" />
<tooltip text="Descending Armor Class" />
</label_column_right>

<number_column_right name="thac0" >
<anchored to="defence" />
</number_column_right>


<label_column name="hit_die_label">
<static textres="hit_die_label" />
</label_column>

<basicstring name="hit_die">
<font>sheetnumber</font>
<center/>
<frame mergerule="replace" name="fielddark" offset="7,5,7,5" />
<anchored width="40" height="20">
<top parent="columnanchor" anchor="bottom" relation="relative" offset="7" />
<left offset="97" />
</anchored>
<delaykeyupdate />
<script>
function onValueChanged()
local nodeNPC = getDatabaseNode().getParent()
MonsterManagerSWWB.onHitDieChanged(nodeNPC)
end
</script>
</basicstring>


<label_column_right name="hit_dice_label">
<anchored to="hit_die" />
<static textres="hit_dice_label" />
</label_column_right>

<number_column_right name="hit_die_type" >
<anchored to="hit_die" />
<default>6</default>
<delaykeyupdate />
<script>
function onValueChanged()
local nodeNPC = getDatabaseNode().getParent()
MonsterManagerSWWB.onHitDieChanged(nodeNPC)
end
</script>
</number_column_right>


<label_column name="hitpoints_label">
<static textres="hp_label" />
</label_column>

<number_column name="health" />


<label_column_right name="wounds_label">
<anchored to="health" />
<static textres="wounds_label" />
</label_column_right>

<number_column_right name="wounds" >
<anchored to="health" />
</number_column_right>


<label_column name="hde_label">
<static textres="hde_label" />
</label_column>

<number_column name="hde" />


<label_column_right name="xp_label">
<anchored to="hde" />
<static textres="xp_label" />
</label_column_right>

<number_column_right name="xp" >
<anchored to="hde" />
</number_column_right>


<label_column name="move_label">
<static textres="move_label" />
</label_column>

<string_columnh name="move" />


<label_column name="special_label">
<static textres="special_label" />
</label_column>

<string_columnh name="special" />



<frame_char name="cas1">
<anchored to="special" position="belowleft" offset="-100,5" height="200" >



EDIT:
I tried to upload a video showing how the control change as I click but I have no idea how to use the formats lists. I have only ever used a camera or iPhone to take video and don’t use upload services really.

So I switched to two snapshots one with asc and one desc

Trenloe
February 10th, 2021, 16:03
Try this:


<sheetdata>
<anchor_column name="columnanchor" />
<label_column name="defence_label">
<static textres="ac_label" />
</label_column>
<number_column name="defence" />

<label_column name="defenceASC_label">
<static textres="ac_label" />
</label_column>
<number_column name="defenceASC" />
...
...

Then, in the window onInit and onLockChanged functions, use defence.update(true/false) and defenceASC.update(true/false) to turn them on/off as needed. The <control>.update function is coded to cover the control and a label of name <control>_label all in one.

As all of the above controls are using templates that specifically anchor in a vertical line (column) then the other controls using "column" templates will be spaced equally as they are all using relative anchoring to the columnanchor control.

Varsuuk
February 10th, 2021, 16:03
Hmm having probs uploading pics but I see you answered so will read first ;) you are FAST!

Edit:
Will try that now

Ok, thought to try iCloud link as url - let’s see if that works:
https://share.icloud.com/photos/0y5yV1mJFogS0W1ZPsT70FkMg#Mamaroneck_-_Old_Rye_Neck

Varsuuk
February 10th, 2021, 16:23
I added the 2 update() calls to onInit()



...
<windowclass name="npc_main">
<margins control="0,0,0,2" />
<script>
function onInit()
update();
defence.update(true)
defenceASC.update(false)
end

function update()
local bReadOnly = WindowManager.getReadOnlyState(getDatabaseNode());

defence.setReadOnly(bReadOnly)
thac0.setReadOnly(true)
..


And in sheet data, I changed to:


...
<anchor_column name="columnanchor" />
<label_column name="defence_label">
<static textres="ac_label" />
</label_column>
<number_column name="defence" />

<label_column name="defenceASC_label">
<static textres="ac_label" />
</label_column>
<number_column name="defenceASC" />

<label_column_right name="thac0_label">
...




I get the error:


Runtime Notice: Reloading ruleset
Runtime Notice: s'aMajor: ' | { s'CoreRPG' = #4, s'MoreCore' = #1 } | s' aMinor: ' | { s'CoreRPG' = #0, s'MoreCore' = #58 }
Runtime Notice: s'onInit: registerResultHandler'
Runtime Notice: s'onInit: '
Script Error: [string "npc_main"]:1: attempt to call field 'update' (a nil value)


? so number_column's chain doesn't have an "update()"?

Trenloe
February 10th, 2021, 16:36
See post below...

Trenloe
February 10th, 2021, 16:42
Follow up - hhmmm, looks like number_column doesn't have the update function added to the underlying template.

Just use <controlname>.setVisible(true/false); to show/hide the controls - at least then you won't need two labels, you can just use one AC label. :)

Sorry for the false info.

Varsuuk
February 10th, 2021, 18:18
NO problem man - you are always quick to help and an epic treasure trove of FG programming truths!

The setVisible(true/false) thing is what I tried that didn't work - the only different is mine was a superimposed mess because I was trying to place the ascending control(s) on top of the "normal" descending versions EXPLICITLY not realizing that the XML controls are "runtime" calculated and the extra "relative" was not actually there in the end because onInit killed the 2 controls.

Had I SIMPLY added the control right after the one to replace WITHOUT extra "work to get it right" ... it WOULD have been right.

ARRRGH. Thank you. I doubt I would have gone back to square one without the explicit position for quite some time in my troubleshooting if not for you.

But the whole stacking thing that made placement neater worked against me - so I tried to give it different anchor/relatve to place it but it messed up the rest.

It turns out that it WAS the right way all along, I must have made a typo, probably with one of the 4 spellings of "defence" (/GLARE at Damned lol :) and his British English!!!!) and the log error was probably covered and I missed it.

Using the setvisible thing works cleanly ... which is how I tried to do it in the first place. When it failed, I assume it was because the relation=relative was offsetting off the non-visible one anyway and pushing it all off alignment.I am not 100% sure what I did wrong

Varsuuk
February 10th, 2021, 19:14
Awesome - got AC/AAC and THAC0/BAB swap and recalculations working. MY extended "lunch" being over - I'll have to make the equivalent updates to CT for NPCs after done at work.

Mega awesome thanks again.

Trenloe
February 10th, 2021, 19:14
Awesome - got AC/AAC and THAC0/BAB swap and recalculations working. MY extended "lunch" being over - I'll have to make the equivalent updates to CT for NPCs after done at work.

Mega awesome thanks again.
Great! :)