pcbnew: code improvements align tools
This commit is contained in:
parent
a2df82537b
commit
7683364bdb
|
@ -131,24 +131,24 @@ bool SortBottommostY( const std::pair<BOARD_ITEM*, EDA_RECT> left, const std::pa
|
||||||
return ( left.second.GetBottom() > right.second.GetBottom() );
|
return ( left.second.GetBottom() > right.second.GetBottom() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIGNMENT_SET GetBoundingBoxesV( const SELECTION& sel )
|
ALIGNMENT_RECTS GetBoundingBoxes( const SELECTION &sel )
|
||||||
{
|
{
|
||||||
const SELECTION& selection = sel;
|
const SELECTION& selection = sel;
|
||||||
|
|
||||||
ALIGNMENT_SET aSet;
|
ALIGNMENT_RECTS rects;
|
||||||
|
|
||||||
for( auto item : selection )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
if( item->Type() == PCB_MODULE_T )
|
if( item->Type() == PCB_MODULE_T )
|
||||||
{
|
{
|
||||||
aSet.push_back( std::make_pair( static_cast<BOARD_ITEM*>( item ), static_cast<MODULE*>( item )->GetFootprintRect() ) );
|
rects.emplace_back( std::make_pair( dynamic_cast<BOARD_ITEM*>( item ), dynamic_cast<MODULE*>( item )->GetFootprintRect() ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aSet.push_back( std::make_pair( static_cast<BOARD_ITEM*>( item ), static_cast<MODULE*>( item )->GetBoundingBox() ) );
|
rects.emplace_back( std::make_pair( dynamic_cast<BOARD_ITEM*>( item ), dynamic_cast<MODULE*>( item )->GetBoundingBox() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return aSet;
|
return rects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,16 +162,16 @@ 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 topmost point of selection - it will be the edge of alignment
|
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortTopmostY );
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortTopmostY );
|
|
||||||
|
|
||||||
int top = alignMap.begin()->second.GetY();
|
// after sorting, the fist item acts as the target for all others
|
||||||
|
const int targetTop = itemsToAlign.begin()->second.GetY();
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToAlign )
|
||||||
{
|
{
|
||||||
int difference = top - i.second.GetY();
|
int difference = targetTop - i.second.GetY();
|
||||||
i.first->Move( wxPoint( 0, difference ) );
|
i.first->Move( wxPoint( 0, difference ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,16 +191,16 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( 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 lowest point of selection - it will be the edge of alignment
|
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortBottommostY );
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortBottommostY );
|
|
||||||
|
|
||||||
int bottom = alignMap.begin()->second.GetBottom();
|
// after sorting, the fist item acts as the target for all others
|
||||||
|
const int targetBottom = itemsToAlign.begin()->second.GetBottom();
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToAlign )
|
||||||
{
|
{
|
||||||
int difference = bottom - i.second.GetBottom();
|
int difference = targetBottom - i.second.GetBottom();
|
||||||
i.first->Move( wxPoint( 0, difference ) );
|
i.first->Move( wxPoint( 0, difference ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,17 +235,16 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||||
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 leftmost point of selection - it will be the edge of alignment
|
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortLeftmostX );
|
||||||
|
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortLeftmostX );
|
// after sorting, the fist item acts as the target for all others
|
||||||
|
const int targetLeft = itemsToAlign.begin()->second.GetX();
|
||||||
int left = alignMap.begin()->second.GetX();
|
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToAlign )
|
||||||
{
|
{
|
||||||
int difference = left - i.second.GetX();
|
int difference = targetLeft - i.second.GetX();
|
||||||
i.first->Move( wxPoint( difference, 0 ) );
|
i.first->Move( wxPoint( difference, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,16 +279,16 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
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 rightmost point of selection - it will be the edge of alignment
|
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortRightmostX );
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortRightmostX );
|
|
||||||
|
|
||||||
int right = alignMap.begin()->second.GetRight();
|
// after sorting, the fist item acts as the target for all others
|
||||||
|
const int targetRight = itemsToAlign.begin()->second.GetRight();
|
||||||
|
|
||||||
// Move the selected items
|
// Move the selected items
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToAlign )
|
||||||
{
|
{
|
||||||
int difference = right - i.second.GetRight();
|
int difference = targetRight - i.second.GetRight();
|
||||||
i.first->Move( wxPoint( difference, 0 ) );
|
i.first->Move( wxPoint( difference, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,28 +308,28 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( 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 );
|
||||||
|
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
auto itemsToDistribute = GetBoundingBoxes( selection );
|
||||||
|
|
||||||
// find the last item by reverse sorting
|
// find the last item by reverse sorting
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortRightmostX );
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(), SortRightmostX );
|
||||||
const auto maxRight = alignMap.begin()->second.GetRight();
|
const auto maxRight = itemsToDistribute.begin()->second.GetRight();
|
||||||
const auto lastItem = alignMap.begin()->first;
|
const auto lastItem = itemsToDistribute.begin()->first;
|
||||||
|
|
||||||
// sort to get starting order
|
// sort to get starting order
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortLeftmostX );
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(), SortLeftmostX );
|
||||||
|
|
||||||
auto totalGap = maxRight - alignMap.begin()->second.GetX();
|
auto totalGap = maxRight - itemsToDistribute.begin()->second.GetX();
|
||||||
|
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToDistribute )
|
||||||
{
|
{
|
||||||
totalGap -= i.second.GetWidth();
|
totalGap -= i.second.GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto itemGap = totalGap / ( alignMap.size() - 1 );
|
const auto itemGap = totalGap / ( itemsToDistribute.size() - 1 );
|
||||||
|
|
||||||
auto targetX = alignMap.begin()->second.GetX();
|
auto targetX = itemsToDistribute.begin()->second.GetX();
|
||||||
|
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToDistribute )
|
||||||
{
|
{
|
||||||
// cover the corner case where the last item is wider than the previous item and gap
|
// cover the corner case where the last item is wider than the previous item and gap
|
||||||
if( lastItem == i.first )
|
if( lastItem == i.first )
|
||||||
|
@ -357,28 +356,29 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( 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 );
|
||||||
|
|
||||||
auto alignMap = GetBoundingBoxesV( selection );
|
auto itemsToDistribute = GetBoundingBoxes( selection );
|
||||||
|
|
||||||
// find the last item by reverse sorting
|
// find the last item by reverse sorting
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortBottommostY );
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(), SortBottommostY );
|
||||||
const auto maxBottom = alignMap.begin()->second.GetBottom();
|
const auto maxBottom = itemsToDistribute.begin()->second.GetBottom();
|
||||||
const auto lastItem = alignMap.begin()->first;
|
const auto lastItem = itemsToDistribute.begin()->first;
|
||||||
|
|
||||||
// sort to get starting order
|
// sort to get starting order
|
||||||
std::sort( alignMap.begin(), alignMap.end(), SortTopmostY );
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(), SortTopmostY );
|
||||||
|
|
||||||
auto totalGap = maxBottom - alignMap.begin()->second.GetY();
|
// determine the distance between the bottommost and topmost Y coordinates
|
||||||
|
auto totalGap = maxBottom - itemsToDistribute.begin()->second.GetY();
|
||||||
|
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToDistribute )
|
||||||
{
|
{
|
||||||
totalGap -= i.second.GetHeight();
|
totalGap -= i.second.GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto itemGap = totalGap / ( alignMap.size() - 1 );
|
const auto itemGap = totalGap / ( itemsToDistribute.size() - 1 );
|
||||||
|
|
||||||
auto targetY = alignMap.begin()->second.GetY();
|
auto targetY = itemsToDistribute.begin()->second.GetY();
|
||||||
|
|
||||||
for( auto& i : alignMap )
|
for( auto& i : itemsToDistribute )
|
||||||
{
|
{
|
||||||
// cover the corner case where the last item is wider than the previous item and gap
|
// cover the corner case where the last item is wider than the previous item and gap
|
||||||
if( lastItem == i.first )
|
if( lastItem == i.first )
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
#include <class_board_item.h>
|
#include <class_board_item.h>
|
||||||
|
|
||||||
typedef std::vector<std::pair<BOARD_ITEM*, EDA_RECT>> ALIGNMENT_SET;
|
typedef std::vector<std::pair<BOARD_ITEM*, EDA_RECT>> ALIGNMENT_RECTS;
|
||||||
|
|
||||||
class SELECTION_TOOL;
|
class SELECTION_TOOL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue