From ea6b6151791c77c70c364f871c9e076b76739e09 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 26 Apr 2016 11:03:51 +0200 Subject: [PATCH] Made ImGui::PushClipRect()/PopClipRect() public. Changed ImDrawList::PushClipRect() prototype. Fixed demo. (#610) --- imgui.cpp | 20 ++++---------------- imgui.h | 6 +++++- imgui_demo.cpp | 2 +- imgui_draw.cpp | 29 +++++++++++++++++++++-------- imgui_internal.h | 3 --- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 851135a98..ad3c6c114 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,6 +152,7 @@ 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. + - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer. - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337). - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337) - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). @@ -557,7 +558,6 @@ - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) - style editor: color child window height expressed in multiple of line height. - remote: make a system like RemoteImGui first-class citizen/project (#75) -!- demo: custom render demo pushes a clipping rectangle past parent window bounds. expose ImGui::PushClipRect() from imgui_internal.h? - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) @@ -2367,23 +2367,11 @@ static void AddWindowToRenderList(ImVector& out_render_list, ImGuiW } } -void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect) +void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { ImGuiWindow* window = GetCurrentWindow(); - - ImRect cr(clip_rect_min, clip_rect_max); - if (intersect_with_existing_clip_rect) // Clip our argument with the current clip rect - cr.Clip(window->ClipRect); - cr.Max.x = ImMax(cr.Min.x, cr.Max.x); - cr.Max.y = ImMax(cr.Min.y, cr.Max.y); - cr.Min.x = (float)(int)(cr.Min.x + 0.5f); // Round (expecting to round down). Ensure that e.g. (int)(max.x-min.x) in user code produce correct result. - cr.Min.y = (float)(int)(cr.Min.y + 0.5f); - cr.Max.x = (float)(int)(cr.Max.x + 0.5f); - cr.Max.y = (float)(int)(cr.Max.y + 0.5f); - - IM_ASSERT(cr.Min.x <= cr.Max.x && cr.Min.y <= cr.Max.y); - window->ClipRect = cr; - window->DrawList->PushClipRect(ImVec4(cr.Min.x, cr.Min.y, cr.Max.x, cr.Max.y)); + window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); + window->ClipRect = window->DrawList->_ClipRectStack.back(); } void ImGui::PopClipRect() diff --git a/imgui.h b/imgui.h index 05932e84b..d6a097ee9 100644 --- a/imgui.h +++ b/imgui.h @@ -368,6 +368,10 @@ namespace ImGui IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed) + // Clipping + IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); + IMGUI_API void PopClipRect(); + // Utilities IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this @@ -1128,7 +1132,7 @@ struct ImDrawList ImDrawList() { _OwnerName = NULL; Clear(); } ~ImDrawList() { ClearFreeMemory(); } - IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. Note that the values are (x1,y1,x2,y2) and NOT (x1,y1,w,h). This is passed down to your render function but not used for CPU-side clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) + IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PopClipRect(); IMGUI_API void PushTextureID(const ImTextureID& texture_id); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3a9162520..cf6cf21bc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1863,7 +1863,7 @@ static void ShowExampleAppCustomRendering(bool* opened) points.pop_back(); } } - draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) + draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) for (int i = 0; i < points.Size - 1; i += 2) draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f); draw_list->PopClipRect(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b82b5cc9e..e2eea92c8 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -214,20 +214,33 @@ void ImDrawList::UpdateTextureID() #undef GetCurrentClipRect #undef GetCurrentTextureId -// Scissoring. The values in clip_rect are x1, y1, x2, y2. Only apply to rendering! Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) -void ImDrawList::PushClipRect(const ImVec4& clip_rect) +// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) +void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) { - _ClipRectStack.push_back(clip_rect); + ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); + if (intersect_with_current_clip_rect && _ClipRectStack.Size) + { + ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1]; + if (cr.x < current.x) cr.x = current.x; + if (cr.y < current.y) cr.y = current.y; + if (cr.z > current.z) cr.z = current.z; + if (cr.w > current.w) cr.w = current.w; + } + cr.z = ImMax(cr.x, cr.z); + cr.w = ImMax(cr.y, cr.w); + cr.x = (float)(int)(cr.x + 0.5f); // Round (expecting to round down). Ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + cr.y = (float)(int)(cr.y + 0.5f); + cr.z = (float)(int)(cr.z + 0.5f); + cr.w = (float)(int)(cr.w + 0.5f); + + _ClipRectStack.push_back(cr); UpdateClipRect(); } void ImDrawList::PushClipRectFullScreen() { - PushClipRect(GNullClipRect); - - // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here? - //ImGuiState& g = *GImGui; - //PushClipRect(GetVisibleRect()); + PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w)); + //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here? } void ImDrawList::PopClipRect() diff --git a/imgui_internal.h b/imgui_internal.h index 8d18d1b5c..90ceba1a0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -711,9 +711,6 @@ namespace ImGui IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. - IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true); - IMGUI_API void PopClipRect(); - IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);