Easy implementation of Scale and Translate transformations in children


#1

Hello,

as many other users, I also want to create a node-based editor with imGui. I was involved with tooll.io for which we used WPF. So far I am very very happy to have replaced this with imGUI. However, one thing I don’t really understand with imGui, is why it doesn’t use transform matrices for to scroll and zoom the content of child containers.

I can see, that clipping calculation would become much less efficient with rotations. And I know from experience that the clipping of transformed containers is very buggy in Unity’s imgui, too.

But what would be a suitable approach, of how to pass a zoom factor to nested child elements? One that not only affects the font size but also things like pixel-units for elements, line weight and border-radius? I.e. an implementation that would not require adjusting the code of children?

imgui is a great project. So please read this post as a beginner’s question, not as critic.


#2

Translation and scaling are indeed left to the user.
Translation is fairly trivial to handle. For scaling you can setup a different style + font size (there’s a ImGuiStyle::ScaleAllSizes helper). If you want pixel perfect rescaled fonts (not using bilinear filtering) you may need to recreate your font atlas and/or create a cache of fonts at intermediary sizes and rely on bilinear filtering between the steps. For the rest, most of the sizes should be derived from styles or fonts sizes so your element should scale automatically. However because our style sizes are rounding to the pixel, you won’t get perfect rescaling.

There’s no way to rotate and probably be never a way because so many things are based around axis-aligned bounding boxes.


#3

Wow. Thanks for this quick answer!

The ScaleAllSizes() helper seems to be a good starting point. I guess, with a bit of more experience, I can probably get it working combined with FontGlobalScale.

Another beginner question: I keep wondering, why imGui doesn’t automatically “pop” the style stacks when ending a group? Or at least throw a warning if the stack got inconsistent.

Currently it seems to be quite easy to add bugs that are very hard to track.


#4

Some of the work on multi-DPI for the multi-viewport branch aims to eventually improve the situation with fonts but it will probably take a while until this is all done.

Another beginner question: I keep wondering, why imGui doesn’t automatically “pop” the style stacks when ending a group? Or at least throw a warning if the stack got inconsistent.

By a group do you mean specifically BeginGroup/EndGroup or any Begin/End pairs? They are various situation where unbalanced Push/Pop are meaningful, so it depends on the specific case you are thinking of. Better error recovery is however still somethng to work out, see e.g. https://github.com/ocornut/imgui/issues/1651


#5

Precisely. I would have assumed that it’s good style to maintain a push/pop balance to prevent leaking of attributes from UI components. I’m still trying to wrap my head around imgui (mostly by looking at imgui.h and example snippets). Could you point me to an example where unbalanced push/pop would be meaningful?

To be honest, I would prefer stricter checking and meaningful warnings instead of a “more graceful handling”. In the long term, I personally find that this results in more maintainable code, instead something that just works by chance. But that’s just personal preference.


#6

For example for manipulating the title bar style:

PushStyleVar/PushStyleColor(...)
Begin(...)
PopStyleVar/PushStyleColor(...)

To be honest, I would prefer stricter checking and meaningful warnings instead of a “more graceful handling”. In the long term,

Fully agreeing - my primary goal is stricter checking (instant crashes or crashes). But users of script languages need to turn the assert emitted from scripting into log entries and keep running nicely. Likewise, many of the asserts could be followed by graceful recovery so skipping asserts (even in C++) gives a chance to developer to keep running and fix the error on the go.