From c603534d380de32cbdc580f1e4497460b9212840 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 31 May 2015 19:24:32 +0100 Subject: [PATCH 01/24] Version 1.40 --- imgui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index e1a1117e..9df8cf1b 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// ImGui library v1.40 WIP +// ImGui library v1.40 // 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, free, qsort, atoi #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.40 WIP" +#define IMGUI_VERSION "1.40" // Define assertion handler. #ifndef IM_ASSERT From 931b8dcdaf63c82c8b7df888bbf1c156442aef29 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 31 May 2015 19:31:02 +0100 Subject: [PATCH 02/24] Version 1.40 --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3e6a09e3..3798063d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// ImGui library v1.40 WIP +// ImGui library v1.40 // 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 From 82d4180f398140c4ec6ac59405d70debd2cc9299 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 31 May 2015 21:15:35 +0100 Subject: [PATCH 03/24] Bits of TODO list --- imgui.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3798063d..5127294c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -326,19 +326,22 @@ ================== - 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? - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. - 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. + - scrolling: add horizontal scroll +!- scrolling: set scrolling given a position. +!- scrolling: allow immediately effective change of scroll if we haven't appended items yet - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. - 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() 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 text: add ImGuiInputTextFlags_EnterToApply? (off github issue #218) +!- input text: multiple lines inputs (#200) !- 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) @@ -359,8 +362,12 @@ - combo/listbox: keyboard control. need inputtext like non-active focus + key handling. considering keybord for custom listbox (see github pr #203) - listbox: multiple selection - listbox: user may want to initial scroll to focus on the one selected value? + - listbox: keyboard navigation. + - listbox: scrolling should track modified selection. - menus: local shortcuts, global shortcuts (github issue #126) - menus: icons + - menus: see we can allow for click-menu-hold-release-on-item to work (like Windows does) + - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? - tabs - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) - gauge: various forms of gauge/loading bars widgets @@ -381,7 +388,7 @@ - tooltip: figure out a way to use TextWrapped() in a tooltip. - settings: write more decent code to allow saving/loading new fields - 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: 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? @@ -392,7 +399,7 @@ - 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) - ! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing +!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing - keyboard: full keyboard navigation and focus. - input: rework IO to be able to pass actual events to fix temporal aliasing issues. - input: support track pad style scrolling & slider edit. From 9928d19af183bfc63adbb2b40bfb8da4a452124e Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 2 Jun 2015 14:41:14 +0100 Subject: [PATCH 04/24] Version 1.41 WIP --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5127294c..3ff73f01 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// ImGui library v1.40 +// ImGui library v1.41 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 9df8cf1b..859bfc61 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// ImGui library v1.40 +// ImGui library v1.41 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, free, qsort, atoi #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.40" +#define IMGUI_VERSION "1.41 WIP" // Define assertion handler. #ifndef IM_ASSERT From 0e04dfbad7208e453290d27f2ef704fdac050a4b Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 2 Jun 2015 20:57:29 +0100 Subject: [PATCH 05/24] Added IsWindowHovered() helper. --- imgui.cpp | 19 +++++++++++++------ imgui.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3ff73f01..3a895f69 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4310,36 +4310,43 @@ const char* ImGui::GetStyleColName(ImGuiCol idx) return "Unknown"; } +bool ImGui::IsWindowHovered() +{ + ImGuiState& g = *GImGui; + return g.HoveredWindow == g.CurrentWindow; +} + bool ImGui::IsWindowFocused() { ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - return g.FocusedWindow == window; + return g.FocusedWindow == g.CurrentWindow; } bool ImGui::IsRootWindowFocused() { ImGuiState& g = *GImGui; - ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; + ImGuiWindow* root_window = g.CurrentWindow->RootWindow; return g.FocusedWindow == root_window; } bool ImGui::IsRootWindowOrAnyChildFocused() { ImGuiState& g = *GImGui; - ImGuiWindow* root_window = GetCurrentWindow()->RootWindow; + ImGuiWindow* root_window = g.CurrentWindow->RootWindow; return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window; } float ImGui::GetWindowWidth() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiState& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; return window->Size.x; } ImVec2 ImGui::GetWindowPos() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiState& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; return window->Pos; } diff --git a/imgui.h b/imgui.h index 859bfc61..93cf7937 100644 --- a/imgui.h +++ b/imgui.h @@ -344,6 +344,7 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " + IMGUI_API bool IsWindowHovered(); IMGUI_API bool IsWindowFocused(); // is current window focused (differentiate child windows from each others) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (top parent window in case of child windows) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused From e57d460e31dfa9337601ed6f35f93cd08317e211 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jun 2015 12:48:55 +0100 Subject: [PATCH 06/24] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b87cb4e..ea2b9fab 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,10 @@ Gallery ![screenshot 4](/web/test_window_04.png?raw=true) ![screenshot 5](/web/test_window_05_menus.png?raw=true) ![screenshot 6](/web/examples_03.png?raw=true) -![screenshot 7](/web/examples_02.png?raw=true) + +![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png) + +![screenshot 8](/web/examples_02.png?raw=true) ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: ``` From eb75ffdc5df78c492738c2bdec460a1eaac65292 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 3 Jun 2015 15:31:08 +0100 Subject: [PATCH 07/24] DragFloat(), SliderFloat() Fixed rounding of negative which sometimes made the negative lower range unreachable. --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3a895f69..1d47e58e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5629,13 +5629,15 @@ static inline float RoundScalar(float value, int decimal_precision) // 0: 1, 1: 0.1, 2: 0.01, etc. // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 // FIXME: Investigate better rounding methods - const float min_step = 1.0f / powf(10.0f, (float)decimal_precision); - const float remainder = fmodf(value, min_step); + float min_step = 1.0f / powf(10.0f, (float)decimal_precision); + bool negative = value < 0.0f; + value = fabsf(value); + float remainder = fmodf(value, min_step); if (remainder <= min_step*0.5f) value -= remainder; else value += (min_step - remainder); - return value; + return negative ? -value : value; } static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, bool horizontal) @@ -5718,7 +5720,6 @@ static bool SliderScalarBehavior(const ImRect& frame_bb, ImGuiID id, float* v, f // Round past decimal precision new_value = RoundScalar(new_value, decimal_precision); - if (*v != new_value) { *v = new_value; @@ -10810,13 +10811,13 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); static float f1=1.00f, f2=0.0067f; - ImGui::DragFloat("drag float", &f1, 1.0f); + ImGui::DragFloat("drag float", &f1, 0.005f); ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); } { static int i1=0; - ImGui::SliderInt("slider int", &i1, 0, 3); + ImGui::SliderInt("slider int", &i1, -1, 3); ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); static float f1=0.123f, f2=0.0f; From 20088303e99cb9c3d0d56d6f1eca4da489b53f72 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 4 Jun 2015 12:26:23 +0100 Subject: [PATCH 08/24] ImFont: ignoring \r --- imgui.cpp | 61 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1d47e58e..9b0cfddf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9714,12 +9714,20 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c if (c == 0) break; - if (c == '\n') + if (c < 32) { - line_width = word_width = blank_width = 0.0f; - inside_word = true; - s = next_s; - continue; + if (c == '\n') + { + line_width = word_width = blank_width = 0.0f; + inside_word = true; + s = next_s; + continue; + } + if (c == '\r') + { + s = next_s; + continue; + } } const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; @@ -9825,12 +9833,17 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons break; } - if (c == '\n') + if (c < 32) { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - continue; + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + if (c == '\r') + continue; } const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; @@ -9872,12 +9885,17 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be { const unsigned int c = (unsigned int)(*s++); - if (c == '\n') + if (c < 32) { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - continue; + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + if (c == '\r') + continue; } const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; @@ -9971,11 +9989,16 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re break; } - if (c == '\n') + if (c < 32) { - x = pos.x; - y += line_height; - continue; + if (c == '\n') + { + x = pos.x; + y += line_height; + continue; + } + if (c == '\r') + continue; } float char_width = 0.0f; From 45366684829674ef9a749430631d3802c0f58c65 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 10:09:12 -0600 Subject: [PATCH 09/24] Fixed issue with activating a Combo() not taking active id (#241) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 9b0cfddf..a7a8ac2e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7341,6 +7341,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (g.IO.MouseClicked[0]) { menu_toggled = true; + SetActiveId(0); g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id; if (g.ActiveComboID) FocusWindow(window); From 6807546cafc1b22f076e8eea88d861adf90c9bcd Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 11:35:29 -0600 Subject: [PATCH 10/24] Allow Set*WindowSize() calls to be used with popups. --- imgui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a7a8ac2e..abc421e5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3468,7 +3468,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } // Process SetNextWindow***() calls - bool window_pos_set_by_api = false; + bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this anymore :( need to look into that. @@ -3481,6 +3481,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ if (g.SetNextWindowSizeCond) { if (!window_was_visible) window->SetWindowSizeAllowFlags |= ImGuiSetCond_Appearing; + window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; ImGui::SetWindowSize(g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; } @@ -3602,11 +3603,11 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } else { - if (flags & ImGuiWindowFlags_AlwaysAutoResize) + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window_size_set_by_api) { window->SizeFull = size_auto_fit; } - else if (window->AutoFitFrames > 0) + else if (window->AutoFitFrames > 0 && !window_size_set_by_api) { // Auto-fit only grows during the first few frames window->SizeFull = window->AutoFitOnlyGrows ? ImMax(window->SizeFull, size_auto_fit) : size_auto_fit; From 6f1dd7a6880cc246747f47e1d7dc471c859cd117 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 12:32:19 -0600 Subject: [PATCH 11/24] Allow Set*WindowSize() calls to be used with popups (fix for using e.g. scroll function on the first frame) --- imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index abc421e5..8f5200f9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3573,7 +3573,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && !window_was_visible) { window->HiddenFrames = 1; - window->Size = window->SizeFull = window->SizeContents = ImVec2(0.f, 0.f); // TODO: We don't support SetNextWindowSize() for tooltips or popups yet + if (!window_size_set_by_api) + window->Size = window->SizeFull = ImVec2(0.f, 0.f); + window->SizeContents = ImVec2(0.f, 0.f); } // Calculate auto-fit size From 8c8632206888776650c526bfcfbe1f4139baad56 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 12:35:55 -0600 Subject: [PATCH 12/24] Combo() now using the popup facility. More consistent + when combo open hovering other widgets is disabled. (#241) --- imgui.cpp | 94 +++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8f5200f9..2e54f4fe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1301,7 +1301,6 @@ struct ImGuiState ImGuiTextEditState InputTextState; ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode - ImGuiID ActiveComboID; ImVec2 ActiveClickDeltaToCenter; float DragCurrentValue; // current dragged value, always float, not rounded by end-user precision settings ImVec2 DragLastMouseDelta; @@ -1362,7 +1361,6 @@ struct ImGuiState SetNextTreeNodeOpenedCond = 0; ScalarAsInputTextId = 0; - ActiveComboID = 0; ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f); DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); @@ -3126,6 +3124,14 @@ static void ClosePopupToLevel(int remaining) g.OpenedPopupStack.resize(remaining); } +static void ClosePopup(ImGuiID id) +{ + if (!IsPopupOpen(id)) + return; + ImGuiState& g = *GImGui; + ClosePopupToLevel(g.OpenedPopupStack.size() - 1); +} + // Close the popup we have begin-ed into. void ImGui::CloseCurrentPopup() { @@ -3156,7 +3162,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) } ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_ShowBorders|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; char name[32]; if (flags & ImGuiWindowFlags_ChildMenu) @@ -3176,7 +3182,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) bool ImGui::BeginPopup(const char* str_id) { - return BeginPopupEx(str_id, 0); + return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders); } void ImGui::EndPopup() @@ -7288,7 +7294,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char** items, int bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) { int items_count = 0; - const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this + const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open while (*p) { p += strlen(p) + 1; @@ -7320,7 +7326,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const bool hovered = IsHovered(frame_bb, id); - bool value_changed = false; 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 @@ -7336,71 +7341,66 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - ImGui::PushID((int)id); bool menu_toggled = false; if (hovered) { g.HoveredId = id; if (g.IO.MouseClicked[0]) { - menu_toggled = true; SetActiveId(0); - g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id; - if (g.ActiveComboID) - FocusWindow(window); + if (IsPopupOpen(id)) + { + ClosePopup(id); + } + else + { + FocusWindow(window); + ImGui::OpenPopup(label); + menu_toggled = true; + } } } - if (g.ActiveComboID == id) + bool value_changed = false; + if (IsPopupOpen(id)) { // Size default to hold ~7 items if (height_in_items < 0) height_in_items = 7; 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.FramePadding.y * 3); - 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 ImRect popup_rect(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImVec2(frame_bb.Max.x, frame_bb.Max.y + popup_height)); + ImGui::SetNextWindowPos(popup_rect.Min); + ImGui::SetNextWindowSize(popup_rect.GetSize()); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - ImGui::BeginChild("#ComboBox", popup_rect.GetSize(), false, flags); - ImGui::Spacing(); - - bool combo_item_active = false; - combo_item_active |= (g.ActiveId == GetCurrentWindow()->GetID("#SCROLLY")); - - // Display items - for (int i = 0; i < items_count; i++) + if (BeginPopupEx(label, flags)) { - ImGui::PushID((void*)(intptr_t)i); - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; - if (ImGui::Selectable(item_text, item_selected)) + // Display items + ImGui::Spacing(); + for (int i = 0; i < items_count; i++) { - SetActiveId(0); - g.ActiveComboID = 0; - value_changed = true; - *current_item = i; + ImGui::PushID((void*)(intptr_t)i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (ImGui::Selectable(item_text, item_selected)) + { + SetActiveId(0); + value_changed = true; + *current_item = i; + } + if (item_selected && menu_toggled) + ImGui::SetScrollPosHere(); + ImGui::PopID(); } - if (item_selected && menu_toggled) - ImGui::SetScrollPosHere(); - combo_item_active |= ImGui::IsItemActive(); - ImGui::PopID(); + ImGui::EndPopup(); } - ImGui::EndChild(); ImGui::PopStyleVar(); - ImGui::SetCursorPos(backup_pos); - - if (!combo_item_active && g.ActiveId != 0) - g.ActiveComboID = 0; } - - ImGui::PopID(); - return value_changed; } @@ -7769,7 +7769,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (opened) { ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always); - ImGuiWindowFlags flags = (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu; + ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display) } From e8422f7aa01cde1bb261d4ed5b9b908515887d07 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 12:49:13 -0600 Subject: [PATCH 13/24] SetScrollPosHere() rewrote to that window size is not required at the time of calling, can be used on frame 0 of an auto-resizing window --- imgui.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2e54f4fe..5459bc94 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1400,7 +1400,7 @@ struct ImGuiWindow ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame ImGuiID MoveID; // == window->GetID("#MOVE") float ScrollY; - float NextScrollY; + float ScrollTargetCenterY; // position which we aim to center on bool ScrollbarY; bool Active; // Set to true on Begin() bool WasActive; @@ -1766,7 +1766,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = ImVec2(0.0f, 0.0f); ScrollY = 0.0f; - NextScrollY = 0.0f; + ScrollTargetCenterY = -1.0f; ScrollbarY = false; Active = WasActive = false; Accessed = false; @@ -2192,7 +2192,7 @@ void ImGui::NewFrame() if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - window->NextScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines; + window->ScrollY -= g.IO.MouseWheel * window->CalcFontSize() * scroll_lines; } } } @@ -3715,11 +3715,14 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX; // Apply scrolling - window->ScrollY = window->NextScrollY; + if (window->ScrollTargetCenterY >= 0.0f) + { + window->ScrollY = window->ScrollTargetCenterY - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y); + window->ScrollTargetCenterY = -1.0f; + } window->ScrollY = ImMax(window->ScrollY, 0.0f); if (!window->Collapsed && !window->SkipItems) window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, window->SizeContents.y - window->SizeFull.y)); - window->NextScrollY = window->ScrollY; // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); @@ -4014,7 +4017,6 @@ static void Scrollbar(ImGuiWindow* window) // Apply scroll const float scroll_y_norm = ImSaturate((clicked_y_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); window->ScrollY = (float)(int)(0.5f + scroll_y_norm * (window->SizeContents.y - window->Size.y)); - window->NextScrollY = window->ScrollY; // Update values for rendering scroll_ratio = ImSaturate(window->ScrollY / scroll_max); @@ -4644,7 +4646,7 @@ float ImGui::GetScrollMaxY() void ImGui::SetScrollPosHere() { ImGuiWindow* window = GetCurrentWindow(); - window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y); + window->ScrollTargetCenterY = (window->DC.CursorPos.y + window->ScrollY); } void ImGui::SetKeyboardFocusHere(int offset) From 3ca54ad3699da66414b7026a87db3c910ac13651 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 12:57:27 -0600 Subject: [PATCH 14/24] SetScrollPosHere() takes account of item height + more accurate centering --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5459bc94..91ce2e1e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3717,7 +3717,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ // Apply scrolling if (window->ScrollTargetCenterY >= 0.0f) { - window->ScrollY = window->ScrollTargetCenterY - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y); + window->ScrollY = window->ScrollTargetCenterY - (window->Pos.y + (window->SizeFull.y + window->TitleBarHeight() + window->WindowPadding().y) * 0.5f); window->ScrollTargetCenterY = -1.0f; } window->ScrollY = ImMax(window->ScrollY, 0.0f); @@ -4646,7 +4646,7 @@ float ImGui::GetScrollMaxY() void ImGui::SetScrollPosHere() { ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTargetCenterY = (window->DC.CursorPos.y + window->ScrollY); + window->ScrollTargetCenterY = (window->DC.CursorPos.y + window->ScrollY) - window->DC.PrevLineHeight * 0.5f; } void ImGui::SetKeyboardFocusHere(int offset) From 3fd4441f70744d888768def5e6ab4203b2cab582 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 13:14:22 -0600 Subject: [PATCH 15/24] SetScrollPosHere() fixed imprecisions --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 91ce2e1e..8a7bbae7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4646,7 +4646,7 @@ float ImGui::GetScrollMaxY() void ImGui::SetScrollPosHere() { ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTargetCenterY = (window->DC.CursorPos.y + window->ScrollY) - window->DC.PrevLineHeight * 0.5f; + window->ScrollTargetCenterY = (float)(int)(window->DC.CursorPos.y + window->ScrollY - window->DC.PrevLineHeight * 0.5f); } void ImGui::SetKeyboardFocusHere(int offset) From 6bb06fdb81ef7bf1caaeb87dff63bc45f6475f69 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 14:32:37 -0600 Subject: [PATCH 16/24] Selectable, MenuItem: don't use frame rounding for hovering/selection. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8a7bbae7..16cac4c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7451,7 +7451,7 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar if (hovered || selected) { const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding); + RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); } if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size); From 039418f393838c77f5707ba75fd7cc529d75dee0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Jun 2015 14:39:27 -0600 Subject: [PATCH 17/24] ColorButton(), ColorEdit4(): colored square stays square, used vertical padding on both axis. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 16cac4c5..85c871b8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7794,7 +7794,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 = g.FontSize; - 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))); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.y*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; @@ -7841,7 +7841,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); const float w_full = ImGui::CalcItemWidth(); - const float square_sz = (g.FontSize + style.FramePadding.x * 2.0f); + const float square_sz = (g.FontSize + style.FramePadding.y * 2.0f); ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) From 96496ced5f1e530a7417f5fcfebfd4594a25fefb Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 11 Jun 2015 16:04:06 -0600 Subject: [PATCH 18/24] Metrics windows display storage size --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 85c871b8..9a001042 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11477,6 +11477,7 @@ void ImGui::ShowMetricsWindow(bool* opened) NodeDrawList(window->DrawList, "DrawList"); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.size() > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + ImGui::BulletText("Storage: %d bytes", (int)window->StateStorage.Data.size() * sizeof(ImGuiStorage::Pair)); ImGui::TreePop(); } }; From 2bcafc861eaf8daaadd44b500e9ef9f2a79cdcf2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 13 Jun 2015 14:20:02 -0600 Subject: [PATCH 19/24] SelectableEx - replaced unnecessary extra size_draw parameter by a flag. --- imgui.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9a001042..5d1bbb22 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -988,9 +988,10 @@ enum ImGuiButtonFlags_ enum ImGuiSelectableFlags_ { - ImGuiSelectableFlags_MenuItem = (1 << 0), - ImGuiSelectableFlags_DontClosePopups = (1 << 1), - ImGuiSelectableFlags_Disabled = (1 << 2) + ImGuiSelectableFlags_MenuItem = (1 << 0), + ImGuiSelectableFlags_DontClosePopups = (1 << 1), + ImGuiSelectableFlags_Disabled = (1 << 2), + ImGuiSelectableFlags_DrawFillAvailWidth = (1 << 3) }; @@ -7406,7 +7407,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi return value_changed; } -static bool SelectableEx(const char* label, bool selected, const ImVec2& size_arg, const ImVec2 size_draw_arg, ImGuiSelectableFlags flags) +static bool SelectableEx(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -7425,9 +7426,9 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar // Fill horizontal space. ImVec2 window_padding = window->WindowPadding(); float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x); - ImVec2 size_draw(size_draw_arg.x != 0.0f ? size_draw_arg.x : w_draw, size_draw_arg.y != 0.0f ? size_draw_arg.y : size.y); + ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); ImRect bb_with_spacing(pos, pos + size_draw); - if (size_draw_arg.x == 0.0f) + if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) bb_with_spacing.Max.x += window_padding.x; // Selectables are tightly packed together, we extend the box to cover spacing between selectable. @@ -7467,12 +7468,12 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) { - return SelectableEx(label, selected, size_arg, size_arg, 0); + return SelectableEx(label, selected, size_arg, 0); } bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg) { - if (SelectableEx(label, *p_selected, size_arg, size_arg, 0)) + if (SelectableEx(label, *p_selected, size_arg, 0)) { *p_selected = !*p_selected; return true; @@ -7588,7 +7589,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), ImGuiSelectableFlags_MenuItem | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); if (shortcut_size.x > 0.0f) { ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); @@ -7701,7 +7702,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); float w = label_size.x; - pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); ImGui::PopStyleVar(); ImGui::SameLine(); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); @@ -7711,7 +7712,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); if (!enabled) ImGui::PopStyleColor(); From cf481e1a7bb7df7f7f3bcef9196fbb30ba21fd10 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 14 Jun 2015 12:41:40 -0600 Subject: [PATCH 20/24] Selectable() added flags ImGuiSelectableFlags_DontClosePopups , ImGuiSelectableFlags_SpanAllColumns (#125) --- imgui.cpp | 66 +++++++++++++++++++++++++++++++++---------------------- imgui.h | 13 +++++++++-- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5d1bbb22..48dfd913 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -518,7 +518,6 @@ struct ImGuiState; struct ImGuiWindow; typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ -typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0); static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); @@ -979,19 +978,19 @@ enum ImGuiLayoutType_ enum ImGuiButtonFlags_ { - ImGuiButtonFlags_Repeat = (1 << 0), - ImGuiButtonFlags_PressedOnClick = (1 << 1), - ImGuiButtonFlags_FlattenChilds = (1 << 2), - ImGuiButtonFlags_DontClosePopups = (1 << 3), - ImGuiButtonFlags_Disabled = (1 << 4) + ImGuiButtonFlags_Repeat = 1 << 0, + ImGuiButtonFlags_PressedOnClick = 1 << 1, + ImGuiButtonFlags_FlattenChilds = 1 << 2, + ImGuiButtonFlags_DontClosePopups = 1 << 3, + ImGuiButtonFlags_Disabled = 1 << 4 }; -enum ImGuiSelectableFlags_ +enum ImGuiSelectableFlagsPrivate_ { - ImGuiSelectableFlags_MenuItem = (1 << 0), - ImGuiSelectableFlags_DontClosePopups = (1 << 1), - ImGuiSelectableFlags_Disabled = (1 << 2), - ImGuiSelectableFlags_DrawFillAvailWidth = (1 << 3) + // NB: need to be in sync with last value of ImGuiSelectableFlags_ + ImGuiSelectableFlags_MenuItem = 1 << 2, + ImGuiSelectableFlags_Disabled = 1 << 3, + ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 4 }; @@ -7407,13 +7406,18 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi return value_changed; } -static bool SelectableEx(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) +// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. +// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. +bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + PopClipRect(); + const ImGuiStyle& style = g.Style; ImGuiID id = window->GetID(label); ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); @@ -7425,7 +7429,8 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar // Fill horizontal space. ImVec2 window_padding = window->WindowPadding(); - float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x); + float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? ImGui::GetWindowContentRegionMax().x : ImGui::GetContentRegionMax().x; + float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x); ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); ImRect bb_with_spacing(pos, pos + size_draw); if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) @@ -7441,7 +7446,11 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar bb_with_spacing.Max.x += spacing_R; bb_with_spacing.Max.y += spacing_D; if (!ItemAdd(bb_with_spacing, &id)) + { + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + PushColumnClipRect(); return false; + } bool hovered, held; bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, ((flags & ImGuiSelectableFlags_MenuItem) ? ImGuiButtonFlags_PressedOnClick : 0) | ((flags & ImGuiSelectableFlags_Disabled) ? ImGuiButtonFlags_Disabled : 0)); @@ -7454,6 +7463,13 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); } + + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + { + PushColumnClipRect(); + bb_with_spacing.Max.x -= (ImGui::GetContentRegionMax().x - max_x); + } + if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size); if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor(); @@ -7464,16 +7480,9 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar return pressed; } -// Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. -// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. -bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) +bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) { - return SelectableEx(label, selected, size_arg, 0); -} - -bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg) -{ - if (SelectableEx(label, *p_selected, size_arg, 0)) + if (ImGui::Selectable(label, *p_selected, size_arg, flags)) { *p_selected = !*p_selected; return true; @@ -7589,7 +7598,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + bool pressed = ImGui::Selectable(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); if (shortcut_size.x > 0.0f) { ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); @@ -7702,7 +7711,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); float w = label_size.x; - pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); ImGui::PopStyleVar(); ImGui::SameLine(); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); @@ -7712,7 +7721,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - pressed = SelectableEx(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); if (!enabled) ImGui::PopStyleColor(); @@ -11226,9 +11235,14 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::Separator(); const char* names[3] = { "One", "Two", "Three" }; const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; for (int i = 0; i < 3; i++) { - ImGui::Text("%04d", i); ImGui::NextColumn(); + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImVec2(0,0), ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + ImGui::NextColumn(); ImGui::Text(names[i]); ImGui::NextColumn(); ImGui::Text(paths[i]); ImGui::NextColumn(); ImGui::Text("...."); ImGui::NextColumn(); diff --git a/imgui.h b/imgui.h index 93cf7937..a27f091c 100644 --- a/imgui.h +++ b/imgui.h @@ -48,6 +48,7 @@ typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ typedef int ImGuiSetCond; // enum ImGuiSetCond_ typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_ +typedef int ImGuiSelectableFlags; // enum ImGuiSelectableFlags_ struct ImGuiTextEditCallbackData; // for advanced uses of InputText() typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); @@ -300,8 +301,8 @@ namespace ImGui IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0)); - IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0)); + IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); + IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. @@ -443,6 +444,14 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_CallbackCharFilter = 1 << 9 // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. }; +// Flags for ImGui::Selectable() +enum ImGuiSelectableFlags_ +{ + // Default: 0 + ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window + ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame spans all columns (text will still fit in current column) +}; + // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { From c82e72eecb30496f857d992cf24dadf714a20990 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 14 Jun 2015 15:14:33 -0600 Subject: [PATCH 21/24] Selectable() parameter comment --- imgui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index a27f091c..a62f3e14 100644 --- a/imgui.h +++ b/imgui.h @@ -301,7 +301,7 @@ namespace ImGui IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); + IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); @@ -449,7 +449,7 @@ enum ImGuiSelectableFlags_ { // Default: 0 ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window - ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame spans all columns (text will still fit in current column) + ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame can span all columns (text will still fit in current column) }; // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array From 4f0fa58ff29c17f6fc25cad051a0b2065df57130 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 14 Jun 2015 15:19:47 -0600 Subject: [PATCH 22/24] Selectable() changed prototype moved flags before size. size override should rarely have been used! sorry. #125 --- imgui.cpp | 27 ++++++++++++++------------- imgui.h | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 48dfd913..c57921e4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -136,11 +136,12 @@ 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/05/31 (1.39) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). - - 2015/05/31 (1.39) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). - - 2015/05/27 (1.39) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. - - 2015/05/11 (1.39) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened. - - 2015/05/03 (1.39) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). + - 2015/06/14 (1.41) - changed prototype of Selectable(label, selected, size) to Selectable(label, selected, flags, size). Size override should have been rarely be used. Sorry! + - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). + - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). + - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. + - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened. + - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. @@ -7408,7 +7409,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi // Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. -bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) +bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -7480,9 +7481,9 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg, return pressed; } -bool ImGui::Selectable(const char* label, bool* p_selected, const ImVec2& size_arg, ImGuiSelectableFlags flags) +bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { - if (ImGui::Selectable(label, *p_selected, size_arg, flags)) + if (ImGui::Selectable(label, *p_selected, flags, size_arg)) { *p_selected = !*p_selected; return true; @@ -7598,7 +7599,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - bool pressed = ImGui::Selectable(label, false, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); if (shortcut_size.x > 0.0f) { ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); @@ -7711,7 +7712,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); float w = label_size.x; - pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); ImGui::PopStyleVar(); ImGui::SameLine(); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); @@ -7721,7 +7722,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w); - pressed = ImGui::Selectable(label, opened, ImVec2(w, 0.0f), ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0)); + pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); if (!enabled) ImGui::PopStyleColor(); @@ -10648,7 +10649,7 @@ void ImGui::ShowTestWindow(bool* opened) for (int i = 0; i < 16; i++) { ImGui::PushID(i); - if (ImGui::Selectable("Me", &selected[i], ImVec2(50,50))) + if (ImGui::Selectable("Me", &selected[i], 0, ImVec2(50,50))) { int x = i % 4, y = i / 4; if (x > 0) selected[i - 1] ^= 1; @@ -11240,7 +11241,7 @@ void ImGui::ShowTestWindow(bool* opened) { char label[32]; sprintf(label, "%04d", i); - if (ImGui::Selectable(label, selected == i, ImVec2(0,0), ImGuiSelectableFlags_SpanAllColumns)) + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) selected = i; ImGui::NextColumn(); ImGui::Text(names[i]); ImGui::NextColumn(); diff --git a/imgui.h b/imgui.h index a62f3e14..ab565ecf 100644 --- a/imgui.h +++ b/imgui.h @@ -301,8 +301,8 @@ namespace ImGui IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height - IMGUI_API bool Selectable(const char* label, bool* p_selected, const ImVec2& size = ImVec2(0,0), ImGuiSelectableFlags flags = 0); + IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height + IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); IMGUI_API bool ListBox(const char* label, int* current_item, const char** items, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. From b503e5ee5b6d65f6fe71e24ce70c6f18272a4dc4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 14 Jun 2015 16:18:22 -0600 Subject: [PATCH 23/24] ImageButton() changed default bg_col parameter from (0,0,0,1) black to (0,0,0,0) tranparent + drawing frame even when no padding (#243) --- imgui.cpp | 10 +++++----- imgui.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c57921e4..4321b6f7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -136,7 +136,8 @@ 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/06/14 (1.41) - changed prototype of Selectable(label, selected, size) to Selectable(label, selected, flags, size). Size override should have been rarely be used. Sorry! + - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence + - 2015/06/14 (1.41) - changed Selectable() API from (label, selected, size) to (label, selected, flags, size). Size override should have been rarely be used. Sorry! - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. @@ -5109,7 +5110,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I const ImGuiStyle& style = g.Style; // Default to using texture ID as ID. User can still push string/integer prefixes. - // We could hash the size/uv to create a unique ID but that would prevent the user from animating buttons. + // We could hash the size/uv to create a unique ID but that would prevent the user from animating UV. ImGui::PushID((void *)user_texture_id); const ImGuiID id = window->GetID("#image"); ImGui::PopID(); @@ -5126,8 +5127,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I // Render const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - if (padding.x > 0.0f || padding.y > 0.0f) - RenderFrame(bb.Min, bb.Max, col); + RenderFrame(bb.Min, bb.Max, col); if (bg_col.w > 0.0f) window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, window->Color(bg_col)); window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, window->Color(tint_col)); @@ -10616,7 +10616,7 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::SameLine(); ImGui::PushID(i); int frame_padding = -1 + i; // -1 = uses default padding - if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding)) + if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255))) pressed_count += 1; ImGui::PopID(); } diff --git a/imgui.h b/imgui.h index ab565ecf..4a891ea6 100644 --- a/imgui.h +++ b/imgui.h @@ -237,7 +237,7 @@ namespace ImGui IMGUI_API bool SmallButton(const char* label); IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); - IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,1), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false); IMGUI_API bool Checkbox(const char* label, bool* v); IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); From 6eb1fec7a991ce815e525e0f7b1882b89bcc1b5c Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 14 Jun 2015 17:30:06 -0600 Subject: [PATCH 24/24] ImFont: added GetCharAdvance() helper. Exposed font Ascent and font Descent. --- imgui.cpp | 7 ++++--- imgui.h | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4321b6f7..f71d54f8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2703,7 +2703,7 @@ static void RenderCheckMark(ImVec2 pos, ImU32 col) a.x = pos.x + start_x; b.x = a.x + rem_third; c.x = a.x + rem_third * 3.0f; - b.y = pos.y + (float)(int)(g.Font->BaseLine * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); + b.y = pos.y + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); a.y = b.y - rem_third; c.y = b.y - rem_third * 2.0f; @@ -9215,7 +9215,8 @@ bool ImFontAtlas::Build() const float font_scale = stbtt_ScaleForPixelHeight(&data.FontInfo, data.SizePixels); int font_ascent, font_descent, font_line_gap; stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap); - data.OutFont->BaseLine = (font_ascent * font_scale); + data.OutFont->Ascent = (font_ascent * font_scale); + data.OutFont->Descent = (font_descent * font_scale); data.OutFont->Glyphs.resize(0); const float uv_scale_x = 1.0f / TexWidth; @@ -9374,7 +9375,7 @@ void ImFont::Clear() { FontSize = 0.0f; DisplayOffset = ImVec2(-0.5f, 0.5f); - BaseLine = 0.0f; + Ascent = Descent = 0.0f; ContainerAtlas = NULL; Glyphs.clear(); FallbackGlyph = NULL; diff --git a/imgui.h b/imgui.h index 4a891ea6..a5a94e06 100644 --- a/imgui.h +++ b/imgui.h @@ -1114,7 +1114,8 @@ struct ImFont signed short XOffset, YOffset; float U0, V0, U1, V1; // Texture coordinates }; - float BaseLine; // Distance from top to bottom of e.g. 'A' [0..FontSize] + float Ascent; // Distance from top to bottom of e.g. 'A' [0..FontSize] + float Descent; // ImFontAtlas* ContainerAtlas; // What we has been loaded into ImVector Glyphs; const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) @@ -1127,9 +1128,10 @@ struct ImFont IMGUI_API ~ImFont(); IMGUI_API void Clear(); IMGUI_API void BuildLookupTable(); + IMGUI_API float GetCharAdvance(unsigned short c) const { return ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] : FallbackXAdvance; } IMGUI_API const Glyph* FindGlyph(unsigned short c) const; IMGUI_API void SetFallbackChar(ImWchar c); - IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } + IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.