@ -805,7 +805,7 @@ static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock
static void SetCurrentWindow ( ImGuiWindow * window ) ;
static void FindHoveredWindow ( ) ;
static ImGuiWindow * CreateNewWindow ( const char * name , ImGuiWindowFlags flags ) ;
static ImVec2 CalcNextScrollFromScrollTargetAndClamp ( ImGuiWindow * window , bool snap_on_edges );
static ImVec2 CalcNextScrollFromScrollTargetAndClamp ( ImGuiWindow * window );
static void AddDrawListToDrawData ( ImVector < ImDrawList * > * out_list , ImDrawList * draw_list ) ;
static void AddWindowToSortBuffer ( ImVector < ImGuiWindow * > * out_sorted_windows , ImGuiWindow * window ) ;
@ -5819,7 +5819,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window - > ScrollMax . y = ImMax ( 0.0f , window - > ContentSize . y + window - > WindowPadding . y * 2.0f - window - > InnerRect . GetHeight ( ) ) ;
// Apply scrolling
window - > Scroll = CalcNextScrollFromScrollTargetAndClamp ( window , true );
window - > Scroll = CalcNextScrollFromScrollTargetAndClamp ( window );
window - > ScrollTarget = ImVec2 ( FLT_MAX , FLT_MAX ) ;
// DRAWING
@ -7325,30 +7325,20 @@ void ImGui::EndGroup()
// [SECTION] SCROLLING
//-----------------------------------------------------------------------------
static ImVec2 CalcNextScrollFromScrollTargetAndClamp ( ImGuiWindow * window , bool snap_on_edges )
static ImVec2 CalcNextScrollFromScrollTargetAndClamp ( ImGuiWindow * window )
{
ImGuiContext & g = * GImGui ;
ImVec2 scroll = window - > Scroll ;
if ( window - > ScrollTarget . x < FLT_MAX )
{
float cr_x = window - > ScrollTargetCenterRatio . x ;
float target_x = window - > ScrollTarget . x ;
if ( snap_on_edges & & cr_x < = 0.0f & & target_x < = window - > WindowPadding . x )
target_x = 0.0f ;
else if ( snap_on_edges & & cr_x > = 1.0f & & target_x > = window - > ContentSize . x + window - > WindowPadding . x + g . Style . ItemSpacing . x )
target_x = window - > ContentSize . x + window - > WindowPadding . x * 2.0f ;
scroll . x = target_x - cr_x * ( window - > SizeFull . x - window - > ScrollbarSizes . x ) ;
}
if ( window - > ScrollTarget . y < FLT_MAX )
{
// 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
float decoration_up_height = window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) ;
float cr_y = window - > ScrollTargetCenterRatio . y ;
float target_y = window - > ScrollTarget . y ;
if ( snap_on_edges & & cr_y < = 0.0f & & target_y < = window - > WindowPadding . y )
target_y = 0.0f ;
if ( snap_on_edges & & cr_y > = 1.0f & & target_y > = window - > ContentSize . y + window - > WindowPadding . y + g . Style . ItemSpacing . y )
target_y = window - > ContentSize . y + window - > WindowPadding . y * 2.0f ;
scroll . y = target_y - cr_y * ( window - > SizeFull . y - window - > ScrollbarSizes . y - decoration_up_height ) ;
}
scroll . x = IM_FLOOR ( ImMax ( scroll . x , 0.0f ) ) ;
@ -7380,7 +7370,7 @@ ImVec2 ImGui::ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_
else if ( item_rect . Max . y > = window_rect . Max . y )
SetScrollFromPosY ( window , item_rect . Max . y - window - > Pos . y + g . Style . ItemSpacing . y , 1.0f ) ;
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp ( window , false );
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp ( window );
delta_scroll = next_scroll - window - > Scroll ;
}
@ -7441,10 +7431,10 @@ void ImGui::SetScrollY(ImGuiWindow* window, float new_scroll_y)
window - > ScrollTargetCenterRatio . y = 0.0f ;
}
// Note that a local position will vary depending on initial scroll value
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
void ImGui : : SetScrollFromPosX ( ImGuiWindow * window , float local_x , float center_x_ratio )
{
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
IM_ASSERT ( center_x_ratio > = 0.0f & & center_x_ratio < = 1.0f ) ;
window - > ScrollTarget . x = IM_FLOOR ( local_x + window - > Scroll . x ) ;
window - > ScrollTargetCenterRatio . x = center_x_ratio ;
@ -7452,10 +7442,8 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
void ImGui : : SetScrollFromPosY ( ImGuiWindow * window , float local_y , float center_y_ratio )
{
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
IM_ASSERT ( center_y_ratio > = 0.0f & & center_y_ratio < = 1.0f ) ;
const float decoration_up_height = window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) ;
local_y - = decoration_up_height ;
local_y - = window - > TitleBarHeight ( ) + window - > MenuBarHeight ( ) ; // FIXME: Would be nice to have a more standardized access to our scrollable/client rect
window - > ScrollTarget . y = IM_FLOOR ( local_y + window - > Scroll . y ) ;
window - > ScrollTargetCenterRatio . y = center_y_ratio ;
}
@ -7472,15 +7460,34 @@ void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
SetScrollFromPosY ( g . CurrentWindow , local_y , center_y_ratio ) ;
}
// Tweak: snap on edges when aiming at an item very close to the edge,
// So the difference between WindowPadding and ItemSpacing will be in the visible area after scrolling.
// When we refactor the scrolling API this may be configurable with a flag?
// Note that the effect for this won't be visible on X axis with default Style settings as WindowPadding.x == ItemSpacing.x by default.
static float CalcScrollSnap ( float target , float snap_min , float snap_max , float snap_threshold , float center_ratio )
{
if ( target < = snap_min + snap_threshold )
return ImLerp ( snap_min , target , center_ratio ) ;
if ( target > = snap_max - snap_threshold )
return ImLerp ( target , snap_max , center_ratio ) ;
return target ;
}
// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
void ImGui : : SetScrollHereX ( float center_x_ratio )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
float target_x = window - > DC . LastItemRect . Min . x - window - > Pos . x ; // Left of last item, in window space
float last_item_width = window - > DC . LastItemRect . GetWidth ( ) ;
target_x + = ( last_item_width * center_x_ratio ) + ( g . Style . ItemSpacing . x * ( center_x_ratio - 0.5f ) * 2.0f ) ; // Precisely aim before, in the middle or after the last item.
SetScrollFromPosX ( target_x , center_x_ratio ) ;
float spacing_x = g . Style . ItemSpacing . x ;
float target_x = ImLerp ( window - > DC . LastItemRect . Min . x - spacing_x , window - > DC . LastItemRect . Max . x + spacing_x , center_x_ratio ) ;
// Tweak: snap on edges when aiming at an item very close to the edge
const float snap_x_threshold = ImMax ( 0.0f , window - > WindowPadding . x - spacing_x ) ;
const float snap_x_min = window - > DC . CursorStartPos . x - window - > WindowPadding . x ;
const float snap_x_max = window - > DC . CursorStartPos . x + window - > ContentSize . x + window - > WindowPadding . x ;
target_x = CalcScrollSnap ( target_x , snap_x_min , snap_x_max , snap_x_threshold , center_x_ratio ) ;
SetScrollFromPosX ( window , target_x - window - > Pos . x , center_x_ratio ) ;
}
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
@ -7488,9 +7495,16 @@ void ImGui::SetScrollHereY(float center_y_ratio)
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * window = g . CurrentWindow ;
float target_y = window - > DC . CursorPosPrevLine . y - window - > Pos . y ; // Top of last item, in window space
target_y + = ( window - > DC . PrevLineSize . y * center_y_ratio ) + ( g . Style . ItemSpacing . y * ( center_y_ratio - 0.5f ) * 2.0f ) ; // Precisely aim above, in the middle or below the last line.
SetScrollFromPosY ( target_y , center_y_ratio ) ;
float spacing_y = g . Style . ItemSpacing . y ;
float target_y = ImLerp ( window - > DC . CursorPosPrevLine . y - spacing_y , window - > DC . CursorPosPrevLine . y + window - > DC . PrevLineSize . y + spacing_y , center_y_ratio ) ;
// Tweak: snap on edges when aiming at an item very close to the edge
const float snap_y_threshold = ImMax ( 0.0f , window - > WindowPadding . y - spacing_y ) ;
const float snap_y_min = window - > DC . CursorStartPos . y - window - > WindowPadding . y ;
const float snap_y_max = window - > DC . CursorStartPos . y + window - > ContentSize . y + window - > WindowPadding . y ;
target_y = CalcScrollSnap ( target_y , snap_y_min , snap_y_max , snap_y_threshold , center_y_ratio ) ;
SetScrollFromPosY ( window , target_y - window - > Pos . y , center_y_ratio ) ;
}
//-----------------------------------------------------------------------------