mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	When resizing from an edge, the border is more visible and better follow the rounded corners. Border rendering moved to RenderOuterBorders so it can be called in a different order for docking. (#1495, #822)
This commit is contained in:
		| @@ -36,6 +36,7 @@ HOW TO UPDATE? | |||||||
| Other Changes: | Other Changes: | ||||||
| - Added .editorconfig file for text editors to standardize using spaces. (#2038) [@kudaba] | - Added .editorconfig file for text editors to standardize using spaces. (#2038) [@kudaba] | ||||||
| - Fixed range-version of PushID() and GetID() not honoring the ### operator to restart from the seed value. | - Fixed range-version of PushID() and GetID() not honoring the ### operator to restart from the seed value. | ||||||
|  | - Window: When resizing from an edge, the border is more visible and better follow the rounded corners. | ||||||
| - ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle" | - ImDrawList: Fixed AddCircle(), AddCircleFilled() angle step being off, which was visible when drawing a "circle" | ||||||
|   with a small number of segments (e.g. an hexagon). (#2287) [@baktery] |   with a small number of segments (e.g. an hexagon). (#2287) [@baktery] | ||||||
| - ImGuiTextBuffer: Added append() function (unformatted). | - ImGuiTextBuffer: Added append() function (unformatted). | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -1033,6 +1033,8 @@ static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | |||||||
| static void             UpdateMouseInputs(); | static void             UpdateMouseInputs(); | ||||||
| static void             UpdateMouseWheel(); | static void             UpdateMouseWheel(); | ||||||
| static void             UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); | static void             UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); | ||||||
|  | static void             RenderOuterBorders(ImGuiWindow* window, int border_held); | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| @@ -4637,12 +4639,12 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co | |||||||
|  |  | ||||||
| struct ImGuiResizeGripDef | struct ImGuiResizeGripDef | ||||||
| { | { | ||||||
|     ImVec2  CornerPos; |     ImVec2  CornerPosN; | ||||||
|     ImVec2  InnerDir; |     ImVec2  InnerDir; | ||||||
|     int     AngleMin12, AngleMax12; |     int     AngleMin12, AngleMax12; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const ImGuiResizeGripDef resize_grip_def[4] = | static const ImGuiResizeGripDef resize_grip_def[4] = | ||||||
| { | { | ||||||
|     { ImVec2(1,1), ImVec2(-1,-1), 0, 3 }, // Lower right |     { ImVec2(1,1), ImVec2(-1,-1), 0, 3 }, // Lower right | ||||||
|     { ImVec2(0,1), ImVec2(+1,-1), 3, 6 }, // Lower left |     { ImVec2(0,1), ImVec2(+1,-1), 3, 6 }, // Lower left | ||||||
| @@ -4654,10 +4656,10 @@ static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_ | |||||||
| { | { | ||||||
|     ImRect rect = window->Rect(); |     ImRect rect = window->Rect(); | ||||||
|     if (thickness == 0.0f) rect.Max -= ImVec2(1,1); |     if (thickness == 0.0f) rect.Max -= ImVec2(1,1); | ||||||
|     if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness,    rect.Max.x - perp_padding, rect.Min.y + thickness); |     if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness,    rect.Max.x - perp_padding, rect.Min.y + thickness);      // Top | ||||||
|     if (border_n == 1) return ImRect(rect.Max.x - thickness,    rect.Min.y + perp_padding, rect.Max.x + thickness,    rect.Max.y - perp_padding); |     if (border_n == 1) return ImRect(rect.Max.x - thickness,    rect.Min.y + perp_padding, rect.Max.x + thickness,    rect.Max.y - perp_padding);   // Right | ||||||
|     if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness,    rect.Max.x - perp_padding, rect.Max.y + thickness); |     if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness,    rect.Max.x - perp_padding, rect.Max.y + thickness);      // Bottom | ||||||
|     if (border_n == 3) return ImRect(rect.Min.x - thickness,    rect.Min.y + perp_padding, rect.Min.x + thickness,    rect.Max.y - perp_padding); |     if (border_n == 3) return ImRect(rect.Min.x - thickness,    rect.Min.y + perp_padding, rect.Min.x + thickness,    rect.Max.y - perp_padding);   // Left | ||||||
|     IM_ASSERT(0); |     IM_ASSERT(0); | ||||||
|     return ImRect(); |     return ImRect(); | ||||||
| } | } | ||||||
| @@ -4685,7 +4687,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | |||||||
|     for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) |     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 ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; | ||||||
|         const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); |         const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN); | ||||||
|  |  | ||||||
|         // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window |         // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window | ||||||
|         ImRect resize_rect(corner - grip.InnerDir * grip_hover_outer_size, corner + grip.InnerDir * grip_hover_inner_size); |         ImRect resize_rect(corner - grip.InnerDir * grip_hover_outer_size, corner + grip.InnerDir * grip_hover_inner_size); | ||||||
| @@ -4707,8 +4709,8 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | |||||||
|         { |         { | ||||||
|             // 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.CornerPos); // 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 | ||||||
|             CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); |             CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target); | ||||||
|         } |         } | ||||||
|         if (resize_grip_n == 0 || held || hovered) |         if (resize_grip_n == 0 || held || hovered) | ||||||
|             resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); |             resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); | ||||||
| @@ -4722,16 +4724,17 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | |||||||
|         if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) |         if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) | ||||||
|         { |         { | ||||||
|             g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; |             g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; | ||||||
|             if (held) *border_held = border_n; |             if (held)  | ||||||
|  |                 *border_held = border_n; | ||||||
|         } |         } | ||||||
|         if (held) |         if (held) | ||||||
|         { |         { | ||||||
|             ImVec2 border_target = window->Pos; |             ImVec2 border_target = window->Pos; | ||||||
|             ImVec2 border_posn; |             ImVec2 border_posn; | ||||||
|             if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } |             if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Top | ||||||
|             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); } |             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); } |             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); } |             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 | ||||||
|             CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); |             CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -4772,6 +4775,41 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | |||||||
|     window->Size = window->SizeFull; |     window->Size = window->SizeFull; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void ImGui::RenderOuterBorders(ImGuiWindow* window, int border_held) | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     float rounding = window->WindowRounding; | ||||||
|  |     float border_size = window->WindowBorderSize; | ||||||
|  |     if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground)) | ||||||
|  |         window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); | ||||||
|  |     if (border_held != -1) | ||||||
|  |     { | ||||||
|  |         struct ImGuiResizeBorderDef | ||||||
|  |         { | ||||||
|  |             ImVec2 InnerDir; | ||||||
|  |             ImVec2 CornerPosN1, CornerPosN2; | ||||||
|  |             float  OuterAngle; | ||||||
|  |         }; | ||||||
|  |         static const ImGuiResizeBorderDef resize_border_def[4] = | ||||||
|  |         { | ||||||
|  |             { ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top | ||||||
|  |             { ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right | ||||||
|  |             { ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom | ||||||
|  |             { ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f }  // Left | ||||||
|  |         }; | ||||||
|  |         const ImGuiResizeBorderDef& def = resize_border_def[border_held]; | ||||||
|  |         ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f); | ||||||
|  |         window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN1) + 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.CornerPosN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI*0.25f); | ||||||
|  |         window->DrawList->PathStroke(GetColorU32(ImGuiCol_SeparatorActive), false, ImMax(2.0f, border_size)); // Thicker than usual | ||||||
|  |     } | ||||||
|  |     if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) | ||||||
|  |     { | ||||||
|  |         float y = window->Pos.y + window->TitleBarHeight() - 1; | ||||||
|  |         window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window) | void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window) | ||||||
| { | { | ||||||
|     window->ParentWindow = parent_window; |     window->ParentWindow = parent_window; | ||||||
| @@ -5193,7 +5231,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | |||||||
|                 for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) |                 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 ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; | ||||||
|                     const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); |                     const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN); | ||||||
|                     window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size))); |                     window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size))); | ||||||
|                     window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size))); |                     window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size))); | ||||||
|                     window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); |                     window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); | ||||||
| @@ -5202,15 +5240,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             // Borders |             // Borders | ||||||
|             if (window_border_size > 0.0f && !(flags & ImGuiWindowFlags_NoBackground)) |             RenderOuterBorders(window, border_held); | ||||||
|                 window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); |  | ||||||
|             if (border_held != -1) |  | ||||||
|             { |  | ||||||
|                 ImRect border = GetResizeBorderRect(window, border_held, grip_draw_size, 0.0f); |  | ||||||
|                 window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); |  | ||||||
|             } |  | ||||||
|             if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) |  | ||||||
|                 window->DrawList->AddLine(title_bar_rect.GetBL() + ImVec2(style.WindowBorderSize, -1), title_bar_rect.GetBR() + ImVec2(-style.WindowBorderSize, -1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Draw navigation selection/windowing rectangle border |         // Draw navigation selection/windowing rectangle border | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user