ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.74k stars 10.26k forks source link

🚧 Removal of GetContentRegionMax(), GetWindowContentRegionMax() etc. (1.91) #7838

Open ocornut opened 2 months ago

ocornut commented 2 months ago

For a long while I have been trying to phase out some functions which I think are confusing, misleading and error-prone.

In 1.91 those three functions are marked obsolete:

They will exist for two more years or disappear immediately if building with IMGUI_DISABLE_OBSOLETE_FUNCTIONS.

I am opening this thread as a recap and to gather questions from users who might have issues.


The reason is: You should never need those functions. I believe you can do everything with simply GetCursorScreenPos() and GetContentRegionAvail().

The three functions above were using some weird window-local coordinates space which required user to take account of scrolling and possible padding. In my experience, a good portion of uses of those functions were actually incorrect. And another portion was simply making user code vastly more complicated than needed.

I am providing equivalence to facilitate transition, but TL;DR the use of local coordinates has been a mistake done early version of dear imgui and I am trying to correct that. the fact that e.g. the equivalent for GetContentRegionMax() looks abnormally complicated is simply that it replicate the same old value, but this value is rarely meaningful by itself.

If you get rid of local coordinates you will notice your code will be simpler. You should PROBABLY never call a function like GetWindowPos(). Calling this generally betray that you are using local coordinates unnecessarily. Absolute coordinates are unambiguous and may be used in ImDrawList functions.


The remaining functions using local coordinates are:


I suggest that you mostly use those two functions:

When you use -FLT_MIN or 0.0f in many function taking a width, it essentially uses GetContentRegionAvail().x. When you use e.g -100.0f to the same function, it essentually uses GetContentRegionAvail().x - 100.0f (with a minimum size)


Debug Drawing

If you are not sure what a position or size is... draw it directly on the screen!

ImVec2 some_pos = ImGui::GetCursorScreenPos();
ImGui::GetForegroundDrawList()->AddCircleFilled(my_pos, 3, IM_COL32(255, 0, 0, 255)); // Draw red circle at position

A nice trick is to condition the display of debug primitive to holding a keyboard modifier:

ImVec2 some_pos = ImGui::GetCursorScreenPos();
if (ImGui::GetIO().KeyShift)
    ImGui::GetForegroundDrawList()->AddCircleFilled(my_pos, 3, IM_COL32(255, 0, 0, 255)); // Draw red circle at position

Additionally, The Metrics/Debugger window has tools to visualize various internal state of windows and various rectangles: debug tools

ocornut commented 2 months ago

@ElectroidDes instead of thumbing this down please consider that the code in your myriad of issues is too complicated because you are using too many of those functions, and your code would be simpler without them.

Arugin commented 1 month ago

Hello, thanks for clarification. I have a question: you've mentioned what to use instead of GetContentRegionMax(). But what to use instead of GetContentRegionMin()? I guess its ImGui.GetCursorScreenPos() - ImGui.GetWindowPos()?

GamingMinds-DanielC commented 1 month ago

I guess its ImGui.GetCursorScreenPos() - ImGui.GetWindowPos()?

Correct. At least taking the formulas above and solving for GetContentRegionMin() will give that exact result.