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