From 97bf2131e20e647417fa9a8c988b0fa082c7f0f7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 14:37:47 +0200 Subject: [PATCH 1/6] Fixed calling SetNextTreeNodeOpen() on a collapsed window leaking to next frame. --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 239566c0..ab6b2906 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6472,6 +6472,8 @@ float ImGui::GetTreeNodeToLabelSpacing() void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) { ImGuiContext& g = *GImGui; + if (g.CurrentWindow->SkipItems) + return; g.SetNextTreeNodeOpenVal = is_open; g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; } From de72e9cc87e9f2da56145c3bd3c4681443c05184 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 23:29:27 +0200 Subject: [PATCH 2/6] Internals: ImLerp() helper for ImVec4 --- imgui_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui_internal.h b/imgui_internal.h index 8f8dcc6c..39efdb2b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -147,6 +147,7 @@ static inline int ImLerp(int a, int b, float t) static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } +static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } From e9ff7162bca1fab3f110b84b5d55e9ad26a762f6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 10:43:41 +0200 Subject: [PATCH 3/6] ColorButton: Fixed rendering color button with a checkerboard if the transparency comes from the global style.Alpha and not from the actual source color. --- imgui.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ab6b2906..15b1f9d9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9433,7 +9433,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); ImRect bb_inner = bb; - float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middleground to reduce those artefacts. + float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. bb_inner.Expand(off); if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { @@ -9443,7 +9443,12 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl } else { - RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(off, off), rounding); + // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha + ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha; + if (col_source.w < 1.0f) + RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); + else + window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } if (window->Flags & ImGuiWindowFlags_ShowBorders) RenderFrameBorder(bb.Min, bb.Max, rounding); From 0260fdd1c6c7198d60fcbd02cce82e4deb8954f4 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 12:10:37 +0200 Subject: [PATCH 4/6] ColorButton: As a small convenience, provide a text baseline. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 15b1f9d9..b8bf8d58 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9419,7 +9419,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (size.y == 0.0f) size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); + ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); if (!ItemAdd(bb, id)) return false; From d2c65aa3e86b99e458cc562828041908b3b82679 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 14:48:00 +0200 Subject: [PATCH 5/6] Examples: DirectX9/10/11: Tweak usage of SetCapture/ReleaseCapture. (#1375) ps: DirectX 12 example (#302) may want to adopt that as well. --- .../directx10_example/imgui_impl_dx10.cpp | 35 +++++++++--------- .../directx11_example/imgui_impl_dx11.cpp | 35 +++++++++--------- examples/directx9_example/imgui_impl_dx9.cpp | 36 ++++++++++--------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 816e5621..06171250 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -234,35 +234,38 @@ static bool IsAnyMouseButtonDown() return false; } +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 7b3a3ba8..1f69bd72 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -241,35 +241,38 @@ static bool IsAnyMouseButtonDown() return false; } +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index fc05c9ce..02d2fd59 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -180,36 +180,38 @@ static bool IsAnyMouseButtonDown() return false; } -// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; From 5b062c4c29a76c345cfedbba57fcd60bf11e0de5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 15:26:04 +0200 Subject: [PATCH 6/6] Fixed typos --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b8bf8d58..eedd3d86 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,8 +216,9 @@ 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. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests that specific behavior if you need it. - - 2017/10/20 (1.52) - removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51, the new flags available for IsItemHovered() and IsWindowHovered() are providing much more details/options, and those legacy entry points were confusing/misleading. + - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. + - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. + removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting. - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete).