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