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_frame = aFrame;
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_frame->GetBoard()->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_frame->Settings().Colors().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_frame->GetBoard()->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 {
85  std::vector<PCB_LAYER_ID> m_layersIdLeftColumn;
86  std::vector<PCB_LAYER_ID> m_layersIdRightColumn;
87 
88 public:
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( aParent ), DIALOG_LAYER_SELECTION_BASE( aParent )
107 {
108  m_layerSelected = aDefaultLayer;
109  m_notAllowedLayersMask = aNotAllowedLayersMask;
110  m_brd = aBrd;
111  buildList();
112  Layout();
113  GetSizer()->SetSizeHints( this );
114  SetFocus();
115 }
116 
117 
118 // Build the layers list
119 // Column position by function:
120 #define SELECT_COLNUM 0
121 #define COLOR_COLNUM 1
122 #define LAYERNAME_COLNUM 2
123 
125 {
126  // Hide layerid column which is used only to know the layer id
127  // not to be shown in dialogs
128  m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
129  m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
130 
131  int left_row = 0;
132  int right_row = 0;
133  wxString layername;
134 
135  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
136  {
137  PCB_LAYER_ID layerid = *ui_seq;
138 
139  if( m_notAllowedLayersMask[layerid] )
140  continue;
141 
142  COLOR4D color = GetLayerColor( layerid );
143  layername = GetLayerName( layerid );
144 
145  if( IsCopperLayer( layerid ) )
146  {
147  if( left_row )
148  m_leftGridLayers->AppendRows( 1 );
149 
150  m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM,
151  color.ToColour() );
152  m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM,
153  layername );
154 
155  if( m_layerSelected == layerid )
156  {
157  m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM,
158  wxT("X") );
159  m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM,
160  color.ToColour() );
161  m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM );
162  }
163 
164  m_layersIdLeftColumn.push_back( layerid );
165  left_row++;
166  }
167  else
168  {
169  if( right_row )
170  m_rightGridLayers->AppendRows( 1 );
171 
172  m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM,
173  color.ToColour() );
174  m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM,
175  layername );
176 
177  if( m_layerSelected == layerid )
178  {
179  m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM,
180  wxT("X") );
181  m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM,
182  color.ToColour() );
183  m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM );
184  }
185 
186  m_layersIdRightColumn.push_back( layerid );
187  right_row++;
188  }
189  }
190 
191  // Show only populated lists:
192  if( left_row <= 0 )
193  m_leftGridLayers->Show( false );
194 
195  if( right_row <= 0 )
196  m_rightGridLayers->Show( false );
197 
198  m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
199  m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
200  m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
201  m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
202 }
203 
204 
206 {
207  m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
208  m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
209  EndModal( 1 );
210 }
211 
212 
214 {
215  m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
216  m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
217  EndModal( 2 );
218 }
219 
220 
222  LSET aNotAllowedLayersMask, wxPoint aDlgPosition )
223 {
224  PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask );
225 
226  if( aDlgPosition != wxDefaultPosition )
227  {
228  wxSize dlgSize = dlg.GetSize();
229  aDlgPosition.x -= dlgSize.x/2;
230  aDlgPosition.y -= dlgSize.y/2;
231  dlg.SetPosition( aDlgPosition );
232  }
233 
234  dlg.ShowModal();
235 
236  PCB_LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() );
237  return layer;
238 }
239 
240 
248 {
249 private:
255 
256  std::vector<PCB_LAYER_ID> m_layersId;
257 
258 public:
260  PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer );
261 
262  void GetLayerPair( PCB_LAYER_ID& aFrontLayer, PCB_LAYER_ID& aBackLayer )
263  {
264  aFrontLayer = m_frontLayer;
265  aBackLayer = m_backLayer;
266  }
267 
268 private:
269  void OnLeftGridCellClick( wxGridEvent& event ) override;
270  void OnRightGridCellClick( wxGridEvent& event ) override;
271 
272  void OnOkClick( wxCommandEvent& event )
273  {
274  EndModal( wxID_OK );
275  }
276 
277  void OnCancelClick( wxCommandEvent& event ) override
278  {
279  EndModal( wxID_CANCEL );
280  }
281 
282  void buildList();
283  void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable );
284 };
285 
286 
288 {
289  PCB_SCREEN* screen = GetScreen();
290 
292  screen->m_Route_Layer_TOP,
293  screen->m_Route_Layer_BOTTOM );
294 
295  if( dlg.ShowModal() == wxID_OK )
296  {
297  dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM );
298 
299  // select the same layer for both layers is allowed (normal in some boards)
300  // but could be a mistake. So display an info message
301  if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM )
302  DisplayInfoMessage( this,
303  _( "Warning: The Top Layer and Bottom Layer are same." ) );
304  }
305 
307 }
308 
309 
311  PCB_BASE_FRAME* aParent, BOARD * aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer) :
312  PCB_LAYER_SELECTOR( aParent ),
314 {
315  m_frontLayer = aFrontLayer;
316  m_backLayer = aBackLayer;
317  m_leftRowSelected = 0;
318  m_rightRowSelected = 0;
319  m_brd = aPcb;
320  buildList();
321  SetFocus();
322  GetSizer()->SetSizeHints( this );
323  Center();
324 }
325 
326 
328 {
329  m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
330  m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
331 
332  // Select a not show cell, to avoid a wrong cell selection for user
333 
334  int row = 0;
335  wxString layername;
336 
337  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
338  {
339  PCB_LAYER_ID layerid = *ui_seq;
340 
341  if( !IsCopperLayer( layerid ) )
342  break;
343 
344  COLOR4D color = GetLayerColor( layerid );
345 
346  layername = GetLayerName( layerid );
347 
348  if( row )
349  m_leftGridLayers->AppendRows( 1 );
350 
351  m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color.ToColour() );
352  m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
353  m_layersId.push_back( layerid );
354 
355  if( m_frontLayer == layerid )
356  {
357  SetGridCursor( m_leftGridLayers, row, true );
358  m_leftRowSelected = row;
359  }
360 
361  if( row )
362  m_rightGridLayers->AppendRows( 1 );
363  m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM,
364  color.ToColour() );
365  m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM,
366  layername );
367 
368  if( m_backLayer == layerid )
369  {
370  SetGridCursor( m_rightGridLayers, row, true );
371  m_rightRowSelected = row;
372  }
373 
374  row++;
375  }
376 
377  m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
378  m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
379  m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
380  m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
381 }
382 
383 
385  bool aEnable )
386 {
387  if( aEnable )
388  {
389  PCB_LAYER_ID layerid = m_layersId[aRow];
390  COLOR4D color = GetLayerColor( layerid );
391  aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") );
392  aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color.ToColour() );
393  aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
394  }
395  else
396  {
397  aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString );
398  aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM,
399  aGrid->GetDefaultCellBackgroundColour() );
400  aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
401  }
402 }
403 
404 
406 {
407  int row = event.GetRow();
408  PCB_LAYER_ID layer = m_layersId[row];
409 
410  if( m_frontLayer == layer )
411  return;
412 
414  m_frontLayer = layer;
415  m_leftRowSelected = row;
417 }
418 
419 
421 {
422  int row = event.GetRow();
423  PCB_LAYER_ID layer = m_layersId[row];
424 
425  if( m_backLayer == layer )
426  return;
427 
429  m_backLayer = layer;
430  m_rightRowSelected = row;
432 }
Class DIALOG_LAYER_SELECTION_BASE.
SELECT_COPPER_LAYERS_PAIR_DIALOG(PCB_BASE_FRAME *aParent, BOARD *aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer)
Definition: sel_layer.cpp:310
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:205
PCB_BASE_FRAME * m_frame
Definition: sel_layer.cpp:52
This file is part of the common library.
#define SELECT_COLNUM
Definition: sel_layer.cpp:120
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:439
bool IsLayerEnabled(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:55
BOARD * GetBoard() const
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:405
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:347
std::vector< PCB_LAYER_ID > m_layersId
Definition: sel_layer.cpp:256
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:262
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
PCB_GENERAL_SETTINGS & Settings()
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
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:102
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
COLORS_DESIGN_SETTINGS & Colors()
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
#define COLOR_COLNUM
Definition: sel_layer.cpp:121
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
PCB_LAYER_ID m_layerSelected
Definition: sel_layer.cpp:82
PCB_LAYER_SELECTOR(PCB_BASE_FRAME *aFrame)
Definition: sel_layer.cpp:45
void OnOkClick(wxCommandEvent &event)
Definition: sel_layer.cpp:272
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:384
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:213
The common library.
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
#define LAYERNAME_COLNUM
Definition: sel_layer.cpp:122
Class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE.
void SelectCopperLayerPair()
Definition: sel_layer.cpp:287
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:420
void OnCancelClick(wxCommandEvent &event) override
Definition: sel_layer.cpp:277
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:221
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:774
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
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:246
PCB_ONE_LAYER_SELECTOR(PCB_BASE_FRAME *aParent, BOARD *aBrd, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask)
Definition: sel_layer.cpp:104
LSEQ UIOrder() const
Definition: lset.cpp:759
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39