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