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 <pcb_base_frame.h>
36 #include <class_board.h>
38 
39 
40 // Column position by function:
41 #define SELECT_COLNUM 0
42 #define COLOR_COLNUM 1
43 #define LAYERNAME_COLNUM 2
44 
45 
46 /* classes to display a layer list using a wxGrid.
47  */
49 {
50 public:
53  {
54  m_frame = aFrame;
55  }
56 
57 protected:
59 
60  // Returns true if the layer id is enabled (i.e. is it should be displayed)
61  bool IsLayerEnabled( LAYER_NUM aLayer ) const override
62  {
63  return m_frame->GetBoard()->IsLayerEnabled( PCB_LAYER_ID( aLayer ) );
64  }
65 
66  // Returns a color index from the layer id
67  // Virtual function
68  COLOR4D GetLayerColor( LAYER_NUM aLayer ) const override
69  {
70  return m_frame->Settings().Colors().GetLayerColor( aLayer );
71  }
72 
73  // Returns the name of the layer id
74  wxString GetLayerName( LAYER_NUM aLayer ) const override
75  {
76  return m_frame->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) );
77  }
78 };
79 
80 
81 /*
82  * This class display a pcb layers list in a dialog,
83  * to select one layer from this list
84  */
87 {
91  std::vector<PCB_LAYER_ID> m_layersIdLeftColumn;
92  std::vector<PCB_LAYER_ID> m_layersIdRightColumn;
93 
94 public:
95  PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD * aBrd, PCB_LAYER_ID aDefaultLayer,
96  LSET aNotAllowedLayersMask );
97 
98  LAYER_NUM GetLayerSelection() { return m_layerSelected; }
99 
100 private:
101  // Event handlers
102  void OnLeftGridCellClick( wxGridEvent& event ) override;
103  void OnRightGridCellClick( wxGridEvent& event ) override;
104 
105  void buildList();
106 };
107 
108 
110  PCB_LAYER_ID aDefaultLayer,
111  LSET aNotAllowedLayersMask ) :
112  PCB_LAYER_SELECTOR( aParent ),
113  DIALOG_LAYER_SELECTION_BASE( aParent )
114 {
115  m_layerSelected = aDefaultLayer;
116  m_notAllowedLayersMask = aNotAllowedLayersMask;
117  m_brd = aBrd;
118 
119  m_leftGridLayers->SetCellHighlightPenWidth( 0 );
120  m_rightGridLayers->SetCellHighlightPenWidth( 0 );
121  m_leftGridLayers->SetColFormatBool( SELECT_COLNUM );
122  m_rightGridLayers->SetColFormatBool( SELECT_COLNUM );
123  buildList();
124 
125  Layout();
126  GetSizer()->SetSizeHints( this );
127  SetFocus();
128 }
129 
130 
132 {
133  wxColour bg = GetLayerColor( LAYER_PCB_BACKGROUND ).ToColour();
134  int left_row = 0;
135  int right_row = 0;
136  wxString layername;
137 
138  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
139  {
140  PCB_LAYER_ID layerid = *ui_seq;
141 
142  if( m_notAllowedLayersMask[layerid] )
143  continue;
144 
145  wxColour fg = GetLayerColor( layerid ).ToColour();
146  wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ),
147  wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ),
148  wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) );
149 
150  layername = wxT( " " ) + GetLayerName( layerid );
151 
152  if( IsCopperLayer( layerid ) )
153  {
154  if( left_row )
155  m_leftGridLayers->AppendRows( 1 );
156 
157  m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM, color );
158  m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM, layername );
159 
160  if( m_layerSelected == layerid )
161  m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM, "1" );
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, color );
172  m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM, layername );
173 
174  if( m_layerSelected == layerid )
175  m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM, "1" );
176 
177  m_layersIdRightColumn.push_back( layerid );
178  right_row++;
179  }
180  }
181 
182  // Show only populated lists:
183  if( left_row <= 0 )
184  m_leftGridLayers->Show( false );
185 
186  if( right_row <= 0 )
187  m_rightGridLayers->Show( false );
188 }
189 
190 
192 {
193  m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
194  EndModal( 1 );
195 }
196 
197 
199 {
200  m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
201  EndModal( 2 );
202 }
203 
204 
205 PCB_LAYER_ID PCB_BASE_FRAME::SelectLayer( PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask,
206  wxPoint aDlgPosition )
207 {
208  PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask );
209 
210  if( aDlgPosition != wxDefaultPosition )
211  {
212  wxSize dlgSize = dlg.GetSize();
213  aDlgPosition.x -= dlgSize.x/2;
214  aDlgPosition.y -= dlgSize.y/2;
215  dlg.SetPosition( aDlgPosition );
216  }
217 
218  dlg.ShowModal();
219 
220  PCB_LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() );
221  return layer;
222 }
223 
224 
232 {
233 private:
239 
240  std::vector<PCB_LAYER_ID> m_layersId;
241 
242 public:
244  PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer );
245 
246  void GetLayerPair( PCB_LAYER_ID& aFrontLayer, PCB_LAYER_ID& aBackLayer )
247  {
248  aFrontLayer = m_frontLayer;
249  aBackLayer = m_backLayer;
250  }
251 
252 private:
253  void OnLeftGridCellClick( wxGridEvent& event ) override;
254  void OnRightGridCellClick( wxGridEvent& event ) override;
255 
256  void buildList();
257 };
258 
259 
261 {
262  PCB_SCREEN* screen = GetScreen();
263 
265  screen->m_Route_Layer_TOP,
266  screen->m_Route_Layer_BOTTOM );
267 
268  if( dlg.ShowModal() == wxID_OK )
269  {
270  dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM );
271 
272  // select the same layer for both layers is allowed (normal in some boards)
273  // but could be a mistake. So display an info message
274  if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM )
275  DisplayInfoMessage( this, _( "Warning: top and bottom layers are same." ) );
276  }
277 
278  m_canvas->MoveCursorToCrossHair();
279 }
280 
281 
283  PCB_BASE_FRAME* aParent, BOARD * aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer) :
284  PCB_LAYER_SELECTOR( aParent ),
286 {
287  m_frontLayer = aFrontLayer;
288  m_backLayer = aBackLayer;
289  m_leftRowSelected = 0;
290  m_rightRowSelected = 0;
291  m_brd = aPcb;
292 
293  m_leftGridLayers->SetCellHighlightPenWidth( 0 );
294  m_rightGridLayers->SetCellHighlightPenWidth( 0 );
295  m_leftGridLayers->SetColFormatBool( SELECT_COLNUM );
296  m_rightGridLayers->SetColFormatBool( SELECT_COLNUM );
297  buildList();
298 
299  SetFocus();
300 
301  GetSizer()->SetSizeHints( this );
302  Center();
303 }
304 
305 
307 {
308  wxColour bg = GetLayerColor( LAYER_PCB_BACKGROUND ).ToColour();
309  int row = 0;
310  wxString layername;
311 
312  for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
313  {
314  PCB_LAYER_ID layerid = *ui_seq;
315 
316  if( !IsCopperLayer( layerid ) )
317  continue;
318 
319  wxColour fg = GetLayerColor( layerid ).ToColour();
320  wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ),
321  wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ),
322  wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) );
323 
324  layername = wxT( " " ) + GetLayerName( layerid );
325 
326  if( row )
327  m_leftGridLayers->AppendRows( 1 );
328 
329  m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
330  m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
331  m_layersId.push_back( layerid );
332 
333  if( m_frontLayer == layerid )
334  {
335  m_leftGridLayers->SetCellValue( row, SELECT_COLNUM, "1" );
336  m_leftGridLayers->SetGridCursor( row, COLOR_COLNUM );
337  m_leftRowSelected = row;
338  }
339 
340  if( row )
341  m_rightGridLayers->AppendRows( 1 );
342 
343  m_rightGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
344  m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
345 
346  if( m_backLayer == layerid )
347  {
348  m_rightGridLayers->SetCellValue( row, SELECT_COLNUM, "1" );
349  m_rightRowSelected = row;
350  }
351 
352  row++;
353  }
354 }
355 
356 
358 {
359  int row = event.GetRow();
360  PCB_LAYER_ID layer = m_layersId[row];
361 
362  if( m_frontLayer == layer )
363  return;
364 
365  m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, wxEmptyString );
366  m_frontLayer = layer;
367  m_leftRowSelected = row;
368  m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, "1" );
369 }
370 
371 
373 {
374  int row = event.GetRow();
375  PCB_LAYER_ID layer = m_layersId[row];
376 
377  if( m_backLayer == layer )
378  return;
379 
380  m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, wxEmptyString );
381  m_backLayer = layer;
382  m_rightRowSelected = row;
383  m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, "1" );
384 }
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:282
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:191
PCB_BASE_FRAME * m_frame
Definition: sel_layer.cpp:58
This file is part of the common library.
#define SELECT_COLNUM
Definition: sel_layer.cpp:41
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:445
int color
Definition: DXF_plotter.cpp:62
bool IsLayerEnabled(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:61
BOARD * GetBoard() const
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:357
std::vector< PCB_LAYER_ID > m_layersId
Definition: sel_layer.cpp:240
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
Classes used in Pcbnew, CvPcb and GerbView.
void GetLayerPair(PCB_LAYER_ID &aFrontLayer, PCB_LAYER_ID &aBackLayer)
Definition: sel_layer.cpp:246
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
std::vector< PCB_LAYER_ID > m_layersIdRightColumn
Definition: sel_layer.cpp:92
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:98
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:46
std::vector< PCB_LAYER_ID > m_layersIdLeftColumn
Definition: sel_layer.cpp:91
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.
BOARD * GetBoard()
#define COLOR_COLNUM
Definition: sel_layer.cpp:42
PCB_LAYER_ID m_layerSelected
Definition: sel_layer.cpp:88
PCB_LAYER_SELECTOR(PCB_BASE_FRAME *aFrame)
Definition: sel_layer.cpp:51
wxString GetLayerName(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:74
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
COLOR4D GetLayerColor(LAYER_NUM aLayer) const override
Definition: sel_layer.cpp:68
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:198
The common library.
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:43
Class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE.
void SelectCopperLayerPair()
Definition: sel_layer.cpp:260
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:372
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.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:205
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:45
Class SELECT_COPPER_LAYERS_PAIR_DIALOG displays a double pcb copper layers list in a dialog...
Definition: sel_layer.cpp:230
PCB_ONE_LAYER_SELECTOR(PCB_BASE_FRAME *aParent, BOARD *aBrd, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask)
Definition: sel_layer.cpp:109
LSEQ UIOrder() const
Definition: lset.cpp:800
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39