diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index a61ebc52b0..e1b95141c6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -36,9 +36,13 @@ TOOL_ACTION COMMON_ACTIONS::moveActivate( "pcbnew.InteractiveMove", "Move", "Moves the selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveMove.rotate", - AS_CONTEXT, ' ', + AS_CONTEXT, 'R', "Rotate", "Rotates selected item(s)" ); TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveMove.flip", AS_CONTEXT, 'F', "Flip", "Flips selected item(s)" ); + +TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveMove.properties", + AS_GLOBAL, 'E', + "Properties...", "Displays properties window" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 547b86f814..c93dd29220 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -24,7 +24,7 @@ #include -class ACTION_MANAGER; +//class ACTION_MANAGER; /** * Class COMMON_ACTIONS @@ -46,4 +46,7 @@ public: /// Flipping of selected objects static TOOL_ACTION flip; + + /// Activation of the edit tool + static TOOL_ACTION properties; }; diff --git a/pcbnew/tools/move_tool.cpp b/pcbnew/tools/move_tool.cpp index 6750d3e8fd..ccafa2c835 100644 --- a/pcbnew/tools/move_tool.cpp +++ b/pcbnew/tools/move_tool.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -41,38 +42,26 @@ MOVE_TOOL::MOVE_TOOL() : } -MOVE_TOOL::~MOVE_TOOL() -{ -} - - -void MOVE_TOOL::Reset() -{ - // The tool launches upon reception of action event ("pcbnew.InteractiveMove") - Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); -} - - bool MOVE_TOOL::Init() { // Find the selection tool, so they can cooperate TOOL_BASE* selectionTool = m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ); - if( selectionTool ) - { - m_selectionTool = static_cast( selectionTool ); - - // Add context menu entries that are displayed when selection tool is active - m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); - } - else + m_selectionTool = static_cast( selectionTool ); + if( !selectionTool ) { DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); return false; } + // Add context menu entries that are displayed when selection tool is active + m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveActivate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties ); + + setTransitions(); + return true; } @@ -85,7 +74,7 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) return 0; // there are no items to operate on VECTOR2D dragPosition; - bool dragging = false; + m_dragging = false; bool restore = false; // Should items' state be restored when finishing the tool? VIEW_CONTROLS* controls = getViewControls(); @@ -105,23 +94,15 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) // Dispatch TOOL_ACTIONs else if( evt->Category() == TC_COMMAND ) { - VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); - - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) // got rotation event? - { - m_state.Rotate( cursorPos, 900.0 ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) // got flip event? - { - m_state.Flip( cursorPos ); - selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); - } + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + Rotate( aEvent ); + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + Flip( aEvent ); } else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) { - if( dragging ) + if( m_dragging ) { // Drag items to the current cursor position VECTOR2D movement = ( evt->Position() - dragPosition ); @@ -138,16 +119,19 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) m_state.Save( *it ); } - dragging = true; + m_dragging = true; } selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); dragPosition = evt->Position(); } + else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) break; // Finish } + m_dragging = false; + if( restore ) { // Modifications has to be rollbacked, so restore the previous state of items @@ -165,5 +149,91 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent ) controls->SetSnapping( false ); controls->SetAutoPan( false ); + setTransitions(); + return 0; } + + +int MOVE_TOOL::Properties( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + // Properties are displayed when there is only one item selected + if( selection.items.size() == 1 ) + { + // Display properties dialog + PCB_EDIT_FRAME* editFrame = static_cast( m_toolMgr->GetEditFrame() ); + BOARD_ITEM* item = *selection.items.begin(); + editFrame->OnEditItemRequest( NULL, item ); + + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + + return 0; +} + + +int MOVE_TOOL::Rotate( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Rotate( cursorPos, 900.0 ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Rotate( wxPoint( cursorPos.x, cursorPos.y ), 900.0 ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + setTransitions(); + } + + return 0; +} + + +int MOVE_TOOL::Flip( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + VECTOR2D cursorPos = getView()->ToWorld( getViewControls()->GetCursorPosition() ); + + if( m_dragging ) + { + m_state.Flip( cursorPos ); + selection.group->ViewUpdate( VIEW_ITEM::GEOMETRY ); + } + else + { + std::set::iterator it; + + for( it = selection.items.begin(); it != selection.items.end(); ++it ) + { + (*it)->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); + (*it)->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); + } + + setTransitions(); + } + + return 0; +} + + +void MOVE_TOOL::setTransitions() +{ + Go( &MOVE_TOOL::Main, COMMON_ACTIONS::moveActivate.MakeEvent() ); + Go( &MOVE_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() ); + Go( &MOVE_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); + Go( &MOVE_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); +} diff --git a/pcbnew/tools/move_tool.h b/pcbnew/tools/move_tool.h index 1140d0067e..9b7a88012d 100644 --- a/pcbnew/tools/move_tool.h +++ b/pcbnew/tools/move_tool.h @@ -49,10 +49,9 @@ class MOVE_TOOL : public TOOL_INTERACTIVE { public: MOVE_TOOL(); - ~MOVE_TOOL(); /// @copydoc TOOL_INTERACTIVE::Reset() - void Reset(); + void Reset() {}; /// @copydoc TOOL_INTERACTIVE::Init() bool Init(); @@ -61,15 +60,43 @@ public: * Function Main() * * Main loop in which events are handled. + * @param aEvent is the handled event. */ int Main( TOOL_EVENT& aEvent ); + /** + * Function Edit() + * + * Displays properties window for the selected object. + */ + int Properties( TOOL_EVENT& aEvent ); + + /** + * Function Rotate() + * + * Rotates currently selected items. + */ + int Rotate( TOOL_EVENT& aEvent ); + + /** + * Function Flip() + * + * Rotates currently selected items. The rotation point is the current cursor position. + */ + int Flip( TOOL_EVENT& aEvent ); + private: - /// Saves the state of items and allows to restore them + ///> Saves the state of items and allows to restore them ITEM_STATE m_state; - /// Selection tool used for obtaining selected items + ///> Selection tool used for obtaining selected items SELECTION_TOOL* m_selectionTool; + + ///> Flag determining if anything is being dragged right now + bool m_dragging; + + ///> Sets up handlers for various events + void setTransitions(); }; #endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 2f9676cb94..aaccb18978 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -51,6 +51,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterAction( &COMMON_ACTIONS::selectionActivate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::rotate ); m_toolManager->RegisterAction( &COMMON_ACTIONS::flip ); + m_toolManager->RegisterAction( &COMMON_ACTIONS::properties ); // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index decd7fe9e5..e7d56cd291 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -102,11 +102,25 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } // single click? Select single object - if( evt->IsClick( BUT_LEFT ) ) + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !m_additive && m_selection.Size() > 1 ) + clearSelection(); + selectSingle( evt->Position() ); + } + + else if( evt->IsDblClick( BUT_LEFT ) ) + { + if( m_selection.Empty() ) + selectSingle( evt->Position() ); + + // Display properties window + m_toolMgr->RunAction( "pcbnew.InteractiveMove.properties" ); + } // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them - if( evt->IsDrag( BUT_LEFT ) ) + else if( evt->IsDrag( BUT_LEFT ) ) { if( m_selection.Empty() || m_additive ) {