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