From 73ccb7e4b8c27af6c7756025f29c495b4effd359 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Feb 2021 12:57:00 +0100 Subject: [PATCH] Viewports: (Breaking) turned GetWorkPos(), GetWorkSize() into straight fields -> WorkPos, WorkSize before exposing in master branch. --- imgui.cpp | 14 +++++++++++--- imgui.h | 11 +++++------ imgui_demo.cpp | 10 +++++----- imgui_internal.h | 7 +++++-- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2b48b27b..8d1ff87d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3583,7 +3583,10 @@ void ImGui::UpdateMouseMovingWindowNewFrame() MarkIniSettingsDirty(moving_window); SetWindowPos(moving_window, pos, ImGuiCond_Always); if (moving_window->ViewportOwned) // Synchronize viewport immediately because some overlays may relies on clipping rectangle before we Begin() into the window. + { moving_window->Viewport->Pos = pos; + moving_window->Viewport->UpdateWorkRect(); + } } FocusWindow(g.MovingWindow); } @@ -6340,6 +6343,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) viewport_rect_changed = true; window->Viewport->Size = window->Size; } + window->Viewport->UpdateWorkRect(); // The viewport may have changed monitor since the global update in UpdateViewportsNewFrame() // Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect. @@ -6467,6 +6471,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Viewport->Pos = window->Pos; if (!window->Viewport->PlatformRequestResize) window->Viewport->Size = window->Size; + window->Viewport->UpdateWorkRect(); viewport_rect = window->Viewport->GetMainRect(); } @@ -11398,6 +11403,7 @@ static void ImGui::UpdateViewportsNewFrame() // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. if (!(viewport->Flags & ImGuiViewportFlags_Minimized) && platform_funcs_available) { + // Viewport->WorkPos and WorkSize will be updated below if (viewport->PlatformRequestMove) viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); if (viewport->PlatformRequestResize) @@ -11412,6 +11418,7 @@ static void ImGui::UpdateViewportsNewFrame() viewport->WorkOffsetMin = viewport->CurrWorkOffsetMin; viewport->WorkOffsetMax = viewport->CurrWorkOffsetMax; viewport->CurrWorkOffsetMin = viewport->CurrWorkOffsetMax = ImVec2(0.0f, 0.0f); + viewport->UpdateWorkRect(); // Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back. viewport->Alpha = 1.0f; @@ -11573,6 +11580,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const viewport->Window = window; viewport->LastFrameActive = g.FrameCount; + viewport->UpdateWorkRect(); IM_ASSERT(window == NULL || viewport->ID == window->ID); if (window != NULL) @@ -14658,8 +14666,8 @@ ImGuiID ImGui::DockSpaceOverViewport(const ImGuiViewport* viewport, ImGuiDockNod if (viewport == NULL) viewport = GetMainViewport(); - SetNextWindowPos(viewport->GetWorkPos()); - SetNextWindowSize(viewport->GetWorkSize()); + SetNextWindowPos(viewport->WorkPos); + SetNextWindowSize(viewport->WorkSize); SetNextWindowViewport(viewport->ID); ImGuiWindowFlags host_window_flags = 0; @@ -16524,7 +16532,7 @@ void ImGui::DebugNodeViewport(ImGuiViewportP* viewport) viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y, viewport->WorkOffsetMin.x, viewport->WorkOffsetMin.y, viewport->WorkOffsetMax.x, viewport->WorkOffsetMax.y, viewport->PlatformMonitor, viewport->DpiScale * 100.0f); - if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200,200); if (viewport->Window) viewport->Window->Pos = ImVec2(200,200); } } + if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200, 200); viewport->UpdateWorkRect(); if (viewport->Window) viewport->Window->Pos = viewport->Pos; } } BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s", viewport->Flags, (flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "", (flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "", diff --git a/imgui.h b/imgui.h index 898bc300..522e3876 100644 --- a/imgui.h +++ b/imgui.h @@ -2850,10 +2850,10 @@ struct ImGuiViewport { ImGuiID ID; // Unique identifier for the viewport ImGuiViewportFlags Flags; // See ImGuiViewportFlags_ - ImVec2 Pos; // Main Area: Position of the viewport (the imgui coordinates are the same as OS desktop/native coordinates) + ImVec2 Pos; // Main Area: Position of the viewport (Dear Imgui coordinates are the same as OS desktop/native coordinates) ImVec2 Size; // Main Area: Size of the viewport. - ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!) - ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height). + ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos) + ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size) float DpiScale; // 1.0f = 96 DPI = No extra scale. ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows. ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame(). @@ -2873,10 +2873,9 @@ struct ImGuiViewport ImGuiViewport() { memset(this, 0, sizeof(*this)); } ~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); } - // Access work-area rectangle with GetWorkXXX functions (see comments above) + // Helpers ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } - ImVec2 GetWorkPos() const { return ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); } - ImVec2 GetWorkSize() const { return ImVec2(Size.x - WorkOffsetMin.x + WorkOffsetMax.x, Size.y - WorkOffsetMin.y + WorkOffsetMax.y); } // This not clamped + ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); } }; //----------------------------------------------------------------------------- diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6beaafc4..47a6f9d7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -334,7 +334,7 @@ void ImGui::ShowDemoWindow(bool* p_open) // We specify a default position/size in case there's no data in the .ini file. // We only do it to make the demo applications a little more welcoming, but typically this isn't required. const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(ImVec2(main_viewport->GetWorkPos().x + 650, main_viewport->GetWorkPos().y + 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); // Main body of the Demo window starts here. @@ -7032,8 +7032,8 @@ static void ShowExampleAppSimpleOverlay(bool* p_open) { window_flags |= ImGuiWindowFlags_NoMove; const ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImVec2 work_area_pos = viewport->GetWorkPos(); // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any! - ImVec2 work_area_size = viewport->GetWorkSize(); + ImVec2 work_area_pos = viewport->WorkPos; // Use work area to avoid menu-bar/task-bar, if any! + ImVec2 work_area_size = viewport->WorkSize; ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE)); ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); @@ -7369,8 +7369,8 @@ void ShowExampleAppDockSpace(bool* p_open) if (opt_fullscreen) { const ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(viewport->GetWorkPos()); - ImGui::SetNextWindowSize(viewport->GetWorkSize()); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); ImGui::SetNextWindowViewport(viewport->ID); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); diff --git a/imgui_internal.h b/imgui_internal.h index 1a6bc289..f5b4da83 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1316,13 +1316,16 @@ struct ImGuiViewportP : public ImGuiViewport ImVec2 LastPlatformPos; ImVec2 LastPlatformSize; ImVec2 LastRendererSize; - ImVec2 CurrWorkOffsetMin; // Work area top-left offset being increased during the frame - ImVec2 CurrWorkOffsetMax; // Work area bottom-right offset being decreased during the frame + ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!) + ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height). + ImVec2 CurrWorkOffsetMin; // Work Area: Offset being built/increased during current frame + ImVec2 CurrWorkOffsetMax; // Work Area: Offset being built/decreased during current frame ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameDrawLists[0] = LastFrameDrawLists[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); } ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImRect GetWorkRect() const { return ImRect(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y, Pos.x + Size.x + WorkOffsetMax.x, Pos.y + Size.y + WorkOffsetMax.y); } + void UpdateWorkRect() { WorkPos = Pos + WorkOffsetMin; WorkSize = ImVec2(ImMax(0.0f, Size.x - WorkOffsetMin.x + WorkOffsetMax.x), ImMax(0.0f, Size.y - WorkOffsetMin.y + WorkOffsetMax.y)); } void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } };