PDA

View Full Version : Problem with control anchors



Bidmaron
November 9th, 2017, 01:55
I really struggle with the controls in FG.

Currently, I am getting the following in the console:


Runtime Notice: Reloading ruleset
Ruleset Warning: window: Anchored static height ignored for control (export_line) in windowclass (masterindexitem)
Ruleset Warning: window: Anchored static width ignored for control (export_line) in windowclass (masterindexitem)
Ruleset Warning: window: Anchored static height ignored for control (export_line) in windowclass (masterindexitem)
Ruleset Warning: window: Anchored static width ignored for control (export_line) in windowclass (masterindexitem)


export_line is created when the user pushes the 'Export' button in the window you can see in the first graphic, which produces the result of the second graphic.

21393
21394
The Export button is defined as:


<template name="button_export">
<buttoncontrol>
<anchored to="buttonanchor" width="50" height="20">
<top />
<left anchor="right" relation="relative" offset="5" />
</anchored>
<pressed name="buttondown" offset="2,2,2,2" nobaseframe="true" />
<font>button-white</font>
<text>Export</text>
<state tooltipres="gen_export_button_up" frame="buttonup" frameoffset="2,2,2,2"/>
<state tooltipres="gen_export_button_down" frame="buttondown" frameoffset="2,2,2,2"/>
<script file="export_table_generator.lua" />
</buttoncontrol>
</template>


Below is the contents of the lua script file, with the code creating the individual table export button highlighted:


--meant to be the script code for the window 'Export' button
function onInit()
setValue(0);
sSaveEditTool="";
window.list_iedit.setRelatedControl(getName());
end

function onValueChanged()
Debug.chat("value=",getValue());
if getValue()==1 then
if window.list then
if window.list_iedit then
window.list_iedit.setSemaphore();
window.list_iedit.setValue(0);
window.list_iedit.clearSemaphore();
end
local aTabGens=window.list.getWindows();
for _,v in ipairs(aTabGens) do
v.idelete.setEnabled(false);
v.idelete.setVisibility(true);
if v.export_line then
--control previously created
Debug.chat("making the export visible");
v.export_line.setVisible(true);
else
Debug.chat("creating the control");
v.createControl("line_button_export","export_line");
end
end
end
else
Debug.chat("resetting export");
if window.list then
local aTabGens=window.list.getWindows();
for _,v in ipairs(aTabGens) do
if v.export_line then
Debug.chat("making the export invisible");
v.export_line.setVisible(false);
end
v.idelete.setEnabled(true);
v.idelete.setVisibility(false);
end
end
end
end

function resetState()
setValue(0);
end --resetState



and this is the template of the control:


<template name="line_button_export">
<buttoncontrol>
<anchored to="idelete" position="over" width="20" height="20" />
<icon normal="button_export" pressed="button_export_down" />
<tooltip textres="tabselect_tooltip_export" />
<script>
function onButtonPress()
TableManager.exportTabGen(window.getDatabaseNode() );
end
</script>
</buttoncontrol>
</template>


What do I need to do to eliminate the ruleset warning I keep getting? Anchoring and control positioning just kicks my butt.

Minty23185Fresh
November 9th, 2017, 04:50
I'm going to ask the obvious and look the fool, but here goes...
You're anchoring button_export to buttonanchor in the line <anchored to="buttonanchor" ....
You do have buttonanchor defined right?
The spelling is the same? (e.g my error would be spelling it button_anchor in it's definition elsewhere :O ).

Another possibility is scope. That's my bane! Are button_export and buttonanchor in the same scope or if one is the super of the other they're of the proper super/self relationship? From my limited understanding the control with buttonanchor would have to contain button_export...

Even if I am totally off base, or backward, I hope this spawns some ideas for you.

Bidmaron
November 9th, 2017, 05:03
Minty, I am sure I have a misconception about some of the issues you raise, and once one of the luminaries chimes in and fixes my level of understanding, it will make perfect sense.

The control with the warnings doesn't use the anchors you are talking about (that is the export button, and it doesn't issue any warnings).

The anchor definitions are in scope because when I create the control (highlighted above), it gets inserted into the following window:


<windowclass name="masterindexitem">
<margins control="0,0,0,2" />
<script file="campaign/scripts/masterindexitem_window.lua" />
<sheetdata>
<masterindexitem_link name="link" />

<masterindexitem_anchor_right name="rightanchor" />
<masterindexitem_idelete name="idelete" />
<masterindexitem_access name="access" />
<masterindexitem_modified name="modified" />
<masterindexitem_category name="category" />

<masterindexitem_name name="name" />
</sheetdata>
</windowclass>

The button causing the warnings anchors to delete, which is highlighted above.

I am thinking it is because if you use the 'over' tag/attribute that maybe it doesn't need height/width?

Minty23185Fresh
November 9th, 2017, 06:59
The control with the warnings doesn't use the anchors you are talking about (that is the export button, and it doesn't issue any warnings).

Aargh! How in the heck did I do that: I saw export_line and jumbled it to button_export! What a moron. Sorry about that.

As a follow up. I'm working in masterindex instead of masterindexitem, but they're pretty similar. There is a generic control that everybody subsequent is anchored to. In your case, the "rightanchor" with the following four controls anchored to it (idelete,access, modified and category). You're trying to anchor to idelete. What if you anchor to rightanchor instead? (might need different offsets though)

damned
November 9th, 2017, 07:26
try moving height and width out of template and into the inline xml

Minty23185Fresh
November 9th, 2017, 07:32
I wonder also, and this is just a guess, based on the verbiage of the warnings. Maybe position="over" doesn't allow heights and widths. I searched for position="over" in the CoreRPG, and in every instance I looked at height and width were absent. It might make sense, the "covering" control might derive it's height and width from the "covered" control.

(EDIT: I just noticed you said this at the bottom of post 3. Did you remove them? And hence the warnings too?)

Bidmaron
November 9th, 2017, 12:48
I will try removing. I think I already did that but cannot remember for sure

Moon Wizard
November 9th, 2017, 22:58
It's because by using the "over" position attribute, you are assigning all four anchors to be assigned to the control specified in the "to" attribute. Therefore, since the top/bottom anchors are defined, the static height is ignored; and similarly, since the left/right anchors are defined, the static width is ignored.

More information:

The layout system assumes that you specify either a specific bounding rectangle ("bounds" tag), or an anchored layout definition ("anchored" tag).

If you used an "anchored" tag, then you need to specify:
* One vertical anchor and a static height; OR both vertical anchors (top/bottom)
* AND one horizontal anchor and a static width; OR both horizontal anchors (left/right)

The "position" attribute allows you to shortcut the anchor definitions by specifying a master parent ("to" attribute), and a set of anchors to automatically anchor to ("position" attribute).

For the "position" attribute, these are the anchors that are created based on the value:
* "over" = all anchors -> same parent anchor (left/top/right/bottom)
* "aboveleft" = bottom anchor -> parent top anchor; left anchor -> parent left anchor
* "above" = bottom anchor -> parent top anchor; left anchor -> parent left anchor; right anchor ->parent right anchor
* "aboveright" = bottom anchor -> parent top anchor; right anchor ->parent right anchor
* "lefthigh" = top anchor -> parent top anchor; right anchor -> parent left anchor
* "left" = top anchor -> parent top anchor; right anchor -> parent left anchor; bottom anchor -> parent bottom anchor
* "leftlow" = right anchor -> parent left anchor; bottom anchor -> parent bottom anchor
* "insidetopleft" = top anchor -> parent top anchor; left anchor -> parent left anchor
* "insidetop" = top anchor -> parent top anchor; left anchor -> parent left anchor; right anchor ->parent right anchor
* "insidetopright" = top anchor -> parent top anchor; right anchor ->parent right anchor
* "insideleft" = top anchor -> parent top anchor; left anchor -> parent left anchor; bottom anchor -> parent bottom anchor
...and so on...
("insidetopright", "insideright", "insidebottomright", "insidebottom", "righthigh", "right", "rightlow", "belowleft", "below", "belowright")

Regards,
JPG

Bidmaron
November 10th, 2017, 02:24
Thanks, MW. Removing the height and width caused the warnings to go away.

Bidmaron
November 16th, 2017, 16:31
A question only SW may be able to answer:

I am trying to determine the record class of a given data node. My algorithm is to simply strip off the top two path levels if the first path level is "reference" or the first path level if it is not reference. Then, to verify it is a valid record node (as defined in DataLibrary), I call getRecordTypeFromPath. (why doesn't this do what it sounds like? It only works if the path is to a record and not to one of its children. If this did what the name implied, I wouldn't need to go through this rigamarole).

So, my question is:
Is it true that it is a safe assumption that the only valid dataLibrary record types have either one level of node address (e.g. 'table,' 'note,' 'encounter') or two and the first is always 'reference?' (e.g. 'reference.table,' 'reference.note').

Currently, for CoreRPG, examining the static table data in dataLibrary.lua, that is a truism, but is it SW's intent that always be the case?

Moon Wizard
November 16th, 2017, 17:56
1. The getRecordTypeFromPath does exactly what it is supposed to do. It was designed to assume that you were asking for a record's type from the top level of a record. It was not designed to determine a record type from anywhere in a record's hierarchy. That is a more complex scenario, with more assumptions. (see number 2)

2. While I've tried to hold to the general tree structure for record types that you've mentioned, there is no enforcement of this scheme within the rulesets. The data paths for each record type are whatever is specified by the ruleset developer. As noted above, the record type determination function cannot therefore make these assumptions. In fact, whenever I work on an adaptation of an older ruleset, there are inevitably "custom" data paths that need to be accounted for.

3. I've tried to build the system in a way that allows the ability to bring forward as many common features as possible from CoreRPG, while giving the ruleset developer full control within their code. While we recommend the data paths in a similar structure as we have provided in other rulesets, there is no enforcement, and no plans to enforce.

Perhaps you can explain what you are trying to accomplish, and it might be easier to point you to a simpler solution. Most database nodes within a record are only one deep (except for PCs).

Regards,
JPG

Bidmaron
November 16th, 2017, 18:12
Thanks, MW. what I am doing is warning the user when he has created a table (exactly like current implementation of tables), generator (much more powerful thing structured like a table [in fact you can drag tables to generator list and they move intact]), and what i am calling a matrix (which is like a non rollable table with more flexible layout options and which generators can perform lookup on [e.g. give me the venerable age range for a gnome]). So with minimal overloading of your existing wonderful data library manager i can take a subnode (necessary because generators can have sub generators so as to support TableSmith importing]) and see whether it is something that should have a unique name and warn the user if he has changed a name to create a duplicate name.

If you have a better idea, i am definitely listening. Please don’t waste any time though because my architecture works as long as master record types are at root level.

Moon Wizard
November 16th, 2017, 18:15
Yeah, tables should be safe, unless we decide to do an overhaul of the way tables work. There are no plans right now, but I always keep my options open. ;)

Cheers,
JPG

damned
November 16th, 2017, 20:52
I have longer data paths in Maelstrom but dont worry as no one else has ever used that ruleset!
I think since then Ive tended to keep things much shorter...

Bidmaron
November 16th, 2017, 21:06
Damned as long as they start with the right record nose it won’t matter how deep they are with the way i am doing it.

Bidmaron
November 19th, 2017, 21:07
OK, here we go again...

I am trying to add another control to the right of the output label and box. Below is the screen shot of how the current table window looks:

21527

I am trying to add a label reading "Iterations" to the right of the output, with a number control below it to control the number of iterations of the table. My window uses layering on the table_main. Here is my window:


<windowclass name="table_main" merge="join">
<sheetdata merge="join">
<label_tabletop name="label_iterations">
<anchored height="10" width="40">
<left parent="label_output" anchor="right" relation="absolute" offset="15" />
</anchored>
<static textres="table_label_iterations" />
<invisible />
<script>
function onInit()
Debug.chat("node=",window.getDatabaseNode().getPath());
if TableManager.isGenerator(window.getDatabaseNode()) then
Debug.chat("making visible");
setVisible(true);
window.iterations.setVisible(true);
end
end
</script>
</label_tabletop>
<basicnumber name="iterations">
<anchored height="20" width="40">
<top parent="label_iterations" anchor="bottom" realtion="absolute" offset="2" />
<left anchor="right" relation="relative" offset="10" />
</anchored>
<invisible />
</basicnumber>
</sheetdata>
</windowclass>


There is no evidence of either of these two controls in my generator window. My chat window shows the following when it runs, indicating that the script is getting invoked:


s'node=' | s'generators.id-00008'
s'making visible'


I am thinking this is another case of onInit not doing what you really want it to do, but I figured that controlling visibility state was fair game in onInit. Furthermore, if I remove the <invisible/> tag, they still don't show up.

Here is the table_main window I am layering on top of so you can see the anchors I am trying to use:


<windowclass name="table_main">
<margins control="0,0,0,5" />
<script file="campaign/scripts/table_main.lua" />
<sheetdata>
<hn name="table_positionoffset" />
<hn name="resultscols">
<default>1</default>
<min>1</min>
<max>20</max>
<script>
function onValueChanged()
window.onColumnsChanged();
end
</script>
</hn>

<anchor_column name="columnanchor" />

<string_column_full name="description">
<empty textres="table_emptydesc" />
</string_column_full>

<line_column name="divider" />

<genericcontrol name="tabletoplabelanchor">
<anchored height="10" width="0">
<top parent="columnanchor" anchor="bottom" relation="relative" offset="2" />
<left />
</anchored>
</genericcontrol>
<label_tabletop name="label_roll">
<anchored width="30" />
<static textres="table_label_roll" />
</label_tabletop>
<label_tabletop name="label_showroll">
<anchored width="20">
<left offset="10" />
</anchored>
<static textres="table_label_showroll" />
<tooltip textres="table_tooltip_showroll" />
</label_tabletop>
<label_tabletop name="label_customroll">
<anchored width="80">
<left offset="15" />
</anchored>
<static textres="table_label_customroll" />
</label_tabletop>
<label_tabletop name="label_output">
<anchored width="40">
<left offset="15" />
</anchored>
<static textres="table_label_output" />
</label_tabletop>

<genericcontrol name="leftanchor">
<anchored height="20" width="0">
<top parent="columnanchor" anchor="bottom" relation="relative" offset="8" />
<left />
</anchored>
</genericcontrol>
<button_roll name="button_roll">
<anchored to="leftanchor" width="30" height="30">
<top offset="-5" />
<left anchor="right" relation="relative" offset="0" />
</anchored>
<script>
function onDragStart(button, x, y, draginfo)
return window.actionRoll(draginfo);
end

function onButtonPress()
return window.actionRoll();
end
</script>
</button_roll>
<buttonfield name="hiderollresults">
<anchored to="leftanchor" height="20" width="20">
<top />
<left anchor="right" relation="relative" offset="10" />
</anchored>
<frame name="fielddark" offset="8,7,8,5" />
<state icon="visibilityon" tooltipres="table_tooltip_rollshow" />
<state icon="visibilityoff" tooltipres="table_tooltip_rollhide" />
</buttonfield>
<basicdice name="dice">
<anchored to="leftanchor" height="20" width="50">
<top />
<left anchor="right" relation="relative" offset="15" />
</anchored>
<script>
function onDragStart(button, x, y, draginfo)
return window.actionRoll(draginfo);
end

function onDoubleClick()
return window.actionRoll();
end
</script>
</basicdice>
<basicnumber name="mod">
<anchored to="leftanchor" height="20" width="20">
<top offset="-1" />
<left anchor="right" relation="relative" offset="10" />
</anchored>
<displaysign />
<script>
function onDragStart(button, x, y, draginfo)
return window.actionRoll(draginfo);
end

function onDoubleClick()
return window.actionRoll();
end
</script>
</basicnumber>
<button_stringcycler name="output">
<anchored to="leftanchor" width="40">
<top offset="-1" />
<left anchor="right" relation="relative" offset="15" />
</anchored>
<gmvisibleonly />
<parameters>
<labelsres>table_label_output_story|table_label_output_parcel |table_label_output_encounter</labelsres>
<values>story|parcel|encounter</values>
<defaultlabelres>table_label_output_chat</defaultlabelres>
</parameters>
</button_stringcycler>

<button_iedit name="table_iedit">
<anchored>
<top parent="leftanchor" />
<right offset="-10" />
</anchored>
<target>list</target>
<script>
function onValueChanged()
local bEditMode = (getValue() == 1);
window.table_iadd_column.setVisible(bEditMode);
window.table_idelete_column.setVisible(bEditMode);
window.table_iadd_row.setVisible(bEditMode);
window.tablerows.update();
end
</script>
</button_iedit>
<button_iadd name="table_iadd_row">
<anchored to="table_iedit" position="lefthigh" offset="2,0" />
<tooltip textres="table_tooltip_rowadd" />
<script>
function onButtonPress()
window.addRow();
end
</script>
</button_iadd>
<button_icon name="table_idelete_column">
<anchored to="table_iadd_row" position="lefthigh" offset="4,0" width="20" height="20" />
<icon normal="button_col_delete" />
<tooltip textres="table_tooltip_coldelete" />
<invisible />
<script>
function onButtonPress()
window.setColumns(window.getColumns() - 1);
end
</script>
</button_icon>
<button_icon name="table_iadd_column">
<anchored to="table_idelete_column" position="lefthigh" offset="5,0" width="20" height="20" />
<icon normal="button_col_insert" />
<tooltip textres="table_tooltip_coladd" />
<invisible />
<script>
function onButtonPress()
window.setColumns(window.getColumns() + 1);
end
</script>
</button_icon>

<line_column name="divider2" />

<subwindow name="tablecolumnheaders">
<anchored>
<top parent="columnanchor" anchor="bottom" relation="relative" offset="7" />
<left />
<right />
</anchored>
<class>table_column_headers</class>
<fastinit />
<activate />
</subwindow>

<windowlist name="tablerows">
<anchored>
<top parent="columnanchor" anchor="bottom" relation="relative" offset="2" />
<left offset="5" />
<right offset="-5" />
</anchored>
<datasource>.tablerows</datasource>
<class>table_row</class>
<noscroll />
<sortby><control>fromrange</control></sortby>
<child />
<child><backcolor>1A40301E</backcolor></child>
<script>
function onListChanged()
update();
end
function update()
local bEditMode = (window.table_iedit.getValue() == 1);
for _,w in ipairs(getWindows()) do
w.idelete.setVisibility(bEditMode);
end
end
</script>
</windowlist>
</sheetdata>
</windowclass>


Someday, I will get all this control stuff figured out....

What am I doing wrong?

Minty23185Fresh
November 20th, 2017, 00:32
Just looking at it quickly, there's a lot for the unfamiliar eye to take in. Your setvisible.. Without an object specifier, as in label_iterations.setVisible or self.setVisible ... The onInit is in scope for that label so that seems remote.

The onInit not doing what you think it should do.... To test that, have a function in TableManager.lightItUp() that you call that sets visible. Again remote.

With the above I'm kind of thinking out loud.

The fact you can't see the control when it's not <invisible /> seems key. Today I had my list box completely covering up other controls accidentally. It was all based on those dang <anchored> settings. Your anchor doesn't seem to have enough specification. You have a width but no height. It's not anchored to the frame or anything else, no "relative to" something..

When generic controls are used as anchors, their width and/or height are zero and they're invisible. I found this out by putting
<icon>dot_red</icon> in one and it was invisible until it had height and/or width.

Minty23185Fresh
November 20th, 2017, 00:42
BTW, MoonWizard, your post in this thread, post #8, is flat out some of the best anchored info I have seen. Thank you so much. Yesterday I floundered around with a list box for about six hours. The scratches on top of my head were bleeding. Last night I reread this thread, paying particular attention to post #8 and pow, first thing this morning, I got it pretty close. Well other than completely covering up some other controls. But at least I FELT like I had some control of it!

Bidmaron
November 20th, 2017, 00:46
My second control is screwed up because it has two anchors. But even fixing that there is still nothing showing. Also, I misspelled relation. But I do have height and width in both. Now I get this error when I try to use the controls (and still nothing shows):

Ruleset Error: window: No horizontal anchor defined for control (iterations) in windowclass (table_main)

Minty23185Fresh
November 20th, 2017, 00:47
.... and it was invisible until it had height and/or width.

Don't be nervous about making it big as hell (say 200x200), to start out with. You'll at least know it's there and kind of where it is.

Bidmaron
November 20th, 2017, 00:52
Well, I just realized it won't work anyway because when you edit the table, the space I wanted to use is taken up by the add column, add row, and delete column. Forget the help for now. Have to go back to drawing board....

Minty23185Fresh
November 20th, 2017, 00:55
Ruleset Error: window: No horizontal anchor defined for control (iterations) in windowclass (table_main)

I think every visible control needs anchor information so it knows where it is supposed to be, so to speak. I'm looking at this code on an iPad so be kind... :) . I don't see a control named "iterations" up there. Is there one? I've had malformed XML give me errors like that. Like a missing closing tag. It says the "what cha ma call it" doesn't have this to that, when it's just malform XML

Minty23185Fresh
November 20th, 2017, 01:05
I think every visible control needs anchor information so it knows where it is supposed to be, so to speak. I'm looking at this code on an iPad so be kind... :) . I don't see a control named "iterations" up there. Is there one? I've had malformed XML give me errors like that. Like a missing closing tag. It says the "what cha ma call it" doesn't have this to that, when it's just malform XML

Grabbed my PC... now I see it. misspelling... "realtion="

Bidmaron
November 20th, 2017, 01:40
OK, MW, here is a question for you:

The Rulesets Layering wiki page has this for windowclass merging:

Window Class Merging


When using ruleset layers, window class asset definitions can also be merged or deleted, in addition to the default replacement behavior. To use this feature, the "merge" attribute needs to be specified on a window class asset definition with a value of: merge, join or delete.
When merging window classes, the merging behaves almost identical to the way templates are merged. (See the Ruleset Templates topic for more information on template merging.) The only exception is that the "sheetdata" tag. Any control definitions below the sheetdata tag only match if both the XML child tag matches as well as the name attribute. This allows specific instances of controls to be overriden within a window class definition.
When deleting window classes, the window class definition is simply removed from usage.
If a merge attribute is specified on a window class definition, and no window class with the same name was previously defined, then an error will be thrown.


That description covers merge tags of join and delete but what does the merge tag of 'merge' do because the highlighted section shows the merge tag can have one of three values: merge, join, or delete?

damned
November 20th, 2017, 06:58
Well, I just realized it won't work anyway because when you edit the table, the space I wanted to use is taken up by the add column, add row, and delete column. Forget the help for now. Have to go back to drawing board....

This is the least of your problems.
Make the default and minimum width of the window 50px wider and either anchor the iedit buttons to your new control or 50px further to the right of whatever they are currently anchored too.

damned
November 20th, 2017, 07:01
OK, MW, here is a question for you:

The Rulesets Layering wiki page has this for windowclass merging:

Window Class Merging


When using ruleset layers, window class asset definitions can also be merged or deleted, in addition to the default replacement behavior. To use this feature, the "merge" attribute needs to be specified on a window class asset definition with a value of: merge, join or delete.
When merging window classes, the merging behaves almost identical to the way templates are merged. (See the Ruleset Templates topic for more information on template merging.) The only exception is that the "sheetdata" tag. Any control definitions below the sheetdata tag only match if both the XML child tag matches as well as the name attribute. This allows specific instances of controls to be overriden within a window class definition.
When deleting window classes, the window class definition is simply removed from usage.
If a merge attribute is specified on a window class definition, and no window class with the same name was previously defined, then an error will be thrown.


That description covers merge tags of join and delete but what does the merge tag of 'merge' do because the highlighted section shows the merge tag can have one of three values: merge, join, or delete?

merge will use code from both the initial definition and the updates from the new definition
you do this when you are adding an additional record like you are doing and then you dont have to add the rest of the code in.
from memory i thought the values were merge, replace, delete

damned
November 20th, 2017, 07:02
As minty points out you have a typo in post #16... realtion...

Bidmaron
November 20th, 2017, 14:23
Yes, damned you are right. But the whole architecture won't work. I think I have a solution though and am working it.

Minty, I cut and pasted that right out of the wiki, so those are the attribute values the wiki claims. Again, I just don't know what the heck merge="merge" could possibly mean. Join and delete are adequately explained, but merge is not.

Minty23185Fresh
November 20th, 2017, 17:23
merge="merge" is explained under templates in the wiki.

I searched the unzipped rulesets for merge=" and came up with:
add, delete, join, merge, & replace
all of which are explained in either templates or windows on the wiki

Bidmaron
November 20th, 2017, 18:05
But windowclass merging supports only merge, join, and delete I believe

Minty23185Fresh
November 20th, 2017, 19:43
But windowclass merging supports only merge, join, and delete I believe

Agreed. There is a description of the merge option in templates. I guess merge could do two different things depending on whether it's affects a template or a windowclass. But given the description I think that might not be too hard to verify. I say with skepticism!

Bidmaron
November 20th, 2017, 20:31
Still trying to figure out anchoring and control sizing. Within the table_main.xml file of the CoreRPG ruleset, there is a windowclass definition of table_main. And within that windowclass there is this control definition:


<string_column_full name="description">
<empty textres="table_emptydesc" />
</string_column_full>

Nowhere in there or the tree of inherited templates is the height set. How does FG know how big to make the height of the control?

Minty23185Fresh
November 20th, 2017, 21:12
How does FG know how big to make it?

I can't speak for table_main, and I'm doing this on my iPhone, but for masterindex, it pretty slick. There is a min size for the masterindex windowclass. Then there are three main anchors. One just below the form's title, one just below the list and one at the bottom of the form. The list's bottom anchor is attached to the bottom of the form anchor. The controls just below the list, including the filters are attached to the anchor just below the list. When there are no filters, the bottom of form anchor is really at the bottom of the form and because the list is resizable it fills the form. If there are filters, a lua routine calculates how much room is needed below the list and moves the bottom of form anchor up that much. The list collapses that much and the filters fit below the list and above the bottom of the form.

So what the hell dies this mean for you? Tables are even mor dynamic that a list because they work in two dimensions. As columns are added, it wouldn't surprise me if something similar is going on.

My suggestion: figure out where every control's four anchors are. If the controls (e.g. columns or rows) dynamically change size look for a setAnchor() call (it's a member of windowcontrol).

Moon Wizard
November 20th, 2017, 22:54
For controls, if the width and/or height is not defined, then the width/height will be calculated automatically during the window layout routine. At least one vertical anchor and at least one horizontal anchor is still required, and is thus the minimum necessary for an anchored definition. Additional anchors or specified width/height are optional.

Each control will perform it's automatic width/height calculation differently, based on the type of control it is.


formattedtextcontrol (width defined) - W=Defined width; H=Height necessary to display formatted text within width
numbercontrol (always single line) - W=Width of display string based on font asset; Height of display string based on font asset
stringcontrol (not multiline or width not defined) - W=Width of text string based on font asset; H=Height of text string based on font asset
stringcontrol (multiline and width defined) - W=Defined width; H=Number of lines to fit wrap text within defined with multiplied by multiline height tag value
subwindow - W=0; H=0 (if contained window not instantiated); H=instantiated window height
windowlist - W=0; H=total height of list child windows (each child recalculates layout size based on width of list control)
otherwise - W=0; H=0
(includes buttoncontrol, chatwindow, diecontrol, formattedtextcontrol (no width defined), genericcontrol, imagecontrol, portraitselectioncontrol, scrollbarcontrol, scrollercontrol, tokenbag, tokencontrol, windowreferencecontrol)


Cheers,
JPG

Bidmaron
November 21st, 2017, 05:01
Thanks, MW.

Bidmaron
November 21st, 2017, 05:45
OK, one more, MW or Trenloe or whoever has the controls mastered:

I want a multiline string box that will have a scrollbar (vertical) if it needs it. I checked the character sheet of CoreRPG, and the Notes section of the character sheet has a scroll bar if you fill up the allotted vertical space. That control is a stringu, defined in common.xml as:


<stringfield>
<font>sheettext</font>
<lineoffset default="on" mergerule="replace">1</lineoffset>
</stringfield>


So, I have the following control definition:


<basicstring name="preprocessor">
<empty textres="generator_emptyforward" />
<anchored position="insidetop" offset="-5" height="100"/>
<invisible />
<multilinespacing>20</multilinespacing>
</basicstring>


basicstring is defined in common.xml as:


<template name="basicstring">
<simplestring>
<frame mergerule="replace" name="fielddark" offset="7,5,7,5" hidereadonly="true" />
<stateframe>
<keyedit name="fieldfocus" offset="7,5,7,5" />
<hover name="fieldfocus" offset="7,5,7,5" hidereadonly="true" />
<drophilight name="fieldfocus" offset="7,5,7,5" hidereadonly="true" />
</stateframe>
</simplestring>
</template>


When I fill my control up with a lot of text, there is no scroll bar. What have I done wrong that the scroll bar doesn't materialize when the box fills up vertically?

Minty23185Fresh
November 21st, 2017, 15:39
Are you positive you can have attach a scrollbar to a simple string? All the basic string controls I am familiar with don't have scrollbars. It seems as though they allow multi line text, but don't have that pop up scroll bar. only the formatted text (free form text) fields seem to support it. (e.g. record_story.xml)

Additionally, I think you need to "attach" a scrollbar object to it. I suspect you have done this, I just don't see it there. Is that what "multilinespacing" does?

Bidmaron
November 21st, 2017, 16:05
Let me go back and look at the caharacter page notes. I think you are right that I need to attach a scrollbar

Minty23185Fresh
November 21st, 2017, 16:26
I was looking at a couple of the other CoreRPG library dialogs for small, basic text fields. NPCs has a few on the form. For it, if you put multiple lines of text in a box the box expands to fit it, until it is too tall to fit on the form then a scrollbar for the entire form appears. The scroll bar doesn't appear to be attached to the box itself but to the whole of the windowclass (see record_npc.xml). The individual text controls are basicstrings. So maybe you can't attach a scrollbar to them - I don't know. Personally I'd search the whole ruleset for the type of control you want to use, e.g. basicstring, see what windowclasses and templates it's in then look to see if scrollbars are ever attached to it. (a Hecka-Ton to work, I know!)

Bidmaron
November 21st, 2017, 16:52
Look at the character notes page in the character sheet. That has individual scroll bars on the bottom notes field

Moon Wizard
November 21st, 2017, 19:45
What does your scrollbarcontrol definition look like? Make sure that your scrollbarcontrol is not set to invisible. It will automatically appear/disappear based on the visibility of the control it is targeted to.

It might be easier to post the XML with the window class definition and any templates to get a more comprehensive view.

This is the one from that PC notes:


<scrollbar_list>
<anchored to="notes" />
<target>notes</target>
</scrollbar_list>

Which uses these templates:


<template name="scrollbar_list">
<scrollbar>
<anchored to="list" />
<target>list</target>
</scrollbar>
</template>
<template name="scrollbar">
<scrollbarcontrol>
<anchored position="right" offset="-5,-5" width="20" />
<frame name="scrollbar_base" offset="0,12,0,12" />
<normal name="scrollbutton_normal">
<minimum height="40" />
</normal>
</scrollbarcontrol>
</template>


Regards,
JPG

Bidmaron
November 21st, 2017, 21:19
JPG, i am ashamed to say I am an idiot (i hope this doesn’t offend any real idiots who might be reading this) and did not include the scrollbar. I am guilty of thinking it was somehow magically attached to the template. Sorry. Crawling back to my cave...

Moon Wizard
November 21st, 2017, 21:41
I'm just glad the issue solved itself. ;)

JPG

Bidmaron
November 21st, 2017, 22:43
My other problem here (https://www.fantasygrounds.com/forums/showthread.php?41183-Trying-to-Implement-Control-Resizing) isn't fixing itself though.

Minty23185Fresh
November 22nd, 2017, 01:41
...offend any real idiots who might be reading this...
No worries. I am not in the least offended. And... welcome!
(Our motto: We never recruit. You'll find your way soon enough.)

Bidmaron
November 22nd, 2017, 03:52
Hah! Birds of a feather