Add mirror tool action for GAL module editor

This is basically a simple clone of the legacy tool with a few minor
tidy-ups for GAL mode.

Fixes: lp:1619301
* https://bugs.launchpad.net/kicad/+bug/1619301
This commit is contained in:
John Beard 2017-01-23 14:47:39 +08:00 committed by Maciej Suminski
parent beed72ffbb
commit 0f5bfdb156
4 changed files with 131 additions and 0 deletions

View File

@ -125,6 +125,10 @@ TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
_( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
TOOL_ACTION COMMON_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
AS_GLOBAL, 0,
_( "Mirror" ), _( "Mirrors selected item" ), mirror_h_xpm );
TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ),
_( "Remove" ), _( "Deletes selected item(s)" ), delete_xpm );

View File

@ -76,6 +76,9 @@ public:
/// Flipping of selected objects
static TOOL_ACTION flip;
/// Mirroring of selected items
static TOOL_ACTION mirror;
/// Activation of the edit tool
static TOOL_ACTION properties;

View File

@ -86,6 +86,10 @@ bool EDIT_TOOL::Init()
return false;
}
auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
return m_editModules;
};
// 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 );
@ -98,6 +102,9 @@ bool EDIT_TOOL::Init()
menu.AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
menu.AddItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
// Mirror only available in modedit
menu.AddItem( COMMON_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty );
// Footprint actions
menu.AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
@ -404,6 +411,115 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
return 0;
}
/*!
* Mirror a point about the vertical axis passing through another point
*/
static wxPoint mirrorPointX( const wxPoint& aPoint, const wxPoint& aMirrorPoint )
{
wxPoint mirrored = aPoint;
mirrored.x -= aMirrorPoint.x;
mirrored.x = -mirrored.x;
mirrored.x += aMirrorPoint.x;
return mirrored;
}
/**
* Mirror a pad in the vertical axis passing through a point
*/
static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
{
wxPoint tmpPt = mirrorPointX( aPad.GetPosition(), aMirrorPoint );
aPad.SetPosition( tmpPt );
aPad.SetX0( aPad.GetPosition().x );
tmpPt = aPad.GetOffset();
tmpPt.x = -tmpPt.x;
aPad.SetOffset( tmpPt );
auto tmpz = aPad.GetDelta();
tmpz.x = -tmpz.x;
aPad.SetDelta( tmpz );
aPad.SetOrientation( -aPad.GetOrientation() );
}
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
wxPoint mirrorPoint = getModificationPoint( selection );
for( auto item : selection )
{
// only modify items we can mirror
switch( item->Type() )
{
case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T:
case PCB_PAD_T:
m_commit->Modify( item );
break;
default:
continue;
}
// modify each object as necessary
switch( item->Type() )
{
case PCB_MODULE_EDGE_T:
{
auto& edge = static_cast<EDGE_MODULE&>( *item );
edge.Mirror( mirrorPoint, false );
break;
}
case PCB_MODULE_TEXT_T:
{
auto& modText = static_cast<TEXTE_MODULE&>( *item );
modText.Mirror( mirrorPoint, false );
break;
}
case PCB_PAD_T:
{
auto& pad = static_cast<D_PAD&>( *item );
mirrorPadX( pad, mirrorPoint );
break;
}
default:
// it's likely the commit object is wrong if you get here
assert( false );
break;
}
}
if( !m_dragging )
m_commit->Push( _( "Mirror" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
// TODO selectionModified
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
editFrame->Refresh();
return 0;
}
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
{
@ -671,6 +787,7 @@ void EDIT_TOOL::SetTransitions()
Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicate.MakeEvent() );
Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicateIncrement.MakeEvent() );
Go( &EDIT_TOOL::CreateArray,COMMON_ACTIONS::createArray.MakeEvent() );
Go( &EDIT_TOOL::Mirror, COMMON_ACTIONS::mirror.MakeEvent() );
Go( &EDIT_TOOL::editFootprintInFpEditor, COMMON_ACTIONS::editFootprintInFpEditor.MakeEvent() );
}

View File

@ -80,6 +80,13 @@ public:
*/
int Flip( const TOOL_EVENT& aEvent );
/**
* Function Mirror
*
* Mirrors the current selection. The mirror axis passes through the current point.
*/
int Mirror( const TOOL_EVENT& aEvent );
/**
* Function Remove()
*