Promote aperture pads to first-class citizens.

Well, almost anyway.  We can't use a pad attribute for them as
that would change the file format.  So they're currently
defined as a CONN pad with no copper layers.

However, when figuring out of existing pads should be *treated*
as aperture pads, we just check for no copper layers.

Fixes: lp:1781760
* https://bugs.launchpad.net/kicad/+bug/1781760
This commit is contained in:
Jeff Young 2018-07-24 14:56:20 +01:00
parent 4618c64213
commit 2d4ba56ac0
8 changed files with 108 additions and 49 deletions

View File

@ -1298,7 +1298,7 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
break;
}
if( aIncrementPadNumbers && new_pad )
if( aIncrementPadNumbers && new_pad && !new_pad->IsAperturePad() )
{
new_pad->IncrementPadName( true, true );
}

View File

@ -123,6 +123,14 @@ LSET D_PAD::UnplatedHoleMask()
return saved;
}
LSET D_PAD::ApertureMask()
{
static LSET saved = LSET( 1, F_Paste );
return saved;
}
bool D_PAD::IsFlipped() const
{
if( GetParent() && GetParent()->GetLayer() == B_Cu )

View File

@ -150,6 +150,7 @@ public:
static LSET ConnSMDMask(); ///< layer set for a SMD pad on Front layer
///< used for edge board connectors
static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
static LSET ApertureMask(); ///< layer set for an aperture pad
static inline bool ClassOf( const EDA_ITEM* aItem )
{
@ -399,11 +400,14 @@ public:
void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
LSET GetLayerSet() const override { return m_layerMask; }
bool IsAperturePad() const { return ( m_layerMask & LSET::AllCuMask() ).none(); }
void SetAttribute( PAD_ATTR_T aAttribute );
PAD_ATTR_T GetAttribute() const { return m_Attribute; }
// We don't currently have an attribute for APERTURE, and adding one will change the file
// format, so for now just infer a copper-less pad to be an APERTURE pad.
bool IsAperturePad() const { return ( m_layerMask & LSET::AllCuMask() ).none(); }
void SetPadToDieLength( int aLength ) { m_LengthPadToDie = aLength; }
int GetPadToDieLength() const { return m_LengthPadToDie; }

View File

@ -83,7 +83,8 @@ static PAD_ATTR_T code_type[] =
PAD_ATTRIB_STANDARD,
PAD_ATTRIB_SMD,
PAD_ATTRIB_CONN,
PAD_ATTRIB_HOLE_NOT_PLATED
PAD_ATTRIB_HOLE_NOT_PLATED,
PAD_ATTRIB_CONN // Aperture pad (type CONN with no copper layers)
};
// Default mask layers setup for pads according to the pad type
@ -92,7 +93,8 @@ static const LSET std_pad_layers[] =
D_PAD::StandardMask(), // PAD_ATTRIB_STANDARD:
D_PAD::SMDMask(), // PAD_ATTRIB_SMD:
D_PAD::ConnSMDMask(), // PAD_ATTRIB_CONN:
D_PAD::UnplatedHoleMask() // PAD_ATTRIB_HOLE_NOT_PLATED:
D_PAD::UnplatedHoleMask(), // PAD_ATTRIB_HOLE_NOT_PLATED:
D_PAD::ApertureMask()
};
@ -683,14 +685,18 @@ void DIALOG_PAD_PROPERTIES::initValues()
enablePrimitivePage( PAD_SHAPE_CUSTOM == m_dummyPad->GetShape() );
// Type of pad selection
m_PadType->SetSelection( 0 );
for( unsigned ii = 0; ii < DIM( code_type ); ii++ )
if( m_dummyPad->GetAttribute() == PAD_ATTRIB_CONN && m_dummyPad->IsAperturePad() )
{
if( code_type[ii] == m_dummyPad->GetAttribute() )
m_PadType->SetSelection( 4 );
}
else
{
switch( m_dummyPad->GetAttribute() )
{
m_PadType->SetSelection( ii );
break;
case PAD_ATTRIB_STANDARD: m_PadType->SetSelection( 0 ); break;
case PAD_ATTRIB_SMD: m_PadType->SetSelection( 1 ); break;
case PAD_ATTRIB_CONN: m_PadType->SetSelection( 2 ); break;
case PAD_ATTRIB_HOLE_NOT_PLATED: m_PadType->SetSelection( 3 ); break;
}
}
@ -922,28 +928,6 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
{
if( m_PadType->GetSelection() == 1 || m_PadType->GetSelection() == 2 )
{
// pad type = SMD or CONN: no hole allowed
m_holeX.Enable( false );
m_holeY.Enable( false );
}
else
{
switch( m_holeShapeCtrl->GetSelection() )
{
case 0: //CIRCLE:
m_holeX.Enable( true );
m_holeY.Enable( false );
break;
case 1: //OVAL:
m_holeX.Enable( true );
m_holeY.Enable( true );
break;
}
}
transferDataToPad( m_dummyPad );
redraw();
}
@ -958,29 +942,88 @@ void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
{
unsigned ii = m_PadType->GetSelection();
int ii = m_PadType->GetSelection();
if( ii >= DIM( code_type ) ) // catches < 0 also
ii = 0;
bool hasHole, hasConnection;
switch( ii )
{
default:
case 0: /* PTH */ hasHole = true; hasConnection = true; break;
case 1: /* SMD */ hasHole = false; hasConnection = true; break;
case 2: /* CONN */ hasHole = false; hasConnection = true; break;
case 3: /* NPTH */ hasHole = true; hasConnection = false; break;
case 4: /* Aperture */ hasHole = false; hasConnection = false; break;
}
LSET layer_mask = std_pad_layers[ii];
setPadLayersList( layer_mask );
// Enable/disable drill dialog items:
event.SetId( m_holeShapeCtrl->GetSelection() );
OnDrillShapeSelected( event );
if( !hasHole )
{
m_holeX.SetValue( 0 );
m_holeY.SetValue( 0 );
}
else if ( m_holeX.GetValue() == 0 && m_currentPad )
{
m_holeX.SetValue( m_currentPad->GetDrillSize().x );
m_holeY.SetValue( m_currentPad->GetDrillSize().y );
}
m_holeShapeLabel->Enable( ii == 0 || ii == DIM( code_type ) - 1 );
m_holeShapeCtrl->Enable( ii == 0 || ii == DIM( code_type ) - 1 );
if( !hasConnection )
{
m_PadNumCtrl->SetValue( wxEmptyString );
m_PadNetNameCombo->SetSelectedNet( 0 );
m_padToDie.SetValue( 0 );
}
else if( m_PadNumCtrl->GetValue().IsEmpty() && m_currentPad )
{
m_PadNumCtrl->SetValue( m_currentPad->GetName() );
m_PadNetNameCombo->SetSelectedNet( m_currentPad->GetNetCode() );
}
// Enable/disable Pad name,and pad length die
// (disable for NPTH pads (mechanical pads)
bool enable = ii != 3;
m_PadNumText->Enable( enable );
m_PadNumCtrl->Enable( enable );
m_PadNameText->Enable( enable );
m_PadNetNameCombo->Enable( enable && m_canEditNetName && m_currentPad );
m_padToDie.Enable( enable );
transferDataToPad( m_dummyPad );
redraw();
}
void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
{
int ii = m_PadType->GetSelection();
if( ii >= DIM( code_type ) ) // catches < 0 also
ii = 0;
bool hasHole, hasConnection;
switch( ii )
{
default:
case 0: /* PTH */ hasHole = true; hasConnection = true; break;
case 1: /* SMD */ hasHole = false; hasConnection = true; break;
case 2: /* CONN */ hasHole = false; hasConnection = true; break;
case 3: /* NPTH */ hasHole = true; hasConnection = false; break;
case 4: /* Aperture */ hasHole = false; hasConnection = false; break;
}
// Enable/disable hole controls
m_holeShapeLabel->Enable( hasHole );
m_holeShapeCtrl->Enable( hasHole );
m_holeX.Enable( hasHole );
m_holeY.Enable( hasHole && m_holeShapeCtrl->GetSelection() == 1 );
// Enable/disable Pad number, net and pad length-to-die
m_PadNumText->Enable( hasConnection );
m_PadNumCtrl->Enable( hasConnection );
m_PadNameText->Enable( hasConnection );
m_PadNetNameCombo->Enable( hasConnection && m_canEditNetName && m_currentPad );
m_padToDie.Enable( hasConnection );
// Enable/disable Copper Layers control
m_rbCopperLayersSel->Enable( ii != 4 );
}

View File

@ -122,6 +122,7 @@ private:
void OnInitDialog( wxInitDialogEvent& event ) override;
void OnResize( wxSizeEvent& event );
void OnCancel( wxCommandEvent& event ) override;
virtual void OnUpdateUI( wxUpdateUIEvent& event ) override;
void OnUpdateUINonCopperWarning( wxUpdateUIEvent& event ) override
{

View File

@ -62,7 +62,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_staticText44->Wrap( -1 );
fgSizerShapeType->Add( m_staticText44, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 3 );
wxString m_PadTypeChoices[] = { _("Through-hole"), _("SMD"), _("Connector"), _("NPTH, Mechanical") };
wxString m_PadTypeChoices[] = { _("Through-hole"), _("SMD"), _("Connector"), _("NPTH, Mechanical"), _("Aperture") };
int m_PadTypeNChoices = sizeof( m_PadTypeChoices ) / sizeof( wxString );
m_PadType = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PadTypeNChoices, m_PadTypeChoices, 0 );
m_PadType->SetSelection( 0 );
@ -721,6 +721,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnInitDialog ) );
m_panelGeneral->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnUpdateUI ), NULL, this );
m_PadNumCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_PadNetNameCombo->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_PadType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this );
@ -769,6 +770,7 @@ DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnInitDialog ) );
m_panelGeneral->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnUpdateUI ), NULL, this );
m_PadNumCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_PadNetNameCombo->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_PadType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this );

View File

@ -261,7 +261,7 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<event name="OnUpdateUI">OnUpdateUI</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bGeneralSizer</property>
@ -763,7 +763,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Through-hole&quot; &quot;SMD&quot; &quot;Connector&quot; &quot;NPTH, Mechanical&quot;</property>
<property name="choices">&quot;Through-hole&quot; &quot;SMD&quot; &quot;Connector&quot; &quot;NPTH, Mechanical&quot; &quot;Aperture&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>

View File

@ -188,6 +188,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnValuesChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void PadTypeSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPadShapeSelection( wxCommandEvent& event ) { event.Skip(); }