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