KiCad PCB EDA Suite
Loading...
Searching...
No Matches
appearance_controls.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) 2020 Jon Evans <[email protected]>
5 * Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22
23#include <bitmaps.h>
24#include <board.h>
26#include <pad.h>
27#include <pcb_track.h>
28#include <eda_list_dialog.h>
29#include <string_utils.h>
31#include <confirm.h>
32#include <pcb_display_options.h>
33#include <pcb_edit_frame.h>
34#include <pcb_painter.h>
35#include <pcbnew_settings.h>
36#include <project.h>
40#include <tool/tool_manager.h>
41#include <tools/pcb_actions.h>
50#include <widgets/wx_infobar.h>
51#include <widgets/wx_grid.h>
53#include <wx/checkbox.h>
54#include <wx/hyperlink.h>
55#include <wx/radiobut.h>
56#include <wx/sizer.h>
57#include <wx/slider.h>
58#include <wx/statline.h>
59#include <wx/textdlg.h>
60#include <wx/bmpbuttn.h> // needed on wxMSW for OnSetFocus()
61
62
63NET_GRID_TABLE::NET_GRID_TABLE( PCB_BASE_FRAME* aFrame, wxColor aBackgroundColor ) :
64 wxGridTableBase(),
65 m_frame( aFrame )
66{
67 m_defaultAttr = new wxGridCellAttr;
68 m_defaultAttr->SetBackgroundColour( aBackgroundColor );
69
70 m_labelAttr = new wxGridCellAttr;
72 m_labelAttr->SetBackgroundColour( aBackgroundColor );
73}
74
75
77{
78 m_defaultAttr->DecRef();
79 m_labelAttr->DecRef();
80}
81
82
83wxGridCellAttr* NET_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
84{
85 wxGridCellAttr* attr = nullptr;
86
87 switch( aCol )
88 {
89 case COL_COLOR: attr = m_defaultAttr; break;
90 case COL_VISIBILITY: attr = m_defaultAttr; break;
91 case COL_LABEL: attr = m_labelAttr; break;
92 default: wxFAIL;
93 }
94
95 if( attr )
96 attr->IncRef();
97
98 return attr;
99}
100
101
102wxString NET_GRID_TABLE::GetValue( int aRow, int aCol )
103{
104 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
105
106 switch( aCol )
107 {
108 case COL_COLOR: return m_nets[aRow].color.ToCSSString();
109 case COL_VISIBILITY: return m_nets[aRow].visible ? wxT( "1" ) : wxT( "0" );
110 case COL_LABEL: return m_nets[aRow].name;
111 default: return wxEmptyString;
112 }
113}
114
115
116void NET_GRID_TABLE::SetValue( int aRow, int aCol, const wxString& aValue )
117{
118 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
119
120 NET_GRID_ENTRY& net = m_nets[aRow];
121
122 switch( aCol )
123 {
124 case COL_COLOR:
125 net.color.SetFromWxString( aValue );
126 updateNetColor( net );
127 break;
128
129 case COL_VISIBILITY:
130 net.visible = ( aValue != wxT( "0" ) );
131 updateNetVisibility( net );
132 break;
133
134 case COL_LABEL:
135 net.name = aValue;
136 break;
137
138 default:
139 break;
140 }
141}
142
143
144wxString NET_GRID_TABLE::GetTypeName( int aRow, int aCol )
145{
146 switch( aCol )
147 {
148 case COL_COLOR: return wxT( "COLOR4D" );
149 case COL_VISIBILITY: return wxGRID_VALUE_BOOL;
150 case COL_LABEL: return wxGRID_VALUE_STRING;
151 default: return wxGRID_VALUE_STRING;
152 }
153}
154
155
156bool NET_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
157{
158 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
159 wxASSERT( aCol == COL_VISIBILITY );
160
161 return m_nets[aRow].visible;
162}
163
164
165void NET_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
166{
167 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
168 wxASSERT( aCol == COL_VISIBILITY );
169
170 m_nets[aRow].visible = aValue;
172}
173
174
175void* NET_GRID_TABLE::GetValueAsCustom( int aRow, int aCol, const wxString& aTypeName )
176{
177 wxASSERT( aCol == COL_COLOR );
178 wxASSERT( aTypeName == wxT( "COLOR4D" ) );
179 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
180
181 return ColorToVoid( m_nets[aRow].color );
182}
183
184
185void NET_GRID_TABLE::SetValueAsCustom( int aRow, int aCol, const wxString& aTypeName, void* aValue )
186{
187 wxASSERT( aCol == COL_COLOR );
188 wxASSERT( aTypeName == wxT( "COLOR4D" ) );
189 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
190
191 m_nets[aRow].color = VoidToColor( aValue );
192 updateNetColor( m_nets[aRow] );
193}
194
195
197{
198 wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
199 return m_nets[aRow];
200}
201
202
204{
205 auto it = std::find_if( m_nets.cbegin(), m_nets.cend(),
206 [aCode]( const NET_GRID_ENTRY& aEntry )
207 {
208 return aEntry.code == aCode;
209 } );
210
211 if( it == m_nets.cend() )
212 return -1;
213
214 return std::distance( m_nets.cbegin(), it );
215}
216
217
219{
220 BOARD* board = m_frame->GetBoard();
221 const NETNAMES_MAP& nets = board->GetNetInfo().NetsByName();
222
225
226 std::set<int>& hiddenNets = rs->GetHiddenNets();
227 std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
228
229 int deleted = m_nets.size();
230 m_nets.clear();
231
232 if( GetView() )
233 {
234 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, deleted );
235 GetView()->ProcessTableMessage( msg );
236 }
237
238 for( const std::pair<const wxString, NETINFO_ITEM*>& pair : nets )
239 {
240 int netCode = pair.second->GetNetCode();
241
242 if( netCode > 0 && !pair.first.StartsWith( wxT( "unconnected-(" ) ) )
243 {
244 COLOR4D color = netColors.count( netCode ) ? netColors.at( netCode ) :
245 COLOR4D::UNSPECIFIED;
246
247 bool visible = hiddenNets.count( netCode ) == 0;
248
249 m_nets.emplace_back( NET_GRID_ENTRY( netCode, pair.first, color, visible ) );
250 }
251 }
252
253 // TODO(JE) move to ::Compare so we can re-sort easily
254 std::sort( m_nets.begin(), m_nets.end(),
255 []( const NET_GRID_ENTRY& a, const NET_GRID_ENTRY& b )
256 {
257 return a.name < b.name;
258 } );
259
260 if( GetView() )
261 {
262 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_nets.size() );
263 GetView()->ProcessTableMessage( msg );
264 }
265}
266
267
269{
270 for( NET_GRID_ENTRY& net : m_nets )
271 {
272 net.visible = true;
273 updateNetVisibility( net );
274 }
275
276 if( GetView() )
277 GetView()->ForceRefresh();
278}
279
280
282{
283 for( NET_GRID_ENTRY& net : m_nets )
284 {
285 net.visible = ( net.code == aNet.code );
286 updateNetVisibility( net );
287 }
288
289 if( GetView() )
290 GetView()->ForceRefresh();
291}
292
293
295{
298
299 m_frame->GetToolManager()->RunAction( action, aNet.code );
300}
301
302
304{
306 KIGFX::PCB_RENDER_SETTINGS* renderSettings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( rs );
307
308 std::map<int, KIGFX::COLOR4D>& netColors = renderSettings->GetNetColorMap();
309
310 if( aNet.color != COLOR4D::UNSPECIFIED )
311 netColors[aNet.code] = aNet.color;
312 else
313 netColors.erase( aNet.code );
314
318}
319
320
323
324#define RR APPEARANCE_CONTROLS::APPEARANCE_SETTING // Render Row abbreviation to reduce source width
325
326 // text id tooltip opacity slider
327 RR( _HKI( "Tracks" ), LAYER_TRACKS, _HKI( "Show tracks" ), true ),
328 RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
329 RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
330 RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
331 RR( _HKI( "Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user images" ), true ),
332 RR(),
333 RR( _HKI( "Footprints Front" ), LAYER_FOOTPRINTS_FR, _HKI( "Show footprints that are on board's front" ) ),
334 RR( _HKI( "Footprints Back" ), LAYER_FOOTPRINTS_BK, _HKI( "Show footprints that are on board's back" ) ),
335 RR( _HKI( "Through-hole Pads" ), LAYER_PADS_TH, _HKI( "Show through-hole pads" ) ),
336 RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
337 RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
338 RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
339 RR( _HKI( "Hidden Text" ), LAYER_HIDDEN_TEXT, _HKI( "Show text marked as hidden" ) ),
340 RR(),
341 RR(),
342 RR( _HKI( "Ratsnest" ), LAYER_RATSNEST, _HKI( "Show unconnected nets as a ratsnest") ),
343 RR( _HKI( "DRC Warnings" ), LAYER_DRC_WARNING, _HKI( "DRC violations with a Warning severity" ) ),
344 RR( _HKI( "DRC Errors" ), LAYER_DRC_ERROR, _HKI( "DRC violations with an Error severity" ) ),
345 RR( _HKI( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _HKI( "DRC violations which have been individually excluded" ) ),
346 RR( _HKI( "Anchors" ), LAYER_ANCHOR, _HKI( "Show footprint and text origins as a cross" ) ),
347 RR( _HKI( "Locked Item Shadow" ), LAYER_LOCKED_ITEM_SHADOW, _HKI( "Show a shadow marker on locked items" ) ),
348 RR( _HKI( "Conflict Footprint Shadow" ), LAYER_CONFLICTS_SHADOW, _HKI( "Show a shadow marker on conflicting footprints" ) ),
349 RR( _HKI( "Drawing Sheet" ), LAYER_DRAWINGSHEET, _HKI( "Show drawing sheet borders and title block" ) ),
350 RR( _HKI( "Grid" ), LAYER_GRID, _HKI( "Show the (x,y) grid dots" ) )
351};
352
354static std::set<int> s_allowedInFpEditor =
355 {
367 };
368
369// These are the built-in layer presets that cannot be deleted
370
372
374
376 LSET::AllCuMask().set( Edge_Cuts ) );
377
380
382 LSET::FrontMask().set( Edge_Cuts ) );
383
386
388 LSET::BackMask().set( Edge_Cuts ) );
389
392
393// this one is only used to store the object visibility settings of the last used
394// built-in layer preset
396
397
399 bool aFpEditorMode ) :
400 APPEARANCE_CONTROLS_BASE( aParent ),
401 m_frame( aParent ),
402 m_focusOwner( aFocusOwner ),
403 m_board( nullptr ),
404 m_isFpEditor( aFpEditorMode ),
405 m_currentPreset( nullptr ),
406 m_lastSelectedUserPreset( nullptr ),
407 m_layerContextMenu( nullptr )
408{
409 // Correct the min size from wxformbuilder not using fromdip
410 SetMinSize( FromDIP( GetMinSize() ) );
411
412 DPI_SCALING_COMMON dpi( nullptr, m_frame );
413
414 int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
415 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
416 m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize );
417 m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
418
419 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
420 SetBorders( true, false, false, false );
421
422 m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
424 m_windowLayers->SetScrollRate( 0, 5 );
425 m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
426
427 m_objectsOuterSizer = new wxBoxSizer( wxVERTICAL );
429 m_windowObjects->SetScrollRate( 0, 5 );
430 m_windowObjects->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
431
432 wxFont infoFont = KIUI::GetInfoFont( this );
433 m_staticTextNets->SetFont( infoFont );
434 m_staticTextNetClasses->SetFont( infoFont );
435 m_panelLayers->SetFont( infoFont );
436 m_windowLayers->SetFont( infoFont );
437 m_windowObjects->SetFont( infoFont );
438 m_presetsLabel->SetFont( infoFont );
439 m_viewportsLabel->SetFont( infoFont );
440
441 m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore layer visibility combinations.\n"
442 "Use %s+Tab to activate selector.\n"
443 "Successive Tabs while holding %s down will "
444 "cycle through presets in the popup." ),
447
448 m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore view location and zoom.\n"
449 "Use %s+Tab to activate selector.\n"
450 "Successive Tabs while holding %s down will "
451 "cycle through viewports in the popup." ),
454
456
457 m_btnNetInspector->SetBitmap( KiBitmapBundle( BITMAPS::list_nets_16 ) );
459
460 m_btnConfigureNetClasses->SetBitmap( KiBitmapBundle( BITMAPS::options_generic_16 ) );
462
463 m_txtNetFilter->SetHint( _( "Filter nets" ) );
464
465 if( screenHeight <= 900 && m_pointSize >= indicatorSize )
466 m_pointSize = m_pointSize * 8 / 10;
467
468 wxFont font = m_notebook->GetFont();
469
470#ifdef __WXMAC__
471 font.SetPointSize( m_pointSize );
472 m_notebook->SetFont( font );
473#endif
474
475 auto setHighContrastMode =
476 [&]( HIGH_CONTRAST_MODE aMode )
477 {
479 opts.m_ContrastModeDisplay = aMode;
480
481 m_frame->SetDisplayOptions( opts );
482 passOnFocus();
483 };
484
485 m_rbHighContrastNormal->Bind( wxEVT_RADIOBUTTON,
486 [=]( wxCommandEvent& aEvent )
487 {
488 setHighContrastMode( HIGH_CONTRAST_MODE::NORMAL );
489 } );
490
491 m_rbHighContrastDim->Bind( wxEVT_RADIOBUTTON,
492 [=]( wxCommandEvent& aEvent )
493 {
494 setHighContrastMode( HIGH_CONTRAST_MODE::DIMMED );
495 } );
496
497 m_rbHighContrastOff->Bind( wxEVT_RADIOBUTTON,
498 [=]( wxCommandEvent& aEvent )
499 {
500 setHighContrastMode( HIGH_CONTRAST_MODE::HIDDEN );
501 } );
502
504
505 m_btnNetInspector->Bind( wxEVT_BUTTON,
506 [&]( wxCommandEvent& aEvent )
507 {
509 passOnFocus();
510 } );
511
512 m_btnConfigureNetClasses->Bind( wxEVT_BUTTON,
513 [&]( wxCommandEvent& aEvent )
514 {
515 // This panel should only be visible in the PCB_EDIT_FRAME anyway
516 if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
517 editframe->ShowBoardSetupDialog( _( "Net Classes" ) );
518
519 passOnFocus();
520 } );
521
522 m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
523 m_cbFlipBoard->Bind( wxEVT_CHECKBOX,
524 [&]( wxCommandEvent& aEvent )
525 {
527 } );
528
530 KiBitmapBundle( BITMAPS::visibility ), KiBitmapBundle( BITMAPS::visibility_off ) );
531
532 m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor );
533
534 m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
537
538 m_netsTable = new NET_GRID_TABLE( m_frame, m_panelNets->GetBackgroundColour() );
541
542 m_netsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
543 m_netsGrid->SetSelectionForeground( m_netsGrid->GetDefaultCellTextColour() );
544 m_netsGrid->SetSelectionBackground( m_panelNets->GetBackgroundColour() );
545
546 const int cellPadding = 6;
547#ifdef __WXMAC__
548 const int rowHeightPadding = 5;
549#else
550 const int rowHeightPadding = 3;
551#endif
552
553 wxSize size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU );
554 m_netsGrid->SetColSize( NET_GRID_TABLE::COL_COLOR, size.x + cellPadding );
555
556 size = KiBitmapBundle( BITMAPS::visibility ).GetPreferredBitmapSizeFor( this );
557 m_netsGrid->SetColSize( NET_GRID_TABLE::COL_VISIBILITY, size.x + cellPadding );
558
559 m_netsGrid->SetDefaultCellFont( font );
560 m_netsGrid->SetDefaultRowSize( font.GetPixelSize().y + rowHeightPadding );
561
562 m_netsGrid->GetGridWindow()->Bind( wxEVT_MOTION, &APPEARANCE_CONTROLS::OnNetGridMouseEvent,
563 this );
564
565 // To handle middle click on color swatches
566 m_netsGrid->GetGridWindow()->Bind( wxEVT_MIDDLE_UP, &APPEARANCE_CONTROLS::OnNetGridMouseEvent,
567 this );
568
569 m_netsGrid->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
570 m_netclassScrolledWindow->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
571
572 if( m_isFpEditor )
573 m_notebook->RemovePage( 2 );
574
576
579
582
586
587 // Grid visibility is loaded and set to the GAL before we are constructed
589
590 Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::OnLayerContextMenu, this,
592}
593
594
596{
597 delete m_iconProvider;
598}
599
600
602{
603 int hotkey;
604 wxString msg;
605 wxFont infoFont = KIUI::GetInfoFont( this );
606
607 // Create layer display options
609 _( "Layer Display Options" ) );
611 m_paneLayerDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
612
613 wxWindow* layerDisplayPane = m_paneLayerDisplayOptions->GetPane();
614
615 wxBoxSizer* layerDisplayOptionsSizer;
616 layerDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
617
619
620 if( hotkey )
621 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
622 else
623 msg = _( "Inactive layers:" );
624
625 m_inactiveLayersLabel = new wxStaticText( layerDisplayPane, wxID_ANY, msg );
626 m_inactiveLayersLabel->SetFont( infoFont );
627 m_inactiveLayersLabel->Wrap( -1 );
628 layerDisplayOptionsSizer->Add( m_inactiveLayersLabel, 0, wxEXPAND | wxBOTTOM, 2 );
629
630 wxBoxSizer* contrastModeSizer;
631 contrastModeSizer = new wxBoxSizer( wxHORIZONTAL );
632
633 m_rbHighContrastNormal = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Normal" ),
634 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
635 m_rbHighContrastNormal->SetFont( infoFont );
636 m_rbHighContrastNormal->SetValue( true );
637 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
638
639 contrastModeSizer->Add( m_rbHighContrastNormal, 0, wxRIGHT, 5 );
640 contrastModeSizer->AddStretchSpacer();
641
642 m_rbHighContrastDim = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Dim" ) );
643 m_rbHighContrastDim->SetFont( infoFont );
644 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
645
646 contrastModeSizer->Add( m_rbHighContrastDim, 0, wxRIGHT, 5 );
647 contrastModeSizer->AddStretchSpacer();
648
649 m_rbHighContrastOff = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Hide" ) );
650 m_rbHighContrastOff->SetFont( infoFont );
651 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
652
653 contrastModeSizer->Add( m_rbHighContrastOff, 0, 0, 5 );
654 contrastModeSizer->AddStretchSpacer();
655
656 layerDisplayOptionsSizer->Add( contrastModeSizer, 0, wxEXPAND, 5 );
657
658 m_layerDisplaySeparator = new wxStaticLine( layerDisplayPane, wxID_ANY, wxDefaultPosition,
659 wxDefaultSize, wxLI_HORIZONTAL );
660 layerDisplayOptionsSizer->Add( m_layerDisplaySeparator, 0, wxEXPAND | wxBOTTOM, 3 );
661
662 m_cbFlipBoard = new wxCheckBox( layerDisplayPane, wxID_ANY, _( "Flip board view" ) );
663 m_cbFlipBoard->SetFont( infoFont );
664 layerDisplayOptionsSizer->Add( m_cbFlipBoard, 0, wxTOP | wxBOTTOM, 5 );
665
666 layerDisplayPane->SetSizer( layerDisplayOptionsSizer );
667 layerDisplayPane->Layout();
668 layerDisplayOptionsSizer->Fit( layerDisplayPane );
669
670 m_panelLayersSizer->Add( m_paneLayerDisplayOptions, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5 );
671
672 m_paneLayerDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
673 [&]( wxCommandEvent& aEvent )
674 {
675 Freeze();
676 m_panelLayers->Fit();
677 m_sizerOuter->Layout();
678 Thaw();
679 } );
680
681 // Create net display options
682
684 _( "Net Display Options" ) );
686 m_paneNetDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
687
688 wxWindow* netDisplayPane = m_paneNetDisplayOptions->GetPane();
689 wxBoxSizer* netDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
690
692
694
695 if( hotkey )
696 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
697 else
698 msg = _( "Net colors:" );
699
700 m_txtNetDisplayTitle = new wxStaticText( netDisplayPane, wxID_ANY, msg );
701 m_txtNetDisplayTitle->SetFont( infoFont );
702 m_txtNetDisplayTitle->Wrap( -1 );
703 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
704
705 netDisplayOptionsSizer->Add( m_txtNetDisplayTitle, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
706
707 wxBoxSizer* netColorSizer = new wxBoxSizer( wxHORIZONTAL );
708
709 m_rbNetColorAll = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ), wxDefaultPosition,
710 wxDefaultSize, wxRB_GROUP );
711 m_rbNetColorAll->SetFont( infoFont );
712 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
713
714 netColorSizer->Add( m_rbNetColorAll, 0, wxRIGHT, 5 );
715 netColorSizer->AddStretchSpacer();
716
717 m_rbNetColorRatsnest = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Ratsnest" ) );
718 m_rbNetColorRatsnest->SetFont( infoFont );
719 m_rbNetColorRatsnest->SetValue( true );
720 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
721
722 netColorSizer->Add( m_rbNetColorRatsnest, 0, wxRIGHT, 5 );
723 netColorSizer->AddStretchSpacer();
724
725 m_rbNetColorOff = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
726 m_rbNetColorOff->SetFont( infoFont );
727 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
728
729 netColorSizer->Add( m_rbNetColorOff, 0, 0, 5 );
730
731 netDisplayOptionsSizer->Add( netColorSizer, 0, wxEXPAND | wxBOTTOM, 5 );
732
734
736
737 if( hotkey )
738 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
739 else
740 msg = _( "Ratsnest display:" );
741
742 m_txtRatsnestVisibility = new wxStaticText( netDisplayPane, wxID_ANY, msg );
743 m_txtRatsnestVisibility->SetFont( infoFont );
744 m_txtRatsnestVisibility->Wrap( -1 );
745 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
746
747 netDisplayOptionsSizer->Add( m_txtRatsnestVisibility, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
748
749 wxBoxSizer* ratsnestDisplayModeSizer = new wxBoxSizer( wxHORIZONTAL );
750
751 m_rbRatsnestAllLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ),
752 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
753 m_rbRatsnestAllLayers->SetFont( infoFont );
754 m_rbRatsnestAllLayers->SetValue( true );
755 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
756
757 ratsnestDisplayModeSizer->Add( m_rbRatsnestAllLayers, 0, wxRIGHT, 5 );
758 ratsnestDisplayModeSizer->AddStretchSpacer();
759
760 m_rbRatsnestVisLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Visible layers" ) );
761 m_rbRatsnestVisLayers->SetFont( infoFont );
762 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
763
764 ratsnestDisplayModeSizer->Add( m_rbRatsnestVisLayers, 0, wxRIGHT, 5 );
765 ratsnestDisplayModeSizer->AddStretchSpacer();
766
767 m_rbRatsnestNone = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
768 m_rbRatsnestNone->SetFont( infoFont );
769 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
770
771 ratsnestDisplayModeSizer->Add( m_rbRatsnestNone, 0, 0, 5 );
772
773 netDisplayOptionsSizer->Add( ratsnestDisplayModeSizer, 0, wxEXPAND | wxBOTTOM, 5 );
774
776
777 netDisplayPane->SetSizer( netDisplayOptionsSizer );
778 netDisplayPane->Layout();
779 netDisplayOptionsSizer->Fit( netDisplayPane );
780
781 m_netsTabOuterSizer->Add( m_paneNetDisplayOptions, 0, wxEXPAND | wxTOP, 5 );
782
783 m_paneNetDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
784 [&]( wxCommandEvent& aEvent )
785 {
786 Freeze();
788 m_sizerOuter->Layout();
789 passOnFocus();
790 Thaw();
791 } );
792
793 m_rbNetColorAll->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
794 m_rbNetColorOff->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
795 m_rbNetColorRatsnest->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
796
797 m_rbRatsnestAllLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
798 m_rbRatsnestVisLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
799 m_rbRatsnestNone->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
800}
801
802
804{
805 DPI_SCALING_COMMON dpi( nullptr, m_frame );
806 wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
807 return size;
808}
809
810
812{
814}
815
816
818{
820}
821
822
823void APPEARANCE_CONTROLS::OnNotebookPageChanged( wxNotebookEvent& aEvent )
824{
825 // Work around wxMac issue where the notebook pages are blank
826#ifdef __WXMAC__
827 int page = aEvent.GetSelection();
828
829 if( page >= 0 )
830 m_notebook->ChangeSelection( static_cast<unsigned>( page ) );
831#endif
832
833#ifndef __WXMSW__
834 // Because wxWidgets is broken and will send click events to children of the collapsible
835 // panes even if they are collapsed without this
836 Freeze();
837 m_panelLayers->Fit();
839 m_sizerOuter->Layout();
840 Thaw();
841#endif
842
843 Bind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
844}
845
846
847void APPEARANCE_CONTROLS::idleFocusHandler( wxIdleEvent& aEvent )
848{
849 passOnFocus();
850 Unbind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
851}
852
853
854void APPEARANCE_CONTROLS::OnSetFocus( wxFocusEvent& aEvent )
855{
856#ifdef __WXMSW__
857 // In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
858 // focus and give it back to the parent in the button event handler.
859 if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
860 {
861 wxCommandEvent evt( wxEVT_BUTTON );
862 wxPostEvent( btn, evt );
863 }
864#endif
865
866 passOnFocus();
867 aEvent.Skip();
868}
869
870
871void APPEARANCE_CONTROLS::OnSize( wxSizeEvent& aEvent )
872{
873 aEvent.Skip();
874}
875
876
877void APPEARANCE_CONTROLS::OnNetGridClick( wxGridEvent& event )
878{
879 int row = event.GetRow();
880 int col = event.GetCol();
881
882 switch( col )
883 {
885 m_netsTable->SetValueAsBool( row, col, !m_netsTable->GetValueAsBool( row, col ) );
886 m_netsGrid->ForceRefresh();
887 break;
888
889 default:
890 break;
891 }
892}
893
894
896{
897 int row = event.GetRow();
898 int col = event.GetCol();
899
900 switch( col )
901 {
903 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
904 break;
905
906 default:
907 break;
908 }
909}
910
911
913{
914 m_netsGrid->SelectRow( event.GetRow() );
915
916 wxString netName = UnescapeString( m_netsGrid->GetCellValue( event.GetRow(),
918 wxMenu menu;
919
920 menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, _( "Set Net Color" ), wxEmptyString,
921 wxITEM_NORMAL ) );
922 menu.Append( new wxMenuItem( &menu, ID_CLEAR_NET_COLOR, _( "Clear Net Color" ), wxEmptyString,
923 wxITEM_NORMAL ) );
924
925 menu.AppendSeparator();
926
927 menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
928 wxString::Format( _( "Highlight %s" ), netName ), wxEmptyString,
929 wxITEM_NORMAL ) );
930 menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
931 wxString::Format( _( "Select Tracks and Vias in %s" ), netName ),
932 wxEmptyString, wxITEM_NORMAL ) );
933 menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
934 wxString::Format( _( "Unselect Tracks and Vias in %s" ), netName ),
935 wxEmptyString, wxITEM_NORMAL ) );
936
937 menu.AppendSeparator();
938
939 menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, _( "Show All Nets" ), wxEmptyString,
940 wxITEM_NORMAL ) );
941 menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, _( "Hide All Other Nets" ),
942 wxEmptyString, wxITEM_NORMAL ) );
943
944 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetContextMenu, this );
945
946 PopupMenu( &menu );
947}
948
949
951{
952 wxPoint pos = m_netsGrid->CalcUnscrolledPosition( aEvent.GetPosition() );
953 wxGridCellCoords cell = m_netsGrid->XYToCell( pos );
954
955 if( aEvent.Moving() || aEvent.Entering() )
956 {
957 aEvent.Skip();
958
959 if( !cell )
960 {
961 m_netsGrid->GetGridWindow()->UnsetToolTip();
962 return;
963 }
964
965 if( cell == m_hoveredCell )
966 return;
967
968 m_hoveredCell = cell;
969
970 NET_GRID_ENTRY& net = m_netsTable->GetEntry( cell.GetRow() );
971
972 wxString name = net.name;
973 wxString showOrHide = net.visible ? _( "Click to hide ratsnest for %s" )
974 : _( "Click to show ratsnest for %s" );
975 wxString tip;
976
977 if( cell.GetCol() == NET_GRID_TABLE::COL_VISIBILITY )
978 {
979 tip.Printf( showOrHide, name );
980 }
981 else if( cell.GetCol() == NET_GRID_TABLE::COL_COLOR )
982 {
983 tip = _( "Double click (or middle click) to change color; "
984 "right click for more actions" );
985 }
986
987 m_netsGrid->GetGridWindow()->SetToolTip( tip );
988 }
989 else if( aEvent.Leaving() )
990 {
991 m_netsGrid->UnsetToolTip();
992 aEvent.Skip();
993 }
994 else if( aEvent.Dragging() )
995 {
996 // not allowed
997 CallAfter( [&]()
998 {
999 m_netsGrid->ClearSelection();
1000 } );
1001 }
1002 else if( aEvent.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !!cell )
1003 {
1004 int row = cell.GetRow();
1005 int col = cell.GetCol();
1006
1007 if(col == NET_GRID_TABLE::COL_COLOR )
1008 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
1009
1010 aEvent.Skip();
1011 }
1012 else
1013 {
1014 aEvent.Skip();
1015 }
1016}
1017
1018
1020{
1021 m_notebook->SetPageText( 0, _( "Layers" ) );
1022 m_notebook->SetPageText( 1, _( "Objects" ) );
1023
1024 if( m_notebook->GetPageCount() >= 3 )
1025 m_notebook->SetPageText( 2, _( "Nets" ) );
1026
1027 Freeze();
1028 rebuildLayers();
1033 rebuildNets();
1034
1038
1040
1041 Thaw();
1042 Refresh();
1043}
1044
1045
1047{
1048 Freeze();
1049 rebuildLayers();
1053 rebuildNets();
1057
1059
1061
1062 if( m_board )
1063 m_board->AddListener( this );
1064
1065 Thaw();
1066 Refresh();
1067}
1068
1069
1071{
1073}
1074
1075
1076void APPEARANCE_CONTROLS::OnNetVisibilityChanged( int aNetCode, bool aVisibility )
1077{
1078 int row = m_netsTable->GetRowByNetcode( aNetCode );
1079
1080 if( row >= 0 )
1081 {
1083 m_netsGrid->ForceRefresh();
1084 }
1085}
1086
1087
1089{
1090 return aBoardItem->Type() == PCB_NETINFO_T;
1091}
1092
1093
1094bool APPEARANCE_CONTROLS::doesBoardItemNeedRebuild( std::vector<BOARD_ITEM*>& aBoardItems )
1095{
1096 bool rebuild = std::any_of( aBoardItems.begin(), aBoardItems.end(),
1097 []( const BOARD_ITEM* a )
1098 {
1099 return a->Type() == PCB_NETINFO_T;
1100 } );
1101
1102 return rebuild;
1103}
1104
1105
1107{
1108 if( doesBoardItemNeedRebuild( aItem ) )
1110}
1111
1112
1113void APPEARANCE_CONTROLS::OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1114{
1115 if( doesBoardItemNeedRebuild( aItems ) )
1117}
1118
1119
1121{
1122 if( doesBoardItemNeedRebuild( aItem ) )
1124}
1125
1126
1127void APPEARANCE_CONTROLS::OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1128{
1129 if( doesBoardItemNeedRebuild( aItems ) )
1131}
1132
1133
1135{
1136 if( doesBoardItemNeedRebuild( aItem ) )
1138}
1139
1140
1141void APPEARANCE_CONTROLS::OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1142{
1143 if( doesBoardItemNeedRebuild( aItems ) )
1145}
1146
1147
1149{
1150 Freeze();
1151 rebuildNets();
1152 Thaw();
1153}
1154
1155
1157{
1160}
1161
1162
1164{
1165 // This is essentially a list of hacks because DarkMode isn't yet implemented inside
1166 // wxWidgets.
1167 //
1168 // The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
1169 // overriding some virtual method or responding to some wxWidgets event so that the parent
1170 // doesn't have to know what it contains. But, that's not where we are, so... :shrug:
1171
1172 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
1173
1174 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1175
1176 for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
1177 {
1178 if( child && child->GetWindow() )
1179 child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
1180 }
1181
1182 // Easier than calling OnDarkModeToggle on all the GRID_CELL_COLOR_RENDERERs:
1183 m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
1186
1187 for( const std::pair<const wxString, APPEARANCE_SETTING*>& pair : m_netclassSettingsMap )
1188 {
1189 if( pair.second->ctl_color )
1190 pair.second->ctl_color->OnDarkModeToggle();
1191 }
1192
1193 OnLayerChanged(); // Update selected highlighting
1194}
1195
1196
1198{
1199 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1200 {
1201 setting->ctl_panel->SetBackgroundColour( m_layerPanelColour );
1202 setting->ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
1203 }
1204
1205 wxChar r = m_layerPanelColour.Red();
1206 wxChar g = m_layerPanelColour.Green();
1207 wxChar b = m_layerPanelColour.Blue();
1208
1209 if( r < 240 || g < 240 || b < 240 )
1210 {
1211 r = wxChar( std::min( (int) r + 15, 255 ) );
1212 g = wxChar( std::min( (int) g + 15, 255 ) );
1213 b = wxChar( std::min( (int) b + 15, 255 ) );
1214 }
1215 else
1216 {
1217 r = wxChar( std::max( (int) r - 15, 0 ) );
1218 g = wxChar( std::max( (int) g - 15, 0 ) );
1219 b = wxChar( std::max( (int) b - 15, 0 ) );
1220 }
1221
1222 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1223
1224 if( !m_layerSettingsMap.count( current ) )
1225 {
1226 wxASSERT( m_layerSettingsMap.count( F_Cu ) );
1227 current = F_Cu;
1228 }
1229
1230 APPEARANCE_SETTING* newSetting = m_layerSettingsMap[ current ];
1231
1232 newSetting->ctl_panel->SetBackgroundColour( wxColour( r, g, b ) );
1234
1235 Refresh();
1236}
1237
1238
1239void APPEARANCE_CONTROLS::SetLayerVisible( int aLayer, bool isVisible )
1240{
1241 LSET visible = getVisibleLayers();
1242 PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
1243
1244 if( visible.test( layer ) == isVisible )
1245 return;
1246
1247 visible.set( layer, isVisible );
1248 setVisibleLayers( visible );
1249
1250 m_frame->GetCanvas()->GetView()->SetLayerVisible( layer, isVisible );
1251
1253}
1254
1255
1257{
1258 if( m_objectSettingsMap.count( aLayer ) )
1259 {
1260 APPEARANCE_SETTING* setting = m_objectSettingsMap.at( aLayer );
1261 setting->ctl_visibility->SetValue( isVisible );
1262 }
1263
1264 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
1265
1267
1268 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1270}
1271
1272
1274{
1275 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1276
1277 if( m_isFpEditor )
1278 {
1279 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1280 view->SetLayerVisible( layer, aLayers.Contains( layer ) );
1281 }
1282 else
1283 {
1284 m_frame->GetBoard()->SetVisibleLayers( aLayers );
1285
1286 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as
1287 // they won't be found in the view layer's itemset for repainting.
1289 []( KIGFX::VIEW_ITEM* aItem ) -> bool
1290 {
1291 // Items rendered to composite layers (such as LAYER_PAD_TH) must be redrawn
1292 // whether they're optionally flashed or not (as the layer being hidden/shown
1293 // might be the last layer the item is visible on).
1294 return dynamic_cast<PCB_VIA*>( aItem ) || dynamic_cast<PAD*>( aItem );
1295 } );
1296
1298 }
1299}
1300
1301
1303{
1304 if( m_isFpEditor )
1305 {
1306 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1307
1308 for( size_t i = 0; i < GAL_LAYER_INDEX( LAYER_ZONE_START ); i++ )
1309 view->SetLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ), aLayers.test( i ) );
1310 }
1311 else
1312 {
1313 // Ratsnest visibility is controlled by the ratsnest option, and not by the preset
1316
1317 m_frame->GetBoard()->SetVisibleElements( aLayers );
1318
1320 }
1321}
1322
1323
1325{
1326 if( m_isFpEditor )
1327 {
1328 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1329 LSET set;
1330
1331 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1332 set.set( layer, view->IsLayerVisible( layer ) );
1333
1334 return set;
1335 }
1336 else
1337 {
1338 return m_frame->GetBoard()->GetVisibleLayers();
1339 }
1340}
1341
1342
1344{
1345 if( m_isFpEditor )
1346 {
1347 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1348 GAL_SET set;
1349 set.reset();
1350
1351 for( size_t i = 0; i < set.size(); i++ )
1352 set.set( i, view->IsLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ) ) );
1353
1354 return set;
1355 }
1356 else
1357 {
1358 return m_frame->GetBoard()->GetVisibleElements();
1359 }
1360}
1361
1362
1364{
1365 const PCB_DISPLAY_OPTIONS& options = m_frame->GetDisplayOptions();
1366
1367 switch( options.m_ContrastModeDisplay )
1368 {
1369 case HIGH_CONTRAST_MODE::NORMAL: m_rbHighContrastNormal->SetValue( true ); break;
1370 case HIGH_CONTRAST_MODE::DIMMED: m_rbHighContrastDim->SetValue( true ); break;
1371 case HIGH_CONTRAST_MODE::HIDDEN: m_rbHighContrastOff->SetValue( true ); break;
1372 }
1373
1374 switch( options.m_NetColorMode )
1375 {
1376 case NET_COLOR_MODE::ALL: m_rbNetColorAll->SetValue( true ); break;
1377 case NET_COLOR_MODE::RATSNEST: m_rbNetColorRatsnest->SetValue( true ); break;
1378 case NET_COLOR_MODE::OFF: m_rbNetColorOff->SetValue( true ); break;
1379 }
1380
1381 m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
1382
1383 if( !m_isFpEditor )
1384 {
1386
1388 m_rbRatsnestNone->SetValue( true );
1389 else if( cfg->m_Display.m_RatsnestMode == RATSNEST_MODE::ALL )
1390 m_rbRatsnestAllLayers->SetValue( true );
1391 else
1392 m_rbRatsnestVisLayers->SetValue( true );
1393
1394 wxASSERT( m_objectSettingsMap.count( LAYER_RATSNEST ) );
1397 }
1398}
1399
1400
1401std::vector<LAYER_PRESET> APPEARANCE_CONTROLS::GetUserLayerPresets() const
1402{
1403 std::vector<LAYER_PRESET> ret;
1404
1405 for( const std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
1406 {
1407 if( !pair.second.readOnly )
1408 ret.emplace_back( pair.second );
1409 }
1410
1411 return ret;
1412}
1413
1414
1415void APPEARANCE_CONTROLS::SetUserLayerPresets( std::vector<LAYER_PRESET>& aPresetList )
1416{
1417 // Reset to defaults
1419
1420 for( const LAYER_PRESET& preset : aPresetList )
1421 {
1422 if( m_layerPresets.count( preset.name ) )
1423 continue;
1424
1425 m_layerPresets[preset.name] = preset;
1426
1427 m_presetMRU.Add( preset.name );
1428 }
1429
1431}
1432
1433
1435{
1436 m_layerPresets.clear();
1437 m_presetMRU.clear();
1438
1439 // Load the read-only defaults
1443 {
1444 m_layerPresets[preset.name] = preset;
1445 m_layerPresets[preset.name].readOnly = true;
1446
1447 m_presetMRU.Add( preset.name );
1448 }
1449}
1450
1451
1452void APPEARANCE_CONTROLS::ApplyLayerPreset( const wxString& aPresetName )
1453{
1454 updateLayerPresetSelection( aPresetName );
1455
1456 wxCommandEvent dummy;
1458}
1459
1460
1462{
1463 if( m_layerPresets.count( aPreset.name ) )
1465 else
1466 m_currentPreset = nullptr;
1467
1469 : nullptr;
1470
1472 doApplyLayerPreset( aPreset );
1473}
1474
1475
1476std::vector<VIEWPORT> APPEARANCE_CONTROLS::GetUserViewports() const
1477{
1478 std::vector<VIEWPORT> ret;
1479
1480 for( const std::pair<const wxString, VIEWPORT>& pair : m_viewports )
1481 ret.emplace_back( pair.second );
1482
1483 return ret;
1484}
1485
1486
1487void APPEARANCE_CONTROLS::SetUserViewports( std::vector<VIEWPORT>& aViewportList )
1488{
1489 m_viewports.clear();
1490
1491 for( const VIEWPORT& viewport : aViewportList )
1492 {
1493 if( m_viewports.count( viewport.name ) )
1494 continue;
1495
1496 m_viewports[viewport.name] = viewport;
1497
1498 m_viewportMRU.Add( viewport.name );
1499 }
1500
1502}
1503
1504
1505void APPEARANCE_CONTROLS::ApplyViewport( const wxString& aViewportName )
1506{
1507 updateViewportSelection( aViewportName );
1508
1509 wxCommandEvent dummy;
1511}
1512
1513
1515{
1516 updateViewportSelection( aViewport.name );
1517 doApplyViewport( aViewport );
1518}
1519
1520
1522{
1523 BOARD* board = m_frame->GetBoard();
1524 LSET enabled = board->GetEnabledLayers();
1525 LSET visible = getVisibleLayers();
1526
1528 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
1529 bool readOnly = theme->IsReadOnly();
1530
1531#ifdef __WXMAC__
1532 wxSizerItem* m_windowLayersSizerItem = m_panelLayersSizer->GetItem( m_windowLayers );
1533 m_windowLayersSizerItem->SetFlag( m_windowLayersSizerItem->GetFlag() & ~wxTOP );
1534#endif
1535
1536 auto appendLayer =
1537 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1538 {
1539 int layer = aSetting->id;
1540
1541 wxPanel* panel = new wxPanel( m_windowLayers, layer );
1542 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
1543 panel->SetSizer( sizer );
1544
1545 panel->SetBackgroundColour( m_layerPanelColour );
1546
1547 aSetting->visible = visible[layer];
1548
1549 // TODO(JE) consider restyling this indicator
1550 INDICATOR_ICON* indicator = new INDICATOR_ICON( panel, *m_iconProvider,
1552 layer );
1553
1554 COLOR_SWATCH* swatch = new COLOR_SWATCH( panel, COLOR4D::UNSPECIFIED, layer,
1555 bgColor, theme->GetColor( layer ),
1556 SWATCH_SMALL );
1557 swatch->SetToolTip( _( "Double click or middle click for color change, "
1558 "right click for menu" ) );
1559
1560 BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE(
1561 panel, layer, KiBitmapBundle( BITMAPS::visibility ),
1562 KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
1563 btn_visible->SetToolTip( _( "Show or hide this layer" ) );
1564
1565 wxStaticText* label = new wxStaticText( panel, layer, aSetting->label );
1566 label->Wrap( -1 );
1567 label->SetToolTip( aSetting->tooltip );
1568
1569 sizer->AddSpacer( 1 );
1570 sizer->Add( indicator, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1571 sizer->AddSpacer( 5 );
1572 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1573 sizer->AddSpacer( 6 );
1574 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1575 sizer->AddSpacer( 5 );
1576 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1577
1578 m_layersOuterSizer->Add( panel, 0, wxEXPAND, 0 );
1579
1580 aSetting->ctl_panel = panel;
1581 aSetting->ctl_indicator = indicator;
1582 aSetting->ctl_visibility = btn_visible;
1583 aSetting->ctl_color = swatch;
1584 aSetting->ctl_text = label;
1585
1586 panel->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1587 indicator->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1588 swatch->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1589 label->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1590
1591 btn_visible->Bind( TOGGLE_CHANGED,
1592 [&]( wxCommandEvent& aEvent )
1593 {
1594 wxObject* btn = aEvent.GetEventObject();
1595 int layerId = static_cast<wxWindow*>( btn )->GetId();
1596
1597 onLayerVisibilityToggled( static_cast<PCB_LAYER_ID>( layerId ) );
1598 } );
1599
1600 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
1601 this );
1603 this ) );
1604 swatch->SetReadOnly( readOnly );
1605
1606 panel->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1607 indicator->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1608 swatch->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1609 btn_visible->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1610 label->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1611 };
1612
1613 auto updateLayer =
1614 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1615 {
1616 int layer = aSetting->id;
1617 aSetting->visible = visible[layer];
1618 aSetting->ctl_panel->Show();
1619 aSetting->ctl_panel->SetId( layer );
1620 aSetting->ctl_indicator->SetWindowID( layer );
1621 aSetting->ctl_color->SetWindowID( layer );
1622 aSetting->ctl_color->SetSwatchColor( theme->GetColor( layer ), false );
1623 aSetting->ctl_visibility->SetWindowID( layer );
1624 aSetting->ctl_text->SetLabelText( aSetting->label );
1625 aSetting->ctl_text->SetId( layer );
1626 aSetting->ctl_text->SetToolTip( aSetting->tooltip );
1627 };
1628
1629 // technical layers are shown in this order:
1630 // Because they are static, wxGetTranslation must be explicitly
1631 // called for tooltips.
1632 static const struct {
1633 PCB_LAYER_ID layerId;
1634 wxString tooltip;
1635 } non_cu_seq[] = {
1636 { F_Adhes, _HKI( "Adhesive on board's front" ) },
1637 { B_Adhes, _HKI( "Adhesive on board's back" ) },
1638 { F_Paste, _HKI( "Solder paste on board's front" ) },
1639 { B_Paste, _HKI( "Solder paste on board's back" ) },
1640 { F_SilkS, _HKI( "Silkscreen on board's front" ) },
1641 { B_SilkS, _HKI( "Silkscreen on board's back" ) },
1642 { F_Mask, _HKI( "Solder mask on board's front" ) },
1643 { B_Mask, _HKI( "Solder mask on board's back" ) },
1644 { Dwgs_User, _HKI( "Explanatory drawings" ) },
1645 { Cmts_User, _HKI( "Explanatory comments" ) },
1646 { Eco1_User, _HKI( "User defined meaning" ) },
1647 { Eco2_User, _HKI( "User defined meaning" ) },
1648 { Edge_Cuts, _HKI( "Board's perimeter definition" ) },
1649 { Margin, _HKI( "Board's edge setback outline" ) },
1650 { F_CrtYd, _HKI( "Footprint courtyards on board's front" ) },
1651 { B_CrtYd, _HKI( "Footprint courtyards on board's back" ) },
1652 { F_Fab, _HKI( "Footprint assembly on board's front" ) },
1653 { B_Fab, _HKI( "Footprint assembly on board's back" ) },
1654 { User_1, _HKI( "User defined layer 1" ) },
1655 { User_2, _HKI( "User defined layer 2" ) },
1656 { User_3, _HKI( "User defined layer 3" ) },
1657 { User_4, _HKI( "User defined layer 4" ) },
1658 { User_5, _HKI( "User defined layer 5" ) },
1659 { User_6, _HKI( "User defined layer 6" ) },
1660 { User_7, _HKI( "User defined layer 7" ) },
1661 { User_8, _HKI( "User defined layer 8" ) },
1662 { User_9, _HKI( "User defined layer 9" ) },
1663 };
1664
1665 // There is a spacer added to the end of the list that we need to remove and re-add
1666 // after possibly adding additional layers
1667 if( m_layersOuterSizer->GetItemCount() > 0 )
1668 {
1669 m_layersOuterSizer->Detach( m_layersOuterSizer->GetItemCount() - 1 );
1670 }
1671 // Otherwise, this is the first time we are updating the control, so we need to attach
1672 // the handler
1673 else
1674 {
1675 // Add right click handling to show the context menu when clicking to the free area in
1676 // m_windowLayers (below the layer items)
1677 m_windowLayers->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1678 }
1679
1680 std::size_t total_layers = enabled.CuStack().size();
1681
1682 for( const auto& entry : non_cu_seq )
1683 {
1684 if( enabled[entry.layerId] )
1685 total_layers++;
1686 }
1687
1688 // Adds layers to the panel until we have enough to hold our total count
1689 while( total_layers > m_layerSettings.size() )
1690 m_layerSettings.push_back( std::make_unique<APPEARANCE_SETTING>() );
1691
1692 // We never delete layers from the panel, only hide them. This saves us
1693 // having to recreate the (possibly) later with minimal overhead
1694 for( std::size_t ii = total_layers; ii < m_layerSettings.size(); ++ii )
1695 {
1696 if( m_layerSettings[ii]->ctl_panel )
1697 m_layerSettings[ii]->ctl_panel->Show( false );
1698 }
1699
1700 auto layer_it = m_layerSettings.begin();
1701
1702 // show all coppers first, with front on top, back on bottom, then technical layers
1703 for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack, ++layer_it )
1704 {
1705 PCB_LAYER_ID layer = *cu_stack;
1706 wxString dsc;
1707
1708 switch( layer )
1709 {
1710 case F_Cu: dsc = _( "Front copper layer" ); break;
1711 case B_Cu: dsc = _( "Back copper layer" ); break;
1712 default: dsc = _( "Inner copper layer" ); break;
1713 }
1714
1715 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1716
1717 setting->label = board->GetLayerName( layer );
1718 setting->id = layer;
1719 setting->tooltip = dsc;
1720
1721 if( setting->ctl_panel == nullptr )
1722 appendLayer( setting );
1723 else
1724 updateLayer( setting );
1725
1726 m_layerSettingsMap[layer] = setting.get();
1727
1729 {
1730 setting->ctl_text->Disable();
1731 setting->ctl_color->SetToolTip( wxEmptyString );
1732 }
1733 }
1734
1735 for( const auto& entry : non_cu_seq )
1736 {
1737 PCB_LAYER_ID layer = entry.layerId;
1738
1739 if( !enabled[layer] )
1740 continue;
1741
1742 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1743
1744 setting->label = board->GetLayerName( layer );
1745 setting->id = layer;
1746 // Because non_cu_seq is created static, we must explicitly call wxGetTranslation for
1747 // texts which are internationalized
1748 setting->tooltip = wxGetTranslation( entry.tooltip );
1749
1750 if( setting->ctl_panel == nullptr )
1751 appendLayer( setting );
1752 else
1753 updateLayer( setting );
1754
1755 m_layerSettingsMap[layer] = setting.get();
1756
1758 {
1759 setting->ctl_text->Disable();
1760 setting->ctl_color->SetToolTip( wxEmptyString );
1761 }
1762
1763 ++layer_it;
1764 }
1765
1766 m_layersOuterSizer->AddSpacer( 10 );
1767 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1768 m_windowLayers->Layout();
1769
1770 m_paneLayerDisplayOptions->SetLabel( _( "Layer Display Options" ) );
1771
1773 wxString msg;
1774
1775 if( hotkey )
1776 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
1777 else
1778 msg = _( "Inactive layers:" );
1779
1780 m_inactiveLayersLabel->SetLabel( msg );
1781
1782 m_rbHighContrastNormal->SetLabel( _( "Normal" ) );
1783 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
1784
1785 m_rbHighContrastDim->SetLabel( _( "Dim" ) );
1786 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
1787
1788 m_rbHighContrastOff->SetLabel( _( "Hide" ) );
1789 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
1790
1791 m_cbFlipBoard->SetLabel( _( "Flip board view" ) );
1792}
1793
1794
1796{
1797 delete m_layerContextMenu;
1798 m_layerContextMenu = new wxMenu;
1799
1800 KIUI::AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_COPPER_LAYERS, _( "Show All Copper Layers" ),
1801 KiBitmap( BITMAPS::show_all_copper_layers ) );
1802 KIUI::AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_COPPER_LAYERS, _( "Hide All Copper Layers" ),
1803 KiBitmap( BITMAPS::show_no_copper_layers ) );
1804
1805 m_layerContextMenu->AppendSeparator();
1806
1808 _( "Hide All Layers But Active" ), KiBitmap( BITMAPS::select_w_layer ) );
1809
1810 m_layerContextMenu->AppendSeparator();
1811
1813 _( "Show All Non Copper Layers" ),
1814 KiBitmap( BITMAPS::show_no_copper_layers ) );
1815
1817 _( "Hide All Non Copper Layers" ),
1818 KiBitmap( BITMAPS::show_all_copper_layers ) );
1819
1820 m_layerContextMenu->AppendSeparator();
1821
1823 KiBitmap( BITMAPS::show_all_layers ) );
1824
1826 KiBitmap( BITMAPS::show_no_layers ) );
1827
1828 m_layerContextMenu->AppendSeparator();
1829
1831 _( "Show Only Front Assembly Layers" ),
1832 KiBitmap( BITMAPS::show_front_assembly_layers ) );
1833
1834 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT, _( "Show Only Front Layers" ),
1835 KiBitmap( BITMAPS::show_all_front_layers ) );
1836
1837 // Only show the internal layer option if internal layers are enabled
1838 if( m_frame->GetBoard()->GetCopperLayerCount() > 2 )
1839 {
1841 _( "Show Only Inner Layers" ),
1842 KiBitmap( BITMAPS::show_all_copper_layers ) );
1843 }
1844
1845 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_BACK, _( "Show Only Back Layers" ),
1846 KiBitmap( BITMAPS::show_all_back_layers ) );
1847
1849 _( "Show Only Back Assembly Layers" ),
1850 KiBitmap( BITMAPS::show_back_assembly_layers ) );
1851}
1852
1853
1854void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent )
1855{
1856 BOARD* board = m_frame->GetBoard();
1857 LSET visible = getVisibleLayers();
1858
1859 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1860
1861 // The new preset. We keep the visibility state of objects:
1862 LAYER_PRESET preset;
1864
1865 switch( aEvent.GetId() )
1866 {
1868 preset.layers = presetNoLayers.layers;
1869 ApplyLayerPreset( preset );
1870 return;
1871
1873 preset.layers = presetAllLayers.layers;
1874 ApplyLayerPreset( preset );
1875 return;
1876
1878 visible |= presetAllCopper.layers;
1879 setVisibleLayers( visible );
1880 break;
1881
1883 preset.layers = presetNoLayers.layers | LSET( current );
1884 ApplyLayerPreset( preset );
1885 break;
1886
1888 visible &= ~presetAllCopper.layers;
1889
1890 if( !visible.test( current ) && visible.count() > 0 )
1891 m_frame->SetActiveLayer( *visible.Seq().begin() );
1892
1893 setVisibleLayers( visible );
1894 break;
1895
1897 visible &= presetAllCopper.layers;
1898
1899 if( !visible.test( current ) && visible.count() > 0 )
1900 m_frame->SetActiveLayer( *visible.Seq().begin() );
1901
1902 setVisibleLayers( visible );
1903 break;
1904
1906 visible |= ~presetAllCopper.layers;
1907
1908 setVisibleLayers( visible );
1909 break;
1910
1913 ApplyLayerPreset( preset );
1914 return;
1915
1916 case ID_PRESET_FRONT:
1917 preset.layers = presetFront.layers;
1918 ApplyLayerPreset( preset );
1919 return;
1920
1923 ApplyLayerPreset( preset );
1924 return;
1925
1926 case ID_PRESET_BACK:
1927 preset.layers = presetBack.layers;
1928 ApplyLayerPreset( preset );
1929 return;
1930
1933 ApplyLayerPreset( preset );
1934 return;
1935 }
1936
1939
1940 if( !m_isFpEditor )
1942
1944}
1945
1946
1948{
1949 return m_notebook->GetSelection();
1950}
1951
1952
1954{
1955 size_t max = m_notebook->GetPageCount();
1956
1957 if( aTab >= 0 && static_cast<size_t>( aTab ) < max )
1958 m_notebook->SetSelection( aTab );
1959}
1960
1961
1963{
1965 bool readOnly = theme->IsReadOnly();
1966 LSET visible = getVisibleLayers();
1967 GAL_SET objects = getVisibleObjects();
1968
1969 Freeze();
1970
1971 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1972 {
1973 int layer = setting->id;
1974
1975 if( setting->ctl_visibility )
1976 setting->ctl_visibility->SetValue( visible[layer] );
1977
1978 if( setting->ctl_color )
1979 {
1980 const COLOR4D& color = theme->GetColor( layer );
1981 setting->ctl_color->SetSwatchColor( color, false );
1982 setting->ctl_color->SetReadOnly( readOnly );
1983 }
1984 }
1985
1986 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
1987 {
1988 GAL_LAYER_ID layer = static_cast<GAL_LAYER_ID>( setting->id );
1989
1990 if( setting->ctl_visibility )
1991 setting->ctl_visibility->SetValue( objects.Contains( layer ) );
1992
1993 if( setting->ctl_color )
1994 {
1995 const COLOR4D& color = theme->GetColor( layer );
1996 setting->ctl_color->SetSwatchColor( color, false );
1997 setting->ctl_color->SetReadOnly( readOnly );
1998 }
1999 }
2000
2001 // Update indicators and panel background colors
2003
2004 Thaw();
2005
2006 m_windowLayers->Refresh();
2007}
2008
2009
2010void APPEARANCE_CONTROLS::onLayerLeftClick( wxMouseEvent& aEvent )
2011{
2012 wxWindow* eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() );
2013
2014 PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() );
2015
2017 return;
2018
2019 m_frame->SetActiveLayer( layer );
2020 passOnFocus();
2021}
2022
2023
2024void APPEARANCE_CONTROLS::rightClickHandler( wxMouseEvent& aEvent )
2025{
2026 wxASSERT( m_layerContextMenu );
2027 PopupMenu( m_layerContextMenu );
2028 passOnFocus();
2029};
2030
2031
2033{
2034 LSET visibleLayers = getVisibleLayers();
2035
2036 visibleLayers.set( aLayer, !visibleLayers.test( aLayer ) );
2037 setVisibleLayers( visibleLayers );
2038 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, visibleLayers.test( aLayer ) );
2039
2042}
2043
2044
2046 bool isFinal )
2047{
2048 // Special-case controls
2049 switch( aLayer )
2050 {
2051 case LAYER_RATSNEST:
2052 {
2053 // don't touch the layers. ratsnest is enabled on per-item basis.
2055 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, true );
2056
2058 {
2060 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
2063 }
2064
2065 break;
2066 }
2067
2068 case LAYER_GRID:
2069 m_frame->SetGridVisibility( isVisible );
2072 break;
2073
2074 case LAYER_FP_TEXT:
2075 // Because Footprint Text is a meta-control that also can disable values/references,
2076 // drag them along here so that the user is less likely to be confused.
2077 if( isFinal )
2078 {
2079 // Should only trigger when you actually click the Footprint Text button
2080 // Otherwise it goes into infinite recursive loop with the following case section
2082 onObjectVisibilityChanged( LAYER_FP_VALUES, isVisible, false );
2083 m_objectSettingsMap[LAYER_FP_REFERENCES]->ctl_visibility->SetValue( isVisible );
2084 m_objectSettingsMap[LAYER_FP_VALUES]->ctl_visibility->SetValue( isVisible );
2085 }
2086 break;
2087
2089 case LAYER_FP_VALUES:
2090 // In case that user changes Footprint Value/References when the Footprint Text
2091 // meta-control is disabled, we should put it back on.
2092 if( isVisible )
2093 {
2094 onObjectVisibilityChanged( LAYER_FP_TEXT, isVisible, false );
2095 m_objectSettingsMap[LAYER_FP_TEXT]->ctl_visibility->SetValue( isVisible );
2096 }
2097 break;
2098
2099 default:
2100 break;
2101 }
2102
2103 GAL_SET visible = getVisibleObjects();
2104
2105 if( visible.Contains( aLayer ) != isVisible )
2106 {
2107 visible.set( aLayer, isVisible );
2108 setVisibleObjects( visible );
2109 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
2111 }
2112
2113 if( isFinal )
2114 {
2116 passOnFocus();
2117 }
2118}
2119
2120
2122{
2124 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2125 GAL_SET visible = getVisibleObjects();
2126 int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
2127 int labelWidth = 0;
2128
2129 m_objectSettings.clear();
2130 m_objectsOuterSizer->Clear( true );
2131 m_objectsOuterSizer->AddSpacer( 5 );
2132
2133 auto appendObject =
2134 [&]( const std::unique_ptr<APPEARANCE_SETTING>& aSetting )
2135 {
2136 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2137 int layer = aSetting->id;
2138
2139 aSetting->visible = visible.Contains( ToGalLayer( layer ) );
2140 COLOR4D color = theme->GetColor( layer );
2141 COLOR4D defColor = theme->GetDefaultColor( layer );
2142
2143 if( color != COLOR4D::UNSPECIFIED )
2144 {
2145 COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer,
2146 bgColor, defColor, SWATCH_SMALL );
2147 swatch->SetToolTip( _( "Left double click or middle click for color change, "
2148 "right click for menu" ) );
2149
2150 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
2151 aSetting->ctl_color = swatch;
2152
2153 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
2154 this );
2155
2157 this ) );
2158 }
2159 else
2160 {
2161 sizer->AddSpacer( swatchWidth );
2162 }
2163
2164 BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE(
2165 m_windowObjects, layer, KiBitmapBundle( BITMAPS::visibility ),
2166 KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
2167
2168 wxString tip;
2169 tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
2170 btn_visible->SetToolTip( tip );
2171
2172 aSetting->ctl_visibility = btn_visible;
2173
2174 sizer->AddSpacer( 5 );
2175
2176 btn_visible->Bind( TOGGLE_CHANGED,
2177 [&]( wxCommandEvent& aEvent )
2178 {
2179 int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
2180 bool isVisible = aEvent.GetInt();
2181 onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
2182 } );
2183
2184 wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label );
2185 label->Wrap( -1 );
2186 label->SetToolTip( aSetting->tooltip );
2187
2188 if( aSetting->can_control_opacity )
2189 {
2190 label->SetMinSize( wxSize( labelWidth, -1 ) );
2191#ifdef __WXMAC__
2192 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2193 sizer->AddSpacer( 5 );
2194 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2195#else
2196 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2197 sizer->AddSpacer( 5 );
2198 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2199#endif
2200
2201 wxSlider* slider = new wxSlider( m_windowObjects, wxID_ANY, 100, 0, 100,
2202 wxDefaultPosition, wxDefaultSize,
2203 wxSL_HORIZONTAL );
2204#ifdef __WXMAC__
2205 slider->SetMinSize( wxSize( 80, 16 ) );
2206#else
2207 slider->SetMinSize( wxSize( 80, -1 ) );
2208#endif
2209
2210 tip.Printf( _( "Set opacity of %s" ), aSetting->label.Lower() );
2211 slider->SetToolTip( tip );
2212
2213 sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
2214 aSetting->ctl_opacity = slider;
2215
2216 auto opacitySliderHandler =
2217 [=]( wxCommandEvent& aEvent )
2218 {
2219 wxSlider* ctrl = static_cast<wxSlider*>( aEvent.GetEventObject() );
2220 int value = ctrl->GetValue();
2221 onObjectOpacitySlider( layer, value / 100.0f );
2222 };
2223
2224 slider->Bind( wxEVT_SCROLL_CHANGED, opacitySliderHandler );
2225 slider->Bind( wxEVT_SCROLL_THUMBTRACK, opacitySliderHandler );
2226 slider->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
2227 }
2228 else
2229 {
2230 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2231 sizer->AddSpacer( 5 );
2232 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2233 }
2234
2235 aSetting->ctl_text = label;
2236 m_objectsOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
2237
2238 if( !aSetting->can_control_opacity )
2239 m_objectsOuterSizer->AddSpacer( 2 );
2240 };
2241
2242 for( const APPEARANCE_SETTING& s_setting : s_objectSettings )
2243 {
2244 if( m_isFpEditor && !s_allowedInFpEditor.count( s_setting.id ) )
2245 continue;
2246
2247 m_objectSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>( s_setting ) );
2248
2249 std::unique_ptr<APPEARANCE_SETTING>& setting = m_objectSettings.back();
2250
2251 // Because s_render_rows is created static, we must explicitly call wxGetTranslation
2252 // for texts which are internationalized (tool tips and item names)
2253 setting->tooltip = wxGetTranslation( s_setting.tooltip );
2254 setting->label = wxGetTranslation( s_setting.label );
2255
2256 if( setting->can_control_opacity )
2257 {
2258 int width = m_windowObjects->GetTextExtent( setting->label ).x + 5;
2259 labelWidth = std::max( labelWidth, width );
2260 }
2261
2262 if( !s_setting.spacer )
2263 m_objectSettingsMap[ToGalLayer( setting->id )] = setting.get();
2264 }
2265
2266 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2267 {
2268 if( setting->spacer )
2269 m_objectsOuterSizer->AddSpacer( m_pointSize / 2 );
2270 else
2271 appendObject( setting );
2272 }
2273
2274 m_objectsOuterSizer->Layout();
2275}
2276
2277
2279{
2280 GAL_SET visible = getVisibleObjects();
2281
2283
2284 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2285 {
2286 if( setting->spacer )
2287 continue;
2288
2289 GAL_LAYER_ID layer = ToGalLayer( setting->id );
2290
2291 if( setting->ctl_visibility )
2292 setting->ctl_visibility->SetValue( visible.Contains( layer ) );
2293
2294 if( setting->ctl_color )
2295 {
2296 COLOR4D color = m_frame->GetColorSettings()->GetColor( setting->id );
2297 setting->ctl_color->SetSwatchColor( color, false );
2298 }
2299 }
2300
2301 wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
2306
2307 m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
2308 m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
2309 m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
2310 m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
2311 m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_ImageOpacity * 100 );
2312}
2313
2314
2315void APPEARANCE_CONTROLS::buildNetClassMenu( wxMenu& aMenu, bool isDefaultClass,
2316 const wxString& aName )
2317{
2318 if( !isDefaultClass)
2319 {
2320 aMenu.Append( new wxMenuItem( &aMenu, ID_SET_NET_COLOR, _( "Set Netclass Color" ),
2321 wxEmptyString, wxITEM_NORMAL ) );
2322 }
2323
2324 wxString name = UnescapeString( aName );
2325
2326 aMenu.Append( new wxMenuItem( &aMenu, ID_HIGHLIGHT_NET,
2327 wxString::Format( _( "Highlight Nets in %s" ), name ),
2328 wxEmptyString, wxITEM_NORMAL ) );
2329 aMenu.Append( new wxMenuItem( &aMenu, ID_SELECT_NET,
2330 wxString::Format( _( "Select Tracks and Vias in %s" ), name ),
2331 wxEmptyString, wxITEM_NORMAL ) );
2332 aMenu.Append( new wxMenuItem( &aMenu, ID_DESELECT_NET,
2333 wxString::Format( _( "Unselect Tracks and Vias in %s" ), name ),
2334 wxEmptyString, wxITEM_NORMAL ) );
2335
2336 aMenu.AppendSeparator();
2337
2338 aMenu.Append( new wxMenuItem( &aMenu, ID_SHOW_ALL_NETS, _( "Show All Netclasses" ),
2339 wxEmptyString, wxITEM_NORMAL ) );
2340 aMenu.Append( new wxMenuItem( &aMenu, ID_HIDE_OTHER_NETS, _( "Hide All Other Netclasses" ),
2341 wxEmptyString, wxITEM_NORMAL ) );
2342
2343 aMenu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetclassContextMenu, this );
2344
2345}
2346
2347
2349{
2350 BOARD* board = m_frame->GetBoard();
2352 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2353
2354 // If the board isn't fully loaded, we can't yet rebuild
2355 if( !board->GetProject() )
2356 return;
2357
2358 m_staticTextNets->SetLabel( _( "Nets" ) );
2359 m_staticTextNetClasses->SetLabel( _( "Net Classes" ) );
2360
2363
2364 std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
2365 const std::set<wxString>& hiddenClasses = m_frame->Prj().GetLocalSettings().m_HiddenNetclasses;
2366
2367 m_netclassOuterSizer->Clear( true );
2368
2369 auto appendNetclass =
2370 [&]( int aId, const std::shared_ptr<NETCLASS>& aClass, bool isDefaultClass = false )
2371 {
2372 wxString name = aClass->GetName();
2373
2374 m_netclassSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>() );
2375 APPEARANCE_SETTING* setting = m_netclassSettings.back().get();
2376 m_netclassSettingsMap[name] = setting;
2377
2378 setting->ctl_panel = new wxPanel( m_netclassScrolledWindow, aId );
2379 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2380 setting->ctl_panel->SetSizer( sizer );
2381 COLOR4D color = netclassColors.count( name ) ? netclassColors.at( name ) :
2382 COLOR4D::UNSPECIFIED;
2383
2384 setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, aId, bgColor,
2385 COLOR4D::UNSPECIFIED, SWATCH_SMALL );
2386 setting->ctl_color->SetToolTip( _( "Left double click or middle click for color "
2387 "change, right click for menu" ) );
2388
2389 setting->ctl_color->Bind( COLOR_SWATCH_CHANGED,
2391
2392 // Default netclass can't have an override color
2393 if( isDefaultClass )
2394 setting->ctl_color->Hide();
2395
2396 setting->ctl_visibility = new BITMAP_TOGGLE(
2397 setting->ctl_panel, aId, KiBitmapBundle( BITMAPS::visibility ),
2398 KiBitmapBundle( BITMAPS::visibility_off ), !hiddenClasses.count( name ) );
2399
2400 wxString tip;
2401 tip.Printf( _( "Show or hide ratsnest for nets in %s" ), name );
2402 setting->ctl_visibility->SetToolTip( tip );
2403
2404 setting->ctl_text = new wxStaticText( setting->ctl_panel, aId, name );
2405 setting->ctl_text->Wrap( -1 );
2406
2407 int flags = wxALIGN_CENTER_VERTICAL;
2408
2409 sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
2410 sizer->AddSpacer( 7 );
2411 sizer->Add( setting->ctl_visibility, 0, flags, 5 );
2412 sizer->AddSpacer( 3 );
2413 sizer->Add( setting->ctl_text, 1, flags, 5 );
2414
2415 m_netclassOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 5 );
2416 m_netclassOuterSizer->AddSpacer( 2 );
2417
2418 setting->ctl_visibility->Bind( TOGGLE_CHANGED,
2420 this );
2421
2422 auto menuHandler =
2423 [&, name, isDefaultClass]( wxMouseEvent& aEvent )
2424 {
2425 wxMenu menu;
2426 buildNetClassMenu( menu, isDefaultClass, name );
2427
2429 PopupMenu( &menu );
2430 };
2431
2432 setting->ctl_panel->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2433 setting->ctl_visibility->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2434 setting->ctl_color->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2435 setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2436 };
2437
2438 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
2439
2440 std::vector<wxString> names;
2441
2442 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
2443 names.emplace_back( name );
2444
2445 std::sort( names.begin(), names.end() );
2446
2447 m_netclassIdMap.clear();
2448
2449 int idx = wxID_HIGHEST;
2450
2451 m_netclassIdMap[idx] = netSettings->m_DefaultNetClass->GetName();
2452 appendNetclass( idx++, netSettings->m_DefaultNetClass, true );
2453
2454 for( const wxString& name : names )
2455 {
2456 m_netclassIdMap[idx] = name;
2457 appendNetclass( idx++, netSettings->m_NetClasses.at( name ) );
2458 }
2459
2460 int hotkey;
2461 wxString msg;
2462
2463 m_paneNetDisplayOptions->SetLabel( _( "Net Display Options" ) );
2464
2466
2467 if( hotkey )
2468 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
2469 else
2470 msg = _( "Net colors:" );
2471
2472 m_txtNetDisplayTitle->SetLabel( msg );
2473 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
2474
2475 m_rbNetColorAll->SetLabel( _( "All" ) );
2476 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
2477
2478 m_rbNetColorRatsnest->SetLabel( _( "Ratsnest" ) );
2479 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
2480
2481 m_rbNetColorOff->SetLabel( _( "None" ) );
2482 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
2483
2485
2486 if( hotkey )
2487 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
2488 else
2489 msg = _( "Ratsnest display:" );
2490
2491 m_txtRatsnestVisibility->SetLabel( msg );
2492 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
2493
2494 m_rbRatsnestAllLayers->SetLabel( _( "All" ) );
2495 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
2496
2497 m_rbRatsnestVisLayers->SetLabel( _( "Visible layers" ) );
2498 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
2499
2500 m_rbRatsnestNone->SetLabel( _( "None" ) );
2501 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
2502
2503 m_netclassOuterSizer->Layout();
2504
2506 m_panelNets->GetSizer()->Layout();
2507}
2508
2509
2511{
2512 m_viewportsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
2514
2515 m_cbLayerPresets->Clear();
2516
2517 // Build the layers preset list.
2518 // By default, the presetAllLayers will be selected
2519 int idx = 0;
2520 int default_idx = 0;
2521
2522 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2523 {
2524 m_cbLayerPresets->Append( wxGetTranslation( pair.first ),
2525 static_cast<void*>( &pair.second ) );
2526
2527 if( pair.first == presetAllLayers.name )
2528 default_idx = idx;
2529
2530 idx++;
2531 }
2532
2533 m_cbLayerPresets->Append( wxT( "---" ) );
2534 m_cbLayerPresets->Append( _( "Save preset..." ) );
2535 m_cbLayerPresets->Append( _( "Delete preset..." ) );
2536
2537 // At least the built-in presets should always be present
2538 wxASSERT( !m_layerPresets.empty() );
2539
2540 // Default preset: all layers
2541 m_cbLayerPresets->SetSelection( default_idx );
2543}
2544
2545
2547{
2548 LSET visibleLayers = getVisibleLayers();
2549 GAL_SET visibleObjects = getVisibleObjects();
2550
2551 auto it = std::find_if( m_layerPresets.begin(), m_layerPresets.end(),
2552 [&]( const std::pair<const wxString, LAYER_PRESET>& aPair )
2553 {
2554 return ( aPair.second.layers == visibleLayers
2555 && aPair.second.renderLayers == visibleObjects );
2556 } );
2557
2558 if( it != m_layerPresets.end() )
2559 {
2560 // Select the right m_cbLayersPresets item.
2561 // but these items are translated if they are predefined items.
2562 bool do_translate = it->second.readOnly;
2563 wxString text = do_translate ? wxGetTranslation( it->first ) : it->first;
2564
2565 m_cbLayerPresets->SetStringSelection( text );
2566 }
2567 else
2568 {
2569 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2570 }
2571
2572 m_currentPreset = static_cast<LAYER_PRESET*>(
2573 m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );
2574}
2575
2576
2578{
2579 // look at m_layerPresets to know if aName is a read only preset, or a user preset.
2580 // Read only presets have translated names in UI, so we have to use
2581 // a translated name in UI selection.
2582 // But for a user preset name we should search for aName (not translated)
2583 wxString ui_label = aName;
2584
2585 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2586 {
2587 if( pair.first != aName )
2588 continue;
2589
2590 if( pair.second.readOnly == true )
2591 ui_label = wxGetTranslation( aName );
2592
2593 break;
2594 }
2595
2596 int idx = m_cbLayerPresets->FindString( ui_label );
2597
2598 if( idx >= 0 && m_cbLayerPresets->GetSelection() != idx )
2599 {
2600 m_cbLayerPresets->SetSelection( idx );
2601 m_currentPreset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( idx ) );
2602 }
2603 else if( idx < 0 )
2604 {
2605 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2606 }
2607}
2608
2609
2610void APPEARANCE_CONTROLS::onLayerPresetChanged( wxCommandEvent& aEvent )
2611{
2612 int count = m_cbLayerPresets->GetCount();
2613 int index = m_cbLayerPresets->GetSelection();
2614
2615 auto resetSelection =
2616 [&]()
2617 {
2618 if( m_currentPreset )
2619 m_cbLayerPresets->SetStringSelection( m_currentPreset->name );
2620 else
2621 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 );
2622 };
2623
2624 if( index == count - 3 )
2625 {
2626 // Separator: reject the selection
2627 resetSelection();
2628 return;
2629 }
2630 else if( index == count - 2 )
2631 {
2632 // Save current state to new preset
2633 wxString name;
2634
2637
2638 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
2639 _( "Save Layer Preset" ), name );
2640
2641 if( dlg.ShowModal() != wxID_OK )
2642 {
2643 resetSelection();
2644 return;
2645 }
2646
2647 name = dlg.GetValue();
2648 bool exists = m_layerPresets.count( name );
2649
2650 if( !exists )
2651 {
2654 }
2655
2656 LAYER_PRESET* preset = &m_layerPresets[name];
2657
2658 if( !exists )
2659 {
2660 index = m_cbLayerPresets->Insert( name, index - 1, static_cast<void*>( preset ) );
2661 preset->flipBoard = m_cbFlipBoard->GetValue();
2662 }
2663 else if( preset->readOnly )
2664 {
2665 wxMessageBox( _( "Default presets cannot be modified.\nPlease use a different name." ),
2666 _( "Error" ), wxOK | wxICON_ERROR, wxGetTopLevelParent( this ) );
2667 resetSelection();
2668 return;
2669 }
2670 else
2671 {
2672 // Ask the user if they want to overwrite the existing preset
2673 if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
2674 {
2675 resetSelection();
2676 return;
2677 }
2678
2679 preset->layers = getVisibleLayers();
2680 preset->renderLayers = getVisibleObjects();
2681 preset->flipBoard = m_cbFlipBoard->GetValue();
2682
2683 index = m_cbLayerPresets->FindString( name );
2684 m_presetMRU.Remove( name );
2685 }
2686
2687 m_currentPreset = preset;
2688 m_cbLayerPresets->SetSelection( index );
2689 m_presetMRU.Insert( name, 0 );
2690
2691 return;
2692 }
2693 else if( index == count - 1 )
2694 {
2695 // Delete a preset
2696 wxArrayString headers;
2697 std::vector<wxArrayString> items;
2698
2699 headers.Add( _( "Presets" ) );
2700
2701 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2702 {
2703 if( !pair.second.readOnly )
2704 {
2705 wxArrayString item;
2706 item.Add( pair.first );
2707 items.emplace_back( item );
2708 }
2709 }
2710
2711 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
2712 dlg.SetListLabel( _( "Select preset:" ) );
2713
2714 if( dlg.ShowModal() == wxID_OK )
2715 {
2716 wxString presetName = dlg.GetTextSelection();
2717 int idx = m_cbLayerPresets->FindString( presetName );
2718
2719 if( idx != wxNOT_FOUND )
2720 {
2721 m_layerPresets.erase( presetName );
2722
2723 m_cbLayerPresets->Delete( idx );
2724 m_currentPreset = nullptr;
2725
2726 m_presetMRU.Remove( presetName );
2727 }
2728 }
2729
2730 resetSelection();
2731 return;
2732 }
2733
2734 // Store the objects visibility settings if the presedt is not a user preset,
2735 // to be reused when selecting a new built-in layer preset, even if a previous
2736 // user preset has changed the object visibility
2738 {
2740 }
2741
2742 LAYER_PRESET* preset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( index ) );
2743 m_currentPreset = preset;
2744
2745 m_lastSelectedUserPreset = ( !preset || preset->readOnly ) ? nullptr : preset;
2746
2747 if( preset )
2748 {
2749 // Change board layers visibility, but do not change objects visibility
2750 LAYER_PRESET curr_layers_choice = *preset;
2751
2752 // For predefined presets that do not manage objects visibility, use
2753 // the objects visibility settings of the last used predefined preset.
2754 if( curr_layers_choice.readOnly )
2755 curr_layers_choice.renderLayers = m_lastBuiltinPreset.renderLayers;
2756
2757 doApplyLayerPreset( curr_layers_choice );
2758 }
2759
2760 if( !m_currentPreset->name.IsEmpty() )
2761 {
2762 m_presetMRU.Remove( m_currentPreset->name );
2763 m_presetMRU.Insert( m_currentPreset->name, 0 );
2764 }
2765
2766 passOnFocus();
2767}
2768
2769
2771{
2772 BOARD* board = m_frame->GetBoard();
2773
2774 setVisibleLayers( aPreset.layers );
2776
2777 // If the preset doesn't have an explicit active layer to restore, we can at least
2778 // force the active layer to be something in the preset's layer set
2779 PCB_LAYER_ID activeLayer = UNSELECTED_LAYER;
2780
2781 if( aPreset.activeLayer != UNSELECTED_LAYER )
2782 activeLayer = aPreset.activeLayer;
2783 else if( aPreset.layers.any() && !aPreset.layers.test( m_frame->GetActiveLayer() ) )
2784 activeLayer = *aPreset.layers.Seq().begin();
2785
2786 LSET boardLayers = board->GetLayerSet();
2787
2788 if( activeLayer != UNSELECTED_LAYER && boardLayers.Contains( activeLayer ) )
2789 m_frame->SetActiveLayer( activeLayer );
2790
2791 if( !m_isFpEditor )
2793
2794 if( aPreset.flipBoard )
2795 {
2796 m_frame->GetCanvas()->GetView()->SetMirror( true, false );
2798 }
2799
2801
2803}
2804
2805
2807{
2808 m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
2810
2811 m_cbViewports->Clear();
2812
2813 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
2814 m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
2815
2816 m_cbViewports->Append( wxT( "---" ) );
2817 m_cbViewports->Append( _( "Save viewport..." ) );
2818 m_cbViewports->Append( _( "Delete viewport..." ) );
2819
2820 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2821 m_lastSelectedViewport = nullptr;
2822}
2823
2824
2826{
2827 int idx = m_cbViewports->FindString( aName );
2828
2829 if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
2830 {
2831 m_cbViewports->SetSelection( idx );
2832 m_lastSelectedViewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( idx ) );
2833 }
2834 else if( idx < 0 )
2835 {
2836 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
2837 m_lastSelectedViewport = nullptr;
2838 }
2839}
2840
2841
2842void APPEARANCE_CONTROLS::onViewportChanged( wxCommandEvent& aEvent )
2843{
2844 int count = m_cbViewports->GetCount();
2845 int index = m_cbViewports->GetSelection();
2846
2847 if( index >= 0 && index < count - 3 )
2848 {
2849 VIEWPORT* viewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( index ) );
2850
2851 wxCHECK( viewport, /* void */ );
2852
2853 doApplyViewport( *viewport );
2854
2855 if( !viewport->name.IsEmpty() )
2856 {
2857 m_viewportMRU.Remove( viewport->name );
2858 m_viewportMRU.Insert( viewport->name, 0 );
2859 }
2860 }
2861 else if( index == count - 2 )
2862 {
2863 // Save current state to new preset
2864 wxString name;
2865
2866 wxTextEntryDialog dlg( wxGetTopLevelParent( this ),
2867 _( "Viewport name:" ), _( "Save Viewport" ), name );
2868
2869 if( dlg.ShowModal() != wxID_OK )
2870 {
2872 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
2873 else
2874 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2875
2876 return;
2877 }
2878
2879 name = dlg.GetValue();
2880 bool exists = m_viewports.count( name );
2881
2882 if( !exists )
2883 {
2885
2886 index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
2887 }
2888 else
2889 {
2891 index = m_cbViewports->FindString( name );
2892 m_viewportMRU.Remove( name );
2893 }
2894
2895 m_cbViewports->SetSelection( index );
2896 m_viewportMRU.Insert( name, 0 );
2897
2898 return;
2899 }
2900 else if( index == count - 1 )
2901 {
2902 // Delete an existing viewport
2903 wxArrayString headers;
2904 std::vector<wxArrayString> items;
2905
2906 headers.Add( _( "Viewports" ) );
2907
2908 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
2909 {
2910 wxArrayString item;
2911 item.Add( pair.first );
2912 items.emplace_back( item );
2913 }
2914
2915 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
2916 dlg.SetListLabel( _( "Select viewport:" ) );
2917
2918 if( dlg.ShowModal() == wxID_OK )
2919 {
2920 wxString viewportName = dlg.GetTextSelection();
2921 int idx = m_cbViewports->FindString( viewportName );
2922
2923 if( idx != wxNOT_FOUND )
2924 {
2925 m_viewports.erase( viewportName );
2926 m_cbViewports->Delete( idx );
2927 m_viewportMRU.Remove( viewportName );
2928 }
2929 }
2930
2932 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
2933 else
2934 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2935
2936 return;
2937 }
2938
2939 passOnFocus();
2940}
2941
2942
2944{
2945 m_frame->GetCanvas()->GetView()->SetViewport( aViewport.rect );
2946 if( m_cbFlipBoard->GetValue() )
2947 {
2948 m_frame->GetCanvas()->GetView()->SetMirror( true, false );
2950 }
2952}
2953
2954
2955void APPEARANCE_CONTROLS::OnColorSwatchChanged( wxCommandEvent& aEvent )
2956{
2957 COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
2958 COLOR4D newColor = swatch->GetSwatchColor();
2959 int layer = swatch->GetId();
2960
2962
2963 cs->SetColor( layer, newColor );
2964 m_frame->GetSettingsManager()->SaveColorSettings( cs, "board" );
2965
2967
2968 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
2969 view->UpdateLayerColor( layer );
2970 view->UpdateLayerColor( GetNetnameLayer( layer ) );
2971
2972 if( IsCopperLayer( layer ) )
2973 view->UpdateLayerColor( ZONE_LAYER_FOR( layer ) );
2974
2975 if( layer == F_Cu )
2977 else if( layer == B_Cu )
2979
2980 // Update the bitmap of the layer box
2982 static_cast<PCB_EDIT_FRAME*>( m_frame )->ReCreateLayerBox( false );
2983
2985
2986 if( layer == LAYER_PCB_BACKGROUND )
2987 m_frame->SetDrawBgColor( newColor );
2988
2989 passOnFocus();
2990}
2991
2992
2993void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
2994{
2996
2997 switch( aLayer )
2998 {
2999 case static_cast<int>( LAYER_TRACKS ): options.m_TrackOpacity = aOpacity; break;
3000 case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
3001 case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
3002 case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
3003 case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_ImageOpacity = aOpacity; break;
3004 default: return;
3005 }
3006
3007 m_frame->SetDisplayOptions( options );
3008 passOnFocus();
3009}
3010
3011
3012void APPEARANCE_CONTROLS::onNetContextMenu( wxCommandEvent& aEvent )
3013{
3014 wxASSERT( m_netsGrid->GetSelectedRows().size() == 1 );
3015
3016 int row = m_netsGrid->GetSelectedRows()[0];
3017 NET_GRID_ENTRY& net = m_netsTable->GetEntry( row );
3018
3019 m_netsGrid->ClearSelection();
3020
3021 switch( aEvent.GetId() )
3022 {
3023 case ID_SET_NET_COLOR:
3024 {
3025 wxGridCellEditor* editor = m_netsGrid->GetCellEditor( row, NET_GRID_TABLE::COL_COLOR );
3026 editor->BeginEdit( row, NET_GRID_TABLE::COL_COLOR, m_netsGrid );
3027 break;
3028 }
3029
3030 case ID_CLEAR_NET_COLOR:
3031 m_netsGrid->SetCellValue( row, NET_GRID_TABLE::COL_COLOR, wxS( "rgba(0,0,0,0)" ) );
3032 break;
3033
3034 case ID_HIGHLIGHT_NET:
3037 break;
3038
3039 case ID_SELECT_NET:
3042 break;
3043
3044 case ID_DESELECT_NET:
3047 break;
3048
3049 case ID_SHOW_ALL_NETS:
3051 break;
3052
3053 case ID_HIDE_OTHER_NETS:
3054 m_netsTable->HideOtherNets( net );
3055 break;
3056
3057 default:
3058 break;
3059 }
3060
3061 passOnFocus();
3062}
3063
3064
3066{
3067 wxString className = netclassNameFromEvent( aEvent );
3068 bool show = aEvent.GetInt();
3069 showNetclass( className, show );
3070 passOnFocus();
3071}
3072
3073
3074void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow )
3075{
3076 for( NETINFO_ITEM* net : m_frame->GetBoard()->GetNetInfo() )
3077 {
3078 if( net->GetNetClass()->GetName() == aClassName )
3079 {
3082 net->GetNetCode() );
3083
3084 int row = m_netsTable->GetRowByNetcode( net->GetNetCode() );
3085
3086 if( row >= 0 )
3088 }
3089 }
3090
3091 PROJECT_LOCAL_SETTINGS& localSettings = m_frame->Prj().GetLocalSettings();
3092
3093 if( !aShow )
3094 localSettings.m_HiddenNetclasses.insert( aClassName );
3095 else
3096 localSettings.m_HiddenNetclasses.erase( aClassName );
3097
3098 m_netsGrid->ForceRefresh();
3099}
3100
3101
3103{
3106
3107 std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
3108
3109 COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
3110 wxString netclassName = netclassNameFromEvent( aEvent );
3111
3112 netclassColors[netclassName] = swatch->GetSwatchColor();
3113
3117}
3118
3119
3121{
3122 COLOR_SWATCH* s = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
3123 int classId = s->GetId();
3124
3125 wxASSERT( m_netclassIdMap.count( classId ) );
3126 return m_netclassIdMap.at( classId );
3127}
3128
3129
3130void APPEARANCE_CONTROLS::onNetColorMode( wxCommandEvent& aEvent )
3131{
3133
3134 if( m_rbNetColorAll->GetValue() )
3135 options.m_NetColorMode = NET_COLOR_MODE::ALL;
3136 else if( m_rbNetColorRatsnest->GetValue() )
3137 options.m_NetColorMode = NET_COLOR_MODE::RATSNEST;
3138 else
3139 options.m_NetColorMode = NET_COLOR_MODE::OFF;
3140
3141 m_frame->SetDisplayOptions( options );
3143 passOnFocus();
3144}
3145
3146
3147void APPEARANCE_CONTROLS::onRatsnestMode( wxCommandEvent& aEvent )
3148{
3150
3151 if( m_rbRatsnestAllLayers->GetValue() )
3152 {
3153 cfg->m_Display.m_ShowGlobalRatsnest = true;
3154 cfg->m_Display.m_RatsnestMode = RATSNEST_MODE::ALL;
3155 }
3156 else if( m_rbRatsnestVisLayers->GetValue() )
3157 {
3158 cfg->m_Display.m_ShowGlobalRatsnest = true;
3159 cfg->m_Display.m_RatsnestMode = RATSNEST_MODE::VISIBLE;
3160 }
3161 else
3162 {
3163 cfg->m_Display.m_ShowGlobalRatsnest = false;
3164 }
3165
3166 if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
3167 {
3168 editframe->SetElementVisibility( LAYER_RATSNEST, cfg->m_Display.m_ShowGlobalRatsnest );
3169 editframe->OnDisplayOptionsChanged();
3170 editframe->GetCanvas()->RedrawRatsnest();
3171 editframe->GetCanvas()->Refresh();
3172 }
3173 passOnFocus();
3174}
3175
3176
3178{
3179 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
3181 static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
3182
3183 BOARD* board = m_frame->GetBoard();
3184 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
3185 APPEARANCE_SETTING* setting = nullptr;
3186
3188
3189 if( it != m_netclassSettingsMap.end() )
3190 setting = it->second;
3191
3192 auto runOnNetsOfClass =
3193 [&]( const wxString& netClassName, std::function<void( NETINFO_ITEM* )> aFunction )
3194 {
3195 for( NETINFO_ITEM* net : board->GetNetInfo() )
3196 {
3197 if( net->GetNetClass()->GetName() == netClassName )
3198 aFunction( net );
3199 }
3200 };
3201
3202 switch( aEvent.GetId() )
3203 {
3204 case ID_SET_NET_COLOR:
3205 if( setting )
3206 {
3207 setting->ctl_color->GetNewSwatchColor();
3208
3209 COLOR4D color = setting->ctl_color->GetSwatchColor();
3210
3211 std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
3212
3213 if( color != COLOR4D::UNSPECIFIED )
3214 netclassColors[m_contextMenuNetclass] = color;
3215 else
3216 netclassColors.erase( m_contextMenuNetclass );
3217
3218 view->UpdateAllLayersColor();
3219 }
3220
3221 break;
3222
3223 case ID_HIGHLIGHT_NET:
3224 if( !m_contextMenuNetclass.IsEmpty() )
3225 {
3226 runOnNetsOfClass( m_contextMenuNetclass,
3227 [&]( NETINFO_ITEM* aItem )
3228 {
3229 static bool first = true;
3230 int code = aItem->GetNetCode();
3231
3232 if( first )
3233 {
3234 board->SetHighLightNet( code );
3235 rs->SetHighlight( true, code );
3236 first = false;
3237 }
3238 else
3239 {
3240 board->SetHighLightNet( code, true );
3241 rs->SetHighlight( true, code, true );
3242 }
3243 } );
3244
3245 view->UpdateAllLayersColor();
3246 board->HighLightON();
3247 }
3248
3249 break;
3250
3251 case ID_SELECT_NET:
3252 case ID_DESELECT_NET:
3253 if( !m_contextMenuNetclass.IsEmpty() )
3254 {
3255 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
3258
3259 runOnNetsOfClass( m_contextMenuNetclass,
3260 [&]( NETINFO_ITEM* aItem )
3261 {
3262 toolMgr->RunAction( action, aItem->GetNetCode() );
3263 } );
3264 }
3265 break;
3266
3267
3268 case ID_SHOW_ALL_NETS:
3270 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3271 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( true );
3272
3273 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
3274 {
3275 showNetclass( name );
3276
3277 if( m_netclassSettingsMap.count( name ) )
3278 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( true );
3279 }
3280
3281 break;
3282
3283 case ID_HIDE_OTHER_NETS:
3284 {
3285 bool showDefault = m_contextMenuNetclass == NETCLASS::Default;
3286 showNetclass( NETCLASS::Default, showDefault );
3287 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3288 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( showDefault );
3289
3290 for( const auto& [ name, netclass ] : netSettings->m_NetClasses )
3291 {
3292 bool show = ( name == m_contextMenuNetclass );
3293
3294 showNetclass( name, show );
3295
3296 if( m_netclassSettingsMap.count( name ) )
3297 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( show );
3298 }
3299
3300 break;
3301 }
3302
3303 default:
3304 break;
3305 }
3306
3309
3310 m_contextMenuNetclass.clear();
3311}
3312
3313
3315{
3316 m_focusOwner->SetFocus();
3317}
3318
3319
3321{
3322 WX_INFOBAR* infobar = m_frame->GetInfoBar();
3323
3324 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Open Preferences" ),
3325 wxEmptyString );
3326
3327 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
3328 [&]( wxHyperlinkEvent& aEvent )
3329 {
3330 m_frame->ShowPreferences( wxEmptyString, wxEmptyString );
3331 } ) );
3332
3333 infobar->RemoveAllButtons();
3334 infobar->AddButton( button );
3335 infobar->AddCloseButton();
3336
3337 infobar->ShowMessageFor( _( "The current color theme is read-only. Create a new theme in "
3338 "Preferences to enable color editing." ),
3339 10000, wxICON_INFORMATION );
3340}
3341
3342
3344{
3345 m_paneLayerDisplayOptions->Refresh();
3346}
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
static std::set< int > s_allowedInFpEditor
These GAL layers are shown in the Objects tab in the footprint editor.
#define RR
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
HIGH_CONTRAST_MODE
Determine how inactive layers should be displayed.
static TOOL_ACTION highContrastModeCycle
Definition: actions.h:111
Class APPEARANCE_CONTROLS_BASE.
wxScrolledWindow * m_netclassScrolledWindow
void OnBoardNetSettingsChanged(BOARD &aBoard) override
void doApplyLayerPreset(const LAYER_PRESET &aPreset)
std::map< PCB_LAYER_ID, APPEARANCE_SETTING * > m_layerSettingsMap
wxStaticText * m_inactiveLayersLabel
std::map< GAL_LAYER_ID, APPEARANCE_SETTING * > m_objectSettingsMap
void ApplyLayerPreset(const wxString &aPresetName)
static LAYER_PRESET m_lastBuiltinPreset
wxRadioButton * m_rbHighContrastNormal
void onObjectVisibilityChanged(GAL_LAYER_ID aLayer, bool isVisible, bool isFinal)
static LAYER_PRESET presetFrontAssembly
void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aItem) override
static LAYER_PRESET presetBackAssembly
void OnNetGridClick(wxGridEvent &event) override
void setVisibleObjects(GAL_SET aObjects)
wxRadioButton * m_rbRatsnestNone
WX_COLLAPSIBLE_PANE * m_paneLayerDisplayOptions
void buildNetClassMenu(wxMenu &aMenu, bool isDefaultClass, const wxString &aName)
void onLayerVisibilityToggled(PCB_LAYER_ID aLayer)
void onLayerPresetChanged(wxCommandEvent &aEvent) override
void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aItem) override
wxRadioButton * m_rbRatsnestVisLayers
wxRadioButton * m_rbNetColorAll
bool doesBoardItemNeedRebuild(BOARD_ITEM *aBoardItem)
void SetUserLayerPresets(std::vector< LAYER_PRESET > &aPresetList)
std::vector< LAYER_PRESET > GetUserLayerPresets() const
Update the current layer presets from those saved in the project file.
static LAYER_PRESET presetInnerCopper
void updateViewportSelection(const wxString &aName)
std::map< wxString, VIEWPORT > m_viewports
void onViewportChanged(wxCommandEvent &aEvent) override
NET_GRID_TABLE * m_netsTable
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_layerSettings
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_objectSettings
void onObjectOpacitySlider(int aLayer, float aOpacity)
wxRadioButton * m_rbRatsnestAllLayers
wxBoxSizer * m_objectsOuterSizer
void setVisibleLayers(LSET aLayers)
LAYER_PRESET * m_lastSelectedUserPreset
wxString m_contextMenuNetclass
The name of the netclass that was right-clicked.
wxRadioButton * m_rbNetColorRatsnest
void onRatsnestMode(wxCommandEvent &aEvent)
wxRadioButton * m_rbNetColorOff
static LAYER_PRESET presetFront
void doApplyViewport(const VIEWPORT &aViewport)
static const APPEARANCE_SETTING s_objectSettings[]
Template for object appearance settings.
void OnNetGridMouseEvent(wxMouseEvent &aEvent)
WX_COLLAPSIBLE_PANE * m_paneNetDisplayOptions
void OnNotebookPageChanged(wxNotebookEvent &event) override
int GetTabIndex() const
Set the current notebook tab.
void onNetclassVisibilityChanged(wxCommandEvent &aEvent)
void OnBoardItemsRemoved(BOARD &aBoard, std::vector< BOARD_ITEM * > &aItems) override
void onNetContextMenu(wxCommandEvent &aEvent)
void OnColorSwatchChanged(wxCommandEvent &aEvent)
void updateLayerPresetSelection(const wxString &aName)
ROW_ICON_PROVIDER * m_iconProvider
std::map< wxString, LAYER_PRESET > m_layerPresets
static LAYER_PRESET presetBack
void RefreshCollapsiblePanes()
Function to force a redraw of the collapsible panes in this control.
static LAYER_PRESET presetNoLayers
void idleFocusHandler(wxIdleEvent &aEvent)
void rightClickHandler(wxMouseEvent &aEvent)
void OnNetGridRightClick(wxGridEvent &event) override
void OnBoardItemsChanged(BOARD &aBoard, std::vector< BOARD_ITEM * > &aItems) override
Update the colors on all the widgets from the new chosen color theme.
wxBoxSizer * m_layersOuterSizer
void UpdateDisplayOptions()
Return a list of the layer presets created by the user.
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_netclassSettings
wxRadioButton * m_rbHighContrastOff
void OnBoardItemsAdded(BOARD &aBoard, std::vector< BOARD_ITEM * > &aItems) override
void OnColorThemeChanged()
Respond to change in OS's DarkMode.
LAYER_PRESET * m_currentPreset
std::map< wxString, APPEARANCE_SETTING * > m_netclassSettingsMap
PCB_BASE_FRAME * m_frame
void OnSetFocus(wxFocusEvent &aEvent) override
static LAYER_PRESET presetAllCopper
void SetUserViewports(std::vector< VIEWPORT > &aPresetList)
wxRadioButton * m_rbHighContrastDim
void OnSize(wxSizeEvent &aEvent) override
wxString netclassNameFromEvent(wxEvent &aEvent)
wxGridCellCoords m_hoveredCell
Grid cell that is being hovered over, for tooltips.
void showNetclass(const wxString &aClassName, bool aShow=true)
wxStaticText * m_txtRatsnestVisibility
void onLayerLeftClick(wxMouseEvent &aEvent)
std::vector< VIEWPORT > GetUserViewports() const
Update the current viewports from those saved in the project file.
void OnLanguageChanged()
Update the panel contents from the application and board models.
std::map< int, wxString > m_netclassIdMap
Stores wxIDs for each netclass for control event mapping.
void OnLayerContextMenu(wxCommandEvent &aEvent)
Return the index of the current tab (0-2).
void onNetColorMode(wxCommandEvent &aEvent)
void OnNetVisibilityChanged(int aNetCode, bool aVisibility)
Notifies the panel when a net has been hidden or shown via the external tool.
void OnDarkModeToggle()
Update the widget when the active board layer is changed.
static LAYER_PRESET presetAllLayers
void onNetclassContextMenu(wxCommandEvent &aEvent)
wxStaticText * m_txtNetDisplayTitle
wxStaticLine * m_layerDisplaySeparator
APPEARANCE_CONTROLS(PCB_BASE_FRAME *aParent, wxWindow *aFocusOwner, bool aFpEditor=false)
void SetObjectVisible(GAL_LAYER_ID aLayer, bool isVisible=true)
void OnNetGridDoubleClick(wxGridEvent &event) override
void SetLayerVisible(int aLayer, bool isVisible)
void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aItem) override
void onNetclassColorChanged(wxCommandEvent &aEvent)
void ApplyViewport(const wxString &aPresetName)
GRID_BITMAP_TOGGLE_RENDERER * m_toggleGridRenderer
void SetBitmap(const wxBitmapBundle &aBmp)
Set the bitmap shown when the button is enabled.
void SetPadding(int aPadding)
Set the amount of padding present on each side of the bitmap.
A checkbox control except with custom bitmaps for the checked and unchecked states.
Definition: bitmap_toggle.h:45
void SetValue(bool aValue)
Read the checkbox state.
std::shared_ptr< NET_SETTINGS > m_NetSettings
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:231
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:832
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:651
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:665
void AddListener(BOARD_LISTENER *aListener)
Add a listener to the board to receive calls whenever something on the board has been modified.
Definition: board.cpp:2291
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition: board.cpp:711
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:2343
int GetCopperLayerCount() const
Definition: board.cpp:627
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:683
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:723
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:538
PROJECT * GetProject() const
Definition: board.h:457
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:768
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2356
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:690
Color settings are a bit different than most of the settings objects in that there can be more than o...
void SetColor(int aLayer, const COLOR4D &aColor)
COLOR4D GetColor(int aLayer) const
COLOR4D GetDefaultColor(int aLayer)
A simple color swatch of the kind used to set layer colors.
Definition: color_swatch.h:57
void GetNewSwatchColor()
Prompt for a new colour, using the colour picker dialog.
KIGFX::COLOR4D GetSwatchColor() const
void SetReadOnlyCallback(std::function< void()> aCallback)
Registers a handler for when the user tries to interact with a read-only swatch.
Definition: color_swatch.h:125
void SetReadOnly(bool aReadOnly=true)
Definition: color_swatch.h:119
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
double GetContentScaleFactor() const override
Get the content scale factor, which may be different from the scale factor on some platforms.
double GetScaleFactor() const override
Get the DPI scale from all known sources in order:
SETTINGS_MANAGER * GetSettingsManager() const
void ShowPreferences(wxString aStartPage, wxString aStartParentPage)
Displays the preferences and settings of all opened editors paged dialog, starting with a particular ...
bool IsType(FRAME_T aType) const
WX_INFOBAR * GetInfoBar()
virtual void SetGridVisibility(bool aVisible)
bool IsGridVisible() const
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
A dialog which shows:
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
void SetListLabel(const wxString &aLabel)
Helper for storing and iterating over GAL_LAYER_IDs.
Definition: layer_ids.h:306
bool Contains(GAL_LAYER_ID aPos)
Definition: layer_ids.h:340
GAL_SET & set()
Definition: layer_ids.h:322
static GAL_SET DefaultVisible()
Definition: lset.cpp:1050
A toggle button renderer for a wxGrid, similar to BITMAP_TOGGLE.
A text renderer that can unescape text for display This is useful where it's desired to keep the unde...
representing a row indicator icon for use in places like the layer widget
void SetIndicatorState(ICON_ID aIconId)
Set the row indicator to the given state.
bool IsReadOnly() const
Definition: json_settings.h:84
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
bool SetFromWxString(const wxString &aColorString)
Set color values by parsing a string using wxColour::Set().
Definition: color4d.cpp:129
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition: pcb_painter.h:76
std::set< int > & GetHiddenNets()
Definition: pcb_painter.h:122
std::map< int, KIGFX::COLOR4D > & GetNetColorMap()
Definition: pcb_painter.h:120
std::map< wxString, KIGFX::COLOR4D > & GetNetclassColorMap()
Definition: pcb_painter.h:118
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
An abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:84
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:534
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:507
void SetViewport(const BOX2D &aViewport)
Set the visible area of the VIEW.
Definition: view.cpp:519
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:758
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:395
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition: view.h:245
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1401
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:737
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:412
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:619
void UpdateAllItemsConditionally(int aUpdateFlags, std::function< bool(VIEW_ITEM *)> aCondition)
Update items in the view according to the given flags and condition.
Definition: view.cpp:1511
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:519
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:573
static LSET AllLayersMask()
Definition: lset.cpp:898
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:418
bool Contains(PCB_LAYER_ID aLayer)
See if the layer set contains a PCB layer.
Definition: layer_ids.h:645
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:177
static LSET FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
Definition: lset.cpp:795
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:823
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:863
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:1005
static LSET BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
Definition: lset.cpp:809
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:985
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:992
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:46
Handle the data for a net.
Definition: netinfo.h:56
int GetNetCode() const
Definition: netinfo.h:108
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:368
void SetValue(int aRow, int aCol, const wxString &aValue) override
void SetValueAsCustom(int aRow, int aCol, const wxString &aTypeName, void *aValue) override
std::vector< NET_GRID_ENTRY > m_nets
void updateNetColor(const NET_GRID_ENTRY &aNet)
NET_GRID_ENTRY & GetEntry(int aRow)
void SetValueAsBool(int aRow, int aCol, bool aValue) override
void * GetValueAsCustom(int aRow, int aCol, const wxString &aTypeName) override
NET_GRID_TABLE(PCB_BASE_FRAME *aFrame, wxColor aBackgroundColor)
void updateNetVisibility(const NET_GRID_ENTRY &aNet)
wxString GetValue(int aRow, int aCol) override
wxGridCellAttr * m_labelAttr
PCB_BASE_FRAME * m_frame
void HideOtherNets(const NET_GRID_ENTRY &aNet)
wxGridCellAttr * m_defaultAttr
bool GetValueAsBool(int aRow, int aCol) override
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind) override
static void * ColorToVoid(COLOR4D &aColor)
int GetRowByNetcode(int aCode) const
wxString GetTypeName(int aRow, int aCol) override
static COLOR4D VoidToColor(void *aColor)
Definition: pad.h:59
DISPLAY_OPTIONS m_Display
AUI_PANELS m_AuiPanels
static TOOL_ACTION listNets
Definition: pcb_actions.h:432
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:543
static TOOL_ACTION hideNetInRatsnest
Definition: pcb_actions.h:550
static TOOL_ACTION showNetInRatsnest
Definition: pcb_actions.h:551
static TOOL_ACTION ratsnestModeCycle
Definition: pcb_actions.h:322
static TOOL_ACTION netColorModeCycle
Definition: pcb_actions.h:321
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
Definition: pcb_actions.h:96
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:377
static TOOL_ACTION deselectNet
Remove all connections belonging to a single net from the active selection.
Definition: pcb_actions.h:99
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual void OnDisplayOptionsChanged()
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual PCB_LAYER_ID GetActiveLayer() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetDrawBgColor(const COLOR4D &aColor) override
BOARD * GetBoard() const
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Updates the current display options from the given options struct.
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
double m_TrackOpacity
Opacity override for all tracks.
double m_ZoneOpacity
Opacity override for filled zone areas.
double m_ImageOpacity
Opacity override for user images.
double m_PadOpacity
Opacity override for SMD pads and PTHs.
double m_ViaOpacity
Opacity override for all types of via.
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
The main frame for Pcbnew.
void ReCreateLayerBox(bool aForceResizeToolbar=true)
Recreate the layer box by clearing the old list and building a new one from the new layer names and c...
The project local settings are things that are attached to a particular project, but also might be pa...
std::set< wxString > m_HiddenNetclasses
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:172
Icon provider for the "standard" row indicators, for example in layer selection lists.
@ OFF
Row "off" or "deselected".
@ ON
Row "on" or "selected".
void SaveColorSettings(COLOR_SETTINGS *aSettings, const std::string &aNamespace="")
Safely saves a COLOR_SETTINGS to disk, preserving any changes outside the given namespace.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Represent a single user action.
Definition: tool_action.h:269
int GetId() const
Return the unique id of the TOOL_ACTION object.
Definition: tool_action.h:324
int GetHotKey() const
Return the hotkey keycode which initiates the action.
Definition: tool_action.h:313
Master controller class:
Definition: tool_manager.h:57
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
A better wxCollapsiblePane that.
void Collapse(bool aCollapse=true)
void SetLabel(const wxString &aLabel) override
bool SetBackgroundColour(const wxColour &aColor) override
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:156
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
Definition: wx_grid.cpp:136
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:301
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION, MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the infobar with the provided message and icon for a specific period of time.
Definition: wx_infobar.cpp:140
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: wx_infobar.cpp:260
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:291
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
Definition: wx_panel.h:39
static const wxSize SWATCH_SIZE_SMALL_DU(8, 6)
@ SWATCH_SMALL
Definition: color_swatch.h:40
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:360
This file is part of the common library.
#define _HKI(x)
#define _(s)
#define VIEWPORT_SWITCH_KEY
#define PRESET_SWITCH_KEY
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
GAL_LAYER_ID ToGalLayer(int aInteger)
Definition: layer_ids.h:285
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
Definition: layer_ids.h:1020
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:879
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition: layer_ids.h:193
@ LAYER_GRID
Definition: layer_ids.h:208
@ GAL_LAYER_ID_START
Definition: layer_ids.h:194
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:242
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
Definition: layer_ids.h:244
@ LAYER_FOOTPRINTS_FR
show footprints on front
Definition: layer_ids.h:211
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
Definition: layer_ids.h:220
@ LAYER_DRAW_BITMAPS
to handle and draw images bitmaps
Definition: layer_ids.h:226
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
Definition: layer_ids.h:214
@ LAYER_DRC_EXCLUSION
layer for drc markers which have been individually excluded
Definition: layer_ids.h:239
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition: layer_ids.h:223
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored)
Definition: layer_ids.h:234
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored)
Definition: layer_ids.h:233
@ LAYER_DRC_WARNING
layer for drc markers with SEVERITY_WARNING
Definition: layer_ids.h:238
@ LAYER_HIDDEN_TEXT
text marked as invisible
Definition: layer_ids.h:203
@ LAYER_TRACKS
Definition: layer_ids.h:215
@ LAYER_RATSNEST
Definition: layer_ids.h:207
@ LAYER_ZONE_START
Virtual layers for stacking zones and tracks on a given copper layer.
Definition: layer_ids.h:256
@ LAYER_FP_TEXT
Definition: layer_ids.h:201
@ LAYER_FOOTPRINTS_BK
show footprints on back
Definition: layer_ids.h:212
@ LAYER_ANCHOR
anchor of items having an anchor point (texts, footprints)
Definition: layer_ids.h:204
@ LAYER_PADS_SMD_BK
smd pads, back layer
Definition: layer_ids.h:206
@ LAYER_PADS_TH
multilayer pads, usually with holes
Definition: layer_ids.h:216
@ LAYER_PADS_SMD_FR
smd pads, front layer
Definition: layer_ids.h:205
@ LAYER_FP_VALUES
show footprints values (when texts are visible)
Definition: layer_ids.h:213
@ LAYER_DRC_ERROR
layer for drc markers with SEVERITY_ERROR
Definition: layer_ids.h:219
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:196
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ User_8
Definition: layer_ids.h:131
@ F_CrtYd
Definition: layer_ids.h:118
@ B_Adhes
Definition: layer_ids.h:98
@ Edge_Cuts
Definition: layer_ids.h:114
@ Dwgs_User
Definition: layer_ids.h:110
@ F_Paste
Definition: layer_ids.h:102
@ Cmts_User
Definition: layer_ids.h:111
@ User_6
Definition: layer_ids.h:129
@ User_7
Definition: layer_ids.h:130
@ F_Adhes
Definition: layer_ids.h:99
@ B_Mask
Definition: layer_ids.h:107
@ B_Cu
Definition: layer_ids.h:96
@ User_5
Definition: layer_ids.h:128
@ Eco1_User
Definition: layer_ids.h:112
@ F_Mask
Definition: layer_ids.h:108
@ B_Paste
Definition: layer_ids.h:101
@ User_9
Definition: layer_ids.h:132
@ UNSELECTED_LAYER
Definition: layer_ids.h:62
@ F_Fab
Definition: layer_ids.h:121
@ Margin
Definition: layer_ids.h:115
@ F_SilkS
Definition: layer_ids.h:105
@ B_CrtYd
Definition: layer_ids.h:117
@ Eco2_User
Definition: layer_ids.h:113
@ User_3
Definition: layer_ids.h:126
@ User_1
Definition: layer_ids.h:124
@ B_SilkS
Definition: layer_ids.h:104
@ User_4
Definition: layer_ids.h:127
@ User_2
Definition: layer_ids.h:125
@ F_Cu
Definition: layer_ids.h:65
@ B_Fab
Definition: layer_ids.h:120
#define ZONE_LAYER_FOR(boardLayer)
Definition: layer_ids.h:275
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
Definition: layer_ids.h:271
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:1022
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition: definitions.h:49
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:151
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: ui_common.cpp:369
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
Container for an appearance setting (can control a single board layer, or GAL layer,...
A saved set of layers that are visible.
GAL_SET renderLayers
Render layers (e.g. object types) that are visible.
wxString name
A name for this layer set.
bool flipBoard
True if the flip board is enabled.
LSET layers
Board layers that are visible.
bool readOnly
True if this is a read-only (built-in) preset.
PCB_LAYER_ID activeLayer
Optional layer to set active when this preset is loaded.
COLOR4D color
int code
wxString name
bool visible
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:107