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