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