From 5d1ec2b20451502aa104a0e2ee9ea3c8ea230c25 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH] Restored invocation of SELECTION_TOOL commands with TOOL_ACTIONs. --- pcbnew/router/router_tool.cpp | 3 +- pcbnew/tools/common_actions.cpp | 9 +- pcbnew/tools/common_actions.h | 6 + pcbnew/tools/drawing_tool.cpp | 17 ++- pcbnew/tools/edit_tool.cpp | 14 +-- pcbnew/tools/selection_tool.cpp | 196 +++++++++++++++++++------------- pcbnew/tools/selection_tool.h | 47 ++++---- 7 files changed, 171 insertions(+), 121 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 09951064d9..7416c14c17 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -40,7 +40,6 @@ #include #include -#include #include @@ -637,7 +636,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); // Deselect all items - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index d96f42d3ee..23d66b4249 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -31,17 +31,22 @@ 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', "Move", "Moves the selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.rotate", +TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", AS_GLOBAL, 'R', "Rotate", "Rotates selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.flip", +TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_GLOBAL, 'F', "Flip", "Flips selected item(s)" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 986489da63..800a085f2a 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -37,6 +37,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; + // Edit Tool /// Activation of the edit tool static TOOL_ACTION editActivate; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index c33bd7a3fa..9d3cf63670 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -38,7 +38,6 @@ #include #include #include -#include "selection_tool.h" #include #include @@ -103,7 +102,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -289,7 +288,7 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -394,7 +393,7 @@ int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -500,7 +499,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -696,7 +695,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -771,7 +770,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -882,7 +881,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1058,7 +1057,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5fa5359fe5..1db8267981 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -48,7 +48,7 @@ EDIT_TOOL::EDIT_TOOL() : bool EDIT_TOOL::Init() { // Find the selection tool, so they can cooperate - m_selectionTool = m_toolMgr->GetTool(); + m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); if( !m_selectionTool ) { @@ -198,7 +198,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); RN_DATA* ratsnest = getModel()->GetRatsnest(); ratsnest->ClearSimple(); @@ -251,7 +251,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) std::vector& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); @@ -328,7 +328,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -382,7 +382,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -407,7 +407,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_BASE_FRAME* editFrame = getEditFrame(); // As we are about to remove items, they have to be removed from the selection first - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) @@ -525,7 +525,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) { if( aSelection.Empty() ) // Try to find an item that could be modified - m_selectionTool->SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); return !aSelection.Empty(); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 08fb358094..ef6d9d0446 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -76,7 +76,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(); m_frame = getEditFrame(); @@ -84,8 +84,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) getView()->Remove( m_selection.group ); getView()->Add( m_selection.group ); - // The tool launches upon reception of action event ("pcbnew.InteractiveSelection") - Go( &SELECTION_TOOL::Main, COMMON_ACTIONS::selectionActivate.MakeEvent() ); + setTransitions(); } @@ -98,13 +97,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // become the new selection (discarding previously selected items) m_additive = evt->Modifier( MD_SHIFT ); - if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO ) - { - ClearSelection(); - } - // single click? Select single object - else if( evt->IsClick( BUT_LEFT ) ) + if( evt->IsClick( BUT_LEFT ) ) { if( evt->Modifier( MD_CTRL ) ) { @@ -113,9 +107,9 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { if( !m_additive ) - ClearSelection(); + clearSelection(); - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); } } @@ -123,7 +117,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_RIGHT ) ) { if( m_selection.Empty() ) - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); if( !m_selection.Empty() ) SetContextMenu( &m_menu, CMENU_NOW ); @@ -133,7 +127,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsDblClick( BUT_LEFT ) ) { if( m_selection.Empty() ) - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); m_toolMgr->RunAction( COMMON_ACTIONS::properties ); } @@ -148,7 +142,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( m_selection.Empty() ) { // There is nothing selected, so try to select something - if( !SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) + if( !selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) { // If nothings has been selected or user wants to select more // draw the selection box @@ -171,10 +165,22 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - ClearSelection(); + clearSelection(); } } } + + else if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) + { + // GetMousePosition() is used, as it is independent of snapping settings + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + } + + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO || + evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) + { + clearSelection(); + } } // This tool is supposed to be active forever @@ -184,7 +190,43 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) +void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +{ + assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER + + m_menu.Add( aAction ); +} + + +void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) +{ + if( aItem->IsSelected() ) + { + deselect( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT deselectEvent( DeselectedEvent ); + m_toolMgr->ProcessEvent( deselectEvent ); + } + else + { + if( !m_additive ) + clearSelection(); + + // Prevent selection of invisible or inactive items + if( selectable( aItem ) ) + { + select( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT selectEvent( SelectedEvent ); + m_toolMgr->ProcessEvent( selectEvent ); + } + } +} + + +bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); @@ -202,7 +244,7 @@ bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua { case 0: if( !m_additive ) - ClearSelection(); + clearSelection(); return false; @@ -254,70 +296,6 @@ bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua } -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(); - - m_frame->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); - - // Inform other potentially interested tools - TOOL_EVENT clearEvent( ClearedEvent ); - m_toolMgr->ProcessEvent( clearEvent ); -} - - -void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) -{ - assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER - - m_menu.Add( aAction ); -} - - -void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) -{ - if( aItem->IsSelected() ) - { - deselect( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT deselectEvent( DeselectedEvent ); - m_toolMgr->ProcessEvent( deselectEvent ); - } - else - { - if( !m_additive ) - ClearSelection(); - - // Prevent selection of invisible or inactive items - if( selectable( aItem ) ) - { - select( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT selectEvent( SelectedEvent ); - m_toolMgr->ProcessEvent( selectEvent ); - } - } -} - - bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? @@ -338,7 +316,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() ); @@ -393,6 +371,60 @@ bool SELECTION_TOOL::selectMultiple() } +void SELECTION_TOOL::setTransitions() +{ + Go( &SELECTION_TOOL::Main, COMMON_ACTIONS::selectionActivate.MakeEvent() ); + Go( &SELECTION_TOOL::SingleSelection, COMMON_ACTIONS::selectionSingle.MakeEvent() ); + Go( &SELECTION_TOOL::ClearSelection, COMMON_ACTIONS::selectionClear.MakeEvent() ); +} + + +int SELECTION_TOOL::SingleSelection( TOOL_EVENT& aEvent ) +{ + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + setTransitions(); + + return 0; +} + +int SELECTION_TOOL::ClearSelection( TOOL_EVENT& aEvent ) +{ + clearSelection(); + setTransitions(); + + return 0; +} + +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 ); + + // Inform other potentially interested tools + TOOL_EVENT clearEvent( ClearedEvent ); + m_toolMgr->ProcessEvent( clearEvent ); + + return; +} + + BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) { BOARD_ITEM* current = NULL; diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index fffd1ec27f..6f5e06606d 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -48,7 +48,7 @@ class VIEW_GROUP; * - pick single objects (click LMB) * - add objects to existing selection (Shift+LMB) * - draw selection box (drag LMB) - * - handles MODULEs properly (ie. selects either MODULE or its PADs, TEXTs, etc.) + * - handles MODULEs properly (i.e. selects either MODULE or its PADs, TEXTs, etc.) * - takes into account high-contrast & layer visibility settings * - invokes InteractiveEdit tool when user starts to drag selected items */ @@ -114,24 +114,6 @@ public: return m_selection; } - /** - * Function SelectSingle() - * Selects an item pointed by the parameter aWhere. If there is more than one item at that - * place, there is a menu displayed that allows to choose the item. - * - * @param aWhere is the place where the item should be selected. - * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then - * a menu is shown, otherise function finishes without selecting anything. - * @return True if an item was selected, false otherwise. - */ - bool SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); - - /** - * Function ClearSelection() - * Clears the current selection. - */ - void ClearSelection(); - /** * Function AddMenuItem() * @@ -160,7 +142,25 @@ public: ///> Event sent after selection is cleared. const TOOL_EVENT ClearedEvent; + ///> Select single item event handler. + int SingleSelection( TOOL_EVENT& aEvent ); + + ///> Clear current selection event handler. + int ClearSelection( TOOL_EVENT& aEvent ); + private: + /** + * Function selectSingle() + * Selects an item pointed by the parameter aWhere. If there is more than one item at that + * place, there is a menu displayed that allows to choose the item. + * + * @param aWhere is the place where the item should be selected. + * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then + * a menu is shown, otherise function finishes without selecting anything. + * @return True if an item was selected, false otherwise. + */ + bool selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); + /** * Function selectMultiple() * Handles drawing a selection box that allows to select many items at the same time. @@ -169,6 +169,15 @@ private: */ bool selectMultiple(); + ///> Sets up handlers for various events. + void setTransitions(); + + /** + * 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