KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_non_copper_zones_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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
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
26#include <kiface_base.h>
27#include <confirm.h>
28#include <pcb_edit_frame.h>
29#include <pcbnew_settings.h>
30#include <zone_settings.h>
31#include <widgets/unit_binder.h>
32#include <wx/statbox.h>
33#include <wx/statline.h>
34#include <wx/radiobut.h>
35#include <zones.h>
36
38
39
41{
42public:
44 CONVERT_SETTINGS* aConvertSettings );
45
47 { delete m_gap; }
48
49private:
50 bool TransferDataToWindow() override;
51 bool TransferDataFromWindow() override;
52
53 void OnStyleSelection( wxCommandEvent& event ) override;
54 void OnLayerSelection( wxDataViewEvent& event ) override;
55 void OnUpdateUI( wxUpdateUIEvent& ) override;
56
57private:
60 ZONE_SETTINGS m_settings; // working copy of zone settings
68 wxStaticText* m_gapLabel;
69 wxTextCtrl* m_gapCtrl;
70 wxStaticText* m_gapUnits;
72
74 wxRadioButton* m_rbCenterline;
75 wxRadioButton* m_rbEnvelope;
77};
78
79
81 CONVERT_SETTINGS* aConvertSettings )
82{
83 DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aSettings, aConvertSettings );
84
85 // TODO: why does this require QuasiModal?
86 return dlg.ShowQuasiModal();
87}
88
89#define MIN_THICKNESS 10*pcbIUScale.IU_PER_MILS
90
92 ZONE_SETTINGS* aSettings,
93 CONVERT_SETTINGS* aConvertSettings ) :
95 m_outlineHatchPitch( aParent, m_stBorderHatchPitchText,
96 m_outlineHatchPitchCtrl, m_outlineHatchUnits ),
97 m_minWidth( aParent, m_MinWidthLabel, m_MinWidthCtrl, m_MinWidthUnits ),
98 m_hatchRotation( aParent, m_hatchOrientLabel, m_hatchOrientCtrl, m_hatchOrientUnits ),
99 m_hatchWidth( aParent, m_hatchWidthLabel, m_hatchWidthCtrl, m_hatchWidthUnits),
100 m_hatchGap( aParent, m_hatchGapLabel, m_hatchGapCtrl, m_hatchGapUnits ),
101 m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
102 m_cornerRadius( aParent, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
103 m_convertSettings( aConvertSettings ),
104 m_rbCenterline( nullptr ),
105 m_rbEnvelope( nullptr ),
106 m_cbDeleteOriginals( nullptr )
107{
108 m_parent = aParent;
109
110 m_ptr = aSettings;
111 m_settings = *aSettings;
112
113 if( aConvertSettings )
114 {
115 wxStaticBox* bConvertBox = new wxStaticBox( this, wxID_ANY, _( "Conversion Settings" ) );
116 wxStaticBoxSizer* bConvertSizer = new wxStaticBoxSizer( bConvertBox, wxVERTICAL );
117
118 m_rbCenterline = new wxRadioButton( this, wxID_ANY, _( "Use centerlines" ) );
119 bConvertSizer->Add( m_rbCenterline, 0, wxLEFT|wxRIGHT, 5 );
120
121 bConvertSizer->AddSpacer( 2 );
122 m_rbEnvelope = new wxRadioButton( this, wxID_ANY, _( "Create bounding hull" ) );
123 bConvertSizer->Add( m_rbEnvelope, 0, wxLEFT|wxRIGHT, 5 );
124
125 m_gapLabel = new wxStaticText( this, wxID_ANY, _( "Gap:" ) );
126 m_gapCtrl = new wxTextCtrl( this, wxID_ANY );
127 m_gapUnits = new wxStaticText( this, wxID_ANY, _( "mm" ) );
130
131 wxBoxSizer* hullParamsSizer = new wxBoxSizer( wxHORIZONTAL );
132 hullParamsSizer->Add( m_gapLabel, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT, 5 );
133 hullParamsSizer->Add( m_gapCtrl, 1, wxALIGN_CENTRE_VERTICAL|wxLEFT|wxRIGHT, 5 );
134 hullParamsSizer->Add( m_gapUnits, 0, wxALIGN_CENTRE_VERTICAL|wxLEFT, 5 );
135 bConvertSizer->AddSpacer( 2 );
136 bConvertSizer->Add( hullParamsSizer, 0, wxLEFT, 26 );
137
138 bConvertSizer->AddSpacer( 6 );
139 m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
140 _( "Delete source objects after conversion" ) );
141 bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
142
143 GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
144
145 wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
146 wxLI_HORIZONTAL );
147 GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
148
149 SetTitle( _( "Convert to Non Copper Zone" ) );
150 }
151 else
152 {
153 m_gapLabel = nullptr;
154 m_gapCtrl = nullptr;
155 m_gapUnits = nullptr;
156 m_gap = nullptr;
157 }
158
159 bool fpEditorMode = m_parent->IsType( FRAME_FOOTPRINT_EDITOR );
160
162
164
166
168}
169
170
172{
173 if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() )
174 {
176
178 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
179 else
180 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
181 }
182
184
185 if( m_gap )
186 m_gap->Enable( m_rbEnvelope->GetValue() );
187}
188
189
191{
193 {
195 m_rbEnvelope->SetValue( true );
196 else
197 m_rbCenterline->SetValue( true );
198
200
201 m_gap->Enable( m_rbEnvelope->GetValue() );
202 }
203
206
208 m_cbLocked->SetValue( m_settings.m_Locked );
209
211 {
212 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
213 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: m_OutlineDisplayCtrl->SetSelection( 1 ); break;
214 case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: m_OutlineDisplayCtrl->SetSelection( 2 ); break;
215 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break; // Not used for standard zones
216 }
217
219
221
222 switch( m_settings.m_FillMode )
223 {
224 case ZONE_FILL_MODE::HATCH_PATTERN: m_GridStyleCtrl->SetSelection( 1 ); break;
225 default: m_GridStyleCtrl->SetSelection( 0 ); break;
226 }
227
228 m_hatchRotation.SetUnits( EDA_UNITS::DEGREES );
230
231 // Gives a reasonable value to grid style parameters, if currently there are no defined
232 // parameters for grid pattern thickness and gap (if the value is 0)
233 // the grid pattern thickness default value is (arbitrary) m_ZoneMinThickness * 4
234 // or 1mm
235 // the grid pattern gap default value is (arbitrary) m_ZoneMinThickness * 6
236 // or 1.5 mm
237 int bestvalue = m_settings.m_HatchThickness;
238
239 if( bestvalue <= 0 ) // No defined value for m_hatchWidth
240 bestvalue = std::max( m_settings.m_ZoneMinThickness * 4, pcbIUScale.mmToIU( 1.0 ) );
241
242 m_hatchWidth.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
243
244 bestvalue = m_settings.m_HatchGap;
245
246 if( bestvalue <= 0 ) // No defined value for m_hatchGap
247 bestvalue = std::max( m_settings.m_ZoneMinThickness * 6, pcbIUScale.mmToIU( 1.5 ) );
248
249 m_hatchGap.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
250
253
254 // Enable/Disable some widgets
255 wxCommandEvent event;
256 OnStyleSelection( event );
257
258 return true;
259}
260
261
263{
264 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
265 m_hatchRotation.Enable( enable );
266 m_hatchWidth.Enable( enable );
267 m_hatchGap.Enable( enable );
268 m_smoothLevelLabel->Enable( enable );
269 m_spinCtrlSmoothLevel->Enable( enable );
270 m_smoothValueLabel->Enable( enable );
271 m_spinCtrlSmoothValue->Enable( enable );
272}
273
274
276{
277 if( event.GetColumn() != 0 )
278 return;
279
280 int row = m_layers->ItemToRow( event.GetItem() );
281 bool val = m_layers->GetToggleValue( row, 0 );
282
283 wxVariant layerID;
284 m_layers->GetValue( layerID, row, 2 );
285 m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), val );
286}
287
288
290{
292 {
293 if( m_rbEnvelope->GetValue() )
295 else
297
300 }
301
303
305 ? 0 : m_cornerRadius.GetValue() );
306
308
309 switch( m_OutlineDisplayCtrl->GetSelection() )
310 {
311 case 0: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
312 case 1: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
313 case 2: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
314 }
315
318 return false;
319
321
322 if( m_GridStyleCtrl->GetSelection() > 0 )
323 m_settings.m_FillMode = ZONE_FILL_MODE::HATCH_PATTERN;
324 else
325 m_settings.m_FillMode = ZONE_FILL_MODE::POLYGONS;
326
327
328 if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
329 {
330 int minThickness = m_minWidth.GetValue();
331
332 if( !m_hatchWidth.Validate( minThickness, INT_MAX ) )
333 return false;
334
335 if( !m_hatchGap.Validate( minThickness, INT_MAX ) )
336 return false;
337 }
338
339
345
346 m_settings.m_Locked = m_cbLocked->GetValue();
347
348 // Get the layer selection for this zone
349 int layer = -1;
350 for( int ii = 0; ii < m_layers->GetItemCount(); ++ii )
351 {
352 if( m_layers->GetToggleValue( (unsigned) ii, 0 ) )
353 {
354 layer = ii;
355 break;
356 }
357 }
358
359 if( layer < 0 )
360 {
361 DisplayError( this, _( "No layer selected." ) );
362 return false;
363 }
364
365 *m_ptr = m_settings;
366 return true;
367}
368
369
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
BASE_SET & set(size_t pos)
Definition: base_set.h:115
Class DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE.
DIALOG_NON_COPPER_ZONES_EDITOR(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
void OnStyleSelection(wxCommandEvent &event) override
void OnLayerSelection(wxDataViewEvent &event) override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
bool IsType(FRAME_T aType) const
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:687
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
int GetIntValue()
Definition: unit_binder.h:129
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()
virtual void SetAngleValue(const EDA_ANGLE &aValue)
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.
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:78
EDA_ANGLE m_HatchOrientation
Definition: zone_settings.h:96
double m_HatchSmoothingValue
Definition: zone_settings.h:99
int m_ZoneMinThickness
Definition: zone_settings.h:93
void SetCornerRadius(int aRadius)
void SetupLayersList(wxDataViewListCtrl *aList, PCB_BASE_FRAME *aFrame, LSET aLayers, bool aFpEditorMode)
A helper routine for the various zone dialogs (copper, non-copper, keepout).
int GetCornerSmoothingType() const
ZONE_FILL_MODE m_FillMode
Definition: zone_settings.h:91
void SetCornerSmoothingType(int aType)
int m_HatchSmoothingLevel
Definition: zone_settings.h:97
unsigned int GetCornerRadius() const
ZONE_BORDER_DISPLAY_STYLE m_ZoneBorderDisplayStyle
Option to show the zone area (outlines only, short hatches or full hatches.
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.
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeNonCopperZonesEditor invokes up a modal dialog window for non-copper zone editing.
#define _(s)
@ FRAME_FOOTPRINT_EDITOR
Definition: frame_type.h:43
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:154
@ CENTERLINE
@ BOUNDING_HULL
CONVERT_STRATEGY m_Strategy
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
Class ZONE_SETTINGS used to handle zones parameters in dialogs.
#define ZONE_BORDER_HATCH_MINDIST_MM
Definition: zones.h:40
#define ZONE_BORDER_HATCH_MAXDIST_MM
Definition: zones.h:41