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
This commit is contained in:
parent
a3e16988be
commit
7045ed92fb
|
@ -297,6 +297,7 @@ set( PCBNEW_CLASS_SRCS
|
||||||
tools/picker_tool.cpp
|
tools/picker_tool.cpp
|
||||||
tools/zoom_tool.cpp
|
tools/zoom_tool.cpp
|
||||||
tools/tools_common.cpp
|
tools/tools_common.cpp
|
||||||
|
tools/tool_event_utils.cpp
|
||||||
tools/tool_menu.cpp
|
tools/tool_menu.cpp
|
||||||
|
|
||||||
tools/grid_menu.cpp
|
tools/grid_menu.cpp
|
||||||
|
|
|
@ -117,9 +117,15 @@ TOOL_ACTION COMMON_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_CREATE_ARRAY ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_CREATE_ARRAY ),
|
||||||
_( "Create array" ), _( "Create array" ), array_module_xpm, AF_ACTIVATE );
|
_( "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 ),
|
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",
|
TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
||||||
|
|
|
@ -70,8 +70,11 @@ public:
|
||||||
/// Activation of the edit tool
|
/// Activation of the edit tool
|
||||||
static TOOL_ACTION editActivate;
|
static TOOL_ACTION editActivate;
|
||||||
|
|
||||||
/// Rotation of selected objects
|
/// Rotation of selected objects clockwise
|
||||||
static TOOL_ACTION rotate;
|
static TOOL_ACTION rotateCw;
|
||||||
|
|
||||||
|
/// Rotation of selected objects counter-clockwise
|
||||||
|
static TOOL_ACTION rotateCcw;
|
||||||
|
|
||||||
/// Flipping of selected objects
|
/// Flipping of selected objects
|
||||||
static TOOL_ACTION flip;
|
static TOOL_ACTION flip;
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
|
|
||||||
#include <tools/selection_tool.h>
|
#include <tools/selection_tool.h>
|
||||||
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
using SCOPED_DRAW_MODE = SCOPED_SET_RESET<DRAWING_TOOL::MODE>;
|
using SCOPED_DRAW_MODE = SCOPED_SET_RESET<DRAWING_TOOL::MODE>;
|
||||||
|
|
||||||
|
@ -239,12 +239,14 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
else if( text && evt->Category() == TC_COMMAND )
|
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 );
|
m_view->Update( &preview );
|
||||||
}
|
}
|
||||||
// TODO rotate CCW
|
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
{
|
{
|
||||||
text->Flip( text->GetPosition() );
|
text->Flip( text->GetPosition() );
|
||||||
|
@ -612,11 +614,16 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
|
||||||
else if( evt->Category() == TC_COMMAND )
|
else if( evt->Category() == TC_COMMAND )
|
||||||
{
|
{
|
||||||
// TODO it should be handled by EDIT_TOOL, so add items and select?
|
// 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 )
|
for( auto item : preview )
|
||||||
item->Rotate( wxPoint( cursorPos.x, cursorPos.y ),
|
{
|
||||||
m_frame->GetRotationAngle() );
|
item->Rotate( rotationPoint, rotationAngle );
|
||||||
|
}
|
||||||
|
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,8 @@ using namespace std::placeholders;
|
||||||
#include <dialogs/dialog_track_via_properties.h>
|
#include <dialogs/dialog_track_via_properties.h>
|
||||||
#include <dialogs/dialog_exchange_modules.h>
|
#include <dialogs/dialog_exchange_modules.h>
|
||||||
|
|
||||||
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
|
||||||
EDIT_TOOL::EDIT_TOOL() :
|
EDIT_TOOL::EDIT_TOOL() :
|
||||||
|
@ -97,7 +99,8 @@ bool EDIT_TOOL::Init()
|
||||||
// Add context menu entries that are displayed when selection tool is active
|
// Add context menu entries that are displayed when selection tool is active
|
||||||
CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu();
|
CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu();
|
||||||
menu.AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
|
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::flip, SELECTION_CONDITIONS::NotEmpty );
|
||||||
menu.AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
|
menu.AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
|
||||||
menu.AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 )
|
menu.AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 )
|
||||||
|
@ -399,11 +402,12 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
wxPoint rotatePoint = getModificationPoint( selection );
|
wxPoint rotatePoint = getModificationPoint( selection );
|
||||||
|
const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
|
||||||
|
|
||||||
for( auto item : selection )
|
for( auto item : selection )
|
||||||
{
|
{
|
||||||
m_commit->Modify( item );
|
m_commit->Modify( item );
|
||||||
item->Rotate( rotatePoint, editFrame->GetRotationAngle() );
|
item->Rotate( rotatePoint, rotateAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !m_dragging )
|
if( !m_dragging )
|
||||||
|
@ -816,7 +820,8 @@ int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
|
||||||
void EDIT_TOOL::SetTransitions()
|
void EDIT_TOOL::SetTransitions()
|
||||||
{
|
{
|
||||||
Go( &EDIT_TOOL::Main, COMMON_ACTIONS::editActivate.MakeEvent() );
|
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::Flip, COMMON_ACTIONS::flip.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
|
Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
|
Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include <class_edge_mod.h>
|
#include <class_edge_mod.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
|
||||||
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
#include <wx/defs.h>
|
#include <wx/defs.h>
|
||||||
|
@ -138,9 +140,11 @@ int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
else if( evt->Category() == TC_COMMAND )
|
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 );
|
m_view->Update( &preview );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
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 )
|
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 );
|
m_view->Update( &preview );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <origin_viewitem.h>
|
#include <origin_viewitem.h>
|
||||||
|
|
||||||
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
@ -312,9 +314,11 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
else if( module && evt->Category() == TC_COMMAND )
|
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 );
|
view->Update( &preview );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue