5E Character Create Playlist
Page 2 of 3 First 123 Last
  1. #11
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,404
    Glad you found a way forward.
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  2. #12
    Quote Originally Posted by Trenloe View Post
    Glad you found a way forward.
    Just as an FYI - I had to still try and solve finding a control via a window. In the end I could only manage to do it when I had a <script> at the level the controls were defined as that was only place they were automagically added into the window.<control name>. Any other script location this was not done and I never did find out how to grab them when given a window XML was down toward the root of things. I ended up putting the global onInit inside one of the controls because I was able to access lower things in the XML toward the root (below where I was) by simply doing window.parentcontrol.window type of operations.

    Kind of a pain to have to program from the top down, instead of the other way, but I could never solve it starting at window.charsheet.

    Just FYI to round out the information - and if anyone ever can tell how to access things wherever one may be in the window XML chain of things (not the DB - that's easy).
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  3. #13
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,404
    Another issue you're probably be running into is that all of the GUI is not initiated at the time you're running the code.

    See this comment in the subwindow Wiki entry: By default, the windowinstance object will not be instantiated until the control is visible on screen. (See fastinit tag below)

    https://fantasygroundsunity.atlassia...9259/subwindow

    Adding <fastinit /> to the subwindow definition in charsheet:
    Code:
    			<sub_charsheet name="main">
    				<class>charsheet_main</class>
    				<fastinit />
    			</sub_charsheet>
    Makes main.subwindow and (for example, the level control in the main subwindow) main.subwindow.level accessible at the top level.

    For example: in the onInit of the "charsheet" windowclass:

    Code:
    	Debug.console("main = ", main);
    	Debug.console("main.subwindow = ", main.subwindow);
    	Debug.console("main.subwindow.level = ", main.subwindow.level);

    Gives the following when the PC sheet is first opened. Without fastinit main.subwindow is nil.
    Code:
    Runtime Notice: Reloading ruleset
    Runtime Notice: s'main = ' | subwindow = { x,y,w,h = 15,89,0,0 }
    Runtime Notice: s'main.subwindow = ' | windowinstance = { class = charsheet_main, node = charsheet.id-00003, x,y,w,h = 712,329,108,430 }
    Runtime Notice: s'main.subwindow.level = ' | numbercontrol = { value = #0, x,y,w,h = 0,0,0,0 }
    WARNING! I would not make all the charsheet subwindows use <fastinit /> I did this in the PFRPG2 ruleset and had a lot of issues with incorrect data across the subwindows. I'd recommend you put any code within the onInit of the individual subwindows (the windowclasses within the subwindows) and not within the code of the top level window (charsheet in campaign\scripts\char.lua - don't put them here).
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  4. #14
    Quote Originally Posted by Trenloe View Post
    Another issue you're probably be running into is that all of the GUI is not initiated at the time you're running the code.

    See this comment in the subwindow Wiki entry: By default, the windowinstance object will not be instantiated until the control is visible on screen. (See fastinit tag below)

    https://fantasygroundsunity.atlassia...9259/subwindow

    Adding <fastinit /> to the subwindow definition in charsheet:
    Code:
    			<sub_charsheet name="main">
    				<class>charsheet_main</class>
    				<fastinit />
    			</sub_charsheet>
    Makes main.subwindow and (for example, the level control in the main subwindow) main.subwindow.level accessible at the top level.

    For example: in the onInit of the "charsheet" windowclass:

    Code:
    	Debug.console("main = ", main);
    	Debug.console("main.subwindow = ", main.subwindow);
    	Debug.console("main.subwindow.level = ", main.subwindow.level);

    Gives the following when the PC sheet is first opened. Without fastinit main.subwindow is nil.
    Code:
    Runtime Notice: Reloading ruleset
    Runtime Notice: s'main = ' | subwindow = { x,y,w,h = 15,89,0,0 }
    Runtime Notice: s'main.subwindow = ' | windowinstance = { class = charsheet_main, node = charsheet.id-00003, x,y,w,h = 712,329,108,430 }
    Runtime Notice: s'main.subwindow.level = ' | numbercontrol = { value = #0, x,y,w,h = 0,0,0,0 }
    WARNING! I would not make all the charsheet subwindows use <fastinit /> I did this in the PFRPG2 ruleset and had a lot of issues with incorrect data across the subwindows. I'd recommend you put any code within the onInit of the individual subwindows (the windowclasses within the subwindows) and not within the code of the top level window (charsheet in campaign\scripts\char.lua - don't put them here).
    Thanks - they already did (having started them from some ruleset code that already did that not through any foreknowledge on my part).

    Everything I wanted in regards to making space and putting something in there on host, while only doing if a buttoncontrol is active on the player - works 'mostly'. My current issue is trying to figure out how to get the player sheets to react to the button press on the host without having to close them down and bring them back up (essentially force a refresh of the sheet).

    I'm about to start looking at that, so if you happen to know a quick way to refresh a window so it "sees" what is currently in the DB (in this case setting of buttoncontrol maintains a status in my personal XML tag section of the sheet DB that needs to be respected), let me know.

    But really I'm just starting to look - hoping its not some elaborate DB.hanlder or something I have to watch in both places - I'm looking for "magic" and "easy"
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  5. #15
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,404
    You'll need to use a field in the DB that the GM side can update and that the player side can get an onUpdate event triggered. If the state of the button press on the GM side is stored in the database this could be that field.

    Usually you'll use DB.addHandler on the player side to register and onUpdate event handler. https://fantasygroundsunity.atlassia.../DB#addHandler

    Search in the 5E ruleset files for DB.addHandler to see plenty of examples.
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  6. #16
    Quote Originally Posted by Trenloe View Post
    You'll need to use a field in the DB that the GM side can update and that the player side can get an onUpdate event triggered. If the state of the button press on the GM side is stored in the database this could be that field.

    Usually you'll use DB.addHandler on the player side to register and onUpdate event handler. https://fantasygroundsunity.atlassia.../DB#addHandler

    Search in the 5E ruleset files for DB.addHandler to see plenty of examples.
    So no magic then. Ok, I already know how to do that as I've done that in other extensions - was hoping there was some bit of arcane stuff I was unaware of that just "did it for me".

    Though I'm not sure I ever done the "onUpdate" when i've dealt with DB handlers. Assuming that is is just something hooked into the low level of the window - but I'll search for examples - thanks again!

    [Oh that onUpdate I've definitely used thats just part of the handler. I'm looking for something to force the sheet to be redisplayed - unless that somehow does it?]
    Last edited by SilentRuin; July 10th, 2020 at 16:28.
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  7. #17
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,404
    onUpdate will just raise an event - you'll need to trigger the GUI update within code that gets triggered by that event.

    If the GM view and the player view are the same, and something gets done on the GM side when a button is pressed, and you want that to happen on the player side as well, then try to write your code that is attached to events that will happen on both sides. For example, tie the button state to a database field (use a buttonfield not a buttoncontrol) and then run code against onValueChanged not onButtonPressed - because onButtonPressed will only run on the side that pressed the button.
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  8. #18
    Quote Originally Posted by Trenloe View Post
    onUpdate will just raise an event - you'll need to trigger the GUI update within code that gets triggered by that event.

    If the GM view and the player view are the same, and something gets done on the GM side when a button is pressed, and you want that to happen on the player side as well, then try to write your code that is attached to events that will happen on both sides. For example, tie the button state to a database field (use a buttonfield not a buttoncontrol) and then run code against onValueChanged not onButtonPressed - because onButtonPressed will only run on the side that pressed the button.
    Probably not expressing myself correctly. I have no issues with understanding onValueChanged vs onButtonPressed as I learned by "trial by fire" in designing my last extension. I also understand DB.addhandler and my function I kick off from it for the same reason (burned till I learned last time).

    My issue is - when I'm popping into my callback - I need to insure the window itself, is redrawn. Physically redone. So far the current rabbit hole I'm down has me looking at trying to do the following in the callback where I'm trying to see how findWindow() works (no luck). Below is an example of my attempts to find the charsheet window sitting right under my face (no luck in syntax - doing something stupid).

    Code:
    	local nodeChar = DB.getChild(nodeActive, "...");
    	Debug.console(nodeChar); -- something like charsheet.id-00001
    
    	local w = Interface.findWindow("charsheet", nodeChar);
    	Debug.console(w); -- nil
    
    	local w = Interface.findWindow(nodeChar.getNodeName(), "charsheet"); 
    	Debug.console(w); -- nil
    
    -- other failed tries with findWindow()
    I see lots of examples in code where this is working but I'm doing something stupid or not understanding the context. IF I can find the window sitting right in front of my face on the screen, then I can do something like this (I hope) to refresh the screen.

    Code:
    w.close();
    
    	local wRefreshed = Interface.openWindow("charsheet", nodeChar);
    	Debug.console(wRefreshed);
    I actually tried to just use the openWindow() and it worked just fine bringing it up (or returning wRefreshed if already up). Which got me down another rabbit hole involving why it was not going through the onInit() code I had to add of one of my controls - which will probably result in moving that back to the windowclass containing them using

    Code:
    function onSubwindowInstantiated()
    -- do stuff like I did in onInit() of control
    end
    WHICH of course gets me FULL CIRCLE back into trying to access the window controls via window.... syntax.

    I suspect some of the magic of adding window.[control_name] logic is messing me up because I'm doing something stupid - but at this point I'm down one to many rabbit holes.

    Learning lots - but ugh... I feel like I'm going around in circles slowing coming into some sort of solution which I've not found yet.

    That's the best I can explain it.
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  9. #19
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,404
    Recheck the Wiki documentation on script scope: https://fantasygroundsunity.atlassia...pt-Block-Scope

    Specifically "parentcontrol" - search for that in the 5E ruleset and see how it's used to navigate up the GUI hierarchy.

    And, always remember where you're running code. Your idea of w.close and then re-opening the window won't work if your code is running in the window - because closing the window will close that script block scope. And closing something like the character sheet and re-opening just to refresh is very inefficient, especially for complex window hierarchies like the character sheet.

    To take a step back from this... Good GUI design has the controls sourced on database fields. Unless the GUI state is temporary and doesn't need to be maintained across system restarts, or across instances. If you're dynamically building the interface, which I believe is what you're doing, then you'll need to have event handlers that trigger when something changes that results in updates being needed. If you have these event handlers at the GUI hierarchy level where you want to run code, then accessing the GUI structure through should be simplified.
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  10. #20
    Quote Originally Posted by Trenloe View Post
    Recheck the Wiki documentation on script scope: https://fantasygroundsunity.atlassia...pt-Block-Scope

    Specifically "parentcontrol" - search for that in the 5E ruleset and see how it's used to navigate up the GUI hierarchy.

    And, always remember where you're running code. Your idea of w.close and then re-opening the window won't work if your code is running in the window - because closing the window will close that script block scope. And closing something like the character sheet and re-opening just to refresh is very inefficient, especially for complex window hierarchies like the character sheet.

    To take a step back from this... Good GUI design has the controls sourced on database fields. Unless the GUI state is temporary and doesn't need to be maintained across system restarts, or across instances. If you're dynamically building the interface, which I believe is what you're doing, then you'll need to have event handlers that trigger when something changes that results in updates being needed. If you have these event handlers at the GUI hierarchy level where you want to run code, then accessing the GUI structure through should be simplified.
    Yeah, those script blocks are what are killing me.

    If I have a windowclass with a script in it - and simply call down into a function from it like the below example:

    XML file
    Code:
        <windowclass name="blah">
               <script>
                      function onInit()
                            MyStuff.InitThisThing()
                      end
               </script>
    The the InitThisThing code will have no access to getDatabaseNode() or any of the script block control names. Yet if I do this:

    Code:
        <windowclass name="blah">
               <script>
                      function onInit()
                            MyStuff.InitThisThing(getDatabaseNode(), MyControlName)
                      end
               </script>
    Then magically I can access it. Yet I have no window available at all here like I do in a buttoncontrol script where I can just pass that in and get access to whatever I want. At the windowclass I literally have to pass everything I want access to into it.

    I feel I'm missing something basic - but this seems to be the only way to get access to things at this level.

    My code currently has the source coded to the controls - but you seem to forget I don't want those controls seen - nor do I want the gap I've created there - when the button is not active. Sure its in the host always - but on player side this is just normal old character sheet - until button hits and everything changes. To get that change instantly on the DB button update is what I'm missing - everything else works.

    Having the anchor points reset and the visibilitly of my window controls reset is the goal. All at once. Which requires code to trigger that can call each of those things - which is where my trouble is (well, until I just discovered what I found above - which I've not worked through the implications of yet).

    Gist being - its very confusing on when things are available in script block and when they are not.
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Starfinder Playlist

Log in

Log in