Internals: Begin: Refactor some code into an UpdateManualResize() function.
diff --git a/imgui.cpp b/imgui.cpp
index 13a12a5..cf5cfb7 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -675,6 +675,7 @@
namespace ImGui
{
+static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4]);
static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window);
}
@@ -4338,6 +4339,93 @@
return ImRect();
}
+// Handle resize for: Resize Grips, Borders, Gamepad
+static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4])
+{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindowFlags flags = window->Flags;
+ if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
+ return;
+
+ const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4
+ const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0;
+ const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
+ const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f);
+
+ ImVec2 pos_target(FLT_MAX, FLT_MAX);
+ ImVec2 size_target(FLT_MAX, FLT_MAX);
+
+ // Manual resize grips
+ PushID("#RESIZE");
+ for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
+ {
+ const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
+ const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos);
+
+ // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window
+ ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size);
+ resize_rect.FixInverted();
+ bool hovered, held;
+ ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
+ if (hovered || held)
+ g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
+
+ if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0)
+ {
+ // Manual auto-fit when double-clicking
+ size_target = CalcSizeAfterConstraint(window, size_auto_fit);
+ ClearActiveID();
+ }
+ else if (held)
+ {
+ // 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
+ ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip
+ CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target);
+ }
+ 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 float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check.
+ const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
+ bool hovered, held;
+ ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
+ ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
+ if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
+ {
+ g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
+ if (held) *border_held = border_n;
+ }
+ if (held)
+ {
+ ImVec2 border_target = window->Pos;
+ ImVec2 border_posn;
+ if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); }
+ if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); }
+ if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); }
+ if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); }
+ CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
+ }
+ }
+ PopID();
+
+ // Apply back modified position/size to window
+ if (size_target.x != FLT_MAX)
+ {
+ window->SizeFull = size_target;
+ MarkIniSettingsDirty(window);
+ }
+ if (pos_target.x != FLT_MAX)
+ {
+ window->Pos = window->PosFloat = ImFloor(pos_target);
+ MarkIniSettingsDirty(window);
+ }
+
+ window->Size = window->SizeFull;
+}
+
// Push a new ImGui window to add widgets to.
// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair.
// - Begin/End can be called multiple times during the frame with the same window name to append content.
@@ -4693,86 +4781,9 @@
int border_held = -1;
ImU32 resize_grip_col[4] = { 0 };
const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4
- const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0;
-
- const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f);
- const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f);
- if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize))
- {
- ImVec2 pos_target(FLT_MAX, FLT_MAX);
- ImVec2 size_target(FLT_MAX, FLT_MAX);
-
- // Manual resize grips
- PushID("#RESIZE");
- for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
- {
- const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
- const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos);
-
- // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window
- ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size);
- resize_rect.FixInverted();
- bool hovered, held;
- ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
- if (hovered || held)
- g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
-
- if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0)
- {
- // Manual auto-fit when double-clicking
- size_target = CalcSizeAfterConstraint(window, size_auto_fit);
- ClearActiveID();
- }
- else if (held)
- {
- // 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
- ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip
- CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target);
- }
- 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 float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check.
- const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
- bool hovered, held;
- ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
- ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
- if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
- {
- g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
- if (held) border_held = border_n;
- }
- if (held)
- {
- ImVec2 border_target = window->Pos;
- ImVec2 border_posn;
- if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); }
- if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); }
- if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); }
- if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); }
- CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
- }
- }
- PopID();
-
- // Apply back modified position/size to window
- if (size_target.x != FLT_MAX)
- {
- window->SizeFull = size_target;
- MarkIniSettingsDirty(window);
- }
- if (pos_target.x != FLT_MAX)
- {
- window->Pos = window->PosFloat = ImFloor(pos_target);
- MarkIniSettingsDirty(window);
- }
-
- window->Size = window->SizeFull;
- title_bar_rect = window->TitleBarRect();
- }
+ const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
+ UpdateManualResize(window, size_auto_fit, &border_held, &resize_grip_col[0]);
+ title_bar_rect = window->TitleBarRect();
// Window background, Default Alpha
ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags));