Windows: Amend 6b0cf2e6 to facilitate working in viewport branch + handle safe area padding and ConfigWindowsMoveFromTitleBarOnly.

# Conflicts:
#	imgui.cpp
This commit is contained in:
omar 2020-06-25 22:58:23 +02:00
parent d7ef56dca2
commit f4f04cb5ec

View File

@ -975,7 +975,7 @@ static void UpdateMouseInputs();
static void UpdateMouseWheel(); static void UpdateMouseWheel();
static void UpdateTabFocus(); static void UpdateTabFocus();
static void UpdateDebugToolItemPicker(); static void UpdateDebugToolItemPicker();
static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
static void RenderWindowOuterBorders(ImGuiWindow* window); static void RenderWindowOuterBorders(ImGuiWindow* window);
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
@ -5489,7 +5489,7 @@ ImGuiID ImGui::GetWindowResizeID(ImGuiWindow* window, int n)
// Handle resize for: Resize Grips, Borders, Gamepad // Handle resize for: Resize Grips, Borders, Gamepad
// Return true when using auto-fit (double click on resize grip) // Return true when using auto-fit (double click on resize grip)
static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]) static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindowFlags flags = window->Flags; ImGuiWindowFlags flags = window->Flags;
@ -5551,8 +5551,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
// Resize from any of the four corners // Resize from any of the four corners
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
ImVec2 clamp_min = ImVec2(grip.CornerPosN.x == 1 ? g.Style.DisplayWindowPadding.x : -FLT_MAX, grip.CornerPosN.y == 1 ? g.Style.DisplayWindowPadding.y : -FLT_MAX); ImVec2 clamp_min = ImVec2(grip.CornerPosN.x == 1.0f ? visibility_rect.Min.x : -FLT_MAX, grip.CornerPosN.y == 1.0f ? visibility_rect.Min.y : -FLT_MAX);
ImVec2 clamp_max = ImVec2(grip.CornerPosN.x == 0 ? g.IO.DisplaySize.x - g.Style.DisplayWindowPadding.x : FLT_MAX, grip.CornerPosN.y == 0 ? g.IO.DisplaySize.y - g.Style.DisplayWindowPadding.y : FLT_MAX); ImVec2 clamp_max = ImVec2(grip.CornerPosN.x == 0.0f ? visibility_rect.Max.x : +FLT_MAX, grip.CornerPosN.y == 0.0f ? visibility_rect.Max.y : +FLT_MAX);
corner_target = ImClamp(corner_target, clamp_min, clamp_max); corner_target = ImClamp(corner_target, clamp_min, clamp_max);
CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target); CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
} }
@ -5579,8 +5579,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
ImVec2 clamp_min = ImVec2(border_n == 1 ? g.Style.DisplayWindowPadding.x : -FLT_MAX, border_n == 2 ? g.Style.DisplayWindowPadding.y : -FLT_MAX); ImVec2 clamp_min = ImVec2(border_n == 1 ? visibility_rect.Min.x : -FLT_MAX, border_n == 2 ? visibility_rect.Min.y : -FLT_MAX);
ImVec2 clamp_max = ImVec2(border_n == 3 ? g.IO.DisplaySize.x - g.Style.DisplayWindowPadding.x : FLT_MAX, border_n == 0 ? g.IO.DisplaySize.y - g.Style.DisplayWindowPadding.y : FLT_MAX); ImVec2 clamp_max = ImVec2(border_n == 3 ? visibility_rect.Max.x : +FLT_MAX, border_n == 0 ? visibility_rect.Max.y : +FLT_MAX);
border_target = ImClamp(border_target, clamp_min, clamp_max); border_target = ImClamp(border_target, clamp_min, clamp_max);
CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
} }
@ -5603,7 +5603,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
{ {
const float NAV_RESIZE_SPEED = 600.0f; const float NAV_RESIZE_SPEED = 600.0f;
nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
nav_resize_delta = ImClamp(nav_resize_delta, g.Style.DisplayWindowPadding - window->Pos - window->Size, ImVec2(FLT_MAX, FLT_MAX)); nav_resize_delta = ImMax(nav_resize_delta, visibility_rect.Min - window->Pos - window->Size);
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
@ -5628,13 +5628,13 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
return ret_auto_fit; return ret_auto_fit;
} }
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& viewport_rect, const ImVec2& padding) static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility_rect)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImVec2 size_for_clamping = window->Size; ImVec2 size_for_clamping = window->Size;
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
size_for_clamping.y = window->TitleBarHeight(); size_for_clamping.y = window->TitleBarHeight();
window->Pos = ImClamp(window->Pos, viewport_rect.Min + padding - size_for_clamping, viewport_rect.Max - padding); window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
} }
static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
@ -6318,16 +6318,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Viewport->Flags = viewport_flags; window->Viewport->Flags = viewport_flags;
} }
// Calculate the range of allowed position for that window (to be movable and visible past safe area padding)
// When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect.
ImRect viewport_rect(window->Viewport->GetMainRect());
ImRect viewport_work_rect(window->Viewport->GetWorkRect());
ImVec2 visibility_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
ImRect visibility_rect(viewport_work_rect.Min + visibility_padding, viewport_work_rect.Max - visibility_padding);
// Clamp position/size so window stays visible within its viewport or monitor // Clamp position/size so window stays visible within its viewport or monitor
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
// FIXME: Similar to code in GetWindowAllowedExtentRect() // FIXME: Similar to code in GetWindowAllowedExtentRect()
ImRect viewport_rect = window->Viewport->GetMainRect();
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
{ {
ImVec2 clamp_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
if (!window->ViewportOwned && viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f) if (!window->ViewportOwned && viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f)
{ {
ClampWindowRect(window, window->Viewport->GetWorkRect(), clamp_padding); ClampWindowRect(window, visibility_rect);
} }
else if (window->ViewportOwned && g.PlatformIO.Monitors.Size > 0) else if (window->ViewportOwned && g.PlatformIO.Monitors.Size > 0)
{ {
@ -6339,7 +6344,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
else else
{ {
ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->Viewport->PlatformMonitor]; ImGuiPlatformMonitor& monitor = g.PlatformIO.Monitors[window->Viewport->PlatformMonitor];
ClampWindowRect(window, ImRect(monitor.WorkPos, monitor.WorkPos + monitor.WorkSize), clamp_padding); visibility_rect.Min = monitor.WorkPos + visibility_padding;
visibility_rect.Max = monitor.WorkPos + monitor.WorkSize - visibility_padding;
ClampWindowRect(window, visibility_rect);
} }
} }
} }
@ -6375,7 +6382,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it. const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
if (handle_borders_and_resize_grips && !window->Collapsed) if (handle_borders_and_resize_grips && !window->Collapsed)
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0])) if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true; use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
window->ResizeBorderHeld = (signed char)border_held; window->ResizeBorderHeld = (signed char)border_held;