Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

global ImGui::hasChanged() ? #1049

Closed
benblo opened this issue Mar 2, 2017 · 2 comments
Closed

global ImGui::hasChanged() ? #1049

benblo opened this issue Mar 2, 2017 · 2 comments

Comments

@benblo
Copy link

benblo commented Mar 2, 2017

I'm looking for a feature similar to Unity's GUI.changed, which allows to track if any widget was clicked/modified so far (button clicked, checkbox toggled, field modified, etc). I know ImGui widgets return the "changed" value as their return value, I'm looking for a global state.
What's nice about GUI.changed is you can track a whole block of widgets (using begin/end stacks) without checking every single one (so you can eg dirtify an object if any of its fields is touched).
I couldn't find anything like it in ImGuiIO, and a quick look at ButtonBehaviour didn't reveal anything that seemed relevant... am I missing something?

So far I have mixed feelings about either API styles.
dear imgui-style:

// simple
ImGui::SliderInt(label, &value, 0, 10);

// advanced
if (ImGui::SliderInt(label, &value, 0, 10))
{
  // value has been modified already, but now you can react to the change
  ...
}
// or, I guess:
int newValue = value;
if (ImGui::SliderInt(label, &newValue, 0, 10))
{
  // validate etc
  value = newValue;
}

// block of properties
bool changed;
changed |= ImGui::SliderInt("some int", &someInt, 0, 10);
changed |= ImGui::Checkbox("some bool", &someBool);
// carry the changed flag around if you have nesting etc
if (changed)
{
  ...
}

Unity-style:

// simple
value = GUI.Slider(label, value, 0, 10);

// advanced
int newValue = GUI.Slider(label, value, 0, 10);
if (newValue != value) // or check GUI.changed change
{
  // validate etc
  value = newValue;
}

// block of properties
BeginChangeCheck();
someInt = GUI.Slider("some int", someInt, 0, 10);
someBool = GUI.Checkbox("some bool", someBool);
// nesting handled automatically
if (EndChangeCheck())
{
  ...
}

Both styles have their pros & cons. ImGui is more terse (or probably more efficient, only writing to variables when they changed), Unity doesn't touch variables directly (and is compatible with get/set property accessors, but that's a C# specificity), and makes it easier (IMO) to track/validate.
Obviously I can wrap dear-style to Unity-style, but then I lose the "changed" return value. Or, I have to handle it in my wrapper smarter, which smells wrong.

 
Overall, after years spent writing OnGUI editor code in Unity, it's fun to finally try dear imgui! I really like immediate mode, and Unity's implementation is great, but so far there's a lot I prefer in dear imgui: no double/triple Layout/[Event/]Repaint passes!!, much leaner API (no dozens of overloads, no GUILayoutOption yuckness), tree and column layouts seem MUCH easier to implement, and richer!

I've only tried flow layouts so far, not sure how it compares with explicit layouts (I saw some rects in the cpp so I'm guessing it's possible). Maybe a bit less easy to do flexible layouts? although Unity's flexible/stretching options are probably the culprits for requiring the Layout/Repaint double pass.

One thing that surprised me is hashing is based on label, so 2 buttons in a row with same label = fail. I saw it's fixable with Push/PopID, but wouldn't it be possible to add the rect to the hash?

Another thing I liked in Unity was their handling of mixed values (for multi-selection edit), quite elegant... I looked for a three-state checkbox in dear imgui, couldn't find one. Dig deeper?

Uh... what was supposed to be a simple question turned into a bunch of random feedback, sorry about that!

@ocornut
Copy link
Owner

ocornut commented Mar 13, 2017

Hello and welcome!

It's better to split the feedback in different threads. It's been hard for me to answer single questions with my resources (shipping a game right now) so answering 3-4 unrelated questions isn't helping :)

There's no global state of this kind. But would be easy to make all code returning true also set a flag that would be queryiable. Personally I don't really see this as a big benefit over the existing style but why not.
There is an old (unmerged) PR doing exactly this: #614
It's only unmerged because I hadn't have the time to look at it and a hundred things were higher priority, but I'm not necessarily against merging something like it as long as it doesn't increase maintenance too much.

tree and column layouts seem MUCH easier to implement, and richer!

Columns in particular are still quite broken/limited in dear imgui, I almost regret hastily putting them in for version 1.0. Will probably and rewrite/finish this in 2017 tho.

I've only tried flow layouts so far, not sure how it compares with explicit layouts (I saw some rects in the cpp so I'm guessing it's possible). Maybe a bit less easy to do flexible layouts? although Unity's flexible/stretching options are probably the culprits for requiring the Layout/Repaint double pass.

They aren't much possibilities in term of layout yet. There is a PR for stack layout ( #846 )
In theory it would be possible to allow a system to introduce multiple passes locally so the user code would effectively loop twice (or more) and dear imgui could then perform any sort of layout. And being local that could be optional and restricted to the times you really want/need it.
Pragmatically speaking I don't imagine it'll be a priority anytime soon, but it would be possible.

One thing that surprised me is hashing is based on label, so 2 buttons in a row with same label = fail. I saw it's fixable with Push/PopID, but wouldn't it be possible to add the rect to the hash?

That would break a lot of possibilities (movig/scrolling things around, preserving keyboard/gamepad focus when changing layout, etc.) and that wouldn't really be a win. Once you get the hang of it, the id stack and ## operators appeared to trouble-less ihmo.

@benblo
Copy link
Author

benblo commented Mar 15, 2017

It's better to split the feedback in different threads.

OK, one post per issue from now on ;) !

There's no global state of this kind.

I can live without, just different habits I guess. Still think it wouldn't hurt, can be a nice fallback in some cases when you want a higher view of things. I feel like there would be very few places where it would have to be maintained (all the WidgetBehaviours or something, basically).

Columns in particular are still quite broken/limited in dear imgui, I almost regret hastily putting them in for version 1.0. Will probably and rewrite/finish this in 2017 tho.

Wow, I'd like to see that :) ! You're being too hard on yourself though, try doing a grid with resizable columns in Unity... you'll feel the pain.

In theory it would be possible to allow a system to introduce multiple passes locally so the user code would effectively loop twice (or more) and dear imgui could then perform any sort of layout. And being local that could be optional and restricted to the times you really want/need it.

Beware of multi-pass, don't fall in Unity's trap :) !
Although... never mind, I'll open another thread: #1066

One thing that surprised me is hashing is based on label, so 2 buttons in a row with same label = fail. I saw it's fixable with Push/PopID, but wouldn't it be possible to add the rect to the hash?

That would break a lot of possibilities (movig/scrolling things around, preserving keyboard/gamepad focus when changing layout, etc.) and that wouldn't really be a win.

OK the rect doesn't cut it (still thinking in Unity's term where the rect from Layout pass is the id used in Event/Repaint pass).
Sure the push/pop id is pretty easy, just not noob-friendly. Another friend that just started using imgui (Guillaume Martin, you know him) told me he had the exact same surprise.

Anyway, thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants