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.
This commit is contained in:
parent
936a8c1a7e
commit
3556c4b8d6
|
@ -21,7 +21,7 @@
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
#include "tool/selection.h"
|
||||||
#include "placement_tool.h"
|
#include "placement_tool.h"
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
|
@ -111,6 +111,47 @@ bool ALIGN_DISTRIBUTE_TOOL::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SortLeftmostX( const std::pair<BOARD_ITEM*, EDA_RECT> left, const std::pair<BOARD_ITEM*, EDA_RECT> right)
|
||||||
|
{
|
||||||
|
return ( left.second.GetX() < right.second.GetX() );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortRightmostX( const std::pair<BOARD_ITEM*, EDA_RECT> left, const std::pair<BOARD_ITEM*, EDA_RECT> right)
|
||||||
|
{
|
||||||
|
return ( left.second.GetRight() > right.second.GetRight() );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortTopmostY( const std::pair<BOARD_ITEM*, EDA_RECT> left, const std::pair<BOARD_ITEM*, EDA_RECT> right)
|
||||||
|
{
|
||||||
|
return ( left.second.GetY() < right.second.GetY() );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SortBottommostY( const std::pair<BOARD_ITEM*, EDA_RECT> left, const std::pair<BOARD_ITEM*, EDA_RECT> 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<BOARD_ITEM*>( item ), static_cast<MODULE*>( item )->GetFootprintRect() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aSet.push_back( std::make_pair( static_cast<BOARD_ITEM*>( item ), static_cast<MODULE*>( item )->GetBoundingBox() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const SELECTION& selection = m_selectionTool->GetSelection();
|
const SELECTION& selection = m_selectionTool->GetSelection();
|
||||||
|
@ -121,25 +162,17 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
|
||||||
commit.StageItems( selection, CHT_MODIFY );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the highest point of selection - it will be the edge of alignment
|
// Compute the topmost point of selection - it will be the edge of alignment
|
||||||
int top = selection.Front()->GetBoundingBox().GetY();
|
auto alignMap = GetBoundingBoxesV( selection );
|
||||||
|
std::sort( alignMap.begin(), alignMap.end(), SortTopmostY );
|
||||||
|
|
||||||
for( int i = 1; i < selection.Size(); ++i )
|
int top = alignMap.begin()->second.GetY();
|
||||||
{
|
|
||||||
int currentTop = selection[i]->GetBoundingBox().GetY();
|
|
||||||
|
|
||||||
if( top > currentTop ) // Y decreases when going up
|
|
||||||
top = currentTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto i : selection )
|
for( auto& i : alignMap )
|
||||||
{
|
{
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
int difference = top - i.second.GetY();
|
||||||
|
i.first->Move( wxPoint( 0, difference ) );
|
||||||
int difference = top - item->GetBoundingBox().GetY();
|
|
||||||
|
|
||||||
item->Move( wxPoint( 0, difference ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to top" ) );
|
commit.Push( _( "Align to top" ) );
|
||||||
|
@ -159,24 +192,16 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||||
commit.StageItems( selection, CHT_MODIFY );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the lowest point of selection - it will be the edge of alignment
|
// 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 bottom = alignMap.begin()->second.GetBottom();
|
||||||
{
|
|
||||||
int currentBottom = selection[i]->GetBoundingBox().GetBottom();
|
|
||||||
|
|
||||||
if( bottom < currentBottom ) // Y increases when going down
|
|
||||||
bottom = currentBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto i : selection )
|
for( auto& i : alignMap )
|
||||||
{
|
{
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
int difference = bottom - i.second.GetBottom();
|
||||||
|
i.first->Move( wxPoint( 0, difference ) );
|
||||||
int difference = bottom - item->GetBoundingBox().GetBottom();
|
|
||||||
|
|
||||||
item->Move( wxPoint( 0, difference ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to bottom" ) );
|
commit.Push( _( "Align to bottom" ) );
|
||||||
|
@ -211,24 +236,17 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||||
commit.StageItems( selection, CHT_MODIFY );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the leftmost point of selection - it will be the edge of alignment
|
// 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 )
|
std::sort( alignMap.begin(), alignMap.end(), SortLeftmostX );
|
||||||
{
|
|
||||||
int currentLeft = selection[i]->GetBoundingBox().GetX();
|
|
||||||
|
|
||||||
if( left > currentLeft ) // X decreases when going left
|
int left = alignMap.begin()->second.GetX();
|
||||||
left = currentLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto i : selection )
|
for( auto& i : alignMap )
|
||||||
{
|
{
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
int difference = left - i.second.GetX();
|
||||||
|
i.first->Move( wxPoint( difference, 0 ) );
|
||||||
int difference = left - item->GetBoundingBox().GetX();
|
|
||||||
|
|
||||||
item->Move( wxPoint( difference, 0 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to left" ) );
|
commit.Push( _( "Align to left" ) );
|
||||||
|
@ -263,24 +281,16 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
commit.StageItems( selection, CHT_MODIFY );
|
commit.StageItems( selection, CHT_MODIFY );
|
||||||
|
|
||||||
// Compute the rightmost point of selection - it will be the edge of alignment
|
// 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 right = alignMap.begin()->second.GetRight();
|
||||||
{
|
|
||||||
int currentRight = selection[i]->GetBoundingBox().GetRight();
|
|
||||||
|
|
||||||
if( right < currentRight ) // X increases when going right
|
|
||||||
right = currentRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto i : selection )
|
for( auto& i : alignMap )
|
||||||
{
|
{
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
int difference = right - i.second.GetRight();
|
||||||
|
i.first->Move( wxPoint( difference, 0 ) );
|
||||||
int difference = right - item->GetBoundingBox().GetRight();
|
|
||||||
|
|
||||||
item->Move( wxPoint( difference, 0 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to right" ) );
|
commit.Push( _( "Align to right" ) );
|
||||||
|
@ -288,7 +298,6 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool compareX( const BOARD_ITEM* aA, const BOARD_ITEM* aB )
|
static bool compareX( const BOARD_ITEM* aA, const BOARD_ITEM* aB )
|
||||||
{
|
{
|
||||||
return aA->GetBoundingBox().Centre().x < aB->GetBoundingBox().Centre().x;
|
return aA->GetBoundingBox().Centre().x < aB->GetBoundingBox().Centre().x;
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#define ALIGN_DISTRIBUTE_TOOL_H_
|
#define ALIGN_DISTRIBUTE_TOOL_H_
|
||||||
|
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
|
#include <class_board_item.h>
|
||||||
|
|
||||||
|
typedef std::vector<std::pair<BOARD_ITEM*, EDA_RECT>> ALIGNMENT_SET;
|
||||||
|
|
||||||
class SELECTION_TOOL;
|
class SELECTION_TOOL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue