From 8a553cdcbe3170e27c8f98e832e41a988bef3895 Mon Sep 17 00:00:00 2001 From: Martins Mozeiko Date: Thu, 19 Mar 2015 19:36:17 -0700 Subject: [PATCH 01/15] Replace assert with IM_ASSERT in few places. --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ac65304a..d654e1b6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10335,7 +10335,7 @@ static unsigned char *stb__dout; static void stb__match(unsigned char *data, unsigned int length) { // INVERSE of memmove... write each byte before copying the next... - assert (stb__dout + length <= stb__barrier); + IM_ASSERT (stb__dout + length <= stb__barrier); if (stb__dout + length > stb__barrier) { stb__dout += length; return; } if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } while (length--) *stb__dout++ = *data++; @@ -10343,7 +10343,7 @@ static void stb__match(unsigned char *data, unsigned int length) static void stb__lit(unsigned char *data, unsigned int length) { - assert (stb__dout + length <= stb__barrier); + IM_ASSERT (stb__dout + length <= stb__barrier); if (stb__dout + length > stb__barrier) { stb__dout += length; return; } if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } memcpy(stb__dout, data, length); @@ -10420,17 +10420,17 @@ static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsi i = stb_decompress_token(i); if (i == old_i) { if (*i == 0x05 && i[1] == 0xfa) { - assert(stb__dout == output + olen); + IM_ASSERT(stb__dout == output + olen); if (stb__dout != output + olen) return 0; if (stb_adler32(1, output, olen) != (unsigned int) stb__in4(2)) return 0; return olen; } else { - assert(0); /* NOTREACHED */ + IM_ASSERT(0); /* NOTREACHED */ return 0; } } - assert(stb__dout <= output + olen); + IM_ASSERT(stb__dout <= output + olen); if (stb__dout > output + olen) return 0; } From a71fc8e6a51d50185fe8c31bae4497ec929ff044 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 10:46:07 +0000 Subject: [PATCH 02/15] Fixed MouseClickedPos not updated on double-click update (fix #167) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index d654e1b6..6ae27108 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1835,8 +1835,8 @@ void ImGui::NewFrame() else { g.IO.MouseClickedTime[i] = g.Time; - g.IO.MouseClickedPos[i] = g.IO.MousePos; } + g.IO.MouseClickedPos[i] = g.IO.MousePos; } } for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) From 2d2990761144d168a818384213ffa94e9c628535 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 10:49:17 +0000 Subject: [PATCH 03/15] Added GetMouseDragDelta() helper. No unlock threshold yet (#167) --- imgui.cpp | 8 ++++++++ imgui.h | 1 + 2 files changed, 9 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 6ae27108..bb2bffcc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2541,6 +2541,14 @@ ImVec2 ImGui::GetMousePos() return GImGui->IO.MousePos; } +ImVec2 ImGui::GetMouseDragDelta() +{ + 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); +} + bool ImGui::IsItemHovered() { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui.h b/imgui.h index 8f28d5fd..5ba5e8bb 100644 --- a/imgui.h +++ b/imgui.h @@ -371,6 +371,7 @@ namespace ImGui 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 ImVec2 GetMouseDragDelta(); // dragging amount - also see: GetItemActiveDragDelta(). IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API const char* GetStyleColName(ImGuiCol idx); From 2d81a73f8552c2aaaba5bbc7f94eb9a7312575ba Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 10:51:33 +0000 Subject: [PATCH 04/15] Double-clicking on resize grip doesn't keep grip active if mouse button is kept held. --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index bb2bffcc..b3842939 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3056,6 +3056,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size, float bg window->SizeFull = size_auto_fit; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) MarkSettingsDirty(); + SetActiveId(0); } else if (held) { From c0703146219ae0de7c4809fae21bda52e852bf83 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 10:54:21 +0000 Subject: [PATCH 05/15] Reverted 11025b31604934b825429980fd1414542d8bd7fc, 129339adb07f36e0795e98cd53dc32206c8e699e it breaks collapsing implicit debug window --- imgui.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b3842939..b6f0cd7a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1169,6 +1169,7 @@ 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; @@ -1222,6 +1223,7 @@ 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; } @@ -1510,6 +1512,7 @@ ImGuiWindow::ImGuiWindow(const char* name) NextScrollY = 0.0f; ScrollbarY = false; Visible = false; + Accessed = false; Collapsed = false; SkipItems = false; AutoFitFrames = -1; @@ -1934,6 +1937,7 @@ 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. @@ -2060,9 +2064,8 @@ void ImGui::Render() { // Hide implicit window if it hasn't been used IM_ASSERT(g.CurrentWindowStack.size() == 1); // Mismatched Begin/End - if (ImGuiWindow* window = g.CurrentWindow) - if (ImLengthSqr(window->DC.CursorMaxPos - window->DC.CursorStartPos) < 0.001f) - g.CurrentWindow->Visible = false; + if (g.CurrentWindow && !g.CurrentWindow->Accessed) + 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) @@ -3194,6 +3197,10 @@ 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 4cd438f66302fa8dd93ad8afe4780e6b30fec262 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 11:13:18 +0000 Subject: [PATCH 06/15] Added IsMouseDragging(), GetMouseDragDelta() given button and lock threshold. added io.MouseDragThreshold setting. (#167) Removed GetItemActiveDragDelta() --- imgui.cpp | 44 +++++++++++++++++++++++++++----------------- imgui.h | 6 ++++-- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b6f0cd7a..33e03e12 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -577,6 +577,7 @@ ImGuiIO::ImGuiIO() MousePosPrev = ImVec2(-1,-1); MouseDoubleClickTime = 0.30f; MouseDoubleClickMaxDist = 6.0f; + MouseDragThreshold = 6.0f; UserData = NULL; // User functions @@ -1840,6 +1841,11 @@ void ImGui::NewFrame() g.IO.MouseClickedTime[i] = g.Time; } g.IO.MouseClickedPos[i] = g.IO.MousePos; + g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (g.IO.MouseDown[i]) + { + g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); } } for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) @@ -2539,16 +2545,29 @@ bool ImGui::IsMouseDoubleClicked(int button) return g.IO.MouseDoubleClicked[button]; } +bool ImGui::IsMouseDragging(int button, float lock_threshold) +{ + ImGuiState& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; +} + ImVec2 ImGui::GetMousePos() { return GImGui->IO.MousePos; } -ImVec2 ImGui::GetMouseDragDelta() +ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) { 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). + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + if (g.IO.MouseDown[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). return ImVec2(0.0f, 0.0f); } @@ -2581,17 +2600,6 @@ 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(); @@ -9417,11 +9425,13 @@ void ImGui::ShowTestWindow(bool* opened) 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); + static ImVec2 value_raw(0.0f, 0.0f); + static ImVec2 value_with_lock_threshold(0.0f, 0.0f); ImGui::Button("Drag Me"); if (ImGui::IsItemActive()) { - value = ImGui::GetItemActiveDragDelta(); + value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + value_with_lock_threshold = ImGui::GetMouseDragDelta(0); //ImGui::SetTooltip("Delta: %.1f, %.1f", value.x, value.y); // Draw a line between the button and the mouse cursor @@ -9430,7 +9440,7 @@ void ImGui::ShowTestWindow(bool* opened) 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::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y); ImGui::TreePop(); } } diff --git a/imgui.h b/imgui.h index 5ba5e8bb..3319624b 100644 --- a/imgui.h +++ b/imgui.h @@ -355,7 +355,6 @@ namespace ImGui 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 IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " @@ -369,9 +368,10 @@ namespace ImGui 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 IsMouseHoveringRect(const ImVec2& rect_min, const ImVec2& rect_max);// is mouse hovering given bounding rect + IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold. 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 ImVec2 GetMouseDragDelta(); // dragging amount - also see: GetItemActiveDragDelta(). + IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount, also see: GetItemActiveDragDelta(). if lock_threshold < -1.0f uses io.MouseDraggingThreshold. IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API const char* GetStyleColName(ImGuiCol idx); @@ -581,6 +581,7 @@ struct ImGuiIO const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array void* UserData; // = NULL // Store your own data for retrieval by callbacks. @@ -650,6 +651,7 @@ struct ImGuiIO bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. float MouseDownTime[5]; // Time the mouse button has been down + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point float KeysDownTime[512]; // Time the keyboard key has been down IMGUI_API ImGuiIO(); From 876a755bac153bdc8119b41e0573cebefe73d2a0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 11:22:26 +0000 Subject: [PATCH 07/15] Removed unnecessary assert (will crash well enough without) + comment --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 33e03e12..c0fd6353 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1222,8 +1222,8 @@ public: static inline ImGuiWindow* GetCurrentWindow() { + // If this ever crash it probably means that ImGui::NewFrame() hasn't been called. We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) ImGuiState& g = *GImGui; - IM_ASSERT(g.CurrentWindow != NULL); // ImGui::NewFrame() hasn't been called yet? g.CurrentWindow->Accessed = true; return g.CurrentWindow; } From efeeba99cacd835a90f32614e699d0fafef32a6a Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 14:03:23 +0000 Subject: [PATCH 08/15] Tweak stb_textedit integration to be lenient if another user are leaking their STB_TEXTEDIT definitions/symbols --- imgui.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c0fd6353..2ce106fa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -400,6 +400,8 @@ namespace IMGUI_STB_NAMESPACE #endif #include "stb_truetype.h" +#undef STB_TEXTEDIT_STRING +#undef STB_TEXTEDIT_CHARTYPE #define STB_TEXTEDIT_STRING ImGuiTextEditState #define STB_TEXTEDIT_CHARTYPE ImWchar #include "stb_textedit.h" @@ -5546,24 +5548,22 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im return true; } -enum -{ - STB_TEXTEDIT_K_LEFT = 1 << 16, // keyboard input to move cursor left - STB_TEXTEDIT_K_RIGHT, // keyboard input to move cursor right - STB_TEXTEDIT_K_UP, // keyboard input to move cursor up - STB_TEXTEDIT_K_DOWN, // keyboard input to move cursor down - STB_TEXTEDIT_K_LINESTART, // keyboard input to move cursor to start of line - STB_TEXTEDIT_K_LINEEND, // keyboard input to move cursor to end of line - STB_TEXTEDIT_K_TEXTSTART, // keyboard input to move cursor to start of text - STB_TEXTEDIT_K_TEXTEND, // keyboard input to move cursor to end of text - STB_TEXTEDIT_K_DELETE, // keyboard input to delete selection or character under cursor - STB_TEXTEDIT_K_BACKSPACE, // keyboard input to delete selection or character left of cursor - STB_TEXTEDIT_K_UNDO, // keyboard input to perform undo - STB_TEXTEDIT_K_REDO, // keyboard input to perform redo - STB_TEXTEDIT_K_WORDLEFT, // keyboard input to move cursor left one word - STB_TEXTEDIT_K_WORDRIGHT, // keyboard input to move cursor right one word - STB_TEXTEDIT_K_SHIFT = 1 << 17 -}; +// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols) +#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left +#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right +#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up +#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down +#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line +#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line +#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text +#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text +#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor +#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor +#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo +#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo +#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word +#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word +#define STB_TEXTEDIT_K_SHIFT 0x20000 #ifdef IMGUI_STB_NAMESPACE namespace IMGUI_STB_NAMESPACE From 2142181c515b8a985bec075ee589c7b76298b9fa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Mar 2015 12:08:00 -0700 Subject: [PATCH 09/15] Allow to disable help and test window functionality --- imconfig.h | 3 +++ imgui.cpp | 2 ++ imgui.h | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/imconfig.h b/imconfig.h index bcb0972e..c924d6f8 100644 --- a/imconfig.h +++ b/imconfig.h @@ -22,6 +22,9 @@ //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS +//---- Don't implement help and test window functionality (ShowUserGuide, ShowStyleEditor and ShowTestWindow methods won't be available) +//#define IMGUI_DISABLE_TEST_WINDOWS + //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions. //#define IMGUI_INCLUDE_IMGUI_USER_INL diff --git a/imgui.cpp b/imgui.cpp index ac65304a..0dccd5bb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8778,6 +8778,7 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) #endif +#ifndef IMGUI_DISABLE_TEST_WINDOWS //----------------------------------------------------------------------------- // HELP //----------------------------------------------------------------------------- @@ -10308,6 +10309,7 @@ static void ShowExampleAppLongText(bool* opened) } // End of Sample code +#endif //----------------------------------------------------------------------------- // FONT DATA diff --git a/imgui.h b/imgui.h index 8f28d5fd..778dea15 100644 --- a/imgui.h +++ b/imgui.h @@ -155,10 +155,11 @@ namespace ImGui IMGUI_API void NewFrame(); IMGUI_API void Render(); IMGUI_API void Shutdown(); +#ifndef IMGUI_DISABLE_TEST_WINDOWS IMGUI_API void ShowUserGuide(); IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); IMGUI_API void ShowTestWindow(bool* open = NULL); - +#endif // Window // See implementation in .cpp for details IMGUI_API bool Begin(const char* name = "Debug", bool* p_opened = NULL, const ImVec2& initial_size = ImVec2(0,0), float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code. passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. From 60f3cfbe98b27a04602437b350037f2a5d228634 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 20:50:55 +0000 Subject: [PATCH 10/15] Fixed MouseDrawCursor feature submitting an empty trailing command in the draw list + Merged 4 draw calls into one, should be merged at lower level. --- imgui.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2ce106fa..77416a8c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1207,7 +1207,6 @@ public: ImGuiID GetID(const char* str); ImGuiID GetID(const void* ptr); - void AddToRenderList(); bool FocusItemRegister(bool is_active, bool tab_stop = true); // Return true if focus is requested void FocusItemUnregister(); @@ -1600,21 +1599,24 @@ void ImGuiWindow::FocusItemUnregister() FocusIdxTabCounter--; } -void ImGuiWindow::AddToRenderList() +static inline void AddDrawListToRenderList(ImDrawList* draw_list) { - ImGuiState& g = *GImGui; - - if (!DrawList->commands.empty() && !DrawList->vtx_buffer.empty()) + if (!draw_list->commands.empty() && !draw_list->vtx_buffer.empty()) { - if (DrawList->commands.back().vtx_count == 0) - DrawList->commands.pop_back(); - g.RenderDrawLists.push_back(DrawList); + if (draw_list->commands.back().vtx_count == 0) + draw_list->commands.pop_back(); + GImGui->RenderDrawLists.push_back(draw_list); } - for (size_t i = 0; i < DC.ChildWindows.size(); i++) +} + +static void AddWindowToRenderList(ImGuiWindow* window) +{ + AddDrawListToRenderList(window->DrawList); + for (size_t i = 0; i < window->DC.ChildWindows.size(); i++) { - ImGuiWindow* child = DC.ChildWindows[i]; + ImGuiWindow* child = window->DC.ChildWindows[i]; if (child->Visible) // clipped children may have been marked not Visible - child->AddToRenderList(); + AddWindowToRenderList(child); } } @@ -2123,13 +2125,13 @@ void ImGui::Render() { ImGuiWindow* window = g.Windows[i]; if (window->Visible && (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) == 0) - window->AddToRenderList(); + AddWindowToRenderList(window); } for (size_t i = 0; i != g.Windows.size(); i++) { ImGuiWindow* window = g.Windows[i]; if (window->Visible && (window->Flags & ImGuiWindowFlags_Tooltip)) - window->AddToRenderList(); + AddWindowToRenderList(window); } if (g.IO.MouseDrawCursor) @@ -2140,11 +2142,13 @@ void ImGui::Render() const ImVec2 tex_uv_scale(1.0f/g.IO.Fonts->TexWidth, 1.0f/g.IO.Fonts->TexHeight); static ImDrawList draw_list; draw_list.Clear(); + draw_list.PushTextureID(tex_id); draw_list.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow draw_list.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow draw_list.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0xFF000000); // Black border draw_list.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_WHITE * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_WHITE + size) * tex_uv_scale, 0xFFFFFFFF); // White fill - g.RenderDrawLists.push_back(&draw_list); + draw_list.PopTextureID(); + AddDrawListToRenderList(&draw_list); } // Render From 5f914c9cbee0918ba7c5d641a02c27fa6b8698c1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 21:06:45 +0000 Subject: [PATCH 11/15] Comment --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 77416a8c..df7309af 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7587,6 +7587,7 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im if ((col >> 24) == 0) return; + // FIXME-OPT: This is wasting draw calls. const bool push_texture_id = texture_id_stack.empty() || user_texture_id != texture_id_stack.back(); if (push_texture_id) PushTextureID(user_texture_id); From 6699ccfd1fa5e9b1d36157ca6485f8e47d222b3d Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 22:52:32 +0000 Subject: [PATCH 12/15] Tweaked IMGUI_DISABLE_TEST_WINDOWS so it doesn't show in ImGui.h --- imconfig.h | 2 +- imgui.cpp | 9 ++++++++- imgui.h | 3 +-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/imconfig.h b/imconfig.h index c924d6f8..a07a1331 100644 --- a/imconfig.h +++ b/imconfig.h @@ -22,7 +22,7 @@ //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS -//---- Don't implement help and test window functionality (ShowUserGuide, ShowStyleEditor and ShowTestWindow methods won't be available) +//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) //#define IMGUI_DISABLE_TEST_WINDOWS //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions. diff --git a/imgui.cpp b/imgui.cpp index ce4afbc4..526ff293 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8807,7 +8807,14 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) #endif -#ifndef IMGUI_DISABLE_TEST_WINDOWS +#ifdef IMGUI_DISABLE_TEST_WINDOWS + +void ImGui::ShowUserGuide() {} +void ImGui::ShowStyleEditor() {} +void ImGui::ShowTestWindow() {} + +#else + //----------------------------------------------------------------------------- // HELP //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index df196325..3319624b 100644 --- a/imgui.h +++ b/imgui.h @@ -155,11 +155,10 @@ namespace ImGui IMGUI_API void NewFrame(); IMGUI_API void Render(); IMGUI_API void Shutdown(); -#ifndef IMGUI_DISABLE_TEST_WINDOWS IMGUI_API void ShowUserGuide(); IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); IMGUI_API void ShowTestWindow(bool* open = NULL); -#endif + // Window // See implementation in .cpp for details IMGUI_API bool Begin(const char* name = "Debug", bool* p_opened = NULL, const ImVec2& initial_size = ImVec2(0,0), float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code. passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. From c18a409a97f0904a3e7ac73ab2bd534a0c70c960 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Mar 2015 23:34:03 +0000 Subject: [PATCH 13/15] Auto-filling child window feed their content size to parent - hopefully fix more problem than it causes? #170 --- imgui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 526ff293..72bcc4f3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2727,12 +2727,13 @@ void ImGui::EndChild() } else { - // When using auto-filling child window, we don't provide the width/height to ItemSize so that it doesn't feed back into automatic size-fitting. + // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. + ImGuiState& g = *GImGui; ImVec2 sz = ImGui::GetWindowSize(); if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) - sz.x = 0; + sz.x = ImMax(g.Style.WindowMinSize.x, sz.x - g.Style.AutoFitPadding.x); if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) - sz.y = 0; + sz.y = ImMax(g.Style.WindowMinSize.y, sz.y - g.Style.AutoFitPadding.y); ImGui::End(); From c0eab2a164b39384f8fe53484ea9e86a50a9e6de Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 21 Mar 2015 00:22:36 +0000 Subject: [PATCH 14/15] Moved draw list for io.MouseDrawCursor to state (#169) --- imgui.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 72bcc4f3..a18c0471 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1081,6 +1081,7 @@ struct ImGuiState // Render ImVector RenderDrawLists; ImVector RenderSortedWindows; + ImDrawList CursorDrawList; // Widget state ImGuiTextEditState InputTextState; @@ -1975,6 +1976,7 @@ void ImGui::Shutdown() g.Windows.clear(); g.CurrentWindowStack.clear(); g.RenderDrawLists.clear(); + g.CursorDrawList.Clear(); g.FocusedWindow = NULL; g.HoveredWindow = NULL; g.HoveredRootWindow = NULL; @@ -2140,15 +2142,14 @@ void ImGui::Render() const ImVec2 size = TEX_ATLAS_SIZE_MOUSE_CURSOR; const ImTextureID tex_id = g.IO.Fonts->TexID; const ImVec2 tex_uv_scale(1.0f/g.IO.Fonts->TexWidth, 1.0f/g.IO.Fonts->TexHeight); - static ImDrawList draw_list; - draw_list.Clear(); - draw_list.PushTextureID(tex_id); - draw_list.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow - draw_list.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow - draw_list.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0xFF000000); // Black border - draw_list.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_WHITE * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_WHITE + size) * tex_uv_scale, 0xFFFFFFFF); // White fill - draw_list.PopTextureID(); - AddDrawListToRenderList(&draw_list); + g.CursorDrawList.Clear(); + g.CursorDrawList.PushTextureID(tex_id); + g.CursorDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow + g.CursorDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0x30000000); // Shadow + g.CursorDrawList.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_BLACK * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_BLACK + size) * tex_uv_scale, 0xFF000000); // Black border + g.CursorDrawList.AddImage(tex_id, pos, pos + size, TEX_ATLAS_POS_MOUSE_CURSOR_WHITE * tex_uv_scale, (TEX_ATLAS_POS_MOUSE_CURSOR_WHITE + size) * tex_uv_scale, 0xFFFFFFFF); // White fill + g.CursorDrawList.PopTextureID(); + AddDrawListToRenderList(&g.CursorDrawList); } // Render From 92a22ab35f8ffd8c9c825792debbac7fcd9887fe Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 21 Mar 2015 00:41:34 +0000 Subject: [PATCH 15/15] Shutdown() freeing a few extra vectors so they don't have to freed by destruction #169 --- imgui.cpp | 28 +++++++++++++++++++--------- imgui.h | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a18c0471..fcd87e4c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1975,8 +1975,6 @@ void ImGui::Shutdown() } g.Windows.clear(); g.CurrentWindowStack.clear(); - g.RenderDrawLists.clear(); - g.CursorDrawList.Clear(); g.FocusedWindow = NULL; g.HoveredWindow = NULL; g.HoveredRootWindow = NULL; @@ -1989,26 +1987,29 @@ void ImGui::Shutdown() g.ColorModifiers.clear(); g.StyleModifiers.clear(); g.FontStack.clear(); + g.RenderDrawLists.clear(); + g.RenderSortedWindows.clear(); + g.CursorDrawList.ClearFreeMemory(); g.ColorEditModeStorage.Clear(); - if (g.LogFile && g.LogFile != stdout) - { - fclose(g.LogFile); - g.LogFile = NULL; - } - g.IO.Fonts->Clear(); - if (g.PrivateClipboard) { ImGui::MemFree(g.PrivateClipboard); g.PrivateClipboard = NULL; } + if (g.LogFile && g.LogFile != stdout) + { + fclose(g.LogFile); + g.LogFile = NULL; + } if (g.LogClipboard) { g.LogClipboard->~ImGuiTextBuffer(); ImGui::MemFree(g.LogClipboard); } + g.IO.Fonts->Clear(); + g.Initialized = false; } @@ -7245,6 +7246,15 @@ void ImDrawList::Clear() texture_id_stack.resize(0); } +void ImDrawList::ClearFreeMemory() +{ + commands.clear(); + vtx_buffer.clear(); + vtx_write = NULL; + clip_rect_stack.clear(); + texture_id_stack.clear(); +} + void ImDrawList::AddDrawCmd() { ImDrawCmd draw_cmd; diff --git a/imgui.h b/imgui.h index 3319624b..e07ad465 100644 --- a/imgui.h +++ b/imgui.h @@ -865,6 +865,7 @@ struct ImDrawList ImDrawList() { Clear(); } IMGUI_API void Clear(); + IMGUI_API void ClearFreeMemory(); IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. The values are x1, y1, x2, y2. IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PopClipRect();