Hi, Here is a patch for adding CCW rotation to the GAL canvas.
Possibly controversial is the new namespace in tool_action_utils.h for dumping generic free function helpers that act on TOOL_ACTIONS and on other classes in concert. I feel that this is a way to isolate the these routines, giving access to whichever GAL tool functions needed them, while emphasising that they act via public interfaces of the relevant classes, but I defer to the GAL wizards for comment! Fixes: https://bugs.launchpad.net/kicad/+bug/1660731 (but it's more extensive than just that, as it adds bidirectional rotation to everywhere there is unidirectional rotation in GAL now). Cheers, John
From 77bc4b3b42d64137d915aecdfef0139150c0844b Mon Sep 17 00:00:00 2001 From: John Beard <[email protected]> Date: Sat, 4 Feb 2017 13:09:50 +0800 Subject: [PATCH] Add CCW rotation to GAL canvas This makes "rotate" into two separate TOOL_EVENTs, which each have a "multiplier" parameter. Also added is a namespace for 'free functions' that use TOOL_EVENT public interfaces (perhaps with other inputs too) to centralise some decision-making and calculations. Fixes: lp:1660731 * https://bugs.launchpad.net/kicad/+bug/1660731 --- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/common_actions.cpp | 10 ++++-- pcbnew/tools/common_actions.h | 7 ++-- pcbnew/tools/drawing_tool.cpp | 21 +++++++---- pcbnew/tools/edit_tool.cpp | 11 ++++-- pcbnew/tools/module_editor_tools.cpp | 14 +++++--- pcbnew/tools/pcb_editor_control.cpp | 8 +++-- pcbnew/tools/tool_event_utils.cpp | 48 +++++++++++++++++++++++++ pcbnew/tools/tool_event_utils.h | 68 ++++++++++++++++++++++++++++++++++++ 9 files changed, 168 insertions(+), 20 deletions(-) create mode 100644 pcbnew/tools/tool_event_utils.cpp create mode 100644 pcbnew/tools/tool_event_utils.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index eedb3a6f0..7c36570c9 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -297,6 +297,7 @@ set( PCBNEW_CLASS_SRCS tools/picker_tool.cpp tools/zoom_tool.cpp tools/tools_common.cpp + tools/tool_event_utils.cpp tools/tool_menu.cpp tools/grid_menu.cpp diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 498d86355..604201fd5 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -117,9 +117,15 @@ TOOL_ACTION COMMON_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_CREATE_ARRAY ), _( "Create array" ), _( "Create array" ), array_module_xpm, AF_ACTIVATE ); -TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", +TOOL_ACTION COMMON_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ROTATE_ITEM ), - _( "Rotate" ), _( "Rotates selected item(s)" ), rotate_cw_xpm ); + _( "Rotate clockwise" ), _( "Rotates selected item(s) clockwise" ), + rotate_cw_xpm, AF_NONE, (void*) 1 ); + +TOOL_ACTION COMMON_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw", + AS_GLOBAL, MD_SHIFT + 'R', + _( "Rotate counter-clockwise" ), _( "Rotates selected item(s) counter-clockwise" ), + rotate_ccw_xpm, AF_NONE, (void*) -1 ); TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ), diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index b8167cf3c..b9800dcd4 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -70,8 +70,11 @@ public: /// Activation of the edit tool static TOOL_ACTION editActivate; - /// Rotation of selected objects - static TOOL_ACTION rotate; + /// Rotation of selected objects clockwise + static TOOL_ACTION rotateCw; + + /// Rotation of selected objects counter-clockwise + static TOOL_ACTION rotateCcw; /// Flipping of selected objects static TOOL_ACTION flip; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index c0b897361..c2196070d 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -53,7 +53,7 @@ #include <class_module.h> #include <tools/selection_tool.h> - +#include <tools/tool_event_utils.h> using SCOPED_DRAW_MODE = SCOPED_SET_RESET<DRAWING_TOOL::MODE>; @@ -236,12 +236,14 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) else if( text && evt->Category() == TC_COMMAND ) { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) { - text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); + const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( + *m_frame, *evt ); + + text->Rotate( text->GetPosition(), rotationAngle ); m_view->Update( &preview ); } - // TODO rotate CCW else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) { text->Flip( text->GetPosition() ); @@ -617,11 +619,16 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent ) else if( evt->Category() == TC_COMMAND ) { // TODO it should be handled by EDIT_TOOL, so add items and select? - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) { + const auto rotationPoint = wxPoint( cursorPos.x, cursorPos.y ); + const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( + *m_frame, *evt ); + for( auto item : preview ) - item->Rotate( wxPoint( cursorPos.x, cursorPos.y ), - m_frame->GetRotationAngle() ); + { + item->Rotate( rotationPoint, rotationAngle ); + } m_view->Update( &preview ); } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index a344b3110..031f2db4f 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -58,6 +58,8 @@ using namespace std::placeholders; #include <dialogs/dialog_track_via_properties.h> #include <dialogs/dialog_exchange_modules.h> +#include <tools/tool_event_utils.h> + #include <board_commit.h> EDIT_TOOL::EDIT_TOOL() : @@ -97,7 +99,8 @@ bool EDIT_TOOL::Init() // Add context menu entries that are displayed when selection tool is active CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu(); menu.AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty ); - menu.AddItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty ); + menu.AddItem( COMMON_ACTIONS::rotateCw, SELECTION_CONDITIONS::NotEmpty ); + menu.AddItem( COMMON_ACTIONS::rotateCcw, SELECTION_CONDITIONS::NotEmpty ); menu.AddItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty ); menu.AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty ); menu.AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 ) @@ -399,11 +402,12 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) return 0; wxPoint rotatePoint = getModificationPoint( selection ); + const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent ); for( auto item : selection ) { m_commit->Modify( item ); - item->Rotate( rotatePoint, editFrame->GetRotationAngle() ); + item->Rotate( rotatePoint, rotateAngle ); } if( !m_dragging ) @@ -816,7 +820,8 @@ int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent ) void EDIT_TOOL::SetTransitions() { Go( &EDIT_TOOL::Main, COMMON_ACTIONS::editActivate.MakeEvent() ); - Go( &EDIT_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() ); + Go( &EDIT_TOOL::Rotate, COMMON_ACTIONS::rotateCw.MakeEvent() ); + Go( &EDIT_TOOL::Rotate, COMMON_ACTIONS::rotateCcw.MakeEvent() ); Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() ); Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); diff --git a/pcbnew/tools/module_editor_tools.cpp b/pcbnew/tools/module_editor_tools.cpp index 8ee451cbd..ab0c28535 100644 --- a/pcbnew/tools/module_editor_tools.cpp +++ b/pcbnew/tools/module_editor_tools.cpp @@ -45,6 +45,8 @@ #include <class_edge_mod.h> #include <board_commit.h> +#include <tools/tool_event_utils.h> + #include <functional> using namespace std::placeholders; #include <wx/defs.h> @@ -138,9 +140,11 @@ int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent ) else if( evt->Category() == TC_COMMAND ) { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) { - pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() ); + const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( + *m_frame, *evt ); + pad->Rotate( pad->GetPosition(), rotationAngle ); m_view->Update( &preview ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -451,9 +455,11 @@ int MODULE_EDITOR_TOOLS::PasteItems( const TOOL_EVENT& aEvent ) else if( evt->Category() == TC_COMMAND ) { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) { - pastedModule->Rotate( pastedModule->GetPosition(), m_frame->GetRotationAngle() ); + const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( + *m_frame, *evt ); + pastedModule->Rotate( pastedModule->GetPosition(), rotationAngle ); m_view->Update( &preview ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index 5fc9779e4..614bd14f5 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -50,6 +50,8 @@ #include <view/view_controls.h> #include <origin_viewitem.h> +#include <tools/tool_event_utils.h> + #include <functional> using namespace std::placeholders; @@ -312,9 +314,11 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) else if( module && evt->Category() == TC_COMMAND ) { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) { - module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() ); + const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( + *m_frame, *evt ); + module->Rotate( module->GetPosition(), rotationAngle ); view->Update( &preview ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) diff --git a/pcbnew/tools/tool_event_utils.cpp b/pcbnew/tools/tool_event_utils.cpp new file mode 100644 index 000000000..b24dae6e3 --- /dev/null +++ b/pcbnew/tools/tool_event_utils.cpp @@ -0,0 +1,48 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <tools/tool_event_utils.h> + +#include <tools/common_actions.h> + +#include <pcb_base_edit_frame.h> + + +bool TOOL_EVT_UTILS::IsRotateToolEvt( const TOOL_EVENT& aEvt ) +{ + return aEvt.IsAction( &COMMON_ACTIONS::rotateCw ) + || aEvt.IsAction( &COMMON_ACTIONS::rotateCcw ); +} + + +int TOOL_EVT_UTILS::GetEventRotationAngle( const PCB_BASE_EDIT_FRAME& aFrame, + const TOOL_EVENT& aEvt ) +{ + wxASSERT_MSG( IsRotateToolEvt( aEvt ), + _( "Expected rotation event" ) ); + + const int rotAngle = aFrame.GetRotationAngle(); + const int angleMultiplier = aEvt.Parameter<intptr_t>(); + + return rotAngle * angleMultiplier; +} diff --git a/pcbnew/tools/tool_event_utils.h b/pcbnew/tools/tool_event_utils.h new file mode 100644 index 000000000..308542454 --- /dev/null +++ b/pcbnew/tools/tool_event_utils.h @@ -0,0 +1,68 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef TOOL_EVENT_UTILS_H +#define TOOL_EVENT_UTILS_H + +#include <tool/tool_interactive.h> + + +class PCB_BASE_EDIT_FRAME; + + +/** + * Namespace TOOL_EVT_UTILS + * + * Utility functions for dealing with various tool events. These are + * free functions, so they interface with any classes exclusively via + * the public interfaces, so they don't need to be subsumed into the + * "helped" classes. + */ +namespace TOOL_EVT_UTILS +{ + /** + * Function isRotateToolEvt() + * + * @param aEvt event to check + * @return true if the event is a rotation action tool event + */ + bool IsRotateToolEvt( const TOOL_EVENT& aEvt ); + + /** + * Function getEventRotationAngle() + * + * Helper function to get a rotation angle based on a frame's + * configured angle and the direction indicated by a rotation action event + * + * @param aFrame the PCB edit frame to use to get the base rotation + * step value from + * @param aEvt the tool event - should be a rotation action event + * and should have a rotation multiplier parameter + * + * @return the rotation angle in clockwise internal units + */ + int GetEventRotationAngle( const PCB_BASE_EDIT_FRAME& aFrame, + const TOOL_EVENT& aEvt ); +}; + +#endif // TOOL_EVENT_UTILS_H -- 2.11.0
_______________________________________________ Mailing list: https://launchpad.net/~kicad-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~kicad-developers More help : https://help.launchpad.net/ListHelp

