From f2ff88b03ad03644b756d11a8b839dafa34a8741 Mon Sep 17 00:00:00 2001 From: "Adam D. Moss" Date: Mon, 16 Mar 2015 10:45:11 +0000 Subject: [PATCH 01/44] opengl3+opengl example: if content window doesn't have focus, tell ImGui we don't have a mouse position. e.g. avoids tooltips popping up in imgui app when you're interacting with a different app window that overlaps it. --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 17 ++++++++++++----- examples/opengl_example/imgui_impl_glfw.cpp | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 07bf5a57..04d81e58 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -329,11 +329,18 @@ void ImGui_ImplGlfwGL3_NewFrame() // Setup inputs // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels - mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels + mouse_y *= (float)display_h / h; + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } for (int i = 0; i < 3; i++) { diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index 00313e45..42278635 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -233,11 +233,18 @@ void ImGui_ImplGlfw_NewFrame() // Setup inputs // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels - mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels + mouse_y *= (float)display_h / h; + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } for (int i = 0; i < 3; i++) { From 04358c301e2b5256a74645dd8695dad04273ebbb Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Mar 2015 11:49:18 +0000 Subject: [PATCH 02/44] Removed extraneous spaces --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++-- examples/opengl_example/imgui_impl_glfw.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 04d81e58..cd43effc 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -333,9 +333,9 @@ void ImGui_ImplGlfwGL3_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels + mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) } else { diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index 42278635..b7a4844c 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -237,9 +237,9 @@ void ImGui_ImplGlfw_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels + mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels mouse_y *= (float)display_h / h; - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) } else { From cb285c4d35757f39dd92137473419e42e5f6c145 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Mar 2015 11:53:36 +0000 Subject: [PATCH 03/44] Examples: uses SetNextWindowPos/SetNextWindowSize when applicable --- examples/directx11_example/main.cpp | 3 ++- examples/directx9_example/main.cpp | 3 ++- examples/opengl3_example/main.cpp | 3 ++- examples/opengl_example/main.cpp | 3 ++- imgui.cpp | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index b051fd24..0064a93a 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -188,7 +188,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 9a01ba31..ce8ca477 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -115,7 +115,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); } diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index dc88a7c6..9f0207aa 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -59,7 +59,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); } diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp index 471f9a29..92bf842c 100644 --- a/examples/opengl_example/main.cpp +++ b/examples/opengl_example/main.cpp @@ -53,7 +53,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); } diff --git a/imgui.cpp b/imgui.cpp index b2c8d11c..715fb6ce 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9545,13 +9545,13 @@ static void ShowExampleAppAutoResize(bool* opened) static void ShowExampleAppFixedOverlay(bool* opened) { + ImGui::SetNextWindowPos(ImVec2(10,10)); if (!ImGui::Begin("Example: Fixed Overlay", opened, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::End(); return; } - ImGui::SetWindowPos(ImVec2(10,10)); ImGui::Text("Simple overlay\non the top-left side of the screen."); ImGui::Separator(); ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); From 7e00a41f1bdf61e75549a7308378c1e4fdf96fd9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 16 Mar 2015 18:04:51 +0000 Subject: [PATCH 04/44] Speculative warning fix --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 715fb6ce..7d65a5dc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9174,7 +9174,7 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::SameLine(); ImGui::PushID("set2"); - for (size_t i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { if (i > 0) ImGui::SameLine(0, 4); ImGui::PushID(i); From fe2809fecc82edc612293d2ac819a2297dafa484 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 16:16:15 +0000 Subject: [PATCH 05/44] Changed default Border and Column border colors to be most subtle, less MS-DOS --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7d65a5dc..21258642 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -515,7 +515,7 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.60f); Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input Colors[ImGuiCol_TitleBg] = ImVec4(0.50f, 0.50f, 1.00f, 0.45f); @@ -536,9 +536,9 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - Colors[ImGuiCol_Column] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - Colors[ImGuiCol_ColumnHovered] = ImVec4(0.60f, 0.40f, 0.40f, 1.00f); - Colors[ImGuiCol_ColumnActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_Column] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_ColumnHovered] = ImVec4(0.70f, 0.60f, 0.60f, 1.00f); + Colors[ImGuiCol_ColumnActive] = ImVec4(0.90f, 0.70f, 0.70f, 1.00f); Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); From bbaf7e2eee484f356411ec5efb0a3855e3d8ccb0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 16:40:47 +0000 Subject: [PATCH 06/44] Internal tweaks --- imgui.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 21258642..791cbb49 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -435,7 +435,7 @@ static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scal static void SetFont(ImFont* font); static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id); static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL); -static void ItemSize(const ImGuiAabb& bb, ImVec2* adjust_start_offset = NULL); +static void ItemSize(const ImGuiAabb& bb); static void PushColumnClipRect(int column_index = -1); static bool IsClipped(const ImGuiAabb& bb); @@ -911,7 +911,7 @@ struct ImGuiDrawContext ImVec2 CursorStartPos; float CurrentLineHeight; float PrevLineHeight; - float LogLineHeight; + float LogLinePosY; int TreeDepth; ImGuiID LastItemID; ImGuiAabb LastItemAabb; @@ -938,7 +938,7 @@ struct ImGuiDrawContext { CursorPos = CursorPosPrevLine = CursorStartPos = ImVec2(0.0f, 0.0f); CurrentLineHeight = PrevLineHeight = 0.0f; - LogLineHeight = -1.0f; + LogLinePosY = -1.0f; TreeDepth = 0; LastItemID = 0; LastItemAabb = ImGuiAabb(0.0f,0.0f,0.0f,0.0f); @@ -2155,8 +2155,8 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en if (!text_end) text_end = FindTextDisplayEnd(text, text_end); - const bool log_new_line = ref_pos.y > window->DC.LogLineHeight+1; - window->DC.LogLineHeight = ref_pos.y; + const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; + window->DC.LogLinePosY = ref_pos.y; const char* text_remaining = text; if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth @@ -3069,7 +3069,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPosPrevLine = window->DC.CursorPos; window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; - window->DC.LogLineHeight = window->DC.CursorPos.y - 9999.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; window->DC.ChildWindows.resize(0); window->DC.ItemWidth.resize(0); window->DC.ItemWidth.push_back(window->ItemWidthDefault); @@ -6400,7 +6400,7 @@ void ImGui::ListBoxFooter() ImGui::EndChildFrame(); parent_window->DC.CursorPos = bb.Min; - ItemSize(bb, NULL); + ItemSize(bb); } bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) @@ -6698,9 +6698,9 @@ static void ItemSize(ImVec2 size, ImVec2* adjust_vertical_offset) window->DC.CurrentLineHeight = 0.0f; } -static inline void ItemSize(const ImGuiAabb& bb, ImVec2* adjust_start_offset) +static inline void ItemSize(const ImGuiAabb& bb) { - ItemSize(bb.GetSize(), adjust_start_offset); + ItemSize(bb.GetSize()); } static bool IsClipped(const ImGuiAabb& bb) @@ -9225,6 +9225,9 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::Text("World"); // Button + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::Text("Normal buttons"); + ImGui::SameLine(); if (ImGui::Button("Banana")) printf("Pressed!\n"); ImGui::SameLine(); ImGui::Button("Apple"); From 3bd5597cee8e603ad7933e391d6b5a0b84ae0975 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 17:17:00 +0000 Subject: [PATCH 07/44] Moved text vertical centering out of ItemSize() for the moment, in TextUnformatted() it's only user --- imgui.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 791cbb49..a50adbaa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -434,7 +434,7 @@ static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scal static void SetFont(ImFont* font); static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id); -static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL); +static void ItemSize(ImVec2 size); static void ItemSize(const ImGuiAabb& bb); static void PushColumnClipRect(int column_index = -1); static bool IsClipped(const ImGuiAabb& bb); @@ -3964,8 +3964,15 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) { const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); - ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + text_size); - ItemSize(bb.GetSize(), &bb.Min); + ImVec2 text_pos = window->DC.CursorPos; + + // Vertical centering over our line height + // FIXME + const float line_height = ImMax(window->DC.CurrentLineHeight, text_size.y); + text_pos.y += (line_height - text_size.y) * 0.5f; + + ImGuiAabb bb(text_pos, window->DC.CursorPos + text_size); + ItemSize(bb.GetSize()); if (!ItemAdd(bb, NULL)) return; @@ -6677,18 +6684,15 @@ void ImGui::Spacing() } // Advance cursor given item size. -static void ItemSize(ImVec2 size, ImVec2* adjust_vertical_offset) +static void ItemSize(ImVec2 size) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; - const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); - if (adjust_vertical_offset) - adjust_vertical_offset->y = adjust_vertical_offset->y + (line_height - size.y) * 0.5f; - // Always align ourselves on pixel boundaries + const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); From fd7f50d269bfee3d08908be372848c5ae12b159e Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 20:17:53 +0000 Subject: [PATCH 08/44] Various fixes related to vertical alignment of text after widget of various sizes. Added demos. Toward #160 Also fixed LabelText() height. --- imgui.cpp | 230 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 137 insertions(+), 93 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a50adbaa..7cd552b3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -434,8 +434,8 @@ static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scal static void SetFont(ImFont* font); static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id); -static void ItemSize(ImVec2 size); -static void ItemSize(const ImGuiAabb& bb); +static void ItemSize(ImVec2 size, float text_offset_y = 0.0f); +static void ItemSize(const ImGuiAabb& bb, float text_offset_y = 0.0f); static void PushColumnClipRect(int column_index = -1); static bool IsClipped(const ImGuiAabb& bb); @@ -910,7 +910,9 @@ struct ImGuiDrawContext ImVec2 CursorPosPrevLine; ImVec2 CursorStartPos; float CurrentLineHeight; + float CurrentLineTextBaseOffset; float PrevLineHeight; + float PrevLineTextBaseOffset; float LogLinePosY; int TreeDepth; ImGuiID LastItemID; @@ -938,6 +940,7 @@ struct ImGuiDrawContext { CursorPos = CursorPosPrevLine = CursorStartPos = ImVec2(0.0f, 0.0f); CurrentLineHeight = PrevLineHeight = 0.0f; + CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; LogLinePosY = -1.0f; TreeDepth = 0; LastItemID = 0; @@ -3069,6 +3072,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPosPrevLine = window->DC.CursorPos; window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; window->DC.ChildWindows.resize(0); window->DC.ItemWidth.resize(0); @@ -3895,18 +3899,18 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. const char* line = text; const float line_height = ImGui::GetTextLineHeight(); - const ImVec2 start_pos = window->DC.CursorPos; + const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); const ImVec4 clip_rect = window->ClipRectStack.back(); ImVec2 text_size(0,0); - if (start_pos.y <= clip_rect.w) + if (text_pos.y <= clip_rect.w) { - ImVec2 pos = start_pos; + ImVec2 pos = text_pos; // Lines to skip (can't skip when logging text) if (!g.LogEnabled) { - int lines_skippable = (int)((clip_rect.y - start_pos.y) / line_height) - 1; + int lines_skippable = (int)((clip_rect.y - text_pos.y) / line_height) - 1; if (lines_skippable > 0) { int lines_skipped = 0; @@ -3954,9 +3958,10 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) pos.y += lines_skipped * line_height; } - text_size.y += (pos - start_pos).y; + text_size.y += (pos - text_pos).y; } - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + text_size); + + ImGuiAabb bb(text_pos, text_pos + text_size); ItemSize(bb); ItemAdd(bb, NULL); } @@ -3964,14 +3969,12 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) { const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); - ImVec2 text_pos = window->DC.CursorPos; - // Vertical centering over our line height - // FIXME - const float line_height = ImMax(window->DC.CurrentLineHeight, text_size.y); - text_pos.y += (line_height - text_size.y) * 0.5f; + // Account of baseline offset + ImVec2 text_pos = window->DC.CursorPos; + text_pos.y += window->DC.CurrentLineTextBaseOffset; - ImGuiAabb bb(text_pos, window->DC.CursorPos + text_size); + ImGuiAabb bb(text_pos, text_pos + text_size); ItemSize(bb.GetSize()); if (!ItemAdd(bb, NULL)) return; @@ -3989,7 +3992,7 @@ void ImGui::AlignFirstTextHeightToWidgets() return; // Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height. - ItemSize(ImVec2(0, window->FontSize() + g.Style.FramePadding.y*2)); + ItemSize(ImVec2(0, window->FontSize() + g.Style.FramePadding.y*2), g.Style.FramePadding.y); ImGui::SameLine(0, 0); } @@ -4008,15 +4011,15 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y)); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), 0.0f) + label_size); - ItemSize(bb); + const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); + const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(value_bb, NULL)) return; // Render - RenderTextClipped(value_bb.Min, value_text_begin, value_text_end, NULL, value_bb.Max); - RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y), label); + RenderTextClipped(ImVec2(value_bb.Min.x, value_bb.Min.y + style.FramePadding.y), value_text_begin, value_text_end, NULL, value_bb.Max); + RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); } void ImGui::LabelText(const char* label, const char* fmt, ...) @@ -4108,7 +4111,7 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size + style.FramePadding*2.0f); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(bb, &id)) return false; @@ -4137,7 +4140,9 @@ bool ImGui::SmallButton(const char* label) const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + label_size + ImVec2(style.FramePadding.x*2,0)); + ImVec2 text_pos = window->DC.CursorPos; + text_pos.y += window->DC.CurrentLineTextBaseOffset; + ImGuiAabb bb(text_pos, text_pos + label_size + ImVec2(style.FramePadding.x*2,0)); ItemSize(bb); if (!ItemAdd(bb, &id)) return false; @@ -4432,8 +4437,9 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display bb.Max.y += style.FramePadding.y * 2; } + // FIXME: we don't provide our width so that it doesn't get feed back into AutoFit. Should manage that better so we can still hover without extending ContentsSize const ImGuiAabb text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + label_size); - ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit + ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y), display_frame ? style.FramePadding.y : 0.0f); // When logging is enabled, if automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). // NB- If we are above max depth we still allow manually opened nodes to be logged. @@ -4916,7 +4922,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c // NB- we don't call ItemSize() yet becausae we may turn into a text edit box below if (!ItemAdd(frame_bb, &id)) { - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); return false; } @@ -4949,7 +4955,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c if (start_text_input || (g.ActiveId == id && id == g.SliderAsInputTextId)) return SliderFloatAsInputText(label, v, id, decimal_precision); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); // Actual slider behavior + render grab bool value_changed = SliderBehavior(frame_bb, slider_bb, id, v, v_min, v_max, power, decimal_precision, true); @@ -4980,7 +4986,7 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float const ImGuiAabb slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; @@ -5158,7 +5164,7 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); const ImGuiAabb graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(bb, NULL)) return; @@ -5285,7 +5291,7 @@ bool ImGui::Checkbox(const char* label, bool* v) const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); - ItemSize(check_bb); + ItemSize(check_bb, style.FramePadding.y); ImGuiAabb total_bb = check_bb; if (label_size.x > 0) @@ -5293,7 +5299,7 @@ bool ImGui::Checkbox(const char* label, bool* v) const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); if (label_size.x > 0) { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight())); + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); total_bb = ImGuiAabb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); } @@ -5343,7 +5349,7 @@ bool ImGui::RadioButton(const char* label, bool active) const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); - ItemSize(check_bb); + ItemSize(check_bb, style.FramePadding.y); ImGuiAabb total_bb = check_bb; if (label_size.x > 0) @@ -5351,7 +5357,7 @@ bool ImGui::RadioButton(const char* label, bool active) const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); if (label_size.x > 0) { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight())); + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); total_bb.Add(text_bb); } @@ -5617,7 +5623,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, if (label_size.x > 0) { ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - ItemSize(label_size); + ItemSize(label_size, style.FramePadding.y); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); } @@ -5738,7 +5744,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; @@ -6212,7 +6218,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; @@ -6403,11 +6409,12 @@ void ImGui::ListBoxFooter() { ImGuiWindow* parent_window = GetParentWindow(); const ImGuiAabb bb = parent_window->DC.LastItemAabb; + const ImGuiStyle& style = ImGui::GetStyle(); ImGui::EndChildFrame(); parent_window->DC.CursorPos = bb.Min; - ItemSize(bb); + ItemSize(bb, style.FramePadding.y); } bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) @@ -6458,7 +6465,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde const ImGuiID id = window->GetID("#colorbutton"); const float square_size = window->FontSize(); const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); - ItemSize(bb); + ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); if (!ItemAdd(bb, &id)) return false; @@ -6684,7 +6691,7 @@ void ImGui::Spacing() } // Advance cursor given item size. -static void ItemSize(ImVec2 size) +static void ItemSize(ImVec2 size, float text_offset_y) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -6693,18 +6700,20 @@ static void ItemSize(ImVec2 size) // Always align ourselves on pixel boundaries const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); + const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, ImVec2(window->DC.CursorPosPrevLine.x - window->Pos.x, window->DC.CursorPos.y + window->ScrollY - window->Pos.y)); window->DC.PrevLineHeight = line_height; - window->DC.CurrentLineHeight = 0.0f; + window->DC.PrevLineTextBaseOffset = text_base_offset; + window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; } -static inline void ItemSize(const ImGuiAabb& bb) +static inline void ItemSize(const ImGuiAabb& bb, float text_offset_y) { - ItemSize(bb.GetSize()); + ItemSize(bb.GetSize(), text_offset_y); } static bool IsClipped(const ImGuiAabb& bb) @@ -6767,6 +6776,7 @@ void ImGui::SameLine(int column_x, int spacing_w) y = window->DC.CursorPosPrevLine.y; } window->DC.CurrentLineHeight = window->DC.PrevLineHeight; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; window->DC.CursorPos = ImVec2(x, y); } @@ -6796,6 +6806,7 @@ void ImGui::NextColumn() window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX); window->DC.CursorPos.y = window->DC.ColumnsCellMinY; window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; PushColumnClipRect(); ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f); @@ -9079,6 +9090,8 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::Separator(); + ImGui::LabelText("label", "Value"); + static int item = 1; ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); @@ -9189,6 +9202,9 @@ void ImGui::ShowTestWindow(bool* opened) } ImGui::PopID(); + ImGui::SameLine(); + ImGui::Text("Label"); + ImGui::Indent(); ImGui::TreePop(); } @@ -9221,66 +9237,94 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); } - if (ImGui::CollapsingHeader("Horizontal Layout")) + if (ImGui::CollapsingHeader("Layout")) { - // Text - ImGui::Text("Hello"); - ImGui::SameLine(); - ImGui::Text("World"); + if (ImGui::TreeNode("Text Baseline Alignment")) + { + ImGui::TextWrapped("This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets."); - // Button - ImGui::AlignFirstTextHeightToWidgets(); - ImGui::Text("Normal buttons"); - ImGui::SameLine(); - if (ImGui::Button("Banana")) printf("Pressed!\n"); - ImGui::SameLine(); - ImGui::Button("Apple"); - ImGui::SameLine(); - ImGui::Button("Corniflower"); + ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); - // Button - ImGui::Text("Small buttons"); - ImGui::SameLine(); - ImGui::SmallButton("Like this one"); - ImGui::SameLine(); - ImGui::Text("can fit within a text block."); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); - // Checkbox - static bool c1=false,c2=false,c3=false,c4=false; - ImGui::Checkbox("My", &c1); - ImGui::SameLine(); - ImGui::Checkbox("Tailor", &c2); - ImGui::SameLine(); - ImGui::Checkbox("Is", &c3); - ImGui::SameLine(); - ImGui::Checkbox("Rich", &c4); - - // Various - static float f0=1.0f, f1=2.0f, f2=3.0f; - ImGui::PushItemWidth(80); - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; - static int item = -1; - ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); - ImGui::SameLine(); - ImGui::SliderFloat("X", &f0, 0.0f,5.0f); - ImGui::SameLine(); - ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); - ImGui::SameLine(); - ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); - ImGui::PopItemWidth(); + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); - ImGui::PushItemWidth(80); - ImGui::Text("Lists:"); - static int selection[4] = { 0, 1, 2, 3 }; - for (int i = 0; i < 4; i++) + ImGui::Button("TEST"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST"); + + ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); + ImGui::Button("Widget"); ImGui::SameLine(); + ImGui::Text("Widget"); ImGui::SameLine(); + ImGui::SmallButton("Widget"); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Horizontal Layout using SameLine()")) { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); - ImGui::PopID(); - //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); + // Text + ImGui::Text("Hello"); + ImGui::SameLine(); + ImGui::TextColored(ImVec4(1,1,0,1), "World"); + + // Button + ImGui::AlignFirstTextHeightToWidgets(); + ImGui::Text("Normal buttons"); ImGui::SameLine(); + ImGui::Button("Banana"); ImGui::SameLine(); + ImGui::Button("Apple"); ImGui::SameLine(); + ImGui::Button("Corniflower"); + + // Button + ImGui::Text("Small buttons"); ImGui::SameLine(); + ImGui::SmallButton("Like this one"); ImGui::SameLine(); + ImGui::Text("can fit within a text block."); + + // Checkbox + static bool c1=false,c2=false,c3=false,c4=false; + ImGui::Checkbox("My", &c1); ImGui::SameLine(); + ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); + ImGui::Checkbox("Is", &c3); ImGui::SameLine(); + ImGui::Checkbox("Rich", &c4); + + // Various + static float f0=1.0f, f1=2.0f, f2=3.0f; + ImGui::PushItemWidth(80); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; + static int item = -1; + ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); + ImGui::SliderFloat("X", &f0, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); + ImGui::PopItemWidth(); + + ImGui::PushItemWidth(80); + ImGui::Text("Lists:"); + static int selection[4] = { 0, 1, 2, 3 }; + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); + ImGui::PopID(); + //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); + } + ImGui::PopItemWidth(); + + ImGui::TreePop(); } - ImGui::PopItemWidth(); } if (ImGui::CollapsingHeader("Child regions")) From 30bc952ac3e9a2dc115cb09b283f470917c613c8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 22:03:02 +0000 Subject: [PATCH 09/44] Maintaining DC.CursorMaxPos instead of SizeContentsCurrent, simpler, faster and easier to understand. --- imgui.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7cd552b3..dde783bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -909,6 +909,7 @@ struct ImGuiDrawContext ImVec2 CursorPos; ImVec2 CursorPosPrevLine; ImVec2 CursorStartPos; + ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame float CurrentLineHeight; float CurrentLineTextBaseOffset; float PrevLineHeight; @@ -925,7 +926,7 @@ struct ImGuiDrawContext ImGuiColorEditMode ColorEditMode; ImGuiStorage* StateStorage; - float ColumnsStartX; // Start position from left of window (increased by TreePush/TreePop, etc.) + float ColumnsStartX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) float ColumnsOffsetX; // 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. int ColumnsCurrent; int ColumnsCount; @@ -938,7 +939,7 @@ struct ImGuiDrawContext ImGuiDrawContext() { - CursorPos = CursorPosPrevLine = CursorStartPos = ImVec2(0.0f, 0.0f); + CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); CurrentLineHeight = PrevLineHeight = 0.0f; CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; LogLinePosY = -1.0f; @@ -1136,7 +1137,6 @@ struct ImGuiWindow ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame - ImVec2 SizeContentsCurrent; // Size of contents, currently extending float ScrollY; float NextScrollY; bool ScrollbarY; @@ -1478,7 +1478,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Flags = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); - SizeContents = SizeContentsCurrent = ImVec2(0.0f, 0.0f); + SizeContents = ImVec2(0.0f, 0.0f); ScrollY = 0.0f; NextScrollY = 0.0f; ScrollbarY = false; @@ -2823,8 +2823,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->ClipRectStack.resize(0); // Reset contents size for auto-fitting - window->SizeContents = window->SizeContentsCurrent; - window->SizeContentsCurrent = ImVec2(0.0f, 0.0f); + window->SizeContents = window->DC.CursorMaxPos - window->Pos; + window->SizeContents.y += window->ScrollY; if (flags & ImGuiWindowFlags_ChildWindow) { @@ -3071,6 +3071,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.ColumnsStartX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->WindowPadding().y) - ImVec2(0.0f, window->ScrollY); window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPosPrevLine = window->DC.CursorPos; + window->DC.CursorMaxPos = window->DC.CursorStartPos; window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; @@ -3762,21 +3763,21 @@ void ImGui::SetCursorPos(const ImVec2& pos) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos = window->Pos + pos; - window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, pos + ImVec2(0.0f, window->ScrollY)); + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); } void ImGui::SetCursorPosX(float x) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos.x = window->Pos.x + x; - window->SizeContentsCurrent.x = ImMax(window->SizeContentsCurrent.x, x); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); } void ImGui::SetCursorPosY(float y) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos.y = window->Pos.y + y; - window->SizeContentsCurrent.y = ImMax(window->SizeContentsCurrent.y, y + window->ScrollY); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); } ImVec2 ImGui::GetCursorScreenPos() @@ -6703,8 +6704,10 @@ static void ItemSize(ImVec2 size, float text_offset_y) const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnsStartX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - window->SizeContentsCurrent = ImMax(window->SizeContentsCurrent, ImVec2(window->DC.CursorPosPrevLine.x - window->Pos.x, window->DC.CursorPos.y + window->ScrollY - window->Pos.y)); + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; From 2e63bf1d160b6771d0458d6e5d933b2d79962eea Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 22:27:00 +0000 Subject: [PATCH 10/44] Button() doesn't add frame padding an explicit size --- imgui.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dde783bf..a7e79842 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4110,8 +4110,8 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size + style.FramePadding*2.0f); + const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : (label_size.x + style.FramePadding.x*2), size_arg.y != 0.0f ? size_arg.y : (label_size.y + style.FramePadding.y*2)); + const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(bb, &id)) return false; @@ -4124,7 +4124,7 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); const ImVec2 off = ImVec2(ImMax(0.0f, size.x - label_size.x) * 0.5f, ImMax(0.0f, size.y - label_size.y) * 0.5f); // Center (only applies if we explicitly gave a size bigger than the text size, which isn't the common path) - RenderTextClipped(bb.Min + style.FramePadding + off, label, NULL, &label_size, bb.Max); // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path) + RenderTextClipped(bb.Min + off, label, NULL, &label_size, bb.Max); // Render clip (only applies if we explicitly gave a size smaller than the text size, which isn't the commmon path) return pressed; } @@ -5584,9 +5584,9 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); ImGui::PushID(label); - const float button_sz = window->FontSize(); + const ImVec2 button_sz = ImVec2(window->FontSize(), window->FontSize()) + style.FramePadding * 2; if (step > 0.0f) - ImGui::PushItemWidth(ImMax(1.0f, w - (button_sz + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*2)); + ImGui::PushItemWidth(ImMax(1.0f, w - (button_sz.x + style.ItemInnerSpacing.x)*2)); char buf[64]; if (decimal_precision < 0) @@ -5606,13 +5606,13 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, { ImGui::PopItemWidth(); ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - if (ImGui::Button("-", ImVec2(button_sz,button_sz), true)) + if (ImGui::Button("-", button_sz, true)) { *v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; value_changed = true; } ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); - if (ImGui::Button("+", ImVec2(button_sz,button_sz), true)) + if (ImGui::Button("+", button_sz, true)) { *v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step; value_changed = true; @@ -6707,7 +6707,7 @@ static void ItemSize(ImVec2 size, float text_offset_y) window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; From da4bfe32899b5062d244119db4a139e957af3390 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 22:36:54 +0000 Subject: [PATCH 11/44] Added GetItemRectSize(). Renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHovering --- imgui.cpp | 35 +++++++++++++++++++++-------------- imgui.h | 16 ++++++++++------ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a7e79842..d2a09d25 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -129,10 +129,11 @@ Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing - - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function. + - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete). - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth - - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function. + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function (will obsolete). - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior @@ -439,7 +440,7 @@ static void ItemSize(const ImGuiAabb& bb, float text_offset_y = 0.0f); static void PushColumnClipRect(int column_index = -1); static bool IsClipped(const ImGuiAabb& bb); -static bool IsMouseHoveringBox(const ImGuiAabb& bb); +static bool IsMouseHoveringRect(const ImGuiAabb& bb); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static void Scrollbar(ImGuiWindow* window); @@ -2419,7 +2420,7 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) // Test if mouse cursor is hovering given aabb // NB- Box is clipped by our current clip setting // NB- Expand the aabb to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -static bool IsMouseHoveringBox(const ImGuiAabb& bb) +static bool IsMouseHoveringRect(const ImGuiAabb& bb) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -2437,9 +2438,9 @@ static bool IsMouseHoveringBox(const ImGuiAabb& bb) return box_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max) +bool ImGui::IsMouseHoveringRect(const ImVec2& box_min, const ImVec2& box_max) { - return IsMouseHoveringBox(ImGuiAabb(box_min, box_max)); + return IsMouseHoveringRect(ImGuiAabb(box_min, box_max)); } bool ImGui::IsMouseHoveringWindow() @@ -2538,18 +2539,24 @@ bool ImGui::IsAnyItemActive() return g.ActiveId != 0; } -ImVec2 ImGui::GetItemBoxMin() +ImVec2 ImGui::GetItemRectMin() { ImGuiWindow* window = GetCurrentWindow(); return window->DC.LastItemAabb.Min; } -ImVec2 ImGui::GetItemBoxMax() +ImVec2 ImGui::GetItemRectMax() { ImGuiWindow* window = GetCurrentWindow(); return window->DC.LastItemAabb.Max; } +ImVec2 ImGui::GetItemRectSize() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemAabb.GetSize(); +} + // Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. void ImGui::SetTooltipV(const char* fmt, va_list args) { @@ -2927,7 +2934,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Collapse window by double-clicking on title bar if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) { - if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringBox(title_bar_aabb) && g.IO.MouseDoubleClicked[0]) + if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringRect(title_bar_aabb) && g.IO.MouseDoubleClicked[0]) { window->Collapsed = !window->Collapsed; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) @@ -4039,7 +4046,7 @@ static bool IsHovered(const ImGuiAabb& bb, ImGuiID id) ImGuiWindow* window = GetCurrentWindow(); if (g.HoveredRootWindow == window->RootWindow) { - bool hovered = (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringBox(bb); + bool hovered = (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb); return hovered; } } @@ -5194,7 +5201,7 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett // Tooltip on hover int v_hovered = -1; - if (IsMouseHoveringBox(graph_bb)) + if (IsMouseHoveringRect(graph_bb)) { const float t = ImClamp((g.IO.MousePos.x - graph_bb.Min.x) / (graph_bb.Max.x - graph_bb.Min.x), 0.0f, 0.9999f); const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0))); @@ -6747,7 +6754,7 @@ static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id) } // This is a sensible default, but widgets are free to override it after calling ItemAdd() - const bool hovered = IsMouseHoveringBox(bb); + const bool hovered = IsMouseHoveringRect(bb); //const bool hovered = (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly) && IsMouseHoveringBox(bb); // matching the behavior of IsHovered(), not always what the user wants? window->DC.LastItemHovered = hovered; return true; @@ -8917,14 +8924,14 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); ImGui::Text("lazy dog. This paragraph is made to fit within %.0f pixels. The quick brown fox jumps over the lazy dog.", wrap_width); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemBoxMin(), ImGui::GetItemBoxMax(), 0xFF00FFFF); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); ImGui::PopTextWrapPos(); ImGui::Text("Test paragraph 2:"); ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetCursorScreenPos() + ImVec2(wrap_width, 0.0f), ImGui::GetCursorScreenPos() + ImVec2(wrap_width+10, ImGui::GetTextLineHeight()), 0xFFFF00FF); ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); ImGui::Text("aaaaaaaa bbbbbbbb, cccccccc,dddddddd. eeeeeeee ffffffff. gggggggg!hhhhhhhh"); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemBoxMin(), ImGui::GetItemBoxMax(), 0xFF00FFFF); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF); ImGui::PopTextWrapPos(); ImGui::TreePop(); diff --git a/imgui.h b/imgui.h index 53e66b70..f72315d8 100644 --- a/imgui.h +++ b/imgui.h @@ -354,15 +354,16 @@ namespace ImGui IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) IMGUI_API bool IsRootWindowFocused(); // is current root window focused IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused - IMGUI_API ImVec2 GetItemBoxMin(); // get bounding box of last item - IMGUI_API ImVec2 GetItemBoxMax(); // get bounding box of last item + IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item + IMGUI_API ImVec2 GetItemRectMax(); // " + IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimization) IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry IMGUI_API bool IsMouseClicked(int button, bool repeat = false); IMGUI_API bool IsMouseDoubleClicked(int button); IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window) IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window - IMGUI_API bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max); // is mouse hovering given bounding box + IMGUI_API bool IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max);// is mouse hovering given bounding rect IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API float GetTime(); @@ -385,9 +386,12 @@ namespace ImGui IMGUI_API void SetInternalState(void* state, bool construct = false); // Obsolete (will be removed) - IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); - static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } - static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } + IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size); // OBSOLETE + static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE + static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE + static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE + static inline ImVec2 GetItemBoxMax() { return GetItemRectMin(); } // OBSOLETE + static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE } // namespace ImGui From 7e297945c3b3d2c742cfb3b30f0d46c262a265f7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 23:28:57 +0000 Subject: [PATCH 12/44] Added BeginGroup() / EndGroup() layout tools (#160) --- imgui.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- imgui.h | 4 +- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d2a09d25..28e3c574 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -904,6 +904,16 @@ struct ImGuiAabb // 2D axis aligned bounding-box void Clip(const ImGuiAabb& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } }; +struct ImGuiGroupData +{ + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + float BackupColumnsStartX; + float BackupCurrentLineHeight; + float BackupCurrentLineTextBaseOffset; + float BackupLogLinePosY; +}; + // Temporary per-window data, reset at the beginning of the frame struct ImGuiDrawContext { @@ -924,6 +934,7 @@ struct ImGuiDrawContext ImVector AllowKeyboardFocus; ImVector ItemWidth; // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window ImVector TextWrapPos; + ImVector GroupStack; ImGuiColorEditMode ColorEditMode; ImGuiStorage* StateStorage; @@ -3096,6 +3107,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPos.y; window->DC.TreeDepth = 0; window->DC.StateStorage = &window->StateStorage; + window->DC.GroupStack.resize(0); if (window->AutoFitFrames > 0) window->AutoFitFrames--; @@ -6383,8 +6395,8 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. ImVec2 size; - size.x = (size_arg.x != 0.0f) ? size_arg.x : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f; - size.y = (size_arg.y != 0.0f) ? size_arg.y : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y; + size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f; + size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y; const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); @@ -6421,6 +6433,9 @@ void ImGui::ListBoxFooter() ImGui::EndChildFrame(); + // Redeclare item size so that it includes the label (we have stored the full size in LastItemAabb) + // We call SameLine() to restore DC.CurrentLine* data + ImGui::SameLine(); parent_window->DC.CursorPos = bb.Min; ItemSize(bb, style.FramePadding.y); } @@ -6760,6 +6775,52 @@ static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id) return true; } +void ImGui::BeginGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + + window->DC.GroupStack.resize(window->DC.GroupStack.size() + 1); + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + group_data.BackupCursorPos = window->DC.CursorPos; + group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; + group_data.BackupColumnsStartX = window->DC.ColumnsStartX; + group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; + group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; + group_data.BackupLogLinePosY = window->DC.LogLinePosY; + + window->DC.ColumnsStartX = window->DC.CursorPos.x - window->Pos.x; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.CurrentLineHeight = 0.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; +} + +void ImGui::EndGroup() +{ + ImGuiWindow* window = GetCurrentWindow(); + ImGuiStyle& style = ImGui::GetStyle(); + + IM_ASSERT(!window->DC.GroupStack.empty()); + + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + + ImGuiAabb group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); + group_bb.Max.y -= style.ItemSpacing.y; + + window->DC.CursorPos = group_data.BackupCursorPos; + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; + window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; // FIXME: Ideally we'll grab the base offset from the first line of the group. + window->DC.ColumnsStartX = group_data.BackupColumnsStartX; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + + ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); + ItemAdd(group_bb, NULL); + + window->DC.GroupStack.pop_back(); + + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, 0xFFFF00FF); // Debug +} + // Gets back to previous line and continue with horizontal layout // column_x == 0 : follow on previous item // columm_x != 0 : align to specified column @@ -9251,7 +9312,7 @@ void ImGui::ShowTestWindow(bool* opened) { if (ImGui::TreeNode("Text Baseline Alignment")) { - ImGui::TextWrapped("This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets."); + ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); @@ -9283,8 +9344,10 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::TreePop(); } - if (ImGui::TreeNode("Horizontal Layout using SameLine()")) + if (ImGui::TreeNode("Basic Horizontal Layout")) { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)"); + // Text ImGui::Text("Hello"); ImGui::SameLine(); @@ -9335,6 +9398,50 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::TreePop(); } + + if (ImGui::TreeNode("Groups")) + { + ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items)"); + + ImVec2 size; + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Group hovered"); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + + // Capture the group size and create widgets using the same size + size = ImGui::GetItemRectSize(); + const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; + ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); + } + ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::SameLine(); + ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::Button("LEVERAGE\nBUZZWORD", size); + ImGui::SameLine(); + + ImGui::ListBoxHeader("List", size); + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::ListBoxFooter(); + + ImGui::TreePop(); + } } if (ImGui::CollapsingHeader("Child regions")) diff --git a/imgui.h b/imgui.h index f72315d8..9d8fbf09 100644 --- a/imgui.h +++ b/imgui.h @@ -223,8 +223,10 @@ namespace ImGui IMGUI_API void EndTooltip(); // Layout + IMGUI_API void BeginGroup(); + IMGUI_API void EndGroup(); IMGUI_API void Separator(); // horizontal line - IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally + IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets or groups to layout them horizontally IMGUI_API void Spacing(); // add vertical spacing IMGUI_API void Indent(); // move content position toward the right by style.IndentSpacing pixels IMGUI_API void Unindent(); // move content position back to the left (cancel Indent) From 302316c6cfd61995d4a3554fac066d8076975eda Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 23:35:12 +0000 Subject: [PATCH 13/44] Renamed internal type ImGuiAabb to ImRect --- imgui.cpp | 225 +++++++++++++++++++++++++++--------------------------- 1 file changed, 113 insertions(+), 112 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 28e3c574..618c54aa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -251,7 +251,7 @@ ISSUES & TODO-LIST ================== - - misc: merge or clarify ImVec4 / ImGuiAabb, they are essentially duplicate containers + - misc: merge or clarify ImVec4 / ImRect, they are essentially duplicate containers - window: add horizontal scroll - window: fix resize grip rendering scaling along with Rounding style setting - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit? @@ -415,16 +415,16 @@ using namespace IMGUI_STB_NAMESPACE; // Forward Declarations //------------------------------------------------------------------------- +struct ImRect; struct ImGuiColMod; struct ImGuiStyleMod; -struct ImGuiAabb; struct ImGuiDrawContext; struct ImGuiTextEditState; struct ImGuiIniData; struct ImGuiState; struct ImGuiWindow; -static bool ButtonBehavior(const ImGuiAabb& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false); +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false); static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); @@ -434,13 +434,13 @@ static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); static void SetFont(ImFont* font); -static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id); +static bool ItemAdd(const ImRect& bb, const ImGuiID* id); static void ItemSize(ImVec2 size, float text_offset_y = 0.0f); -static void ItemSize(const ImGuiAabb& bb, float text_offset_y = 0.0f); +static void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); static void PushColumnClipRect(int column_index = -1); -static bool IsClipped(const ImGuiAabb& bb); +static bool IsClipped(const ImRect& bb); -static bool IsMouseHoveringRect(const ImGuiAabb& bb); +static bool IsMouseHoveringRect(const ImRect& bb); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static void Scrollbar(ImGuiWindow* window); @@ -877,32 +877,33 @@ struct ImGuiStyleMod // Style modifier, backup of modified data so we can res ImVec2 PreviousValue; }; -struct ImGuiAabb // 2D axis aligned bounding-box +struct ImRect // 2D axis aligned bounding-box { ImVec2 Min; ImVec2 Max; - ImGuiAabb() { Min = ImVec2(FLT_MAX,FLT_MAX); Max = ImVec2(-FLT_MAX,-FLT_MAX); } - ImGuiAabb(const ImVec2& min, const ImVec2& max) { Min = min; Max = max; } - ImGuiAabb(const ImVec4& v) { Min.x = v.x; Min.y = v.y; Max.x = v.z; Max.y = v.w; } - ImGuiAabb(float x1, float y1, float x2, float y2) { Min.x = x1; Min.y = y1; Max.x = x2; Max.y = y2; } - - ImVec2 GetCenter() const { return Min + (Max-Min)*0.5f; } - ImVec2 GetSize() const { return Max-Min; } - float GetWidth() const { return (Max-Min).x; } - float GetHeight() const { return (Max-Min).y; } - ImVec2 GetTL() const { return Min; } - ImVec2 GetTR() const { return ImVec2(Max.x,Min.y); } - ImVec2 GetBL() const { return ImVec2(Min.x,Max.y); } - ImVec2 GetBR() const { return Max; } - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x <= Max.x && p.y <= Max.y; } - bool Contains(const ImGuiAabb& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } - bool Overlaps(const ImGuiAabb& r) const { return r.Min.y <= Max.y && r.Max.y >= Min.y && r.Min.x <= Max.x && r.Max.x >= Min.x; } - void Add(const ImVec2& rhs) { Min.x = ImMin(Min.x, rhs.x); Min.y = ImMin(Min.y, rhs.y); Max.x = ImMax(Max.x, rhs.x); Max.y = ImMax(Max.x, rhs.x); } - void Add(const ImGuiAabb& rhs) { Min.x = ImMin(Min.x, rhs.Min.x); Min.y = ImMin(Min.y, rhs.Min.y); Max.x = ImMax(Max.x, rhs.Max.x); Max.y = ImMax(Max.y, rhs.Max.y); } - void Expand(const ImVec2& sz) { Min -= sz; Max += sz; } - void Clip(const ImGuiAabb& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } + ImRect() { Min = ImVec2(FLT_MAX,FLT_MAX); Max = ImVec2(-FLT_MAX,-FLT_MAX); } + ImRect(const ImVec2& min, const ImVec2& max) { Min = min; Max = max; } + ImRect(const ImVec4& v) { Min.x = v.x; Min.y = v.y; Max.x = v.z; Max.y = v.w; } + ImRect(float x1, float y1, float x2, float y2) { Min.x = x1; Min.y = y1; Max.x = x2; Max.y = y2; } + + ImVec2 GetCenter() const { return Min + (Max-Min)*0.5f; } + ImVec2 GetSize() const { return Max-Min; } + float GetWidth() const { return (Max-Min).x; } + float GetHeight() const { return (Max-Min).y; } + ImVec2 GetTL() const { return Min; } + ImVec2 GetTR() const { return ImVec2(Max.x,Min.y); } + ImVec2 GetBL() const { return ImVec2(Min.x,Max.y); } + ImVec2 GetBR() const { return Max; } + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x <= Max.x && p.y <= Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y <= Max.y && r.Max.y >= Min.y && r.Min.x <= Max.x && r.Max.x >= Min.x; } + void Add(const ImVec2& rhs) { Min.x = ImMin(Min.x, rhs.x); Min.y = ImMin(Min.y, rhs.y); Max.x = ImMax(Max.x, rhs.x); Max.y = ImMax(Max.x, rhs.x); } + void Add(const ImRect& rhs) { Min.x = ImMin(Min.x, rhs.Min.x); Min.y = ImMin(Min.y, rhs.Min.y); Max.x = ImMax(Max.x, rhs.Max.x); Max.y = ImMax(Max.y, rhs.Max.y); } + void Expand(const ImVec2& sz) { Min -= sz; Max += sz; } + void Clip(const ImRect& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } }; +typedef ImRect ImGuiAabb; // FIXME-OBSOLETE struct ImGuiGroupData { @@ -928,7 +929,7 @@ struct ImGuiDrawContext float LogLinePosY; int TreeDepth; ImGuiID LastItemID; - ImGuiAabb LastItemAabb; + ImRect LastItemRect; bool LastItemHovered; ImVector ChildWindows; ImVector AllowKeyboardFocus; @@ -957,7 +958,7 @@ struct ImGuiDrawContext LogLinePosY = -1.0f; TreeDepth = 0; LastItemID = 0; - LastItemAabb = ImGuiAabb(0.0f,0.0f,0.0f,0.0f); + LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); LastItemHovered = false; StateStorage = NULL; @@ -1165,7 +1166,7 @@ struct ImGuiWindow ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector ClipRectStack; // Scissoring / clipping rectangle. x1, y1, x2, y2. - ImGuiAabb ClippedAabb; // = ClipRectStack.front() after setup in Begin() + ImRect ClippedRect; // = ClipRectStack.front() after setup in Begin() int LastFrameDrawn; float ItemWidthDefault; ImGuiStorage StateStorage; @@ -1192,12 +1193,12 @@ public: bool FocusItemRegister(bool is_active, bool tab_stop = true); // Return true if focus is requested void FocusItemUnregister(); - ImGuiAabb Aabb() const { return ImGuiAabb(Pos, Pos+Size); } + ImRect Aabb() const { return ImRect(Pos, Pos+Size); } ImFont* Font() const { return GImGui->Font; } float FontSize() const { return GImGui->FontSize * FontWindowScale; } ImVec2 CursorPos() const { return DC.CursorPos; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui->Style.FramePadding.y * 2.0f; } - ImGuiAabb TitleBarAabb() const { return ImGuiAabb(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } + ImRect TitleBarAabb() const { return ImRect(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } ImVec2 WindowPadding() const { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders)) ? ImVec2(0,0) : GImGui->Style.WindowPadding; } ImU32 Color(ImGuiCol idx, float a=1.f) const { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * a; return ImGui::ColorConvertFloat4ToU32(c); } ImU32 Color(const ImVec4& col) const { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } @@ -2421,37 +2422,37 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) continue; // Using the clipped AABB so a child window will typically be clipped by its parent. - ImGuiAabb bb(window->ClippedAabb.Min - g.Style.TouchExtraPadding, window->ClippedAabb.Max + g.Style.TouchExtraPadding); + ImRect bb(window->ClippedRect.Min - g.Style.TouchExtraPadding, window->ClippedRect.Max + g.Style.TouchExtraPadding); if (bb.Contains(pos)) return window; } return NULL; } -// Test if mouse cursor is hovering given aabb +// Test if mouse cursor is hovering given rectangle // NB- Box is clipped by our current clip setting -// NB- Expand the aabb to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -static bool IsMouseHoveringRect(const ImGuiAabb& bb) +// NB- Expand the AABB to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) +static bool IsMouseHoveringRect(const ImRect& bb) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); // Clip - ImGuiAabb box_clipped = bb; + ImRect box_clipped = bb; if (!window->ClipRectStack.empty()) { const ImVec4 clip_rect = window->ClipRectStack.back(); - box_clipped.Clip(ImGuiAabb(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); + box_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); } // Expand for touch input - const ImGuiAabb box_for_touch(box_clipped.Min - g.Style.TouchExtraPadding, box_clipped.Max + g.Style.TouchExtraPadding); + const ImRect box_for_touch(box_clipped.Min - g.Style.TouchExtraPadding, box_clipped.Max + g.Style.TouchExtraPadding); return box_for_touch.Contains(g.IO.MousePos); } bool ImGui::IsMouseHoveringRect(const ImVec2& box_min, const ImVec2& box_max) { - return IsMouseHoveringRect(ImGuiAabb(box_min, box_max)); + return IsMouseHoveringRect(ImRect(box_min, box_max)); } bool ImGui::IsMouseHoveringWindow() @@ -2553,19 +2554,19 @@ bool ImGui::IsAnyItemActive() ImVec2 ImGui::GetItemRectMin() { ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemAabb.Min; + return window->DC.LastItemRect.Min; } ImVec2 ImGui::GetItemRectMax() { ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemAabb.Max; + return window->DC.LastItemRect.Max; } ImVec2 ImGui::GetItemRectSize() { ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemAabb.GetSize(); + return window->DC.LastItemRect.GetSize(); } // Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. @@ -2673,7 +2674,7 @@ void ImGui::EndChild() ImGui::End(); window = GetCurrentWindow(); - ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + sz); + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); ItemSize(sz); ItemAdd(bb, NULL); } @@ -2932,7 +2933,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX; - ImGuiAabb title_bar_aabb = window->TitleBarAabb(); + ImRect title_bar_aabb = window->TitleBarAabb(); // Apply and ImClamp scrolling window->ScrollY = window->NextScrollY; @@ -3002,7 +3003,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg else if (!(window->Flags & ImGuiWindowFlags_NoResize)) { // Manual resize grip - const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR()); + const ImRect resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR()); const ImGuiID resize_id = window->GetID("#RESIZE"); bool hovered, held; ButtonBehavior(resize_aabb, resize_id, &hovered, &held, true); @@ -3131,8 +3132,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() - window->ClippedAabb = window->Aabb(); - window->ClippedAabb.Clip(window->ClipRectStack.front()); + window->ClippedRect = window->Aabb(); + window->ClippedRect.Clip(window->ClipRectStack.front()); // Pressing CTRL+C while holding on a window copy its content to the clipboard // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. @@ -3146,7 +3147,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Inner clipping rectangle // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - const ImGuiAabb title_bar_aabb = window->TitleBarAabb(); + const ImRect title_bar_aabb = window->TitleBarAabb(); ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Aabb().Max.y-1.5f); if (window->ScrollbarY) clip_rect.z -= style.ScrollbarWidth; @@ -3210,7 +3211,7 @@ static void Scrollbar(ImGuiWindow* window) const ImGuiID id = window->GetID("#SCROLLY"); // Render background - ImGuiAabb bb(window->Aabb().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Aabb().Max.x, window->Aabb().Max.y-1); + ImRect bb(window->Aabb().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Aabb().Max.x, window->Aabb().Max.y-1); window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg)); bb.Expand(ImVec2(-3,-3)); const float scrollbar_height = bb.GetHeight(); @@ -3947,7 +3948,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // Lines to render if (line < text_end) { - ImGuiAabb line_box(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); + ImRect line_box(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); while (line < text_end) { const char* line_end = strchr(line, '\n'); @@ -3981,7 +3982,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) text_size.y += (pos - text_pos).y; } - ImGuiAabb bb(text_pos, text_pos + text_size); + ImRect bb(text_pos, text_pos + text_size); ItemSize(bb); ItemAdd(bb, NULL); } @@ -3994,7 +3995,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) ImVec2 text_pos = window->DC.CursorPos; text_pos.y += window->DC.CurrentLineTextBaseOffset; - ImGuiAabb bb(text_pos, text_pos + text_size); + ImRect bb(text_pos, text_pos + text_size); ItemSize(bb.GetSize()); if (!ItemAdd(bb, NULL)) return; @@ -4031,8 +4032,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); + const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(value_bb, NULL)) return; @@ -4050,7 +4051,7 @@ void ImGui::LabelText(const char* label, const char* fmt, ...) va_end(args); } -static bool IsHovered(const ImGuiAabb& bb, ImGuiID id) +static bool IsHovered(const ImRect& bb, ImGuiID id) { ImGuiState& g = *GImGui; if (g.HoveredId == 0) @@ -4065,7 +4066,7 @@ static bool IsHovered(const ImGuiAabb& bb, ImGuiID id) return false; } -static bool ButtonBehavior(const ImGuiAabb& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat, bool pressed_on_click) +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat, bool pressed_on_click) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -4130,7 +4131,7 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : (label_size.x + style.FramePadding.x*2), size_arg.y != 0.0f ? size_arg.y : (label_size.y + style.FramePadding.y*2)); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(bb, &id)) return false; @@ -4162,7 +4163,7 @@ bool ImGui::SmallButton(const char* label) ImVec2 text_pos = window->DC.CursorPos; text_pos.y += window->DC.CurrentLineTextBaseOffset; - ImGuiAabb bb(text_pos, text_pos + label_size + ImVec2(style.FramePadding.x*2,0)); + ImRect bb(text_pos, text_pos + label_size + ImVec2(style.FramePadding.x*2,0)); ItemSize(bb); if (!ItemAdd(bb, &id)) return false; @@ -4187,7 +4188,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size) return false; const ImGuiID id = window->GetID(str_id); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); if (!ItemAdd(bb, &id)) return false; @@ -4205,7 +4206,7 @@ static bool CloseWindowButton(bool* p_opened) const ImGuiID id = window->GetID("#CLOSE"); const float size = window->TitleBarHeight() - 4.0f; - const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-3.0f-size,2.0f), window->Aabb().GetTR() + ImVec2(-3.0f,2.0f+size)); + const ImRect bb(window->Aabb().GetTR() + ImVec2(-3.0f-size,2.0f), window->Aabb().GetTR() + ImVec2(-3.0f,2.0f+size)); bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); @@ -4234,7 +4235,7 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& if (window->SkipItems) return; - ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size); + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); if (border_col.w > 0.0f) bb.Max += ImVec2(2,2); ItemSize(bb); @@ -4272,8 +4273,8 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I ImGui::PopID(); const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); - const ImGuiAabb image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); + const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); ItemSize(bb); if (!ItemAdd(bb, &id)) return false; @@ -4449,7 +4450,7 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImVec2 pos_min = window->DC.CursorPos; const ImVec2 pos_max = window->Pos + GetContentRegionMax(); - ImGuiAabb bb = ImGuiAabb(pos_min, ImVec2(pos_max.x, pos_min.y + label_size.y)); + ImRect bb = ImRect(pos_min, ImVec2(pos_max.x, pos_min.y + label_size.y)); if (display_frame) { bb.Min.x -= window_padding.x*0.5f - 1; @@ -4458,7 +4459,7 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display } // FIXME: we don't provide our width so that it doesn't get feed back into AutoFit. Should manage that better so we can still hover without extending ContentsSize - const ImGuiAabb text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + label_size); + const ImRect text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + label_size); ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y), display_frame ? style.FramePadding.y : 0.0f); // When logging is enabled, if automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). @@ -4520,7 +4521,7 @@ void ImGui::Bullet() const ImGuiStyle& style = g.Style; const float line_height = window->FontSize(); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height, line_height)); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height, line_height)); ItemSize(bb); if (!ItemAdd(bb, NULL)) return; @@ -4547,7 +4548,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) const ImGuiStyle& style = g.Style; const float line_height = window->FontSize(); const ImVec2 label_size = CalcTextSize(text_begin, text_end, true); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (label_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + label_size); // Empty text doesn't add padding + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (label_size.x > 0.0f ? (style.FramePadding.x*2) : 0.0f),0) + label_size); // Empty text doesn't add padding ItemSize(bb); if (!ItemAdd(bb, NULL)) return; @@ -4779,7 +4780,7 @@ static void ParseFormat(const char* fmt, int& decimal_precision) } } -static bool SliderBehavior(const ImGuiAabb& frame_bb, const ImGuiAabb& slider_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) +static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -4907,11 +4908,11 @@ static bool SliderBehavior(const ImGuiAabb& frame_bb, const ImGuiAabb& slider_bb if (!horizontal) grab_t = 1.0f - grab_t; const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); - ImGuiAabb grab_bb; + ImRect grab_bb; if (horizontal) - grab_bb = ImGuiAabb(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + 2.0f), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - 2.0f)); + grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + 2.0f), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - 2.0f)); else - grab_bb = ImGuiAabb(ImVec2(frame_bb.Min.x + 2.0f, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - 2.0f, grab_pos + grab_sz*0.5f)); + grab_bb = ImRect(ImVec2(frame_bb.Min.x + 2.0f, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - 2.0f, grab_pos + grab_sz*0.5f)); window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, window->Color(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab)); } @@ -4935,9 +4936,9 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c const float w = ImGui::CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImGuiAabb slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); // NB- we don't call ItemSize() yet becausae we may turn into a text edit box below if (!ItemAdd(frame_bb, &id)) @@ -5002,9 +5003,9 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImGuiAabb slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) @@ -5181,9 +5182,9 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett if (graph_size.y == 0.0f) graph_size.y = label_size.y + (style.FramePadding.y * 2); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); - const ImGuiAabb graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); + const ImRect graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(bb, NULL)) return; @@ -5310,17 +5311,17 @@ bool ImGui::Checkbox(const char* label, bool* v) const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); ItemSize(check_bb, style.FramePadding.y); - ImGuiAabb total_bb = check_bb; + ImRect total_bb = check_bb; if (label_size.x > 0) SameLine(0, (int)style.ItemInnerSpacing.x); - const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); if (label_size.x > 0) { ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); - total_bb = ImGuiAabb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); + total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); } if (!ItemAdd(total_bb, &id)) @@ -5368,13 +5369,13 @@ bool ImGui::RadioButton(const char* label, bool active) const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); ItemSize(check_bb, style.FramePadding.y); - ImGuiAabb total_bb = check_bb; + ImRect total_bb = check_bb; if (label_size.x > 0) SameLine(0, (int)style.ItemInnerSpacing.x); - const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); if (label_size.x > 0) { ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); @@ -5600,7 +5601,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, const ImGuiStyle& style = g.Style; const float w = ImGui::CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); ImGui::PushID(label); const ImVec2 button_sz = ImVec2(window->FontSize(), window->FontSize()) + style.FramePadding * 2; @@ -5762,8 +5763,8 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT const float w = ImGui::CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; @@ -6236,8 +6237,8 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float w = ImGui::CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; @@ -6246,7 +6247,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const bool hovered = IsHovered(frame_bb, id); bool value_changed = false; - const ImGuiAabb value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); + const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); @@ -6284,7 +6285,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const ImVec2 backup_pos = ImGui::GetCursorPos(); const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x; const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + style.WindowPadding.y; - const ImGuiAabb popup_aabb(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); + const ImRect popup_aabb(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); ImGui::SetCursorPos(popup_aabb.Min - window->Pos); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); @@ -6341,11 +6342,11 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) const float w = window->Pos.x + ImGui::GetContentRegionMax().x - window->DC.CursorPos.x; const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : w, size_arg.y != 0.0f ? size_arg.y : label_size.y); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); // Selectables are meant to be tightly packed together. So for both rendering and collision we extend to compensate for spacing. - ImGuiAabb bb_with_spacing = bb; + ImRect bb_with_spacing = bb; const float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); const float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); const float spacing_R = style.ItemSpacing.x - spacing_L; @@ -6398,9 +6399,9 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f; size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y; const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); - const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); - const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - window->DC.LastItemAabb = bb; + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + window->DC.LastItemRect = bb; if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -6428,7 +6429,7 @@ bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_item void ImGui::ListBoxFooter() { ImGuiWindow* parent_window = GetParentWindow(); - const ImGuiAabb bb = parent_window->DC.LastItemAabb; + const ImRect bb = parent_window->DC.LastItemRect; const ImGuiStyle& style = ImGui::GetStyle(); ImGui::EndChildFrame(); @@ -6487,7 +6488,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID("#colorbutton"); const float square_size = window->FontSize(); - const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); if (!ItemAdd(bb, &id)) return false; @@ -6681,7 +6682,7 @@ void ImGui::Separator() if (window->DC.ColumnsCount > 1) PopClipRect(); - const ImGuiAabb bb(ImVec2(window->Pos.x, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x, window->DC.CursorPos.y)); + const ImRect bb(ImVec2(window->Pos.x, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x, window->DC.CursorPos.y)); ItemSize(ImVec2(0.0f, bb.GetSize().y)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit if (!ItemAdd(bb, NULL)) { @@ -6736,17 +6737,17 @@ static void ItemSize(ImVec2 size, float text_offset_y) window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; } -static inline void ItemSize(const ImGuiAabb& bb, float text_offset_y) +static inline void ItemSize(const ImRect& bb, float text_offset_y) { ItemSize(bb.GetSize(), text_offset_y); } -static bool IsClipped(const ImGuiAabb& bb) +static bool IsClipped(const ImRect& bb) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - if (!bb.Overlaps(ImGuiAabb(window->ClipRectStack.back())) && !g.LogEnabled) + if (!bb.Overlaps(ImRect(window->ClipRectStack.back())) && !g.LogEnabled) return true; return false; } @@ -6754,14 +6755,14 @@ static bool IsClipped(const ImGuiAabb& bb) bool ImGui::IsClipped(const ImVec2& item_size) { ImGuiWindow* window = GetCurrentWindow(); - return IsClipped(ImGuiAabb(window->DC.CursorPos, window->DC.CursorPos + item_size)); + return IsClipped(ImRect(window->DC.CursorPos, window->DC.CursorPos + item_size)); } -static bool ItemAdd(const ImGuiAabb& bb, const ImGuiID* id) +static bool ItemAdd(const ImRect& bb, const ImGuiID* id) { ImGuiWindow* window = GetCurrentWindow(); window->DC.LastItemID = id ? *id : 0; - window->DC.LastItemAabb = bb; + window->DC.LastItemRect = bb; if (IsClipped(bb)) { window->DC.LastItemHovered = false; @@ -6803,7 +6804,7 @@ void ImGui::EndGroup() ImGuiGroupData& group_data = window->DC.GroupStack.back(); - ImGuiAabb group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); + ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); group_bb.Max.y -= style.ItemSpacing.y; window->DC.CursorPos = group_data.BackupCursorPos; @@ -6977,7 +6978,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) float x = window->Pos.x + GetColumnOffset(i); const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); - const ImGuiAabb column_aabb(ImVec2(x-4,y1),ImVec2(x+4,y2)); + const ImRect column_aabb(ImVec2(x-4,y1),ImVec2(x+4,y2)); if (IsClipped(column_aabb)) continue; From 7e6112bf263cc428561b7c888b30f32ea29365fc Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 23:37:17 +0000 Subject: [PATCH 14/44] Changed remaining mentions of 'aabb' to be 'rect' --- imgui.cpp | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 618c54aa..b2d7f9ab 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1193,12 +1193,12 @@ public: bool FocusItemRegister(bool is_active, bool tab_stop = true); // Return true if focus is requested void FocusItemUnregister(); - ImRect Aabb() const { return ImRect(Pos, Pos+Size); } + ImRect Rect() const { return ImRect(Pos, Pos+Size); } ImFont* Font() const { return GImGui->Font; } float FontSize() const { return GImGui->FontSize * FontWindowScale; } ImVec2 CursorPos() const { return DC.CursorPos; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui->Style.FramePadding.y * 2.0f; } - ImRect TitleBarAabb() const { return ImRect(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } + ImRect TitleBarRect() const { return ImRect(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); } ImVec2 WindowPadding() const { return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders)) ? ImVec2(0,0) : GImGui->Style.WindowPadding; } ImU32 Color(ImGuiCol idx, float a=1.f) const { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * a; return ImGui::ColorConvertFloat4ToU32(c); } ImU32 Color(const ImVec4& col) const { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } @@ -2933,7 +2933,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX; - ImRect title_bar_aabb = window->TitleBarAabb(); + ImRect title_bar_rect = window->TitleBarRect(); // Apply and ImClamp scrolling window->ScrollY = window->NextScrollY; @@ -2946,7 +2946,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Collapse window by double-clicking on title bar if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) { - if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringRect(title_bar_aabb) && g.IO.MouseDoubleClicked[0]) + if (!(window->Flags & ImGuiWindowFlags_NoCollapse) && g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect) && g.IO.MouseDoubleClicked[0]) { window->Collapsed = !window->Collapsed; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) @@ -2963,12 +2963,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg if (window->Collapsed) { // Draw title bar only - window->Size = title_bar_aabb.GetSize(); - window->DrawList->AddRectFilled(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_TitleBgCollapsed), window_rounding); + window->Size = title_bar_rect.GetSize(); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBgCollapsed), window_rounding); if (window->Flags & ImGuiWindowFlags_ShowBorders) { - window->DrawList->AddRect(title_bar_aabb.GetTL()+ImVec2(1,1), title_bar_aabb.GetBR()+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_Border), window_rounding); + window->DrawList->AddRect(title_bar_rect.GetTL()+ImVec2(1,1), title_bar_rect.GetBR()+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); + window->DrawList->AddRect(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border), window_rounding); } } else @@ -3003,10 +3003,10 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg else if (!(window->Flags & ImGuiWindowFlags_NoResize)) { // Manual resize grip - const ImRect resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR()); + const ImRect resize_rect(window->Rect().GetBR()-ImVec2(18,18), window->Rect().GetBR()); const ImGuiID resize_id = window->GetID("#RESIZE"); bool hovered, held; - ButtonBehavior(resize_aabb, resize_id, &hovered, &held, true); + ButtonBehavior(resize_rect, resize_id, &hovered, &held, true); resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) @@ -3027,8 +3027,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg } } - // Update aabb immediately so that rendering right below us isn't one frame late - title_bar_aabb = window->TitleBarAabb(); + // Update rectangle immediately so that rendering right below us isn't one frame late + title_bar_rect = window->TitleBarRect(); } // Scrollbar @@ -3049,7 +3049,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Title bar if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_TitleBg), window_rounding, 1|2); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_TitleBg), window_rounding, 1|2); // Borders if (window->Flags & ImGuiWindowFlags_ShowBorders) @@ -3057,7 +3057,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), window_rounding); window->DrawList->AddRect(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_Border), window_rounding); if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_aabb.GetBL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_Border)); + window->DrawList->AddLine(title_bar_rect.GetBL(), title_bar_rect.GetBR(), window->Color(ImGuiCol_Border)); } // Scrollbar @@ -3069,7 +3069,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg if (!(window->Flags & ImGuiWindowFlags_NoResize)) { const float r = window_rounding; - const ImVec2 br = window->Aabb().GetBR(); + const ImVec2 br = window->Rect().GetBR(); if (r == 0.0f) { window->DrawList->AddTriangleFilled(br, br-ImVec2(0,14), br-ImVec2(14,0), resize_col); @@ -3127,12 +3127,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg } const ImVec2 text_size = CalcTextSize(name, NULL, true); - const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_aabb.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); + const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_rect.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); RenderTextClipped(text_min, name, NULL, &text_size, text_max); } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() - window->ClippedRect = window->Aabb(); + window->ClippedRect = window->Rect(); window->ClippedRect.Clip(window->ClipRectStack.front()); // Pressing CTRL+C while holding on a window copy its content to the clipboard @@ -3147,8 +3147,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Inner clipping rectangle // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - const ImRect title_bar_aabb = window->TitleBarAabb(); - ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Aabb().Max.y-1.5f); + const ImRect title_bar_rect = window->TitleBarRect(); + ImVec4 clip_rect(title_bar_rect.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_rect.Max.y+0.5f, window->Rect().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Rect().Max.y-1.5f); if (window->ScrollbarY) clip_rect.z -= style.ScrollbarWidth; PushClipRect(clip_rect); @@ -3211,7 +3211,7 @@ static void Scrollbar(ImGuiWindow* window) const ImGuiID id = window->GetID("#SCROLLY"); // Render background - ImRect bb(window->Aabb().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Aabb().Max.x, window->Aabb().Max.y-1); + ImRect bb(window->Rect().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Rect().Max.x, window->Rect().Max.y-1); window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg)); bb.Expand(ImVec2(-3,-3)); const float scrollbar_height = bb.GetHeight(); @@ -4206,7 +4206,7 @@ static bool CloseWindowButton(bool* p_opened) const ImGuiID id = window->GetID("#CLOSE"); const float size = window->TitleBarHeight() - 4.0f; - const ImRect bb(window->Aabb().GetTR() + ImVec2(-3.0f-size,2.0f), window->Aabb().GetTR() + ImVec2(-3.0f,2.0f+size)); + const ImRect bb(window->Rect().GetTR() + ImVec2(-3.0f-size,2.0f), window->Rect().GetTR() + ImVec2(-3.0f,2.0f+size)); bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, true); @@ -6285,11 +6285,11 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const ImVec2 backup_pos = ImGui::GetCursorPos(); const float popup_off_x = 0.0f;//style.ItemInnerSpacing.x; const float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + style.WindowPadding.y; - const ImRect popup_aabb(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); - ImGui::SetCursorPos(popup_aabb.Min - window->Pos); + const ImRect popup_rect(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height)); + ImGui::SetCursorPos(popup_rect.Min - window->Pos); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - ImGui::BeginChild("#ComboBox", popup_aabb.GetSize(), false, flags); + ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags); ImGui::Spacing(); bool combo_item_active = false; @@ -6434,7 +6434,7 @@ void ImGui::ListBoxFooter() ImGui::EndChildFrame(); - // Redeclare item size so that it includes the label (we have stored the full size in LastItemAabb) + // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) // We call SameLine() to restore DC.CurrentLine* data ImGui::SameLine(); parent_window->DC.CursorPos = bb.Min; @@ -6978,13 +6978,13 @@ void ImGui::Columns(int columns_count, const char* id, bool border) float x = window->Pos.x + GetColumnOffset(i); const ImGuiID column_id = window->DC.ColumnsSetID + ImGuiID(i); - const ImRect column_aabb(ImVec2(x-4,y1),ImVec2(x+4,y2)); + const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); - if (IsClipped(column_aabb)) + if (IsClipped(column_rect)) continue; bool hovered, held; - ButtonBehavior(column_aabb, column_id, &hovered, &held, true); + ButtonBehavior(column_rect, column_id, &hovered, &held, true); // Draw before resize so our items positioning are in sync with the line being drawn const ImU32 col = window->Color(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); From be83c07957142fd7d00d88dce3765b49bca7b4b5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 23:41:20 +0000 Subject: [PATCH 15/44] Changed mentions of 'box' to be 'rect' --- imgui.cpp | 30 +++++++++++++++--------------- imgui.h | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b2d7f9ab..ea128f29 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -505,7 +505,7 @@ ImGuiStyle::ImGuiStyle() FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - TouchExtraPadding = ImVec2(0,0); // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much! + TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! AutoFitPadding = ImVec2(8,8); // Extra space after auto-fit (double-clicking on resize grip) WindowFillAlphaDefault = 0.70f; // Default alpha of window background, if not specified in ImGui::Begin() IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node @@ -2430,29 +2430,29 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) } // Test if mouse cursor is hovering given rectangle -// NB- Box is clipped by our current clip setting -// NB- Expand the AABB to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -static bool IsMouseHoveringRect(const ImRect& bb) +// NB- Rectangle is clipped by our current clip setting +// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) +static bool IsMouseHoveringRect(const ImRect& rect) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); // Clip - ImRect box_clipped = bb; + ImRect rect_clipped = rect; if (!window->ClipRectStack.empty()) { const ImVec4 clip_rect = window->ClipRectStack.back(); - box_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); + rect_clipped.Clip(ImRect(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w))); } // Expand for touch input - const ImRect box_for_touch(box_clipped.Min - g.Style.TouchExtraPadding, box_clipped.Max + g.Style.TouchExtraPadding); - return box_for_touch.Contains(g.IO.MousePos); + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + return rect_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsMouseHoveringRect(const ImVec2& box_min, const ImVec2& box_max) +bool ImGui::IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max) { - return IsMouseHoveringRect(ImRect(box_min, box_max)); + return IsMouseHoveringRect(ImRect(rect_min, rect_max)); } bool ImGui::IsMouseHoveringWindow() @@ -3948,11 +3948,11 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // Lines to render if (line < text_end) { - ImRect line_box(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); + ImRect line_rect(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height)); while (line < text_end) { const char* line_end = strchr(line, '\n'); - if (IsClipped(line_box)) + if (IsClipped(line_rect)) break; const ImVec2 line_size = CalcTextSize(line, line_end, false); @@ -3961,8 +3961,8 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) if (!line_end) line_end = text_end; line = line_end + 1; - line_box.Min.y += line_height; - line_box.Max.y += line_height; + line_rect.Min.y += line_height; + line_rect.Max.y += line_height; pos.y += line_height; } @@ -6771,7 +6771,7 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id) // This is a sensible default, but widgets are free to override it after calling ItemAdd() const bool hovered = IsMouseHoveringRect(bb); - //const bool hovered = (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly) && IsMouseHoveringBox(bb); // matching the behavior of IsHovered(), not always what the user wants? + //const bool hovered = (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb); // matching the behavior of IsHovered(), not always what the user wants? window->DC.LastItemHovered = hovered; return true; } diff --git a/imgui.h b/imgui.h index 9d8fbf09..92ba35b2 100644 --- a/imgui.h +++ b/imgui.h @@ -548,7 +548,7 @@ struct ImGuiStyle float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - ImVec2 TouchExtraPadding; // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much! + ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! ImVec2 AutoFitPadding; // Extra space after auto-fit (double-clicking on resize grip) float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin() float IndentSpacing; // Horizontal indentation when e.g. entering a tree node From 9c489a081cee772ddede3d4fdb067af8f6acb522 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 17 Mar 2015 23:58:22 +0000 Subject: [PATCH 16/44] ShowTestWindow(): added vertical sliders examples, tweaks. --- imgui.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ea128f29..428552eb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9242,12 +9242,14 @@ void ImGui::ShowTestWindow(bool* opened) if (ImGui::TreeNode("Vertical Sliders")) { ImGui::Unindent(); + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; ImGui::PushID("set1"); for (int i = 0; i < 7; i++) { - if (i > 0) ImGui::SameLine(0, 4); + if (i > 0) ImGui::SameLine(); ImGui::PushID(i); ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(i/7.0f, 0.5f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(i/7.0f, 0.9f, 0.9f)); @@ -9261,11 +9263,31 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::PopID(); ImGui::SameLine(); - ImGui::PushID("set2"); + static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; + const int rows = 3; + const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx*rows+ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); for (int i = 0; i < 4; i++) { - if (i > 0) ImGui::SameLine(0, 4); + if (i > 0) ImGui::SameLine(); ImGui::PushID(i); ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f"); @@ -9274,9 +9296,6 @@ void ImGui::ShowTestWindow(bool* opened) } ImGui::PopID(); - ImGui::SameLine(); - ImGui::Text("Label"); - ImGui::Indent(); ImGui::TreePop(); } @@ -9288,7 +9307,7 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); static bool pause; - static ImVector values; if (values.empty()) { values.resize(100); memset(&values.front(), 0, values.size()*sizeof(float)); } + static ImVector values; if (values.empty()) { values.resize(90); memset(&values.front(), 0, values.size()*sizeof(float)); } static size_t values_offset = 0; if (!pause) { @@ -9488,6 +9507,7 @@ void ImGui::ShowTestWindow(bool* opened) // Basic columns ImGui::Text("Basic:"); ImGui::Columns(4, "mycolumns"); + ImGui::Separator(); ImGui::Text("ID"); ImGui::NextColumn(); ImGui::Text("Name"); ImGui::NextColumn(); ImGui::Text("Path"); ImGui::NextColumn(); From 2a9a2918f84f7820b2218e4f80ee5ff7cc86db23 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 00:07:21 +0000 Subject: [PATCH 17/44] ShowTestWindow(): more examples of SameLine() usage --- imgui.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 428552eb..1ed7d6c1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9369,10 +9369,15 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)"); // Text - ImGui::Text("Hello"); + ImGui::Text("Two items: Hello"); ImGui::SameLine(); ImGui::TextColored(ImVec4(1,1,0,1), "World"); + // Adjust spacing + ImGui::Text("More spacing: Hello"); + ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1,1,0,1), "World"); + // Button ImGui::AlignFirstTextHeightToWidgets(); ImGui::Text("Normal buttons"); ImGui::SameLine(); @@ -9385,6 +9390,14 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::SmallButton("Like this one"); ImGui::SameLine(); ImGui::Text("can fit within a text block."); + // Aligned to arbitrary position. Easy/cheap column. + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::Text("x=150"); + ImGui::SameLine(300); ImGui::Text("x=300"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::SmallButton("x=150"); + ImGui::SameLine(300); ImGui::SmallButton("x=300"); + // Checkbox static bool c1=false,c2=false,c3=false,c4=false; ImGui::Checkbox("My", &c1); ImGui::SameLine(); From d8026e4d845b7877e3b4cf927609c12d9746b9b7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 09:39:09 +0000 Subject: [PATCH 18/44] Added VSliderInt() --- imgui.cpp | 14 ++++++++++++++ imgui.h | 1 + 2 files changed, 15 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 1ed7d6c1..82736d7d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5060,6 +5060,16 @@ bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const cha return value_changed; } +bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) +{ + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = ImGui::VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; +} + // Add multiple sliders on 1 line for compact edition of multiple components static bool SliderFloatN(const char* label, float v[3], int components, float v_min, float v_max, const char* display_format, float power) { @@ -9245,6 +9255,10 @@ void ImGui::ShowTestWindow(bool* opened) const float spacing = 4; ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5); + ImGui::SameLine(); + static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; ImGui::PushID("set1"); for (int i = 0; i < 7; i++) diff --git a/imgui.h b/imgui.h index 92ba35b2..d315f89a 100644 --- a/imgui.h +++ b/imgui.h @@ -288,6 +288,7 @@ namespace ImGui IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float)); From 7665b8e5e7df8c7a2692962e445995622add7b29 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 09:39:38 +0000 Subject: [PATCH 19/44] Version number --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 82736d7d..0dfd6e9f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// ImGui library v1.36 WIP +// ImGui library v1.36 // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui diff --git a/imgui.h b/imgui.h index d315f89a..60d2684f 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// ImGui library v1.36 WIP +// ImGui library v1.36 // See .cpp file for documentation. // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase. @@ -13,7 +13,7 @@ #include // NULL, malloc #include // memset, memmove -#define IMGUI_VERSION "1.36 WIP" +#define IMGUI_VERSION "1.36" // Define assertion handler. #ifndef IM_ASSERT From 215b0065e3c0be20cdb830cf8c6e228b00e4f4f0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 10:24:56 +0000 Subject: [PATCH 20/44] Version number 1.37 WIP --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0dfd6e9f..d8b71f39 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// ImGui library v1.36 +// ImGui library v1.37 WIP // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui diff --git a/imgui.h b/imgui.h index 60d2684f..08a3a585 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// ImGui library v1.36 +// ImGui library v1.37 WIP // See .cpp file for documentation. // See ImGui::ShowTestWindow() for sample code. // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase. @@ -13,7 +13,7 @@ #include // NULL, malloc #include // memset, memmove -#define IMGUI_VERSION "1.36" +#define IMGUI_VERSION "1.37 WIP" // Define assertion handler. #ifndef IM_ASSERT From e10d648a2808df340537c1f2127b7a723b39f118 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 10:41:46 +0000 Subject: [PATCH 21/44] Added ImGui::GetItemActiveDragDelta() helpers for drag operations --- imgui.cpp | 11 +++++++++++ imgui.h | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8b71f39..cfd85bb7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2551,6 +2551,17 @@ bool ImGui::IsAnyItemActive() return g.ActiveId != 0; } +ImVec2 ImGui::GetItemActiveDragDelta() +{ + if (ImGui::IsItemActive()) + { + ImGuiState& g = *GImGui; + if (g.IO.MouseDown[0]) + return g.IO.MousePos - g.IO.MouseClickedPos[0]; // Assume we can only get active with left-mouse button (at the moment). + } + return ImVec2(0.0f, 0.0f); +} + ImVec2 ImGui::GetItemRectMin() { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui.h b/imgui.h index 08a3a585..874858f2 100644 --- a/imgui.h +++ b/imgui.h @@ -354,12 +354,13 @@ namespace ImGui IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsAnyItemActive(); // - IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) - IMGUI_API bool IsRootWindowFocused(); // is current root window focused - IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused + IMGUI_API ImVec2 GetItemActiveDragDelta(); // mouse delta from the time the item first got active IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " + IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) + IMGUI_API bool IsRootWindowFocused(); // is current root window focused + IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimization) IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry IMGUI_API bool IsMouseClicked(int button, bool repeat = false); From 1de735ba7c8bd1193c7c6d0d2939f10f4eb81353 Mon Sep 17 00:00:00 2001 From: "Adam D. Moss" Date: Wed, 18 Mar 2015 11:27:37 +0000 Subject: [PATCH 22/44] GetItemBoxMax: fix obsolete function copy-n-paste bug --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 874858f2..cfbf3204 100644 --- a/imgui.h +++ b/imgui.h @@ -394,7 +394,7 @@ namespace ImGui static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE - static inline ImVec2 GetItemBoxMax() { return GetItemRectMin(); } // OBSOLETE + static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE } // namespace ImGui From 7d26e85b05b49a3c8bae0d9591d41b241f338368 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 12:10:26 +0000 Subject: [PATCH 23/44] IsItemHovered() return false if another widget is active. Added IsItemHoveredRectOnly(). --- imgui.cpp | 43 ++++++++++++++++++++++++++++++++----------- imgui.h | 1 + 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cfd85bb7..a476e875 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -930,7 +930,8 @@ struct ImGuiDrawContext int TreeDepth; ImGuiID LastItemID; ImRect LastItemRect; - bool LastItemHovered; + bool LastItemHoveredAndUsable; + bool LastItemHoveredRectOnly; ImVector ChildWindows; ImVector AllowKeyboardFocus; ImVector ItemWidth; // 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window @@ -959,7 +960,7 @@ struct ImGuiDrawContext TreeDepth = 0; LastItemID = 0; LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); - LastItemHovered = false; + LastItemHoveredAndUsable = LastItemHoveredRectOnly = false; StateStorage = NULL; ColumnsStartX = 0.0f; @@ -1150,6 +1151,7 @@ struct ImGuiWindow ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame + ImGuiID MoveID; // == window->GetID("#MOVE") float ScrollY; float NextScrollY; bool ScrollbarY; @@ -1487,6 +1489,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Name = ImStrdup(name); ID = ImHash(name, 0); IDStack.push_back(ID); + MoveID = GetID("#MOVE"); Flags = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); @@ -2057,7 +2060,7 @@ void ImGui::Render() { IM_ASSERT(g.MovedWindow == NULL); g.MovedWindow = g.HoveredWindow; - SetActiveId(g.HoveredRootWindow->GetID("#MOVE")); + SetActiveId(g.HoveredRootWindow->MoveID); } // Sort the window list so that all child windows are after their parent @@ -2531,7 +2534,13 @@ ImVec2 ImGui::GetMousePos() bool ImGui::IsItemHovered() { ImGuiWindow* window = GetCurrentWindow(); - return window->DC.LastItemHovered; + return window->DC.LastItemHoveredAndUsable; +} + +bool ImGui::IsItemHoveredRectOnly() +{ + ImGuiWindow* window = GetCurrentWindow(); + return window->DC.LastItemHoveredRectOnly; } bool ImGui::IsItemActive() @@ -2882,9 +2891,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->IDStack.resize(1); // Move window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. - const ImGuiID move_id = window->GetID("#MOVE"); - RegisterAliveId(move_id); - if (g.ActiveId == move_id) + RegisterAliveId(window->MoveID); + if (g.ActiveId == window->MoveID) { if (g.IO.MouseDown[0]) { @@ -6786,14 +6794,27 @@ static bool ItemAdd(const ImRect& bb, const ImGuiID* id) window->DC.LastItemRect = bb; if (IsClipped(bb)) { - window->DC.LastItemHovered = false; + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRectOnly = false; return false; } // This is a sensible default, but widgets are free to override it after calling ItemAdd() - const bool hovered = IsMouseHoveringRect(bb); - //const bool hovered = (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb); // matching the behavior of IsHovered(), not always what the user wants? - window->DC.LastItemHovered = hovered; + ImGuiState& g = *GImGui; + if (IsMouseHoveringRect(bb)) + { + // Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background) + // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() + window->DC.LastItemHoveredRectOnly = true; + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdIsFocusedOnly || (g.ActiveId == window->MoveID)) + window->DC.LastItemHoveredAndUsable = true; + else + window->DC.LastItemHoveredAndUsable = false; + } + else + { + window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRectOnly = false; + } + return true; } diff --git a/imgui.h b/imgui.h index cfbf3204..ec0846b3 100644 --- a/imgui.h +++ b/imgui.h @@ -352,6 +352,7 @@ namespace ImGui // Utilities IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? + IMGUI_API bool IsItemHoveredRectOnly(); // was the last item hovered by mouse? even if another item is active while we are hovering this. IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsAnyItemActive(); // IMGUI_API ImVec2 GetItemActiveDragDelta(); // mouse delta from the time the item first got active From 9f1b407defdcfb676138486ee6258d8ea1650d32 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 12:54:44 +0000 Subject: [PATCH 24/44] ImDrawList: added thickness param to AddLine(). Added PushClipRectFullScreen() helper. --- imgui.cpp | 24 ++++++++++++++++++------ imgui.h | 5 +++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a476e875..61bb11f5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7229,6 +7229,18 @@ void ImDrawList::PushClipRect(const ImVec4& clip_rect) UpdateClipRect(); } +void ImDrawList::PushClipRectFullScreen() +{ + PushClipRect(GNullClipRect); + + // This would be more correct but we're not supposed to access ImGuiState from here? + //ImGuiState& g = *GImGui; + //if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + // PushClipRect(ImVec4(g.IO.DisplayVisibleMin.x, g.IO.DisplayVisibleMin.y, g.IO.DisplayVisibleMax.x, g.IO.DisplayVisibleMax.y)); + //else + // PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y)); +} + void ImDrawList::PopClipRect() { IM_ASSERT(clip_rect_stack.size() > 0); @@ -7291,11 +7303,11 @@ void ImDrawList::AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv) } // NB: memory should be reserved for 6 vertices by the caller. -void ImDrawList::AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col) +void ImDrawList::AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col, float half_thickness) { - const float length = sqrtf(ImLengthSqr(b - a)); - const ImVec2 hn = (b - a) * (0.50f / length); // half normal - const ImVec2 hp0 = ImVec2(+hn.y, -hn.x); // half perpendiculars + user offset + const float inv_length = 1.0f / sqrtf(ImLengthSqr(b - a)); + const ImVec2 hn = (b - a) * (half_thickness * inv_length); // half normal + const ImVec2 hp0 = ImVec2(+hn.y, -hn.x); // half perpendiculars + user offset const ImVec2 hp1 = ImVec2(-hn.y, +hn.x); // Two triangles makes up one line. Using triangles allows us to reduce amount of draw calls. @@ -7307,13 +7319,13 @@ void ImDrawList::AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col) AddVtx(a + hp1, col); } -void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col) +void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float half_thickness) { if ((col >> 24) == 0) return; ReserveVertices(6); - AddVtxLine(a, b, col); + AddVtxLine(a, b, col, half_thickness); } void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) diff --git a/imgui.h b/imgui.h index ec0846b3..0fb22eec 100644 --- a/imgui.h +++ b/imgui.h @@ -861,12 +861,13 @@ struct ImDrawList ImDrawList() { Clear(); } IMGUI_API void Clear(); IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. The values are x1, y1, x2, y2. + IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PopClipRect(); IMGUI_API void PushTextureID(const ImTextureID& texture_id); IMGUI_API void PopTextureID(); // Primitives - IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col); + IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float half_thickness = 0.50f); IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); @@ -884,7 +885,7 @@ struct ImDrawList IMGUI_API void ReserveVertices(unsigned int vtx_count); IMGUI_API void AddVtx(const ImVec2& pos, ImU32 col); IMGUI_API void AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv); - IMGUI_API void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col); + IMGUI_API void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col, float half_thickness = 0.50f); IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); }; From dcaafffe0ed21c9b03530a911785ded80e14358f Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 13:07:37 +0000 Subject: [PATCH 25/44] Added CalcItemRectClosestPoint() helper. --- imgui.cpp | 23 +++++++++++++++++++++-- imgui.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 61bb11f5..c74f0e98 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -900,8 +900,19 @@ struct ImRect // 2D axis aligned bounding-box bool Overlaps(const ImRect& r) const { return r.Min.y <= Max.y && r.Max.y >= Min.y && r.Min.x <= Max.x && r.Max.x >= Min.x; } void Add(const ImVec2& rhs) { Min.x = ImMin(Min.x, rhs.x); Min.y = ImMin(Min.y, rhs.y); Max.x = ImMax(Max.x, rhs.x); Max.y = ImMax(Max.x, rhs.x); } void Add(const ImRect& rhs) { Min.x = ImMin(Min.x, rhs.Min.x); Min.y = ImMin(Min.y, rhs.Min.y); Max.x = ImMax(Max.x, rhs.Max.x); Max.y = ImMax(Max.y, rhs.Max.y); } - void Expand(const ImVec2& sz) { Min -= sz; Max += sz; } + void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } + void Expand(const ImVec2& amount) { Min -= amount; Max += amount; } void Clip(const ImRect& clip) { Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); } + ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const + { + if (!on_edge && Contains(p)) + return p; + if (p.x > Max.x) p.x = Max.x; + else if (p.x < Min.x) p.x = Min.x; + if (p.y > Max.y) p.y = Max.y; + else if (p.y < Min.y) p.y = Min.y; + return p; + } }; typedef ImRect ImGuiAabb; // FIXME-OBSOLETE @@ -2589,6 +2600,14 @@ ImVec2 ImGui::GetItemRectSize() return window->DC.LastItemRect.GetSize(); } +ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float outward) +{ + ImGuiWindow* window = GetCurrentWindow(); + ImRect rect = window->DC.LastItemRect; + rect.Expand(outward); + return rect.GetClosestPoint(pos, on_edge); +} + // Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. void ImGui::SetTooltipV(const char* fmt, va_list args) { @@ -3232,7 +3251,7 @@ static void Scrollbar(ImGuiWindow* window) // Render background ImRect bb(window->Rect().Max.x - style.ScrollbarWidth, window->Pos.y + window->TitleBarHeight()+1, window->Rect().Max.x, window->Rect().Max.y-1); window->DrawList->AddRectFilled(bb.Min, bb.Max, window->Color(ImGuiCol_ScrollbarBg)); - bb.Expand(ImVec2(-3,-3)); + bb.Expand(-3.0f); const float scrollbar_height = bb.GetHeight(); // The grabable box size generally represent the amount visible (vs the total scrollable amount) diff --git a/imgui.h b/imgui.h index 0fb22eec..eb60a7ec 100644 --- a/imgui.h +++ b/imgui.h @@ -374,6 +374,7 @@ namespace ImGui IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API const char* GetStyleColName(ImGuiCol idx); + IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items. IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // helper to manually clip large list of items. see comments in implementation. From e14c7e55102d78eef0d94516262dc0a0819a25c5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 13:15:11 +0000 Subject: [PATCH 26/44] ShowTestWindow(): Added simple dragging widget example. --- imgui.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index c74f0e98..76e998d9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9376,6 +9376,26 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::Indent(); ImGui::TreePop(); } + + if (ImGui::TreeNode("Dragging")) + { + // You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget. + static ImVec2 value(0.0f, 0.0f); + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + { + value = ImGui::GetItemActiveDragDelta(); + //ImGui::SetTooltip("Delta: %.1f, %.1f", value.x, value.y); + + // Draw a line between the button and the mouse cursor + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->PushClipRectFullScreen(); + draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 2.0f); + draw_list->PopClipRect(); + } + ImGui::SameLine(); ImGui::Text("Value: %.1f, %.1f", value.x, value.y); + ImGui::TreePop(); + } } if (ImGui::CollapsingHeader("Graphs widgets")) From bc88ed0cb997b30e3f090beea432006e98786bed Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 13:21:32 +0000 Subject: [PATCH 27/44] Fixed bounding measurement of empty groups (fix #162) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 76e998d9..1f34ab02 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6866,7 +6866,8 @@ void ImGui::EndGroup() ImGuiGroupData& group_data = window->DC.GroupStack.back(); ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); - group_bb.Max.y -= style.ItemSpacing.y; + group_bb.Max.y -= style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves. + group_bb.Max = ImMax(group_bb.Min, group_bb.Max); window->DC.CursorPos = group_data.BackupCursorPos; window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); From 4e245f0bfbf32a8f6ce2fd4998e0a4f1587abc55 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 18 Mar 2015 14:06:39 +0000 Subject: [PATCH 28/44] Update README.md Link to Synergy sources --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc4a2120..ac5ac169 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ The bulk of example user code is contained within the ImGui::ShowTestWindow() fu How do you use ImGui on a platform that may not have a mouse or keyboard? -I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running on your platform and connecting to your PC, you can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accomodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. +I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). With the uSynergy.c micro client running on your platform and connecting to your PC, you can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accomodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. I integrated ImGui in my engine and the text or lines are blurry.. From ed0f0dbe8796b01920e313c9702439baac5d53e0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 14:58:17 +0000 Subject: [PATCH 29/44] ImDrawList::AddText() takes a const ImFont* --- imgui.cpp | 2 +- imgui.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f34ab02..5670a11f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7516,7 +7516,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, } } -void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec2* cpu_clip_max) +void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec2* cpu_clip_max) { if ((col >> 24) == 0) return; diff --git a/imgui.h b/imgui.h index eb60a7ec..d345bc6f 100644 --- a/imgui.h +++ b/imgui.h @@ -875,7 +875,7 @@ struct ImDrawList IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); - IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); + IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); // Advanced From d45d1d1bcaa65d48c645ac0d2c7e004ee07cbfee Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 19:00:03 +0000 Subject: [PATCH 30/44] Documentation tweaks and fixes --- imgui.cpp | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5670a11f..87638d79 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -34,7 +34,7 @@ Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - doesn't look fancy, doesn't animate - limited layout features, intricate layouts are typically crafted in code - - occasionally uses statically sized buffers for string manipulations - won't crash, but some long text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. + - occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. END-USER GUIDE @@ -66,16 +66,17 @@ - read the FAQ below this section! - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - call and read ImGui::ShowTestWindow() for sample code demonstrating most features. - - see examples/ folder for standalone sample applications. - - customization: use the style editor or PushStyleColor/PushStyleVar to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). + - see examples/ folder for standalone sample applications. e.g. examples/opengl_example/ + - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). - getting started: - - initialisation: call ImGui::GetIO() and fill the 'Settings' data. + - initialisation: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the 'Settings' data. - every frame: 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the 'Input' data, then call ImGui::NewFrame(). 2/ use any ImGui function you want between NewFrame() and Render() 3/ ImGui::Render() to render all the accumulated command-lists. it will call your RenderDrawListFn handler that you set in the IO structure. - - all rendering information are stored into command-lists until ImGui::Render() is called. + - all rendering information are stored into command-lists until ImGui::Render() is called. + - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you must provide. - effectively it means you can create widgets at any time in your code, regardless of "update" vs "render" considerations. - refer to the examples applications in the examples/ folder for instruction on how to setup your code. - a typical application skeleton may be: @@ -178,7 +179,7 @@ - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) - A primer on the meaning and use of ID in ImGui: + A primer on the meaning and use of IDs in ImGui: - widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). to do so they need an unique ID. unique ID are typically derived from a string label, an integer index or a pointer. @@ -186,6 +187,8 @@ Button("OK"); // Label = "OK", ID = hash of "OK" Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" + - element that are not interactive, such as Text() items don't need an ID. + - ID are uniquely scoped within Windows so no conflict can happen if you have two buttons called "OK" in two different Windows. - when passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. @@ -203,16 +206,16 @@ Button("Click"); // Label = "Click", ID = hash of "Click" PushID("node"); - Button("Click"); // Label = "Click", ID = hash of "node" and "Click" + Button("Click"); // Label = "Click", ID = hash of "node" + "Click" for (int i = 0; i < 100; i++) { PushID(i); - Button("Click"); // Label = "Click", ID = hash of "node" and i and "label" + Button("Click"); // Label = "Click", ID = hash of "node" + i + "label" PopID(); } PopID(); PushID(my_ptr); - Button("Click"); // Label = "Click", ID = hash of ptr and "Click" + Button("Click"); // Label = "Click", ID = hash of ptr + "Click" PopID(); so if you have a loop creating multiple items, you can use PushID() / PopID() with the index of each item, or their pointer, etc. @@ -234,6 +237,8 @@ ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels); io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + // the first loaded font gets used by default + // use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime If you want to display Chinese, Japanese, Korean characters, pass custom Unicode ranges when loading a font: @@ -251,7 +256,7 @@ ISSUES & TODO-LIST ================== - - misc: merge or clarify ImVec4 / ImRect, they are essentially duplicate containers + - misc: merge or clarify ImVec4 vs ImRect? - window: add horizontal scroll - window: fix resize grip rendering scaling along with Rounding style setting - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit? @@ -259,20 +264,17 @@ - window: allow resizing of child windows (possibly given min/max for each axis?) - window: background options for child windows, border option (disable rounding) - window: resizing from any sides? + mouse cursor directives for app. - - widgets: clicking on widget b while widget a should activate widget b (doesn't anymore because of hover capture) - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. - - widgets: clip text? hover clipped text shows it in a tooltip or in-place overlay + - widgets: clean up widgets internal toward exposing everything. - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them. - - main: IsItemHovered() returns true even if mouse is active on another widget (e.g. dragging outside of sliders). Maybe not a sensible default? Add parameter or alternate function? - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? -!- input number: very large int not reliably supported because of int<>float conversions. +!- input number: large int not reliably supported because of int<>float conversions. - input number: optional range min/max for Input*() functions - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) - input number: use mouse wheel to step up/down - input number: non-decimal input. - - text: vertical alignment (e.g. for Text after a large widget) - - text: proper horizontal centering + - text: proper alignment options - layout: horizontal layout helper (github issue #97) - layout: more generic alignment state (left/right/centered) for single items? - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. @@ -294,7 +296,8 @@ - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - file selection widget -> build the tool in our codebase to improve model-dialog idioms - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - - slider: initial absolute click is imprecise. change to relative movement slider? hide mouse cursor, allow more precise input using less screen-space. same as scrollbar. + - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). + - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now. - text edit: centered text for slider as input text so it matches typical positioning. - text edit: flag to disable live update of the user buffer. @@ -302,14 +305,15 @@ - text edit: add multi-line text edit - tree: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings - settings: write more decent code to allow saving/loading new fields - - settings: api for per-tool simple persistent data (bool,int,float) in .ini file + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file ! style: store rounded corners in texture to use 1 quad per corner (filled and wireframe). so rounding have minor cost. - style: checkbox: padding for "active" color should be a multiplier of the - style: colorbox not always square? - text: simple markup language for color change? - log: LogButtons() options for specifying depth and/or hiding depth slider - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - - log: be able to right-click and log a window or tree-node into tty/file/clipboard / generalized context menu? + - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) + - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - filters: set a current filter that tree node can automatically query to hide themselves - filters: handle wildcards (with implicit leading/trailing *), regexps - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) @@ -319,17 +323,15 @@ - input: support track pad style scrolling & slider edit. - tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen). - portability: big-endian test/support (github issue #81) - - misc: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?) - misc: mark printf compiler attributes on relevant functions - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? - style editor: color child window height expressed in multiple of line height. - - optimization/render: use indexed rendering to reduce vertex data cost (for remote/networked imgui) + - optimization/render: use indexed rendering to reduce vertex data cost (e.g. for remote/networked imgui) - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? - optimization: turn some the various stack vectors into statically-sized arrays - optimization: better clipping for multi-component widgets - - optimization: specialize for height based clipping first (assume widgets never go up + height tests before width tests?) */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) From 2f4271a2b347dae9a0be7773c012630f0f01feb3 Mon Sep 17 00:00:00 2001 From: biller23 Date: Wed, 18 Mar 2015 21:02:29 +0100 Subject: [PATCH 31/44] typo ImGui_ImplGlfwGL3_KeyCallback() --- examples/opengl3_example/imgui_impl_glfw_gl3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 7b181577..81b59528 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -16,5 +16,5 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects(); // You can also handle inputs yourself and use those as a reference. void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -void ImGui_ImplGlFwGL3_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow* window, unsigned int c); From 62e8661a37326d8f5d65467c0870f4ec2a415f07 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 22:26:55 +0000 Subject: [PATCH 32/44] Fixed assignment order in Begin() making auto-fit size effectively lag by one frame Also disabling "clamp into view" while windows are auto-fitting --- imgui.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 87638d79..8e7b0aa8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2944,7 +2944,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg { // FIXME: Parameterize padding. const ImVec2 pad = ImVec2(window->FontSize()*2.0f, window->FontSize()*2.0f); // FIXME: Parametrize of clarify this behavior. - if (g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. + if (window->AutoFitFrames == 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. { ImVec2 clip_min = pad; ImVec2 clip_max = g.IO.DisplaySize - pad; @@ -3013,14 +3013,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg } else { - window->Size = window->SizeFull; - ImU32 resize_col = 0; if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0) { // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. const ImVec2 size_auto_fit = window->SizeContents + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); - window->SizeFull = size_auto_fit; + window->Size = window->SizeFull = size_auto_fit; } else { @@ -3053,7 +3051,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg { // Manual auto-fit when double-clicking window->SizeFull = size_auto_fit; - window->Size = window->SizeFull; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) MarkSettingsDirty(); } @@ -3061,13 +3058,13 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg { // Resize window->SizeFull = ImMax(window->SizeFull + g.IO.MouseDelta, style.WindowMinSize); - window->Size = window->SizeFull; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) MarkSettingsDirty(); } } // Update rectangle immediately so that rendering right below us isn't one frame late + window->Size = window->SizeFull; title_bar_rect = window->TitleBarRect(); } From 7a2da7cd02c0d8cfd5833842eebc621990bfacda Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 18 Mar 2015 22:35:14 +0000 Subject: [PATCH 33/44] Added style.DisplaySafeAreaPadding which was previously hard-coded (for use if you can't see the edges of your display, e.g. TV screens) --- imgui.cpp | 7 +++---- imgui.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8e7b0aa8..2f7a6298 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -514,6 +514,7 @@ ImGuiStyle::ImGuiStyle() ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns ScrollbarWidth = 16.0f; // Width of the vertical scrollbar GrabMinSize = 10.0f; // Minimum width/height of a slider or scrollbar grab + DisplaySafeAreaPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); @@ -2942,12 +2943,10 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg // Clamp into view if (!(window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Tooltip)) { - // FIXME: Parameterize padding. - const ImVec2 pad = ImVec2(window->FontSize()*2.0f, window->FontSize()*2.0f); // FIXME: Parametrize of clarify this behavior. if (window->AutoFitFrames == 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. { - ImVec2 clip_min = pad; - ImVec2 clip_max = g.IO.DisplaySize - pad; + ImVec2 clip_min = style.DisplaySafeAreaPadding; + ImVec2 clip_max = g.IO.DisplaySize - style.DisplaySafeAreaPadding; window->PosFloat = ImMax(window->PosFloat + window->Size, clip_min) - window->Size; window->PosFloat = ImMin(window->PosFloat, clip_max); } diff --git a/imgui.h b/imgui.h index d345bc6f..8f28d5fd 100644 --- a/imgui.h +++ b/imgui.h @@ -559,6 +559,7 @@ struct ImGuiStyle float ColumnsMinSpacing; // Minimum horizontal spacing between two columns float ScrollbarWidth; // Width of the vertical scrollbar float GrabMinSize; // Minimum width/height of a slider or scrollbar grab + ImVec2 DisplaySafeAreaPadding; // Window positions are clamped to be visible within the display area. If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. ImVec4 Colors[ImGuiCol_COUNT]; IMGUI_API ImGuiStyle(); From 13caf21018ff8feffc1f0cade8ac04ed524df7ac Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 09:06:34 +0000 Subject: [PATCH 34/44] Use fabs() instead of abs() to ensure we use floating point. #164 --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 2f7a6298..d9a00d62 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4826,7 +4826,7 @@ static bool SliderBehavior(const ImRect& frame_bb, const ImRect& slider_bb, ImGu RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding); const bool is_finite = (v_min != -FLT_MAX && v_min != FLT_MAX && v_max != -FLT_MAX && v_max != FLT_MAX); - const bool is_non_linear = abs(power - 1.0f) > 0.0001f; + const bool is_non_linear = fabsf(power - 1.0f) > 0.0001f; const float slider_sz = horizontal ? slider_bb.GetWidth() : slider_bb.GetHeight(); float grab_sz; From 6425b8c1cf5afe8f9cb290afa3fc3981144af3a5 Mon Sep 17 00:00:00 2001 From: Josh Simmons Date: Thu, 19 Mar 2015 22:42:17 +1100 Subject: [PATCH 35/44] Remove spurious assert Remove nop assert that causes warnings on Clang. --- imgui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index d9a00d62..5ae03a54 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -828,7 +828,6 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes) { IM_ASSERT(filename && file_open_mode && out_file_data && out_file_size); - IM_ASSERT(padding_bytes >= 0); *out_file_data = NULL; *out_file_size = 0; From 314b87dfaf6e5664e8e038e2a8c7b7040841d42d Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 14:15:51 +0000 Subject: [PATCH 36/44] InputFloat(): fixed label alignment if total widget width forcefully bigger than space available --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 5ae03a54..76c5d08d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5689,8 +5689,8 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, if (label_size.x > 0) { ImGui::SameLine(0, (int)style.ItemInnerSpacing.x); + RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); ItemSize(label_size, style.FramePadding.y); - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); } return value_changed; From 2f0fb2bc34829799636193c28c663b1d5e9139a2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 14:48:36 +0000 Subject: [PATCH 37/44] IsItemhovered() include label and behave consistently (#145) --- imgui.cpp | 70 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 76c5d08d..37721c82 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4068,9 +4068,9 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, label_size.y + style.FramePadding.y*2)); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(value_bb, NULL)) + const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) return; // Render @@ -4972,13 +4972,13 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect slider_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); // NB- we don't call ItemSize() yet becausae we may turn into a text edit box below - if (!ItemAdd(frame_bb, &id)) + if (!ItemAdd(total_bb, &id)) { - ItemSize(bb, style.FramePadding.y); + ItemSize(total_bb, style.FramePadding.y); return false; } @@ -5011,18 +5011,18 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c if (start_text_input || (g.ActiveId == id && id == g.SliderAsInputTextId)) return SliderFloatAsInputText(label, v, id, decimal_precision); - ItemSize(bb, style.FramePadding.y); + ItemSize(total_bb, style.FramePadding.y); // Actual slider behavior + render grab - bool value_changed = SliderBehavior(frame_bb, slider_bb, id, v, v_min, v_max, power, decimal_precision, true); + bool value_changed = SliderBehavior(frame_bb, inner_bb, id, v, v_min, v_max, power, decimal_precision, true); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. char value_buf[64]; char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); const ImVec2 value_text_size = CalcTextSize(value_buf, value_buf_end, true); - RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, slider_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); + RenderTextClipped(ImVec2(ImMax(frame_bb.Min.x + style.FramePadding.x, inner_bb.GetCenter().x - value_text_size.x*0.5f), frame_bb.Min.y + style.FramePadding.y), value_buf, value_buf_end, &value_text_size, frame_bb.Max); - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label); + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); return value_changed; } @@ -5119,6 +5119,7 @@ static bool SliderFloatN(const char* label, float v[3], int components, float v_ const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); bool value_changed = false; + ImGui::BeginGroup(); ImGui::PushID(label); ImGui::PushItemWidth(w_item_one); for (int i = 0; i < components; i++) @@ -5137,6 +5138,7 @@ static bool SliderFloatN(const char* label, float v[3], int components, float v_ ImGui::PopID(); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); return value_changed; } @@ -5169,6 +5171,7 @@ static bool SliderIntN(const char* label, int v[3], int components, int v_min, i const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x)*(components-1))); bool value_changed = false; + ImGui::BeginGroup(); ImGui::PushID(label); ImGui::PushItemWidth(w_item_one); for (int i = 0; i < components; i++) @@ -5187,6 +5190,7 @@ static bool SliderIntN(const char* label, int v[3], int components, int v_min, i ImGui::PopID(); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); return value_changed; } @@ -5228,10 +5232,10 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett graph_size.y = label_size.y + (style.FramePadding.y * 2); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); - const ImRect graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, NULL)) + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, NULL)) return; // Determine scale from values if not specified @@ -5259,9 +5263,9 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett // Tooltip on hover int v_hovered = -1; - if (IsMouseHoveringRect(graph_bb)) + if (IsMouseHoveringRect(inner_bb)) { - const float t = ImClamp((g.IO.MousePos.x - graph_bb.Min.x) / (graph_bb.Max.x - graph_bb.Min.x), 0.0f, 0.9999f); + const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0))); IM_ASSERT(v_idx >= 0 && v_idx < values_count); @@ -5293,9 +5297,9 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett // NB- Draw calls are merged together by the DrawList system. if (plot_type == ImGuiPlotType_Lines) - window->DrawList->AddLine(ImLerp(graph_bb.Min, graph_bb.Max, p0), ImLerp(graph_bb.Min, graph_bb.Max, p1), v_hovered == v_idx ? col_hovered : col_base); + window->DrawList->AddLine(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, p1), v_hovered == v_idx ? col_hovered : col_base); else if (plot_type == ImGuiPlotType_Histogram) - window->DrawList->AddRectFilled(ImLerp(graph_bb.Min, graph_bb.Max, p0), ImLerp(graph_bb.Min, graph_bb.Max, ImVec2(p1.x, 1.0f))+ImVec2(-1,0), v_hovered == v_idx ? col_hovered : col_base); + window->DrawList->AddRectFilled(ImLerp(inner_bb.Min, inner_bb.Max, p0), ImLerp(inner_bb.Min, inner_bb.Max, ImVec2(p1.x, 1.0f))+ImVec2(-1,0), v_hovered == v_idx ? col_hovered : col_base); t0 = t1; p0 = p1; @@ -5303,9 +5307,9 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett // Text overlay if (overlay_text) - RenderText(ImVec2(graph_bb.GetCenter().x - ImGui::CalcTextSize(overlay_text, NULL, true).x*0.5f, frame_bb.Min.y + style.FramePadding.y), overlay_text); + RenderText(ImVec2(inner_bb.GetCenter().x - ImGui::CalcTextSize(overlay_text, NULL, true).x*0.5f, frame_bb.Min.y + style.FramePadding.y), overlay_text); - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, graph_bb.Min.y), label); + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); } struct ImGuiPlotArrayGetterData @@ -5648,6 +5652,7 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); + ImGui::BeginGroup(); ImGui::PushID(label); const ImVec2 button_sz = ImVec2(window->FontSize(), window->FontSize()) + style.FramePadding * 2; if (step > 0.0f) @@ -5693,6 +5698,8 @@ bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, ItemSize(label_size, style.FramePadding.y); } + ImGui::EndGroup(); + return value_changed; } @@ -5809,9 +5816,9 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, &id)) + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) return false; // NB: we are only allowed to access 'edit_state' if we are the active widget. @@ -6133,6 +6140,7 @@ static bool InputFloatN(const char* label, float* v, int components, int decimal const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); bool value_changed = false; + ImGui::BeginGroup(); ImGui::PushID(label); ImGui::PushItemWidth(w_item_one); for (int i = 0; i < components; i++) @@ -6150,7 +6158,9 @@ static bool InputFloatN(const char* label, float* v, int components, int decimal ImGui::PopItemWidth(); ImGui::PopID(); + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, style.FramePadding.y); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); return value_changed; } @@ -6183,6 +6193,7 @@ static bool InputIntN(const char* label, int* v, int components) const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.FramePadding.x*2.0f + style.ItemInnerSpacing.x) * (components-1))); bool value_changed = false; + ImGui::BeginGroup(); ImGui::PushID(label); ImGui::PushItemWidth(w_item_one); for (int i = 0; i < components; i++) @@ -6201,6 +6212,7 @@ static bool InputIntN(const char* label, int* v, int components) ImGui::PopID(); ImGui::TextUnformatted(label, FindTextDisplayEnd(label)); + ImGui::EndGroup(); return value_changed; } @@ -6283,9 +6295,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y) + style.FramePadding*2.0f); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, &id)) + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + label_size.x,0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, &id)) return false; const float arrow_size = (window->FontSize() + style.FramePadding.x * 2.0f); @@ -6448,6 +6460,7 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); window->DC.LastItemRect = bb; + ImGui::BeginGroup(); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -6484,6 +6497,7 @@ void ImGui::ListBoxFooter() ImGui::SameLine(); parent_window->DC.CursorPos = bb.Min; ItemSize(bb, style.FramePadding.y); + ImGui::EndGroup(); } bool ImGui::ListBox(const char* label, int* current_item, const char** items, int items_count, int height_items) @@ -6603,6 +6617,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) int components = alpha ? 4 : 3; bool value_changed = false; + ImGui::BeginGroup(); ImGui::PushID(label); bool hsv = (edit_mode == 1); @@ -6707,6 +6722,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) } ImGui::PopID(); + ImGui::EndGroup(); return value_changed; } From d953f8d99a25479346d7133b658fa0f66eb4f6d5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 14:49:58 +0000 Subject: [PATCH 38/44] ShowTestWindow: Graph checkbox under the label, also demo using BeginGroup/EndGroup() --- imgui.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 37721c82..84b9a541 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9433,9 +9433,12 @@ void ImGui::ShowTestWindow(bool* opened) phase += 0.10f*values_offset; } } - ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), (int)values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); - - ImGui::SameLine(); ImGui::Checkbox("pause", &pause); + ImGui::PlotLines("##Graph", &values.front(), (int)values.size(), (int)values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); + ImGui::SameLine(0, (int)ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::BeginGroup(); + ImGui::Text("Graph"); + ImGui::Checkbox("pause", &pause); + ImGui::EndGroup(); ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); } From 11025b31604934b825429980fd1414542d8bd7fc Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 15:01:07 +0000 Subject: [PATCH 39/44] Implicit "Debug" window hide itself based on cursor extend instead of the 'Accessed' flag. --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 84b9a541..96934461 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2064,8 +2064,9 @@ void ImGui::Render() { // Hide implicit window if it hasn't been used IM_ASSERT(g.CurrentWindowStack.size() == 1); // Mismatched Begin/End - if (g.CurrentWindow && !g.CurrentWindow->Accessed) - g.CurrentWindow->Visible = false; + if (ImGuiWindow* window = g.CurrentWindow) + if (ImLengthSqr(window->DC.CursorMaxPos - window->DC.CursorStartPos) < 0.001f) + g.CurrentWindow->Visible = false; ImGui::End(); // Select window for move/focus when we're done with all our widgets (we use the root window ID here) From 129339adb07f36e0795e98cd53dc32206c8e699e Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 15:03:10 +0000 Subject: [PATCH 40/44] Removed 'Accessed' flag from ImGuiWindow so GetCurrentWindow() compiles to a simpler accessor --- imgui.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 96934461..2b5f86d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1169,7 +1169,6 @@ struct ImGuiWindow float NextScrollY; bool ScrollbarY; bool Visible; // Set to true on Begin() - bool Accessed; // Set to true when any widget access the current window bool Collapsed; // Set when collapsing window to become only title-bar bool SkipItems; // == Visible && !Collapsed int AutoFitFrames; @@ -1223,7 +1222,6 @@ static inline ImGuiWindow* GetCurrentWindow() { ImGuiState& g = *GImGui; IM_ASSERT(g.CurrentWindow != NULL); // ImGui::NewFrame() hasn't been called yet? - g.CurrentWindow->Accessed = true; return g.CurrentWindow; } @@ -1512,7 +1510,6 @@ ImGuiWindow::ImGuiWindow(const char* name) NextScrollY = 0.0f; ScrollbarY = false; Visible = false; - Accessed = false; Collapsed = false; SkipItems = false; AutoFitFrames = -1; @@ -1937,7 +1934,6 @@ void ImGui::NewFrame() { ImGuiWindow* window = g.Windows[i]; window->Visible = false; - window->Accessed = false; } // No window should be open at the beginning of the frame. @@ -3189,10 +3185,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg clip_rect.z -= style.ScrollbarWidth; PushClipRect(clip_rect); - // Clear 'accessed' flag last thing - if (first_begin_of_the_frame) - window->Accessed = false; - // Child window can be out of sight and have "negative" clip windows. // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). if (flags & ImGuiWindowFlags_ChildWindow) From 6e5130ddf44c76fb191878f5a6875bdf58e63684 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 15:10:43 +0000 Subject: [PATCH 41/44] ShowTestWindow: Added Wdigets Alignment demo under Layout section --- imgui.cpp | 75 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2b5f86d5..2f680805 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9437,36 +9437,23 @@ void ImGui::ShowTestWindow(bool* opened) if (ImGui::CollapsingHeader("Layout")) { - if (ImGui::TreeNode("Text Baseline Alignment")) + if (ImGui::TreeNode("Widgets Alignment")) { - ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); - - ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("One\nTwo\nThree"); - - ImGui::Button("HOP"); ImGui::SameLine(); - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Button("HOP"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); + static float f = 0.0f; + ImGui::Text("Fixed: 100 pixels"); + ImGui::PushItemWidth(100); + ImGui::InputFloat("float##1", &f); + ImGui::PopItemWidth(); - ImGui::Button("TEST"); ImGui::SameLine(); - ImGui::Text("TEST"); ImGui::SameLine(); - ImGui::SmallButton("TEST"); + ImGui::Text("Proportional: 50%% of window width"); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); + ImGui::InputFloat("float##2", &f); + ImGui::PopItemWidth(); - ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. - ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); - ImGui::Button("Widget"); ImGui::SameLine(); - ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget"); + ImGui::Text("Right-aligned: Leave 100 pixels for label"); + ImGui::PushItemWidth(-100); + ImGui::InputFloat("float##3", &f); + ImGui::PopItemWidth(); ImGui::TreePop(); } @@ -9582,6 +9569,40 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::TreePop(); } + + if (ImGui::TreeNode("Text Baseline Alignment")) + { + ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); + + ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); + + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("TEST"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST"); + + ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); + ImGui::Button("Widget"); ImGui::SameLine(); + ImGui::Text("Widget"); ImGui::SameLine(); + ImGui::SmallButton("Widget"); + + ImGui::TreePop(); + } } if (ImGui::CollapsingHeader("Child regions")) From 693bd56db202ab53c59643b5144739b209e9d178 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 16:04:22 +0000 Subject: [PATCH 42/44] InputText() removed the odd ~ characters when clipping. Tweaks and fixes of clipping. --- imgui.cpp | 50 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2f680805..643bac46 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5562,9 +5562,9 @@ void ImGuiTextEditState::UpdateScrollOffset() // Scroll in chunks of quarter width const float scroll_x_increment = Width * 0.25f; const float cursor_offset_x = Font->CalcTextSizeW(FontSize, FLT_MAX, Text, Text+StbState.cursor, NULL).x; - if (ScrollX > cursor_offset_x) + if (cursor_offset_x < ScrollX) ScrollX = ImMax(0.0f, cursor_offset_x - scroll_x_increment); - else if (ScrollX < cursor_offset_x - Width) + else if (cursor_offset_x - Width >= ScrollX) ScrollX = cursor_offset_x - Width + scroll_x_increment; } @@ -5574,7 +5574,7 @@ ImVec2 ImGuiTextEditState::CalcDisplayOffsetFromCharIdx(int i) const const ImWchar* text_end = (Text+i >= text_start) ? Text+i : text_start; // Clip if requested character is outside of display IM_ASSERT(text_end >= text_start); - const ImVec2 offset = Font->CalcTextSizeW(FontSize, Width, text_start, text_end, NULL); + const ImVec2 offset = Font->CalcTextSizeW(FontSize, Width+1, text_start, text_end, NULL); return offset; } @@ -5607,30 +5607,19 @@ const ImWchar* ImGuiTextEditState::GetTextPointerClippedW(ImFont* font, float fo // [Static] void ImGuiTextEditState::RenderTextScrolledClipped(ImFont* font, float font_size, const char* buf, ImVec2 pos, float width, float scroll_x) { - // NB- We start drawing at character boundary - ImVec2 text_size; - const char* text_start = GetTextPointerClippedA(font, font_size, buf, scroll_x, NULL); - const char* text_end = GetTextPointerClippedA(font, font_size, text_start, width, &text_size); - - // We need to test for the possibility of malformed UTF-8 (instead of just text_end[0] != 0) - unsigned int text_end_char = 0; - ImTextCharFromUtf8(&text_end_char, text_end, NULL); - - // Draw a little clip symbol if we've got text on either left or right of the box - const char symbol_c = '~'; - const float symbol_w = font_size*0.40f; // FIXME: compute correct width - const float clip_begin = (text_start > buf && text_start < text_end) ? symbol_w : 0.0f; - const float clip_end = (text_end_char != 0 && text_end > text_start) ? symbol_w : 0.0f; + ImGuiWindow* window = GetCurrentWindow(); + const ImU32 font_color = window->Color(ImGuiCol_Text); + //window->DrawList->AddLine(pos, pos+ImVec2(width,0), 0xFF00FFFF); - // Draw text - RenderText(pos+ImVec2(clip_begin,0), text_start+(clip_begin>0.0f?1:0), text_end-(clip_end>0.0f?1:0), false); + // Determine start and end of visible string + // FIXME-OPT: This is pretty slow for what it does. + const char* text_start = scroll_x <= 0.0f ? buf : GetTextPointerClippedA(font, font_size, buf, scroll_x, NULL); + const char* text_end = GetTextPointerClippedA(font, font_size, text_start, width + 1, NULL); // +1 to allow character spacing to fit outside the allowed width + window->DrawList->AddText(font, font_size, pos, font_color, text_start, text_end); - // Draw the clip symbol - const char s[2] = {symbol_c,'\0'}; - if (clip_begin > 0.0f) - RenderText(pos, s); - if (clip_end > 0.0f) - RenderText(pos+ImVec2(width-clip_end,0.0f), s); + // Log as text + if (GImGui->LogEnabled) + LogText(pos, buf, NULL); } bool ImGui::InputFloat(const char* label, float *v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) @@ -5840,7 +5829,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT const char* buf_end = NULL; edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text, IM_ARRAYSIZE(edit_state.Text), buf, NULL, &buf_end); edit_state.CurLenA = buf_end - buf; // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. - edit_state.Width = w; + edit_state.Width = w + style.FramePadding.x; edit_state.InputCursorScreenPos = ImVec2(-1.f,-1.f); edit_state.CursorAnimReset(); @@ -6094,7 +6083,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT } } - ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w, (g.ActiveId == id) ? edit_state.ScrollX : 0.0f); + ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, (g.ActiveId == id) ? edit_state.ScrollX : 0.0f); if (g.ActiveId == id) { @@ -8430,6 +8419,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons } // Decode and advance source (handle unlikely UTF-8 decoding failure by skipping to the next byte) + const char* prev_s = s; unsigned int c = (unsigned int)*s; if (c < 0x80) { @@ -8452,7 +8442,10 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; if (line_width + char_width >= max_width) + { + s = prev_s; break; + } line_width += char_width; } @@ -8496,7 +8489,10 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; if (line_width + char_width >= max_width) + { + s--; break; + } line_width += char_width; } From d1aca79f4e795a2ae54eb3d838b55e7357eaaa19 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 16:40:59 +0000 Subject: [PATCH 43/44] InputText() update its width in case of resize initiated programmatically --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 643bac46..e506976a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5875,14 +5875,15 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT if (g.ActiveId == id) { // Edit in progress + edit_state.Width = w + style.FramePadding.x; edit_state.BufSizeA = buf_size; edit_state.Font = window->Font(); edit_state.FontSize = window->FontSize(); + edit_state.UpdateScrollOffset(); const float mx = g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x; const float my = window->FontSize()*0.5f; // Flatten mouse because we are doing a single-line edit - edit_state.UpdateScrollOffset(); if (select_all || (hovered && io.MouseDoubleClicked[0])) { edit_state.SelectAll(); @@ -5892,7 +5893,6 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT { stb_textedit_click(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my); edit_state.CursorAnimReset(); - } else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock) { @@ -6083,7 +6083,9 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT } } - ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, (g.ActiveId == id) ? edit_state.ScrollX : 0.0f); + const float render_scroll_x = (g.ActiveId == id) ? edit_state.ScrollX : 0.0f; + //const float render_scroll_x = (edit_state.Id == id) ? edit_state.ScrollX : 0.0f; + ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, render_scroll_x); if (g.ActiveId == id) { From ff5378bd662e7edd87d056bf4a5272e9c9624eb8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 19 Mar 2015 16:45:37 +0000 Subject: [PATCH 44/44] InputText() last active preserve scrolling position. Reset scroll if widget size becomes bigger than contents. --- imgui.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e506976a..ac65304a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5562,6 +5562,18 @@ void ImGuiTextEditState::UpdateScrollOffset() // Scroll in chunks of quarter width const float scroll_x_increment = Width * 0.25f; const float cursor_offset_x = Font->CalcTextSizeW(FontSize, FLT_MAX, Text, Text+StbState.cursor, NULL).x; + + // If widget became bigger than text (because of a resize), reset horizontal scrolling + if (ScrollX > 0.0f) + { + const float text_width = cursor_offset_x + Font->CalcTextSizeW(FontSize, FLT_MAX, Text+StbState.cursor, NULL, NULL).x; + if (text_width < Width) + { + ScrollX = 0.0f; + return; + } + } + if (cursor_offset_x < ScrollX) ScrollX = ImMax(0.0f, cursor_offset_x - scroll_x_increment); else if (cursor_offset_x - Width >= ScrollX) @@ -5873,14 +5885,18 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT bool cancel_edit = false; bool enter_pressed = false; if (g.ActiveId == id) + //if (edit_state.Id == id) // Works, but double-click to select-all sets cursors to end which in turn tends to scroll toward the right when shrinking widget. { - // Edit in progress + // Update some data if we are active or last active edit_state.Width = w + style.FramePadding.x; edit_state.BufSizeA = buf_size; edit_state.Font = window->Font(); edit_state.FontSize = window->FontSize(); edit_state.UpdateScrollOffset(); - + } + if (g.ActiveId == id) + { + // Edit in progress const float mx = g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x; const float my = window->FontSize()*0.5f; // Flatten mouse because we are doing a single-line edit @@ -6083,8 +6099,8 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT } } - const float render_scroll_x = (g.ActiveId == id) ? edit_state.ScrollX : 0.0f; - //const float render_scroll_x = (edit_state.Id == id) ? edit_state.ScrollX : 0.0f; + //const float render_scroll_x = (g.ActiveId == id) ? edit_state.ScrollX : 0.0f; + const float render_scroll_x = (edit_state.Id == id) ? edit_state.ScrollX : 0.0f; ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w + style.FramePadding.x, render_scroll_x); if (g.ActiveId == id)