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
586
587 // Grid visibility is loaded and set to the GAL before we are constructed
589
590 Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::OnLayerContextMenu, this,
592
593 m_frame->Bind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS::OnLanguageChanged, this );
594}
595
596
598{
599 m_frame->Unbind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS::OnLanguageChanged, this );
600
601 delete m_iconProvider;
602}
603
604
606{
607 int hotkey;
608 wxString msg;
609 wxFont infoFont = KIUI::GetInfoFont( this );
610
611 // Create layer display options
613 _( "Layer Display Options" ) );
615 m_paneLayerDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
616
617 wxWindow* layerDisplayPane = m_paneLayerDisplayOptions->GetPane();
618
619 wxBoxSizer* layerDisplayOptionsSizer;
620 layerDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
621
623
624 if( hotkey )
625 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
626 else
627 msg = _( "Inactive layers:" );
628
629 m_inactiveLayersLabel = new wxStaticText( layerDisplayPane, wxID_ANY, msg );
630 m_inactiveLayersLabel->SetFont( infoFont );
631 m_inactiveLayersLabel->Wrap( -1 );
632 layerDisplayOptionsSizer->Add( m_inactiveLayersLabel, 0, wxEXPAND | wxBOTTOM, 2 );
633
634 wxBoxSizer* contrastModeSizer;
635 contrastModeSizer = new wxBoxSizer( wxHORIZONTAL );
636
637 m_rbHighContrastNormal = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Normal" ),
638 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
639 m_rbHighContrastNormal->SetFont( infoFont );
640 m_rbHighContrastNormal->SetValue( true );
641 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
642
643 contrastModeSizer->Add( m_rbHighContrastNormal, 0, wxRIGHT, 5 );
644 contrastModeSizer->AddStretchSpacer();
645
646 m_rbHighContrastDim = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Dim" ) );
647 m_rbHighContrastDim->SetFont( infoFont );
648 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
649
650 contrastModeSizer->Add( m_rbHighContrastDim, 0, wxRIGHT, 5 );
651 contrastModeSizer->AddStretchSpacer();
652
653 m_rbHighContrastOff = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Hide" ) );
654 m_rbHighContrastOff->SetFont( infoFont );
655 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
656
657 contrastModeSizer->Add( m_rbHighContrastOff, 0, 0, 5 );
658 contrastModeSizer->AddStretchSpacer();
659
660 layerDisplayOptionsSizer->Add( contrastModeSizer, 0, wxEXPAND, 5 );
661
662 m_layerDisplaySeparator = new wxStaticLine( layerDisplayPane, wxID_ANY, wxDefaultPosition,
663 wxDefaultSize, wxLI_HORIZONTAL );
664 layerDisplayOptionsSizer->Add( m_layerDisplaySeparator, 0, wxEXPAND | wxBOTTOM, 3 );
665
666 m_cbFlipBoard = new wxCheckBox( layerDisplayPane, wxID_ANY, _( "Flip board view" ) );
667 m_cbFlipBoard->SetFont( infoFont );
668 layerDisplayOptionsSizer->Add( m_cbFlipBoard, 0, wxTOP | wxBOTTOM, 5 );
669
670 layerDisplayPane->SetSizer( layerDisplayOptionsSizer );
671 layerDisplayPane->Layout();
672 layerDisplayOptionsSizer->Fit( layerDisplayPane );
673
674 m_panelLayersSizer->Add( m_paneLayerDisplayOptions, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5 );
675
676 m_paneLayerDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
677 [&]( wxCommandEvent& aEvent )
678 {
679 Freeze();
680 m_panelLayers->Fit();
681 m_sizerOuter->Layout();
682 Thaw();
683 } );
684
685 // Create net display options
686
688 _( "Net Display Options" ) );
690 m_paneNetDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
691
692 wxWindow* netDisplayPane = m_paneNetDisplayOptions->GetPane();
693 wxBoxSizer* netDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
694
696
698
699 if( hotkey )
700 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
701 else
702 msg = _( "Net colors:" );
703
704 m_txtNetDisplayTitle = new wxStaticText( netDisplayPane, wxID_ANY, msg );
705 m_txtNetDisplayTitle->SetFont( infoFont );
706 m_txtNetDisplayTitle->Wrap( -1 );
707 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
708
709 netDisplayOptionsSizer->Add( m_txtNetDisplayTitle, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
710
711 wxBoxSizer* netColorSizer = new wxBoxSizer( wxHORIZONTAL );
712
713 m_rbNetColorAll = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ), wxDefaultPosition,
714 wxDefaultSize, wxRB_GROUP );
715 m_rbNetColorAll->SetFont( infoFont );
716 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
717
718 netColorSizer->Add( m_rbNetColorAll, 0, wxRIGHT, 5 );
719 netColorSizer->AddStretchSpacer();
720
721 m_rbNetColorRatsnest = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Ratsnest" ) );
722 m_rbNetColorRatsnest->SetFont( infoFont );
723 m_rbNetColorRatsnest->SetValue( true );
724 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
725
726 netColorSizer->Add( m_rbNetColorRatsnest, 0, wxRIGHT, 5 );
727 netColorSizer->AddStretchSpacer();
728
729 m_rbNetColorOff = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
730 m_rbNetColorOff->SetFont( infoFont );
731 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
732
733 netColorSizer->Add( m_rbNetColorOff, 0, 0, 5 );
734
735 netDisplayOptionsSizer->Add( netColorSizer, 0, wxEXPAND | wxBOTTOM, 5 );
736
738
740
741 if( hotkey )
742 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
743 else
744 msg = _( "Ratsnest display:" );
745
746 m_txtRatsnestVisibility = new wxStaticText( netDisplayPane, wxID_ANY, msg );
747 m_txtRatsnestVisibility->SetFont( infoFont );
748 m_txtRatsnestVisibility->Wrap( -1 );
749 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
750
751 netDisplayOptionsSizer->Add( m_txtRatsnestVisibility, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
752
753 wxBoxSizer* ratsnestDisplayModeSizer = new wxBoxSizer( wxHORIZONTAL );
754
755 m_rbRatsnestAllLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ),
756 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
757 m_rbRatsnestAllLayers->SetFont( infoFont );
758 m_rbRatsnestAllLayers->SetValue( true );
759 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
760
761 ratsnestDisplayModeSizer->Add( m_rbRatsnestAllLayers, 0, wxRIGHT, 5 );
762 ratsnestDisplayModeSizer->AddStretchSpacer();
763
764 m_rbRatsnestVisLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Visible layers" ) );
765 m_rbRatsnestVisLayers->SetFont( infoFont );
766 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
767
768 ratsnestDisplayModeSizer->Add( m_rbRatsnestVisLayers, 0, wxRIGHT, 5 );
769 ratsnestDisplayModeSizer->AddStretchSpacer();
770
771 m_rbRatsnestNone = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
772 m_rbRatsnestNone->SetFont( infoFont );
773 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
774
775 ratsnestDisplayModeSizer->Add( m_rbRatsnestNone, 0, 0, 5 );
776
777 netDisplayOptionsSizer->Add( ratsnestDisplayModeSizer, 0, wxEXPAND | wxBOTTOM, 5 );
778
780
781 netDisplayPane->SetSizer( netDisplayOptionsSizer );
782 netDisplayPane->Layout();
783 netDisplayOptionsSizer->Fit( netDisplayPane );
784
785 m_netsTabOuterSizer->Add( m_paneNetDisplayOptions, 0, wxEXPAND | wxTOP, 5 );
786
787 m_paneNetDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
788 [&]( wxCommandEvent& aEvent )
789 {
790 Freeze();
792 m_sizerOuter->Layout();
793 passOnFocus();
794 Thaw();
795 } );
796
797 m_rbNetColorAll->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
798 m_rbNetColorOff->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
799 m_rbNetColorRatsnest->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
800
801 m_rbRatsnestAllLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
802 m_rbRatsnestVisLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
803 m_rbRatsnestNone->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
804}
805
806
808{
809 DPI_SCALING_COMMON dpi( nullptr, m_frame );
810 wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
811 return size;
812}
813
814
816{
818}
819
820
822{
824}
825
826
827void APPEARANCE_CONTROLS::OnNotebookPageChanged( wxNotebookEvent& aEvent )
828{
829 // Work around wxMac issue where the notebook pages are blank
830#ifdef __WXMAC__
831 int page = aEvent.GetSelection();
832
833 if( page >= 0 )
834 m_notebook->ChangeSelection( static_cast<unsigned>( page ) );
835#endif
836
837#ifndef __WXMSW__
838 // Because wxWidgets is broken and will send click events to children of the collapsible
839 // panes even if they are collapsed without this
840 Freeze();
841 m_panelLayers->Fit();
843 m_sizerOuter->Layout();
844 Thaw();
845#endif
846
847 Bind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
848}
849
850
851void APPEARANCE_CONTROLS::idleFocusHandler( wxIdleEvent& aEvent )
852{
853 passOnFocus();
854 Unbind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
855}
856
857
858void APPEARANCE_CONTROLS::OnSetFocus( wxFocusEvent& aEvent )
859{
860#ifdef __WXMSW__
861 // In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
862 // focus and give it back to the parent in the button event handler.
863 if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
864 {
865 wxCommandEvent evt( wxEVT_BUTTON );
866 wxPostEvent( btn, evt );
867 }
868#endif
869
870 passOnFocus();
871 aEvent.Skip();
872}
873
874
875void APPEARANCE_CONTROLS::OnSize( wxSizeEvent& aEvent )
876{
877 aEvent.Skip();
878}
879
880
881void APPEARANCE_CONTROLS::OnNetGridClick( wxGridEvent& event )
882{
883 int row = event.GetRow();
884 int col = event.GetCol();
885
886 switch( col )
887 {
889 m_netsTable->SetValueAsBool( row, col, !m_netsTable->GetValueAsBool( row, col ) );
890 m_netsGrid->ForceRefresh();
891 break;
892
893 default:
894 break;
895 }
896}
897
898
900{
901 int row = event.GetRow();
902 int col = event.GetCol();
903
904 switch( col )
905 {
907 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
908 break;
909
910 default:
911 break;
912 }
913}
914
915
917{
918 m_netsGrid->SelectRow( event.GetRow() );
919
920 wxString netName = UnescapeString( m_netsGrid->GetCellValue( event.GetRow(),
922 wxMenu menu;
923
924 menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, _( "Set Net Color" ), wxEmptyString,
925 wxITEM_NORMAL ) );
926 menu.Append( new wxMenuItem( &menu, ID_CLEAR_NET_COLOR, _( "Clear Net Color" ), wxEmptyString,
927 wxITEM_NORMAL ) );
928
929 menu.AppendSeparator();
930
931 menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
932 wxString::Format( _( "Highlight %s" ), netName ), wxEmptyString,
933 wxITEM_NORMAL ) );
934 menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
935 wxString::Format( _( "Select Tracks and Vias in %s" ), netName ),
936 wxEmptyString, wxITEM_NORMAL ) );
937 menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
938 wxString::Format( _( "Unselect Tracks and Vias in %s" ), netName ),
939 wxEmptyString, wxITEM_NORMAL ) );
940
941 menu.AppendSeparator();
942
943 menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, _( "Show All Nets" ), wxEmptyString,
944 wxITEM_NORMAL ) );
945 menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, _( "Hide All Other Nets" ),
946 wxEmptyString, wxITEM_NORMAL ) );
947
948 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetContextMenu, this );
949
950 PopupMenu( &menu );
951}
952
953
955{
956 wxPoint pos = m_netsGrid->CalcUnscrolledPosition( aEvent.GetPosition() );
957 wxGridCellCoords cell = m_netsGrid->XYToCell( pos );
958
959 if( aEvent.Moving() || aEvent.Entering() )
960 {
961 aEvent.Skip();
962
963 if( !cell )
964 {
965 m_netsGrid->GetGridWindow()->UnsetToolTip();
966 return;
967 }
968
969 if( cell == m_hoveredCell )
970 return;
971
972 m_hoveredCell = cell;
973
974 NET_GRID_ENTRY& net = m_netsTable->GetEntry( cell.GetRow() );
975
976 wxString name = net.name;
977 wxString showOrHide = net.visible ? _( "Click to hide ratsnest for %s" )
978 : _( "Click to show ratsnest for %s" );
979 wxString tip;
980
981 if( cell.GetCol() == NET_GRID_TABLE::COL_VISIBILITY )
982 {
983 tip.Printf( showOrHide, name );
984 }
985 else if( cell.GetCol() == NET_GRID_TABLE::COL_COLOR )
986 {
987 tip = _( "Double click (or middle click) to change color; "
988 "right click for more actions" );
989 }
990
991 m_netsGrid->GetGridWindow()->SetToolTip( tip );
992 }
993 else if( aEvent.Leaving() )
994 {
995 m_netsGrid->UnsetToolTip();
996 aEvent.Skip();
997 }
998 else if( aEvent.Dragging() )
999 {
1000 // not allowed
1001 CallAfter( [this]()
1002 {
1003 m_netsGrid->ClearSelection();
1004 } );
1005 }
1006 else if( aEvent.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !!cell )
1007 {
1008 int row = cell.GetRow();
1009 int col = cell.GetCol();
1010
1011 if(col == NET_GRID_TABLE::COL_COLOR )
1012 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
1013
1014 aEvent.Skip();
1015 }
1016 else
1017 {
1018 aEvent.Skip();
1019 }
1020}
1021
1022
1023void APPEARANCE_CONTROLS::OnLanguageChanged( wxCommandEvent& aEvent )
1024{
1025 m_notebook->SetPageText( 0, _( "Layers" ) );
1026 m_notebook->SetPageText( 1, _( "Objects" ) );
1027
1028 if( m_notebook->GetPageCount() >= 3 )
1029 m_notebook->SetPageText( 2, _( "Nets" ) );
1030
1031 Freeze();
1032 rebuildLayers();
1037 rebuildNets();
1038
1042
1044
1045 Thaw();
1046 Refresh();
1047
1048 aEvent.Skip();
1049}
1050
1051
1053{
1054 Freeze();
1055 rebuildLayers();
1059 rebuildNets();
1063
1065
1067
1068 if( m_board )
1069 m_board->AddListener( this );
1070
1071 Thaw();
1072 Refresh();
1073}
1074
1075
1077{
1079}
1080
1081
1082void APPEARANCE_CONTROLS::OnNetVisibilityChanged( int aNetCode, bool aVisibility )
1083{
1085 return;
1086
1087 int row = m_netsTable->GetRowByNetcode( aNetCode );
1088
1089 if( row >= 0 )
1090 {
1092 m_netsGrid->ForceRefresh();
1093 }
1094}
1095
1096
1098{
1099 return aBoardItem->Type() == PCB_NETINFO_T;
1100}
1101
1102
1103bool APPEARANCE_CONTROLS::doesBoardItemNeedRebuild( std::vector<BOARD_ITEM*>& aBoardItems )
1104{
1105 bool rebuild = std::any_of( aBoardItems.begin(), aBoardItems.end(),
1106 []( const BOARD_ITEM* a )
1107 {
1108 return a->Type() == PCB_NETINFO_T;
1109 } );
1110
1111 return rebuild;
1112}
1113
1114
1116{
1117 if( doesBoardItemNeedRebuild( aItem ) )
1119}
1120
1121
1122void APPEARANCE_CONTROLS::OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1123{
1124 if( doesBoardItemNeedRebuild( aItems ) )
1126}
1127
1128
1130{
1131 if( doesBoardItemNeedRebuild( aItem ) )
1133}
1134
1135
1136void APPEARANCE_CONTROLS::OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1137{
1138 if( doesBoardItemNeedRebuild( aItems ) )
1140}
1141
1142
1144{
1145 if( doesBoardItemNeedRebuild( aItem ) )
1147}
1148
1149
1150void APPEARANCE_CONTROLS::OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1151{
1152 if( doesBoardItemNeedRebuild( aItems ) )
1154}
1155
1156
1158 std::vector<BOARD_ITEM*>& aAddedItems,
1159 std::vector<BOARD_ITEM*>& aRemovedItems,
1160 std::vector<BOARD_ITEM*>& aDeletedItems )
1161{
1162 if( doesBoardItemNeedRebuild( aAddedItems ) || doesBoardItemNeedRebuild( aRemovedItems )
1163 || doesBoardItemNeedRebuild( aDeletedItems ) )
1164 {
1166 }
1167}
1168
1169
1171{
1172 Freeze();
1173 rebuildNets();
1174 Thaw();
1175}
1176
1177
1179{
1182}
1183
1184
1186{
1187 // This is essentially a list of hacks because DarkMode isn't yet implemented inside
1188 // wxWidgets.
1189 //
1190 // The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
1191 // overriding some virtual method or responding to some wxWidgets event so that the parent
1192 // doesn't have to know what it contains. But, that's not where we are, so... :shrug:
1193
1194 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
1195
1196 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1197
1198 for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
1199 {
1200 if( child && child->GetWindow() )
1201 child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
1202 }
1203
1204 // Easier than calling OnDarkModeToggle on all the GRID_CELL_COLOR_RENDERERs:
1205 m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
1208
1209 for( const std::pair<const wxString, APPEARANCE_SETTING*>& pair : m_netclassSettingsMap )
1210 {
1211 if( pair.second->ctl_color )
1212 pair.second->ctl_color->OnDarkModeToggle();
1213 }
1214
1215 OnLayerChanged(); // Update selected highlighting
1216}
1217
1218
1220{
1221 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1222 {
1223 setting->ctl_panel->SetBackgroundColour( m_layerPanelColour );
1224 setting->ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
1225 }
1226
1227 wxChar r = m_layerPanelColour.Red();
1228 wxChar g = m_layerPanelColour.Green();
1229 wxChar b = m_layerPanelColour.Blue();
1230
1231 if( r < 240 || g < 240 || b < 240 )
1232 {
1233 r = wxChar( std::min( (int) r + 15, 255 ) );
1234 g = wxChar( std::min( (int) g + 15, 255 ) );
1235 b = wxChar( std::min( (int) b + 15, 255 ) );
1236 }
1237 else
1238 {
1239 r = wxChar( std::max( (int) r - 15, 0 ) );
1240 g = wxChar( std::max( (int) g - 15, 0 ) );
1241 b = wxChar( std::max( (int) b - 15, 0 ) );
1242 }
1243
1244 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1245
1246 if( !m_layerSettingsMap.count( current ) )
1247 {
1248 wxASSERT( m_layerSettingsMap.count( F_Cu ) );
1249 current = F_Cu;
1250 }
1251
1252 APPEARANCE_SETTING* newSetting = m_layerSettingsMap[ current ];
1253
1254 newSetting->ctl_panel->SetBackgroundColour( wxColour( r, g, b ) );
1256
1257 Refresh();
1258}
1259
1260
1261void APPEARANCE_CONTROLS::SetLayerVisible( int aLayer, bool isVisible )
1262{
1263 LSET visible = getVisibleLayers();
1264 PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
1265
1266 if( visible.test( layer ) == isVisible )
1267 return;
1268
1269 visible.set( layer, isVisible );
1270 setVisibleLayers( visible );
1271
1272 m_frame->GetCanvas()->GetView()->SetLayerVisible( layer, isVisible );
1273
1275}
1276
1277
1279{
1280 if( m_objectSettingsMap.count( aLayer ) )
1281 {
1282 APPEARANCE_SETTING* setting = m_objectSettingsMap.at( aLayer );
1283
1284 if( setting->can_control_visibility )
1285 setting->ctl_visibility->SetValue( isVisible );
1286 }
1287
1288 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
1289
1291
1292 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1294}
1295
1296
1298{
1299 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1300
1301 if( m_isFpEditor )
1302 {
1303 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1304 view->SetLayerVisible( layer, aLayers.Contains( layer ) );
1305 }
1306 else
1307 {
1308 m_frame->GetBoard()->SetVisibleLayers( aLayers );
1309
1310 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as
1311 // they won't be found in the view layer's itemset for repainting.
1313 []( KIGFX::VIEW_ITEM* aItem ) -> bool
1314 {
1315 // Items rendered to composite layers (such as LAYER_PAD_TH) must be redrawn
1316 // whether they're optionally flashed or not (as the layer being hidden/shown
1317 // might be the last layer the item is visible on).
1318 return dynamic_cast<PCB_VIA*>( aItem ) || dynamic_cast<PAD*>( aItem );
1319 } );
1320
1322 }
1323}
1324
1325
1327{
1328 if( m_isFpEditor )
1329 {
1330 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1331
1332 for( size_t i = 0; i < GAL_LAYER_INDEX( LAYER_ZONE_START ); i++ )
1333 view->SetLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ), aLayers.test( i ) );
1334 }
1335 else
1336 {
1337 // Ratsnest visibility is controlled by the ratsnest option, and not by the preset
1340
1341 m_frame->GetBoard()->SetVisibleElements( aLayers );
1342
1344 }
1345}
1346
1347
1349{
1350 if( m_isFpEditor )
1351 {
1352 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1353 LSET set;
1354
1355 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1356 set.set( layer, view->IsLayerVisible( layer ) );
1357
1358 return set;
1359 }
1360 else
1361 {
1362 return m_frame->GetBoard()->GetVisibleLayers();
1363 }
1364}
1365
1366
1368{
1369 if( m_isFpEditor )
1370 {
1371 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1372 GAL_SET set;
1373 set.reset();
1374
1375 for( size_t i = 0; i < set.size(); i++ )
1376 set.set( i, view->IsLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ) ) );
1377
1378 return set;
1379 }
1380 else
1381 {
1382 return m_frame->GetBoard()->GetVisibleElements();
1383 }
1384}
1385
1386
1388{
1389 const PCB_DISPLAY_OPTIONS& options = m_frame->GetDisplayOptions();
1390
1391 switch( options.m_ContrastModeDisplay )
1392 {
1393 case HIGH_CONTRAST_MODE::NORMAL: m_rbHighContrastNormal->SetValue( true ); break;
1394 case HIGH_CONTRAST_MODE::DIMMED: m_rbHighContrastDim->SetValue( true ); break;
1395 case HIGH_CONTRAST_MODE::HIDDEN: m_rbHighContrastOff->SetValue( true ); break;
1396 }
1397
1398 switch( options.m_NetColorMode )
1399 {
1400 case NET_COLOR_MODE::ALL: m_rbNetColorAll->SetValue( true ); break;
1401 case NET_COLOR_MODE::RATSNEST: m_rbNetColorRatsnest->SetValue( true ); break;
1402 case NET_COLOR_MODE::OFF: m_rbNetColorOff->SetValue( true ); break;
1403 }
1404
1405 m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
1406
1407 if( !m_isFpEditor )
1408 {
1410
1412 m_rbRatsnestNone->SetValue( true );
1413 else if( cfg->m_Display.m_RatsnestMode == RATSNEST_MODE::ALL )
1414 m_rbRatsnestAllLayers->SetValue( true );
1415 else
1416 m_rbRatsnestVisLayers->SetValue( true );
1417
1418 wxASSERT( m_objectSettingsMap.count( LAYER_RATSNEST ) );
1421 }
1422}
1423
1424
1425std::vector<LAYER_PRESET> APPEARANCE_CONTROLS::GetUserLayerPresets() const
1426{
1427 std::vector<LAYER_PRESET> ret;
1428
1429 for( const std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
1430 {
1431 if( !pair.second.readOnly )
1432 ret.emplace_back( pair.second );
1433 }
1434
1435 return ret;
1436}
1437
1438
1439void APPEARANCE_CONTROLS::SetUserLayerPresets( std::vector<LAYER_PRESET>& aPresetList )
1440{
1441 // Reset to defaults
1443
1444 for( const LAYER_PRESET& preset : aPresetList )
1445 {
1446 if( m_layerPresets.count( preset.name ) )
1447 continue;
1448
1449 m_layerPresets[preset.name] = preset;
1450
1451 m_presetMRU.Add( preset.name );
1452 }
1453
1455}
1456
1457
1459{
1460 m_layerPresets.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}
1471
1472
1473void APPEARANCE_CONTROLS::ApplyLayerPreset( const wxString& aPresetName )
1474{
1475 updateLayerPresetSelection( aPresetName );
1476
1477 wxCommandEvent dummy;
1479}
1480
1481
1483{
1484 if( m_layerPresets.count( aPreset.name ) )
1486 else
1487 m_currentPreset = nullptr;
1488
1490 : nullptr;
1491
1493 doApplyLayerPreset( aPreset );
1494}
1495
1496
1497std::vector<VIEWPORT> APPEARANCE_CONTROLS::GetUserViewports() const
1498{
1499 std::vector<VIEWPORT> ret;
1500
1501 for( const std::pair<const wxString, VIEWPORT>& pair : m_viewports )
1502 ret.emplace_back( pair.second );
1503
1504 return ret;
1505}
1506
1507
1508void APPEARANCE_CONTROLS::SetUserViewports( std::vector<VIEWPORT>& aViewportList )
1509{
1510 m_viewports.clear();
1511
1512 for( const VIEWPORT& viewport : aViewportList )
1513 {
1514 if( m_viewports.count( viewport.name ) )
1515 continue;
1516
1517 m_viewports[viewport.name] = viewport;
1518
1519 m_viewportMRU.Add( viewport.name );
1520 }
1521
1523}
1524
1525
1526void APPEARANCE_CONTROLS::ApplyViewport( const wxString& aViewportName )
1527{
1528 updateViewportSelection( aViewportName );
1529
1530 wxCommandEvent dummy;
1532}
1533
1534
1536{
1537 updateViewportSelection( aViewport.name );
1538 doApplyViewport( aViewport );
1539}
1540
1541
1543{
1544 BOARD* board = m_frame->GetBoard();
1545 LSET enabled = board->GetEnabledLayers();
1546 LSET visible = getVisibleLayers();
1547
1549 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
1550 bool readOnly = theme->IsReadOnly();
1551
1552#ifdef __WXMAC__
1553 wxSizerItem* m_windowLayersSizerItem = m_panelLayersSizer->GetItem( m_windowLayers );
1554 m_windowLayersSizerItem->SetFlag( m_windowLayersSizerItem->GetFlag() & ~wxTOP );
1555#endif
1556
1557 auto appendLayer =
1558 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1559 {
1560 int layer = aSetting->id;
1561
1562 wxPanel* panel = new wxPanel( m_windowLayers, layer );
1563 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
1564 panel->SetSizer( sizer );
1565
1566 panel->SetBackgroundColour( m_layerPanelColour );
1567
1568 aSetting->visible = visible[layer];
1569
1570 // TODO(JE) consider restyling this indicator
1571 INDICATOR_ICON* indicator = new INDICATOR_ICON( panel, *m_iconProvider,
1573 layer );
1574
1575 COLOR_SWATCH* swatch = new COLOR_SWATCH( panel, COLOR4D::UNSPECIFIED, layer,
1576 bgColor, theme->GetColor( layer ),
1577 SWATCH_SMALL );
1578 swatch->SetToolTip( _( "Double click or middle click for color change, "
1579 "right click for menu" ) );
1580
1581 BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE(
1582 panel, layer, KiBitmapBundle( BITMAPS::visibility ),
1583 KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
1584 btn_visible->SetToolTip( _( "Show or hide this layer" ) );
1585
1586 wxStaticText* label = new wxStaticText( panel, layer, aSetting->label );
1587 label->Wrap( -1 );
1588 label->SetToolTip( aSetting->tooltip );
1589
1590 sizer->AddSpacer( 1 );
1591 sizer->Add( indicator, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1592 sizer->AddSpacer( 5 );
1593 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1594 sizer->AddSpacer( 6 );
1595 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1596 sizer->AddSpacer( 5 );
1597 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1598
1599 m_layersOuterSizer->Add( panel, 0, wxEXPAND, 0 );
1600
1601 aSetting->ctl_panel = panel;
1602 aSetting->ctl_indicator = indicator;
1603 aSetting->ctl_visibility = btn_visible;
1604 aSetting->ctl_color = swatch;
1605 aSetting->ctl_text = label;
1606
1607 panel->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1608 indicator->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1609 swatch->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1610 label->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1611
1612 btn_visible->Bind( TOGGLE_CHANGED,
1613 [&]( wxCommandEvent& aEvent )
1614 {
1615 wxObject* btn = aEvent.GetEventObject();
1616 int layerId = static_cast<wxWindow*>( btn )->GetId();
1617
1618 onLayerVisibilityToggled( static_cast<PCB_LAYER_ID>( layerId ) );
1619 } );
1620
1621 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
1622 this );
1624 this ) );
1625 swatch->SetReadOnly( readOnly );
1626
1627 panel->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1628 indicator->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1629 swatch->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1630 btn_visible->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1631 label->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1632 };
1633
1634 auto updateLayer =
1635 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1636 {
1637 int layer = aSetting->id;
1638 aSetting->visible = visible[layer];
1639 aSetting->ctl_panel->Show();
1640 aSetting->ctl_panel->SetId( layer );
1641 aSetting->ctl_indicator->SetWindowID( layer );
1642 aSetting->ctl_color->SetWindowID( layer );
1643 aSetting->ctl_color->SetSwatchColor( theme->GetColor( layer ), false );
1644 aSetting->ctl_visibility->SetWindowID( layer );
1645 aSetting->ctl_text->SetLabelText( aSetting->label );
1646 aSetting->ctl_text->SetId( layer );
1647 aSetting->ctl_text->SetToolTip( aSetting->tooltip );
1648 };
1649
1650 // technical layers are shown in this order:
1651 // Because they are static, wxGetTranslation must be explicitly
1652 // called for tooltips.
1653 static const struct {
1654 PCB_LAYER_ID layerId;
1655 wxString tooltip;
1656 } non_cu_seq[] = {
1657 { F_Adhes, _HKI( "Adhesive on board's front" ) },
1658 { B_Adhes, _HKI( "Adhesive on board's back" ) },
1659 { F_Paste, _HKI( "Solder paste on board's front" ) },
1660 { B_Paste, _HKI( "Solder paste on board's back" ) },
1661 { F_SilkS, _HKI( "Silkscreen on board's front" ) },
1662 { B_SilkS, _HKI( "Silkscreen on board's back" ) },
1663 { F_Mask, _HKI( "Solder mask on board's front" ) },
1664 { B_Mask, _HKI( "Solder mask on board's back" ) },
1665 { Dwgs_User, _HKI( "Explanatory drawings" ) },
1666 { Cmts_User, _HKI( "Explanatory comments" ) },
1667 { Eco1_User, _HKI( "User defined meaning" ) },
1668 { Eco2_User, _HKI( "User defined meaning" ) },
1669 { Edge_Cuts, _HKI( "Board's perimeter definition" ) },
1670 { Margin, _HKI( "Board's edge setback outline" ) },
1671 { F_CrtYd, _HKI( "Footprint courtyards on board's front" ) },
1672 { B_CrtYd, _HKI( "Footprint courtyards on board's back" ) },
1673 { F_Fab, _HKI( "Footprint assembly on board's front" ) },
1674 { B_Fab, _HKI( "Footprint assembly on board's back" ) },
1675 { User_1, _HKI( "User defined layer 1" ) },
1676 { User_2, _HKI( "User defined layer 2" ) },
1677 { User_3, _HKI( "User defined layer 3" ) },
1678 { User_4, _HKI( "User defined layer 4" ) },
1679 { User_5, _HKI( "User defined layer 5" ) },
1680 { User_6, _HKI( "User defined layer 6" ) },
1681 { User_7, _HKI( "User defined layer 7" ) },
1682 { User_8, _HKI( "User defined layer 8" ) },
1683 { User_9, _HKI( "User defined layer 9" ) },
1684 };
1685
1686 // There is a spacer added to the end of the list that we need to remove and re-add
1687 // after possibly adding additional layers
1688 if( m_layersOuterSizer->GetItemCount() > 0 )
1689 {
1690 m_layersOuterSizer->Detach( m_layersOuterSizer->GetItemCount() - 1 );
1691 }
1692 // Otherwise, this is the first time we are updating the control, so we need to attach
1693 // the handler
1694 else
1695 {
1696 // Add right click handling to show the context menu when clicking to the free area in
1697 // m_windowLayers (below the layer items)
1698 m_windowLayers->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1699 }
1700
1701 std::size_t total_layers = enabled.CuStack().size();
1702
1703 for( const auto& entry : non_cu_seq )
1704 {
1705 if( enabled[entry.layerId] )
1706 total_layers++;
1707 }
1708
1709 // Adds layers to the panel until we have enough to hold our total count
1710 while( total_layers > m_layerSettings.size() )
1711 m_layerSettings.push_back( std::make_unique<APPEARANCE_SETTING>() );
1712
1713 // We never delete layers from the panel, only hide them. This saves us
1714 // having to recreate the (possibly) later with minimal overhead
1715 for( std::size_t ii = total_layers; ii < m_layerSettings.size(); ++ii )
1716 {
1717 if( m_layerSettings[ii]->ctl_panel )
1718 m_layerSettings[ii]->ctl_panel->Show( false );
1719 }
1720
1721 auto layer_it = m_layerSettings.begin();
1722
1723 // show all coppers first, with front on top, back on bottom, then technical layers
1724 for( PCB_LAYER_ID layer : enabled.CuStack() )
1725 {
1726 wxString dsc;
1727
1728 switch( layer )
1729 {
1730 case F_Cu: dsc = _( "Front copper layer" ); break;
1731 case B_Cu: dsc = _( "Back copper layer" ); break;
1732 default: dsc = _( "Inner copper layer" ); break;
1733 }
1734
1735 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1736
1737 setting->label = board->GetLayerName( layer );
1738 setting->id = layer;
1739 setting->tooltip = dsc;
1740
1741 if( setting->ctl_panel == nullptr )
1742 appendLayer( setting );
1743 else
1744 updateLayer( setting );
1745
1746 m_layerSettingsMap[layer] = setting.get();
1747
1749 {
1750 setting->ctl_text->Disable();
1751 setting->ctl_color->SetToolTip( wxEmptyString );
1752 }
1753
1754 ++layer_it;
1755 }
1756
1757 for( const auto& entry : non_cu_seq )
1758 {
1759 PCB_LAYER_ID layer = entry.layerId;
1760
1761 if( !enabled[layer] )
1762 continue;
1763
1764 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1765
1766 setting->label = board->GetLayerName( layer );
1767 setting->id = layer;
1768 // Because non_cu_seq is created static, we must explicitly call wxGetTranslation for
1769 // texts which are internationalized
1770 setting->tooltip = wxGetTranslation( entry.tooltip );
1771
1772 if( setting->ctl_panel == nullptr )
1773 appendLayer( setting );
1774 else
1775 updateLayer( setting );
1776
1777 m_layerSettingsMap[layer] = setting.get();
1778
1780 {
1781 setting->ctl_text->Disable();
1782 setting->ctl_color->SetToolTip( wxEmptyString );
1783 }
1784
1785 ++layer_it;
1786 }
1787
1788 m_layersOuterSizer->AddSpacer( 10 );
1789 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1790 m_windowLayers->Layout();
1791
1792 m_paneLayerDisplayOptions->SetLabel( _( "Layer Display Options" ) );
1793
1795 wxString msg;
1796
1797 if( hotkey )
1798 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
1799 else
1800 msg = _( "Inactive layers:" );
1801
1802 m_inactiveLayersLabel->SetLabel( msg );
1803
1804 m_rbHighContrastNormal->SetLabel( _( "Normal" ) );
1805 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
1806
1807 m_rbHighContrastDim->SetLabel( _( "Dim" ) );
1808 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
1809
1810 m_rbHighContrastOff->SetLabel( _( "Hide" ) );
1811 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
1812
1813 m_cbFlipBoard->SetLabel( _( "Flip board view" ) );
1814}
1815
1816
1818{
1819 delete m_layerContextMenu;
1820 m_layerContextMenu = new wxMenu;
1821
1822 KIUI::AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_COPPER_LAYERS, _( "Show All Copper Layers" ),
1823 KiBitmap( BITMAPS::show_all_copper_layers ) );
1824 KIUI::AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_COPPER_LAYERS, _( "Hide All Copper Layers" ),
1825 KiBitmap( BITMAPS::show_no_copper_layers ) );
1826
1827 m_layerContextMenu->AppendSeparator();
1828
1830 _( "Hide All Layers But Active" ), KiBitmap( BITMAPS::select_w_layer ) );
1831
1832 m_layerContextMenu->AppendSeparator();
1833
1835 _( "Show All Non Copper Layers" ),
1836 KiBitmap( BITMAPS::show_no_copper_layers ) );
1837
1839 _( "Hide All Non Copper Layers" ),
1840 KiBitmap( BITMAPS::show_all_copper_layers ) );
1841
1842 m_layerContextMenu->AppendSeparator();
1843
1845 KiBitmap( BITMAPS::show_all_layers ) );
1846
1848 KiBitmap( BITMAPS::show_no_layers ) );
1849
1850 m_layerContextMenu->AppendSeparator();
1851
1853 _( "Show Only Front Assembly Layers" ),
1854 KiBitmap( BITMAPS::show_front_assembly_layers ) );
1855
1856 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT, _( "Show Only Front Layers" ),
1857 KiBitmap( BITMAPS::show_all_front_layers ) );
1858
1859 // Only show the internal layer option if internal layers are enabled
1860 if( m_frame->GetBoard()->GetCopperLayerCount() > 2 )
1861 {
1863 _( "Show Only Inner Layers" ),
1864 KiBitmap( BITMAPS::show_all_copper_layers ) );
1865 }
1866
1867 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_BACK, _( "Show Only Back Layers" ),
1868 KiBitmap( BITMAPS::show_all_back_layers ) );
1869
1871 _( "Show Only Back Assembly Layers" ),
1872 KiBitmap( BITMAPS::show_back_assembly_layers ) );
1873}
1874
1875
1876void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent )
1877{
1878 BOARD* board = m_frame->GetBoard();
1879 LSET visible = getVisibleLayers();
1880
1881 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1882
1883 // The new preset. We keep the visibility state of objects:
1884 LAYER_PRESET preset;
1886
1887 switch( aEvent.GetId() )
1888 {
1890 preset.layers = presetNoLayers.layers;
1891 ApplyLayerPreset( preset );
1892 return;
1893
1895 preset.layers = presetAllLayers.layers;
1896 ApplyLayerPreset( preset );
1897 return;
1898
1900 visible |= presetAllCopper.layers;
1901 setVisibleLayers( visible );
1902 break;
1903
1905 preset.layers = presetNoLayers.layers | LSET( { current } );
1906 ApplyLayerPreset( preset );
1907 break;
1908
1910 visible &= ~presetAllCopper.layers;
1911
1912 if( !visible.test( current ) && visible.count() > 0 )
1913 m_frame->SetActiveLayer( *visible.Seq().begin() );
1914
1915 setVisibleLayers( visible );
1916 break;
1917
1919 visible &= presetAllCopper.layers;
1920
1921 if( !visible.test( current ) && visible.count() > 0 )
1922 m_frame->SetActiveLayer( *visible.Seq().begin() );
1923
1924 setVisibleLayers( visible );
1925 break;
1926
1928 visible |= ~presetAllCopper.layers;
1929
1930 setVisibleLayers( visible );
1931 break;
1932
1935 ApplyLayerPreset( preset );
1936 return;
1937
1938 case ID_PRESET_FRONT:
1939 preset.layers = presetFront.layers;
1940 ApplyLayerPreset( preset );
1941 return;
1942
1945 ApplyLayerPreset( preset );
1946 return;
1947
1948 case ID_PRESET_BACK:
1949 preset.layers = presetBack.layers;
1950 ApplyLayerPreset( preset );
1951 return;
1952
1955 ApplyLayerPreset( preset );
1956 return;
1957 }
1958
1961
1962 if( !m_isFpEditor )
1964
1966}
1967
1968
1970{
1971 return m_notebook->GetSelection();
1972}
1973
1974
1976{
1977 size_t max = m_notebook->GetPageCount();
1978
1979 if( aTab >= 0 && static_cast<size_t>( aTab ) < max )
1980 m_notebook->SetSelection( aTab );
1981}
1982
1983
1985{
1987 bool readOnly = theme->IsReadOnly();
1988 LSET visible = getVisibleLayers();
1989 GAL_SET objects = getVisibleObjects();
1990
1991 Freeze();
1992
1993 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1994 {
1995 int layer = setting->id;
1996
1997 if( setting->ctl_visibility )
1998 setting->ctl_visibility->SetValue( visible[layer] );
1999
2000 if( setting->ctl_color )
2001 {
2002 const COLOR4D& color = theme->GetColor( layer );
2003 setting->ctl_color->SetSwatchColor( color, false );
2004 setting->ctl_color->SetReadOnly( readOnly );
2005 }
2006 }
2007
2008 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2009 {
2010 GAL_LAYER_ID layer = static_cast<GAL_LAYER_ID>( setting->id );
2011
2012 if( setting->ctl_visibility )
2013 setting->ctl_visibility->SetValue( objects.Contains( layer ) );
2014
2015 if( setting->ctl_color )
2016 {
2017 const COLOR4D& color = theme->GetColor( layer );
2018 setting->ctl_color->SetSwatchColor( color, false );
2019 setting->ctl_color->SetReadOnly( readOnly );
2020 }
2021 }
2022
2023 // Update indicators and panel background colors
2025
2026 Thaw();
2027
2028 m_windowLayers->Refresh();
2029}
2030
2031
2032void APPEARANCE_CONTROLS::onLayerLeftClick( wxMouseEvent& aEvent )
2033{
2034 wxWindow* eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() );
2035
2036 PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() );
2037
2039 return;
2040
2041 m_frame->SetActiveLayer( layer );
2042 passOnFocus();
2043}
2044
2045
2046void APPEARANCE_CONTROLS::rightClickHandler( wxMouseEvent& aEvent )
2047{
2048 wxASSERT( m_layerContextMenu );
2049 PopupMenu( m_layerContextMenu );
2050 passOnFocus();
2051};
2052
2053
2055{
2056 LSET visibleLayers = getVisibleLayers();
2057
2058 visibleLayers.set( aLayer, !visibleLayers.test( aLayer ) );
2059 setVisibleLayers( visibleLayers );
2060 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, visibleLayers.test( aLayer ) );
2061
2064}
2065
2066
2068 bool isFinal )
2069{
2070 // Special-case controls
2071 switch( aLayer )
2072 {
2073 case LAYER_RATSNEST:
2074 {
2075 // don't touch the layers. ratsnest is enabled on per-item basis.
2077 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, true );
2078
2080 {
2082 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
2085 }
2086
2087 break;
2088 }
2089
2090 case LAYER_GRID:
2091 m_frame->SetGridVisibility( isVisible );
2094 break;
2095
2096 case LAYER_FP_TEXT:
2097 // Because Footprint Text is a meta-control that also can disable values/references,
2098 // drag them along here so that the user is less likely to be confused.
2099 if( isFinal )
2100 {
2101 // Should only trigger when you actually click the Footprint Text button
2102 // Otherwise it goes into infinite recursive loop with the following case section
2104 onObjectVisibilityChanged( LAYER_FP_VALUES, isVisible, false );
2105 m_objectSettingsMap[LAYER_FP_REFERENCES]->ctl_visibility->SetValue( isVisible );
2106 m_objectSettingsMap[LAYER_FP_VALUES]->ctl_visibility->SetValue( isVisible );
2107 }
2108 break;
2109
2111 case LAYER_FP_VALUES:
2112 // In case that user changes Footprint Value/References when the Footprint Text
2113 // meta-control is disabled, we should put it back on.
2114 if( isVisible )
2115 {
2116 onObjectVisibilityChanged( LAYER_FP_TEXT, isVisible, false );
2117 m_objectSettingsMap[LAYER_FP_TEXT]->ctl_visibility->SetValue( isVisible );
2118 }
2119 break;
2120
2121 default:
2122 break;
2123 }
2124
2125 GAL_SET visible = getVisibleObjects();
2126
2127 if( visible.Contains( aLayer ) != isVisible )
2128 {
2129 visible.set( aLayer, isVisible );
2130 setVisibleObjects( visible );
2131 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
2133 }
2134
2135 if( isFinal )
2136 {
2138 passOnFocus();
2139 }
2140}
2141
2142
2144{
2146 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2147 GAL_SET visible = getVisibleObjects();
2148 int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
2149 int labelWidth = 0;
2150
2151 int btnWidth =
2152 KiBitmapBundle( BITMAPS::visibility ).GetPreferredLogicalSizeFor( m_windowObjects ).x;
2153
2154 m_objectSettings.clear();
2155 m_objectsOuterSizer->Clear( true );
2156 m_objectsOuterSizer->AddSpacer( 5 );
2157
2158 auto appendObject =
2159 [&]( const std::unique_ptr<APPEARANCE_SETTING>& aSetting )
2160 {
2161 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2162 int layer = aSetting->id;
2163
2164 aSetting->visible = visible.Contains( ToGalLayer( layer ) );
2165 COLOR4D color = theme->GetColor( layer );
2166 COLOR4D defColor = theme->GetDefaultColor( layer );
2167
2168 if( color != COLOR4D::UNSPECIFIED )
2169 {
2170 COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer,
2171 bgColor, defColor, SWATCH_SMALL );
2172 swatch->SetToolTip( _( "Left double click or middle click for color change, "
2173 "right click for menu" ) );
2174
2175 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
2176 aSetting->ctl_color = swatch;
2177
2178 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
2179 this );
2180
2182 this ) );
2183 }
2184 else
2185 {
2186 sizer->AddSpacer( swatchWidth );
2187 }
2188
2189 BITMAP_TOGGLE* btn_visible = nullptr;
2190 wxString tip;
2191
2192 if( aSetting->can_control_visibility )
2193 {
2194 btn_visible = new BITMAP_TOGGLE(
2195 m_windowObjects, layer, KiBitmapBundle( BITMAPS::visibility ),
2196 KiBitmapBundle( BITMAPS::visibility_off ), aSetting->visible );
2197
2198 tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
2199 btn_visible->SetToolTip( tip );
2200
2201 aSetting->ctl_visibility = btn_visible;
2202
2203 btn_visible->Bind( TOGGLE_CHANGED,
2204 [&]( wxCommandEvent& aEvent )
2205 {
2206 int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
2207 bool isVisible = aEvent.GetInt();
2208 onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
2209 } );
2210 }
2211
2212 sizer->AddSpacer( 5 );
2213
2214 wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label );
2215 label->Wrap( -1 );
2216 label->SetToolTip( aSetting->tooltip );
2217
2218 if( aSetting->can_control_opacity )
2219 {
2220 label->SetMinSize( wxSize( labelWidth, -1 ) );
2221#ifdef __WXMAC__
2222 if( btn_visible )
2223 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2224 else
2225 sizer->AddSpacer( btnWidth );
2226
2227 sizer->AddSpacer( 5 );
2228 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2229#else
2230 if( btn_visible )
2231 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2232 else
2233 sizer->AddSpacer( btnWidth );
2234
2235 sizer->AddSpacer( 5 );
2236 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2237#endif
2238
2239 wxSlider* slider = new wxSlider( m_windowObjects, wxID_ANY, 100, 0, 100,
2240 wxDefaultPosition, wxDefaultSize,
2241 wxSL_HORIZONTAL );
2242#ifdef __WXMAC__
2243 slider->SetMinSize( wxSize( 80, 16 ) );
2244#else
2245 slider->SetMinSize( wxSize( 80, -1 ) );
2246#endif
2247
2248 tip.Printf( _( "Set opacity of %s" ), aSetting->label.Lower() );
2249 slider->SetToolTip( tip );
2250
2251 sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
2252 aSetting->ctl_opacity = slider;
2253
2254 auto opacitySliderHandler =
2255 [this, layer]( wxCommandEvent& aEvent )
2256 {
2257 wxSlider* ctrl = static_cast<wxSlider*>( aEvent.GetEventObject() );
2258 int value = ctrl->GetValue();
2259 onObjectOpacitySlider( layer, value / 100.0f );
2260 };
2261
2262 slider->Bind( wxEVT_SCROLL_CHANGED, opacitySliderHandler );
2263 slider->Bind( wxEVT_SCROLL_THUMBTRACK, opacitySliderHandler );
2264 slider->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
2265 }
2266 else
2267 {
2268 if( btn_visible )
2269 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2270 else
2271 sizer->AddSpacer( btnWidth );
2272
2273 sizer->AddSpacer( 5 );
2274 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2275 }
2276
2277 aSetting->ctl_text = label;
2278 m_objectsOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
2279
2280 if( !aSetting->can_control_opacity )
2281 m_objectsOuterSizer->AddSpacer( 2 );
2282 };
2283
2284 for( const APPEARANCE_SETTING& s_setting : s_objectSettings )
2285 {
2286 if( m_isFpEditor && !s_allowedInFpEditor.count( s_setting.id ) )
2287 continue;
2288
2289 m_objectSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>( s_setting ) );
2290
2291 std::unique_ptr<APPEARANCE_SETTING>& setting = m_objectSettings.back();
2292
2293 // Because s_render_rows is created static, we must explicitly call wxGetTranslation
2294 // for texts which are internationalized (tool tips and item names)
2295 setting->tooltip = wxGetTranslation( s_setting.tooltip );
2296 setting->label = wxGetTranslation( s_setting.label );
2297
2298 if( setting->can_control_opacity )
2299 {
2300 int width = m_windowObjects->GetTextExtent( setting->label ).x + 5;
2301 labelWidth = std::max( labelWidth, width );
2302 }
2303
2304 if( !s_setting.spacer )
2305 m_objectSettingsMap[ToGalLayer( setting->id )] = setting.get();
2306 }
2307
2308 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2309 {
2310 if( setting->spacer )
2311 m_objectsOuterSizer->AddSpacer( m_pointSize / 2 );
2312 else
2313 appendObject( setting );
2314 }
2315
2316 m_objectsOuterSizer->Layout();
2317}
2318
2319
2321{
2322 GAL_SET visible = getVisibleObjects();
2323
2325
2326 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2327 {
2328 if( setting->spacer )
2329 continue;
2330
2331 GAL_LAYER_ID layer = ToGalLayer( setting->id );
2332
2333 if( setting->ctl_visibility )
2334 setting->ctl_visibility->SetValue( visible.Contains( layer ) );
2335
2336 if( setting->ctl_color )
2337 {
2338 COLOR4D color = m_frame->GetColorSettings()->GetColor( setting->id );
2339 setting->ctl_color->SetSwatchColor( color, false );
2340 }
2341 }
2342
2343 wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
2348 && m_objectSettingsMap.count( LAYER_SHAPES ) );
2349
2350 m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
2351 m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
2352 m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
2353 m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
2354 m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_ImageOpacity * 100 );
2355 m_objectSettingsMap[LAYER_SHAPES]->ctl_opacity->SetValue( opts.m_FilledShapeOpacity * 100 );
2356}
2357
2358
2359void APPEARANCE_CONTROLS::buildNetClassMenu( wxMenu& aMenu, bool isDefaultClass,
2360 const wxString& aName )
2361{
2362 BOARD* board = m_frame->GetBoard();
2363 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
2364
2365 if( !isDefaultClass)
2366 {
2367 aMenu.Append( new wxMenuItem( &aMenu, ID_SET_NET_COLOR, _( "Set Netclass Color" ),
2368 wxEmptyString, wxITEM_NORMAL ) );
2369
2370 wxMenuItem* schematicColor =
2371 new wxMenuItem( &aMenu, ID_USE_SCHEMATIC_NET_COLOR, _( "Use Color from Schematic" ),
2372 wxEmptyString, wxITEM_NORMAL );
2373 std::shared_ptr<NETCLASS> nc = netSettings->GetNetClassByName( aName );
2374 const KIGFX::COLOR4D ncColor = nc->GetSchematicColor();
2375 aMenu.Append( schematicColor );
2376
2377 if( ncColor == KIGFX::COLOR4D::UNSPECIFIED )
2378 schematicColor->Enable( false );
2379
2380 aMenu.Append( new wxMenuItem( &aMenu, ID_CLEAR_NET_COLOR, _( "Clear Netclass Color" ),
2381 wxEmptyString, wxITEM_NORMAL ) );
2382 aMenu.AppendSeparator();
2383 }
2384
2385 wxString name = UnescapeString( aName );
2386
2387 aMenu.Append( new wxMenuItem( &aMenu, ID_HIGHLIGHT_NET,
2388 wxString::Format( _( "Highlight Nets in %s" ), name ),
2389 wxEmptyString, wxITEM_NORMAL ) );
2390 aMenu.Append( new wxMenuItem( &aMenu, ID_SELECT_NET,
2391 wxString::Format( _( "Select Tracks and Vias in %s" ), name ),
2392 wxEmptyString, wxITEM_NORMAL ) );
2393 aMenu.Append( new wxMenuItem( &aMenu, ID_DESELECT_NET,
2394 wxString::Format( _( "Unselect Tracks and Vias in %s" ), name ),
2395 wxEmptyString, wxITEM_NORMAL ) );
2396
2397 aMenu.AppendSeparator();
2398
2399 aMenu.Append( new wxMenuItem( &aMenu, ID_SHOW_ALL_NETS, _( "Show All Netclasses" ),
2400 wxEmptyString, wxITEM_NORMAL ) );
2401 aMenu.Append( new wxMenuItem( &aMenu, ID_HIDE_OTHER_NETS, _( "Hide All Other Netclasses" ),
2402 wxEmptyString, wxITEM_NORMAL ) );
2403
2404 aMenu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetclassContextMenu, this );
2405
2406}
2407
2408
2410{
2411 BOARD* board = m_frame->GetBoard();
2413 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2414
2415 // If the board isn't fully loaded, we can't yet rebuild
2416 if( !board->GetProject() )
2417 return;
2418
2419 m_staticTextNets->SetLabel( _( "Nets" ) );
2420 m_staticTextNetClasses->SetLabel( _( "Net Classes" ) );
2421
2422 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
2423
2424 const std::set<wxString>& hiddenClasses = m_frame->Prj().GetLocalSettings().m_HiddenNetclasses;
2425
2426 m_netclassOuterSizer->Clear( true );
2427
2428 auto appendNetclass =
2429 [&]( int aId, const std::shared_ptr<NETCLASS>& aClass, bool isDefaultClass = false )
2430 {
2431 wxString name = aClass->GetName();
2432
2433 m_netclassSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>() );
2434 APPEARANCE_SETTING* setting = m_netclassSettings.back().get();
2435 m_netclassSettingsMap[name] = setting;
2436
2437 setting->ctl_panel = new wxPanel( m_netclassScrolledWindow, aId );
2438 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2439 setting->ctl_panel->SetSizer( sizer );
2440
2441 COLOR4D color = netSettings->HasNetclass( name )
2442 ? netSettings->GetNetClassByName( name )->GetPcbColor()
2443 : COLOR4D::UNSPECIFIED;
2444
2445 setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, aId, bgColor,
2446 COLOR4D::UNSPECIFIED, SWATCH_SMALL );
2447 setting->ctl_color->SetToolTip( _( "Left double click or middle click for color "
2448 "change, right click for menu" ) );
2449
2450 setting->ctl_color->Bind( COLOR_SWATCH_CHANGED,
2452
2453 // Default netclass can't have an override color
2454 if( isDefaultClass )
2455 setting->ctl_color->Hide();
2456
2457 setting->ctl_visibility = new BITMAP_TOGGLE(
2458 setting->ctl_panel, aId, KiBitmapBundle( BITMAPS::visibility ),
2459 KiBitmapBundle( BITMAPS::visibility_off ), !hiddenClasses.count( name ) );
2460
2461 wxString tip;
2462 tip.Printf( _( "Show or hide ratsnest for nets in %s" ), name );
2463 setting->ctl_visibility->SetToolTip( tip );
2464
2465 setting->ctl_text = new wxStaticText( setting->ctl_panel, aId, name );
2466 setting->ctl_text->Wrap( -1 );
2467
2468 int flags = wxALIGN_CENTER_VERTICAL;
2469
2470 sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
2471 sizer->AddSpacer( 7 );
2472 sizer->Add( setting->ctl_visibility, 0, flags, 5 );
2473 sizer->AddSpacer( 3 );
2474 sizer->Add( setting->ctl_text, 1, flags, 5 );
2475
2476 m_netclassOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 5 );
2477 m_netclassOuterSizer->AddSpacer( 2 );
2478
2479 setting->ctl_visibility->Bind( TOGGLE_CHANGED,
2481 this );
2482
2483 auto menuHandler =
2484 [&, name, isDefaultClass]( wxMouseEvent& aEvent )
2485 {
2486 wxMenu menu;
2487 buildNetClassMenu( menu, isDefaultClass, name );
2488
2490 PopupMenu( &menu );
2491 };
2492
2493 setting->ctl_panel->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2494 setting->ctl_visibility->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2495 setting->ctl_color->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2496 setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2497 };
2498
2499 std::vector<wxString> names;
2500
2501 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
2502 names.emplace_back( name );
2503
2504 std::sort( names.begin(), names.end() );
2505
2506 m_netclassIdMap.clear();
2507
2508 int idx = wxID_HIGHEST;
2509
2510 m_netclassIdMap[idx] = netSettings->GetDefaultNetclass()->GetName();
2511 appendNetclass( idx++, netSettings->GetDefaultNetclass(), true );
2512
2513 for( const wxString& name : names )
2514 {
2515 m_netclassIdMap[idx] = name;
2516 appendNetclass( idx++, netSettings->GetNetclasses().at( name ) );
2517 }
2518
2519 int hotkey;
2520 wxString msg;
2521
2522 m_paneNetDisplayOptions->SetLabel( _( "Net Display Options" ) );
2523
2525
2526 if( hotkey )
2527 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
2528 else
2529 msg = _( "Net colors:" );
2530
2531 m_txtNetDisplayTitle->SetLabel( msg );
2532 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
2533
2534 m_rbNetColorAll->SetLabel( _( "All" ) );
2535 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
2536
2537 m_rbNetColorRatsnest->SetLabel( _( "Ratsnest" ) );
2538 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
2539
2540 m_rbNetColorOff->SetLabel( _( "None" ) );
2541 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
2542
2544
2545 if( hotkey )
2546 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
2547 else
2548 msg = _( "Ratsnest display:" );
2549
2550 m_txtRatsnestVisibility->SetLabel( msg );
2551 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
2552
2553 m_rbRatsnestAllLayers->SetLabel( _( "All" ) );
2554 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
2555
2556 m_rbRatsnestVisLayers->SetLabel( _( "Visible layers" ) );
2557 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
2558
2559 m_rbRatsnestNone->SetLabel( _( "None" ) );
2560 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
2561
2562 m_netclassOuterSizer->Layout();
2563
2565 m_panelNets->GetSizer()->Layout();
2566}
2567
2568
2570{
2571 m_viewportsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
2573
2574 m_cbLayerPresets->Clear();
2575 m_presetMRU.clear();
2576
2577 // Build the layers preset list.
2578 // By default, the presetAllLayers will be selected
2579 int idx = 0;
2580 int default_idx = 0;
2581
2582 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2583 {
2584 const wxString translatedName = wxGetTranslation( pair.first );
2585 m_cbLayerPresets->Append( wxGetTranslation( translatedName ),
2586 static_cast<void*>( &pair.second ) );
2587 m_presetMRU.push_back( translatedName );
2588
2589 if( pair.first == presetAllLayers.name )
2590 default_idx = idx;
2591
2592 idx++;
2593 }
2594
2595 m_cbLayerPresets->Append( wxT( "---" ) );
2596 m_cbLayerPresets->Append( _( "Save preset..." ) );
2597 m_cbLayerPresets->Append( _( "Delete preset..." ) );
2598
2599 // At least the built-in presets should always be present
2600 wxASSERT( !m_layerPresets.empty() );
2601
2602 // Default preset: all layers
2603 m_cbLayerPresets->SetSelection( default_idx );
2605}
2606
2607
2609{
2610 LSET visibleLayers = getVisibleLayers();
2611 GAL_SET visibleObjects = getVisibleObjects();
2612 bool flipBoard = m_cbFlipBoard->GetValue();
2613
2614 auto it = std::find_if( m_layerPresets.begin(), m_layerPresets.end(),
2615 [&]( const std::pair<const wxString, LAYER_PRESET>& aPair )
2616 {
2617 return ( aPair.second.layers == visibleLayers
2618 && aPair.second.renderLayers == visibleObjects
2619 && aPair.second.flipBoard == flipBoard );
2620 } );
2621
2622 if( it != m_layerPresets.end() )
2623 {
2624 // Select the right m_cbLayersPresets item.
2625 // but these items are translated if they are predefined items.
2626 bool do_translate = it->second.readOnly;
2627 wxString text = do_translate ? wxGetTranslation( it->first ) : it->first;
2628
2629 m_cbLayerPresets->SetStringSelection( text );
2630 }
2631 else
2632 {
2633 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2634 }
2635
2636 m_currentPreset = static_cast<LAYER_PRESET*>(
2637 m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );
2638}
2639
2640
2642{
2643 // look at m_layerPresets to know if aName is a read only preset, or a user preset.
2644 // Read only presets have translated names in UI, so we have to use
2645 // a translated name in UI selection.
2646 // But for a user preset name we should search for aName (not translated)
2647 wxString ui_label = aName;
2648
2649 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2650 {
2651 if( pair.first != aName )
2652 continue;
2653
2654 if( pair.second.readOnly == true )
2655 ui_label = wxGetTranslation( aName );
2656
2657 break;
2658 }
2659
2660 int idx = m_cbLayerPresets->FindString( ui_label );
2661
2662 if( idx >= 0 && m_cbLayerPresets->GetSelection() != idx )
2663 {
2664 m_cbLayerPresets->SetSelection( idx );
2665 m_currentPreset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( idx ) );
2666 }
2667 else if( idx < 0 )
2668 {
2669 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2670 }
2671}
2672
2673
2674void APPEARANCE_CONTROLS::onLayerPresetChanged( wxCommandEvent& aEvent )
2675{
2676 int count = m_cbLayerPresets->GetCount();
2677 int index = m_cbLayerPresets->GetSelection();
2678
2679 auto resetSelection =
2680 [&]()
2681 {
2682 if( m_currentPreset )
2683 m_cbLayerPresets->SetStringSelection( m_currentPreset->name );
2684 else
2685 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 );
2686 };
2687
2688 if( index == count - 3 )
2689 {
2690 // Separator: reject the selection
2691 resetSelection();
2692 return;
2693 }
2694 else if( index == count - 2 )
2695 {
2696 // Save current state to new preset
2697 wxString name;
2698
2701
2702 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
2703 _( "Save Layer Preset" ), name );
2704
2705 if( dlg.ShowModal() != wxID_OK )
2706 {
2707 resetSelection();
2708 return;
2709 }
2710
2711 name = dlg.GetValue();
2712 bool exists = m_layerPresets.count( name );
2713
2714 if( !exists )
2715 {
2717 UNSELECTED_LAYER, m_cbFlipBoard->GetValue() );
2718 }
2719
2720 LAYER_PRESET* preset = &m_layerPresets[name];
2721
2722 if( !exists )
2723 {
2724 index = m_cbLayerPresets->Insert( name, index - 1, static_cast<void*>( preset ) );
2725 }
2726 else if( preset->readOnly )
2727 {
2728 wxMessageBox( _( "Default presets cannot be modified.\nPlease use a different name." ),
2729 _( "Error" ), wxOK | wxICON_ERROR, wxGetTopLevelParent( this ) );
2730 resetSelection();
2731 return;
2732 }
2733 else
2734 {
2735 // Ask the user if they want to overwrite the existing preset
2736 if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
2737 {
2738 resetSelection();
2739 return;
2740 }
2741
2742 preset->layers = getVisibleLayers();
2743 preset->renderLayers = getVisibleObjects();
2744 preset->flipBoard = m_cbFlipBoard->GetValue();
2745
2746 index = m_cbLayerPresets->FindString( name );
2747 m_presetMRU.Remove( name );
2748 }
2749
2750 m_currentPreset = preset;
2751 m_cbLayerPresets->SetSelection( index );
2752 m_presetMRU.Insert( name, 0 );
2753
2754 return;
2755 }
2756 else if( index == count - 1 )
2757 {
2758 // Delete a preset
2759 wxArrayString headers;
2760 std::vector<wxArrayString> items;
2761
2762 headers.Add( _( "Presets" ) );
2763
2764 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2765 {
2766 if( !pair.second.readOnly )
2767 {
2768 wxArrayString item;
2769 item.Add( pair.first );
2770 items.emplace_back( item );
2771 }
2772 }
2773
2774 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
2775 dlg.SetListLabel( _( "Select preset:" ) );
2776
2777 if( dlg.ShowModal() == wxID_OK )
2778 {
2779 wxString presetName = dlg.GetTextSelection();
2780 int idx = m_cbLayerPresets->FindString( presetName );
2781
2782 if( idx != wxNOT_FOUND )
2783 {
2784 m_layerPresets.erase( presetName );
2785
2786 m_cbLayerPresets->Delete( idx );
2787 m_currentPreset = nullptr;
2788
2789 m_presetMRU.Remove( presetName );
2790 }
2791 }
2792
2793 resetSelection();
2794 return;
2795 }
2796
2797 // Store the objects visibility settings if the presedt is not a user preset,
2798 // to be reused when selecting a new built-in layer preset, even if a previous
2799 // user preset has changed the object visibility
2801 {
2803 }
2804
2805 LAYER_PRESET* preset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( index ) );
2806 m_currentPreset = preset;
2807
2808 m_lastSelectedUserPreset = ( !preset || preset->readOnly ) ? nullptr : preset;
2809
2810 if( preset )
2811 {
2812 // Change board layers visibility, but do not change objects visibility
2813 LAYER_PRESET curr_layers_choice = *preset;
2814
2815 // For predefined presets that do not manage objects visibility, use
2816 // the objects visibility settings of the last used predefined preset.
2817 if( curr_layers_choice.readOnly )
2818 curr_layers_choice.renderLayers = m_lastBuiltinPreset.renderLayers;
2819
2820 doApplyLayerPreset( curr_layers_choice );
2821 }
2822
2823 if( !m_currentPreset->name.IsEmpty() )
2824 {
2825 const wxString translatedName = wxGetTranslation( m_currentPreset->name );
2826
2827 m_presetMRU.Remove( translatedName );
2828 m_presetMRU.Insert( translatedName, 0 );
2829 }
2830
2831 passOnFocus();
2832}
2833
2834
2836{
2837 BOARD* board = m_frame->GetBoard();
2839
2840 setVisibleLayers( aPreset.layers );
2842
2843 // If the preset doesn't have an explicit active layer to restore, we can at least
2844 // force the active layer to be something in the preset's layer set
2845 PCB_LAYER_ID activeLayer = UNSELECTED_LAYER;
2846
2847 if( aPreset.activeLayer != UNSELECTED_LAYER )
2848 activeLayer = aPreset.activeLayer;
2849 else if( aPreset.layers.any() && !aPreset.layers.test( m_frame->GetActiveLayer() ) )
2850 activeLayer = *aPreset.layers.Seq().begin();
2851
2852 LSET boardLayers = board->GetLayerSet();
2853
2854 if( activeLayer != UNSELECTED_LAYER && boardLayers.Contains( activeLayer ) )
2855 m_frame->SetActiveLayer( activeLayer );
2856
2857 if( !m_isFpEditor )
2859
2860 if( aPreset.flipBoard != view->IsMirroredX() )
2861 {
2862 view->SetMirror( !view->IsMirroredX(), view->IsMirroredY() );
2863 view->RecacheAllItems();
2864 }
2865
2867
2870}
2871
2872
2874{
2875 m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
2877
2878 m_cbViewports->Clear();
2879
2880 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
2881 m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
2882
2883 m_cbViewports->Append( wxT( "---" ) );
2884 m_cbViewports->Append( _( "Save viewport..." ) );
2885 m_cbViewports->Append( _( "Delete viewport..." ) );
2886
2887 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2888 m_lastSelectedViewport = nullptr;
2889}
2890
2891
2893{
2894 int idx = m_cbViewports->FindString( aName );
2895
2896 if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
2897 {
2898 m_cbViewports->SetSelection( idx );
2899 m_lastSelectedViewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( idx ) );
2900 }
2901 else if( idx < 0 )
2902 {
2903 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
2904 m_lastSelectedViewport = nullptr;
2905 }
2906}
2907
2908
2909void APPEARANCE_CONTROLS::onViewportChanged( wxCommandEvent& aEvent )
2910{
2911 int count = m_cbViewports->GetCount();
2912 int index = m_cbViewports->GetSelection();
2913
2914 if( index >= 0 && index < count - 3 )
2915 {
2916 VIEWPORT* viewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( index ) );
2917
2918 wxCHECK( viewport, /* void */ );
2919
2920 doApplyViewport( *viewport );
2921
2922 if( !viewport->name.IsEmpty() )
2923 {
2924 m_viewportMRU.Remove( viewport->name );
2925 m_viewportMRU.Insert( viewport->name, 0 );
2926 }
2927 }
2928 else if( index == count - 2 )
2929 {
2930 // Save current state to new preset
2931 wxString name;
2932
2933 wxTextEntryDialog dlg( wxGetTopLevelParent( this ),
2934 _( "Viewport name:" ), _( "Save Viewport" ), name );
2935
2936 if( dlg.ShowModal() != wxID_OK )
2937 {
2939 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
2940 else
2941 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2942
2943 return;
2944 }
2945
2946 name = dlg.GetValue();
2947 bool exists = m_viewports.count( name );
2948
2949 if( !exists )
2950 {
2952
2953 index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
2954 }
2955 else
2956 {
2958 index = m_cbViewports->FindString( name );
2959 m_viewportMRU.Remove( name );
2960 }
2961
2962 m_cbViewports->SetSelection( index );
2963 m_viewportMRU.Insert( name, 0 );
2964
2965 return;
2966 }
2967 else if( index == count - 1 )
2968 {
2969 // Delete an existing viewport
2970 wxArrayString headers;
2971 std::vector<wxArrayString> items;
2972
2973 headers.Add( _( "Viewports" ) );
2974
2975 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
2976 {
2977 wxArrayString item;
2978 item.Add( pair.first );
2979 items.emplace_back( item );
2980 }
2981
2982 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
2983 dlg.SetListLabel( _( "Select viewport:" ) );
2984
2985 if( dlg.ShowModal() == wxID_OK )
2986 {
2987 wxString viewportName = dlg.GetTextSelection();
2988 int idx = m_cbViewports->FindString( viewportName );
2989
2990 if( idx != wxNOT_FOUND )
2991 {
2992 m_viewports.erase( viewportName );
2993 m_cbViewports->Delete( idx );
2994 m_viewportMRU.Remove( viewportName );
2995 }
2996 }
2997
2999 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
3000 else
3001 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
3002
3003 return;
3004 }
3005
3006 passOnFocus();
3007}
3008
3009
3011{
3012 m_frame->GetCanvas()->GetView()->SetViewport( aViewport.rect );
3014}
3015
3016
3017void APPEARANCE_CONTROLS::OnColorSwatchChanged( wxCommandEvent& aEvent )
3018{
3019 COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
3020 COLOR4D newColor = swatch->GetSwatchColor();
3021 int layer = swatch->GetId();
3022
3024
3025 cs->SetColor( layer, newColor );
3026 m_frame->GetSettingsManager()->SaveColorSettings( cs, "board" );
3027
3029
3030 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
3031 view->UpdateLayerColor( layer );
3032 view->UpdateLayerColor( GetNetnameLayer( layer ) );
3033
3034 if( IsCopperLayer( layer ) )
3035 view->UpdateLayerColor( ZONE_LAYER_FOR( layer ) );
3036
3037 // Update the bitmap of the layer box
3039 static_cast<PCB_EDIT_FRAME*>( m_frame )->ReCreateLayerBox( false );
3040
3042
3043 if( layer == LAYER_PCB_BACKGROUND )
3044 m_frame->SetDrawBgColor( newColor );
3045
3046 passOnFocus();
3047}
3048
3049
3050void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
3051{
3053
3054 switch( aLayer )
3055 {
3056 case static_cast<int>( LAYER_TRACKS ): options.m_TrackOpacity = aOpacity; break;
3057 case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
3058 case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
3059 case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
3060 case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_ImageOpacity = aOpacity; break;
3061 case static_cast<int>( LAYER_SHAPES ): options.m_FilledShapeOpacity = aOpacity; break;
3062 default: return;
3063 }
3064
3065 m_frame->SetDisplayOptions( options );
3066 passOnFocus();
3067}
3068
3069
3070void APPEARANCE_CONTROLS::onNetContextMenu( wxCommandEvent& aEvent )
3071{
3072 wxASSERT( m_netsGrid->GetSelectedRows().size() == 1 );
3073
3074 int row = m_netsGrid->GetSelectedRows()[0];
3075 NET_GRID_ENTRY& net = m_netsTable->GetEntry( row );
3076
3077 m_netsGrid->ClearSelection();
3078
3079 switch( aEvent.GetId() )
3080 {
3081 case ID_SET_NET_COLOR:
3082 {
3083 wxGridCellEditor* editor = m_netsGrid->GetCellEditor( row, NET_GRID_TABLE::COL_COLOR );
3084 editor->BeginEdit( row, NET_GRID_TABLE::COL_COLOR, m_netsGrid );
3085 break;
3086 }
3087
3088 case ID_CLEAR_NET_COLOR:
3089 m_netsGrid->SetCellValue( row, NET_GRID_TABLE::COL_COLOR, wxS( "rgba(0,0,0,0)" ) );
3090 break;
3091
3092 case ID_HIGHLIGHT_NET:
3095 break;
3096
3097 case ID_SELECT_NET:
3100 break;
3101
3102 case ID_DESELECT_NET:
3105 break;
3106
3107 case ID_SHOW_ALL_NETS:
3109 break;
3110
3111 case ID_HIDE_OTHER_NETS:
3112 m_netsTable->HideOtherNets( net );
3113 break;
3114
3115 default:
3116 break;
3117 }
3118
3119 passOnFocus();
3120}
3121
3122
3124{
3125 wxString className = netclassNameFromEvent( aEvent );
3126 bool show = aEvent.GetInt();
3127 showNetclass( className, show );
3128 passOnFocus();
3129}
3130
3131
3132void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow )
3133{
3135
3136 for( NETINFO_ITEM* net : m_frame->GetBoard()->GetNetInfo() )
3137 {
3138 if( net->GetNetClass()->ContainsNetclassWithName( aClassName ) )
3139 {
3142 net->GetNetCode() );
3143
3144 int row = m_netsTable->GetRowByNetcode( net->GetNetCode() );
3145
3146 if( row >= 0 )
3148 }
3149 }
3150
3151 PROJECT_LOCAL_SETTINGS& localSettings = m_frame->Prj().GetLocalSettings();
3152
3153 if( !aShow )
3154 localSettings.m_HiddenNetclasses.insert( aClassName );
3155 else
3156 localSettings.m_HiddenNetclasses.erase( aClassName );
3157
3158 m_netsGrid->ForceRefresh();
3162}
3163
3164
3166{
3167 COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
3168 wxString netclassName = netclassNameFromEvent( aEvent );
3169
3170 BOARD* board = m_frame->GetBoard();
3171 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
3172 std::shared_ptr<NETCLASS> nc = netSettings->GetNetClassByName( netclassName );
3173
3174 nc->SetPcbColor( swatch->GetSwatchColor() );
3175 netSettings->RecomputeEffectiveNetclasses();
3176
3180}
3181
3182
3184{
3185 COLOR_SWATCH* s = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
3186 int classId = s->GetId();
3187
3188 wxASSERT( m_netclassIdMap.count( classId ) );
3189 return m_netclassIdMap.at( classId );
3190}
3191
3192
3193void APPEARANCE_CONTROLS::onNetColorMode( wxCommandEvent& aEvent )
3194{
3196
3197 if( m_rbNetColorAll->GetValue() )
3198 options.m_NetColorMode = NET_COLOR_MODE::ALL;
3199 else if( m_rbNetColorRatsnest->GetValue() )
3200 options.m_NetColorMode = NET_COLOR_MODE::RATSNEST;
3201 else
3202 options.m_NetColorMode = NET_COLOR_MODE::OFF;
3203
3204 m_frame->SetDisplayOptions( options );
3206 passOnFocus();
3207}
3208
3209
3210void APPEARANCE_CONTROLS::onRatsnestMode( wxCommandEvent& aEvent )
3211{
3213
3214 if( m_rbRatsnestAllLayers->GetValue() )
3215 {
3216 cfg->m_Display.m_ShowGlobalRatsnest = true;
3217 cfg->m_Display.m_RatsnestMode = RATSNEST_MODE::ALL;
3218 }
3219 else if( m_rbRatsnestVisLayers->GetValue() )
3220 {
3221 cfg->m_Display.m_ShowGlobalRatsnest = true;
3222 cfg->m_Display.m_RatsnestMode = RATSNEST_MODE::VISIBLE;
3223 }
3224 else
3225 {
3226 cfg->m_Display.m_ShowGlobalRatsnest = false;
3227 }
3228
3229 if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
3230 {
3231 editframe->SetElementVisibility( LAYER_RATSNEST, cfg->m_Display.m_ShowGlobalRatsnest );
3232 editframe->OnDisplayOptionsChanged();
3233 editframe->GetCanvas()->RedrawRatsnest();
3234 editframe->GetCanvas()->Refresh();
3235 }
3236 passOnFocus();
3237}
3238
3239
3241{
3242 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
3244 static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
3245
3246 BOARD* board = m_frame->GetBoard();
3247 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
3248 APPEARANCE_SETTING* setting = nullptr;
3249
3251
3252 if( it != m_netclassSettingsMap.end() )
3253 setting = it->second;
3254
3255 auto runOnNetsOfClass =
3256 [&]( const wxString& netClassName, std::function<void( NETINFO_ITEM* )> aFunction )
3257 {
3258 for( NETINFO_ITEM* net : board->GetNetInfo() )
3259 {
3260 if( net->GetNetClass()->ContainsNetclassWithName( netClassName ) )
3261 aFunction( net );
3262 }
3263 };
3264
3265 switch( aEvent.GetId() )
3266 {
3267 case ID_SET_NET_COLOR:
3268 {
3269 if( setting )
3270 {
3271 setting->ctl_color->GetNewSwatchColor();
3272
3273 COLOR4D color = setting->ctl_color->GetSwatchColor();
3274
3275 if( color != COLOR4D::UNSPECIFIED )
3276 {
3277 netSettings->GetNetClassByName( m_contextMenuNetclass )->SetPcbColor( color );
3278 netSettings->RecomputeEffectiveNetclasses();
3279 }
3280
3281 view->UpdateAllLayersColor();
3282 }
3283
3284 break;
3285 }
3286
3287 case ID_CLEAR_NET_COLOR:
3288 {
3289 if( setting )
3290 {
3291 setting->ctl_color->SetSwatchColor( COLOR4D( 0, 0, 0, 0 ), true );
3292
3293 netSettings->GetNetClassByName( m_contextMenuNetclass )
3294 ->SetPcbColor( COLOR4D::UNSPECIFIED );
3295 netSettings->RecomputeEffectiveNetclasses();
3296
3297 view->UpdateAllLayersColor();
3298 }
3299
3300 break;
3301 }
3302
3304 {
3305 if( setting )
3306 {
3307 std::shared_ptr<NETCLASS> nc =
3308 netSettings->GetNetClassByName( m_contextMenuNetclass );
3309 const KIGFX::COLOR4D ncColor = nc->GetSchematicColor();
3310
3311 setting->ctl_color->SetSwatchColor( ncColor, true );
3312
3313 netSettings->GetNetClassByName( m_contextMenuNetclass )->SetPcbColor( ncColor );
3314 netSettings->RecomputeEffectiveNetclasses();
3315
3316 view->UpdateAllLayersColor();
3317 }
3318
3319 break;
3320 }
3321
3322 case ID_HIGHLIGHT_NET:
3323 {
3324 if( !m_contextMenuNetclass.IsEmpty() )
3325 {
3326 runOnNetsOfClass( m_contextMenuNetclass,
3327 [&]( NETINFO_ITEM* aItem )
3328 {
3329 static bool first = true;
3330 int code = aItem->GetNetCode();
3331
3332 if( first )
3333 {
3334 board->SetHighLightNet( code );
3335 rs->SetHighlight( true, code );
3336 first = false;
3337 }
3338 else
3339 {
3340 board->SetHighLightNet( code, true );
3341 rs->SetHighlight( true, code, true );
3342 }
3343 } );
3344
3345 view->UpdateAllLayersColor();
3346 board->HighLightON();
3347 }
3348
3349 break;
3350 }
3351
3352 case ID_SELECT_NET:
3353 case ID_DESELECT_NET:
3354 {
3355 if( !m_contextMenuNetclass.IsEmpty() )
3356 {
3357 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
3360
3361 runOnNetsOfClass( m_contextMenuNetclass,
3362 [&]( NETINFO_ITEM* aItem )
3363 {
3364 toolMgr->RunAction( action, aItem->GetNetCode() );
3365 } );
3366 }
3367 break;
3368 }
3369
3370
3371 case ID_SHOW_ALL_NETS:
3372 {
3374 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3375 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( true );
3376
3377 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
3378 {
3379 showNetclass( name );
3380
3381 if( m_netclassSettingsMap.count( name ) )
3382 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( true );
3383 }
3384
3385 break;
3386 }
3387
3388 case ID_HIDE_OTHER_NETS:
3389 {
3390 bool showDefault = m_contextMenuNetclass == NETCLASS::Default;
3391 showNetclass( NETCLASS::Default, showDefault );
3392 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3393 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( showDefault );
3394
3395 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
3396 {
3397 bool show = ( name == m_contextMenuNetclass );
3398
3399 showNetclass( name, show );
3400
3401 if( m_netclassSettingsMap.count( name ) )
3402 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( show );
3403 }
3404
3405 break;
3406 }
3407
3408 default:
3409 break;
3410 }
3411
3414
3415 m_contextMenuNetclass.clear();
3416}
3417
3418
3420{
3421 m_focusOwner->SetFocus();
3422}
3423
3424
3426{
3427 WX_INFOBAR* infobar = m_frame->GetInfoBar();
3428
3429 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Open Preferences" ),
3430 wxEmptyString );
3431
3432 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
3433 [&]( wxHyperlinkEvent& aEvent )
3434 {
3435 m_frame->ShowPreferences( wxEmptyString, wxEmptyString );
3436 } ) );
3437
3438 infobar->RemoveAllButtons();
3439 infobar->AddButton( button );
3440 infobar->AddCloseButton();
3441
3442 infobar->ShowMessageFor( _( "The current color theme is read-only. Create a new theme in "
3443 "Preferences to enable color editing." ),
3444 10000, wxICON_INFORMATION );
3445}
3446
3447
3449{
3450 m_paneLayerDisplayOptions->Refresh();
3451}
3452
3453
3455{
3457}
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:778
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:792
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:2669
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition: board.cpp:838
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:2730
int GetCopperLayerCount() const
Definition: board.cpp:741
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:810
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:850
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:574
PROJECT * GetProject() const
Definition: board.h:491
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:895
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2743
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:817
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:852
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:138
std::map< int, KIGFX::COLOR4D > & GetNetColorMap()
Definition: pcb_painter.h:136
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:549
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:522
void SetViewport(const BOX2D &aViewport)
Set the visible area of the VIEW.
Definition: view.cpp:534
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:765
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:397
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition: view.h:247
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1435
bool IsMirroredY() const
Return true if view is flipped across the Y axis.
Definition: view.h:255
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:744
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:419
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:217
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:636
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:1555
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:711
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:250
static LSET FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
Definition: lset.cpp:661
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:675
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:802
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:420
static LSET BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
Definition: lset.cpp:668
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:782
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:789
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Definition: lset.h:62
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:706
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:820
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition: definitions.h:38
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