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