Isn't the whole point of immediate mode UIs to get rid of the "event loop" though?
> multiple application views that conditionally show/hide
The ImGui way of doing this is to conditionally run or not run the code which describes the conditionally shown UI elements. E.g. a simple
if (viewShown) {
...code which describes what the view looks like
}
There are plenty of real-world applications with complex UIs implemented in Dear ImGui which don't seem to have a problem with those things, e.g. see https://github.com/ocornut/imgui/labels/gallery
> The trouble comes from not componentizing things...
In ImGui, reusable UI components are just code which describes the UI component by calling lower-level ImGui functions and which itself is a new ImGui-style function. It works surprisingly well.
If your entire system ran with immediate mode GUIs your performance would either be in the toilet or battery life would be destroyed (or both).
They’re great for games and GPU where you’re in a for a pound anyway. There are some music apps that use it and it’s horrible if you’re on a laptop. No I don’t want to consume a couple watts when I should be idling because the entire screen is being repainted doing nothing.
Makes electron seem nice.
I'm not sure the perf/battery life tradeoff is a necessary aspect of immediate mode UI.
while (running) {
event := get_next_event()
process_event(event)
repaint()
}
You could just have get_next_event block until there is a meaningful event that occurs (e.g. mouse click). You could even have your UI report "interactive" rectangles to the event layer to prevent it from producing e.g. mouse move events that are irrelevant.
> You could even have your UI report "interactive" rectangles to the event layer to prevent it from producing e.g. mouse move events that are irrelevant.
And then what?
With this one innocuous seeming sentence you are hand waving a way a ton of complexity. If you try to implement it you will at least have some respect for toolkit authors.
> IMGUI is just a different API design IMO.
Yes one that is lower level and
therefore is fundamentally harder to deal with to get all the things people take for granted in a full blown mature state based GUI toolkit.
You can implement a retained GUI toolkit with IMGUI. Or you can use something already done.
IMGUI eschews this complexity as part of its purpose but it comes with trade offs that limit its use cases.
Of course this is a greatly simplified example, but I can see this extending to any GUI widget that can be represented with a (hierarchy) of rectangles.
All major GUI toolkits are ultimately implemented on some immediate mode drawing system. So I don’t see the point. (You’re literally just unfactoring what a GUI library does behind the scenes into your loop.)
When you unsimplify your example then you are reinventing a wheel. A big wheel. It can be done, but it’s a lot of work. And then you might go factoring things back so it starts to look very similar to prior art. It’s actually easier than ever to implement accessibility for instance (assuming you’re ok pulling in a large dependency), but show me an actual example of this done on top of imgui.
Things I never said: imgui doesn’t have uses, imgui isn’t great.
Fantastic - “only” 1 to 2 ms (and that’s for simple stuff). Depending on what you’re doing that’s a big chunk. Also time you could be sleeping. Also something you don’t usually have to worry about.
It looks like they only repaint when there is interaction as well (so it does sleep while nothing is happening).
However, my point with linking this library was just to demonstrate that accessibility and IMGUI are not inherently incompatible.
My point with the example I created above was that you don't have to trade away battery life in order to take advantage of the IMGUI paradigm. My secondary point was also to implement the "interactive rectangles" optimization I mentioned above (which only took a few lines of code).
While I agree with you that there are definitely tradeoffs, I don't think the aforementioned ones are necessary.
> my point with linking this library was just to demonstrate that accessibility and IMGUI are not inherently incompatible.
Once again, all major GUI toolkits and browser are implemented on top of immediate mode graphics APIs, so you continue to beat this straw man argument. Obviously everything is ultimately immediate mode. No one was refuting those points and sorry they’re not particularly informative.
The point is you’re just rearranging where that state lives and who manages it. You’re retaining it somewhere. But your app is not the best place to manage a lot of this state (as even egui itself admits), it belongs in a well tested library.
Once you start using dirty rectangles, someone has to keep track of them. What benefit is it to me to drive when to call the apis for those details?
IMGUI has a certain elegance where your answer to that is to just say fuck it, and that works well for like a game editor. (The point about accessibility was not that it can’t be done but IMGUI rarely gets actually used where this is ever done). Because if your answer isn’t fuck it to all those things than just go get a library to it for you, which will be managing that state.
I think a lot of people pining for IMGUI really just want sane data binding. Which is understandable, but IMGUI is often throwing the baby out with the bath water.
Like honestly read that egui advantages/disadvantages. That’s a lot of cons (that first one woo) for that one pro (which is not even inherent to all retained APIs).
If you do that, you have an event loop again (like in the OP), which your comment's grandparent was trying to get rid of (and your parent explained to them why they can't).
In practice there is always a loop. I believe the point flohofwoe was making is that with an immediate UI you don't have to even touch events in your immediate UI code (they are abstracted away, if needed, in a pretty clean manner, IMO), so there's no need to do anything to get a "sane event loop". I might be wrong about what's his point though.
There's a loop yes, but not an event loop - the other argument is that you can have a loop that runs every frame, and you just rerender the whole thing
Not really. To expand on my response: In practice there is always the operating system's event loop, both in retained and immediate mode. This is true for all mainstream operating systems.
What I am explaining is that in practice you have to use the second code, because of how operating systems work. This can be handled by a windowing library (SDL, GLFW, Sokol), and the adapters for libraries like Dear Imgui, Nuklear, etc. also expect the second code.
There are ways to skip processing events in some OSs, but this is not really advised by OS writers, and in some cases you will get subpar experience, apps that don't close correctly, etc.
… huh? The entire purpose of Bitcoin mining is to use every compute cycle. My entire point about about ImGui is it doesn’t take as many cycles as people seem to think.
It doesn't need to be inefficient, it depends on the implementation. Immediate mode is describing the API and usage, you can implement it such that it's retained mode behind the scenes, or only redrawing when necessary, etc.
I've written an immediate mode GUI for my projects and it's fine for performance. I've written a music player for instance which uses a negligible amount of CPU, it uses slightly more resources than Clementine, my previous music player.
> that it's retained mode behind the scenes, or only redrawing when necessary
And why reinvent that wheel? Then localization and accessibility while you’re at it?
> it uses slightly more resources than Clementine
That’s an odd flex, Clementine is extremely horrible for CPU usage (compared to nicer looking examples), probably not due to the GUI, but still. foobar2000 with a ton of plugins works better in wine.
>> Isn't the whole point of immediate UIs to get rid of the "event loop" though?
No, not at all. It's to take explicit control of the event loop. It's right there, you have a loop and the buttons still fire events, you just have to check for them on every iteration of the loop.
You don't have to 'install' event handlers, there are no event objects, and there's no event loop like:
while (uiEvent = uiGetNextEvent()) {
uiHandleEvent(uiEvent);
}
...and it would never enter my mind to call this an 'event handler':
if (Button("Click Me!")) {
printf("Button Clicked!");
}
One very nice side effect of this immediate mode style code is that it 'runs on a linear timeline', e.g. you can step through the code in a debugger without having to put breakpoints inside 'event handlers'.
How all this is implemented inside the immediate mode UI framework isn't relevant. The 'immediate mode idea' is only about the user-facing code which describes the UI, not the internal implementation (those can vastly differ, and could even manage a 'retained mode' widget tree under the hood).
> multiple application views that conditionally show/hide
The ImGui way of doing this is to conditionally run or not run the code which describes the conditionally shown UI elements. E.g. a simple
There are plenty of real-world applications with complex UIs implemented in Dear ImGui which don't seem to have a problem with those things, e.g. see https://github.com/ocornut/imgui/labels/gallery> The trouble comes from not componentizing things...
In ImGui, reusable UI components are just code which describes the UI component by calling lower-level ImGui functions and which itself is a new ImGui-style function. It works surprisingly well.