KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2021 KiCad Developers, see AUTHORS.txt for contributors.
10 *
11 * This program is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation, either version 3 of the License, or (at your
14 * option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25
26#include <kiplatform/ui.h>
27#include <confirm.h>
28#include <lset.h>
29#include <pcb_base_frame.h>
31#include <board.h>
33#include <router/router_tool.h>
35#include <tools/pcb_actions.h>
36
37// Column position by function:
38#define SELECT_COLNUM 0
39#define COLOR_COLNUM 1
40#define LAYERNAME_COLNUM 2
41#define LAYER_HK_COLUMN 3
42
43/*
44 * Display a layer list using a wxGrid.
45 */
47{
48public:
51 {
52 m_frame = aFrame;
53 }
54
55protected:
57
59 bool isLayerEnabled( int aLayer ) const override
60 {
61 return m_frame->GetBoard()->IsLayerEnabled( PCB_LAYER_ID( aLayer ) );
62 }
63
64 // Return the color index from the layer ID.
65 COLOR4D getLayerColor( int aLayer ) const override
66 {
67 return m_frame->GetColorSettings()->GetColor( aLayer );
68 }
69
70 // Return the name of the layer ID.
71 wxString getLayerName( int aLayer ) const override
72 {
73 return m_frame->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) );
74 }
75};
76
77
82{
83public:
84 PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD * aBrd, PCB_LAYER_ID aDefaultLayer,
85 LSET aNotAllowedLayersMask, bool aHideCheckBoxes = false );
87
89
90private:
91 // Event handlers
92 void OnLeftGridCellClick( wxGridEvent& aEvent ) override;
93 void OnRightGridCellClick( wxGridEvent& aEvent ) override;
94 void OnMouseMove( wxUpdateUIEvent& aEvent ) override;
95
96 // Will close the dialog on ESC key
97 void onCharHook( wxKeyEvent& event );
98
99 wxString getLayerHotKey( PCB_LAYER_ID aLayer ) const
100 {
101 int code = PCB_ACTIONS::LayerIDToAction( aLayer )->GetHotKey();
102 return AddHotkeyName( wxS( "" ), code, IS_COMMENT );
103 }
104
105 void buildList();
106
110 std::vector<PCB_LAYER_ID> m_layersIdLeftColumn;
111 std::vector<PCB_LAYER_ID> m_layersIdRightColumn;
112};
113
114
116 PCB_LAYER_ID aDefaultLayer,
117 LSET aNotAllowedLayersMask,
118 bool aHideCheckBoxes ) :
119 PCB_LAYER_SELECTOR( aParent ),
121{
122 m_useCalculatedSize = true;
123
124 m_layerSelected = aDefaultLayer;
125 m_notAllowedLayersMask = aNotAllowedLayersMask;
126 m_brd = aBrd;
127
128 m_leftGridLayers->SetCellHighlightPenWidth( 0 );
129 m_rightGridLayers->SetCellHighlightPenWidth( 0 );
130 m_leftGridLayers->SetColFormatBool( SELECT_COLNUM );
131 m_rightGridLayers->SetColFormatBool( SELECT_COLNUM );
132
133 m_leftGridLayers->AppendCols( 1 );
134
135 buildList();
136
137 if( aHideCheckBoxes )
138 {
141 }
142
143 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PCB_ONE_LAYER_SELECTOR::onCharHook ) );
144
145 Layout();
146 GetSizer()->SetSizeHints( this );
147 SetFocus();
148}
149
150
152{
153 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PCB_ONE_LAYER_SELECTOR::onCharHook ) );
154}
155
156
157void PCB_ONE_LAYER_SELECTOR::OnMouseMove( wxUpdateUIEvent& aEvent )
158{
162
163 wxPoint mouse_pos = KIPLATFORM::UI::GetMousePosition();
164 wxPoint left_pos = m_leftGridLayers->ScreenToClient( mouse_pos );
165 wxPoint right_pos = m_rightGridLayers->ScreenToClient( mouse_pos );
166
167 if( m_leftGridLayers->HitTest( left_pos ) == wxHT_WINDOW_INSIDE )
168 {
169 int row = m_leftGridLayers->YToRow( left_pos.y );
170
171 if( row != wxNOT_FOUND && row < static_cast<int>( m_layersIdLeftColumn.size() ) )
172 {
174 m_leftGridLayers->SelectBlock( row, LAYERNAME_COLNUM, row, LAYER_HK_COLUMN );
175 return;
176 }
177 }
178
179 if( m_rightGridLayers->HitTest( right_pos ) == wxHT_WINDOW_INSIDE )
180 {
181 int row = m_rightGridLayers->YToRow( right_pos.y );
182
183 if( row == wxNOT_FOUND || row >= static_cast<int>( m_layersIdRightColumn.size() ) )
184 return;
185
187 m_rightGridLayers->SelectBlock( row, LAYERNAME_COLNUM, row, LAYERNAME_COLNUM);
188 }
189}
190
191
192void PCB_ONE_LAYER_SELECTOR::onCharHook( wxKeyEvent& event )
193{
194 if( event.GetKeyCode() == WXK_ESCAPE )
195 Close();
196}
197
198
200{
202 int left_row = 0;
203 int right_row = 0;
204 wxString layername;
205
206 for( PCB_LAYER_ID layerid : m_brd->GetEnabledLayers().UIOrder() )
207 {
208 if( m_notAllowedLayersMask[layerid] )
209 continue;
210
211 wxColour fg = getLayerColor( layerid ).ToColour();
212 wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ),
213 wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ),
214 wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) );
215
216 layername = wxT( " " ) + getLayerName( layerid );
217
218 if( IsCopperLayer( layerid ) )
219 {
220 if( left_row )
221 m_leftGridLayers->AppendRows( 1 );
222
223 m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM, color );
224 m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM, layername );
225 m_leftGridLayers->SetCellValue( left_row, LAYER_HK_COLUMN, getLayerHotKey( layerid ) );
226
227 if( m_layerSelected == layerid )
228 m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM, wxT( "1" ) );
229
230 m_layersIdLeftColumn.push_back( layerid );
231 left_row++;
232 }
233 else
234 {
235 if( right_row )
236 m_rightGridLayers->AppendRows( 1 );
237
238 m_rightGridLayers->SetCellBackgroundColour( right_row, COLOR_COLNUM, color );
239 m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM, layername );
240
241 if( m_layerSelected == layerid )
242 m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM, wxT( "1" ) );
243
244 m_layersIdRightColumn.push_back( layerid );
245 right_row++;
246 }
247 }
248
249 // Show only populated lists:
250 if( left_row <= 0 )
251 m_leftGridLayers->Show( false );
252
253 if( right_row <= 0 )
254 m_rightGridLayers->Show( false );
255
256 // Now fix min grid column size (it also sets a minimal size)
257 m_leftGridLayers->AutoSizeColumns();
258 m_rightGridLayers->AutoSizeColumns();
259}
260
261
263{
264 m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
265
266 if( IsQuasiModal() )
267 EndQuasiModal( 1 );
268 else
269 EndDialog( 1 );
270}
271
272
274{
275 m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
276
277 if( IsQuasiModal() )
278 EndQuasiModal( 2 );
279 else
280 EndDialog( 2 );
281}
282
283
284PCB_LAYER_ID PCB_BASE_FRAME::SelectOneLayer( PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask,
285 wxPoint aDlgPosition )
286{
287 PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask, true );
288
289 if( aDlgPosition != wxDefaultPosition )
290 {
291 wxSize dlgSize = dlg.GetSize();
292 aDlgPosition.x -= dlgSize.x/2;
293 aDlgPosition.y -= dlgSize.y/2;
294 dlg.SetPosition( aDlgPosition );
295 }
296
297 if( dlg.ShowModal() != wxID_CANCEL )
298 return ToLAYER_ID( dlg.GetLayerSelection() );
299 else
300 return UNDEFINED_LAYER;
301}
302
303
309{
310public:
312 PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer );
313
314 void GetLayerPair( PCB_LAYER_ID& aFrontLayer, PCB_LAYER_ID& aBackLayer )
315 {
316 aFrontLayer = m_frontLayer;
317 aBackLayer = m_backLayer;
318 }
319
320private:
321 void OnLeftGridCellClick( wxGridEvent& event ) override;
322 void OnRightGridCellClick( wxGridEvent& event ) override;
323
324 void buildList();
325
331
332 std::vector<PCB_LAYER_ID> m_layersId;
333};
334
335
337{
338 PCB_SCREEN* screen = frame()->GetScreen();
339
341 screen->m_Route_Layer_BOTTOM );
342
343 if( dlg.ShowModal() == wxID_OK )
344 {
346
347 // select the same layer for both layers is allowed (normal in some boards)
348 // but could be a mistake. So display an info message
349 if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM )
350 DisplayInfoMessage( frame(), _( "Warning: top and bottom layers are same." ) );
351 }
352
353 return 0;
354}
355
356
358 PCB_BASE_FRAME* aParent, BOARD * aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer) :
359 PCB_LAYER_SELECTOR( aParent ),
361{
362 m_frontLayer = aFrontLayer;
363 m_backLayer = aBackLayer;
366 m_brd = aPcb;
367
368 m_leftGridLayers->SetCellHighlightPenWidth( 0 );
369 m_rightGridLayers->SetCellHighlightPenWidth( 0 );
370 m_leftGridLayers->SetColFormatBool( SELECT_COLNUM );
371 m_rightGridLayers->SetColFormatBool( SELECT_COLNUM );
372 buildList();
373
374 SetFocus();
375
376 GetSizer()->SetSizeHints( this );
377 Center();
378}
379
380
382{
384 int row = 0;
385 wxString layername;
386
387 for( PCB_LAYER_ID layerid : m_brd->GetEnabledLayers().UIOrder() )
388 {
389 if( !IsCopperLayer( layerid ) )
390 continue;
391
392 wxColour fg = getLayerColor( layerid ).ToColour();
393 wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ),
394 wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ),
395 wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) );
396
397 layername = wxT( " " ) + getLayerName( layerid );
398
399 if( row )
400 m_leftGridLayers->AppendRows( 1 );
401
402 m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
403 m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
404 m_layersId.push_back( layerid );
405
406 if( m_frontLayer == layerid )
407 {
408 m_leftGridLayers->SetCellValue( row, SELECT_COLNUM, wxT( "1" ) );
409 m_leftGridLayers->SetGridCursor( row, COLOR_COLNUM );
410 m_leftRowSelected = row;
411 }
412
413 if( row )
414 m_rightGridLayers->AppendRows( 1 );
415
416 m_rightGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
417 m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
418
419 if( m_backLayer == layerid )
420 {
421 m_rightGridLayers->SetCellValue( row, SELECT_COLNUM, wxT( "1" ) );
422 m_rightRowSelected = row;
423 }
424
425 row++;
426 }
427
428 // Now fix min grid layer name column size (it also sets a minimal size)
429 m_leftGridLayers->AutoSizeColumn( LAYERNAME_COLNUM );
430 m_rightGridLayers->AutoSizeColumn( LAYERNAME_COLNUM );
431}
432
433
435{
436 int row = event.GetRow();
437 PCB_LAYER_ID layer = m_layersId[row];
438
439 if( m_frontLayer == layer )
440 return;
441
442 m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, wxEmptyString );
443 m_frontLayer = layer;
444 m_leftRowSelected = row;
445 m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, wxT( "1" ) );
446}
447
448
450{
451 int row = event.GetRow();
452 PCB_LAYER_ID layer = m_layersId[row];
453
454 if( m_backLayer == layer )
455 return;
456
457 m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, wxEmptyString );
458 m_backLayer = layer;
459 m_rightRowSelected = row;
460 m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, wxT( "1" ) );
461}
int color
Definition: DXF_plotter.cpp:58
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:289
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:757
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:783
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:575
COLOR4D GetColor(int aLayer) const
Class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE.
Class DIALOG_LAYER_SELECTION_BASE.
bool IsQuasiModal() const
Definition: dialog_shim.h:111
bool m_useCalculatedSize
Definition: dialog_shim.h:214
void EndQuasiModal(int retCode)
void SetPosition(const wxPoint &aNewPosition)
Force the position of the dialog to a new position.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
wxColour ToColour() const
Definition: color4d.cpp:220
Base class to build a layer list.
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:35
LSEQ UIOrder() const
Definition: lset.cpp:865
static TOOL_ACTION * LayerIDToAction(PCB_LAYER_ID aLayerID)
Translate a layer ID into the action that switches to that layer.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCB_LAYER_ID SelectOneLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Show the dialog box for a layer selection.
Definition: sel_layer.cpp:284
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
virtual COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
PCB_BASE_FRAME * m_frame
Definition: sel_layer.cpp:56
bool isLayerEnabled(int aLayer) const override
Definition: sel_layer.cpp:59
COLOR4D getLayerColor(int aLayer) const override
Definition: sel_layer.cpp:65
PCB_LAYER_SELECTOR(PCB_BASE_FRAME *aFrame)
Definition: sel_layer.cpp:49
wxString getLayerName(int aLayer) const override
Definition: sel_layer.cpp:71
Display a PCB layers list in a dialog to select one layer from this list.
Definition: sel_layer.cpp:82
void OnLeftGridCellClick(wxGridEvent &aEvent) override
Definition: sel_layer.cpp:262
void OnRightGridCellClick(wxGridEvent &aEvent) override
Definition: sel_layer.cpp:273
void onCharHook(wxKeyEvent &event)
Definition: sel_layer.cpp:192
std::vector< PCB_LAYER_ID > m_layersIdLeftColumn
Definition: sel_layer.cpp:110
PCB_ONE_LAYER_SELECTOR(PCB_BASE_FRAME *aParent, BOARD *aBrd, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask, bool aHideCheckBoxes=false)
Definition: sel_layer.cpp:115
std::vector< PCB_LAYER_ID > m_layersIdRightColumn
Definition: sel_layer.cpp:111
void OnMouseMove(wxUpdateUIEvent &aEvent) override
Definition: sel_layer.cpp:157
PCB_LAYER_ID m_layerSelected
Definition: sel_layer.cpp:107
wxString getLayerHotKey(PCB_LAYER_ID aLayer) const
Definition: sel_layer.cpp:99
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:43
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:44
PCB_BASE_EDIT_FRAME * frame() const
int SelectCopperLayerPair(const TOOL_EVENT &aEvent)
Definition: sel_layer.cpp:336
Display a pair PCB copper layers list in a dialog to select a layer pair from these lists.
Definition: sel_layer.cpp:309
std::vector< PCB_LAYER_ID > m_layersId
Definition: sel_layer.cpp:332
void GetLayerPair(PCB_LAYER_ID &aFrontLayer, PCB_LAYER_ID &aBackLayer)
Definition: sel_layer.cpp:314
void OnRightGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:449
void OnLeftGridCellClick(wxGridEvent &event) override
Definition: sel_layer.cpp:434
SELECT_COPPER_LAYERS_PAIR_DIALOG(PCB_BASE_FRAME *aParent, BOARD *aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer)
Definition: sel_layer.cpp:357
int GetHotKey() const
Return the hotkey keycode which initiates the action.
Definition: tool_action.h:313
Generic, UI-independent tool event.
Definition: tool_event.h:167
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:222
This file is part of the common library.
#define _(s)
wxString AddHotkeyName(const wxString &aText, int aHotKey, HOTKEY_ACTION_TYPE aStyle)
@ IS_COMMENT
Definition: hotkeys_basic.h:78
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:531
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition: layer_ids.h:224
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:875
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: wxgtk/ui.cpp:611
BOARD * GetBoard()
#define LAYER_HK_COLUMN
Definition: sel_layer.cpp:41
#define LAYERNAME_COLNUM
Definition: sel_layer.cpp:40
#define SELECT_COLNUM
Definition: sel_layer.cpp:38
#define COLOR_COLNUM
Definition: sel_layer.cpp:39