From 3556c4b8d6d5fe15e8b618acce3fb809a297bb8a Mon Sep 17 00:00:00 2001 From: Robbert Lagerweij Date: Wed, 31 Jan 2018 22:24:32 +0100 Subject: [PATCH] pcbnew: change alignment tools use footprint rect where appropriate Using footprint rects instead of the larger bounding box means that reference and value texts no longer influence the positioning of the footprint in unexpected ways. Treatment of non-module items is unchanged. --- pcbnew/tools/placement_tool.cpp | 125 +++++++++++++++++--------------- pcbnew/tools/placement_tool.h | 3 + 2 files changed, 70 insertions(+), 58 deletions(-) diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index 76fe66efec..ae716e4330 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -21,7 +21,7 @@ * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - +#include "tool/selection.h" #include "placement_tool.h" #include "pcb_actions.h" #include "selection_tool.h" @@ -111,6 +111,47 @@ bool ALIGN_DISTRIBUTE_TOOL::Init() } +bool SortLeftmostX( const std::pair left, const std::pair right) +{ + return ( left.second.GetX() < right.second.GetX() ); +} + +bool SortRightmostX( const std::pair left, const std::pair right) +{ + return ( left.second.GetRight() > right.second.GetRight() ); +} + +bool SortTopmostY( const std::pair left, const std::pair right) +{ + return ( left.second.GetY() < right.second.GetY() ); +} + +bool SortBottommostY( const std::pair left, const std::pair right) +{ + return ( left.second.GetBottom() > right.second.GetBottom() ); +} + +ALIGNMENT_SET GetBoundingBoxesV( const SELECTION& sel ) +{ + const SELECTION& selection = sel; + + ALIGNMENT_SET aSet; + + for( auto item : selection ) + { + if( item->Type() == PCB_MODULE_T ) + { + aSet.push_back( std::make_pair( static_cast( item ), static_cast( item )->GetFootprintRect() ) ); + } + else + { + aSet.push_back( std::make_pair( static_cast( item ), static_cast( item )->GetBoundingBox() ) ); + } + } + return aSet; +} + + int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); @@ -121,25 +162,17 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent ) BOARD_COMMIT commit( getEditFrame() ); commit.StageItems( selection, CHT_MODIFY ); - // Compute the highest point of selection - it will be the edge of alignment - int top = selection.Front()->GetBoundingBox().GetY(); + // Compute the topmost point of selection - it will be the edge of alignment + auto alignMap = GetBoundingBoxesV( selection ); + std::sort( alignMap.begin(), alignMap.end(), SortTopmostY ); - for( int i = 1; i < selection.Size(); ++i ) - { - int currentTop = selection[i]->GetBoundingBox().GetY(); - - if( top > currentTop ) // Y decreases when going up - top = currentTop; - } + int top = alignMap.begin()->second.GetY(); // Move the selected items - for( auto i : selection ) + for( auto& i : alignMap ) { - auto item = static_cast( i ); - - int difference = top - item->GetBoundingBox().GetY(); - - item->Move( wxPoint( 0, difference ) ); + int difference = top - i.second.GetY(); + i.first->Move( wxPoint( 0, difference ) ); } commit.Push( _( "Align to top" ) ); @@ -159,24 +192,16 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent ) commit.StageItems( selection, CHT_MODIFY ); // Compute the lowest point of selection - it will be the edge of alignment - int bottom = selection.Front()->GetBoundingBox().GetBottom(); + auto alignMap = GetBoundingBoxesV( selection ); + std::sort( alignMap.begin(), alignMap.end(), SortBottommostY ); - for( int i = 1; i < selection.Size(); ++i ) - { - int currentBottom = selection[i]->GetBoundingBox().GetBottom(); - - if( bottom < currentBottom ) // Y increases when going down - bottom = currentBottom; - } + int bottom = alignMap.begin()->second.GetBottom(); // Move the selected items - for( auto i : selection ) + for( auto& i : alignMap ) { - auto item = static_cast( i ); - - int difference = bottom - item->GetBoundingBox().GetBottom(); - - item->Move( wxPoint( 0, difference ) ); + int difference = bottom - i.second.GetBottom(); + i.first->Move( wxPoint( 0, difference ) ); } commit.Push( _( "Align to bottom" ) ); @@ -211,24 +236,17 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft() commit.StageItems( selection, CHT_MODIFY ); // Compute the leftmost point of selection - it will be the edge of alignment - int left = selection.Front()->GetBoundingBox().GetX(); + auto alignMap = GetBoundingBoxesV( selection ); - for( int i = 1; i < selection.Size(); ++i ) - { - int currentLeft = selection[i]->GetBoundingBox().GetX(); + std::sort( alignMap.begin(), alignMap.end(), SortLeftmostX ); - if( left > currentLeft ) // X decreases when going left - left = currentLeft; - } + int left = alignMap.begin()->second.GetX(); // Move the selected items - for( auto i : selection ) + for( auto& i : alignMap ) { - auto item = static_cast( i ); - - int difference = left - item->GetBoundingBox().GetX(); - - item->Move( wxPoint( difference, 0 ) ); + int difference = left - i.second.GetX(); + i.first->Move( wxPoint( difference, 0 ) ); } commit.Push( _( "Align to left" ) ); @@ -263,24 +281,16 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight() commit.StageItems( selection, CHT_MODIFY ); // Compute the rightmost point of selection - it will be the edge of alignment - int right = selection.Front()->GetBoundingBox().GetRight(); + auto alignMap = GetBoundingBoxesV( selection ); + std::sort( alignMap.begin(), alignMap.end(), SortRightmostX ); - for( int i = 1; i < selection.Size(); ++i ) - { - int currentRight = selection[i]->GetBoundingBox().GetRight(); - - if( right < currentRight ) // X increases when going right - right = currentRight; - } + int right = alignMap.begin()->second.GetRight(); // Move the selected items - for( auto i : selection ) + for( auto& i : alignMap ) { - auto item = static_cast( i ); - - int difference = right - item->GetBoundingBox().GetRight(); - - item->Move( wxPoint( difference, 0 ) ); + int difference = right - i.second.GetRight(); + i.first->Move( wxPoint( difference, 0 ) ); } commit.Push( _( "Align to right" ) ); @@ -288,7 +298,6 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight() return 0; } - static bool compareX( const BOARD_ITEM* aA, const BOARD_ITEM* aB ) { return aA->GetBoundingBox().Centre().x < aB->GetBoundingBox().Centre().x; diff --git a/pcbnew/tools/placement_tool.h b/pcbnew/tools/placement_tool.h index daf6b8981f..d5388b6a50 100644 --- a/pcbnew/tools/placement_tool.h +++ b/pcbnew/tools/placement_tool.h @@ -26,6 +26,9 @@ #define ALIGN_DISTRIBUTE_TOOL_H_ #include +#include + +typedef std::vector> ALIGNMENT_SET; class SELECTION_TOOL;