Integrate move individually into move algo so other commands don't choke.
Also adds commands to cancel and finish move individually. Fixes https://gitlab.com/kicad/code/kicad/issues/12750 Fixes https://gitlab.com/kicad/code/kicad/issues/12749
This commit is contained in:
parent
365674dfdf
commit
7089e99f4b
|
@ -437,9 +437,14 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
|||
}
|
||||
|
||||
if( changed && copy )
|
||||
{
|
||||
m_commit.Modified( aPcbFootprint, copy );
|
||||
}
|
||||
else
|
||||
{
|
||||
copy->SetParentGroup( nullptr );
|
||||
delete copy;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -621,9 +626,14 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( FOOTPRINT* aFootprint
|
|||
}
|
||||
|
||||
if( changed && copy )
|
||||
{
|
||||
m_commit.Modified( aFootprint, copy );
|
||||
}
|
||||
else
|
||||
{
|
||||
copy->SetParentGroup( nullptr );
|
||||
delete copy;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2260,7 +2260,7 @@ void EDIT_TOOL::setTransitions()
|
|||
{
|
||||
Go( &EDIT_TOOL::GetAndPlace, PCB_ACTIONS::getAndPlace.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.MakeEvent() );
|
||||
Go( &EDIT_TOOL::MoveIndividually, PCB_ACTIONS::moveIndividually.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Move, PCB_ACTIONS::moveIndividually.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Drag, PCB_ACTIONS::drag45Degree.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Drag, PCB_ACTIONS::dragFreeAngle.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.MakeEvent() );
|
||||
|
@ -2270,7 +2270,7 @@ void EDIT_TOOL::setTransitions()
|
|||
Go( &EDIT_TOOL::Remove, PCB_ACTIONS::deleteFull.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Properties, PCB_ACTIONS::properties.MakeEvent() );
|
||||
Go( &EDIT_TOOL::MoveExact, PCB_ACTIONS::moveExact.MakeEvent() );
|
||||
Go( &EDIT_TOOL::MoveWithReference, PCB_ACTIONS::moveWithReference.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Move, PCB_ACTIONS::moveWithReference.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Duplicate, PCB_ACTIONS::duplicateIncrement.MakeEvent() );
|
||||
Go( &EDIT_TOOL::CreateArray, PCB_ACTIONS::createArray.MakeEvent() );
|
||||
|
|
|
@ -80,11 +80,6 @@ public:
|
|||
*/
|
||||
int Move( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Move a selection of items one-at-a-time.
|
||||
*/
|
||||
int MoveIndividually( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Invoke the PNS router to drag tracks or do an offline resizing of an arc track
|
||||
* if a single arc track is selected.
|
||||
|
@ -150,11 +145,6 @@ public:
|
|||
*/
|
||||
int MoveExact( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Move an item but with a reference point selected first
|
||||
*/
|
||||
int MoveWithReference( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Create an array of the selected items, invoking the array editor dialog to set the options.
|
||||
*/
|
||||
|
@ -197,7 +187,7 @@ private:
|
|||
bool invokeInlineRouter( int aDragMode );
|
||||
bool isRouterActive() const;
|
||||
|
||||
int doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference = false );
|
||||
int doMoveSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
VECTOR2I getSafeMovement( const VECTOR2I& aMovement, const BOX2I& aSourceBBox,
|
||||
const VECTOR2D& aBBoxOffset );
|
||||
|
|
|
@ -241,46 +241,6 @@ int EDIT_TOOL::Move( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::MoveIndividually( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
|
||||
if( isRouterActive() )
|
||||
{
|
||||
wxBell();
|
||||
return 0;
|
||||
}
|
||||
|
||||
EDA_ITEMS sortedItems = selTool->GetSelection().GetItemsSortedBySelectionOrder();
|
||||
|
||||
if( sortedItems.size() == 0 )
|
||||
return 0;
|
||||
|
||||
for( EDA_ITEM* item : sortedItems )
|
||||
{
|
||||
selTool->ClearSelection();
|
||||
selTool->AddItemToSel( item );
|
||||
doMoveSelection( aEvent );
|
||||
}
|
||||
|
||||
selTool->AddItemsToSel( &sortedItems );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::MoveWithReference( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( isRouterActive() )
|
||||
{
|
||||
wxBell();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return doMoveSelection( aEvent, true );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I EDIT_TOOL::getSafeMovement( const VECTOR2I& aMovement, const BOX2I& aSourceBBox,
|
||||
const VECTOR2D& aBBoxOffset )
|
||||
{
|
||||
|
@ -315,13 +275,19 @@ VECTOR2I EDIT_TOOL::getSafeMovement( const VECTOR2I& aMovement, const BOX2I& aSo
|
|||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||
int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
bool moveWithReference = aEvent.IsAction( &PCB_ACTIONS::moveWithReference );
|
||||
bool moveIndividually = aEvent.IsAction( &PCB_ACTIONS::moveIndividually );
|
||||
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
PCBNEW_SETTINGS* cfg = editFrame->GetPcbNewSettings();
|
||||
BOARD* board = editFrame->GetBoard();
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
VECTOR2I originalCursorPos = controls->GetCursorPosition();
|
||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
||||
wxString status;
|
||||
size_t itemIdx = 0;
|
||||
|
||||
// Be sure that there is at least one item that we can modify. If nothing was selected before,
|
||||
// try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
|
||||
|
@ -368,16 +334,6 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
controls->SetAutoPan( true );
|
||||
controls->ForceCursorPosition( false );
|
||||
|
||||
if( aPickReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
|
||||
pickedReferencePoint ) )
|
||||
{
|
||||
if( is_hover )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
editFrame->PopTool( aEvent );
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto displayConstraintsMessage =
|
||||
[editFrame]( bool constrained )
|
||||
{
|
||||
|
@ -385,6 +341,32 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
: wxT( "" ) );
|
||||
};
|
||||
|
||||
auto updateStatusPopup =
|
||||
[&]( EDA_ITEM* item, size_t ii, size_t count )
|
||||
{
|
||||
wxString status = _( "Click to place %s (item %ld of %ld)\n"
|
||||
"Press <esc> to cancel all; double-click to finish" );
|
||||
wxString msg;
|
||||
|
||||
if( item->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
|
||||
msg = fp->GetReference();
|
||||
}
|
||||
else if( item->Type() == PCB_PAD_T )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( item );
|
||||
FOOTPRINT* fp = static_cast<FOOTPRINT*>( pad->GetParentFootprint() );
|
||||
msg = wxString::Format( _( "%s pad %s" ), fp->GetReference(), pad->GetNumber() );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = item->GetTypeDesc().Lower();
|
||||
}
|
||||
|
||||
statusPopup.SetText( wxString::Format( status, msg, ii, count ) );
|
||||
};
|
||||
|
||||
std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
|
||||
std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
|
||||
|
||||
|
@ -412,6 +394,35 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
}
|
||||
}
|
||||
|
||||
if( moveWithReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
|
||||
pickedReferencePoint ) )
|
||||
{
|
||||
if( is_hover )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
editFrame->PopTool( aEvent );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( moveIndividually )
|
||||
{
|
||||
orig_items.clear();
|
||||
|
||||
for( EDA_ITEM* item : selection.GetItemsSortedBySelectionOrder() )
|
||||
orig_items.push_back( static_cast<BOARD_ITEM*>( item ) );
|
||||
|
||||
updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() );
|
||||
statusPopup.Popup();
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
|
||||
canvas()->SetStatusPopup( statusPopup.GetPanel() );
|
||||
|
||||
m_selectionTool->ClearSelection();
|
||||
m_selectionTool->AddItemToSel( orig_items[ itemIdx ] );
|
||||
|
||||
sel_items.clear();
|
||||
sel_items.push_back( orig_items[ itemIdx ] );
|
||||
}
|
||||
|
||||
bool restore_state = false;
|
||||
VECTOR2I originalPos;
|
||||
VECTOR2I totalMovement;
|
||||
|
@ -624,22 +635,18 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
}
|
||||
else
|
||||
{
|
||||
std::vector<BOARD_ITEM*> items;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
for( BOARD_ITEM* item : sel_items )
|
||||
{
|
||||
items.push_back( static_cast<BOARD_ITEM*>( item ) );
|
||||
|
||||
if( showCourtyardConflicts && item->Type() == PCB_FOOTPRINT_T )
|
||||
drc_on_move->m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
|
||||
}
|
||||
|
||||
m_cursor = grid.BestDragOrigin( originalCursorPos, items,
|
||||
m_cursor = grid.BestDragOrigin( originalCursorPos, sel_items,
|
||||
&m_selectionTool->GetFilter() );
|
||||
|
||||
// Set the current cursor position to the first dragged item origin, so the
|
||||
// movement vector could be computed later
|
||||
if( aPickReference )
|
||||
if( moveWithReference )
|
||||
{
|
||||
selection.SetReferencePoint( pickedReferencePoint );
|
||||
controls->ForceCursorPosition( true, pickedReferencePoint );
|
||||
|
@ -668,6 +675,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||
}
|
||||
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false, new VECTOR2I( movement ) );
|
||||
}
|
||||
else if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
|
@ -723,7 +732,31 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
eatFirstMouseUp = false;
|
||||
continue;
|
||||
}
|
||||
else if( moveIndividually && m_dragging )
|
||||
{
|
||||
if( ++itemIdx < orig_items.size() )
|
||||
{
|
||||
m_selectionTool->ClearSelection();
|
||||
m_selectionTool->AddItemToSel( orig_items[ itemIdx ] );
|
||||
selection.ClearReferencePoint();
|
||||
|
||||
sel_items.clear();
|
||||
sel_items.push_back( orig_items[ itemIdx ] );
|
||||
updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() );
|
||||
|
||||
// Pick up new item
|
||||
m_dragging = false;
|
||||
controls->ForceCursorPosition( false );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::move );
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break; // finish
|
||||
}
|
||||
else if( evt->IsDblClick( BUT_LEFT ) )
|
||||
{
|
||||
break; // finish
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::toggleHV45Mode ) )
|
||||
|
|
|
@ -331,7 +331,7 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
|
|||
setCursor();
|
||||
|
||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
||||
wxString msg = _( "Click on pad %s%d\nPress <esc> to cancel or double-click to commit" );
|
||||
wxString msg = _( "Click on pad %s%d\nPress <esc> to cancel all; double-click to finish" );
|
||||
statusPopup.SetText( wxString::Format( msg, padPrefix, seqPadNum ) );
|
||||
statusPopup.Popup();
|
||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
|
||||
|
@ -448,8 +448,7 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
|
||||
evt->IsDblClick( BUT_LEFT ) )
|
||||
else if( evt->IsDblClick( BUT_LEFT ) )
|
||||
{
|
||||
commit.Push( _( "Renumber pads" ) );
|
||||
frame()->PopTool( aEvent );
|
||||
|
|
Loading…
Reference in New Issue