@ -5270,53 +5270,64 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co
* out_size = size_constrained ;
}
// Data for resizing from corner
struct ImGuiResizeGripDef
{
ImVec2 CornerPosN ;
ImVec2 InnerDir ;
int AngleMin12 , AngleMax12 ;
} ;
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
{ ImVec2 ( 0 , 0 ) , ImVec2 ( + 1 , + 1 ) , 6 , 9 } , // Upper-left (Unused)
{ ImVec2 ( 1 , 0 ) , ImVec2 ( - 1 , + 1 ) , 9 , 12 } , // Upper-right (Unused)
{ ImVec2 ( 1 , 0 ) , ImVec2 ( - 1 , + 1 ) , 9 , 12 } // Upper-right (Unused)
} ;
// Data for resizing from borders
struct ImGuiResizeBorderDef
{
ImVec2 InnerDir ;
ImVec2 CornerPosN1, CornerPos N2;
ImVec2 SegmentN1, Segment N2;
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 ( 0 , 1 ) , ImVec2 ( 0 , 0 ) , IM_PI * 1.00f } , // Left
{ 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
{ ImVec2 ( 0 , +1 ) , ImVec2 ( 0 , 0 ) , ImVec2 ( 1 , 0 ) , IM_PI * 1.50f } , // Up
{ ImVec2 ( 0 , - 1 ) , ImVec2 ( 1 , 1 ) , ImVec2 ( 0 , 1 ) , IM_PI * 0.50f } // Down
} ;
static ImRect GetResizeBorderRect ( ImGuiWindow * window , int border_n , float perp_padding , float thickness )
{
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 ) ; } // 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
if ( thickness = = 0.0f )
rect . Max - = ImVec2 ( 1 , 1 ) ;
if ( border_n = = ImGuiDir_Left ) { return ImRect ( rect . Min . x - thickness , rect . Min . y + perp_padding , rect . Min . x + thickness , rect . Max . y - perp_padding ) ; }
if ( border_n = = ImGuiDir_Right ) { return ImRect ( rect . Max . x - thickness , rect . Min . y + perp_padding , rect . Max . x + thickness , rect . Max . y - perp_padding ) ; }
if ( border_n = = ImGuiDir_Up ) { return ImRect ( rect . Min . x + perp_padding , rect . Min . y - thickness , rect . Max . x - perp_padding , rect . Min . y + thickness ) ; }
if ( border_n = = ImGuiDir_Down ) { return ImRect ( rect . Min . x + perp_padding , rect . Max . y - thickness , rect . Max . x - perp_padding , rect . Max . y + thickness ) ; }
IM_ASSERT ( 0 ) ;
return ImRect ( ) ;
}
// 0..3: corners (Lower-right, Lower-left, Unused, Unused)
// 4..7: borders (Top, Right, Bottom, Left)
ImGuiID ImGui : : GetWindowResizeID ( ImGuiWindow * window , int n )
ImGuiID ImGui : : GetWindowResizeCornerID ( ImGuiWindow * window , int n )
{
IM_ASSERT ( n > = 0 & & n < = 7 ) ;
IM_ASSERT ( n > = 0 & & n < 4 ) ;
ImGuiID id = window - > ID ;
id = ImHashStr ( " #RESIZE " , 0 , id ) ;
id = ImHashData ( & n , sizeof ( int ) , id ) ;
return id ;
}
// Borders (Left, Right, Up, Down)
ImGuiID ImGui : : GetWindowResizeBorderID ( ImGuiWindow * window , ImGuiDir dir )
{
IM_ASSERT ( dir > = 0 & & dir < 4 ) ;
int n = ( int ) dir + 4 ;
ImGuiID id = window - > ID ;
id = ImHashStr ( " #RESIZE " , 0 , id ) ;
id = ImHashData ( & n , sizeof ( int ) , id ) ;
@ -5351,15 +5362,16 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
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 . CornerPosN ) ;
const ImGuiResizeGripDef & def = resize_grip_def [ resize_grip_n ] ;
const ImVec2 corner = ImLerp ( window - > Pos , window - > Pos + window - > Size , def . 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 ) ;
bool hovered , held ;
ImRect resize_rect ( corner - def . InnerDir * grip_hover_outer_size , corner + def . InnerDir * grip_hover_inner_size ) ;
if ( resize_rect . Min . x > resize_rect . Max . x ) ImSwap ( resize_rect . Min . x , resize_rect . Max . x ) ;
if ( resize_rect . Min . y > resize_rect . Max . y ) ImSwap ( resize_rect . Min . y , resize_rect . Max . y ) ;
bool hovered , held ;
ButtonBehavior ( resize_rect , window- > GetID ( resize_grip_n ) , & hovered , & held , ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus ) ;
ImGuiID resize_grip_id = window - > GetID ( resize_grip_n ) ; // == GetWindowResizeCornerID()
ButtonBehavior ( resize_rect , resize_grip_id , & hovered , & held , ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus ) ;
//GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
if ( hovered | | held )
g . MouseCursor = ( resize_grip_n & 1 ) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE ;
@ -5375,39 +5387,41 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
{
// 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 c orner_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
ImVec2 clamp_m in = ImVec2 ( grip . CornerPosN . x = = 1.0f ? visibility_rect . Min . x : - FLT_MAX , grip . CornerPosN . y = = 1.0f ? visibility_rect . Min . y : - FLT_MAX ) ;
ImVec2 c lamp_max = ImVec2 ( grip . CornerPosN . x = = 0.0f ? visibility_rect . Max . x : + FLT_MAX , grip . CornerPosN . y = = 0.0f ? visibility_rect . Max . y : + FLT_MAX ) ;
ImVec2 c lamp_min = ImVec2 ( def . CornerPosN . x = = 1.0f ? visibility_rect . Min . x : - FLT_MAX , def . CornerPosN . y = = 1.0f ? visibility_rect . Min . y : - FLT_MAX ) ;
ImVec2 clamp_m ax = ImVec2 ( def . CornerPosN . x = = 0.0f ? visibility_rect . Max . x : + FLT_MAX , def . CornerPosN . y = = 0.0f ? visibility_rect . Max . y : + FLT_MAX ) ;
ImVec2 c orner_target = g . IO . MousePos - g . ActiveIdClickOffset + ImLerp ( def . InnerDir * grip_hover_outer_size , def . InnerDir * - grip_hover_inner_size , def . CornerPosN ) ; // Corner of the window corresponding to our corner grip
corner_target = ImClamp ( corner_target , clamp_min , clamp_max ) ;
CalcResizePosSizeFromAnyCorner ( window , corner_target , grip . CornerPosN , & pos_target , & size_target ) ;
CalcResizePosSizeFromAnyCorner ( window , corner_target , def . CornerPosN , & pos_target , & size_target ) ;
}
// Only lower-left grip is visible before hovering/activating
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 ImGuiResizeBorderDef & def = resize_border_def [ border_n ] ;
const ImGuiAxis axis = ( border_n = = ImGuiDir_Left | | border_n = = ImGuiDir_Right ) ? ImGuiAxis_X : ImGuiAxis_Y ;
bool hovered , held ;
ImRect border_rect = GetResizeBorderRect ( window , border_n , grip_hover_inner_size , WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS ) ;
ButtonBehavior ( border_rect , window - > GetID ( border_n + 4 ) , & hovered , & held , ImGuiButtonFlags_FlattenChildren ) ;
ImGuiID border_id = window - > GetID ( border_n + 4 ) ; // == GetWindowResizeBorderID()
ButtonBehavior ( border_rect , border_id , & hovered , & held , ImGuiButtonFlags_FlattenChildren ) ;
//GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
if ( ( hovered & & g . HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER ) | | held )
{
g . MouseCursor = ( border_n & 1 ) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS ;
g . MouseCursor = ( axis = = ImGuiAxis_X ) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS ;
if ( held )
* border_held = border_n ;
}
if ( held )
{
ImVec2 clamp_min ( border_n = = ImGuiDir_Right ? visibility_rect . Min . x : - FLT_MAX , border_n = = ImGuiDir_Down ? visibility_rect . Min . y : - FLT_MAX ) ;
ImVec2 clamp_max ( border_n = = ImGuiDir_Left ? visibility_rect . Max . x : + FLT_MAX , border_n = = ImGuiDir_Up ? visibility_rect . Max . y : + FLT_MAX ) ;
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 ) ; } // 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
ImVec2 clamp_min = ImVec2 ( border_n = = 1 ? visibility_rect . Min . x : - FLT_MAX , border_n = = 2 ? visibility_rect . Min . y : - FLT_MAX ) ;
ImVec2 clamp_max = ImVec2 ( border_n = = 3 ? visibility_rect . Max . x : + FLT_MAX , border_n = = 0 ? visibility_rect . Max . y : + FLT_MAX ) ;
border_target [ axis ] = g . IO . MousePos [ axis ] - g . ActiveIdClickOffset [ axis ] + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS ;
border_target = ImClamp ( border_target , clamp_min , clamp_max ) ;
CalcResizePosSizeFromAnyCorner ( window , border_target , border_posn , & pos_target , & size_target ) ;
CalcResizePosSizeFromAnyCorner ( window , border_target , ImMin ( def . SegmentN1 , def . SegmentN2 ) , & pos_target , & size_target ) ;
}
}
PopID ( ) ;
@ -5474,8 +5488,8 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
{
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 . CornerPos N1) + 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 . CornerPos N2) + ImVec2 ( 0.5f , 0.5f ) + def . InnerDir * rounding , rounding , def . OuterAngle , def . OuterAngle + IM_PI * 0.25f ) ;
window - > DrawList - > PathArcTo ( ImLerp ( border_r . Min , border_r . Max , def . Segment N1) + 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 . Segment N2) + 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
}
if ( g . Style . FrameBorderSize > 0 & & ! ( window - > Flags & ImGuiWindowFlags_NoTitleBar ) )