mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-22 23:56:36 +00:00
Windows: Double-clicking bottom or right window border auto-resize on a singles axis.
This commit is contained in:
parent
ade2acfd1d
commit
c95fbb4464
@ -73,7 +73,8 @@ Other changes:
|
||||
- Windows:
|
||||
- Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
|
||||
to false when popup is closed in ways other than clicking the close button. (#6900)
|
||||
- Can also auto-resize by double-clicking lower-left resize grip (not only lower-right one).
|
||||
- Double-clicking lower-left resize grip auto-resize (like lower-rightone).
|
||||
- Double-clicking bottom or right window border auto-resize on a singles axis.
|
||||
- Separators:
|
||||
- Altered end-points to use more standard boundaries. (#205, #4787, #1643)
|
||||
Left position is always current cursor X position.
|
||||
|
88
imgui.cpp
88
imgui.cpp
@ -1098,9 +1098,9 @@ static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt);
|
||||
|
||||
// Misc
|
||||
static void UpdateSettings();
|
||||
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 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 int UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
||||
static void RenderWindowOuterBorders(ImGuiWindow* window, int border_hovered, int border_held);
|
||||
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, int border_hovered, int border_held);
|
||||
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||||
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
||||
static void RenderDimmedBackgrounds();
|
||||
@ -5838,7 +5838,7 @@ ImGuiID ImGui::GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir)
|
||||
|
||||
// Handle resize for: Resize Grips, Borders, Gamepad
|
||||
// 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], const ImRect& visibility_rect)
|
||||
static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindowFlags flags = window->Flags;
|
||||
@ -5848,8 +5848,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window.
|
||||
return false;
|
||||
|
||||
bool ret_auto_fit = false;
|
||||
const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0;
|
||||
int ret_auto_fit_mask = 0x00;
|
||||
const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
|
||||
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
||||
@ -5884,11 +5883,11 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
if (hovered || held)
|
||||
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
|
||||
|
||||
if (held && g.IO.MouseClickedCount[0] == 2)
|
||||
if (held && g.IO.MouseDoubleClicked[0])
|
||||
{
|
||||
// Manual auto-fit when double-clicking
|
||||
// Auto-fit when double-clicking
|
||||
size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
|
||||
ret_auto_fit = true;
|
||||
ret_auto_fit_mask = 0x03; // Both axises
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (held)
|
||||
@ -5906,8 +5905,12 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
if (resize_grip_n == 0 || held || hovered)
|
||||
resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
|
||||
}
|
||||
for (int border_n = 0; border_n < resize_border_count; border_n++)
|
||||
|
||||
const int resize_border_mask = g.IO.ConfigWindowsResizeFromEdges ? 0x0F : 0x00;
|
||||
for (int border_n = 0; border_n < 4; border_n++)
|
||||
{
|
||||
if ((resize_border_mask & (1 << border_n)) == 0)
|
||||
continue;
|
||||
const ImGuiResizeBorderDef& def = resize_border_def[border_n];
|
||||
const ImGuiAxis axis = (border_n == ImGuiDir_Left || border_n == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y;
|
||||
|
||||
@ -5920,10 +5923,23 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
|
||||
{
|
||||
g.MouseCursor = (axis == ImGuiAxis_X) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
|
||||
if (hovered)
|
||||
*border_hovered = border_n;
|
||||
if (held)
|
||||
*border_held = border_n;
|
||||
}
|
||||
if (held)
|
||||
if (held && g.IO.MouseDoubleClicked[0])
|
||||
{
|
||||
// Double-clicking bottom or right border auto-fit on this axis
|
||||
// FIXME: Support top and right borders: rework CalcResizePosSizeFromAnyCorner() to be reusable in both cases.
|
||||
if (border_n == 1 || border_n == 3) // Right and bottom border
|
||||
{
|
||||
size_target[axis] = CalcWindowSizeAfterConstraint(window, size_auto_fit)[axis];
|
||||
ret_auto_fit_mask |= (1 << axis);
|
||||
}
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (held)
|
||||
{
|
||||
ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX);
|
||||
ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX);
|
||||
@ -5969,18 +5985,17 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
|
||||
// Apply back modified position/size to window
|
||||
if (size_target.x != FLT_MAX)
|
||||
{
|
||||
window->SizeFull = size_target;
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
window->Size.x = window->SizeFull.x = size_target.x;
|
||||
if (size_target.y != FLT_MAX)
|
||||
window->Size.y = window->SizeFull.y = size_target.y;
|
||||
if (pos_target.x != FLT_MAX)
|
||||
{
|
||||
window->Pos = ImTrunc(pos_target);
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
window->Pos.x = ImTrunc(pos_target.x);
|
||||
if (pos_target.y != FLT_MAX)
|
||||
window->Pos.y = ImTrunc(pos_target.y);
|
||||
if (size_target.x != FLT_MAX || size_target.y != FLT_MAX || pos_target.x != FLT_MAX|| pos_target.y != FLT_MAX)
|
||||
MarkIniSettingsDirty(window);
|
||||
|
||||
window->Size = window->SizeFull;
|
||||
return ret_auto_fit;
|
||||
return ret_auto_fit_mask;
|
||||
}
|
||||
|
||||
static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_rect)
|
||||
@ -5992,7 +6007,7 @@ static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_
|
||||
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, int border_hovered, int border_held)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
float rounding = window->WindowRounding;
|
||||
@ -6000,14 +6015,15 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||
if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
|
||||
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
|
||||
|
||||
int border_held = window->ResizeBorderHeld;
|
||||
if (border_held != -1)
|
||||
if (border_hovered != -1 || border_held != -1)
|
||||
{
|
||||
const ImGuiResizeBorderDef& def = resize_border_def[border_held];
|
||||
ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f);
|
||||
const int border_n = (border_held != -1) ? border_held : border_hovered;
|
||||
const ImGuiResizeBorderDef& def = resize_border_def[border_n];
|
||||
const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f);
|
||||
const ImU32 border_col = GetColorU32((border_held != -1) ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered);
|
||||
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle);
|
||||
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f);
|
||||
window->DrawList->PathStroke(GetColorU32(ImGuiCol_SeparatorActive), 0, ImMax(2.0f, border_size)); // Thicker than usual
|
||||
window->DrawList->PathStroke(border_col, 0, ImMax(2.0f, border_size)); // Thicker than usual
|
||||
}
|
||||
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
{
|
||||
@ -6018,7 +6034,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||
|
||||
// Draw background and borders
|
||||
// Draw and handle scrollbars
|
||||
void ImGui::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)
|
||||
void ImGui::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, int border_hovered, int border_held)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiStyle& style = g.Style;
|
||||
@ -6101,7 +6117,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
|
||||
// Borders
|
||||
if (handle_borders_and_resize_grips)
|
||||
RenderWindowOuterBorders(window);
|
||||
RenderWindowOuterBorders(window, border_hovered, border_held);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6627,14 +6643,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
#endif
|
||||
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
int border_held = -1;
|
||||
int border_hovered = -1, border_held = -1;
|
||||
ImU32 resize_grip_col[4] = {};
|
||||
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_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
if (!window->Collapsed)
|
||||
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;
|
||||
window->ResizeBorderHeld = (signed char)border_held;
|
||||
if (int auto_fit_mask = UpdateWindowManualResize(window, size_auto_fit, &border_hovered, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
||||
{
|
||||
if (auto_fit_mask & (1 << ImGuiAxis_X))
|
||||
use_current_size_for_scrollbar_x = true;
|
||||
if (auto_fit_mask & (1 << ImGuiAxis_Y))
|
||||
use_current_size_for_scrollbar_y = true;
|
||||
}
|
||||
|
||||
// SCROLLBAR VISIBILITY
|
||||
|
||||
@ -6749,7 +6769,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
|
||||
const bool title_bar_is_highlight = want_focus || (window_to_highlight && window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight);
|
||||
const bool handle_borders_and_resize_grips = true; // This exists to facilitate merge with 'docking' branch.
|
||||
RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size);
|
||||
RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size, border_hovered, border_held);
|
||||
|
||||
if (render_decorations_in_parent)
|
||||
window->DrawList = &window->DrawListInst;
|
||||
|
@ -2428,7 +2428,6 @@ struct IMGUI_API ImGuiWindow
|
||||
bool IsFallbackWindow; // Set on the "Debug##Default" window.
|
||||
bool IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked()
|
||||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
||||
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
||||
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
|
||||
short BeginCountPreviousFrame; // Number of Begin() during the previous frame
|
||||
short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0.
|
||||
|
Loading…
Reference in New Issue
Block a user