Improved speed of Duplicate action
- Removed repetitive tool calls
This commit is contained in:
parent
d5e85726ea
commit
18488342a5
|
@ -297,8 +297,10 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Drag items to the current cursor position
|
||||
for( auto item : selection )
|
||||
{
|
||||
static_cast<BOARD_ITEM*>( item )->Move( movement + m_offset );
|
||||
}
|
||||
}
|
||||
else if( !m_dragging ) // Prepare to start dragging
|
||||
{
|
||||
if( !invokeInlineRouter() )
|
||||
|
@ -830,8 +832,6 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
|||
|
||||
int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Note: original items are no more modified.
|
||||
|
||||
bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
|
||||
|
||||
// Be sure that there is at least one item that we can modify
|
||||
|
@ -843,28 +843,24 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
// we have a selection to work on now, so start the tool process
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
std::vector<BOARD_ITEM*> old_items;
|
||||
std::vector<BOARD_ITEM*> new_items;
|
||||
new_items.reserve( selection.Size() );
|
||||
|
||||
BOARD_ITEM* orig_item = nullptr;
|
||||
BOARD_ITEM* dupe_item = nullptr;
|
||||
|
||||
// Each selected item is duplicated and pushed to new_items list
|
||||
// Old selection is cleared, and new items are then selected.
|
||||
for( auto item : selection )
|
||||
{
|
||||
if( item )
|
||||
old_items.push_back( static_cast<BOARD_ITEM*>( item ) );
|
||||
}
|
||||
if( !item )
|
||||
continue;
|
||||
|
||||
for( unsigned i = 0; i < old_items.size(); ++i )
|
||||
{
|
||||
BOARD_ITEM* item = old_items[i];
|
||||
|
||||
// Unselect the item, so we won't pick it up again
|
||||
// Do this first, so a single-item duplicate will correctly call
|
||||
// SetCurItem and show the item properties
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::unselectItem, true, item );
|
||||
|
||||
BOARD_ITEM* new_item = NULL;
|
||||
orig_item = static_cast<BOARD_ITEM*>( item );
|
||||
|
||||
if( m_editModules )
|
||||
{
|
||||
new_item = editFrame->GetBoard()->m_Modules->Duplicate( item, increment );
|
||||
dupe_item = editFrame->GetBoard()->m_Modules->Duplicate( orig_item, increment );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -874,23 +870,31 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
// so zones are not duplicated
|
||||
if( item->Type() != PCB_ZONE_AREA_T )
|
||||
#endif
|
||||
new_item = editFrame->GetBoard()->Duplicate( item );
|
||||
dupe_item = editFrame->GetBoard()->Duplicate( orig_item );
|
||||
}
|
||||
|
||||
if( new_item )
|
||||
if( dupe_item )
|
||||
{
|
||||
m_commit->Add( new_item );
|
||||
// Clear the selection flag here, otherwise the SELECTION_TOOL
|
||||
// will not properly select it later on
|
||||
dupe_item->ClearSelected();
|
||||
|
||||
// Select the new item, so we can pick it up
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, new_item );
|
||||
new_items.push_back( dupe_item );
|
||||
m_commit->Add( dupe_item );
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the old selection first
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
// Select the new items
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
|
||||
|
||||
// record the new items as added
|
||||
if( !selection.Empty() )
|
||||
{
|
||||
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
|
||||
(int) old_items.size() ) );
|
||||
(int) new_items.size() ) );
|
||||
|
||||
// If items were duplicated, pick them up
|
||||
// this works well for "dropping" copies around and pushes the commit
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
/**
|
||||
* Function Duplicate()
|
||||
*
|
||||
* Duplicates a selection and starts a move action
|
||||
* Duplicates the current selection and starts a move action.
|
||||
*/
|
||||
int Duplicate( const TOOL_EVENT& aEvent );
|
||||
|
||||
|
|
|
@ -55,9 +55,15 @@ public:
|
|||
/// Selects an item (specified as the event parameter).
|
||||
static TOOL_ACTION selectItem;
|
||||
|
||||
/// Selects a list of items (specified as the event parameter)
|
||||
static TOOL_ACTION selectItems;
|
||||
|
||||
/// Unselects an item (specified as the event parameter).
|
||||
static TOOL_ACTION unselectItem;
|
||||
|
||||
/// Unselects a list of items (specified as the event parameter)
|
||||
static TOOL_ACTION unselectItems;
|
||||
|
||||
/// Selects a connection between junctions.
|
||||
static TOOL_ACTION selectConnection;
|
||||
|
||||
|
|
|
@ -70,10 +70,18 @@ TOOL_ACTION PCB_ACTIONS::selectItem( "pcbnew.InteractiveSelection.SelectItem",
|
|||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectItems( "pcbnew.InteractiveSelection.SelectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::unselectItem( "pcbnew.InteractiveSelection.UnselectItem",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::unselectItems( "pcbnew.InteractiveSelection.UnselectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
@ -235,7 +243,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
// This will be ignored if the SHIFT modifier is pressed
|
||||
m_subtractive = !m_additive && evt->Modifier( MD_CTRL );
|
||||
|
||||
// single click? Select single object
|
||||
// Single click? Select single object
|
||||
if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if( evt->Modifier( MD_CTRL ) && !m_editModules )
|
||||
|
@ -244,8 +252,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
else
|
||||
{
|
||||
// If no modifier keys are pressed, clear the selection
|
||||
if( !m_additive )
|
||||
{
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
selectPoint( evt->Position() );
|
||||
}
|
||||
|
@ -585,7 +596,9 @@ void SELECTION_TOOL::SetTransitions()
|
|||
Go( &SELECTION_TOOL::CursorSelection, PCB_ACTIONS::selectionCursor.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::ClearSelection, PCB_ACTIONS::selectionClear.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::SelectItem, PCB_ACTIONS::selectItem.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::SelectItems, PCB_ACTIONS::selectItems.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::UnselectItem, PCB_ACTIONS::unselectItem.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::UnselectItems, PCB_ACTIONS::unselectItems.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::findMove, PCB_ACTIONS::findMove.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::filterSelection, PCB_ACTIONS::filterSelection.MakeEvent() );
|
||||
|
@ -672,6 +685,27 @@ int SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual selection of each item
|
||||
// before processing the event.
|
||||
for( auto item : *items )
|
||||
{
|
||||
select( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Check if there is an item to be selected
|
||||
|
@ -689,6 +723,26 @@ int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<BOARD_ITEM*>* items = aEvent.Parameter<std::vector<BOARD_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual unselection of each item
|
||||
// before processing the event
|
||||
for( auto item : *items )
|
||||
{
|
||||
unselect( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Check if there is an item to be selected
|
||||
|
@ -1165,10 +1219,14 @@ int SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
|
|||
void SELECTION_TOOL::clearSelection()
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( auto item : m_selection )
|
||||
{
|
||||
unselectVisually( static_cast<BOARD_ITEM*>( item ) );
|
||||
}
|
||||
|
||||
m_selection.Clear();
|
||||
|
||||
|
@ -1393,6 +1451,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
return board()->IsLayerVisible( aItem->GetLayer() );
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::select( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( aItem->IsSelected() )
|
||||
|
|
|
@ -114,9 +114,15 @@ public:
|
|||
///> Item selection event handler.
|
||||
int SelectItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Multiple item selection event handler
|
||||
int SelectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Item unselection event handler.
|
||||
int UnselectItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Multiple item unselection event handler
|
||||
int UnselectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Event sent after an item is selected.
|
||||
static const TOOL_EVENT SelectedEvent;
|
||||
|
||||
|
|
Loading…
Reference in New Issue