From 1eee10778be403a9942727e89eaf22c5c0a7b0c5 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 10 Jan 2018 23:06:51 +0100 Subject: [PATCH] Internals: Begin: Refactor some code into an UpdateManualResize() function. --- imgui.cpp | 171 +++++++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 13a12a55..cf5cfb77 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -675,6 +675,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini 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 @@ static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_paddin 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 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) 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));