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