KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_zone_properties.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Ethan Chien <[email protected]>
5 * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
6 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
7 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
29
30#include <wx/radiobut.h>
31#include <kiface_base.h>
32#include <confirm.h>
33#include <pcb_edit_frame.h>
34#include <pcbnew_settings.h>
35#include <wx/string.h>
36#include <zones.h>
37#include <widgets/unit_binder.h>
38#include <zone.h>
39#include <pad.h>
40#include <board.h>
41#include <trigo.h>
42#include <eda_pattern_match.h>
43
45#include <string_utils.h>
46
47wxDEFINE_EVENT( EVT_ZONE_NAME_UPDATE, wxCommandEvent );
48
50 ZONES_CONTAINER& aZoneContainer ) :
52 m_ZoneContainer( aZoneContainer ), m_PCB_Frame( aPCB_FRAME ),
53 m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
54 m_outlineHatchPitch( aPCB_FRAME, m_stBorderHatchPitchText, m_outlineHatchPitchCtrl,
55 m_outlineHatchUnits ),
56 m_cornerRadius( aPCB_FRAME, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
57 m_clearance( aPCB_FRAME, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits ),
58 m_minThickness( aPCB_FRAME, m_minWidthLabel, m_minWidthCtrl, m_minWidthUnits ),
59 m_antipadClearance( aPCB_FRAME, m_antipadLabel, m_antipadCtrl, m_antipadUnits ),
60 m_spokeWidth( aPCB_FRAME, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ),
61 m_gridStyleRotation( aPCB_FRAME, m_staticTextGrindOrient, m_tcGridStyleOrientation,
62 m_staticTextRotUnits ),
63 m_gridStyleThickness( aPCB_FRAME, m_staticTextStyleThickness, m_tcGridStyleThickness,
64 m_GridStyleThicknessUnits ),
65 m_gridStyleGap( aPCB_FRAME, m_staticTextGridGap, m_tcGridStyleGap, m_GridStyleGapUnits ),
66 m_islandThreshold( aPCB_FRAME, m_islandThresholdLabel, m_tcIslandThreshold,
67 m_islandThresholdUnits ),
68 m_isTeardrop()
69{
70 m_cbRemoveIslands->Bind( wxEVT_CHOICE,
71 [&]( wxCommandEvent& )
72 {
73 // Area mode is index 2
74 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
75 } );
76}
77
78
80{
81 if( m_settings )
83
85 m_isTeardrop = m_settings->m_TeardropType != TEARDROP_TYPE::TD_NONE;
86
88}
89
91{
93}
94
95
97{
98 if( !m_settings )
99 return false;
100 m_cbLocked->SetValue( m_settings->m_Locked );
101 m_cornerSmoothingChoice->SetSelection( m_settings->GetCornerSmoothingType() );
102 m_cornerRadius.SetValue( m_settings->GetCornerRadius() );
103
104 if( m_isTeardrop ) // outlines are never smoothed: they have already the right shape
105 {
106 m_cornerSmoothingChoice->SetSelection( 0 );
107 m_cornerSmoothingChoice->Enable( false );
109 m_cornerRadius.Enable( false );
110 }
111
112 switch( m_settings->m_ZoneBorderDisplayStyle )
113 {
114 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
115 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: m_OutlineDisplayCtrl->SetSelection( 1 ); break;
116 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: m_OutlineDisplayCtrl->SetSelection( 2 ); break;
117 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break;
118 }
119
120 m_outlineHatchPitch.SetValue( m_settings->m_BorderHatchPitch );
121
122 m_clearance.SetValue( m_settings->m_ZoneClearance );
123 m_minThickness.SetValue( m_settings->m_ZoneMinThickness );
124
125 switch( m_settings->GetPadConnection() )
126 {
127 default:
128 case ZONE_CONNECTION::THERMAL: m_PadInZoneOpt->SetSelection( 1 ); break;
129 case ZONE_CONNECTION::THT_THERMAL: m_PadInZoneOpt->SetSelection( 2 ); break;
130 case ZONE_CONNECTION::NONE: m_PadInZoneOpt->SetSelection( 3 ); break;
131 case ZONE_CONNECTION::FULL: m_PadInZoneOpt->SetSelection( 0 ); break;
132 }
133
134 if( m_isTeardrop )
135 {
136 m_PadInZoneOpt->SetSelection( 0 );
137 m_PadInZoneOpt->Enable( false );
138 }
139
140 // Do not enable/disable antipad clearance and spoke width. They might be needed if
141 // a footprint or pad overrides the zone to specify a thermal connection.
142 m_antipadClearance.SetValue( m_settings->m_ThermalReliefGap );
143 m_spokeWidth.SetValue( m_settings->m_ThermalReliefSpokeWidth );
144
145 m_islandThreshold.SetDataType( EDA_DATA_TYPE::AREA );
146 m_islandThreshold.SetDoubleValue( static_cast<double>( m_settings->GetMinIslandArea() ) );
147
148 m_cbRemoveIslands->SetSelection( static_cast<int>( m_settings->GetIslandRemovalMode() ) );
149
150 m_islandThreshold.Enable( m_settings->GetIslandRemovalMode() == ISLAND_REMOVAL_MODE::AREA );
151
152
153 if( !m_isTeardrop && m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
154 m_GridStyleCtrl->SetSelection( 1 );
155 else
156 m_GridStyleCtrl->SetSelection( 0 );
157
158 m_GridStyleCtrl->Enable( !m_isTeardrop );
159
160 m_gridStyleRotation.SetUnits( EDA_UNITS::DEGREES );
161 m_gridStyleRotation.SetAngleValue( m_settings->m_HatchOrientation );
162 m_gridStyleThickness.SetValue( m_settings->m_HatchThickness );
163 m_gridStyleGap.SetValue( m_settings->m_HatchGap );
164
165 m_spinCtrlSmoothLevel->SetValue( m_settings->m_HatchSmoothingLevel );
166 m_spinCtrlSmoothValue->SetValue( m_settings->m_HatchSmoothingValue );
167
168 m_tcZoneName->SetValue( m_settings->m_Name );
169
170
171 // Enable/Disable some widgets
172 wxCommandEvent aEvent;
173 OnStyleSelection( aEvent );
174 Fit();
175
176 return true;
177}
178
179
180void PANEL_ZONE_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& )
181{
182 if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() )
183 {
185
187 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
188 else
189 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
190 }
191
193}
194
195
197{
198 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
199}
200
201void PANEL_ZONE_PROPERTIES::OnZoneNameChanged( wxCommandEvent& aEvent )
202{
203 wxCommandEvent* evt = new wxCommandEvent( EVT_ZONE_NAME_UPDATE );
204 evt->SetString( m_tcZoneName->GetValue() );
205 wxQueueEvent( m_parent, evt );
206}
207
208
210{
211 if( !m_settings )
212 return false;
213 if( m_GridStyleCtrl->GetSelection() > 0 )
214 m_settings->m_FillMode = ZONE_FILL_MODE::HATCH_PATTERN;
215 else
216 m_settings->m_FillMode = ZONE_FILL_MODE::POLYGONS;
217
218 if( !AcceptOptions() )
219 return false;
220 m_settings->m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
221 m_settings->m_HatchThickness = m_gridStyleThickness.GetValue();
222 m_settings->m_HatchGap = m_gridStyleGap.GetValue();
223 m_settings->m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
224 m_settings->m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
225
226 return true;
227}
228
229
230bool PANEL_ZONE_PROPERTIES::AcceptOptions( bool aUseExportableSetupOnly )
231{
233 return false;
234
236 return false;
237
238 if( !m_cornerRadius.Validate( 0, INT_MAX ) )
239 return false;
240
241 if( !m_spokeWidth.Validate( 0, INT_MAX ) )
242 return false;
243
245
246 if( m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
247 {
248 int minThickness = m_minThickness.GetValue();
249
250 if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) )
251 return false;
252
253 if( !m_gridStyleGap.Validate( minThickness, INT_MAX ) )
254 return false;
255 }
256
257 switch( m_PadInZoneOpt->GetSelection() )
258 {
259 case 3: m_settings->SetPadConnection( ZONE_CONNECTION::NONE ); break;
260 case 2: m_settings->SetPadConnection( ZONE_CONNECTION::THT_THERMAL ); break;
261 case 1: m_settings->SetPadConnection( ZONE_CONNECTION::THERMAL ); break;
262 case 0: m_settings->SetPadConnection( ZONE_CONNECTION::FULL ); break;
263 }
264
265 switch( m_OutlineDisplayCtrl->GetSelection() )
266 {
267 case 0: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
268 case 1: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
269 case 2: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
270 }
271
274 return false;
275
276 m_settings->m_BorderHatchPitch = m_outlineHatchPitch.GetValue();
277
278 m_settings->m_ZoneClearance = m_clearance.GetValue();
279 m_settings->m_ZoneMinThickness = m_minThickness.GetValue();
280
281 m_settings->SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
282
283 m_settings->SetCornerRadius( m_settings->GetCornerSmoothingType()
285 ? 0
287
288 m_settings->m_Locked = m_cbLocked->GetValue();
289
290 m_settings->m_ThermalReliefGap = m_antipadClearance.GetValue();
291 m_settings->m_ThermalReliefSpokeWidth = m_spokeWidth.GetValue();
292
293 if( m_settings->m_ThermalReliefSpokeWidth < m_settings->m_ZoneMinThickness )
294 {
295 DisplayError( this, _( "Thermal spoke width cannot be smaller than the minimum width." ) );
296 return false;
297 }
298
299 m_settings->SetIslandRemovalMode( (ISLAND_REMOVAL_MODE) m_cbRemoveIslands->GetSelection() );
300 m_settings->SetMinIslandArea( m_islandThreshold.GetValue() );
301
302 // If we use only exportable to others zones parameters, exit here:
303 if( aUseExportableSetupOnly )
304 return true;
305
306 m_settings->m_Name = m_tcZoneName->GetValue();
307
308 return true;
309}
310
311
312void PANEL_ZONE_PROPERTIES::OnStyleSelection( wxCommandEvent& aEvent )
313{
314 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
315 m_tcGridStyleThickness->Enable( enable );
316 m_tcGridStyleGap->Enable( enable );
317 m_tcGridStyleOrientation->Enable( enable );
318 m_spinCtrlSmoothLevel->Enable( enable );
319 m_spinCtrlSmoothValue->Enable( enable );
320}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
Class PANEL_ZONE_PROPERTIES_BASE.
PANEL_ZONE_PROPERTIES(wxWindow *aParent, PCB_BASE_FRAME *aPcb, ZONES_CONTAINER &aZoneContainer)
ZONES_CONTAINER & m_ZoneContainer
void ActivateSelectedZone(ZONE *new_zone) override
void OnUserConfirmChange() override
void OnZoneNameChanged(wxCommandEvent &event) override
void OnStyleSelection(wxCommandEvent &event) override
bool AcceptOptions(bool aUseExportableSetupOnly=false)
void OnUpdateUI(wxUpdateUIEvent &) override
void OnRemoveIslandsSelection(wxCommandEvent &event) override
std::shared_ptr< ZONE_SETTINGS > m_settings
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual EDA_ANGLE GetAngleValue()
void SetDataType(EDA_DATA_TYPE aDataType)
Used to override the datatype of the displayed property (default is DISTANCE)
virtual void SetAngleValue(const EDA_ANGLE &aValue)
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
std::shared_ptr< ZONE_SETTINGS > GetZoneSettings(ZONE *zone)
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:71
Handle a list of polygons defining a copper zone.
Definition: zone.h:72
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:161
This file is part of the common library.
#define _(s)
Abstract pattern-matching tool and implementations.
wxDEFINE_EVENT(EVT_ZONE_NAME_UPDATE, wxCommandEvent)
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .
Definition: trigo.h:230
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
Definition: zone_settings.h:58
#define ZONE_CLEARANCE_MAX_VALUE_MM
Definition: zones.h:38
#define ZONE_BORDER_HATCH_MINDIST_MM
Definition: zones.h:40
#define ZONE_THICKNESS_MIN_VALUE_MM
Definition: zones.h:36
#define ZONE_BORDER_HATCH_MAXDIST_MM
Definition: zones.h:41