PDA

View Full Version : Coding Question



Bidmaron
March 16th, 2014, 05:47
I have a situation where I need to pass a value from a script in one window class (call it topclass) to a script in a window class subordinate to the first one (call it bottomclass) (e.g. a sub window). This value must not be in the campaign or other database.

Alternatively, if the above cannot be done, I need to be able to call a script (call it getMyValue()) residing in the topclass script block from a script in the bottomclass script block. If it were a control script, it would be easy, as I could just use the special "window" variable to get to things within the parent, including script functions. But there isn't such a defined variable in a sub window.

Does anyone know how to do either of these things?

Nickademus
March 16th, 2014, 09:18
You can always cheat. An extension has a global object. Put the value in a variable on the extension object and grab it again in the subordinate window script.

Bidmaron
March 16th, 2014, 12:57
Yeah, I thought about that, but the problem is that a new window will overwrite that global, and the original window when it needs to get the value won't have a way to get the correct value set by its initialization code. If windows had an 'onActivate' event, that would be what I'd have already done, but there is no such event....

But you got me thinking, Nickademus. The only time I need the value is at initialization and when the interface items driving the determination of that value change. So, if I capture those changes in an event and recompute the value, then using a global should work. Cheesey, but what the heck!

Moon Wizard
March 16th, 2014, 19:45
There are two ways I do this, depending on the situation.

* Drill-down: Capture the value change at the top level, then navigate the control/window structures down to the point where other controls/windows need to be updated. (Ex: Ability score changes in 3.5E/4E impact all weapon and power entries.) I use this approach when there are many subrecords to update.
* Event-driven: Register a DB event handler for when a given DB node path updates in the control that needs to change. (Ex: Name changes, etc.) I use this approach when ony a few controls are affected, as it's more contained code-wise.

Regards,
JPG

Bidmaron
March 17th, 2014, 01:04
JPG, the problem with approach 1 is that I need to drill up. The change occurs to a control within a sub window (not a DB field), and the change impacts display of data in a sister sub window. I don't think there is a way to drill up.

The problem with approach #2 is that the change is to a control, not a field, so there is no event to capture (or so I believe).

Unless you know of a more elegant solution, I am using the kludge Nickademus suggested. I think it's safe, as I don't need to sample the value unless the value has changed (which I detect in the control and store in the global) or upon initialization. Since the application isn't threaded, I don't think there is a danger of the global being overwritten by a simultaneous process.

Moon Wizard
March 17th, 2014, 03:59
You can always navigate up, then down. You just need to traverse subwindow/parentcontrol and windowlist/children, and window/control structures.

Cheers,
JPG

Bidmaron
March 17th, 2014, 04:04
Sorry to be a rock, JPG, but the only way I can figure out how to go up in control hierarchy is using findWindow. Of course, if you have a control, window gets you to the parent, but I can't figure out how to navigate up beyond the window to the parent window. I'm sure I'm rocking out and it's simple. Right now, I'm using findWindow to get the parent window, but the problem with that is that the control must know the class of the parent, and I'm trying not to build in dependencies like that.

Trenloe
March 17th, 2014, 04:15
Sorry to be a rock, JPG, but the only way I can figure out how to go up in control hierarchy is using findWindow. Of course, if you have a control, window gets you to the parent, but I can't figure out how to navigate up beyond the window to the parent window. I'm sure I'm rocking out and it's simple. Right now, I'm using findWindow to get the parent window, but the problem with that is that the control must know the class of the parent, and I'm trying not to build in dependencies like that.
What is your window/subwindow structure?

Bidmaron
March 17th, 2014, 04:31
Here is the file: 6274.
If you search for findWindow, that is where I'd like to walk up the window chain back to the reference feat parent (but I don't want to build in this dependency, as it might be a child in any library class).

Thanks for the help, JPG.

Trenloe
March 17th, 2014, 04:55
Here is the file: 6274.
If you search for findWindow, that is where I'd like to walk up the window chain back to the reference feat parent (but I don't want to build in this dependency, as it might be a child in any library class).
Just to clarify here - you are trying to find a completely separate, stand-alone window instance? That is, a completely separate window that has been launched from a link? This is not a subwindow in FG terms - a subwindow is a window within a window, see the charsheet for an example of a subwindow. If it is a completely separate window, then you can't using the "window.", "subwindow." or similar commands to traverse the GUI hierarchy as the "referencefeat" window is actually a top level window - as described in the Interface.findWindow API description: "Finds a top level window or panel by its windowclass and datasource." - it is a top level window, not a subwindow or child of another window.

What are you trying to do with the code in your extension?

Bidmaron
March 17th, 2014, 05:00
Referencefeat has two sub windows: ref_feat_header and ref_feat_stats. I need to be able to walk up to the reference feat window from the two sub windows, and the only way I can figure out how to do that is findWindow. As I said, that builds in a dependency I don't want, as the code will ultimately be encapsulated for use in any library module editing code for reuse and ease of maintenance. Search for findWindow; there is only one, and you will see what I am attempting to do right under the findWindow.

Trenloe
March 17th, 2014, 05:37
Sorry, I think I've been up too long today - try using window.parentcontrol.window to give you the windowinstance of referencefeat from the "button_record_lockedit" control.

The hierarchy is:

button_record_lockedit.window = "ref_feat_header" windowclass.
ref_feat_header.parentcontrol = "header" subwindow.
header.window = the containing window of the "header" subwindow = "referencefeat"

So, in your code, substitute masterWindow=Interface.findWindow("referencefeat",window.getDatabaseNode().getNodeName()); with masterWindow=window.parentcontrol.window;

A bit of info about the parentcontrol variable withing the subwindow element here: https://www.fantasygrounds.com/refdoc/subwindow.xcp

Bidmaron
March 17th, 2014, 09:17
Thanks, Trenloe. That information in the link would be even more helpful in the "Windows and Controls" section of the Ruleset Modification Guide, where it discusses the window and sub window variable but not the parent control variable. I would never have had this question if that information had been there (as I knew about sub window and window, as you can see from the extension).

Willot
March 17th, 2014, 12:28
ah coding.. my old friend. Have I missed you? Perhaps Not...

Bidmaron
March 17th, 2014, 17:15
Here's another one. All over the place in scripts, there is an onValueChanged() function. I'm thinking this is an event that is missing in the windowControl documentation? It seems to work where I've used it, but I'm danged if I can find where it's documented.

Trenloe
March 17th, 2014, 17:25
Here's another one. All over the place in scripts, there is an onValueChanged() function. I'm thinking this is an event that is missing in the windowControl documentation? It seems to work where I've used it, but I'm danged if I can find where it's documented.
https://www.fantasygrounds.com/refdoc/stringcontrol.xcp#onValueChanged

https://www.fantasygrounds.com/refdoc/numbercontrol.xcp#onValueChanged

Nickademus
March 17th, 2014, 17:27
Trenloe, the search-fu ninja. :ninja:

Bidmaron
March 17th, 2014, 18:30
Thanks, again. Trenloe, are you just searching from the FG home page to come up with these?
So, it appears that buttonControls, scrollbarControls, scrollerControls, and formatted text controls are the only controls without an onValueChanged event. I think formattedtextcontrol should have the onValueChanged function listed in the documentation, as the function is used in several places in the rulesets.
So, assuming that is an oversight, only scroll thingies and buttonControls (which have a buttonClicked event anyway) are the only things missing onValueChanged events. That seems workable and reasonable.

New question:
It appears to me that during the game, the GM owns the character sheets. Any changes the player makes on his local character sheet copy are then echoed to the GM's master. Do I have that right?

Moon Wizard
March 17th, 2014, 20:29
Not all window controls have an associated value object. Those that do have a value fire an onValueChanged event when the underlying value object is changed. Value objects can be tied to a database node (i.e. stringfield, numberfield, ...) or just to the control (i.e. stringcontrol, numbercontrol, ...).

Controls that have values: buttoncontrol, diecontrol, formattedtextcontrol, numbercontrol, stringcontrol, tokencontrol, windowreferencecontrol
Controls that do not have values: categoryselectioncontrol, chatentry, chatwindow, genericcontrol, portraitselectioncontrol, scrollbarcontrol, scrollercontrol, subwindow, tokenbag

I just updated the buttoncontrol and formattedtextcontrol documentation pages, since that event was missing there. They were added in v3.0.0.

Regards,
JPG

Moon Wizard
March 17th, 2014, 20:32
The GM is the master database for the campaign. Each record (i.e. XML tree) within the database may be optionally "owned" or "shared" by a player. Each record can only have one owner. Any owned or shared records are viewable by players. Any owned records can be edited by players. Any edits are replicated to the host machine.

Regards,
JPG

Bidmaron
March 17th, 2014, 20:47
Thanks for both, JPG!

Bidmaron
March 18th, 2014, 03:16
Am I going insane or are the getValue() and setValue() calls for controls missing all of a sudden in the documentation?

Nickademus
March 18th, 2014, 03:40
First control in the list, buttoncontrol, has both. So not 'all' are missing. Which control are you looking at?

Bidmaron
March 18th, 2014, 03:44
Well, I think every control has a value and it should be on windowcontrol, the parent of all controls.

Bidmaron
March 18th, 2014, 03:48
Well, I guess some controls don't have values. Anyway, all the ones you normally want to look at have them. Sorry, getting late, and I came down with something on my trip to New England last week. Top of my head feels like it's about to blow off.

Trenloe
March 18th, 2014, 05:53
Well, I think every control has a value and it should be on windowcontrol, the parent of all controls.
JPG specifically lists all controls that have a value in post #19 in this very thread.

Bidmaron
March 19th, 2014, 01:12
WEll, I'd like to plead my illness, but I just have to admit the truth: as my Dad says, I don't have Alzheimers but I do have part-heimers. My memory was not that great to start with and it hasn't aged any better. I did qualify that post with "was I going insane" - maybe that's it.