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: | ||||
| - 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. | ||||
| - 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" | ||||
|   with a small number of segments (e.g. an hexagon). (#2287) [@baktery] | ||||
| - 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             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             RenderOuterBorders(ImGuiWindow* window, int border_held); | ||||
|  | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| @@ -4637,12 +4639,12 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co | ||||
|  | ||||
| struct ImGuiResizeGripDef | ||||
| { | ||||
|     ImVec2  CornerPos; | ||||
|     ImVec2  CornerPosN; | ||||
|     ImVec2  InnerDir; | ||||
|     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(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(); | ||||
|     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 == 1) return ImRect(rect.Max.x - thickness,    rect.Min.y + perp_padding, rect.Max.x + thickness,    rect.Max.y - perp_padding); | ||||
|     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 == 3) return ImRect(rect.Min.x - thickness,    rect.Min.y + perp_padding, rect.Min.x + thickness,    rect.Max.y - perp_padding); | ||||
|     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);   // 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);      // 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);   // Left | ||||
|     IM_ASSERT(0); | ||||
|     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++) | ||||
|     { | ||||
|         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 | ||||
|         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 | ||||
|             // 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 | ||||
|             CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); | ||||
|             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.CornerPosN, &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); | ||||
| @@ -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) | ||||
|         { | ||||
|             g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; | ||||
|             if (held) *border_held = border_n; | ||||
|             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 + 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); } | ||||
|             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 == 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 == 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); } // 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 == 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); | ||||
|         } | ||||
|     } | ||||
| @@ -4772,6 +4775,41 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | ||||
|     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) | ||||
| { | ||||
|     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++) | ||||
|                 { | ||||
|                     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(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); | ||||
| @@ -5202,15 +5240,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|             } | ||||
|  | ||||
|             // Borders | ||||
|             if (window_border_size > 0.0f && !(flags & ImGuiWindowFlags_NoBackground)) | ||||
|                 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); | ||||
|             RenderOuterBorders(window, border_held); | ||||
|         } | ||||
|  | ||||
|         // Draw navigation selection/windowing rectangle border | ||||
|   | ||||
		Reference in New Issue
	
	Block a user