Support both X and Y mirroring in FPEditor.
Fixes https://gitlab.com/kicad/code/kicad/issues/12409
This commit is contained in:
parent
0150655ed3
commit
513fc872bb
|
@ -1118,7 +1118,8 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions()
|
|||
|
||||
mgr->SetConditions( PCB_ACTIONS::rotateCw, ENABLE( cond.HasItems() ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::rotateCcw, ENABLE( cond.HasItems() ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::mirror, ENABLE( cond.HasItems() ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::mirrorH, ENABLE( cond.HasItems() ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::mirrorV, ENABLE( cond.HasItems() ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::group, ENABLE( SELECTION_CONDITIONS::MoreThan( 1 ) ) );
|
||||
mgr->SetConditions( PCB_ACTIONS::ungroup, ENABLE( haveAtLeastOneGroupCond ) );
|
||||
|
||||
|
|
|
@ -330,9 +330,7 @@ void FP_SHAPE::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
|
|||
break;
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
// polygon corners coordinates are always relative to the
|
||||
// footprint position, orientation 0
|
||||
m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
|
||||
m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis, aCentre );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1050,7 +1050,8 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
if( primitive->IsAnnotationProxy() )
|
||||
{
|
||||
position = aPad->GetPosition() + primitive->GetCenter();
|
||||
padsize = primitive->GetBotRight() - primitive->GetTopLeft();
|
||||
padsize.x = abs( primitive->GetBotRight().x - primitive->GetTopLeft().x );
|
||||
padsize.y = abs( primitive->GetBotRight().y - primitive->GetTopLeft().y );
|
||||
|
||||
// We normally draw a bit outside the pad, but this will be somewhat
|
||||
// unexpected when the user has drawn a box.
|
||||
|
@ -1080,7 +1081,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
m_gal->Translate( position );
|
||||
|
||||
// Keep the size ratio for the font, but make it smaller
|
||||
if( padsize.x < padsize.y )
|
||||
if( padsize.x < ( padsize.y * 0.95 ) )
|
||||
{
|
||||
m_gal->Rotate( -ANGLE_90.AsRadians() );
|
||||
size = padsize.x;
|
||||
|
|
|
@ -76,7 +76,8 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
|
|||
m_mainToolBar->AddScaledSeparator( this );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::rotateCcw );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::rotateCw );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::mirror );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::mirrorH );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::mirrorV );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::group );
|
||||
m_mainToolBar->Add( PCB_ACTIONS::ungroup );
|
||||
|
||||
|
|
|
@ -197,7 +197,8 @@ bool EDIT_TOOL::Init()
|
|||
menu.AddItem( PCB_ACTIONS::rotateCcw, SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::rotateCw, SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::mirror, inFootprintEditor && SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::mirrorH, inFootprintEditor && SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::mirrorV, inFootprintEditor && SELECTION_CONDITIONS::NotEmpty );
|
||||
menu.AddItem( PCB_ACTIONS::swap, SELECTION_CONDITIONS::MoreThan( 1 ) );
|
||||
|
||||
menu.AddItem( PCB_ACTIONS::properties, propertiesCondition );
|
||||
|
@ -934,11 +935,10 @@ int EDIT_TOOL::FilletTracks( const TOOL_EVENT& aEvent )
|
|||
continue;
|
||||
|
||||
SHAPE_ARC sArc( t1Seg, t2Seg, filletRadiusIU );
|
||||
|
||||
wxPoint t1newPoint, t2newPoint;
|
||||
VECTOR2I t1newPoint, t2newPoint;
|
||||
|
||||
auto setIfPointOnSeg =
|
||||
[]( wxPoint& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
|
||||
[]( VECTOR2I& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
|
||||
{
|
||||
VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
|
||||
|
||||
|
@ -1206,6 +1206,21 @@ static VECTOR2I mirrorPointX( const VECTOR2I& aPoint, const VECTOR2I& aMirrorPoi
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mirror a point about the vertical axis passing through another point.
|
||||
*/
|
||||
static VECTOR2I mirrorPointY( const VECTOR2I& aPoint, const VECTOR2I& aMirrorPoint )
|
||||
{
|
||||
VECTOR2I mirrored = aPoint;
|
||||
|
||||
mirrored.y -= aMirrorPoint.y;
|
||||
mirrored.y = -mirrored.y;
|
||||
mirrored.y += aMirrorPoint.y;
|
||||
|
||||
return mirrored;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mirror a pad in the vertical axis passing through a point (mirror left to right).
|
||||
*/
|
||||
|
@ -1231,6 +1246,31 @@ static void mirrorPadX( PAD& aPad, const VECTOR2I& aMirrorPoint )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mirror a pad in the vertical axis passing through a point (mirror left to right).
|
||||
*/
|
||||
static void mirrorPadY( PAD& aPad, const VECTOR2I& aMirrorPoint )
|
||||
{
|
||||
if( aPad.GetShape() == PAD_SHAPE::CUSTOM )
|
||||
aPad.FlipPrimitives( false ); // mirror primitives top to bottom
|
||||
|
||||
VECTOR2I tmpPt = mirrorPointY( aPad.GetPosition(), aMirrorPoint );
|
||||
aPad.SetPosition( tmpPt );
|
||||
|
||||
aPad.SetY0( aPad.GetPosition().y );
|
||||
|
||||
tmpPt = aPad.GetOffset();
|
||||
tmpPt.y = -tmpPt.y;
|
||||
aPad.SetOffset( tmpPt );
|
||||
|
||||
auto tmpz = aPad.GetDelta();
|
||||
tmpz.y = -tmpz.y;
|
||||
aPad.SetDelta( tmpz );
|
||||
|
||||
aPad.SetOrientation( -aPad.GetOrientation() );
|
||||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( isRouterActive() )
|
||||
|
@ -1252,18 +1292,23 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
|
||||
updateModificationPoint( selection );
|
||||
auto refPoint = selection.GetReferencePoint();
|
||||
wxPoint mirrorPoint( refPoint.x, refPoint.y );
|
||||
VECTOR2I mirrorPoint = selection.GetReferencePoint();
|
||||
|
||||
// When editing footprints, all items have the same parent
|
||||
if( IsFootprintEditor() )
|
||||
m_commit->Modify( selection.Front() );
|
||||
|
||||
// Set the mirroring options. We are mirroring here Left to Right.
|
||||
// Set the mirroring options.
|
||||
// Unfortunately, the mirror function do not have the same parameter for all items
|
||||
// So we need these 2 parameters to avoid mistakes
|
||||
const bool mirrorLeftRight = true;
|
||||
const bool mirrorAroundXaxis = false;
|
||||
bool mirrorLeftRight = true;
|
||||
bool mirrorAroundXaxis = false;
|
||||
|
||||
if( aEvent.IsAction( &PCB_ACTIONS::mirrorV ) )
|
||||
{
|
||||
mirrorLeftRight = false;
|
||||
mirrorAroundXaxis = true;
|
||||
}
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
|
@ -1318,7 +1363,11 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
case PCB_PAD_T:
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( item );
|
||||
mirrorPadX( *pad, mirrorPoint );
|
||||
|
||||
if( mirrorLeftRight )
|
||||
mirrorPadX( *pad, mirrorPoint );
|
||||
else
|
||||
mirrorPadY( *pad, mirrorPoint );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2192,7 +2241,8 @@ void EDIT_TOOL::setTransitions()
|
|||
Go( &EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Duplicate, PCB_ACTIONS::duplicateIncrement.MakeEvent() );
|
||||
Go( &EDIT_TOOL::CreateArray, PCB_ACTIONS::createArray.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorH.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorV.MakeEvent() );
|
||||
Go( &EDIT_TOOL::Swap, PCB_ACTIONS::swap.MakeEvent() );
|
||||
Go( &EDIT_TOOL::ChangeTrackWidth, PCB_ACTIONS::changeTrackWidth.MakeEvent() );
|
||||
Go( &EDIT_TOOL::FilletTracks, PCB_ACTIONS::filletTracks.MakeEvent() );
|
||||
|
|
|
@ -846,7 +846,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
|
|||
else if( evt->IsAction( &PCB_ACTIONS::rotateCw )
|
||||
|| evt->IsAction( &PCB_ACTIONS::rotateCcw )
|
||||
|| evt->IsAction( &PCB_ACTIONS::flip )
|
||||
|| evt->IsAction( &PCB_ACTIONS::mirror ) )
|
||||
|| evt->IsAction( &PCB_ACTIONS::mirrorH )
|
||||
|| evt->IsAction( &PCB_ACTIONS::mirrorV ) )
|
||||
{
|
||||
updateBBox = true;
|
||||
eatFirstMouseUp = false;
|
||||
|
|
|
@ -122,7 +122,8 @@ bool PAD_TOOL::Init()
|
|||
ctxMenu.AddItem( PCB_ACTIONS::rotateCcw, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::rotateCw, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::flip, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::mirror, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::mirrorH, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::mirrorV, SELECTION_CONDITIONS::ShowAlways );
|
||||
ctxMenu.AddItem( PCB_ACTIONS::properties, SELECTION_CONDITIONS::ShowAlways );
|
||||
|
||||
// Finally, add the standard zoom/grid items
|
||||
|
|
|
@ -320,11 +320,16 @@ TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
|
|||
_( "Change Side / Flip" ), _( "Flips selected item(s) to opposite side of board" ),
|
||||
BITMAPS::swap_layer );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::mirror( "pcbnew.InteractiveEdit.mirror",
|
||||
TOOL_ACTION PCB_ACTIONS::mirrorH( "pcbnew.InteractiveEdit.mirrorHoriontally",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Mirror" ), _( "Mirrors selected item" ),
|
||||
_( "Mirror Horizontally" ), _( "Mirrors selected item across the Y axis" ),
|
||||
BITMAPS::mirror_h );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::mirrorV( "pcbnew.InteractiveEdit.mirrorVertically",
|
||||
AS_GLOBAL, 0, "",
|
||||
_( "Mirror Vertically" ), _( "Mirrors selected item across the X axis" ),
|
||||
BITMAPS::mirror_v );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::swap( "pcbnew.InteractiveEdit.swap",
|
||||
AS_GLOBAL,
|
||||
'S', "",
|
||||
|
|
|
@ -117,7 +117,8 @@ public:
|
|||
static TOOL_ACTION flip;
|
||||
|
||||
/// Mirroring of selected items
|
||||
static TOOL_ACTION mirror;
|
||||
static TOOL_ACTION mirrorH;
|
||||
static TOOL_ACTION mirrorV;
|
||||
|
||||
/// Swapping of selected items
|
||||
static TOOL_ACTION swap;
|
||||
|
|
Loading…
Reference in New Issue