diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 6756e10a9d..f1fb3befd6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -30,6 +30,12 @@ TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + +TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 19b0004182..86aafe5894 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -24,13 +24,11 @@ #include -//class ACTION_MANAGER; - /** * Class COMMON_ACTIONS * - * Gathers all the actions that are shared by tools. The instance of COMMON_ACTIOSN is created - * inside of ACTION_MANAGER object and registers them. + * Gathers all the actions that are shared by tools. The instance of COMMON_ACTION is created + * inside of ACTION_MANAGER object that registers the actions. */ class COMMON_ACTIONS { @@ -38,6 +36,12 @@ public: /// Activation of the selection tool static TOOL_ACTION selectionActivate; + /// Select a single item under the cursor position + static TOOL_ACTION selectionSingle; + + /// Clears the current selection + static TOOL_ACTION selectionClear; + /// Activation of the edit tool static TOOL_ACTION editActivate; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 812d7732dd..008305193d 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -74,10 +74,6 @@ bool EDIT_TOOL::Init() int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); - - // By default, modified items need to update their geometry - m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; if( selection.Empty() ) { @@ -90,7 +86,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) m_dragging = false; bool restore = false; // Should items' state be restored when finishing the tool? + // By default, modified items need to update their geometry + m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; + VIEW_CONTROLS* controls = getViewControls(); + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); controls->ShowCursor( true ); controls->SetSnapping( true ); controls->SetAutoPan( true ); @@ -163,7 +163,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) if( restore ) { - // Modifications has to be rollbacked, so restore the previous state of items + // Modifications have to be rollbacked, so restore the previous state of items wxCommandEvent dummy; editFrame->GetBoardFromUndoList( dummy ); } @@ -290,7 +290,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); // As we are about to remove items, they have to be removed from the selection first - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( "pcbnew.InteractiveSelection.Clear" ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 9908012f6b..a4b4f21a24 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -47,6 +47,8 @@ void PCB_EDIT_FRAME::setupTools() GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); // Register tool actions + m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionSingle ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionClear ); m_toolManager->RegisterAction( &COMMON_ACTIONS::editActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 9cdd5fc072..ce59adbb1f 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -72,7 +72,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) m_selection.clear(); else // Restore previous properties of selected items and remove them from containers - ClearSelection(); + clearSelection(); // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -92,25 +92,22 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // become the new selection (discarding previously selected items) m_additive = evt->Modifier( MD_SHIFT ); - if( evt->IsCancel() ) + if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) { - // Cancel event deselects items... - ClearSelection(); - - // This tool never exits + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); } - else if( evt->Action() == TA_UNDO_REDO ) + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO || + evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) { - // Clear the selection, as it may be altered with undone items - ClearSelection(); + clearSelection(); } // single click? Select single object else if( evt->IsClick( BUT_LEFT ) ) { if( !m_additive ) - ClearSelection(); + clearSelection(); selectSingle( evt->Position() ); } @@ -144,7 +141,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - ClearSelection(); + clearSelection(); } } } @@ -157,30 +154,6 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -void SELECTION_TOOL::ClearSelection() -{ - if( m_selection.Empty() ) - return; - - KIGFX::VIEW_GROUP::const_iter it, it_end; - - // Restore the initial properties - for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) - { - BOARD_ITEM* item = static_cast( *it ); - - item->ViewSetVisible( true ); - item->ClearSelected(); - } - m_selection.clear(); - - getEditFrame()->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); -} - - void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) { assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER @@ -198,7 +171,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) else { if( !m_additive ) - ClearSelection(); + clearSelection(); // Prevent selection of invisible or inactive items if( selectable( aItem ) ) @@ -221,7 +194,7 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) { case 0: if( !m_additive ) - ClearSelection(); + clearSelection(); break; case 1: @@ -254,43 +227,6 @@ void SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere ) } -BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector ) -{ - int count = aCollector->GetPrimaryCount(); // try to use preferred layer - - if( 0 == count ) - count = aCollector->GetCount(); - - for( int i = 0; i < count; ++i ) - { - if( ( *aCollector )[i]->Type() != PCB_MODULE_T ) - return NULL; - } - - // All are modules, now find smallest MODULE - int minDim = 0x7FFFFFFF; - int minNdx = 0; - - for( int i = 0; i < count; ++i ) - { - MODULE* module = (MODULE*) ( *aCollector )[i]; - - int lx = module->GetBoundingBox().GetWidth(); - int ly = module->GetBoundingBox().GetHeight(); - - int lmin = std::min( lx, ly ); - - if( lmin < minDim ) - { - minDim = lmin; - minNdx = i; - } - } - - return (*aCollector)[minNdx]; -} - - bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? @@ -311,7 +247,7 @@ bool SELECTION_TOOL::selectMultiple() if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) - ClearSelection(); + clearSelection(); // Start drawing a selection box m_selArea->SetOrigin( evt->DragOrigin() ); @@ -356,6 +292,30 @@ bool SELECTION_TOOL::selectMultiple() } +void SELECTION_TOOL::clearSelection() +{ + if( m_selection.Empty() ) + return; + + KIGFX::VIEW_GROUP::const_iter it, it_end; + + // Restore the initial properties + for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + + item->ViewSetVisible( true ); + item->ClearSelected(); + } + m_selection.clear(); + + getEditFrame()->SetCurItem( NULL ); + + // Do not show the context menu when there is nothing selected + SetContextMenu( &m_menu, CMENU_OFF ); +} + + BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) { BOARD_ITEM* current = NULL; @@ -419,6 +379,43 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) } +BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector ) +{ + int count = aCollector->GetPrimaryCount(); // try to use preferred layer + + if( 0 == count ) + count = aCollector->GetCount(); + + for( int i = 0; i < count; ++i ) + { + if( ( *aCollector )[i]->Type() != PCB_MODULE_T ) + return NULL; + } + + // All are modules, now find smallest MODULE + int minDim = 0x7FFFFFFF; + int minNdx = 0; + + for( int i = 0; i < count; ++i ) + { + MODULE* module = (MODULE*) ( *aCollector )[i]; + + int lx = module->GetBoundingBox().GetWidth(); + int ly = module->GetBoundingBox().GetHeight(); + + int lmin = std::min( lx, ly ); + + if( lmin < minDim ) + { + minDim = lmin; + minNdx = i; + } + } + + return (*aCollector)[minNdx]; +} + + bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const { // Is high contrast mode enabled? diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 93b25083c6..4c5e4b2d9a 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -106,12 +106,6 @@ public: return m_selection; } - /** - * Function ClearSelection() - * Clears the current selection. - */ - void ClearSelection(); - /** * Function AddMenuItem() * @@ -138,6 +132,12 @@ private: */ bool selectMultiple(); + /** + * Function ClearSelection() + * Clears the current selection. + */ + void clearSelection(); + /** * Function disambiguationMenu() * Handles the menu that allows to select one of many items in case there is more than one