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
{
EDA_RECT rect = GetBoundingBox();
return rect.Inflate( aAccuracy ).Contains( aPosition );
// Groups are selected by promoting a selection of one of their children
return false;
}
bool PCB_GROUP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
EDA_RECT arect = aRect;
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
// Groups are selected by promoting a selection of one of their children
return false;
}

View File

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