From 1a3af8cb4cc1d58f3b7a755e491943efe9b8feab Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 Feb 2021 12:02:55 +0100 Subject: [PATCH] Viewports: trying to treat GetMainViewport() as const. Reducing unnecessary casts of ImGuiViewportP* Metrics: readded root Drawlists node in metrics to match master. The (void*) casts are implying const-casst but currently left GetMainViewport() as returning non-const. --- imgui.cpp | 48 +++++++++++++++++++++++++++++++++++------------ imgui.h | 8 ++++---- imgui_demo.cpp | 6 +++--- imgui_internal.h | 5 +++-- imgui_widgets.cpp | 2 +- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6f3e9494..2b48b27b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5295,7 +5295,7 @@ ImGuiWindow* ImGui::FindWindowByName(const char* name) static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) { - ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); window->ViewportPos = main_viewport->Pos; if (settings->ViewportId) { @@ -5321,7 +5321,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) g.WindowsById.SetVoidPtr(window->ID, window); // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. - ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); window->Pos = main_viewport->Pos + ImVec2(60, 60); window->ViewportPos = main_viewport->Pos; @@ -6412,7 +6412,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->Viewport->PlatformMonitor == -1) { // Fallback for "lost" window (e.g. a monitor disconnected): we move the window back over the main viewport - ImGuiViewport* main_viewport = GetMainViewport(); + const ImGuiViewport* main_viewport = GetMainViewport(); SetWindowPos(window, main_viewport->Pos + style.DisplayWindowPadding, ImGuiCond_Always); } else @@ -8878,8 +8878,8 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0) { - ImGuiViewportP* viewport = window->WasActive ? window->Viewport : (ImGuiViewportP*)GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport? - SetNextWindowPos(viewport->GetMainRect().GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f)); + const ImGuiViewport* viewport = window->WasActive ? window->Viewport : GetMainViewport(); // FIXME-VIEWPORT: What may be our reference viewport? + SetNextWindowPos(viewport->GetCenter(), ImGuiCond_FirstUseEver, ImVec2(0.5f, 0.5f)); } flags |= ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking; @@ -10259,7 +10259,7 @@ void ImGui::NavUpdateWindowingOverlay() if (g.NavWindowingListWindow == NULL) g.NavWindowingListWindow = FindWindowByName("###NavWindowingList"); - ImGuiViewportP* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ (ImGuiViewportP*)GetMainViewport(); + const ImGuiViewport* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ GetMainViewport(); SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX)); SetNextWindowPos(viewport->Pos + viewport->Size * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f); @@ -11589,7 +11589,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) window->ViewportAllowPlatformMonitorExtend = -1; // Restore main viewport if multi-viewport is not supported by the backend - ImGuiViewportP* main_viewport = (ImGuiViewportP*)GetMainViewport(); + ImGuiViewportP* main_viewport = (ImGuiViewportP*)(void*)GetMainViewport(); if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)) { SetWindowViewport(window, main_viewport); @@ -14409,7 +14409,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node) /* // [DEBUG] Render limits - ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport()); + ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); for (int n = 0; n < 2; n++) if (axis == ImGuiAxis_X) draw_list->AddLine(ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y), ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y + node->ChildNodes[n]->Size.y), IM_COL32(255, 0, 255, 255), 3.0f); @@ -14437,7 +14437,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node) for (int touching_node_n = 0; touching_node_n < touching_nodes[side_n].Size; touching_node_n++) { ImGuiDockNode* touching_node = touching_nodes[side_n][touching_node_n]; - //ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport()); + //ImDrawList* draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); //draw_list->AddRect(touching_node->Pos, touching_node->Pos + touching_node->Size, IM_COL32(255, 128, 0, 255)); while (touching_node->ParentNode != node) { @@ -14653,7 +14653,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags fla // The limitation with this call is that your window won't have a menu bar. // Even though we could pass window flags, it would also require the user to be able to call BeginMenuBar() somehow meaning we can't Begin/End in a single function. // But you can also use BeginMainMenuBar(). If you really want a menu bar inside the same window as the one hosting the dockspace, you will need to copy this code somewhere and tweak it. -ImGuiID ImGui::DockSpaceOverViewport(ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class) +ImGuiID ImGui::DockSpaceOverViewport(const ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags, const ImGuiWindowClass* window_class) { if (viewport == NULL) viewport = GetMainViewport(); @@ -15980,9 +15980,33 @@ void ImGui::ShowMetricsWindow(bool* p_open) TreePop(); } - // Contents + // Windows DebugNodeWindowsList(&g.Windows, "Windows"); //DebugNodeWindowsList(&g.WindowsFocusOrder, "WindowsFocusOrder"); + + // Drawlists + int drawlist_count = 0; + for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++) + drawlist_count += g.Viewports[viewport_i]->DrawDataBuilder.GetDrawListCount(); + if (TreeNode("DrawLists", "DrawLists (%d)", drawlist_count)) + { + for (int viewport_i = 0; viewport_i < g.Viewports.Size; viewport_i++) + { + ImGuiViewportP* viewport = g.Viewports[viewport_i]; + bool viewport_has_drawlist = false; + for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++) + for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++) + { + if (!viewport_has_drawlist) + ImGui::Text("Active DrawLists in Viewport #%d, ID: 0x%08X", viewport->Idx, viewport->ID); + viewport_has_drawlist = true; + DebugNodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList"); + } + } + TreePop(); + } + + // Viewports if (TreeNode("Viewports", "Viewports (%d)", g.Viewports.Size)) { Indent(GetTreeNodeToLabelSpacing()); @@ -16228,7 +16252,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) char buf[64] = ""; char* p = buf; ImGuiDockNode* node = g.HoveredDockNode; - ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport()); + ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList(GetMainViewport()); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : ""); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y); diff --git a/imgui.h b/imgui.h index dec2fb21..898bc300 100644 --- a/imgui.h +++ b/imgui.h @@ -756,7 +756,7 @@ namespace ImGui // - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details. // - DockSpace() needs to be submitted _before_ any window they can host. If you use a dockspace, submit it early in your app. IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL); - IMGUI_API ImGuiID DockSpaceOverViewport(ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL); + IMGUI_API ImGuiID DockSpaceOverViewport(const ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL); IMGUI_API void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id (FIXME-DOCK) IMGUI_API void SetNextWindowClass(const ImGuiWindowClass* window_class); // set next window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info) IMGUI_API ImGuiID GetWindowDockID(); @@ -2874,9 +2874,9 @@ struct ImGuiViewport ~ImGuiViewport() { IM_ASSERT(PlatformUserData == NULL && RendererUserData == NULL); } // Access work-area rectangle with GetWorkXXX functions (see comments above) - ImVec2 GetCenter() { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } - ImVec2 GetWorkPos() { return ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); } - ImVec2 GetWorkSize() { return ImVec2(Size.x - WorkOffsetMin.x + WorkOffsetMax.x, Size.y - WorkOffsetMin.y + WorkOffsetMax.y); } // This not clamped + 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 }; //----------------------------------------------------------------------------- diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 09ddb476..6beaafc4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -333,7 +333,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. - ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGui::SetNextWindowPos(ImVec2(main_viewport->GetWorkPos().x + 650, main_viewport->GetWorkPos().y + 20), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); @@ -7031,7 +7031,7 @@ static void ShowExampleAppSimpleOverlay(bool* p_open) if (corner != -1) { window_flags |= ImGuiWindowFlags_NoMove; - ImGuiViewport* viewport = ImGui::GetMainViewport(); + 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 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)); @@ -7368,7 +7368,7 @@ void ShowExampleAppDockSpace(bool* p_open) ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; if (opt_fullscreen) { - ImGuiViewport* viewport = ImGui::GetMainViewport(); + const ImGuiViewport* viewport = ImGui::GetMainViewport(); ImGui::SetNextWindowPos(viewport->GetWorkPos()); ImGui::SetNextWindowSize(viewport->GetWorkSize()); ImGui::SetNextWindowViewport(viewport->ID); diff --git a/imgui_internal.h b/imgui_internal.h index 3ff8c521..1a6bc289 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -664,8 +664,9 @@ struct ImDrawDataBuilder { ImVector Layers[2]; // Global layers for: regular, tooltip - void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } - void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } + void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } + void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } + int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; } IMGUI_API void FlattenIntoSingleLayer(); }; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d0539412..17761630 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6575,7 +6575,7 @@ void ImGui::EndMenuBar() bool ImGui::BeginMainMenuBar() { ImGuiContext& g = *GImGui; - ImGuiViewportP* viewport = (ImGuiViewportP*)GetMainViewport(); + ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport(); ImGuiWindow* menu_bar_window = FindWindowByName("##MainMenuBar"); // For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.