Board index FlightGear Development New features

GUI dialog: slider and setlistener

Discussion and requests for new features. Please note that FlightGear developers are volunteers and may or may not be able to consider these requests.

GUI dialog: slider and setlistener

Postby legoboyvdlp » Wed Jan 16, 2019 3:34 pm

I'm attempting to fix a bug in Advanced Weather - to do so, I need to reload AW with new settings when the user moves a slider in the rendering dialog. A setlistener on the property works - but it fires while the slider is moving (i.e. when you drag the slider). How can I make it only fire when the user stops moving the slider, i.e. when they release the slider after dragging it?
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: GUI dialog: slider and setlistener

Postby Isaak » Wed Jan 16, 2019 4:49 pm

maybe you could use a function that activates with the setlistener on the base property and loops every 0.5 second to check if the the previous value is the same as the current value of the base property. When it detects that the slider has stopped moving (the previous value is the same as the current), we can asume that the user has stopped sliding and the function can modify a second property that triggers the weather reset via a second setlistener. It 's not completely fool proof, e.g. when the user still holds the slider but pauzes the movement, the weather will reset already, but I think that waiting 0.5 seconds should be enough, because waiting longer can feel too slow.
Want to support medical research with your pc? Start Folding at Home and join team FlightGear!
Isaak
 
Posts: 768
Joined: Sat Jun 04, 2011 3:52 pm
Location: Hamme, Belgium
Pronouns: he, him
Callsign: OO-ISA
Version: next
OS: Windows 10

Re: GUI dialog: slider and setlistener

Postby wkitty42 » Wed Jan 16, 2019 5:02 pm

@lego: the same thing happens in the new static-lod.xml dialog file, too... you move the sliders and the function updates the screen (descriptive distance text in the table)... i'm not sure exactly how you would do it so the refresh only happens after the slide stops but i think you are on the right track...
"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up."
"Why not?" said Gurder.
"Dunno. It's frightened of heights, I guess."
User avatar
wkitty42
 
Posts: 9148
Joined: Fri Feb 20, 2015 4:46 pm
Location: central NC, USA
Callsign: wk42
Version: git next
OS: Kubuntu 20.04

Re: GUI dialog: slider and setlistener

Postby Hooray » Wed Jan 16, 2019 6:13 pm

actually, just don't do it this way - it's kinda problematic to potentially call a Nasal callback that way, especially because you may not know whether the previous instance has finished already or not.

It is much better/cleaner to separate things, and use dedicated fgcommands or controls (buttons) in the form of "ok" or "apply".

Using a listener like this directly to invoke the callback is begging for trouble.

Obviously, Thorsten would be in the best position to tell if it's supposed to be safe to invoke the callback that way, but I would never do it that way, unless it's not actually doing anything "directly", i.e. if all it is doing is stopping/restarting a maketimer object.

Otherwise, it's really begging for trouble
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: GUI dialog: slider and setlistener

Postby wlbragg » Wed Jan 16, 2019 7:24 pm

What about catching the mouse up event in the code block that the listener is executing?
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: GUI dialog: slider and setlistener

Postby legoboyvdlp » Wed Jan 16, 2019 8:39 pm

Wlbragg, how exactly would I do that? Thanks
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: GUI dialog: slider and setlistener

Postby wlbragg » Thu Jan 17, 2019 1:19 am

I don't know for sure that it will work, but maybe?
This is a bit of code from the AirCrane that listens for a shift left click and also a ctrl left click (for example of catching the event).
I'd have to look at the slider code to have any idea about adapting any of this to it.
But maybe this will give you some ideas.
Code: Select all
 # firebug fire starter ctrl+shift+leftmouseclick
  setlistener("/sim/signals/click", func {
     if (__kbd.shift.getBoolValue()) {
        var click_pos = geo.click_position();
        if (__kbd.ctrl.getBoolValue()) {
           wildfire.ignite(click_pos);
        } else {
           #wildfire.resolve_foam_drop(click_pos, 50, 1);
        var aic = getprop("/sim/gui/dialogs/aicargo-dialog/ai-path");
        if (aic != nil) {
          var pos_lat = click_pos.lat();
          var pos_lon = click_pos.lon();
          var click_alt = geo.elevation(click_pos.lat(), click_pos.lon()) * 3.28;
          var alt_offset = getprop("/models/cargo/"~aic~"/elev-offset");
          setprop("/models/cargo/"~aic~"/latitude-deg", pos_lat);
          setprop("/models/cargo/"~aic~"/longitude-deg", pos_lon);
          setprop("/models/cargo/"~aic~"/elevation-ft/", click_alt + alt_offset);
          setprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_lat", pos_lat);
          setprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_lon", pos_lon);
          setprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_alt", click_alt + alt_offset);
          setprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_head", getprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_head"));

          if (getprop("/sim/gui/dialogs/aicargo-dialog/save")) {
            var cargo = getprop("/sim/gui/dialogs/aicargo-dialog/selected-cargo");
            setprop("/sim/model/aircrane/"~cargo~"/saved", 1);
            setprop("/sim/model/aircrane/"~cargo~"/position/latitude-deg", getprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_lat"));
            setprop("/sim/model/aircrane/"~cargo~"/position/longitude-deg", getprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_lon"));
            setprop("/sim/model/aircrane/"~cargo~"/position/altitude-ft", getprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_alt"));
            setprop("/sim/model/aircrane/"~cargo~"/orientation/true-heading-deg", getprop("/sim/gui/dialogs/aicargo-dialog/selected_cargo_head"));
            aircraft.data.add("/sim/model/aircrane/"~cargo~"/position/latitude-deg",
                              "/sim/model/aircrane/"~cargo~"/position/longitude-deg",
                              "/sim/model/aircrane/"~cargo~"/position/altitude-ft",
                              "/sim/model/aircrane/"~cargo~"/orientation/true-heading-deg");
            aircraft.data.save();
          }
        } else {
          gui.popupTip("No Cargo Selected, first select cargo to move in the AirCrane's Cargo Menu", 3);
        }
        }
     }


Also, there is the release binding. Don't know if you can use that with the slider?
Code: Select all
<action>
            <binding>
                <command>property-adjust</command>
                <property>/fdm/jsbsim/systems/rms/direct-drive-switch</property>
                <factor>1</factor>
                <min>-1</min>
                <max>1</max>
                <wrap>false</wrap>
            </binding>
            <binding>
                <command>nasal</command>
                <script>SpaceShuttle.click("avionics")</script>
            </binding>
        </action>
        <release>
            <binding>
                <command>property-assign</command>
                <property>/fdm/jsbsim/systems/rms/direct-drive-switch</property>
                <value>0</value>
            </binding>
        </release>
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: GUI dialog: slider and setlistener

Postby Hooray » Thu Jan 17, 2019 1:22 am

Really, you don't want to do this. Even if you can make it work, it's unlikely to yield the result that you want.
If in doubt, please coordinate this with Thorsten - simply because you are talking about Advanced Weather, and explicitly or not, the underlying code must be structured with a certain reset/re-init approach in mind. If you are using a different one, you will have to deal with those hard-coded assumptions - regardless of the UI you are using.

In other words, while you may have a hard time getting this done via PUI, it is obviously trivial to do via Canvas, Qt and/or Phi (JavaScript), but the approach still is problematic - unless the person who wrote the code in question tells you exactly how the code wants to be re-initialized or how certain values can be updated.

Again, even unrelated to Nasal and unrelated to the Advanced Weather system, the back-end must be designed with such "live updates" in mind - keep in mind that you talk about reloading Advanced Weather, which is is about doing much more than just updating a single property, there are several "subsystems" in the form of timers scheduling different tasks, even spread across several frames - in other words, you may be screwing up the scheduling mechanism by dragging a slider and firing a listener along the way to invoke an AW calback that was never designed with this usage pattern in mind.

You should really shouldn't be pursuing this approach unless Thorsten tells you specifically that you can indeed do it this way - personally, I would be rather surprised seeing this used, and like I said would much rather use a timer object to suspend all activity and restart it using an offset - otherwise, you are literally begging for trouble by using Nasal and listeners to fire callbacks via a slider to reload whole subsystems - potentially several times per second.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: GUI dialog: slider and setlistener

Postby legoboyvdlp » Thu Jan 17, 2019 1:35 am

I'm not exactly sure if you looked at my post - I'm adapting an existing dialog , not proposing to replace the entire menubar with QT, Canvas, or anything else just to fix one bug ;) and Advanced Weather as far as I am aware is not a subsystem, so unrelated to reset / reinit..?

I would expect what reloads AW 'properly' in the weather dialog also does it 'properly' in the rendering dialog.

Regardless, thanks for your attempts to help - I'll bear it in mind.


Wlbragg, thanks for the snippets - I'll take a look tomorrow morming.
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: GUI dialog: slider and setlistener

Postby Hooray » Thu Jan 17, 2019 2:18 am

legoboyvdlp wrote in Thu Jan 17, 2019 1:35 am:I'm not exactly sure if you looked at my post

Likewise, I am pretty sure that you didn't look at what I wrote ..

legoboyvdlp wrote in Thu Jan 17, 2019 1:35 am:I'm adapting an existing dialog , not proposing to replace the entire menubar with QT, Canvas, or anything else just to fix one bug ;)

right, I understand all of that.
That is exactly why I posted, that what I posted.

I mentioned Qt, Canvas and Phi for the simple reason that you asked for the equivalent of a "mouse-up" event on the slider.
While also pointing out that even if there was such a mechanism in place (that is in PUI) it still would not be safe to assume that this could be used "as is" without first checking back with Thorsten.

legoboyvdlp wrote in Thu Jan 17, 2019 1:35 am:and Advanced Weather as far as I am aware is not a subsystem, so unrelated to reset / reinit..?

Sort of right: Advanced Weather is certainly not a SGSubsystem, but it's still grown to be more complex than many other systems, despite being written in Nasal - it ends up using different loops to do different things, in conjunction with timers.

So while this is indeed unrelated to reset/re-init, you yourself used the terms "reload AW", which implies stopping/suspending and restarting the system.

Subsequently, you mentioned your intention to use a slider-bound callback to invoke the corresponding Nasal callback.
I tried to point how this is unlikely to do what you want, unless Thorsten himself confirmed that this is indeed how you can do, but that even then, I would not expect such a mechanism from an UX perspective, and it would still be problematic for other reasons, e.g. I mentioned already loops that may still be running.

legoboyvdlp wrote in Thu Jan 17, 2019 1:35 am:I would expect what reloads AW 'properly' in the weather dialog also does it 'properly' in the rendering dialog.

Right, which is why I suggested to check back with Thorsten - or if in doubt, simply open the corresponding PUI/XML dialog and look at the mechanism used there, if that is indeed a slider, I would be totally surprised - but then you should be free to proceed.

What I would expect to find is a concrete set of controls to apply/restart the system, and not some obscure slider triggering all sorts of background behavior, possibly dozens of times per second - that would be problematic for a plethora of reasons, totally unrelated to Nasal or Advanced Weather.

Again, believe me, I absolutely understand what you are trying to do, all of my responses were based on this understanding. What I don't recommend doing is using a slider in conjunction with Nasal callbacks that are invoked "on-update" or "on-mouseup" unless Advanced Weather is indeed prepared to be restarted in such an aggressive/inter-active fashion.

In other words, your proposed approach of using a slider and a callback would break most Nasal scripts, certainly those not supporting reset/re-init, especially the more complex ones.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: GUI dialog: slider and setlistener

Postby wlbragg » Thu Jan 17, 2019 4:02 am

@legoboyvdlp
Doesn't the "OK" button activate the AW reset?
Why do you want it on the fly with the slider, because you think it needs to be seen as you scroll the slider, so you can judge if it is set where you want it?
I ask because even if the mouse up event were to trigger the reset, wouldn't it basically act the same as if you hit the OK button?
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: GUI dialog: slider and setlistener

Postby wlbragg » Thu Jan 17, 2019 4:07 am

Hum, not what I thought at all, Is changing the "Cloud Density" slider and hitting OK actually shutting off AW? Then you have to go into weather and apply again?
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: GUI dialog: slider and setlistener

Postby wlbragg » Thu Jan 17, 2019 4:56 am

The more I look at that slider and what it should be doing, the more I am thinking it needs to be in the "Weather" dialog and not the "Rendering" dialog as there is a whole bunch of things that need to take place to get the correct reset and they are all available and active in the "Weather" dialog and not in the "Rendering" dialog.
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: GUI dialog: slider and setlistener

Postby Octal450 » Thu Jan 17, 2019 6:14 am

BE CAREFUL!
I tried using setlisteners on PUI stuff when I made my AUTOPILOT-V for the 727... it doesn't work reliably. Better to just add a binding to the slider calling a function.

Kind Regards,
Josh
Skillset: JSBsim Flight Dynamics, Systems, Canvas, Autoflight/Control, Instrumentation, Animations
Aircraft: A320-family, MD-11, MD-80, Contribs in a few others

Octal450's GitHub|Launcher Catalog
|Airbus Dev Discord|Octal450 Hangar Dev Discord
User avatar
Octal450
 
Posts: 5583
Joined: Tue Oct 06, 2015 1:51 pm
Location: Huntsville, AL
Callsign: WTF411
Version: next
OS: Windows 11

Re: GUI dialog: slider and setlistener

Postby legoboyvdlp » Thu Jan 17, 2019 4:27 pm

I wonder is this an improvement? It's removing the listener and reloading AW only when you close the dialog. :?:
By enclosing the listener in if{} tags, it should be only creating it if AW is loaded in the first place?
Code: Select all
<open>
      setprop("/sim/gui/dialogs/rendering/3d-clouds-density-changed", 0);
      
      if (getprop("/nasal/local_weather/loaded")) {
         var clouds3DdensityListener = setlistener("/sim/rendering/clouds3d-density", func() {
            if (getprop("/sim/gui/dialogs/rendering/3d-clouds-density-changed") == 0) {
               setprop("/sim/gui/dialogs/rendering/3d-clouds-density-changed", 1);
            }
         }, 0, 0);
      }
      </open>
      
      <close>
      <![CDATA[
         if (getprop("/sim/gui/dialogs/rendering/3d-clouds-density-changed") and getprop("/nasal/local_weather/loaded")) {
            # Clear any active local weather
            local_weather.clear_all();
            setprop("/nasal/local_weather/enabled", "false");
          
         
            # If Local Weather is enabled, re-initialize with updated
            # initial tile and tile selection.
            setprop("/nasal/local_weather/enabled", "true");

            # Re-initialize local weather.
            settimer( func {local_weather.set_tile();}, 0.2);
                 removelistener(clouds3DdensityListener);
         }
         
      ]]>
      
      </close>



Wlbragg,
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Next

Return to New features

Who is online

Users browsing this forum: No registered users and 6 guests