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 The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <kiface_base.h>
23#include <confirm.h>
24#include <pcb_edit_frame.h>
25#include <pcbnew_settings.h>
26#include <zone_settings.h>
27#include <widgets/unit_binder.h>
28#include <wx/statbox.h>
29#include <wx/statline.h>
30#include <wx/radiobut.h>
31#include <zones.h>
32
34
35
37{
38public:
40 CONVERT_SETTINGS* aConvertSettings );
41
44
45private:
46 bool TransferDataToWindow() override;
47 bool TransferDataFromWindow() override;
48
49 void OnStyleSelection( wxCommandEvent& event ) override;
50 void OnLayerSelection( wxDataViewEvent& event ) override;
51 void OnUpdateUI( wxUpdateUIEvent& ) override;
52
53private:
56 ZONE_SETTINGS m_settings; // working copy of zone settings
64 wxStaticText* m_gapLabel;
65 wxTextCtrl* m_gapCtrl;
66 wxStaticText* m_gapUnits;
68
70 wxRadioButton* m_rbCenterline;
71 wxRadioButton* m_rbEnvelope;
73};
74
75
77 CONVERT_SETTINGS* aConvertSettings )
78{
79 DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aSettings, aConvertSettings );
80
81 // TODO: why does this require QuasiModal?
82 return dlg.ShowQuasiModal();
83}
84
85#define MIN_THICKNESS 10*pcbIUScale.IU_PER_MILS
86
88 ZONE_SETTINGS* aSettings,
89 CONVERT_SETTINGS* aConvertSettings ) :
97 m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ),
99 m_convertSettings( aConvertSettings ),
100 m_rbCenterline( nullptr ),
101 m_rbEnvelope( nullptr ),
102 m_cbDeleteOriginals( nullptr )
103{
104 m_parent = aParent;
105
106 m_ptr = aSettings;
107 m_settings = *aSettings;
108
109 if( aConvertSettings )
110 {
111 wxStaticBox* bConvertBox = new wxStaticBox( this, wxID_ANY, _( "Conversion Settings" ) );
112 wxStaticBoxSizer* bConvertSizer = new wxStaticBoxSizer( bConvertBox, wxVERTICAL );
113
114 m_rbCenterline = new wxRadioButton( this, wxID_ANY, _( "Use centerlines" ) );
115 bConvertSizer->Add( m_rbCenterline, 0, wxLEFT|wxRIGHT, 5 );
116
117 bConvertSizer->AddSpacer( 2 );
118 m_rbEnvelope = new wxRadioButton( this, wxID_ANY, _( "Create bounding hull" ) );
119 bConvertSizer->Add( m_rbEnvelope, 0, wxLEFT|wxRIGHT, 5 );
120
121 m_gapLabel = new wxStaticText( this, wxID_ANY, _( "Gap:" ) );
122 m_gapCtrl = new wxTextCtrl( this, wxID_ANY );
123 m_gapUnits = new wxStaticText( this, wxID_ANY, _( "mm" ) );
125 m_gap->SetValue( m_convertSettings->m_Gap );
126
127 wxBoxSizer* hullParamsSizer = new wxBoxSizer( wxHORIZONTAL );
128 hullParamsSizer->Add( m_gapLabel, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT, 5 );
129 hullParamsSizer->Add( m_gapCtrl, 1, wxALIGN_CENTRE_VERTICAL|wxLEFT|wxRIGHT, 5 );
130 hullParamsSizer->Add( m_gapUnits, 0, wxALIGN_CENTRE_VERTICAL|wxLEFT, 5 );
131 bConvertSizer->AddSpacer( 2 );
132 bConvertSizer->Add( hullParamsSizer, 0, wxLEFT, 26 );
133
134 bConvertSizer->AddSpacer( 6 );
135 m_cbDeleteOriginals = new wxCheckBox( this, wxID_ANY,
136 _( "Delete source objects after conversion" ) );
137 bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
138
139 GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
140
141 wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
142 wxLI_HORIZONTAL );
143 GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
144
145 SetTitle( _( "Convert to Non Copper Zone" ) );
146 }
147 else
148 {
149 m_gapLabel = nullptr;
150 m_gapCtrl = nullptr;
151 m_gapUnits = nullptr;
152 m_gap = nullptr;
153 }
154
156
157 m_settings.SetupLayersList( m_layers, m_parent, LSET::AllNonCuMask() );
158
160
162}
163
164
166{
167 if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() )
168 {
170
172 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
173 else
174 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
175 }
176
178
179 if( m_gap )
180 m_gap->Enable( m_rbEnvelope->GetValue() );
181}
182
183
185{
187 {
188 if( m_convertSettings->m_Strategy == BOUNDING_HULL )
189 m_rbEnvelope->SetValue( true );
190 else
191 m_rbCenterline->SetValue( true );
192
193 m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
194
195 m_gap->Enable( m_rbEnvelope->GetValue() );
196 }
197
198 m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
199 m_cornerRadius.SetValue( m_settings.GetCornerRadius() );
200
201 m_minWidth.SetValue( m_settings.m_ZoneMinThickness );
202 m_cbLocked->SetValue( m_settings.m_Locked );
203
204 switch( m_settings.m_ZoneBorderDisplayStyle )
205 {
206 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
209 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break; // Not used for standard zones
210 }
211
212 m_outlineHatchPitch.SetValue( m_settings.m_BorderHatchPitch );
213
215
216 switch( m_settings.m_FillMode )
217 {
218 case ZONE_FILL_MODE::HATCH_PATTERN: m_GridStyleCtrl->SetSelection( 1 ); break;
219 default: m_GridStyleCtrl->SetSelection( 0 ); break;
220 }
221
223 m_hatchRotation.SetAngleValue( m_settings.m_HatchOrientation );
224
225 // Gives a reasonable value to grid style parameters, if currently there are no defined
226 // parameters for grid pattern thickness and gap (if the value is 0)
227 // the grid pattern thickness default value is (arbitrary) m_ZoneMinThickness * 4
228 // or 1mm
229 // the grid pattern gap default value is (arbitrary) m_ZoneMinThickness * 6
230 // or 1.5 mm
231 int bestvalue = m_settings.m_HatchThickness;
232
233 if( bestvalue <= 0 ) // No defined value for m_hatchWidth
234 bestvalue = std::max( m_settings.m_ZoneMinThickness * 4, pcbIUScale.mmToIU( 1.0 ) );
235
236 m_hatchWidth.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
237
238 bestvalue = m_settings.m_HatchGap;
239
240 if( bestvalue <= 0 ) // No defined value for m_hatchGap
241 bestvalue = std::max( m_settings.m_ZoneMinThickness * 6, pcbIUScale.mmToIU( 1.5 ) );
242
243 m_hatchGap.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
244
245 m_spinCtrlSmoothLevel->SetValue( m_settings.m_HatchSmoothingLevel );
246 m_spinCtrlSmoothValue->SetValue( m_settings.m_HatchSmoothingValue );
247
248 // Enable/Disable some widgets
249 wxCommandEvent event;
250 OnStyleSelection( event );
251
252 return true;
253}
254
255
257{
258 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
259 m_hatchRotation.Enable( enable );
260 m_hatchWidth.Enable( enable );
261 m_hatchGap.Enable( enable );
262 m_smoothLevelLabel->Enable( enable );
263 m_spinCtrlSmoothLevel->Enable( enable );
264 m_smoothValueLabel->Enable( enable );
265 m_spinCtrlSmoothValue->Enable( enable );
266}
267
268
270{
271 if( event.GetColumn() != 0 )
272 return;
273
274 int row = m_layers->ItemToRow( event.GetItem() );
275 bool val = m_layers->GetToggleValue( row, 0 );
276
277 wxVariant layerID;
278 m_layers->GetValue( layerID, row, 2 );
279 m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), val );
280}
281
282
284{
286 {
287 if( m_rbEnvelope->GetValue() )
288 m_convertSettings->m_Strategy = BOUNDING_HULL;
289 else
290 m_convertSettings->m_Strategy = CENTERLINE;
291
292 m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
293 m_convertSettings->m_Gap = m_gap->GetIntValue();
294 }
295
296 m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
297
298 m_settings.SetCornerRadius( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE
299 ? 0 : m_cornerRadius.GetValue() );
300
301 m_settings.m_ZoneMinThickness = m_minWidth.GetValue();
302
303 switch( m_OutlineDisplayCtrl->GetSelection() )
304 {
305 case 0: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break;
306 case 1: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break;
307 case 2: m_settings.m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break;
308 }
309
312 return false;
313
314 m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetValue();
315
316 if( m_GridStyleCtrl->GetSelection() > 0 )
318 else
320
321
322 if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
323 {
324 int minThickness = m_minWidth.GetValue();
325
326 if( !m_hatchWidth.Validate( minThickness, INT_MAX ) )
327 return false;
328
329 if( !m_hatchGap.Validate( minThickness, INT_MAX ) )
330 return false;
331 }
332
333
334 m_settings.m_HatchOrientation = m_hatchRotation.GetAngleValue();
335 m_settings.m_HatchThickness = m_hatchWidth.GetValue();
336 m_settings.m_HatchGap = m_hatchGap.GetValue();
337 m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
338 m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
339
340 m_settings.m_Locked = m_cbLocked->GetValue();
341
342 // Get the layer selection for this zone
343 int layer = -1;
344 for( int ii = 0; ii < m_layers->GetItemCount(); ++ii )
345 {
346 if( m_layers->GetToggleValue( (unsigned) ii, 0 ) )
347 {
348 layer = ii;
349 break;
350 }
351 }
352
353 if( layer < 0 )
354 {
355 DisplayError( this, _( "No layer selected." ) );
356 return false;
357 }
358
359 *m_ptr = m_settings;
360 return true;
361}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Non Copper Zone Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxBORDER_SUNKEN)
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:79
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition lset.cpp:623
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
ZONE_SETTINGS handles zones parameters.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
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)
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:750
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
@ CENTERLINE
@ BOUNDING_HULL
Class ZONE_SETTINGS used to handle zones parameters in dialogs.
#define ZONE_BORDER_HATCH_MINDIST_MM
Definition zones.h:35
#define ZONE_BORDER_HATCH_MAXDIST_MM
Definition zones.h:36