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:
parent
beed72ffbb
commit
0f5bfdb156
|
@ -125,6 +125,10 @@ TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
|
||||||
_( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
|
_( "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",
|
TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ),
|
||||||
_( "Remove" ), _( "Deletes selected item(s)" ), delete_xpm );
|
_( "Remove" ), _( "Deletes selected item(s)" ), delete_xpm );
|
||||||
|
|
|
@ -76,6 +76,9 @@ public:
|
||||||
/// Flipping of selected objects
|
/// Flipping of selected objects
|
||||||
static TOOL_ACTION flip;
|
static TOOL_ACTION flip;
|
||||||
|
|
||||||
|
/// Mirroring of selected items
|
||||||
|
static TOOL_ACTION mirror;
|
||||||
|
|
||||||
/// Activation of the edit tool
|
/// Activation of the edit tool
|
||||||
static TOOL_ACTION properties;
|
static TOOL_ACTION properties;
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,10 @@ bool EDIT_TOOL::Init()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
|
||||||
|
return m_editModules;
|
||||||
|
};
|
||||||
|
|
||||||
// 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 );
|
||||||
|
@ -98,6 +102,9 @@ bool EDIT_TOOL::Init()
|
||||||
menu.AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
|
menu.AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
|
||||||
menu.AddItem( COMMON_ACTIONS::createArray, 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
|
// Footprint actions
|
||||||
menu.AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
|
menu.AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
|
||||||
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
|
SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
|
||||||
|
@ -404,6 +411,115 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
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 )
|
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::duplicate.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicateIncrement.MakeEvent() );
|
Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicateIncrement.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::CreateArray,COMMON_ACTIONS::createArray.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() );
|
Go( &EDIT_TOOL::editFootprintInFpEditor, COMMON_ACTIONS::editFootprintInFpEditor.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,13 @@ public:
|
||||||
*/
|
*/
|
||||||
int Flip( const TOOL_EVENT& aEvent );
|
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()
|
* Function Remove()
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue