From 6eacddb50f267546d8b0f5bc9a51d239fe369603 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 10 May 2018 12:10:10 +0200 Subject: [PATCH] Viewport: Changed Monitor field to use Pos+Size (more consistent), changed FullMin,FullMax to MainPos,MainSize. Made main viewport accessible in PlatformIO on first frame. Fixed casing of ImGuiViewportFlags_TopMost flag. (#1542) --- examples/imgui_impl_glfw.cpp | 6 +++--- examples/imgui_impl_sdl2.cpp | 10 +++++----- examples/imgui_impl_win32.cpp | 10 +++++----- imgui.cpp | 28 +++++++++++++++------------- imgui.h | 9 +++++---- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index af984041..a8e9c8c8 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -364,7 +364,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) glfwWindowHint(GLFW_FOCUSED, false); glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true); #if GLFW_HAS_WINDOW_TOPMOST - glfwWindowHint(GLFW_FLOATING, (viewport->Flags & imGuiViewportFlags_TopMost) ? true : false); + glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false); #endif GLFWwindow* share_window = (g_ClientApi == GlfwClientApi_OpenGL) ? g_Window : NULL; data->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window); @@ -579,8 +579,8 @@ static void ImGui_ImplGlfw_UpdateMonitors() int x, y; glfwGetMonitorPos(glfw_monitors[n], &x, &y); const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]); - monitor.FullMin = monitor.WorkMin = ImVec2((float)x, (float)y); - monitor.FullMax = monitor.WorkMax = ImVec2((float)(x + vid_mode->width), (float)(y + vid_mode->height)); + monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height); #if GLFW_HAS_PER_MONITOR_DPI // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. float x_scale, y_scale; diff --git a/examples/imgui_impl_sdl2.cpp b/examples/imgui_impl_sdl2.cpp index e33c2a18..8234fcf8 100644 --- a/examples/imgui_impl_sdl2.cpp +++ b/examples/imgui_impl_sdl2.cpp @@ -317,7 +317,7 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport) sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; #if SDL_HAS_ALWAYS_ON_TOP - sdl_flags |= (viewport->Flags & imGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; + sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0; #endif data->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags); data->WindowOwned = true; @@ -463,12 +463,12 @@ static void ImGui_ImplSDL2_UpdateMonitors() ImGuiPlatformMonitor monitor; SDL_Rect r; SDL_GetDisplayBounds(n, &r); - monitor.FullMin = monitor.WorkMin = ImVec2((float)(r.x), (float)(r.y)); - monitor.FullMax = monitor.WorkMax = ImVec2((float)(r.x + r.w), (float)(r.y + r.h)); + monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h); #if SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_GetDisplayUsableBounds(n, &r); - monitor.WorkMin = ImVec2((float)(r.x), (float)(r.y)); - monitor.WorkMax = ImVec2((float)(r.x + r.w), (float)(r.y + r.h)); + monitor.WorkPos = ImVec2((float)r.x, (float)r.y); + monitor.WorkSize = ImVec2((float)r.w, (float)r.h); #endif #if SDL_HAS_PER_MONITOR_DPI float dpi = 0.0f; diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index 76c5b76b..097c5dbc 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -431,7 +431,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport) data->DwStyle = WS_OVERLAPPEDWINDOW; data->DwExStyle = no_task_bar_icon ? WS_EX_TOOLWINDOW : WS_EX_APPWINDOW; } - if (viewport->Flags & imGuiViewportFlags_TopMost) + if (viewport->Flags & ImGuiViewportFlags_TopMost) data->DwExStyle |= WS_EX_TOPMOST; // Create window @@ -618,10 +618,10 @@ static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, H if (!::GetMonitorInfo(monitor, &info)) return TRUE; ImGuiPlatformMonitor imgui_monitor; - imgui_monitor.FullMin = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top); - imgui_monitor.FullMax = ImVec2((float)info.rcMonitor.right, (float)info.rcMonitor.bottom); - imgui_monitor.WorkMin = ImVec2((float)info.rcWork.left, (float)info.rcWork.top); - imgui_monitor.WorkMax = ImVec2((float)info.rcWork.right, (float)info.rcWork.bottom); + imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top); + imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top)); + imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top); + imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top)); imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); ImGuiPlatformIO& io = ImGui::GetPlatformIO(); if (info.dwFlags & MONITORINFOF_PRIMARY) diff --git a/imgui.cpp b/imgui.cpp index 832108c1..b1827746 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3620,7 +3620,7 @@ void ImGui::UpdatePlatformWindows() { bool topmost = (viewport->Window->Flags & ImGuiWindowFlags_Tooltip) != 0; bool no_task_bar_icon = (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsNoTaskBarIcons) != 0 || (viewport->Window->Flags & (ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) != 0; - viewport->Flags = topmost ? (viewport->Flags | imGuiViewportFlags_TopMost) : (viewport->Flags & ~imGuiViewportFlags_TopMost); + viewport->Flags = topmost ? (viewport->Flags | ImGuiViewportFlags_TopMost) : (viewport->Flags & ~ImGuiViewportFlags_TopMost); viewport->Flags = no_task_bar_icon ? (viewport->Flags | ImGuiViewportFlags_NoTaskBarIcon) : (viewport->Flags & ~ImGuiViewportFlags_NoTaskBarIcon); } @@ -3881,8 +3881,8 @@ void ImGui::NewFrame() for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++) { ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[monitor_n]; - IM_ASSERT(mon.FullMin.x < mon.FullMax.x && mon.FullMin.y < mon.FullMax.y && "Monitor bounds not setup properly."); - IM_ASSERT(mon.WorkMin.x < mon.WorkMax.x && mon.WorkMin.y < mon.WorkMax.y && "Monitor bounds not setup properly. If you don't have work area information, just copy Min/Max into them."); + IM_ASSERT(mon.MainSize.x > 0.0f && mon.MainSize.y > 0.0f && "Monitor bounds not setup properly."); + IM_ASSERT(mon.WorkSize.x > 0.0f && mon.WorkSize.y > 0.0f && "Monitor bounds not setup properly. If you don't have work area information, just copy Min/Max into them."); IM_ASSERT(mon.DpiScale != 0.0f); } } @@ -4152,6 +4152,8 @@ void ImGui::Initialize(ImGuiContext* context) viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID; viewport->Idx = 0; g.Viewports.push_back(viewport); + g.PlatformIO.MainViewport = g.Viewports[0]; // Make it accessible in public-facing GetPlatformIO() immediately (before the first call to EndFrame) + g.PlatformIO.Viewports.push_back(g.Viewports[0]); g.Initialized = true; } @@ -5936,8 +5938,8 @@ static ImRect FindAllowedExtentRectForWindow(ImGuiWindow* window) { // Extent with be in the frame of reference of the given viewport (so Min is likely to be negative here) const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->ViewportAllowPlatformMonitorExtend]; - r_screen.Min = monitor.WorkMin; - r_screen.Max = monitor.WorkMax; + r_screen.Min = monitor.WorkPos; + r_screen.Max = monitor.WorkPos + monitor.WorkSize; } else { @@ -6119,7 +6121,7 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) avail_size = ImVec2(FLT_MAX, FLT_MAX); const int monitor_idx = window->ViewportAllowPlatformMonitorExtend; if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size) - avail_size = (g.PlatformIO.Monitors[monitor_idx].WorkMax - g.PlatformIO.Monitors[monitor_idx].WorkMin); + avail_size = g.PlatformIO.Monitors[monitor_idx].WorkSize; ImVec2 size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, avail_size - g.Style.DisplaySafeAreaPadding * 2.0f)); // When the window cannot fit all contents (either because of constraints, either because screen is too small), @@ -6190,7 +6192,7 @@ static int ImGui::FindPlatformMonitorForPos(const ImVec2& pos) for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size; monitor_n++) { const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[monitor_n]; - if (ImRect(monitor.FullMin, monitor.FullMax).Contains(pos)) + if (ImRect(monitor.MainPos, monitor.MainPos + monitor.MainSize).Contains(pos)) return monitor_n; } return -1; @@ -6207,10 +6209,10 @@ static int ImGui::FindPlatformMonitorForRect(const ImRect& rect) for (int monitor_n = 0; monitor_n < g.PlatformIO.Monitors.Size && best_monitor_surface < surface_threshold; monitor_n++) { const ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[monitor_n]; - if (ImRect(monitor.FullMin, monitor.FullMax).Contains(rect)) + if (ImRect(monitor.MainPos, monitor.MainPos + monitor.MainSize).Contains(rect)) return monitor_n; ImRect overlapping_rect = rect; - overlapping_rect.ClipWithFull(ImRect(monitor.FullMin, monitor.FullMax)); + overlapping_rect.ClipWithFull(ImRect(monitor.MainPos, monitor.MainPos + monitor.MainSize)); float overlapping_surface = overlapping_rect.GetWidth() * overlapping_rect.GetHeight(); if (overlapping_surface < best_monitor_surface) continue; @@ -6796,7 +6798,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else { ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->Viewport->PlatformMonitor]; - ClampWindowRect(window, ImRect(monitor.WorkMin, monitor.WorkMax), clamp_padding); + ClampWindowRect(window, ImRect(monitor.WorkPos, monitor.WorkPos + monitor.WorkSize), clamp_padding); } } } @@ -14401,10 +14403,10 @@ void ImGui::ShowMetricsWindow(bool* p_open) for (int i = 0; i < g.PlatformIO.Monitors.Size; i++) { const ImGuiPlatformMonitor& mon = g.PlatformIO.Monitors[i]; - ImGui::BulletText("Monitor #%d: DPI %.0f%%\n FullMin (%.0f,%.0f), FullMax (%.0f,%.0f), FullSize (%.0f,%.0f)\n WorkMin (%.0f,%.0f), WorkMax (%.0f,%.0f), WorkSize (%.0f,%.0f)", + ImGui::BulletText("Monitor #%d: DPI %.0f%%\n MainMin (%.0f,%.0f), MainMax (%.0f,%.0f), MainSize (%.0f,%.0f)\n WorkMin (%.0f,%.0f), WorkMax (%.0f,%.0f), WorkSize (%.0f,%.0f)", i, mon.DpiScale * 100.0f, - mon.FullMin.x, mon.FullMin.y, mon.FullMax.x, mon.FullMax.y, mon.FullMax.x - mon.FullMin.x, mon.FullMax.y - mon.FullMin.y, - mon.WorkMin.x, mon.WorkMin.y, mon.WorkMax.x, mon.WorkMax.y, mon.WorkMax.x - mon.WorkMin.x, mon.WorkMax.y - mon.WorkMin.y); + mon.MainPos.x, mon.MainPos.y, mon.MainPos.x + mon.MainSize.x, mon.MainPos.y + mon.MainSize.y, mon.MainSize.x, mon.MainSize.y, + mon.WorkPos.x, mon.WorkPos.y, mon.WorkPos.x + mon.WorkSize.x, mon.WorkPos.y + mon.WorkSize.y, mon.WorkSize.x, mon.WorkSize.y); } ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index 38b776a3..d2b5faa3 100644 --- a/imgui.h +++ b/imgui.h @@ -74,6 +74,7 @@ struct ImGuiListClipper; // Helper to manually clip large list of ite struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiViewport; // Viewport (generally ~1 per window to output to at the OS level. Need per-platform support to use multiple viewports) struct ImGuiPlatformIO; // Multi-viewport support: interface for Platform/Renderer back-ends + viewports to render +struct ImGuiPlatformMonitor; // Multi-viewport support: user-provided bounds for each connected monitor/display. Used when positioning popups and tooltips to avoid them straddling monitors struct ImGuiContext; // ImGui context (opaque) #ifndef ImTextureID @@ -1890,10 +1891,10 @@ struct ImFont // Dear ImGui only uses this to clamp the position of popups and tooltips so they don't straddle multiple monitors struct ImGuiPlatformMonitor { - ImVec2 FullMin, FullMax; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) - ImVec2 WorkMin, WorkMax; // (Optional) Coordinates without task bars / side bars / menu bars. imgui uses this to avoid positioning popups/tooltips inside this region. + ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) + ImVec2 WorkPos, WorkSize; // (Optional) Coordinates without task bars / side bars / menu bars. imgui uses this to avoid positioning popups/tooltips inside this region. float DpiScale; - ImGuiPlatformMonitor() { FullMin = FullMax = WorkMin = WorkMax = ImVec2(0,0); DpiScale = 1.0f; } + ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0,0); DpiScale = 1.0f; } }; // (Optional) Setup required only if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) is enabled @@ -1956,7 +1957,7 @@ enum ImGuiViewportFlags_ ImGuiViewportFlags_NoInputs = 1 << 2, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it. ImGuiViewportFlags_NoTaskBarIcon = 1 << 3, // Platform Window: Disable platform task bar icon (for popups, menus, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcons if set) ImGuiViewportFlags_NoRendererClear = 1 << 4, // Platform Window: Renderer doesn't need to clear the framebuffer ahead. - imGuiViewportFlags_TopMost = 1 << 5 // Platform Window: Display on top (for tooltips only) + ImGuiViewportFlags_TopMost = 1 << 5 // Platform Window: Display on top (for tooltips only) }; // The viewports created and managed by imgui. The role of the platform back-end is to create the platform/OS windows corresponding to each viewport.