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 )
|
if( changed && copy )
|
||||||
|
{
|
||||||
m_commit.Modified( aPcbFootprint, copy );
|
m_commit.Modified( aPcbFootprint, copy );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
copy->SetParentGroup( nullptr );
|
||||||
delete copy;
|
delete copy;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -621,9 +626,14 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( FOOTPRINT* aFootprint
|
||||||
}
|
}
|
||||||
|
|
||||||
if( changed && copy )
|
if( changed && copy )
|
||||||
|
{
|
||||||
m_commit.Modified( aFootprint, copy );
|
m_commit.Modified( aFootprint, copy );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
copy->SetParentGroup( nullptr );
|
||||||
delete copy;
|
delete copy;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2260,7 +2260,7 @@ void EDIT_TOOL::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &EDIT_TOOL::GetAndPlace, PCB_ACTIONS::getAndPlace.MakeEvent() );
|
Go( &EDIT_TOOL::GetAndPlace, PCB_ACTIONS::getAndPlace.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.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::drag45Degree.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Drag, PCB_ACTIONS::dragFreeAngle.MakeEvent() );
|
Go( &EDIT_TOOL::Drag, PCB_ACTIONS::dragFreeAngle.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Rotate, PCB_ACTIONS::rotateCw.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::Remove, PCB_ACTIONS::deleteFull.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Properties, PCB_ACTIONS::properties.MakeEvent() );
|
Go( &EDIT_TOOL::Properties, PCB_ACTIONS::properties.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::MoveExact, PCB_ACTIONS::moveExact.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, ACTIONS::duplicate.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Duplicate, PCB_ACTIONS::duplicateIncrement.MakeEvent() );
|
Go( &EDIT_TOOL::Duplicate, PCB_ACTIONS::duplicateIncrement.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::CreateArray, PCB_ACTIONS::createArray.MakeEvent() );
|
Go( &EDIT_TOOL::CreateArray, PCB_ACTIONS::createArray.MakeEvent() );
|
||||||
|
|
|
@ -80,11 +80,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int Move( const TOOL_EVENT& aEvent );
|
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
|
* Invoke the PNS router to drag tracks or do an offline resizing of an arc track
|
||||||
* if a single arc track is selected.
|
* if a single arc track is selected.
|
||||||
|
@ -150,11 +145,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int MoveExact( const TOOL_EVENT& aEvent );
|
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.
|
* 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 invokeInlineRouter( int aDragMode );
|
||||||
bool isRouterActive() const;
|
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,
|
VECTOR2I getSafeMovement( const VECTOR2I& aMovement, const BOX2I& aSourceBBox,
|
||||||
const VECTOR2D& aBBoxOffset );
|
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,
|
VECTOR2I EDIT_TOOL::getSafeMovement( const VECTOR2I& aMovement, const BOX2I& aSourceBBox,
|
||||||
const VECTOR2D& aBBoxOffset )
|
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>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
PCBNEW_SETTINGS* cfg = editFrame->GetPcbNewSettings();
|
PCBNEW_SETTINGS* cfg = editFrame->GetPcbNewSettings();
|
||||||
BOARD* board = editFrame->GetBoard();
|
BOARD* board = editFrame->GetBoard();
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
VECTOR2I originalCursorPos = controls->GetCursorPosition();
|
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,
|
// 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)
|
// 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->SetAutoPan( true );
|
||||||
controls->ForceCursorPosition( false );
|
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 =
|
auto displayConstraintsMessage =
|
||||||
[editFrame]( bool constrained )
|
[editFrame]( bool constrained )
|
||||||
{
|
{
|
||||||
|
@ -385,6 +341,32 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||||
: wxT( "" ) );
|
: 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*> sel_items; // All the items operated on by the move below
|
||||||
std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
|
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;
|
bool restore_state = false;
|
||||||
VECTOR2I originalPos;
|
VECTOR2I originalPos;
|
||||||
VECTOR2I totalMovement;
|
VECTOR2I totalMovement;
|
||||||
|
@ -624,22 +635,18 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<BOARD_ITEM*> items;
|
for( BOARD_ITEM* item : sel_items )
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
|
||||||
{
|
{
|
||||||
items.push_back( static_cast<BOARD_ITEM*>( item ) );
|
|
||||||
|
|
||||||
if( showCourtyardConflicts && item->Type() == PCB_FOOTPRINT_T )
|
if( showCourtyardConflicts && item->Type() == PCB_FOOTPRINT_T )
|
||||||
drc_on_move->m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
|
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() );
|
&m_selectionTool->GetFilter() );
|
||||||
|
|
||||||
// Set the current cursor position to the first dragged item origin, so the
|
// Set the current cursor position to the first dragged item origin, so the
|
||||||
// movement vector could be computed later
|
// movement vector could be computed later
|
||||||
if( aPickReference )
|
if( moveWithReference )
|
||||||
{
|
{
|
||||||
selection.SetReferencePoint( pickedReferencePoint );
|
selection.SetReferencePoint( pickedReferencePoint );
|
||||||
controls->ForceCursorPosition( true, pickedReferencePoint );
|
controls->ForceCursorPosition( true, pickedReferencePoint );
|
||||||
|
@ -668,6 +675,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||||
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false, new VECTOR2I( movement ) );
|
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false, new VECTOR2I( movement ) );
|
||||||
}
|
}
|
||||||
else if( evt->IsCancelInteractive() || evt->IsActivate() )
|
else if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||||
|
@ -723,7 +732,31 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
||||||
eatFirstMouseUp = false;
|
eatFirstMouseUp = false;
|
||||||
continue;
|
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
|
break; // finish
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::toggleHV45Mode ) )
|
else if( evt->IsAction( &PCB_ACTIONS::toggleHV45Mode ) )
|
||||||
|
|
|
@ -331,7 +331,7 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
|
||||||
setCursor();
|
setCursor();
|
||||||
|
|
||||||
STATUS_TEXT_POPUP statusPopup( frame() );
|
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.SetText( wxString::Format( msg, padPrefix, seqPadNum ) );
|
||||||
statusPopup.Popup();
|
statusPopup.Popup();
|
||||||
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
|
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 ) ||
|
else if( evt->IsDblClick( BUT_LEFT ) )
|
||||||
evt->IsDblClick( BUT_LEFT ) )
|
|
||||||
{
|
{
|
||||||
commit.Push( _( "Renumber pads" ) );
|
commit.Push( _( "Renumber pads" ) );
|
||||||
frame()->PopTool( aEvent );
|
frame()->PopTool( aEvent );
|
||||||
|
|
Loading…
Reference in New Issue