Pārlūkot izejas kodu

Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
omar 6 gadi atpakaļ
vecāks
revīzija
655ebe4eaf

+ 2 - 0
docs/CHANGELOG.txt

@@ -114,6 +114,7 @@ Other Changes:
 - GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
 - GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
 - Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
 - Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
 - PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485)
 - PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485)
+- Window: Window close button is horizontally aligned with style.FramePadding.x.
 - Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert
 - Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert
   to using the ImGui::MemAlloc()/MemFree() calls directly.
   to using the ImGui::MemAlloc()/MemFree() calls directly.
 - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
 - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
@@ -125,6 +126,7 @@ Other Changes:
 - Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
 - Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
 - Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam]
 - Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam]
 - Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
 - Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
+- Examples: DirectX10/11/12, Allegro, Marmalade: Render functions early out when display size is zero (minimized). (#2496)
 - Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott]
 - Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott]
 - Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott]
 - Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott]
 - Examples: GLUT: Made io.DeltaTime always > 0. (#2430)
 - Examples: GLUT: Made io.DeltaTime always > 0. (#2430)

+ 1 - 0
examples/.gitignore

@@ -25,6 +25,7 @@ project.xcworkspace
 xcuserdata
 xcuserdata
 
 
 ## Emscripten output
 ## Emscripten output
+*.o.tmp
 *.out.js
 *.out.js
 *.out.wasm
 *.out.wasm
 example_emscripten/example_emscripten.*
 example_emscripten/example_emscripten.*

+ 4 - 2
examples/example_emscripten/Makefile

@@ -24,10 +24,12 @@ UNAME_S := $(shell uname -s)
 EMS = -s USE_SDL=2 -s WASM=1
 EMS = -s USE_SDL=2 -s WASM=1
 EMS += -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp
 EMS += -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp
 EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0
 EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0
-EMS += -s ASSERTIONS=1 -s SAFE_HEAP=1
+EMS += -s ASSERTIONS=1 -s NO_FILESYSTEM=1
+#EMS += -s SAFE_HEAP=1    ## Adds overhead
 
 
 CPPFLAGS = -I../ -I../../
 CPPFLAGS = -I../ -I../../
-CPPFLAGS += -g -Wall -Wformat -O3
+#CPPFLAGS += -g
+CPPFLAGS += -Wall -Wformat -Os
 CPPFLAGS += $(EMS)
 CPPFLAGS += $(EMS)
 LIBS = $(EMS)
 LIBS = $(EMS)
 LDFLAGS = --shell-file shell_minimal.html
 LDFLAGS = --shell-file shell_minimal.html

+ 6 - 2
examples/example_emscripten/main.cpp

@@ -14,7 +14,7 @@
 #include <SDL.h>
 #include <SDL.h>
 #include <SDL_opengles2.h>
 #include <SDL_opengles2.h>
 
 
-// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally. 
+// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally.
 // Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this.
 // Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this.
 SDL_Window*     g_Window = NULL;
 SDL_Window*     g_Window = NULL;
 SDL_GLContext   g_GLContext = NULL;
 SDL_GLContext   g_GLContext = NULL;
@@ -63,6 +63,10 @@ int main(int, char**)
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
 
 
+    // For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
+    // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
+    io.IniFilename = NULL;
+
     // Setup Dear ImGui style
     // Setup Dear ImGui style
     ImGui::StyleColorsDark();
     ImGui::StyleColorsDark();
     //ImGui::StyleColorsClassic();
     //ImGui::StyleColorsClassic();
@@ -90,7 +94,7 @@ int main(int, char**)
     emscripten_set_main_loop_arg(main_loop, NULL, 0, true);
     emscripten_set_main_loop_arg(main_loop, NULL, 0, true);
 }
 }
 
 
-void main_loop(void* arg) 
+void main_loop(void* arg)
 {
 {
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
     IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.
     IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.

+ 4 - 0
examples/imgui_impl_allegro5.cpp

@@ -64,6 +64,10 @@ struct ImDrawVertAllegro
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
 void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
 {
 {
+    // Avoid rendering when minimized
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
+        return;
+
     // Backup Allegro state that will be modified
     // Backup Allegro state that will be modified
     ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
     ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
     ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
     ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();

+ 4 - 0
examples/imgui_impl_dx10.cpp

@@ -65,6 +65,10 @@ static void ImGui_ImplDX10_ShutdownPlatformInterface();
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
 void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
 {
 {
+    // Avoid rendering when minimized
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
+        return;
+
     ID3D10Device* ctx = g_pd3dDevice;
     ID3D10Device* ctx = g_pd3dDevice;
 
 
     // Create and grow vertex/index buffers if needed
     // Create and grow vertex/index buffers if needed

+ 4 - 0
examples/imgui_impl_dx11.cpp

@@ -65,6 +65,10 @@ static void ImGui_ImplDX11_ShutdownPlatformInterface();
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
 void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
 {
 {
+    // Avoid rendering when minimized
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
+        return;
+
     ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
     ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
 
 
     // Create and grow vertex/index buffers if needed
     // Create and grow vertex/index buffers if needed

+ 4 - 0
examples/imgui_impl_dx12.cpp

@@ -66,6 +66,10 @@ static void ImGui_ImplDX12_ShutdownPlatformInterface();
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
 void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
 {
 {
+    // Avoid rendering when minimized
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
+        return;
+
     // FIXME: I'm assuming that this only gets called once per frame!
     // FIXME: I'm assuming that this only gets called once per frame!
     // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
     // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
     g_frameIndex = g_frameIndex + 1;
     g_frameIndex = g_frameIndex + 1;

+ 4 - 0
examples/imgui_impl_marmalade.cpp

@@ -40,6 +40,10 @@ static ImVec2       g_RenderScale = ImVec2(1.0f,1.0f);
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
 void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
 {
 {
+    // Avoid rendering when minimized
+    if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
+        return;
+
     // Render command lists
     // Render command lists
     for (int n = 0; n < draw_data->CmdListsCount; n++)
     for (int n = 0; n < draw_data->CmdListsCount; n++)
     {
     {

+ 54 - 43
imgui.cpp

@@ -925,7 +925,7 @@ CODE
       (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
       (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
       Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
       Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
     - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
     - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
-      contents behind or over every other imgui windows. (1 bg/fg drawlist per viewport)
+      contents behind or over every other imgui windows (one bg/fg drawlist per viewport).
     - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
     - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
       your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
       your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
 
 
@@ -2277,8 +2277,8 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
     ImGuiWindow* window = ImGui::GetCurrentWindow();
     ImGuiWindow* window = ImGui::GetCurrentWindow();
     window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;      // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
     window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;      // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
     window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y);    // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
     window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y);    // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
-    if (window->DC.ColumnsSet)
-        window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y;           // Setting this so that cell Y position are set properly
+    if (window->DC.CurrentColumns)
+        window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y;           // Setting this so that cell Y position are set properly
 }
 }
 
 
 // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
 // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
@@ -2654,7 +2654,7 @@ ImGuiWindow::~ImGuiWindow()
     IM_ASSERT(DrawList == &DrawListInst);
     IM_ASSERT(DrawList == &DrawListInst);
     IM_DELETE(Name);
     IM_DELETE(Name);
     for (int i = 0; i != ColumnsStorage.Size; i++)
     for (int i = 0; i != ColumnsStorage.Size; i++)
-        ColumnsStorage[i].~ImGuiColumnsSet();
+        ColumnsStorage[i].~ImGuiColumns();
 }
 }
 
 
 ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
 ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
@@ -5957,7 +5957,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
         window->DC.ItemFlagsStack.resize(0);
         window->DC.ItemFlagsStack.resize(0);
         window->DC.ItemWidthStack.resize(0);
         window->DC.ItemWidthStack.resize(0);
         window->DC.TextWrapPosStack.resize(0);
         window->DC.TextWrapPosStack.resize(0);
-        window->DC.ColumnsSet = NULL;
+        window->DC.CurrentColumns = NULL;
         window->DC.TreeDepth = 0;
         window->DC.TreeDepth = 0;
         window->DC.TreeDepthMayJumpToParentOnPop = 0x00;
         window->DC.TreeDepthMayJumpToParentOnPop = 0x00;
         window->DC.StateStorage = &window->StateStorage;
         window->DC.StateStorage = &window->StateStorage;
@@ -6093,7 +6093,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
                         BeginAsDockableDragDropTarget(window);
                         BeginAsDockableDragDropTarget(window);
         }
         }
 
 
-        // We fill last item data based on Title Bar or Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
+        // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
         // This is useful to allow creating context menus on title bar only, etc.
         // This is useful to allow creating context menus on title bar only, etc.
         if (window->DockIsActive)
         if (window->DockIsActive)
         {
         {
@@ -6202,7 +6202,7 @@ void ImGui::End()
 
 
     ImGuiWindow* window = g.CurrentWindow;
     ImGuiWindow* window = g.CurrentWindow;
 
 
-    if (window->DC.ColumnsSet != NULL)
+    if (window->DC.CurrentColumns != NULL)
         EndColumns();
         EndColumns();
     if (!(window->Flags & ImGuiWindowFlags_DockNodeHost))   // Pop inner window clip rectangle
     if (!(window->Flags & ImGuiWindowFlags_DockNodeHost))   // Pop inner window clip rectangle
         PopClipRect();
         PopClipRect();
@@ -6991,8 +6991,8 @@ ImVec2 ImGui::GetContentRegionMax()
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
     ImVec2 mx = window->ContentsRegionRect.Max - window->Pos;
     ImVec2 mx = window->ContentsRegionRect.Max - window->Pos;
-    if (window->DC.ColumnsSet)
-        mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x;
+    if (window->DC.CurrentColumns)
+        mx.x = GetColumnOffset(window->DC.CurrentColumns->Current + 1) - window->WindowPadding.x;
     return mx;
     return mx;
 }
 }
 
 
@@ -8630,8 +8630,8 @@ static void ImGui::NavUpdate()
     if (g.NavWindow)
     if (g.NavWindow)
     {
     {
         ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
         ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
-        if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG]
-        if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255, 0, 255, 255) : IM_COL32(255, 0, 0, 255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8, -4), col, buf); }
+        if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG]
+        if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); }
     }
     }
 #endif
 #endif
 }
 }
@@ -8973,11 +8973,11 @@ void ImGui::NavUpdateWindowingList()
 void ImGui::NextColumn()
 void ImGui::NextColumn()
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-    if (window->SkipItems || window->DC.ColumnsSet == NULL)
+    if (window->SkipItems || window->DC.CurrentColumns == NULL)
         return;
         return;
 
 
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
 
 
     if (columns->Count == 1)
     if (columns->Count == 1)
     {
     {
@@ -9016,28 +9016,28 @@ void ImGui::NextColumn()
 int ImGui::GetColumnIndex()
 int ImGui::GetColumnIndex()
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0;
+    return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0;
 }
 }
 
 
 int ImGui::GetColumnsCount()
 int ImGui::GetColumnsCount()
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1;
+    return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1;
 }
 }
 
 
-static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm)
+static float OffsetNormToPixels(const ImGuiColumns* columns, float offset_norm)
 {
 {
     return offset_norm * (columns->MaxX - columns->MinX);
     return offset_norm * (columns->MaxX - columns->MinX);
 }
 }
 
 
-static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset)
+static float PixelsToOffsetNorm(const ImGuiColumns* columns, float offset)
 {
 {
     return offset / (columns->MaxX - columns->MinX);
     return offset / (columns->MaxX - columns->MinX);
 }
 }
 
 
 static inline float GetColumnsRectHalfWidth() { return 4.0f; }
 static inline float GetColumnsRectHalfWidth() { return 4.0f; }
 
 
-static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index)
+static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
 {
 {
     // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
     // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
     // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
     // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
@@ -9057,7 +9057,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index)
 float ImGui::GetColumnOffset(int column_index)
 float ImGui::GetColumnOffset(int column_index)
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     IM_ASSERT(columns != NULL);
     IM_ASSERT(columns != NULL);
 
 
     if (column_index < 0)
     if (column_index < 0)
@@ -9069,7 +9069,7 @@ float ImGui::GetColumnOffset(int column_index)
     return x_offset;
     return x_offset;
 }
 }
 
 
-static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool before_resize = false)
+static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false)
 {
 {
     if (column_index < 0)
     if (column_index < 0)
         column_index = columns->Current;
         column_index = columns->Current;
@@ -9085,7 +9085,7 @@ static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool b
 float ImGui::GetColumnWidth(int column_index)
 float ImGui::GetColumnWidth(int column_index)
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     IM_ASSERT(columns != NULL);
     IM_ASSERT(columns != NULL);
 
 
     if (column_index < 0)
     if (column_index < 0)
@@ -9097,7 +9097,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
     ImGuiWindow* window = g.CurrentWindow;
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     IM_ASSERT(columns != NULL);
     IM_ASSERT(columns != NULL);
 
 
     if (column_index < 0)
     if (column_index < 0)
@@ -9118,7 +9118,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
 void ImGui::SetColumnWidth(int column_index, float width)
 void ImGui::SetColumnWidth(int column_index, float width)
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     IM_ASSERT(columns != NULL);
     IM_ASSERT(columns != NULL);
 
 
     if (column_index < 0)
     if (column_index < 0)
@@ -9129,46 +9129,57 @@ void ImGui::SetColumnWidth(int column_index, float width)
 void ImGui::PushColumnClipRect(int column_index)
 void ImGui::PushColumnClipRect(int column_index)
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     ImGuiWindow* window = GetCurrentWindowRead();
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     if (column_index < 0)
     if (column_index < 0)
         column_index = columns->Current;
         column_index = columns->Current;
 
 
-    PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false);
+    ImGuiColumnData* column = &columns->Columns[column_index];
+    PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false);
 }
 }
 
 
-static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id)
+ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
 {
 {
+    // We have few columns per window so for now we don't need bother much with turning this into a faster lookup.
     for (int n = 0; n < window->ColumnsStorage.Size; n++)
     for (int n = 0; n < window->ColumnsStorage.Size; n++)
         if (window->ColumnsStorage[n].ID == id)
         if (window->ColumnsStorage[n].ID == id)
             return &window->ColumnsStorage[n];
             return &window->ColumnsStorage[n];
 
 
-    window->ColumnsStorage.push_back(ImGuiColumnsSet());
-    ImGuiColumnsSet* columns = &window->ColumnsStorage.back();
+    window->ColumnsStorage.push_back(ImGuiColumns());
+    ImGuiColumns* columns = &window->ColumnsStorage.back();
     columns->ID = id;
     columns->ID = id;
     return columns;
     return columns;
 }
 }
 
 
-void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
+ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
 {
 {
-    ImGuiContext& g = *GImGui;
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
 
 
-    IM_ASSERT(columns_count >= 1);
-    IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported
-
     // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
     // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
     // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
     // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
     PushID(0x11223347 + (str_id ? 0 : columns_count));
     PushID(0x11223347 + (str_id ? 0 : columns_count));
     ImGuiID id = window->GetID(str_id ? str_id : "columns");
     ImGuiID id = window->GetID(str_id ? str_id : "columns");
     PopID();
     PopID();
 
 
+    return id;
+}
+
+void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
+{
+    ImGuiContext& g = *GImGui;
+    ImGuiWindow* window = GetCurrentWindow();
+
+    IM_ASSERT(columns_count >= 1);
+    IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
+
+    ImGuiID id = GetColumnsID(str_id, columns_count);
+
     // Acquire storage for the columns set
     // Acquire storage for the columns set
-    ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id);
+    ImGuiColumns* columns = FindOrCreateColumns(window, id);
     IM_ASSERT(columns->ID == id);
     IM_ASSERT(columns->ID == id);
     columns->Current = 0;
     columns->Current = 0;
     columns->Count = columns_count;
     columns->Count = columns_count;
     columns->Flags = flags;
     columns->Flags = flags;
-    window->DC.ColumnsSet = columns;
+    window->DC.CurrentColumns = columns;
 
 
     // Set state for first column
     // Set state for first column
     const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x);
     const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x);
@@ -9219,7 +9230,7 @@ void ImGui::EndColumns()
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
-    ImGuiColumnsSet* columns = window->DC.ColumnsSet;
+    ImGuiColumns* columns = window->DC.CurrentColumns;
     IM_ASSERT(columns != NULL);
     IM_ASSERT(columns != NULL);
 
 
     PopItemWidth();
     PopItemWidth();
@@ -9280,7 +9291,7 @@ void ImGui::EndColumns()
     }
     }
     columns->IsBeingResized = is_being_resized;
     columns->IsBeingResized = is_being_resized;
 
 
-    window->DC.ColumnsSet = NULL;
+    window->DC.CurrentColumns = NULL;
     window->DC.ColumnsOffset.x = 0.0f;
     window->DC.ColumnsOffset.x = 0.0f;
     window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
     window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
 }
 }
@@ -9293,10 +9304,10 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
 
 
     ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
     ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
     //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
     //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
-    if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count == columns_count && window->DC.ColumnsSet->Flags == flags)
+    if (window->DC.CurrentColumns != NULL && window->DC.CurrentColumns->Count == columns_count && window->DC.CurrentColumns->Flags == flags)
         return;
         return;
 
 
-    if (window->DC.ColumnsSet != NULL)
+    if (window->DC.CurrentColumns != NULL)
         EndColumns();
         EndColumns();
 
 
     if (columns_count != 1)
     if (columns_count != 1)
@@ -14189,7 +14200,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
             {
             {
                 for (int n = 0; n < window->ColumnsStorage.Size; n++)
                 for (int n = 0; n < window->ColumnsStorage.Size; n++)
                 {
                 {
-                    const ImGuiColumnsSet* columns = &window->ColumnsStorage[n];
+                    const ImGuiColumns* columns = &window->ColumnsStorage[n];
                     if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
                     if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
                     {
                     {
                         ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX);
                         ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX);
@@ -14295,9 +14306,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
             char buf[64] = "";
             char buf[64] = "";
             char* p = buf;
             char* p = buf;
             p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext);
             p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext);
-            ImDrawList* overlay_draw_list = GetForegroundDrawList(window->Viewport);
-            overlay_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
-            overlay_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf);
+            ImDrawList* fg_draw_list = GetForegroundDrawList(window->Viewport);
+            fg_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
+            fg_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf);
         }
         }
     }
     }
     ImGui::End();
     ImGui::End();

+ 1 - 2
imgui_demo.cpp

@@ -1697,7 +1697,6 @@ static void ShowDemoWindowWidgets()
                 if (ImGui::MenuItem("Close")) { test_window = false; }
                 if (ImGui::MenuItem("Close")) { test_window = false; }
                 ImGui::EndPopup();
                 ImGui::EndPopup();
             }
             }
-            //if (IsItemHovered() || IsItemActive()) { printf("[%05d] Hovered %d Active %d\n", GetFrameCount(), IsItemHovered(), IsItemActive()); } // [DEBUG]
             ImGui::Text(
             ImGui::Text(
                 "IsItemHovered() after begin = %d (== is title bar hovered)\n"
                 "IsItemHovered() after begin = %d (== is title bar hovered)\n"
                 "IsItemActive() after begin = %d (== is window being clicked/moved)\n",
                 "IsItemActive() after begin = %d (== is window being clicked/moved)\n",
@@ -4051,7 +4050,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
 // Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
 // Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
 static void ShowExampleAppSimpleOverlay(bool* p_open)
 static void ShowExampleAppSimpleOverlay(bool* p_open)
 {
 {
-    // FIXME-VIEWPORT-ABS: Select a default viewport
+    // FIXME-VIEWPORT: Select a default viewport
     const float DISTANCE = 10.0f;
     const float DISTANCE = 10.0f;
     static int corner = 0;
     static int corner = 0;
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();

+ 8 - 6
imgui_internal.h

@@ -63,7 +63,7 @@ struct ImDrawDataBuilder;           // Helper to build a ImDrawData instance
 struct ImDrawListSharedData;        // Data shared between all ImDrawList instances
 struct ImDrawListSharedData;        // Data shared between all ImDrawList instances
 struct ImGuiColorMod;               // Stacked color modifier, backup of modified data so we can restore it
 struct ImGuiColorMod;               // Stacked color modifier, backup of modified data so we can restore it
 struct ImGuiColumnData;             // Storage data for a single column
 struct ImGuiColumnData;             // Storage data for a single column
-struct ImGuiColumnsSet;             // Storage data for a columns set
+struct ImGuiColumns;                // Storage data for a columns set
 struct ImGuiContext;                // Main imgui context
 struct ImGuiContext;                // Main imgui context
 struct ImGuiDockContext;            // Docking system context
 struct ImGuiDockContext;            // Docking system context
 struct ImGuiDockNode;               // Docking system node (hold a list of Windows OR two child dock nodes)
 struct ImGuiDockNode;               // Docking system node (hold a list of Windows OR two child dock nodes)
@@ -681,7 +681,7 @@ struct ImGuiColumnData
     ImGuiColumnData()   { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; }
     ImGuiColumnData()   { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; }
 };
 };
 
 
-struct ImGuiColumnsSet
+struct ImGuiColumns
 {
 {
     ImGuiID             ID;
     ImGuiID             ID;
     ImGuiColumnsFlags   Flags;
     ImGuiColumnsFlags   Flags;
@@ -695,7 +695,7 @@ struct ImGuiColumnsSet
     float               StartMaxPosX;       // Copy of CursorMaxPos
     float               StartMaxPosX;       // Copy of CursorMaxPos
     ImVector<ImGuiColumnData> Columns;
     ImVector<ImGuiColumnData> Columns;
 
 
-    ImGuiColumnsSet()   { Clear(); }
+    ImGuiColumns()      { Clear(); }
     void Clear()
     void Clear()
     {
     {
         ID = 0;
         ID = 0;
@@ -1311,7 +1311,7 @@ struct IMGUI_API ImGuiWindowTempData
     ImVec1                  Indent;                 // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
     ImVec1                  Indent;                 // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
     ImVec1                  GroupOffset;
     ImVec1                  GroupOffset;
     ImVec1                  ColumnsOffset;          // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
     ImVec1                  ColumnsOffset;          // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
-    ImGuiColumnsSet*        ColumnsSet;             // Current columns set
+    ImGuiColumns*           CurrentColumns;         // Current columns set
 
 
     ImGuiWindowTempData()
     ImGuiWindowTempData()
     {
     {
@@ -1342,7 +1342,7 @@ struct IMGUI_API ImGuiWindowTempData
         Indent = ImVec1(0.0f);
         Indent = ImVec1(0.0f);
         GroupOffset = ImVec1(0.0f);
         GroupOffset = ImVec1(0.0f);
         ColumnsOffset = ImVec1(0.0f);
         ColumnsOffset = ImVec1(0.0f);
-        ColumnsSet = NULL;
+        CurrentColumns = NULL;
     }
     }
 };
 };
 
 
@@ -1414,7 +1414,7 @@ struct IMGUI_API ImGuiWindow
     float                   ItemWidthDefault;
     float                   ItemWidthDefault;
     ImGuiMenuColumns        MenuColumns;                        // Simplified columns storage for menu items
     ImGuiMenuColumns        MenuColumns;                        // Simplified columns storage for menu items
     ImGuiStorage            StateStorage;
     ImGuiStorage            StateStorage;
-    ImVector<ImGuiColumnsSet> ColumnsStorage;
+    ImVector<ImGuiColumns>  ColumnsStorage;
     float                   FontWindowScale;                    // User scale multiplier per-window
     float                   FontWindowScale;                    // User scale multiplier per-window
     float                   FontDpiScale;
     float                   FontDpiScale;
     int                     SettingsIdx;                        // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back)
     int                     SettingsIdx;                        // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back)
@@ -1711,6 +1711,8 @@ namespace ImGui
     IMGUI_API void          BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
     IMGUI_API void          BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
     IMGUI_API void          EndColumns();                                                             // close columns
     IMGUI_API void          EndColumns();                                                             // close columns
     IMGUI_API void          PushColumnClipRect(int column_index = -1);
     IMGUI_API void          PushColumnClipRect(int column_index = -1);
+    IMGUI_API ImGuiID       GetColumnsID(const char* str_id, int count);
+    IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id);
 
 
     // Tab Bars
     // Tab Bars
     IMGUI_API bool          BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node);
     IMGUI_API bool          BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node);

+ 7 - 7
imgui_widgets.cpp

@@ -1240,7 +1240,7 @@ void ImGui::Separator()
     }
     }
 
 
     // Horizontal Separator
     // Horizontal Separator
-    if (window->DC.ColumnsSet)
+    if (window->DC.CurrentColumns)
         PopClipRect();
         PopClipRect();
 
 
     float x1 = window->Pos.x;
     float x1 = window->Pos.x;
@@ -1252,7 +1252,7 @@ void ImGui::Separator()
     ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
     ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
     if (!ItemAdd(bb, 0))
     if (!ItemAdd(bb, 0))
     {
     {
-        if (window->DC.ColumnsSet)
+        if (window->DC.CurrentColumns)
             PushColumnClipRect();
             PushColumnClipRect();
         return;
         return;
     }
     }
@@ -1262,10 +1262,10 @@ void ImGui::Separator()
     if (g.LogEnabled)
     if (g.LogEnabled)
         LogRenderedText(&bb.Min, "--------------------------------");
         LogRenderedText(&bb.Min, "--------------------------------");
 
 
-    if (window->DC.ColumnsSet)
+    if (window->DC.CurrentColumns)
     {
     {
         PushColumnClipRect();
         PushColumnClipRect();
-        window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y;
+        window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y;
     }
     }
 }
 }
 
 
@@ -5337,7 +5337,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     const ImGuiStyle& style = g.Style;
     const ImGuiStyle& style = g.Style;
 
 
-    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped.
+    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
         PopClipRect();
         PopClipRect();
 
 
     ImGuiID id = window->GetID(label);
     ImGuiID id = window->GetID(label);
@@ -5381,7 +5381,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
     }
     }
     if (!item_add)
     if (!item_add)
     {
     {
-        if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
+        if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
             PushColumnClipRect();
             PushColumnClipRect();
         return false;
         return false;
     }
     }
@@ -5426,7 +5426,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
         RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
         RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
     }
     }
 
 
-    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet)
+    if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
     {
     {
         PushColumnClipRect();
         PushColumnClipRect();
         bb.Max.x -= (GetContentRegionMax().x - max_x);
         bb.Max.x -= (GetContentRegionMax().x - max_x);