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
28
29#include <wx/radiobut.h>
30#include <kiface_base.h>
31#include <confirm.h>
32#include <pcb_edit_frame.h>
33#include <pcbnew_settings.h>
34#include <wx/string.h>
35#include <widgets/unit_binder.h>
36#include <pad.h>
37#include <trigo.h>
38
40#include <string_utils.h>
41
42wxDEFINE_EVENT( EVT_ZONE_NAME_UPDATE, wxCommandEvent );
43
45 ZONES_CONTAINER& aZoneContainer ) :
47 m_ZoneContainer( aZoneContainer ),
48 m_PCB_Frame( aPCB_FRAME ),
49 m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
50 m_outlineHatchPitch( aPCB_FRAME, m_stBorderHatchPitchText, m_outlineHatchPitchCtrl,
51 m_outlineHatchUnits ),
52 m_cornerRadius( aPCB_FRAME, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
53 m_clearance( aPCB_FRAME, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits ),
54 m_minThickness( aPCB_FRAME, m_minWidthLabel, m_minWidthCtrl, m_minWidthUnits ),
55 m_antipadClearance( aPCB_FRAME, m_antipadLabel, m_antipadCtrl, m_antipadUnits ),
56 m_spokeWidth( aPCB_FRAME, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ),
57 m_gridStyleRotation( aPCB_FRAME, m_staticTextGrindOrient, m_tcGridStyleOrientation,
58 m_staticTextRotUnits ),
59 m_gridStyleThickness( aPCB_FRAME, m_staticTextStyleThickness, m_tcGridStyleThickness,
60 m_GridStyleThicknessUnits ),
61 m_gridStyleGap( aPCB_FRAME, m_staticTextGridGap, m_tcGridStyleGap, m_GridStyleGapUnits ),
62 m_islandThreshold( aPCB_FRAME, m_islandThresholdLabel, m_tcIslandThreshold,
63 m_islandThresholdUnits ),
64 m_isTeardrop()
65{
66 m_cbRemoveIslands->Bind( wxEVT_CHOICE,
67 [&]( wxCommandEvent& )
68 {
69 // Area mode is index 2
70 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
71 } );
72}
73
74
76{
77 if( m_settings )
79
81 m_isTeardrop = m_settings->m_TeardropType != TEARDROP_TYPE::TD_NONE;
82
84}
85
87{
89}
90
91
93{
94 if( !m_settings )
95 return false;
96
97 m_cbLocked->SetValue( m_settings->m_Locked );
98 m_cornerSmoothingChoice->SetSelection( m_settings->GetCornerSmoothingType() );
99 m_cornerRadius.SetValue( m_settings->GetCornerRadius() );
100
101 if( m_isTeardrop ) // outlines are never smoothed: they have already the right shape
102 {
103 m_cornerSmoothingChoice->SetSelection( 0 );
104 m_cornerSmoothingChoice->Enable( false );
106 m_cornerRadius.Enable( false );
107 }
108
109 switch( m_settings->m_ZoneBorderDisplayStyle )
110 {
111 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
112 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: m_OutlineDisplayCtrl->SetSelection( 1 ); break;
113 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: m_OutlineDisplayCtrl->SetSelection( 2 ); break;
114 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break;
115 }
116
117 m_outlineHatchPitch.SetValue( m_settings->m_BorderHatchPitch );
118
119 m_clearance.SetValue( m_settings->m_ZoneClearance );
120 m_minThickness.SetValue( m_settings->m_ZoneMinThickness );
121
122 switch( m_settings->GetPadConnection() )
123 {
124 default:
125 case ZONE_CONNECTION::THERMAL: m_PadInZoneOpt->SetSelection( 1 ); break;
126 case ZONE_CONNECTION::THT_THERMAL: m_PadInZoneOpt->SetSelection( 2 ); break;
127 case ZONE_CONNECTION::NONE: m_PadInZoneOpt->SetSelection( 3 ); break;
128 case ZONE_CONNECTION::FULL: m_PadInZoneOpt->SetSelection( 0 ); break;
129 }
130
131 if( m_isTeardrop )
132 {
133 m_PadInZoneOpt->SetSelection( 0 );
134 m_PadInZoneOpt->Enable( false );
135 }
136
137 // Do not enable/disable antipad clearance and spoke width. They might be needed if
138 // a footprint or pad overrides the zone to specify a thermal connection.
139 m_antipadClearance.SetValue( m_settings->m_ThermalReliefGap );
140 m_spokeWidth.SetValue( m_settings->m_ThermalReliefSpokeWidth );
141
142 m_islandThreshold.SetDataType( EDA_DATA_TYPE::AREA );
143 m_islandThreshold.SetDoubleValue( static_cast<double>( m_settings->GetMinIslandArea() ) );
144
145 m_cbRemoveIslands->SetSelection( static_cast<int>( m_settings->GetIslandRemovalMode() ) );
146
147 m_islandThreshold.Enable( m_settings->GetIslandRemovalMode() == ISLAND_REMOVAL_MODE::AREA );
148
149
150 if( !m_isTeardrop && m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
151 m_GridStyleCtrl->SetSelection( 1 );
152 else
153 m_GridStyleCtrl->SetSelection( 0 );
154
155 m_GridStyleCtrl->Enable( !m_isTeardrop );
156
157 m_gridStyleRotation.SetUnits( EDA_UNITS::DEGREES );
158 m_gridStyleRotation.SetAngleValue( m_settings->m_HatchOrientation );
159 m_gridStyleThickness.SetValue( m_settings->m_HatchThickness );
160 m_gridStyleGap.SetValue( m_settings->m_HatchGap );
161
162 m_spinCtrlSmoothLevel->SetValue( m_settings->m_HatchSmoothingLevel );
163 m_spinCtrlSmoothValue->SetValue( m_settings->m_HatchSmoothingValue );
164
165 m_tcZoneName->SetValue( m_settings->m_Name );
166
167
168 // Enable/Disable some widgets
169 wxCommandEvent aEvent;
170 OnStyleSelection( aEvent );
171 Fit();
172
173 return true;
174}
175
176
177void PANEL_ZONE_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& )
178{
179 if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() )
180 {
182
184 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
185 else
186 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
187 }
188
190}
191
192
194{
195 m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 );
196}
197
198void PANEL_ZONE_PROPERTIES::OnZoneNameChanged( wxCommandEvent& aEvent )
199{
200 wxCommandEvent* evt = new wxCommandEvent( EVT_ZONE_NAME_UPDATE );
201 evt->SetString( m_tcZoneName->GetValue() );
202 wxQueueEvent( m_parent, evt );
203}
204
205
207{
208 if( !m_settings )
209 return false;
210
211 if( m_GridStyleCtrl->GetSelection() > 0 )
212 m_settings->m_FillMode = ZONE_FILL_MODE::HATCH_PATTERN;
213 else
214 m_settings->m_FillMode = ZONE_FILL_MODE::POLYGONS;
215
216 if( !AcceptOptions() )
217 return false;
218
219 m_settings->m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
220 m_settings->m_HatchThickness = m_gridStyleThickness.GetIntValue();
221 m_settings->m_HatchGap = m_gridStyleGap.GetIntValue();
222 m_settings->m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
223 m_settings->m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
224
225 return true;
226}
227
228
229bool PANEL_ZONE_PROPERTIES::AcceptOptions( bool aUseExportableSetupOnly )
230{
232 return false;
233
235 return false;
236
237 if( !m_cornerRadius.Validate( 0, INT_MAX ) )
238 return false;
239
240 if( !m_spokeWidth.Validate( 0, INT_MAX ) )
241 return false;
242
244
245 if( m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
246 {
247 int minThickness = m_minThickness.GetIntValue();
248
249 if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) )
250 return false;
251
252 if( !m_gridStyleGap.Validate( minThickness, INT_MAX ) )
253 return false;
254 }
255
256 switch( m_PadInZoneOpt->GetSelection() )
257 {
258 case 3: m_settings->SetPadConnection( ZONE_CONNECTION::NONE ); break;
259 case 2: m_settings->SetPadConnection( ZONE_CONNECTION::THT_THERMAL ); break;
260 case 1: m_settings->SetPadConnection( ZONE_CONNECTION::THERMAL ); break;
261 case 0: m_settings->SetPadConnection( ZONE_CONNECTION::FULL ); break;
262 }
263
264 switch( m_OutlineDisplayCtrl->GetSelection() )
265 {
266 case 0: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
267 case 1: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
268 case 2: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
269 }
270
273 return false;
274
275 m_settings->m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
276
277 m_settings->m_ZoneClearance = m_clearance.GetIntValue();
278 m_settings->m_ZoneMinThickness = m_minThickness.GetIntValue();
279
280 m_settings->SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
281
282 if( m_settings->GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE )
283 m_settings->SetCornerRadius( 0 );
284 else
285 m_settings->SetCornerRadius( m_cornerRadius.GetIntValue() );
286
287 m_settings->m_Locked = m_cbLocked->GetValue();
288
289 m_settings->m_ThermalReliefGap = m_antipadClearance.GetValue();
290 m_settings->m_ThermalReliefSpokeWidth = m_spokeWidth.GetValue();
291
292 if( m_settings->m_ThermalReliefSpokeWidth < m_settings->m_ZoneMinThickness )
293 {
294 DisplayError( this, _( "Thermal spoke width cannot be smaller than the minimum width." ) );
295 return false;
296 }
297
298 m_settings->SetIslandRemovalMode( (ISLAND_REMOVAL_MODE) m_cbRemoveIslands->GetSelection() );
299 m_settings->SetMinIslandArea( m_islandThreshold.GetValue() );
300
301 // If we use only exportable to others zones parameters, exit here:
302 if( aUseExportableSetupOnly )
303 return true;
304
305 m_settings->m_Name = m_tcZoneName->GetValue();
306
307 return true;
308}
309
310
311void PANEL_ZONE_PROPERTIES::OnStyleSelection( wxCommandEvent& aEvent )
312{
313 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
314 m_tcGridStyleThickness->Enable( enable );
315 m_tcGridStyleGap->Enable( enable );
316 m_tcGridStyleOrientation->Enable( enable );
317 m_spinCtrlSmoothLevel->Enable( enable );
318 m_spinCtrlSmoothValue->Enable( enable );
319}
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.
int GetIntValue()
Definition: unit_binder.h:127
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:72
Handle a list of polygons defining a copper zone.
Definition: zone.h:73
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
This file is part of the common library.
#define _(s)
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:170
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
Definition: zone_settings.h:59
#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