ADDED ability to specify where pad number (& net name) go on custom shaped pads.
Fixes https://gitlab.com/kicad/code/kicad/issues/6627
This commit is contained in:
parent
ecd99633d8
commit
281b9d405a
|
@ -55,6 +55,9 @@ EDA_SHAPE::~EDA_SHAPE()
|
|||
|
||||
wxString EDA_SHAPE::ShowShape() const
|
||||
{
|
||||
if( IsAnnotationProxy() )
|
||||
return _( "Number Box" );
|
||||
|
||||
switch( m_shape )
|
||||
{
|
||||
case SHAPE_T::SEGMENT: return _( "Line" );
|
||||
|
@ -599,7 +602,10 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
|
|||
break;
|
||||
|
||||
case SHAPE_T::RECT:
|
||||
aList.emplace_back( shape, _( "Rectangle" ) );
|
||||
if( IsAnnotationProxy() )
|
||||
aList.emplace_back( shape, _( "Pad Number Box" ) );
|
||||
else
|
||||
aList.emplace_back( shape, _( "Rectangle" ) );
|
||||
|
||||
msg = MessageTextFromValue( units, std::abs( GetEnd().x - GetStart().x ) );
|
||||
aList.emplace_back( _( "Width" ), msg );
|
||||
|
@ -773,7 +779,7 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
|||
return TestSegmentHit( aPosition, GetStart(), GetEnd(), maxdist );
|
||||
|
||||
case SHAPE_T::RECT:
|
||||
if( IsFilled() ) // Filled rect hit-test
|
||||
if( IsAnnotationProxy() || IsFilled() ) // Filled rect hit-test
|
||||
{
|
||||
SHAPE_POLY_SET poly;
|
||||
poly.NewOutline();
|
||||
|
@ -783,7 +789,7 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
|||
|
||||
return poly.Collide( aPosition, maxdist );
|
||||
}
|
||||
else // Open rect hit-test
|
||||
else // Open rect hit-test
|
||||
{
|
||||
std::vector<VECTOR2I> pts = GetRectCorners();
|
||||
|
||||
|
@ -1094,7 +1100,7 @@ std::vector<SHAPE*> EDA_SHAPE::makeEffectiveShapes( bool aEdgeOnly, bool aLineCh
|
|||
{
|
||||
std::vector<VECTOR2I> pts = GetRectCorners();
|
||||
|
||||
if( IsFilled() && !aEdgeOnly )
|
||||
if( ( IsFilled() || IsAnnotationProxy() ) && !aEdgeOnly )
|
||||
effectiveShapes.emplace_back( new SHAPE_SIMPLE( pts ) );
|
||||
|
||||
if( width > 0 || !IsFilled() || aEdgeOnly )
|
||||
|
@ -1517,7 +1523,7 @@ void EDA_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
|
|||
{
|
||||
std::vector<VECTOR2I> pts = GetRectCorners();
|
||||
|
||||
if( IsFilled() )
|
||||
if( IsFilled() || IsAnnotationProxy() )
|
||||
{
|
||||
aCornerBuffer.NewOutline();
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ generator
|
|||
grid_origin
|
||||
group
|
||||
gr_arc
|
||||
gr_bbox
|
||||
gr_circle
|
||||
gr_curve
|
||||
gr_line
|
||||
|
|
|
@ -85,6 +85,9 @@ public:
|
|||
|
||||
wxString SHAPE_T_asString() const;
|
||||
|
||||
bool IsAnnotationProxy() const { return m_annotationProxy; }
|
||||
void SetIsAnnotationProxy( bool aIsProxy = true ) { m_annotationProxy = aIsProxy; }
|
||||
|
||||
bool IsFilled() const
|
||||
{
|
||||
return GetFillMode() != FILL_T::NO_FILL;
|
||||
|
@ -376,6 +379,7 @@ protected:
|
|||
SHAPE_POLY_SET m_poly; // Stores the S_POLYGON shape
|
||||
|
||||
int m_editState;
|
||||
bool m_annotationProxy; // A shape storing the position of an annotation
|
||||
};
|
||||
|
||||
#endif // EDA_SHAPE_H
|
||||
|
|
|
@ -208,6 +208,8 @@ public:
|
|||
/// Compound assignment operator
|
||||
VECTOR2<T>& operator*=( const VECTOR2<T>& aVector );
|
||||
|
||||
VECTOR2<T>& operator*=( const T& aScalar );
|
||||
|
||||
/// Compound assignment operator
|
||||
VECTOR2<T>& operator+=( const T& aScalar );
|
||||
|
||||
|
@ -336,6 +338,15 @@ VECTOR2<T>& VECTOR2<T>::operator*=( const VECTOR2<T>& aVector )
|
|||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
VECTOR2<T>& VECTOR2<T>::operator*=( const T& aScalar )
|
||||
{
|
||||
x *= aScalar;
|
||||
y *= aScalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
|
||||
{
|
||||
|
|
|
@ -158,12 +158,34 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
|
|||
m_filledCtrl->Show( true );
|
||||
break;
|
||||
|
||||
case SHAPE_T::RECT:
|
||||
if( m_shape->IsAnnotationProxy() )
|
||||
SetTitle( _( "Number Box" ) );
|
||||
else
|
||||
SetTitle( _( "Rectangle" ) );
|
||||
|
||||
m_startX.SetValue( m_shape->GetStart().x );
|
||||
m_startY.SetValue( m_shape->GetStart().y );
|
||||
m_endX.SetValue( m_shape->GetEnd().x );
|
||||
m_endY.SetValue( m_shape->GetEnd().y );
|
||||
m_ctrl1X.Show( false, true );
|
||||
m_ctrl1Y.Show( false, true );
|
||||
m_ctrl2X.Show( false, true );
|
||||
m_ctrl2Y.Show( false, true );
|
||||
m_staticTextPosCtrl1->Show( false );
|
||||
m_staticTextPosCtrl1->SetSize( 0, 0 );
|
||||
m_staticTextPosCtrl2->Show( false );
|
||||
m_staticTextPosCtrl2->SetSize( 0, 0 );
|
||||
m_radius.Show( false );
|
||||
m_filledCtrl->Show( false );
|
||||
break;
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
// polygon has a specific dialog editor. So nothing here
|
||||
break;
|
||||
|
||||
default:
|
||||
SetTitle( "Unknown basic shape" );
|
||||
SetTitle( "Unknown Basic Shape" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -190,6 +212,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
|
|||
switch( m_shape->GetShape() )
|
||||
{
|
||||
case SHAPE_T::SEGMENT:
|
||||
case SHAPE_T::RECT:
|
||||
m_shape->SetStart( VECTOR2I( m_startX.GetValue(), m_startY.GetValue() ) );
|
||||
m_shape->SetEnd( VECTOR2I( m_endX.GetValue(), m_endY.GetValue() ) );
|
||||
break;
|
||||
|
@ -217,7 +240,6 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
|
|||
break;
|
||||
|
||||
default:
|
||||
SetTitle( "Unknown basic shape" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -706,32 +706,32 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
|
|||
{
|
||||
case SHAPE_T::SEGMENT:
|
||||
bs_info[0] = _( "Segment" );
|
||||
bs_info[1] = _( "from" ) + wxS( " " )+ formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "to" ) + wxS( " " )+ formatCoord( m_units, primitive->GetEnd() );
|
||||
bs_info[1] = _( "from" ) + wxS( " " ) + formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "to" ) + wxS( " " ) + formatCoord( m_units, primitive->GetEnd() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::BEZIER:
|
||||
bs_info[0] = _( "Bezier" );
|
||||
bs_info[1] = _( "from" ) + wxS( " " )+ formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "to" ) + wxS( " " )+ formatCoord( m_units, primitive->GetEnd() );
|
||||
bs_info[1] = _( "from" ) + wxS( " " ) + formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "to" ) + wxS( " " ) + formatCoord( m_units, primitive->GetEnd() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::ARC:
|
||||
bs_info[0] = _( "Arc" );
|
||||
bs_info[1] = _( "center" ) + wxS( " " )+ formatCoord( m_units, primitive->GetCenter() );
|
||||
bs_info[2] = _( "start" ) + wxS( " " )+ formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[3] = _( "angle" ) + wxS( " " )+ EDA_UNIT_UTILS::FormatAngle( primitive->GetArcAngle() );
|
||||
bs_info[1] = _( "center" ) + wxS( " " ) + formatCoord( m_units, primitive->GetCenter() );
|
||||
bs_info[2] = _( "start" ) + wxS( " " ) + formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[3] = _( "angle" ) + wxS( " " ) + EDA_UNIT_UTILS::FormatAngle( primitive->GetArcAngle() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
if( primitive->GetWidth() )
|
||||
bs_info[0] = _( "ring" );
|
||||
bs_info[0] = _( "Ring" );
|
||||
else
|
||||
bs_info[0] = _( "circle" );
|
||||
bs_info[0] = _( "Circle" );
|
||||
|
||||
bs_info[1] = formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "radius" ) + wxS( " " )+ MessageTextFromValue( m_units,
|
||||
primitive->GetRadius() );
|
||||
bs_info[1] = _( "at" ) + wxS( " " ) + formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "radius" ) + wxS( " " ) + MessageTextFromValue( m_units,
|
||||
primitive->GetRadius() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
|
@ -740,6 +740,16 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
|
|||
primitive->GetPolyShape().Outline( 0 ).PointCount() );
|
||||
break;
|
||||
|
||||
case SHAPE_T::RECT:
|
||||
if( primitive->IsAnnotationProxy() )
|
||||
bs_info[0] = _( "Number box" );
|
||||
else
|
||||
bs_info[0] = _( "Rectangle" );
|
||||
|
||||
bs_info[1] = _( "from" ) + wxS( " " ) + formatCoord( m_units, primitive->GetStart() );
|
||||
bs_info[2] = _( "to" ) + wxS( " " ) + formatCoord( m_units, primitive->GetEnd() );
|
||||
break;
|
||||
|
||||
default:
|
||||
bs_info[0] = _( "Unknown primitive" );
|
||||
break;
|
||||
|
@ -2164,7 +2174,8 @@ void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
|
|||
_( "Arc" ),
|
||||
_( "Bezier" ),
|
||||
_( "Ring/Circle" ),
|
||||
_( "Polygon" )
|
||||
_( "Polygon" ),
|
||||
_( "Number box" ),
|
||||
};
|
||||
|
||||
int type = wxGetSingleChoiceIndex( _( "Shape type:" ), _( "Add Primitive" ),
|
||||
|
@ -2175,10 +2186,14 @@ void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
|
|||
return;
|
||||
|
||||
SHAPE_T listtype[] = { SHAPE_T::SEGMENT, SHAPE_T::ARC, SHAPE_T::BEZIER, SHAPE_T::CIRCLE,
|
||||
SHAPE_T::POLY };
|
||||
SHAPE_T::POLY, SHAPE_T::RECT };
|
||||
|
||||
PCB_SHAPE* primitive = new PCB_SHAPE();
|
||||
primitive->SetShape( listtype[type] );
|
||||
|
||||
if( type == arrayDim( shapelist ) - 1 )
|
||||
primitive->SetIsAnnotationProxy();
|
||||
|
||||
primitive->SetStroke( STROKE_PARAMS( m_board->GetDesignSettings().GetLineThickness( F_Cu ),
|
||||
PLOT_DASH_TYPE::SOLID ) );
|
||||
primitive->SetFilled( true );
|
||||
|
|
|
@ -292,6 +292,11 @@ public:
|
|||
void AddPrimitiveCurve( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCtrl1,
|
||||
const VECTOR2I& aCtrl2, int aThickness );
|
||||
|
||||
/**
|
||||
* Has meaning only for custom shape pads. Allows one to specify the box in which to place
|
||||
* the pad number and/or net name (if they are being displayed).
|
||||
*/
|
||||
void AddPrimitiveAnnotationBox( const VECTOR2I& aStart, const VECTOR2I& aEnd );
|
||||
|
||||
bool GetBestAnchorPosition( VECTOR2I& aPos );
|
||||
|
||||
|
@ -723,7 +728,7 @@ private:
|
|||
* Editing definitions of primitives for custom pad shapes. In local coordinates relative
|
||||
* to m_Pos (NOT shapePos) at orient 0.
|
||||
*/
|
||||
std::vector<std::shared_ptr<PCB_SHAPE>> m_editPrimitives;
|
||||
std::vector<std::shared_ptr<PCB_SHAPE>> m_editPrimitives;
|
||||
|
||||
// Must be set to true to force rebuild shapes to draw (after geometry change for instance)
|
||||
mutable bool m_shapesDirty;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 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
|
||||
|
@ -136,7 +136,7 @@ void PAD::AddPrimitiveCircle( const VECTOR2I& aCenter, int aRadius, int aThickne
|
|||
void PAD::AddPrimitiveRect( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aThickness,
|
||||
bool aFilled)
|
||||
{
|
||||
PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T:: RECT );
|
||||
PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T::RECT );
|
||||
item->SetFilled( aFilled );
|
||||
item->SetStart( aStart );
|
||||
item->SetEnd( aEnd );
|
||||
|
@ -147,6 +147,20 @@ void PAD::AddPrimitiveRect( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aT
|
|||
}
|
||||
|
||||
|
||||
void PAD::AddPrimitiveAnnotationBox( const VECTOR2I& aStart, const VECTOR2I& aEnd )
|
||||
{
|
||||
PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T::RECT );
|
||||
item->SetIsAnnotationProxy();
|
||||
item->SetFilled( false );
|
||||
item->SetStart( aStart );
|
||||
item->SetEnd( aEnd );
|
||||
item->SetStroke( STROKE_PARAMS( 1, PLOT_DASH_TYPE::SOLID ) );
|
||||
item->SetParent( this );
|
||||
m_editPrimitives.emplace_back( item );
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
|
||||
void PAD::ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList )
|
||||
{
|
||||
// clear old list
|
||||
|
@ -195,8 +209,11 @@ void PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError,
|
|||
|
||||
for( const std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
|
||||
{
|
||||
primitive->TransformShapeWithClearanceToPolygon( polyset, UNDEFINED_LAYER, 0, aError,
|
||||
aErrorLoc );
|
||||
if( !primitive->IsAnnotationProxy() )
|
||||
{
|
||||
primitive->TransformShapeWithClearanceToPolygon( polyset, UNDEFINED_LAYER, 0, aError,
|
||||
aErrorLoc );
|
||||
}
|
||||
}
|
||||
|
||||
polyset.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||
|
|
|
@ -1017,6 +1017,50 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
|||
VECTOR2D position = padBBox.Centre();
|
||||
VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
|
||||
|
||||
if( aPad->GetFlags() & ENTERED )
|
||||
{
|
||||
FOOTPRINT* fp = static_cast<FOOTPRINT*>( aPad->GetParentFootprint() );
|
||||
|
||||
// Find the number box
|
||||
for( const BOARD_ITEM* aItem : fp->GraphicalItems() )
|
||||
{
|
||||
if( aItem->Type() == PCB_FP_SHAPE_T )
|
||||
{
|
||||
const FP_SHAPE* shape = static_cast<const FP_SHAPE*>( aItem );
|
||||
|
||||
if( shape->IsAnnotationProxy() )
|
||||
{
|
||||
position = shape->GetCenter();
|
||||
padsize = shape->GetBotRight() - shape->GetTopLeft();
|
||||
|
||||
// We normally draw a bit outside the pad, but this will be somewhat
|
||||
// unexpected when the user has drawn a box.
|
||||
padsize *= 0.9;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
|
||||
{
|
||||
// See if we have a number box
|
||||
for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
|
||||
{
|
||||
if( primitive->IsAnnotationProxy() )
|
||||
{
|
||||
position = aPad->GetPosition() + primitive->GetCenter();
|
||||
padsize = primitive->GetBotRight() - primitive->GetTopLeft();
|
||||
|
||||
// We normally draw a bit outside the pad, but this will be somewhat
|
||||
// unexpected when the user has drawn a box.
|
||||
padsize *= 0.9;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aPad->GetShape() != PAD_SHAPE::CUSTOM )
|
||||
{
|
||||
// Don't allow a 45° rotation to bloat a pad's bounding box unnecessarily
|
||||
|
@ -1486,7 +1530,16 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
|
|||
{
|
||||
std::vector<VECTOR2I> pts = aShape->GetRectCorners();
|
||||
|
||||
if( outline_mode )
|
||||
if( aShape->IsAnnotationProxy() )
|
||||
{
|
||||
m_gal->DrawSegment( pts[0], pts[1], thickness );
|
||||
m_gal->DrawSegment( pts[1], pts[2], thickness );
|
||||
m_gal->DrawSegment( pts[2], pts[3], thickness );
|
||||
m_gal->DrawSegment( pts[3], pts[0], thickness );
|
||||
m_gal->DrawSegment( pts[0], pts[2], thickness );
|
||||
m_gal->DrawSegment( pts[1], pts[3], thickness );
|
||||
}
|
||||
else if( outline_mode )
|
||||
{
|
||||
m_gal->DrawSegment( pts[0], pts[1], thickness );
|
||||
m_gal->DrawSegment( pts[1], pts[2], thickness );
|
||||
|
|
|
@ -2462,7 +2462,8 @@ void PCB_PARSER::parseNETCLASS()
|
|||
PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
|
||||
CurTok() == T_gr_rect || CurTok() == T_gr_line || CurTok() == T_gr_poly, nullptr,
|
||||
CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
|
||||
CurTok() == T_gr_poly, nullptr,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_SHAPE." ) );
|
||||
|
||||
T token;
|
||||
|
@ -2603,6 +2604,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_gr_bbox:
|
||||
case T_gr_rect:
|
||||
shape->SetShape( SHAPE_T::RECT );
|
||||
token = NextTok();
|
||||
|
@ -2704,7 +2706,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
|
|||
}
|
||||
|
||||
default:
|
||||
Expecting( "gr_arc, gr_circle, gr_curve, gr_line, gr_poly, or gr_rect" );
|
||||
Expecting( "gr_arc, gr_circle, gr_curve, gr_line, gr_poly, gr_rect or gr_bbox" );
|
||||
}
|
||||
|
||||
bool foundFill = false;
|
||||
|
@ -4980,6 +4982,10 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
|
|||
dummyShape->GetWidth(), dummyShape->IsFilled() );
|
||||
break;
|
||||
|
||||
case T_gr_bbox:
|
||||
dummyShape = parsePCB_SHAPE();
|
||||
pad->AddPrimitiveAnnotationBox( dummyShape->GetStart(), dummyShape->GetEnd() );
|
||||
break;
|
||||
|
||||
case T_gr_poly:
|
||||
dummyShape = parsePCB_SHAPE();
|
||||
|
@ -4995,7 +5001,7 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
|
|||
break;
|
||||
|
||||
default:
|
||||
Expecting( "gr_line, gr_arc, gr_circle, gr_curve, gr_rect or gr_poly" );
|
||||
Expecting( "gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1764,9 +1764,18 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
|
|||
break;
|
||||
|
||||
case SHAPE_T::RECT:
|
||||
m_out->Print( nested_level, "(gr_rect (start %s) (end %s)",
|
||||
FormatInternalUnits( primitive->GetStart() ).c_str(),
|
||||
FormatInternalUnits( primitive->GetEnd() ).c_str() );
|
||||
if( primitive->IsAnnotationProxy() )
|
||||
{
|
||||
m_out->Print( nested_level, "(gr_bbox (start %s) (end %s)",
|
||||
FormatInternalUnits( primitive->GetStart() ).c_str(),
|
||||
FormatInternalUnits( primitive->GetEnd() ).c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_out->Print( nested_level, "(gr_rect (start %s) (end %s)",
|
||||
FormatInternalUnits( primitive->GetStart() ).c_str(),
|
||||
FormatInternalUnits( primitive->GetEnd() ).c_str() );
|
||||
}
|
||||
break;
|
||||
|
||||
case SHAPE_T::ARC:
|
||||
|
|
|
@ -126,7 +126,8 @@ class SHAPE_LINE_CHAIN;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20220609 // Add teardrop keywords to identify teardrop zones
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220621 // Add Image support
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220815 // Add allow-soldermask-bridges-in-FPs flag
|
||||
#define SEXPR_BOARD_FILE_VERSION 20220818 // First-class storage for net-ties
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20220818 // First-class storage for net-ties
|
||||
#define SEXPR_BOARD_FILE_VERSION 20220914 // Number boxes for custom-shape pads
|
||||
|
||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
|
||||
|
|
|
@ -644,6 +644,7 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad )
|
|||
FP_SHAPE* shape = new FP_SHAPE( board()->GetFirstFootprint() );
|
||||
|
||||
shape->SetShape( primitive->GetShape() );
|
||||
shape->SetIsAnnotationProxy( primitive->IsAnnotationProxy());
|
||||
shape->SetFilled( primitive->IsFilled() );
|
||||
shape->SetStroke( primitive->GetStroke() );
|
||||
|
||||
|
@ -687,6 +688,7 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad )
|
|||
|
||||
aPad->SetShape( aPad->GetAnchorPadShape() );
|
||||
aPad->DeletePrimitivesList();
|
||||
aPad->SetFlags( ENTERED );
|
||||
m_editPad = aPad->m_Uuid;
|
||||
}
|
||||
|
||||
|
@ -721,6 +723,9 @@ void PAD_TOOL::recombinePad( PAD* aPad )
|
|||
if( shape->GetLayer() != aLayer )
|
||||
continue;
|
||||
|
||||
if( shape->IsAnnotationProxy() ) // Pad number (and net name) box
|
||||
return (FP_SHAPE*) item;
|
||||
|
||||
SHAPE_POLY_SET drawPoly;
|
||||
shape->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
|
@ -821,12 +826,15 @@ void PAD_TOOL::recombinePad( PAD* aPad )
|
|||
|
||||
pcbShape->Move( - aPad->GetPosition() );
|
||||
pcbShape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() );
|
||||
pcbShape->SetIsAnnotationProxy( fpShape->IsAnnotationProxy());
|
||||
aPad->AddPrimitive( pcbShape );
|
||||
|
||||
fpShape->SetFlags( STRUCT_DELETED );
|
||||
commit.Remove( fpShape );
|
||||
}
|
||||
|
||||
aPad->ClearFlags( ENTERED );
|
||||
|
||||
commit.Push( _( "Recombine pads" ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ using namespace std::placeholders;
|
|||
#include <pcb_textbox.h>
|
||||
#include <pad.h>
|
||||
#include <zone.h>
|
||||
#include <footprint.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <progress_reporter.h>
|
||||
|
||||
|
@ -1269,10 +1270,21 @@ void PCB_POINT_EDITOR::updateItem() const
|
|||
break;
|
||||
}
|
||||
|
||||
// Update relative coordinates for footprint shapes
|
||||
if( FP_SHAPE* fpShape = dynamic_cast<FP_SHAPE*>( item ) )
|
||||
{
|
||||
// Update relative coordinates for footprint shapes
|
||||
fpShape->SetLocalCoord();
|
||||
|
||||
if( fpShape->IsAnnotationProxy() )
|
||||
{
|
||||
for( PAD* pad : fpShape->GetParentFootprint()->Pads() )
|
||||
{
|
||||
if( pad->GetFlags() & ENTERED )
|
||||
view()->Update( pad );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nuke outline font render caches
|
||||
if( PCB_TEXTBOX* textBox = dynamic_cast<PCB_TEXTBOX*>( item ) )
|
||||
textBox->ClearRenderCache();
|
||||
|
|
Loading…
Reference in New Issue