From a0c54951db841483e14ce2c9528528bf69ab60e9 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 14 Aug 2020 19:45:56 -0700 Subject: [PATCH] pcbnew: Clean up group move SetPosition() only changes the base position of tracks, we need to use Move() to move the whole element. This also cleans up white space and group handling in ratsnest Fixes https://gitlab.com/kicad/code/kicad/issues/5188 --- pcbnew/class_pcb_group.cpp | 43 ++++++++++++++++------------ pcbnew/tools/pcb_inspection_tool.cpp | 12 +++++++- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/pcbnew/class_pcb_group.cpp b/pcbnew/class_pcb_group.cpp index 688032fbaa..3b5feb5b8e 100644 --- a/pcbnew/class_pcb_group.cpp +++ b/pcbnew/class_pcb_group.cpp @@ -37,26 +37,27 @@ bool PCB_GROUP::AddItem( BOARD_ITEM* item ) return m_items.insert( item ).second; } + bool PCB_GROUP::RemoveItem( const BOARD_ITEM* item ) { return m_items.erase( const_cast( item ) ) == 1; } + wxPoint PCB_GROUP::GetPosition() const { return GetBoundingBox().Centre(); } + void PCB_GROUP::SetPosition( const wxPoint& newpos ) { wxPoint delta = newpos - GetPosition(); - for( auto member : m_items ) - { - member->SetPosition( member->GetPosition() + delta ); - } + Move( delta ); } + EDA_ITEM* PCB_GROUP::Clone() const { // Use copy constructor to get the same uuid and other fields @@ -64,6 +65,7 @@ EDA_ITEM* PCB_GROUP::Clone() const return newGroup; } + PCB_GROUP* PCB_GROUP::DeepClone() const { // Use copy constructor to get the same uuid and other fields @@ -114,19 +116,6 @@ void PCB_GROUP::SwapData( BOARD_ITEM* aImage ) std::swap( *( (PCB_GROUP*) this ), *( (PCB_GROUP*) aImage ) ); } -#if 0 -void PCB_GROUP::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, - PCB_LAYER_ID aLayer, int aClearanceValue, - int aError = ARC_LOW_DEF, - bool ignoreLineWidth = false ) const -{ -} -const BOX2I PCB_GROUP::ViewBBox() const -{ - return GetBoundingBox(); -} - -#endif bool PCB_GROUP::HitTest( const wxPoint& aPosition, int aAccuracy ) const { @@ -134,6 +123,7 @@ bool PCB_GROUP::HitTest( const wxPoint& aPosition, int aAccuracy ) const return rect.Inflate( aAccuracy ).Contains( aPosition ); } + bool PCB_GROUP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT arect = aRect; @@ -160,6 +150,7 @@ bool PCB_GROUP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) } } + const EDA_RECT PCB_GROUP::GetBoundingBox() const { EDA_RECT area; @@ -182,6 +173,7 @@ const EDA_RECT PCB_GROUP::GetBoundingBox() const return area; } + SEARCH_RESULT PCB_GROUP::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) { for( const KICAD_T* stype = scanTypes; *stype != EOT; ++stype ) @@ -197,6 +189,7 @@ SEARCH_RESULT PCB_GROUP::Visit( INSPECTOR inspector, void* testData, const KICAD return SEARCH_RESULT::CONTINUE; } + LSET PCB_GROUP::GetLayerSet() const { LSET aSet; @@ -208,6 +201,7 @@ LSET PCB_GROUP::GetLayerSet() const return aSet; } + void PCB_GROUP::ViewGetLayers( int aLayers[], int& aCount ) const { // What layer to put bounding box on? change in class_pcb_group.cpp @@ -229,6 +223,7 @@ void PCB_GROUP::ViewGetLayers( int aLayers[], int& aCount ) const aLayers[i++] = layer; } + unsigned int PCB_GROUP::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const { if( aView->IsLayerVisible( LAYER_ANCHOR ) ) @@ -237,12 +232,16 @@ unsigned int PCB_GROUP::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const return std::numeric_limits::max(); } + void PCB_GROUP::Move( const wxPoint& aMoveVector ) { - wxPoint newpos = GetPosition() + aMoveVector; - SetPosition( newpos ); + for( auto member : m_items ) + { + member->Move( aMoveVector ); + } } + void PCB_GROUP::Rotate( const wxPoint& aRotCentre, double aAngle ) { for( BOARD_ITEM* item : m_items ) @@ -251,6 +250,7 @@ void PCB_GROUP::Rotate( const wxPoint& aRotCentre, double aAngle ) } } + void PCB_GROUP::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) { for( BOARD_ITEM* item : m_items ) @@ -259,6 +259,7 @@ void PCB_GROUP::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) } } + wxString PCB_GROUP::GetSelectMenuText( EDA_UNITS aUnits ) const { if( m_name.empty() ) @@ -268,11 +269,13 @@ wxString PCB_GROUP::GetSelectMenuText( EDA_UNITS aUnits ) const return wxString::Format( _( "Group \"%s\" with %ld members" ), m_name, m_items.size() ); } + BITMAP_DEF PCB_GROUP::GetMenuImage() const { return module_xpm; } + void PCB_GROUP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { aList.emplace_back( _( "Group" ), m_name.empty() ? _( "Anonymous" ) : @@ -280,6 +283,7 @@ void PCB_GROUP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aFunction ) { try @@ -293,6 +297,7 @@ void PCB_GROUP::RunOnChildren( const std::function& aFuncti } } + void PCB_GROUP::RunOnDescendants( const std::function& aFunction ) { try diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index cdaf7dda28..bae93b21d9 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -462,9 +463,12 @@ void PCB_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta ) SELECTION& selection = selectionTool->GetSelection(); std::shared_ptr connectivity = board()->GetConnectivity(); std::vector items; + std::deque queued_items( selection.begin(), selection.end() ); - for( EDA_ITEM* item : selection ) + for( std::size_t i = 0; i < queued_items.size(); ++i ) { + BOARD_ITEM* item = static_cast( queued_items[i] ); + if( item->Type() == PCB_MODULE_T ) { for( auto pad : static_cast( item )->Pads() ) @@ -473,6 +477,12 @@ void PCB_INSPECTION_TOOL::calculateSelectionRatsnest( const VECTOR2I& aDelta ) items.push_back( pad ); } } + else if( item->Type() == PCB_GROUP_T ) + { + PCB_GROUP *group = static_cast( item ); + group->RunOnDescendants( [ &queued_items ]( BOARD_ITEM *aItem ) + { queued_items.push_back( aItem );} ); + } else if( BOARD_CONNECTED_ITEM* boardItem = dyn_cast( item ) ) { if( boardItem->GetLocalRatsnestVisible() || displayOptions().m_ShowModuleRatsnest )