Account for groups in undo of Position Relative To.
Also fixes a bug were pads weren't correctly being found for anchoring
the selection before the Position Relative To.
Fixes https://gitlab.com/kicad/code/kicad/issues/11793
(cherry picked from commit 1e68c353f1
)
This commit is contained in:
parent
9bce3c243a
commit
9d0d45450b
|
@ -2678,7 +2678,7 @@ void PCB_SELECTION_TOOL::FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollec
|
||||||
std::unordered_set<BOARD_ITEM*> toAdd;
|
std::unordered_set<BOARD_ITEM*> toAdd;
|
||||||
|
|
||||||
// Set TEMP_SELECTED on all parents which are included in the GENERAL_COLLECTOR. This
|
// Set TEMP_SELECTED on all parents which are included in the GENERAL_COLLECTOR. This
|
||||||
// algorithm is O3n, whereas checking for the parent inclusion could potentially be On^2.
|
// algorithm is O(3n), whereas checking for the parent inclusion could potentially be O(n^2).
|
||||||
for( int j = 0; j < aCollector.GetCount(); j++ )
|
for( int j = 0; j < aCollector.GetCount(); j++ )
|
||||||
{
|
{
|
||||||
if( aCollector[j]->GetParent() )
|
if( aCollector[j]->GetParent() )
|
||||||
|
|
|
@ -25,18 +25,18 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
#include "position_relative_tool.h"
|
#include <tools/position_relative_tool.h>
|
||||||
#include "pcb_actions.h"
|
#include <tools/pcb_actions.h>
|
||||||
#include "pcb_selection_tool.h"
|
#include <tools/pcb_selection_tool.h>
|
||||||
#include "edit_tool.h"
|
#include <tools/pcb_picker_tool.h>
|
||||||
#include "pcb_picker_tool.h"
|
|
||||||
#include <dialogs/dialog_position_relative.h>
|
#include <dialogs/dialog_position_relative.h>
|
||||||
#include <status_popup.h>
|
#include <status_popup.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
#include <bitmaps.h>
|
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <collectors.h>
|
#include <collectors.h>
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
|
#include <footprint.h>
|
||||||
|
#include <pcb_group.h>
|
||||||
|
|
||||||
|
|
||||||
POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() :
|
POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() :
|
||||||
|
@ -64,44 +64,16 @@ bool POSITION_RELATIVE_TOOL::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Clean up this global once TOOL_EVENT supports std::functions as parameters
|
|
||||||
BOARD_ITEM* g_PositionRelativePadAnchor;
|
|
||||||
|
|
||||||
|
|
||||||
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
|
|
||||||
g_PositionRelativePadAnchor = nullptr;
|
|
||||||
|
|
||||||
const auto& selection = m_selectionTool->RequestSelection(
|
const auto& selection = m_selectionTool->RequestSelection(
|
||||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
||||||
{
|
{
|
||||||
std::set<BOARD_ITEM*> to_add;
|
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||||
|
sTool->FilterCollectorForMarkers( aCollector );
|
||||||
// Iterate from the back so we don't have to worry about removals.
|
sTool->FilterCollectorForFreePads( aCollector );
|
||||||
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = aCollector[i];
|
|
||||||
|
|
||||||
if( item->Type() == PCB_MARKER_T )
|
|
||||||
aCollector.Remove( item );
|
|
||||||
|
|
||||||
/// Locked pads do not get moved independently of the footprint
|
|
||||||
if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T && item->IsLocked()
|
|
||||||
&& !item->GetParent()->IsLocked() )
|
|
||||||
{
|
|
||||||
if( !aCollector.HasItem( item->GetParent() ) )
|
|
||||||
to_add.insert( item->GetParent() );
|
|
||||||
|
|
||||||
g_PositionRelativePadAnchor = item;
|
|
||||||
|
|
||||||
aCollector.Remove( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( BOARD_ITEM* item : to_add )
|
|
||||||
aCollector.Append( item );
|
|
||||||
},
|
},
|
||||||
!m_isFootprintEditor /* prompt user regarding locked items */ );
|
!m_isFootprintEditor /* prompt user regarding locked items */ );
|
||||||
|
|
||||||
|
@ -110,8 +82,30 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
m_selection = selection;
|
m_selection = selection;
|
||||||
|
|
||||||
if( g_PositionRelativePadAnchor )
|
static KICAD_T padsOnly[] = { PCB_PAD_T, EOT };
|
||||||
m_selectionAnchor = static_cast<PAD*>( g_PositionRelativePadAnchor )->GetPosition();
|
PCB_TYPE_COLLECTOR collector;
|
||||||
|
collector.Collect( static_cast<BOARD_ITEM*>( m_selection.GetTopLeftItem() ), padsOnly );
|
||||||
|
|
||||||
|
if( collector.GetCount() == 0 )
|
||||||
|
{
|
||||||
|
for( FOOTPRINT* footprint : editFrame->GetBoard()->Footprints() )
|
||||||
|
{
|
||||||
|
for( PAD* pad : footprint->Pads() )
|
||||||
|
{
|
||||||
|
if( pad->IsSelected() )
|
||||||
|
collector.Append( pad );
|
||||||
|
|
||||||
|
if( collector.GetCount() > 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( collector.GetCount() > 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( collector.GetCount() > 0 )
|
||||||
|
m_selectionAnchor = collector[0]->GetPosition();
|
||||||
else
|
else
|
||||||
m_selectionAnchor = m_selection.GetTopLeftItem()->GetPosition();
|
m_selectionAnchor = m_selection.GetTopLeftItem()->GetPosition();
|
||||||
|
|
||||||
|
@ -138,13 +132,24 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( const wxPoint& aPosAnchor
|
||||||
{
|
{
|
||||||
wxPoint aggregateTranslation = aPosAnchor + aTranslation - GetSelectionAnchorPosition();
|
wxPoint aggregateTranslation = aPosAnchor + aTranslation - GetSelectionAnchorPosition();
|
||||||
|
|
||||||
for( auto item : m_selection )
|
for( EDA_ITEM* item : m_selection )
|
||||||
{
|
{
|
||||||
// Don't move a pad by itself unless editing the footprint
|
// Don't move a pad by itself unless editing the footprint
|
||||||
if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB_EDITOR ) )
|
if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB_EDITOR ) )
|
||||||
item = item->GetParent();
|
item = item->GetParent();
|
||||||
|
|
||||||
m_commit->Modify( item );
|
m_commit->Modify( item );
|
||||||
|
|
||||||
|
// If moving a group, record position of all the descendants for undo
|
||||||
|
if( item->Type() == PCB_GROUP_T )
|
||||||
|
{
|
||||||
|
PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
|
||||||
|
group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
|
||||||
|
{
|
||||||
|
m_commit->Modify( bItem );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
|
static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue