KiCad PCB EDA Suite
sel_layer.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
9  * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 
30 #include <fctsys.h>
31 #include <common.h>
32 #include <class_drawpanel.h>
33 #include <confirm.h>
34 #include <wxBasePcbFrame.h>
36 #include <class_board.h>
38 
39 
40 /* classes to display a layer list using a wxGrid.
41  */
43 {
44 public:
47  {
48  m_brd = aBrd;
49  }
50 
51 protected:
53 
54  // Returns true if the layer id is enabled (i.e. is it should be displayed)
55  bool IsLayerEnabled( LAYER_NUM aLayer ) const override
56  {
57  return m_brd->IsLayerEnabled( PCB_LAYER_ID( aLayer ) );
58  }
59 
60  // Returns a color index from the layer id
61  // Virtual function
62  COLOR4D GetLayerColor( LAYER_NUM aLayer ) const override
63  {
64  return m_brd->GetLayerColor( ToLAYER_ID( aLayer ) );
65  }
66 
67  // Returns the name of the layer id
68  wxString GetLayerName( LAYER_NUM aLayer ) const override
69  {
70  return m_brd->GetLayerName( ToLAYER_ID( aLayer ) );
71  }
72 };
73 
74 
75 /*
76  * This class display a pcb layers list in a dialog,
77  * to select one layer from this list
78  */
81 {
84 
85  std::vector<PCB_LAYER_ID> m_layersIdLeftColumn;
86  std::vector<PCB_LAYER_ID> m_layersIdRightColumn;
87 
88 public:
89  PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd,
90  PCB_LAYER_ID aDefaultLayer,
91  LSET aNotAllowedLayersMask );
92 
94 
95 private:
96  // Event handlers
97  void OnLeftGridCellClick( wxGridEvent& event ) override;
98  void OnRightGridCellClick( wxGridEvent& event ) override;
99 
100  void buildList();
101 };
102 
103 
105  BOARD* aBrd, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask )
106  : PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
107 {
108  m_layerSelected = aDefaultLayer;
109  m_notAllowedLayersMask = aNotAllowedLayersMask;
110  buildList();
111  Layout();
112  GetSizer()->SetSizeHints( this );
113  SetFocus();
114 }
115 
116 
117 // Build the layers list
118 // Column position by function:
119 #define SELECT_COLNUM 0
120 #define COLOR_COLNUM 1
121 #define LAYERNAME_COLNUM 2
122 
124 {
125  // Hide layerid column which is used only to know the layer id
126  // not to be shown in dialogs
127  m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
128  m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
129 
130  int left_row = 0;
131  int right_row = 0;
132  wxString layername;
133 
134  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
135  {
136  PCB_LAYER_ID layerid = *ui_seq;
137 
138  if( m_notAllowedLayersMask[layerid] )
139  continue;
140 
141  COLOR4D color = GetLayerColor( layerid );
142  layername = GetLayerName( layerid );
143 
144  if( IsCopperLayer( layerid ) )
145  {
146  if( left_row )
147  m_leftGridLayers->AppendRows( 1 );
148 
149  m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM,
150  color.ToColour() );
151  m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM,
152  layername );
153 
154  if( m_layerSelected == layerid )
155  {
156  m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM,
157  wxT("X") );
158  m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM,
159  color.ToColour() );
160  m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM );
161  }
162 
163  m_layersIdLeftColumn.push_back( layerid );
164  left_row++;
165  }
166  else
167  {
168  if( right_row )
169  m_rightGridLayers->AppendRows( 1 );
170 
171  m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM,
172  color.ToColour() );
173  m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM,
174  layername );
175 
176  if( m_layerSelected == layerid )
177  {
178  m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM,
179  wxT("X") );
180  m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM,
181  color.ToColour() );
182  m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM );
183  }
184 
185  m_layersIdRightColumn.push_back( layerid );
186  right_row++;
187  }
188  }
189 
190  // Show only populated lists:
191  if( left_row <= 0 )
192  m_leftGridLayers->Show( false );
193 
194  if( right_row <= 0 )
195  m_rightGridLayers->Show( false );
196 
197  m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
198  m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
199  m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
200  m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
201 }
202 
203 
205 {
206  m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
207  m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
208  EndModal( 1 );
209 }
210 
211 
213 {
214  m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
215  m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
216  EndModal( 2 );
217 }
218 
219 
221  LSET aNotAllowedLayersMask, wxPoint aDlgPosition )
222 {
223  PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask );
224 
225  if( aDlgPosition != wxDefaultPosition )
226  {
227  wxSize dlgSize = dlg.GetSize();
228  aDlgPosition.x -= dlgSize.x/2;
229  aDlgPosition.y -= dlgSize.y/2;
230  dlg.SetPosition( aDlgPosition );
231  }
232 
233  dlg.ShowModal();
234 
235  PCB_LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() );
236  return layer;
237 }
238 
239 
247 {
248 private:
253 
254  std::vector<PCB_LAYER_ID> m_layersId;
255 
256 public:
257  SELECT_COPPER_LAYERS_PAIR_DIALOG( wxWindow* aParent, BOARD* aPcb,
258  PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer );
259 
260  void GetLayerPair( PCB_LAYER_ID& aFrontLayer, PCB_LAYER_ID& aBackLayer )
261  {
262  aFrontLayer = m_frontLayer;
263  aBackLayer = m_backLayer;
264  }
265 
266 private:
267  void OnLeftGridCellClick( wxGridEvent& event ) override;
268  void OnRightGridCellClick( wxGridEvent& event ) override;
269 
270  void OnOkClick( wxCommandEvent& event )
271  {
272  EndModal( wxID_OK );
273  }
274 
275  void OnCancelClick( wxCommandEvent& event ) override
276  {
277  EndModal( wxID_CANCEL );
278  }
279 
280  void buildList();
281  void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable );
282 };
283 
284 
286 {
287  PCB_SCREEN* screen = GetScreen();
288 
290  screen->m_Route_Layer_TOP,
291  screen->m_Route_Layer_BOTTOM );
292 
293  if( dlg.ShowModal() == wxID_OK )
294  {
295  dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM );
296 
297  // select the same layer for both layers is allowed (normal in some boards)
298  // but could be a mistake. So display an info message
299  if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM )
300  DisplayInfoMessage( this,
301  _( "Warning: The Top Layer and Bottom Layer are same." ) );
302  }
303 
305 }
306 
307 
309  wxWindow* aParent, BOARD * aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer) :
310  PCB_LAYER_SELECTOR( aPcb ),
312 {
313  m_frontLayer = aFrontLayer;
314  m_backLayer = aBackLayer;
315  m_leftRowSelected = 0;
316  m_rightRowSelected = 0;
317  buildList();
318  SetFocus();
319  GetSizer()->SetSizeHints( this );
320  Center();
321 }
322 
323 
325 {
326  m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
327  m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
328 
329  // Select a not show cell, to avoid a wrong cell selection for user
330 
331  int row = 0;
332  wxString layername;
333 
334  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
335  {
336  PCB_LAYER_ID layerid = *ui_seq;
337 
338  if( !IsCopperLayer( layerid ) )
339  break;
340 
341  COLOR4D color = GetLayerColor( layerid );
342 
343  layername = GetLayerName( layerid );
344 
345  if( row )
346  m_leftGridLayers->AppendRows( 1 );
347 
348  m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color.ToColour() );
349  m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
350  m_layersId.push_back( layerid );
351 
352  if( m_frontLayer == layerid )
353  {
354  SetGridCursor( m_leftGridLayers, row, true );
355  m_leftRowSelected = row;
356  }
357 
358  if( row )
359  m_rightGridLayers->AppendRows( 1 );
360  m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM,
361  color.ToColour() );
362  m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM,
363  layername );
364 
365  if( m_backLayer == layerid )
366  {
367  SetGridCursor( m_rightGridLayers, row, true );
368  m_rightRowSelected = row;
369  }
370 
371  row++;
372  }
373 
374  m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
375  m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
376  m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
377  m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
378 }
379 
380 
382  bool aEnable )
383 {
384  if( aEnable )
385  {
386  PCB_LAYER_ID layerid = m_layersId[aRow];
387  COLOR4D color = GetLayerColor( layerid );
388  aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") );
389  aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color.ToColour() );
390  aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
391  }
392  else
393  {
394  aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString );
395  aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM,
396  aGrid->GetDefaultCellBackgroundColour() );
397  aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
398  }
399 }
400 
401 
403 {
404  int row = event.GetRow();
405  PCB_LAYER_ID layer = m_layersId[row];
406 
407  if( m_frontLayer == layer )
408  return;
409 
411  m_frontLayer = layer;
412  m_leftRowSelected = row;
414 }
415 
416 
418 {
419  int row = event.GetRow();
420  PCB_LAYER_ID layer = m_layersId[row];
421 
422  if( m_backLayer == layer )
423  return;
424 
426  m_backLayer = layer;
427  m_rightRowSelected = row;
429 }
Class DIALOG_LAYER_SELECTION_BASE.
COLOR4D GetLayerColor(PCB_LAYER_ID aLayer) const
Function GetLayerColor gets a layer color for any valid layer, including non-copper ones...
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:204
This file is part of the common library.
#define SELECT_COLNUM
Definition: sel_layer.cpp:119
Class BOARD to handle a board.
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
Function IsLayerEnabled is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:431
bool IsLayerEnabled(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:55
BOARD * GetBoard() const
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:402
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:348
std::vector< PCB_LAYER_ID > m_layersId
Definition: sel_layer.cpp:254
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
void GetLayerPair(PCB_LAYER_ID &aFrontLayer, PCB_LAYER_ID &aBackLayer)
Definition: sel_layer.cpp:260
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
Classes used in Pcbnew, CvPcb and GerbView.
std::vector< PCB_LAYER_ID > m_layersIdRightColumn
Definition: sel_layer.cpp:86
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
LAYER_NUM GetLayerSelection()
Definition: sel_layer.cpp:93
PCB_LAYER_ID m_Route_Layer_BOTTOM
std::vector< PCB_LAYER_ID > m_layersIdLeftColumn
Definition: sel_layer.cpp:85
PCB_LAYER_SELECTOR(BOARD *aBrd)
Definition: sel_layer.cpp:45
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
SELECT_COPPER_LAYERS_PAIR_DIALOG(wxWindow *aParent, BOARD *aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer)
Definition: sel_layer.cpp:308
#define COLOR_COLNUM
Definition: sel_layer.cpp:120
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
PCB_ONE_LAYER_SELECTOR(wxWindow *aParent, BOARD *aBrd, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask)
Definition: sel_layer.cpp:104
void DisplayInfoMessage(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:89
PCB_LAYER_ID m_layerSelected
Definition: sel_layer.cpp:82
void OnOkClick(wxCommandEvent &event)
Definition: sel_layer.cpp:270
wxString GetLayerName(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:68
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
COLOR4D GetLayerColor(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:62
void SetGridCursor(wxGrid *aGrid, int aRow, bool aEnable)
Definition: sel_layer.cpp:381
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:212
The common library.
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
#define LAYERNAME_COLNUM
Definition: sel_layer.cpp:121
Class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE.
void SelectCopperLayerPair()
Definition: sel_layer.cpp:285
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:417
void OnCancelClick(wxCommandEvent &event) override
Definition: sel_layer.cpp:275
PCB_LAYER_ID SelectLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Install the dialog box for layer selection.
Definition: sel_layer.cpp:220
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
PCB_LAYER_ID m_Route_Layer_TOP
Class SELECT_COPPER_LAYERS_PAIR_DIALOG displays a double pcb copper layers list in a dialog...
Definition: sel_layer.cpp:245
LSEQ UIOrder() const
Definition: lset.cpp:752
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39