Enforce group selection to abide by L/R behavior

When selecting greedy (right to left), selecting any part of the group
will get the whole group.  When selecting left to right, we must select
all items in the group to get the grouped items unless we are in the
group itself

Fixes https://gitlab.com/kicad/code/kicad/issues/11902

(cherry picked from commit e87ba10a5a)
This commit is contained in:
Seth Hillbrand 2022-07-12 10:46:45 -07:00
parent 48b520a098
commit 63e638cfab
1 changed files with 28 additions and 4 deletions

View File

@ -797,12 +797,12 @@ bool PCB_SELECTION_TOOL::selectMultiple()
* Left > Right : Select objects that are fully enclosed by selection * Left > Right : Select objects that are fully enclosed by selection
* Right > Left : Select objects that are crossed by selection * Right > Left : Select objects that are crossed by selection
*/ */
bool windowSelection = width >= 0 ? true : false; bool greedySelection = width >= 0 ? false : true;
if( view->IsMirroredX() ) if( view->IsMirroredX() )
windowSelection = !windowSelection; greedySelection = !greedySelection;
m_frame->GetCanvas()->SetCurrentCursor( windowSelection ? KICURSOR::SELECT_WINDOW m_frame->GetCanvas()->SetCurrentCursor( !greedySelection ? KICURSOR::SELECT_WINDOW
: KICURSOR::SELECT_LASSO ); : KICURSOR::SELECT_LASSO );
if( evt->IsCancelInteractive() || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
@ -853,13 +853,37 @@ bool PCB_SELECTION_TOOL::selectMultiple()
selectionRect.Normalize(); selectionRect.Normalize();
GENERAL_COLLECTOR collector; GENERAL_COLLECTOR collector;
std::set<BOARD_ITEM*> group_items;
for( PCB_GROUP* group : board()->Groups() )
{
// The currently entered group does not get limited
if( m_enteredGroup == group )
continue;
std::unordered_set<BOARD_ITEM*>& newset = group->GetItems();
// If we are not greedy and have selected the whole group, add just one item
// to allow it to be promoted to the group later
if( !greedySelection && selectionRect.Contains( group->GetBoundingBox() )
&& newset.size() )
{
collector.Append( *newset.begin() );
}
for( BOARD_ITEM* group_item : newset )
group_items.emplace( group_item );
}
for( auto it = candidates.begin(), it_end = candidates.end(); it != it_end; ++it ) for( auto it = candidates.begin(), it_end = candidates.end(); it != it_end; ++it )
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first ); BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) ) if( item && Selectable( item ) && item->HitTest( selectionRect, !greedySelection )
&& ( greedySelection || !group_items.count( item ) ) )
{
collector.Append( item ); collector.Append( item );
}
} }
// Apply the stateful filter // Apply the stateful filter