StereoKit icon indicating copy to clipboard operation
StereoKit copied to clipboard

Add a `NotifyMode` to `UI.HSlider`

Open paulmelis opened this issue 3 years ago • 8 comments

Describe the feature

This might be a bit too specific of a use case, but I'm looking for a way to determine if a slider is still being grabbed or not at the moment that e.g. HSlider() returns true.

An example use-case

The use case is for a slider value that controls a longer-running (remote) computation of the order of seconds, on-the-fly. I'd like to be able to have a user change the slider value with some precision, but only kick off the computation at the moment the user releases the slider grab, so as not to produce too many unnecessary recomputations while manipulating the slider, but still have reasonably fast updates. I can do it in the current API by starting a timer since the last value change and then force a recomputation after X milliseconds of no change, but it's a bit hacky and error-prone. However, I think adding this feature would not be easy to fit into the current API, as it would require an extra pass-by-ref value signaling the grab state.

paulmelis avatar Mar 07 '22 19:03 paulmelis

I think this one may also fall under #272! I'll definitely make sure this is possible with that as well :)

maluoi avatar Mar 07 '22 20:03 maluoi

A simpler alternative could be something like a NotifyMode that would change how the return value behaves?

maluoi avatar Mar 07 '22 20:03 maluoi

A simpler alternative could be something like a NotifyMode that would change how the return value behaves?

Yes, that's actually a good way of doing it!

Edit: actually, it would still need a 3-state return value (no change, value changed grabbed, value change ungrabbed), as even the value change will still grabbing would be needed.

paulmelis avatar Mar 08 '22 07:03 paulmelis

To expand on the NotifyMode thought:

NotifyMode.Changed would behave like it does now, returning true anytime the value changes. NotifyMode.ChangeComplete would return true when the user has let go of the slider, if the value is different from when it started.

In most cases, simply knowing when the change has finished is enough to avoid performing unnecessary calculations. Knowing when the interaction begins isn't critical here, but might be nice if you're trying to do a low-cost preview or something?

I think NotifyMode.ChangeComplete should cover the common case, and #272 can be used in conjunction with it for the more advanced case. UI.LastElementIsActive() would then be used to show the preview, while the return value would tell it to perform the expensive calculation.

maluoi avatar Mar 08 '22 17:03 maluoi

Okay, that would work, as long as the referenced value is still updated even when false is returned in NotifyMode.ChangeComplete mode. The reason is still wanting to show the current slider value at any moment during interaction.

paulmelis avatar Mar 09 '22 07:03 paulmelis

The cool thing with immediate mode stuff is that that reference value is what's getting displayed as the slider! This actually makes it tricky to do the ChangeCompleted check, as I don't normally have access to the initial value :) I've got a few thoughts about how to do it, but immediate mode GUIs can be tricky!

maluoi avatar Mar 09 '22 08:03 maluoi

Not sure we mean the same thing here, but two remarks :)

With "show the current slider value" I meant using a text label to show the current value to the user, not just through the slider position.

The other this is that changing the slider from an initial value X to say Y (but not letting go) and then back to X and then releasing should also trigger a ChangeComplete in my opinion, so even if the slider value begins and ends at the same value. The letting go is the important trigger, not the specific value (but opinions can differ on this, of course ;-))

paulmelis avatar Mar 09 '22 08:03 paulmelis

With "show the current slider value" I meant using a text label to show the current value to the user, not just through the slider position.

Yeah, this is indeed what I meant. The float that gets passed in is the variable that stores the slider's state, so an external label using that float would update appropriately.

The other this is that changing the slider from an initial value X to say Y (but not letting go) and then back to X and then releasing should also trigger a ChangeComplete in my opinion, so even if the slider value begins and ends at the same value. The letting go is the important trigger, not the specific value (but opinions can differ on this, of course ;-))

That's interesting indeed! I do think that's actually a good idea, but that is something that may depend on the context. I'm not sure if that would be better as two separate NotifyModes, or if it'd be better to just have one and push towards a UI.LastElement API again. Thanks for the clarification here though, that's some good food for thought.

maluoi avatar Mar 09 '22 08:03 maluoi

Better late than never, this is now in v0.3.7-preview.5! I wasn't able to guarantee the value has changed upon finalization, but that may be something I can do in the future.

maluoi avatar Oct 14 '22 22:10 maluoi