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#include <magic_enum.hpp>
35#include <zone_settings.h>
36
37
39{
40public:
42 CONVERT_SETTINGS* aConvertSettings );
43
45 {
46 delete m_gap;
47 }
48
49 bool TransferDataToWindow() override;
50 bool TransferDataFromWindow() override;
51
52protected:
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
80int InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings, CONVERT_SETTINGS* aConvertSettings )
81{
82 DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aSettings, aConvertSettings );
83
84 return dlg.ShowModal();
85}
86
87#define MIN_THICKNESS 10*pcbIUScale.IU_PER_MILS
88
90 CONVERT_SETTINGS* aConvertSettings ) :
97 m_cornerSmoothingType( ZONE_SETTINGS::CORNER_SMOOTHING::NO_SMOOTHING ),
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, _( "Delete source objects after conversion" ) );
136 bConvertSizer->Add( m_cbDeleteOriginals, 0, wxALL, 5 );
137
138 GetSizer()->Insert( 0, bConvertSizer, 0, wxALL|wxEXPAND, 10 );
139
140 wxStaticLine* line = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
141 GetSizer()->Insert( 1, line, 0, wxLEFT|wxRIGHT|wxEXPAND, 10 );
142
143 SetTitle( _( "Convert to Non Copper Zone" ) );
144 }
145 else
146 {
147 m_gapLabel = nullptr;
148 m_gapCtrl = nullptr;
149 m_gapUnits = nullptr;
150 m_gap = nullptr;
151 }
152
154
155 m_settings.SetupLayersList( m_layers, m_parent, LSET::AllNonCuMask() );
156
158
160}
161
162
164{
166 magic_enum::enum_cast<ZONE_SETTINGS::CORNER_SMOOTHING>( m_cornerSmoothingChoice->GetSelection() )
168
169 if( m_cornerSmoothingType != current )
170 {
171 m_cornerSmoothingType = current;
172
174 m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) );
175 else
176 m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) );
177 }
178
180
181 if( m_gap )
182 m_gap->Enable( m_rbEnvelope->GetValue() );
183}
184
185
187{
189 {
190 if( m_convertSettings->m_Strategy == BOUNDING_HULL )
191 m_rbEnvelope->SetValue( true );
192 else
193 m_rbCenterline->SetValue( true );
194
195 m_cbDeleteOriginals->SetValue( m_convertSettings->m_DeleteOriginals );
196
197 m_gap->Enable( m_rbEnvelope->GetValue() );
198 }
199
200 m_cornerSmoothingChoice->SetSelection( static_cast<int>( m_settings.GetCornerSmoothingType() ) );
201 m_cornerRadius.SetValue( m_settings.GetCornerRadius() );
202
203 m_minWidth.SetValue( m_settings.m_ZoneMinThickness );
204 m_cbLocked->SetValue( m_settings.m_Locked );
205
206 switch( m_settings.m_ZoneBorderDisplayStyle )
207 {
208 case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break;
211 case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break; // Not used
212 }
213
214 m_outlineHatchPitch.SetValue( m_settings.m_BorderHatchPitch );
215
217
218 switch( m_settings.m_FillMode )
219 {
220 case ZONE_FILL_MODE::HATCH_PATTERN: m_GridStyleCtrl->SetSelection( 1 ); break;
221 default: m_GridStyleCtrl->SetSelection( 0 ); break;
222 }
223
225 m_hatchRotation.SetAngleValue( m_settings.m_HatchOrientation );
226
227 // Gives a reasonable value to grid style parameters, if currently there are no defined
228 // parameters for grid pattern thickness and gap (if the value is 0)
229 // the grid pattern thickness default value is (arbitrary) m_ZoneMinThickness * 4
230 // or 1mm
231 // the grid pattern gap default value is (arbitrary) m_ZoneMinThickness * 6
232 // or 1.5 mm
233 int bestvalue = m_settings.m_HatchThickness;
234
235 if( bestvalue <= 0 ) // No defined value for m_hatchWidth
236 bestvalue = std::max( m_settings.m_ZoneMinThickness * 4, pcbIUScale.mmToIU( 1.0 ) );
237
238 m_hatchWidth.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
239
240 bestvalue = m_settings.m_HatchGap;
241
242 if( bestvalue <= 0 ) // No defined value for m_hatchGap
243 bestvalue = std::max( m_settings.m_ZoneMinThickness * 6, pcbIUScale.mmToIU( 1.5 ) );
244
245 m_hatchGap.SetValue( std::max( bestvalue, m_settings.m_ZoneMinThickness ) );
246
247 m_spinCtrlSmoothLevel->SetValue( m_settings.m_HatchSmoothingLevel );
248 m_spinCtrlSmoothValue->SetValue( m_settings.m_HatchSmoothingValue );
249
250 // Enable/Disable some widgets
251 wxCommandEvent event;
252 OnStyleSelection( event );
253
254 return true;
255}
256
257
259{
260 bool enable = m_GridStyleCtrl->GetSelection() >= 1;
261 m_hatchRotation.Enable( enable );
262 m_hatchWidth.Enable( enable );
263 m_hatchGap.Enable( enable );
264 m_smoothLevelLabel->Enable( enable );
265 m_spinCtrlSmoothLevel->Enable( enable );
266 m_smoothValueLabel->Enable( enable );
267 m_spinCtrlSmoothValue->Enable( enable );
268}
269
270
272{
273 if( event.GetColumn() != 0 )
274 return;
275
276 int row = m_layers->ItemToRow( event.GetItem() );
277 bool val = m_layers->GetToggleValue( row, 0 );
278
279 wxVariant layerID;
280 m_layers->GetValue( layerID, row, 2 );
281 m_settings.m_Layers.set( ToLAYER_ID( layerID.GetInteger() ), val );
282}
283
284
286{
288 {
289 if( m_rbEnvelope->GetValue() )
290 m_convertSettings->m_Strategy = BOUNDING_HULL;
291 else
292 m_convertSettings->m_Strategy = CENTERLINE;
293
294 m_convertSettings->m_DeleteOriginals = m_cbDeleteOriginals->GetValue();
295 m_convertSettings->m_Gap = m_gap->GetIntValue();
296 }
297
299 magic_enum::enum_cast<ZONE_SETTINGS::CORNER_SMOOTHING>( m_cornerSmoothingChoice->GetSelection() )
301
302 m_settings.SetCornerSmoothingType( smoothing );
303
304 m_settings.SetCornerRadius( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::CORNER_SMOOTHING::NO_SMOOTHING
305 ? 0 : m_cornerRadius.GetIntValue() );
306
307 m_settings.m_ZoneMinThickness = m_minWidth.GetIntValue();
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 {
319 return false;
320 }
321
322 m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
323
324 if( m_GridStyleCtrl->GetSelection() > 0 )
326 else
328
329
330 if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
331 {
332 int minThickness = m_minWidth.GetIntValue();
333
334 if( !m_hatchWidth.Validate( minThickness, INT_MAX ) )
335 return false;
336
337 if( !m_hatchGap.Validate( minThickness, INT_MAX ) )
338 return false;
339 }
340
341
342 m_settings.m_HatchOrientation = m_hatchRotation.GetAngleValue();
343 m_settings.m_HatchThickness = m_hatchWidth.GetIntValue();
344 m_settings.m_HatchGap = m_hatchGap.GetIntValue();
345 m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
346 m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
347
348 m_settings.m_Locked = m_cbLocked->GetValue();
349
350 // Get the layer selection for this zone
351 int layer = -1;
352
353 for( int ii = 0; ii < m_layers->GetItemCount(); ++ii )
354 {
355 if( m_layers->GetToggleValue( (unsigned) ii, 0 ) )
356 {
357 layer = ii;
358 break;
359 }
360 }
361
362 if( layer < 0 )
363 {
364 DisplayError( this, _( "No layer selected." ) );
365 return false;
366 }
367
368 *m_ptr = m_settings;
369 return true;
370}
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)
ZONE_SETTINGS::CORNER_SMOOTHING m_cornerSmoothingType
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:94
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...
int ShowModal() override
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