Don't hit-test groups; allow only selection promotions from members.

Also fixes some bugs were the selection filters weren't getting
applied correctly on drag-selects.

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

Fixes https://gitlab.com/kicad/code/kicad/issues/5804
This commit is contained in:
Jeff Young 2020-10-02 12:32:48 +01:00
parent c1b34b02b5
commit 732f588d83
2 changed files with 30 additions and 51 deletions

View File

@ -165,36 +165,14 @@ void PCB_GROUP::SwapData( BOARD_ITEM* aImage )
bool PCB_GROUP::HitTest( const wxPoint& aPosition, int aAccuracy ) const bool PCB_GROUP::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{ {
EDA_RECT rect = GetBoundingBox(); // Groups are selected by promoting a selection of one of their children
return rect.Inflate( aAccuracy ).Contains( aPosition ); return false;
} }
bool PCB_GROUP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const bool PCB_GROUP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{ {
EDA_RECT arect = aRect; // Groups are selected by promoting a selection of one of their children
arect.Inflate( aAccuracy );
EDA_RECT bbox = GetBoundingBox();
if( aContained )
{
return arect.Contains( bbox );
}
else
{
// If the rect does not intersect the bounding box, skip any tests
if( !aRect.Intersects( bbox ) )
return false;
for( BOARD_ITEM* member : m_items )
{
if( member->HitTest( arect, false, 0 ) )
return true;
}
}
// No items were hit
return false; return false;
} }

View File

@ -533,6 +533,8 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
// Apply the stateful filter // Apply the stateful filter
filterCollectedItems( collector ); filterCollectedItems( collector );
FilterCollectorForGroups( collector );
// Apply some ugly heuristics to avoid disambiguation menus whenever possible // Apply some ugly heuristics to avoid disambiguation menus whenever possible
if( collector.GetCount() > 1 && !m_skip_heuristics ) if( collector.GetCount() > 1 && !m_skip_heuristics )
{ {
@ -660,14 +662,9 @@ bool SELECTION_TOOL::selectMultiple()
// End drawing the selection box // End drawing the selection box
view->SetVisible( &area, false ); view->SetVisible( &area, false );
// Mark items within the selection box as selected std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> candidates;
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
// Filter the view items based on the selection box
BOX2I selectionBox = area.ViewBBox(); BOX2I selectionBox = area.ViewBBox();
view->Query( selectionBox, selectedItems ); // Get the list of selected items view->Query( selectionBox, candidates ); // Get the list of nearby items
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
int width = area.GetEnd().x - area.GetOrigin().x; int width = area.GetEnd().x - area.GetOrigin().x;
int height = area.GetEnd().y - area.GetOrigin().y; int height = area.GetEnd().y - area.GetOrigin().y;
@ -686,25 +683,34 @@ bool SELECTION_TOOL::selectMultiple()
selectionRect.Normalize(); selectionRect.Normalize();
for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) GENERAL_COLLECTOR collector;
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 ) || !itemPassesFilter( item ) ) if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
continue; collector.Append( item );
}
if( item->HitTest( selectionRect, windowSelection ) ) // Apply the stateful filter
filterCollectedItems( collector );
FilterCollectorForGroups( collector );
for( EDA_ITEM* i : collector )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( i );
if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
{ {
if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) ) unselect( item );
{ anySubtracted = true;
unselect( item ); }
anySubtracted = true; else
} {
else select( item );
{ anyAdded = true;
select( item );
anyAdded = true;
}
} }
} }
@ -1546,9 +1552,6 @@ bool SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem )
return false; return false;
} }
if( m_enteredGroup && !PCB_GROUP::WithinScope( aItem, m_enteredGroup ) )
return false;
return true; return true;
} }
@ -2548,8 +2551,6 @@ void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector,
aCollector.Transfer( item ); aCollector.Transfer( item );
} }
} }
FilterCollectorForGroups( aCollector );
} }