diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 8a473959ee..8676b69643 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -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 ); } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 3cfdadcccc..7e73a0f7ac 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -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 ) diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index c8af03d6c4..7c93b45ff2 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -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; } diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index c5489aa77f..aca7e2782c 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -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 ); } diff --git a/pcbnew/dialogs/dialog_pad_properties.h b/pcbnew/dialogs/dialog_pad_properties.h index 6146056a3e..9ee7f5f264 100644 --- a/pcbnew/dialogs/dialog_pad_properties.h +++ b/pcbnew/dialogs/dialog_pad_properties.h @@ -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 { diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp index 2a71bb1f5b..242edec395 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.cpp +++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp index b1f63b401c..a955b108ab 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.fbp +++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp @@ -261,7 +261,7 @@ - + OnUpdateUI bGeneralSizer @@ -763,7 +763,7 @@ 1 0 - "Through-hole" "SMD" "Connector" "NPTH, Mechanical" + "Through-hole" "SMD" "Connector" "NPTH, Mechanical" "Aperture" 1 1 diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h index 49343c1f56..5aee5fde12 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.h +++ b/pcbnew/dialogs/dialog_pad_properties_base.h @@ -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(); }