@ -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 ) ) ;