@ -7014,13 +7014,18 @@ void ImGui::DebugNodeTypingSelectState(ImGuiTypingSelectState* data)
// [SECTION] Widgets: Box-Select support
// This has been extracted away from Multi-Select logic in the hope that it could eventually be used elsewhere, but hasn't been yet.
//-------------------------------------------------------------------------
// - BoxSelectStartDrag() [Internal]
// Extra logic in MultiSelectItemFooter() and ImGuiListClipper::Step()
//-------------------------------------------------------------------------
// - BoxSelectPreStartDrag() [Internal]
// - BoxSelectActivateDrag() [Internal]
// - BoxSelectDeactivateDrag() [Internal]
// - BoxSelectScrollWithMouseDrag() [Internal]
// - BeginBoxSelect() [Internal]
// - EndBoxSelect() [Internal]
//-------------------------------------------------------------------------
static void BoxSelectStartDrag ( ImGuiID id , ImGuiSelectionUserData clicked_item )
// Call on the initial click.
static void BoxSelectPreStartDrag ( ImGuiID id , ImGuiSelectionUserData clicked_item )
{
ImGuiContext & g = * GImGui ;
ImGuiBoxSelectState * bs = & g . BoxSelectState ;
@ -7032,10 +7037,33 @@ static void BoxSelectStartDrag(ImGuiID id, ImGuiSelectionUserData clicked_item)
bs - > ScrollAccum = ImVec2 ( 0.0f , 0.0f ) ;
}
static void BoxSelectScrollWithMouseDrag ( ImGuiWindow * window , const ImRect & inner_r )
static void BoxSelectActivateDrag ( ImGuiBoxSelectState * bs , ImGuiWindow * window )
{
ImGuiContext & g = * GImGui ;
IMGUI_DEBUG_LOG_SELECTION ( " [selection] BeginBoxSelect() 0X%08X: Activate \n " , bs - > ID ) ;
bs - > IsActive = true ;
bs - > Window = window ;
bs - > IsStarting = false ;
ImGui : : SetActiveID ( bs - > ID , window ) ;
if ( bs - > IsStartedFromVoid & & ( bs - > KeyMods & ( ImGuiMod_Ctrl | ImGuiMod_Shift ) ) = = 0 )
bs - > RequestClear = true ;
}
static void BoxSelectDeactivateDrag ( ImGuiBoxSelectState * bs )
{
ImGuiContext & g = * GImGui ;
bs - > IsActive = bs - > IsStarting = false ;
if ( g . ActiveId = = bs - > ID )
{
IMGUI_DEBUG_LOG_SELECTION ( " [selection] BeginBoxSelect() 0X%08X: Deactivate \n " , bs - > ID ) ;
ImGui : : ClearActiveID ( ) ;
}
bs - > ID = 0 ;
}
static void BoxSelectScrollWithMouseDrag ( ImGuiBoxSelectState * bs , ImGuiWindow * window , const ImRect & inner_r )
{
ImGuiContext & g = * GImGui ;
ImGuiBoxSelectState * bs = & g . BoxSelectState ;
IM_ASSERT ( bs - > Window = = window ) ;
for ( int n = 0 ; n < 2 ; n + + ) // each axis
{
@ -7069,30 +7097,13 @@ bool ImGui::BeginBoxSelect(ImGuiWindow* window, ImGuiID box_select_id, ImGuiMult
if ( bs - > ID ! = box_select_id )
return false ;
// IsStarting is set by MultiSelectItemFooter() when considering a possible box-select. We validate it here and lock geometry.
bs - > UnclipMode = false ;
bs - > RequestClear = false ;
// IsStarting is set by MultiSelectItemFooter() when considering a possible box-select. We validate it here and lock geometry.
if ( bs - > IsStarting & & IsMouseDragPastThreshold ( 0 ) )
{
IMGUI_DEBUG_LOG_SELECTION ( " [selection] BeginBoxSelect() 0X%08X: Started. \n " , box_select_id ) ;
bs - > IsActive = true ;
bs - > Window = window ;
bs - > IsStarting = false ;
SetActiveID ( bs - > ID , window ) ;
if ( bs - > IsStartedFromVoid & & ( bs - > KeyMods & ( ImGuiMod_Ctrl | ImGuiMod_Shift ) ) = = 0 )
bs - > RequestClear = true ;
}
BoxSelectActivateDrag ( bs , window ) ;
else if ( ( bs - > IsStarting | | bs - > IsActive ) & & g . IO . MouseDown [ 0 ] = = false )
{
bs - > IsActive = bs - > IsStarting = false ;
if ( g . ActiveId = = bs - > ID )
{
IMGUI_DEBUG_LOG_SELECTION ( " [selection] BeginBoxSelect() 0X%08X: Ended. \n " , box_select_id ) ;
ClearActiveID ( ) ;
}
bs - > ID = 0 ;
}
BoxSelectDeactivateDrag ( bs ) ;
if ( ! bs - > IsActive )
return false ;
@ -7147,7 +7158,7 @@ void ImGui::EndBoxSelect(const ImRect& scope_rect, bool enable_scroll)
scroll_r . Expand ( - g . FontSize ) ;
//GetForegroundDrawList()->AddRect(scroll_r.Min, scroll_r.Max, IM_COL32(0, 255, 0, 255));
if ( ! scroll_r . Contains ( g . IO . MousePos ) )
BoxSelectScrollWithMouseDrag ( window , scroll_r ) ;
BoxSelectScrollWithMouseDrag ( bs , window , scroll_r ) ;
}
}
@ -7330,7 +7341,7 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect()
{
if ( ! g . BoxSelectState . IsActive & & ! g . BoxSelectState . IsStarting & & g . IO . MouseClickedCount [ 0 ] = = 1 )
{
BoxSelectStartDrag ( ms - > BoxSelectId , ImGuiSelectionUserData_Invalid ) ;
BoxSelectPre StartDrag ( ms - > BoxSelectId , ImGuiSelectionUserData_Invalid ) ;
FocusWindow ( window , ImGuiFocusRequestFlags_UnlessBelowModal ) ;
SetHoveredID ( ms - > BoxSelectId ) ;
if ( ms - > Flags & ImGuiMultiSelectFlags_ScopeRect )
@ -7517,22 +7528,23 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
}
// Box-select toggle handling
if ( ImGuiBoxSelectState * bs = GetBoxSelectState ( ms - > BoxSelectId ) )
{
const bool rect_overlap_curr = bs - > BoxSelectRectCurr . Overlaps ( g . LastItemData . Rect ) ;
const bool rect_overlap_prev = bs - > BoxSelectRectPrev . Overlaps ( g . LastItemData . Rect ) ;
if ( ( rect_overlap_curr & & ! rect_overlap_prev & & ! selected ) | | ( rect_overlap_prev & & ! rect_overlap_curr ) )
if ( ms - > BoxSelectId ! = 0 )
if ( ImGuiBoxSelectState * bs = GetBoxSelectState ( ms - > BoxSelectId ) )
{
selected = ! selected ;
ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange , selected , item_data , item_data } ;
ImGuiSelectionRequest * prev_req = ( ms - > IO . Requests . Size > 0 ) ? & ms - > IO . Requests . Data [ ms - > IO . Requests . Size - 1 ] : NULL ;
if ( prev_req & & prev_req - > Type = = ImGuiSelectionRequestType_SetRange & & prev_req - > RangeLastItem = = ms - > BoxSelectLastitem & & prev_req - > Selected = = selected )
prev_req - > RangeLastItem = item_data ; // Merge span into same request
else
ms - > IO . Requests . push_back ( req ) ;
const bool rect_overlap_curr = bs - > BoxSelectRectCurr . Overlaps ( g . LastItemData . Rect ) ;
const bool rect_overlap_prev = bs - > BoxSelectRectPrev . Overlaps ( g . LastItemData . Rect ) ;
if ( ( rect_overlap_curr & & ! rect_overlap_prev & & ! selected ) | | ( rect_overlap_prev & & ! rect_overlap_curr ) )
{
selected = ! selected ;
ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange , selected , item_data , item_data } ;
ImGuiSelectionRequest * prev_req = ( ms - > IO . Requests . Size > 0 ) ? & ms - > IO . Requests . Data [ ms - > IO . Requests . Size - 1 ] : NULL ;
if ( prev_req & & prev_req - > Type = = ImGuiSelectionRequestType_SetRange & & prev_req - > RangeLastItem = = ms - > BoxSelectLastitem & & prev_req - > Selected = = selected )
prev_req - > RangeLastItem = item_data ; // Merge span into same request
else
ms - > IO . Requests . push_back ( req ) ;
}
ms - > BoxSelectLastitem = item_data ;
}
ms - > BoxSelectLastitem = item_data ;
}
// Right-click handling.
// FIXME-MULTISELECT: Currently filtered out by ImGuiMultiSelectFlags_NoAutoSelect but maybe should be moved to Selectable(). See https://github.com/ocornut/imgui/pull/5816
@ -7560,7 +7572,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
ImGuiInputSource input_source = ( g . NavJustMovedToId = = id | | g . NavActivateId = = id ) ? g . NavInputSource : ImGuiInputSource_Mouse ;
if ( flags & ImGuiMultiSelectFlags_BoxSelect )
if ( selected = = false & & ! g . BoxSelectState . IsActive & & ! g . BoxSelectState . IsStarting & & input_source = = ImGuiInputSource_Mouse & & g . IO . MouseClickedCount [ 0 ] = = 1 )
BoxSelectStartDrag ( ms - > BoxSelectId , item_data ) ;
BoxSelectPre StartDrag ( ms - > BoxSelectId , item_data ) ;
//----------------------------------------------------------------------------------------
// ACTION | Begin | Pressed/Activated | End