Schematic editor: allow box-selecting pins.

This commit is contained in:
Alex 2022-07-03 20:21:59 +03:00 committed by Mike Williams
parent d343d87b73
commit c6d9dcdad5
3 changed files with 63 additions and 14 deletions

View File

@ -305,10 +305,10 @@ VECTOR2I SCH_PIN::GetTransformedPosition() const
}
const EDA_RECT SCH_PIN::GetBoundingBox() const
const EDA_RECT SCH_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly ) const
{
TRANSFORM t = GetParentSymbol()->GetTransform();
EDA_RECT r = m_libPin->GetBoundingBox();
EDA_RECT r = m_libPin->GetBoundingBox( aIncludeInvisibles, aPinOnly );
r.RevertYAxis();
@ -331,6 +331,20 @@ bool SCH_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
}
bool SCH_PIN::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
EDA_RECT sel = aRect;
if( aAccuracy )
sel.Inflate( aAccuracy );
if( aContained )
return sel.Contains( GetBoundingBox( false, true ) );
return sel.Intersects( GetBoundingBox( false, true ) );
}
EDA_ITEM* SCH_PIN::Clone() const
{
return new SCH_PIN( *this );

View File

@ -81,8 +81,17 @@ public:
const VECTOR2I GetLocalPosition() const { return m_position; }
void SetPosition( const VECTOR2I& aPosition ) override { m_position = aPosition; }
const EDA_RECT GetBoundingBox() const override;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
/* Cannot use a default parameter here as it will not be compatible with the virtual. */
const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false ); }
/**
* @param aIncludeInvisibles - if false, do not include labels for invisible pins
* in the calculation.
*/
const EDA_RECT GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly = false ) const;
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
EDA_ITEM* Clone() const override;

View File

@ -1194,7 +1194,11 @@ bool EE_SELECTION_TOOL::selectMultiple()
{
bool cancelled = false; // Was the tool canceled while it was running?
m_multiple = true; // Multiple selection mode is active
KIGFX::VIEW* view = getView();
KIGFX::VIEW* view = getView();
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
if( !editFrame )
return cancelled;
KIGFX::PREVIEW::SELECTION_AREA area;
view->Add( &area );
@ -1251,21 +1255,43 @@ bool EE_SELECTION_TOOL::selectMultiple()
view->Query( area.ViewBBox(), nearbyViewItems );
// Build lists of nearby items and their children
std::vector<EDA_ITEM*> nearbyItems;
std::vector<EDA_ITEM*> nearbyChildren;
std::vector<EDA_ITEM*> flaggedItems;
std::unordered_set<EDA_ITEM*> nearbyItems;
std::vector<EDA_ITEM*> nearbyChildren;
std::vector<EDA_ITEM*> flaggedItems;
for( KIGFX::VIEW::LAYER_ITEM_PAIR& pair : nearbyViewItems )
{
EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( pair.first );
if( item )
{
item->ClearFlags( CANDIDATE );
nearbyItems.push_back( item );
}
if( !item )
continue;
if( SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item ) )
item->ClearFlags( CANDIDATE );
auto emplaceRet = nearbyItems.emplace( item );
if( !emplaceRet.second )
continue; // Item already in set
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item ) )
{
int unit = symbol->GetUnitSelection( &editFrame->Schematic().CurrentSheet() );
symbol->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
// Filter pins by unit
SCH_PIN* pin = dyn_cast<SCH_PIN*>( aChild );
if( pin && unit && pin->GetLibPin()->GetUnit()
&& ( pin->GetLibPin()->GetUnit() != unit ) )
{
return;
}
nearbyChildren.push_back( aChild );
} );
}
else if( SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item ) )
{
sch_item->RunOnChildren(
[&]( SCH_ITEM* aChild )