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();
227 KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
228
229 std::set<int>& hiddenNets = rs->GetHiddenNets();
230 std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
231
232 int deleted = (int) m_nets.size();
233 m_nets.clear();
234
235 if( GetView() )
236 {
237 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, deleted );
238 GetView()->ProcessTableMessage( msg );
239 }
240
241 for( const std::pair<const wxString, NETINFO_ITEM*>& pair : nets )
242 {
243 int netCode = pair.second->GetNetCode();
244
245 if( netCode > 0 && !pair.first.StartsWith( wxT( "unconnected-(" ) ) )
246 {
247 COLOR4D color = netColors.count( netCode ) ? netColors.at( netCode )
248 : COLOR4D::UNSPECIFIED;
249
250 bool visible = hiddenNets.count( netCode ) == 0;
251
252 m_nets.emplace_back( NET_GRID_ENTRY( netCode, pair.first, color, visible ) );
253 }
254 }
255
256 // TODO(JE) move to ::Compare so we can re-sort easily
257 std::sort( m_nets.begin(), m_nets.end(),
258 []( const NET_GRID_ENTRY& a, const NET_GRID_ENTRY& b )
259 {
260 return a.name < b.name;
261 } );
262
263 if( GetView() )
264 {
265 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, (int) m_nets.size() );
266 GetView()->ProcessTableMessage( msg );
267 }
268}
269
270
272{
273 for( NET_GRID_ENTRY& net : m_nets )
274 {
275 net.visible = true;
276 updateNetVisibility( net );
277 }
278
279 if( GetView() )
280 GetView()->ForceRefresh();
281}
282
283
285{
286 for( NET_GRID_ENTRY& net : m_nets )
287 {
288 net.visible = ( net.code == aNet.code );
289 updateNetVisibility( net );
290 }
291
292 if( GetView() )
293 GetView()->ForceRefresh();
294}
295
296
298{
301
302 m_frame->GetToolManager()->RunAction( action, aNet.code );
303}
304
305
307{
309 KIGFX::PCB_RENDER_SETTINGS* renderSettings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( rs );
310
311 std::map<int, KIGFX::COLOR4D>& netColors = renderSettings->GetNetColorMap();
312
313 if( aNet.color != COLOR4D::UNSPECIFIED )
314 netColors[aNet.code] = aNet.color;
315 else
316 netColors.erase( aNet.code );
317
321}
322
323
326
327#define RR APPEARANCE_CONTROLS::APPEARANCE_SETTING // Render Row abbreviation to reduce source width
328
329 // clang-format off
330
331 // text id tooltip opacity slider visibility checkbox
332 RR( _HKI( "Tracks" ), LAYER_TRACKS, _HKI( "Show tracks" ), true ),
333 RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
334 RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
335 RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
336 RR( _HKI( "Filled Shapes" ), LAYER_FILLED_SHAPES, _HKI( "Opacity of filled shapes" ), true, false ),
337 RR( _HKI( "Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user images" ), true ),
338 RR(),
339 RR( _HKI( "Footprints Front" ), LAYER_FOOTPRINTS_FR, _HKI( "Show footprints that are on board's front" ) ),
340 RR( _HKI( "Footprints Back" ), LAYER_FOOTPRINTS_BK, _HKI( "Show footprints that are on board's back" ) ),
341 RR( _HKI( "Values" ), LAYER_FP_VALUES, _HKI( "Show footprint values" ) ),
342 RR( _HKI( "References" ), LAYER_FP_REFERENCES, _HKI( "Show footprint references" ) ),
343 RR( _HKI( "Footprint Text" ), LAYER_FP_TEXT, _HKI( "Show all footprint text" ) ),
344 RR(),
345 RR(),
346 RR( _HKI( "Ratsnest" ), LAYER_RATSNEST, _HKI( "Show unconnected nets as a ratsnest") ),
347 RR( _HKI( "DRC Warnings" ), LAYER_DRC_WARNING, _HKI( "DRC violations with a Warning severity" ) ),
348 RR( _HKI( "DRC Errors" ), LAYER_DRC_ERROR, _HKI( "DRC violations with an Error severity" ) ),
349 RR( _HKI( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _HKI( "DRC violations which have been individually excluded" ) ),
350 RR( _HKI( "Anchors" ), LAYER_ANCHOR, _HKI( "Show footprint and text origins as a cross" ) ),
351 RR( _HKI( "Locked Item Shadow" ), LAYER_LOCKED_ITEM_SHADOW, _HKI( "Show a shadow on locked items" ) ),
352 RR( _HKI( "Colliding Courtyards" ), LAYER_CONFLICTS_SHADOW, _HKI( "Show colliding footprint courtyards" ) ),
353 RR( _HKI( "Board Area Shadow" ), LAYER_BOARD_OUTLINE_AREA, _HKI( "Show board area shadow" ) ),
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
404APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner, bool aFpEditorMode ) :
405 APPEARANCE_CONTROLS_BASE( aParent ),
406 m_frame( aParent ),
407 m_focusOwner( aFocusOwner ),
408 m_board( nullptr ),
409 m_isFpEditor( aFpEditorMode ),
410 m_currentPreset( nullptr ),
411 m_lastSelectedUserPreset( nullptr ),
412 m_layerContextMenu( nullptr ),
413 m_togglingNetclassRatsnestVisibility( false )
414{
415 // Correct the min size from wxformbuilder not using fromdip
416 SetMinSize( FromDIP( GetMinSize() ) );
417
418 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
420 m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
421 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
422 SetBorders( true, false, false, false );
423
424 m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
426 m_windowLayers->SetScrollRate( 0, 5 );
427 m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
428
429 m_objectsOuterSizer = new wxBoxSizer( wxVERTICAL );
431 m_windowObjects->SetScrollRate( 0, 5 );
432 m_windowObjects->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
433
434 wxFont infoFont = KIUI::GetInfoFont( this );
435 m_staticTextNets->SetFont( infoFont );
436 m_staticTextNetClasses->SetFont( infoFont );
437 m_panelLayers->SetFont( infoFont );
438 m_windowLayers->SetFont( infoFont );
439 m_windowObjects->SetFont( infoFont );
440 m_presetsLabel->SetFont( infoFont );
441 m_viewportsLabel->SetFont( infoFont );
442
443 m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore layer visibility combinations.\n"
444 "Use %s+Tab to activate selector.\n"
445 "Successive Tabs while holding %s down will "
446 "cycle through presets in the popup." ),
449
450 m_cbViewports->SetToolTip( wxString::Format( _( "Save and restore view location and zoom.\n"
451 "Use %s+Tab to activate selector.\n"
452 "Successive Tabs while holding %s down will "
453 "cycle through viewports in the popup." ),
456
458
459 m_btnNetInspector->SetBitmap( KiBitmapBundle( BITMAPS::list_nets_16 ) );
461
462 m_btnConfigureNetClasses->SetBitmap( KiBitmapBundle( BITMAPS::options_generic_16 ) );
464
465 m_txtNetFilter->SetHint( _( "Filter nets" ) );
466
467 if( screenHeight <= 900 && m_pointSize >= FromDIP( KIUI::c_IndicatorSizeDIP ) )
468 m_pointSize = m_pointSize * 8 / 10;
469
470 wxFont font = m_notebook->GetFont();
471
472#ifdef __WXMAC__
473 font.SetPointSize( m_pointSize );
474 m_notebook->SetFont( font );
475#endif
476
477 auto setHighContrastMode =
478 [&]( HIGH_CONTRAST_MODE aMode )
479 {
481 opts.m_ContrastModeDisplay = aMode;
482
483 m_frame->SetDisplayOptions( opts );
484 passOnFocus();
485 };
486
487 m_rbHighContrastNormal->Bind( wxEVT_RADIOBUTTON,
488 [=]( wxCommandEvent& aEvent )
489 {
490 setHighContrastMode( HIGH_CONTRAST_MODE::NORMAL );
491 } );
492
493 m_rbHighContrastDim->Bind( wxEVT_RADIOBUTTON,
494 [=]( wxCommandEvent& aEvent )
495 {
496 setHighContrastMode( HIGH_CONTRAST_MODE::DIMMED );
497 } );
498
499 m_rbHighContrastOff->Bind( wxEVT_RADIOBUTTON,
500 [=]( wxCommandEvent& aEvent )
501 {
502 setHighContrastMode( HIGH_CONTRAST_MODE::HIDDEN );
503 } );
504
506
507 m_btnNetInspector->Bind( wxEVT_BUTTON,
508 [&]( wxCommandEvent& aEvent )
509 {
511 } );
512
513 m_btnConfigureNetClasses->Bind( wxEVT_BUTTON,
514 [&]( wxCommandEvent& aEvent )
515 {
516 // This panel should only be visible in the PCB_EDIT_FRAME anyway
517 if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
518 editframe->ShowBoardSetupDialog( _( "Net Classes" ) );
519
520 passOnFocus();
521 } );
522
523 m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
524 m_cbFlipBoard->Bind( wxEVT_CHECKBOX,
525 [&]( wxCommandEvent& aEvent )
526 {
529 } );
530
532 KiBitmapBundle( BITMAPS::visibility_off ) );
533
534 m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor );
535
536 m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
539
540 m_netsTable = new NET_GRID_TABLE( m_frame, m_panelNets->GetBackgroundColour() );
543
544 m_netsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
545 m_netsGrid->SetSelectionForeground( m_netsGrid->GetDefaultCellTextColour() );
546 m_netsGrid->SetSelectionBackground( m_panelNets->GetBackgroundColour() );
547
548 const int cellPadding = 6;
549#ifdef __WXMAC__
550 const int rowHeightPadding = 5;
551#else
552 const int rowHeightPadding = 3;
553#endif
554
555 wxSize size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU );
556 m_netsGrid->SetColSize( NET_GRID_TABLE::COL_COLOR, size.x + cellPadding );
557
558 size = KiBitmapBundle( BITMAPS::visibility ).GetPreferredBitmapSizeFor( this );
559 m_netsGrid->SetColSize( NET_GRID_TABLE::COL_VISIBILITY, size.x + cellPadding );
560
561 m_netsGrid->SetDefaultCellFont( font );
562 m_netsGrid->SetDefaultRowSize( font.GetPixelSize().y + rowHeightPadding );
563
564 m_netsGrid->GetGridWindow()->Bind( wxEVT_MOTION, &APPEARANCE_CONTROLS::OnNetGridMouseEvent, this );
565
566 // To handle middle click on color swatches
567 m_netsGrid->GetGridWindow()->Bind( wxEVT_MIDDLE_UP, &APPEARANCE_CONTROLS::OnNetGridMouseEvent, this );
568
569 m_netsGrid->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
570 m_netclassScrolledWindow->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
571
572 if( m_isFpEditor )
573 m_notebook->RemovePage( 2 );
574
576 {
577 if( cfg->m_AuiPanels.appearance_expand_layer_display )
579
580 if( cfg->m_AuiPanels.appearance_expand_net_display )
582 }
583
588
589 // Grid visibility is loaded and set to the GAL before we are constructed
591
592 Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::OnLayerContextMenu, this,
594
595 m_frame->Bind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS::OnLanguageChanged, this );
596}
597
598
600{
601 m_frame->Unbind( EDA_LANG_CHANGED, &APPEARANCE_CONTROLS::OnLanguageChanged, this );
602
603 delete m_iconProvider;
604}
605
606
608{
609 int hotkey;
610 wxString msg;
611 wxFont infoFont = KIUI::GetInfoFont( this );
612
613 // Create layer display options
615 _( "Layer Display Options" ) );
617 m_paneLayerDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
618
619 wxWindow* layerDisplayPane = m_paneLayerDisplayOptions->GetPane();
620
621 wxBoxSizer* layerDisplayOptionsSizer;
622 layerDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
623
625
626 if( hotkey )
627 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
628 else
629 msg = _( "Inactive layers:" );
630
631 m_inactiveLayersLabel = new wxStaticText( layerDisplayPane, wxID_ANY, msg );
632 m_inactiveLayersLabel->SetFont( infoFont );
633 m_inactiveLayersLabel->Wrap( -1 );
634 layerDisplayOptionsSizer->Add( m_inactiveLayersLabel, 0, wxEXPAND | wxBOTTOM, 2 );
635
636 wxBoxSizer* contrastModeSizer;
637 contrastModeSizer = new wxBoxSizer( wxHORIZONTAL );
638
639 m_rbHighContrastNormal = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Normal" ),
640 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
641 m_rbHighContrastNormal->SetFont( infoFont );
642 m_rbHighContrastNormal->SetValue( true );
643 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
644
645 contrastModeSizer->Add( m_rbHighContrastNormal, 0, wxRIGHT, 5 );
646 contrastModeSizer->AddStretchSpacer();
647
648 m_rbHighContrastDim = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Dim" ) );
649 m_rbHighContrastDim->SetFont( infoFont );
650 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
651
652 contrastModeSizer->Add( m_rbHighContrastDim, 0, wxRIGHT, 5 );
653 contrastModeSizer->AddStretchSpacer();
654
655 m_rbHighContrastOff = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Hide" ) );
656 m_rbHighContrastOff->SetFont( infoFont );
657 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
658
659 contrastModeSizer->Add( m_rbHighContrastOff, 0, 0, 5 );
660 contrastModeSizer->AddStretchSpacer();
661
662 layerDisplayOptionsSizer->Add( contrastModeSizer, 0, wxEXPAND, 5 );
663
664 m_layerDisplaySeparator = new wxStaticLine( layerDisplayPane, wxID_ANY, wxDefaultPosition,
665 wxDefaultSize, wxLI_HORIZONTAL );
666 layerDisplayOptionsSizer->Add( m_layerDisplaySeparator, 0, wxEXPAND | wxTOP, 4 );
667
668 m_cbFlipBoard = new wxCheckBox( layerDisplayPane, wxID_ANY, _( "Flip board view" ) );
669 m_cbFlipBoard->SetFont( infoFont );
670 layerDisplayOptionsSizer->Add( m_cbFlipBoard, 0, wxTOP | wxBOTTOM, 3 );
671
672 layerDisplayPane->SetSizer( layerDisplayOptionsSizer );
673 layerDisplayPane->Layout();
674 layerDisplayOptionsSizer->Fit( layerDisplayPane );
675
676 m_panelLayersSizer->Add( m_paneLayerDisplayOptions, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5 );
677
678 m_paneLayerDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
679 [&]( wxCommandEvent& aEvent )
680 {
681 Freeze();
682 m_panelLayers->Fit();
683 m_sizerOuter->Layout();
684 Thaw();
685 } );
686
687 // Create net display options
688
690 _( "Net Display Options" ) );
692 m_paneNetDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
693
694 wxWindow* netDisplayPane = m_paneNetDisplayOptions->GetPane();
695 wxBoxSizer* netDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
696
698
700
701 if( hotkey )
702 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
703 else
704 msg = _( "Net colors:" );
705
706 m_txtNetDisplayTitle = new wxStaticText( netDisplayPane, wxID_ANY, msg );
707 m_txtNetDisplayTitle->SetFont( infoFont );
708 m_txtNetDisplayTitle->Wrap( -1 );
709 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
710
711 netDisplayOptionsSizer->Add( m_txtNetDisplayTitle, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
712
713 wxBoxSizer* netColorSizer = new wxBoxSizer( wxHORIZONTAL );
714
715 m_rbNetColorAll = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ), wxDefaultPosition,
716 wxDefaultSize, wxRB_GROUP );
717 m_rbNetColorAll->SetFont( infoFont );
718 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
719
720 netColorSizer->Add( m_rbNetColorAll, 0, wxRIGHT, 5 );
721 netColorSizer->AddStretchSpacer();
722
723 m_rbNetColorRatsnest = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Ratsnest" ) );
724 m_rbNetColorRatsnest->SetFont( infoFont );
725 m_rbNetColorRatsnest->SetValue( true );
726 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
727
728 netColorSizer->Add( m_rbNetColorRatsnest, 0, wxRIGHT, 5 );
729 netColorSizer->AddStretchSpacer();
730
731 m_rbNetColorOff = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
732 m_rbNetColorOff->SetFont( infoFont );
733 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
734
735 netColorSizer->Add( m_rbNetColorOff, 0, 0, 5 );
736
737 netDisplayOptionsSizer->Add( netColorSizer, 0, wxEXPAND | wxBOTTOM, 5 );
738
740
742
743 if( hotkey )
744 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
745 else
746 msg = _( "Ratsnest display:" );
747
748 m_txtRatsnestVisibility = new wxStaticText( netDisplayPane, wxID_ANY, msg );
749 m_txtRatsnestVisibility->SetFont( infoFont );
750 m_txtRatsnestVisibility->Wrap( -1 );
751 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
752
753 netDisplayOptionsSizer->Add( m_txtRatsnestVisibility, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
754
755 wxBoxSizer* ratsnestDisplayModeSizer = new wxBoxSizer( wxHORIZONTAL );
756
757 m_rbRatsnestAllLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ),
758 wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
759 m_rbRatsnestAllLayers->SetFont( infoFont );
760 m_rbRatsnestAllLayers->SetValue( true );
761 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
762
763 ratsnestDisplayModeSizer->Add( m_rbRatsnestAllLayers, 0, wxRIGHT, 5 );
764 ratsnestDisplayModeSizer->AddStretchSpacer();
765
766 m_rbRatsnestVisLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Visible layers" ) );
767 m_rbRatsnestVisLayers->SetFont( infoFont );
768 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
769
770 ratsnestDisplayModeSizer->Add( m_rbRatsnestVisLayers, 0, wxRIGHT, 5 );
771 ratsnestDisplayModeSizer->AddStretchSpacer();
772
773 m_rbRatsnestNone = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ) );
774 m_rbRatsnestNone->SetFont( infoFont );
775 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
776
777 ratsnestDisplayModeSizer->Add( m_rbRatsnestNone, 0, 0, 5 );
778
779 netDisplayOptionsSizer->Add( ratsnestDisplayModeSizer, 0, wxEXPAND | wxBOTTOM, 5 );
780
782
783 netDisplayPane->SetSizer( netDisplayOptionsSizer );
784 netDisplayPane->Layout();
785 netDisplayOptionsSizer->Fit( netDisplayPane );
786
787 m_netsTabOuterSizer->Add( m_paneNetDisplayOptions, 0, wxEXPAND | wxTOP, 5 );
788
789 m_paneNetDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
790 [&]( wxCommandEvent& aEvent )
791 {
792 Freeze();
794 m_sizerOuter->Layout();
795 passOnFocus();
796 Thaw();
797 } );
798
799 m_rbNetColorAll->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
800 m_rbNetColorOff->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
801 m_rbNetColorRatsnest->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorMode, this );
802
803 m_rbRatsnestAllLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
804 m_rbRatsnestVisLayers->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
805 m_rbRatsnestNone->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onRatsnestMode, this );
806}
807
808
810{
811 DPI_SCALING_COMMON dpi( nullptr, m_frame );
812 wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
813 return size;
814}
815
816
818{
820}
821
822
824{
826}
827
828
829void APPEARANCE_CONTROLS::OnNotebookPageChanged( wxNotebookEvent& aEvent )
830{
831 // Work around wxMac issue where the notebook pages are blank
832#ifdef __WXMAC__
833 int page = aEvent.GetSelection();
834
835 if( page >= 0 )
836 m_notebook->ChangeSelection( static_cast<unsigned>( page ) );
837#endif
838
839#ifndef __WXMSW__
840 // Because wxWidgets is broken and will send click events to children of the collapsible
841 // panes even if they are collapsed without this
842 Freeze();
843 m_panelLayers->Fit();
845 m_sizerOuter->Layout();
846 Thaw();
847#endif
848
849 Bind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
850}
851
852
853void APPEARANCE_CONTROLS::idleFocusHandler( wxIdleEvent& aEvent )
854{
855 passOnFocus();
856 Unbind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
857}
858
859
860void APPEARANCE_CONTROLS::OnSetFocus( wxFocusEvent& aEvent )
861{
862#ifdef __WXMSW__
863 // In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
864 // focus and give it back to the parent in the button event handler.
865 if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
866 {
867 wxCommandEvent evt( wxEVT_BUTTON );
868 wxPostEvent( btn, evt );
869 }
870#endif
871
872 passOnFocus();
873 aEvent.Skip();
874}
875
876
877void APPEARANCE_CONTROLS::OnSize( wxSizeEvent& aEvent )
878{
879 aEvent.Skip();
880}
881
882
883void APPEARANCE_CONTROLS::OnNetGridClick( wxGridEvent& event )
884{
885 int row = event.GetRow();
886 int col = event.GetCol();
887
888 switch( col )
889 {
891 m_netsTable->SetValueAsBool( row, col, !m_netsTable->GetValueAsBool( row, col ) );
892 m_netsGrid->ForceRefresh();
893 break;
894
895 default:
896 break;
897 }
898}
899
900
902{
903 int row = event.GetRow();
904 int col = event.GetCol();
905
906 switch( col )
907 {
909 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
910 break;
911
912 default:
913 break;
914 }
915}
916
917
919{
920 m_netsGrid->SelectRow( event.GetRow() );
921
922 wxString netName = UnescapeString( m_netsGrid->GetCellValue( event.GetRow(),
924 wxMenu menu;
925
926 menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR, _( "Set Net Color" ), wxEmptyString,
927 wxITEM_NORMAL ) );
928 menu.Append( new wxMenuItem( &menu, ID_CLEAR_NET_COLOR, _( "Clear Net Color" ), wxEmptyString,
929 wxITEM_NORMAL ) );
930
931 menu.AppendSeparator();
932
933 menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
934 wxString::Format( _( "Highlight %s" ), netName ), wxEmptyString,
935 wxITEM_NORMAL ) );
936 menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
937 wxString::Format( _( "Select Tracks and Vias in %s" ), netName ),
938 wxEmptyString, wxITEM_NORMAL ) );
939 menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
940 wxString::Format( _( "Unselect Tracks and Vias in %s" ), netName ),
941 wxEmptyString, wxITEM_NORMAL ) );
942
943 menu.AppendSeparator();
944
945 menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS, _( "Show All Nets" ), wxEmptyString,
946 wxITEM_NORMAL ) );
947 menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS, _( "Hide All Other Nets" ),
948 wxEmptyString, wxITEM_NORMAL ) );
949
950 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetContextMenu, this );
951
952 PopupMenu( &menu );
953}
954
955
957{
958 wxPoint pos = m_netsGrid->CalcUnscrolledPosition( aEvent.GetPosition() );
959 wxGridCellCoords cell = m_netsGrid->XYToCell( pos );
960
961 if( aEvent.Moving() || aEvent.Entering() )
962 {
963 aEvent.Skip();
964
965 if( !cell )
966 {
967 m_netsGrid->GetGridWindow()->UnsetToolTip();
968 return;
969 }
970
971 if( cell == m_hoveredCell )
972 return;
973
974 m_hoveredCell = cell;
975
976 NET_GRID_ENTRY& net = m_netsTable->GetEntry( cell.GetRow() );
977
978 wxString name = net.name;
979 wxString showOrHide = net.visible ? _( "Click to hide ratsnest for %s" )
980 : _( "Click to show ratsnest for %s" );
981 wxString tip;
982
983 if( cell.GetCol() == NET_GRID_TABLE::COL_VISIBILITY )
984 tip.Printf( showOrHide, name );
985 else if( cell.GetCol() == NET_GRID_TABLE::COL_COLOR )
986 tip = _( "Double click (or middle click) to change color; right click for more actions" );
987
988 m_netsGrid->GetGridWindow()->SetToolTip( tip );
989 }
990 else if( aEvent.Leaving() )
991 {
992 m_netsGrid->UnsetToolTip();
993 aEvent.Skip();
994 }
995 else if( aEvent.Dragging() )
996 {
997 // not allowed
998 CallAfter( [this]()
999 {
1000 m_netsGrid->ClearSelection();
1001 } );
1002 }
1003 else if( aEvent.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !!cell )
1004 {
1005 int row = cell.GetRow();
1006 int col = cell.GetCol();
1007
1008 if(col == NET_GRID_TABLE::COL_COLOR )
1009 m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
1010
1011 aEvent.Skip();
1012 }
1013 else
1014 {
1015 aEvent.Skip();
1016 }
1017}
1018
1019
1020void APPEARANCE_CONTROLS::OnLanguageChanged( wxCommandEvent& aEvent )
1021{
1022 m_notebook->SetPageText( 0, _( "Layers" ) );
1023 m_notebook->SetPageText( 1, _( "Objects" ) );
1024
1025 if( m_notebook->GetPageCount() >= 3 )
1026 m_notebook->SetPageText( 2, _( "Nets" ) );
1027
1028 m_netsGrid->ClearSelection();
1029
1030 Freeze();
1031 rebuildLayers();
1036 rebuildNets();
1037
1041
1043
1044 Thaw();
1045 Refresh();
1046
1047 aEvent.Skip();
1048}
1049
1050
1052{
1053 m_netsGrid->ClearSelection();
1054
1055 Freeze();
1056 rebuildLayers();
1060 rebuildNets();
1064
1066
1068
1069 if( m_board )
1070 m_board->AddListener( this );
1071
1072 Thaw();
1073 Refresh();
1074}
1075
1076
1078{
1080}
1081
1082
1083void APPEARANCE_CONTROLS::OnNetVisibilityChanged( int aNetCode, bool aVisibility )
1084{
1086 return;
1087
1088 int row = m_netsTable->GetRowByNetcode( aNetCode );
1089
1090 if( row >= 0 )
1091 {
1093 m_netsGrid->ForceRefresh();
1094 }
1095}
1096
1097
1099{
1100 return aBoardItem->Type() == PCB_NETINFO_T;
1101}
1102
1103
1104bool APPEARANCE_CONTROLS::doesBoardItemNeedRebuild( std::vector<BOARD_ITEM*>& aBoardItems )
1105{
1106 bool rebuild = std::any_of( aBoardItems.begin(), aBoardItems.end(),
1107 []( const BOARD_ITEM* a )
1108 {
1109 return a->Type() == PCB_NETINFO_T;
1110 } );
1111
1112 return rebuild;
1113}
1114
1115
1117{
1118 if( doesBoardItemNeedRebuild( aItem ) )
1120}
1121
1122
1123void APPEARANCE_CONTROLS::OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1124{
1125 if( doesBoardItemNeedRebuild( aItems ) )
1127}
1128
1129
1131{
1132 if( doesBoardItemNeedRebuild( aItem ) )
1134}
1135
1136
1137void APPEARANCE_CONTROLS::OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1138{
1139 if( doesBoardItemNeedRebuild( aItems ) )
1141}
1142
1143
1145{
1146 if( doesBoardItemNeedRebuild( aItem ) )
1148}
1149
1150
1151void APPEARANCE_CONTROLS::OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems )
1152{
1153 if( doesBoardItemNeedRebuild( aItems ) )
1155}
1156
1157
1159 std::vector<BOARD_ITEM*>& aAddedItems,
1160 std::vector<BOARD_ITEM*>& aRemovedItems,
1161 std::vector<BOARD_ITEM*>& aChangedItems )
1162{
1163 if( doesBoardItemNeedRebuild( aAddedItems ) || doesBoardItemNeedRebuild( aRemovedItems )
1164 || doesBoardItemNeedRebuild( aChangedItems ) )
1165 {
1167 }
1168}
1169
1170
1172{
1173 m_netsGrid->ClearSelection();
1174
1175 Freeze();
1176 rebuildNets();
1177 Thaw();
1178}
1179
1180
1182{
1185}
1186
1187
1189{
1190 // This is essentially a list of hacks because DarkMode isn't yet implemented inside
1191 // wxWidgets.
1192 //
1193 // The individual wxPanels, COLOR_SWATCHes and GRID_CELL_COLOR_RENDERERs should really be
1194 // overriding some virtual method or responding to some wxWidgets event so that the parent
1195 // doesn't have to know what it contains. But, that's not where we are, so... :shrug:
1196
1197 m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
1198
1199 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1200
1201 for( wxSizerItem* child : m_layersOuterSizer->GetChildren() )
1202 {
1203 if( child && child->GetWindow() )
1204 child->GetWindow()->SetBackgroundColour( m_layerPanelColour );
1205 }
1206
1207 // Easier than calling OnDarkModeToggle on all the GRID_CELL_COLOR_RENDERERs:
1208 m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
1211
1212 for( const std::pair<const wxString, APPEARANCE_SETTING*>& pair : m_netclassSettingsMap )
1213 {
1214 if( pair.second->ctl_color )
1215 pair.second->ctl_color->OnDarkModeToggle();
1216 }
1217
1218 OnLayerChanged(); // Update selected highlighting
1219}
1220
1221
1223{
1224 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1225 {
1226 setting->ctl_panel->SetBackgroundColour( m_layerPanelColour );
1227 setting->ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
1228 }
1229
1230 wxChar r = m_layerPanelColour.Red();
1231 wxChar g = m_layerPanelColour.Green();
1232 wxChar b = m_layerPanelColour.Blue();
1233
1234 if( r < 240 || g < 240 || b < 240 )
1235 {
1236 r = wxChar( std::min( (int) r + 15, 255 ) );
1237 g = wxChar( std::min( (int) g + 15, 255 ) );
1238 b = wxChar( std::min( (int) b + 15, 255 ) );
1239 }
1240 else
1241 {
1242 r = wxChar( std::max( (int) r - 15, 0 ) );
1243 g = wxChar( std::max( (int) g - 15, 0 ) );
1244 b = wxChar( std::max( (int) b - 15, 0 ) );
1245 }
1246
1247 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1248
1249 if( !m_layerSettingsMap.count( current ) )
1250 {
1251 wxASSERT( m_layerSettingsMap.count( F_Cu ) );
1252 current = F_Cu;
1253 }
1254
1255 APPEARANCE_SETTING* newSetting = m_layerSettingsMap[ current ];
1256
1257 newSetting->ctl_panel->SetBackgroundColour( wxColour( r, g, b ) );
1259
1260 Refresh();
1261}
1262
1263
1264void APPEARANCE_CONTROLS::SetLayerVisible( int aLayer, bool isVisible )
1265{
1266 LSET visible = getVisibleLayers();
1267 PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
1268
1269 if( visible.test( layer ) == isVisible )
1270 return;
1271
1272 visible.set( layer, isVisible );
1273 setVisibleLayers( visible );
1274
1275 m_frame->GetCanvas()->GetView()->SetLayerVisible( layer, isVisible );
1276
1278}
1279
1280
1282{
1283 if( m_objectSettingsMap.count( aLayer ) )
1284 {
1285 APPEARANCE_SETTING* setting = m_objectSettingsMap.at( aLayer );
1286
1287 if( setting->can_control_visibility )
1288 setting->ctl_visibility->SetValue( isVisible );
1289 }
1290
1291 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
1292
1294
1295 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1297}
1298
1299
1301{
1302 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1303
1304 if( m_isFpEditor )
1305 {
1306 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1307 view->SetLayerVisible( layer, aLayers.Contains( layer ) );
1308 }
1309 else
1310 {
1311 m_frame->GetBoard()->SetVisibleLayers( aLayers );
1312
1313 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as
1314 // they won't be found in the view layer's itemset for repainting.
1316 []( KIGFX::VIEW_ITEM* aItem ) -> bool
1317 {
1318 // Items rendered to composite layers (such as LAYER_PAD_TH) must be redrawn
1319 // whether they're optionally flashed or not (as the layer being hidden/shown
1320 // might be the last layer the item is visible on).
1321 return dynamic_cast<PCB_VIA*>( aItem ) || dynamic_cast<PAD*>( aItem );
1322 } );
1323
1325 }
1326}
1327
1328
1330{
1331 if( m_isFpEditor )
1332 {
1333 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1334
1335 for( size_t i = 0; i < GAL_LAYER_INDEX( LAYER_ZONE_START ); i++ )
1336 view->SetLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ), aLayers.test( i ) );
1337 }
1338 else
1339 {
1340 // Ratsnest visibility is controlled by the ratsnest option, and not by the preset
1343
1345 m_frame->GetBoard()->SetVisibleElements( aLayers );
1346
1348 }
1349}
1350
1351
1353{
1354 if( m_isFpEditor )
1355 {
1356 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1357 LSET set;
1358
1359 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1360 set.set( layer, view->IsLayerVisible( layer ) );
1361
1362 return set;
1363 }
1364 else
1365 {
1366 return m_frame->GetBoard()->GetVisibleLayers();
1367 }
1368}
1369
1370
1372{
1373 if( m_isFpEditor )
1374 {
1375 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1376 GAL_SET set;
1377 set.reset();
1378
1379 for( size_t i = 0; i < set.size(); i++ )
1380 set.set( i, view->IsLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ) ) );
1381
1382 return set;
1383 }
1384 else
1385 {
1386 return m_frame->GetBoard()->GetVisibleElements();
1387 }
1388}
1389
1390
1392{
1393 const PCB_DISPLAY_OPTIONS& options = m_frame->GetDisplayOptions();
1394
1395 switch( options.m_ContrastModeDisplay )
1396 {
1397 case HIGH_CONTRAST_MODE::NORMAL: m_rbHighContrastNormal->SetValue( true ); break;
1398 case HIGH_CONTRAST_MODE::DIMMED: m_rbHighContrastDim->SetValue( true ); break;
1399 case HIGH_CONTRAST_MODE::HIDDEN: m_rbHighContrastOff->SetValue( true ); break;
1400 }
1401
1402 switch( options.m_NetColorMode )
1403 {
1404 case NET_COLOR_MODE::ALL: m_rbNetColorAll->SetValue( true ); break;
1405 case NET_COLOR_MODE::RATSNEST: m_rbNetColorRatsnest->SetValue( true ); break;
1406 case NET_COLOR_MODE::OFF: m_rbNetColorOff->SetValue( true ); break;
1407 }
1408
1409 m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
1410
1411 if( !m_isFpEditor )
1412 {
1414 {
1415 if( !cfg->m_Display.m_ShowGlobalRatsnest )
1416 m_rbRatsnestNone->SetValue( true );
1417 else if( cfg->m_Display.m_RatsnestMode == RATSNEST_MODE::ALL )
1418 m_rbRatsnestAllLayers->SetValue( true );
1419 else
1420 m_rbRatsnestVisLayers->SetValue( true );
1421
1422 wxASSERT( m_objectSettingsMap.count( LAYER_RATSNEST ) );
1424 ratsnest->ctl_visibility->SetValue( cfg->m_Display.m_ShowGlobalRatsnest );
1425 }
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 : { presetAllLayers,
1474 presetBack,
1476 {
1477 m_layerPresets[preset.name] = preset;
1478 m_layerPresets[preset.name].readOnly = true;
1479 }
1480}
1481
1482
1483void APPEARANCE_CONTROLS::ApplyLayerPreset( const wxString& aPresetName )
1484{
1485 updateLayerPresetSelection( aPresetName );
1486
1487 wxCommandEvent dummy;
1489}
1490
1491
1493{
1494 if( m_layerPresets.count( aPreset.name ) )
1496 else
1497 m_currentPreset = nullptr;
1498
1500 : nullptr;
1501
1503 doApplyLayerPreset( aPreset );
1504}
1505
1506
1507std::vector<VIEWPORT> APPEARANCE_CONTROLS::GetUserViewports() const
1508{
1509 std::vector<VIEWPORT> ret;
1510
1511 for( const std::pair<const wxString, VIEWPORT>& pair : m_viewports )
1512 ret.emplace_back( pair.second );
1513
1514 return ret;
1515}
1516
1517
1518void APPEARANCE_CONTROLS::SetUserViewports( std::vector<VIEWPORT>& aViewportList )
1519{
1520 m_viewports.clear();
1521
1522 for( const VIEWPORT& viewport : aViewportList )
1523 {
1524 if( m_viewports.count( viewport.name ) )
1525 continue;
1526
1527 m_viewports[viewport.name] = viewport;
1528
1529 m_viewportMRU.Add( viewport.name );
1530 }
1531
1533}
1534
1535
1536void APPEARANCE_CONTROLS::ApplyViewport( const wxString& aViewportName )
1537{
1538 updateViewportSelection( aViewportName );
1539
1540 wxCommandEvent dummy;
1542}
1543
1544
1546{
1547 updateViewportSelection( aViewport.name );
1548 doApplyViewport( aViewport );
1549}
1550
1551
1553{
1554 BOARD* board = m_frame->GetBoard();
1555 LSET enabled = board->GetEnabledLayers();
1556 LSET visible = getVisibleLayers();
1557
1559 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
1560 bool readOnly = theme->IsReadOnly();
1561
1562 FOOTPRINT_EDITOR_SETTINGS* cfg = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" );
1563
1564#ifdef __WXMAC__
1565 wxSizerItem* m_windowLayersSizerItem = m_panelLayersSizer->GetItem( m_windowLayers );
1566 m_windowLayersSizerItem->SetFlag( m_windowLayersSizerItem->GetFlag() & ~wxTOP );
1567#endif
1568
1569 auto appendLayer =
1570 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1571 {
1572 int layer = aSetting->id;
1573
1574 wxPanel* panel = new wxPanel( m_windowLayers, layer );
1575 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
1576 panel->SetSizer( sizer );
1577
1578 panel->SetBackgroundColour( m_layerPanelColour );
1579
1580 aSetting->visible = visible[layer];
1581
1582 // TODO(JE) consider restyling this indicator
1583 INDICATOR_ICON* indicator = new INDICATOR_ICON( panel, *m_iconProvider,
1585
1586 COLOR_SWATCH* swatch = new COLOR_SWATCH( panel, COLOR4D::UNSPECIFIED, layer, bgColor,
1587 theme->GetColor( layer ), SWATCH_SMALL );
1588 swatch->SetToolTip( _( "Double click or middle click for color change, right click for menu" ) );
1589
1590 BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( panel, layer,
1591 KiBitmapBundle( BITMAPS::visibility ),
1592 KiBitmapBundle( BITMAPS::visibility_off ),
1593 aSetting->visible );
1594 btn_visible->SetToolTip( _( "Show or hide this layer" ) );
1595
1596 wxStaticText* label = new wxStaticText( panel, layer, aSetting->label );
1597 label->Wrap( -1 );
1598 label->SetToolTip( aSetting->tooltip );
1599
1600 sizer->AddSpacer( 1 );
1601 sizer->Add( indicator, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1602 sizer->AddSpacer( 5 );
1603 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1604 sizer->AddSpacer( 6 );
1605 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1606 sizer->AddSpacer( 5 );
1607 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxTOP, 2 );
1608
1609 m_layersOuterSizer->Add( panel, 0, wxEXPAND, 0 );
1610
1611 aSetting->ctl_panel = panel;
1612 aSetting->ctl_indicator = indicator;
1613 aSetting->ctl_visibility = btn_visible;
1614 aSetting->ctl_color = swatch;
1615 aSetting->ctl_text = label;
1616
1617 panel->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1618 indicator->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1619 swatch->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1620 label->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerLeftClick, this );
1621
1622 btn_visible->Bind( TOGGLE_CHANGED,
1623 [&]( wxCommandEvent& aEvent )
1624 {
1625 wxObject* btn = aEvent.GetEventObject();
1626 int layerId = static_cast<wxWindow*>( btn )->GetId();
1627
1628 onLayerVisibilityToggled( static_cast<PCB_LAYER_ID>( layerId ) );
1629 } );
1630
1631 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged, this );
1632 swatch->SetReadOnlyCallback( std::bind( &APPEARANCE_CONTROLS::onReadOnlySwatch, this ) );
1633 swatch->SetReadOnly( readOnly );
1634
1635 panel->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1636 indicator->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1637 swatch->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1638 btn_visible->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1639 label->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1640 };
1641
1642 auto updateLayer =
1643 [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1644 {
1645 int layer = aSetting->id;
1646 aSetting->visible = visible[layer];
1647 aSetting->ctl_panel->Show();
1648 aSetting->ctl_panel->SetId( layer );
1649 aSetting->ctl_indicator->SetWindowID( layer );
1650 aSetting->ctl_color->SetWindowID( layer );
1651 aSetting->ctl_color->SetSwatchColor( theme->GetColor( layer ), false );
1652 aSetting->ctl_visibility->SetWindowID( layer );
1653 aSetting->ctl_text->SetLabelText( aSetting->label );
1654 aSetting->ctl_text->SetId( layer );
1655 aSetting->ctl_text->SetToolTip( aSetting->tooltip );
1656 };
1657
1658 // technical layers are shown in this order:
1659 // Because they are static, wxGetTranslation must be explicitly
1660 // called for tooltips.
1661 static const struct {
1662 PCB_LAYER_ID layerId;
1663 wxString tooltip;
1664 } non_cu_seq[] = {
1665 { F_Adhes, _HKI( "Adhesive on board's front" ) },
1666 { B_Adhes, _HKI( "Adhesive on board's back" ) },
1667 { F_Paste, _HKI( "Solder paste on board's front" ) },
1668 { B_Paste, _HKI( "Solder paste on board's back" ) },
1669 { F_SilkS, _HKI( "Silkscreen on board's front" ) },
1670 { B_SilkS, _HKI( "Silkscreen on board's back" ) },
1671 { F_Mask, _HKI( "Solder mask on board's front" ) },
1672 { B_Mask, _HKI( "Solder mask on board's back" ) },
1673 { Dwgs_User, _HKI( "Explanatory drawings" ) },
1674 { Cmts_User, _HKI( "Explanatory comments" ) },
1675 { Eco1_User, _HKI( "User defined meaning" ) },
1676 { Eco2_User, _HKI( "User defined meaning" ) },
1677 { Edge_Cuts, _HKI( "Board's perimeter definition" ) },
1678 { Margin, _HKI( "Board's edge setback outline" ) },
1679 { F_CrtYd, _HKI( "Footprint courtyards on board's front" ) },
1680 { B_CrtYd, _HKI( "Footprint courtyards on board's back" ) },
1681 { F_Fab, _HKI( "Footprint assembly on board's front" ) },
1682 { B_Fab, _HKI( "Footprint assembly on board's back" ) },
1683 { User_1, _HKI( "User defined layer 1" ) },
1684 { User_2, _HKI( "User defined layer 2" ) },
1685 { User_3, _HKI( "User defined layer 3" ) },
1686 { User_4, _HKI( "User defined layer 4" ) },
1687 { User_5, _HKI( "User defined layer 5" ) },
1688 { User_6, _HKI( "User defined layer 6" ) },
1689 { User_7, _HKI( "User defined layer 7" ) },
1690 { User_8, _HKI( "User defined layer 8" ) },
1691 { User_9, _HKI( "User defined layer 9" ) },
1692 { User_10, _HKI( "User defined layer 10" ) },
1693 { User_11, _HKI( "User defined layer 11" ) },
1694 { User_12, _HKI( "User defined layer 12" ) },
1695 { User_13, _HKI( "User defined layer 13" ) },
1696 { User_14, _HKI( "User defined layer 14" ) },
1697 { User_15, _HKI( "User defined layer 15" ) },
1698 { User_16, _HKI( "User defined layer 16" ) },
1699 { User_17, _HKI( "User defined layer 17" ) },
1700 { User_18, _HKI( "User defined layer 18" ) },
1701 { User_19, _HKI( "User defined layer 19" ) },
1702 { User_20, _HKI( "User defined layer 20" ) },
1703 { User_21, _HKI( "User defined layer 21" ) },
1704 { User_22, _HKI( "User defined layer 22" ) },
1705 { User_23, _HKI( "User defined layer 23" ) },
1706 { User_24, _HKI( "User defined layer 24" ) },
1707 { User_25, _HKI( "User defined layer 25" ) },
1708 { User_26, _HKI( "User defined layer 26" ) },
1709 { User_27, _HKI( "User defined layer 27" ) },
1710 { User_28, _HKI( "User defined layer 28" ) },
1711 { User_29, _HKI( "User defined layer 29" ) },
1712 { User_30, _HKI( "User defined layer 30" ) },
1713 { User_31, _HKI( "User defined layer 31" ) },
1714 { User_32, _HKI( "User defined layer 32" ) },
1715 { User_33, _HKI( "User defined layer 33" ) },
1716 { User_34, _HKI( "User defined layer 34" ) },
1717 { User_35, _HKI( "User defined layer 35" ) },
1718 { User_36, _HKI( "User defined layer 36" ) },
1719 { User_37, _HKI( "User defined layer 37" ) },
1720 { User_38, _HKI( "User defined layer 38" ) },
1721 { User_39, _HKI( "User defined layer 39" ) },
1722 { User_40, _HKI( "User defined layer 40" ) },
1723 { User_41, _HKI( "User defined layer 41" ) },
1724 { User_42, _HKI( "User defined layer 42" ) },
1725 { User_43, _HKI( "User defined layer 43" ) },
1726 { User_44, _HKI( "User defined layer 44" ) },
1727 { User_45, _HKI( "User defined layer 45" ) },
1728 };
1729
1730 // There is a spacer added to the end of the list that we need to remove and re-add
1731 // after possibly adding additional layers
1732 if( m_layersOuterSizer->GetItemCount() > 0 )
1733 {
1734 m_layersOuterSizer->Detach( m_layersOuterSizer->GetItemCount() - 1 );
1735 }
1736 // Otherwise, this is the first time we are updating the control, so we need to attach
1737 // the handler
1738 else
1739 {
1740 // Add right click handling to show the context menu when clicking to the free area in
1741 // m_windowLayers (below the layer items)
1742 m_windowLayers->Bind( wxEVT_RIGHT_DOWN, &APPEARANCE_CONTROLS::rightClickHandler, this );
1743 }
1744
1745 std::size_t total_layers = enabled.CuStack().size();
1746
1747 for( const auto& entry : non_cu_seq )
1748 {
1749 if( enabled[entry.layerId] )
1750 total_layers++;
1751 }
1752
1753 // Adds layers to the panel until we have enough to hold our total count
1754 while( total_layers > m_layerSettings.size() )
1755 m_layerSettings.push_back( std::make_unique<APPEARANCE_SETTING>() );
1756
1757 // We never delete layers from the panel, only hide them. This saves us
1758 // having to recreate the (possibly) later with minimal overhead
1759 for( std::size_t ii = total_layers; ii < m_layerSettings.size(); ++ii )
1760 {
1761 if( m_layerSettings[ii]->ctl_panel )
1762 m_layerSettings[ii]->ctl_panel->Show( false );
1763 }
1764
1765 auto layer_it = m_layerSettings.begin();
1766
1767 // show all coppers first, with front on top, back on bottom, then technical layers
1768 for( PCB_LAYER_ID layer : enabled.CuStack() )
1769 {
1770 wxString dsc;
1771
1772 switch( layer )
1773 {
1774 case F_Cu: dsc = _( "Front copper layer" ); break;
1775 case B_Cu: dsc = _( "Back copper layer" ); break;
1776 default: dsc = _( "Inner copper layer" ); break;
1777 }
1778
1779 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1780
1781 setting->label = board->GetLayerName( layer );
1782 setting->id = layer;
1783 setting->tooltip = dsc;
1784
1785 if( setting->ctl_panel == nullptr )
1786 appendLayer( setting );
1787 else
1788 updateLayer( setting );
1789
1790 m_layerSettingsMap[layer] = setting.get();
1791
1793 {
1794 setting->ctl_text->Disable();
1795 setting->ctl_color->SetToolTip( wxEmptyString );
1796 }
1797
1798 ++layer_it;
1799 }
1800
1801 for( const auto& entry : non_cu_seq )
1802 {
1803 PCB_LAYER_ID layer = entry.layerId;
1804
1805 if( !enabled[layer] )
1806 continue;
1807
1808 std::unique_ptr<APPEARANCE_SETTING>& setting = *layer_it;
1809
1810 if( m_isFpEditor )
1811 {
1812 wxString canonicalName = LSET::Name( static_cast<PCB_LAYER_ID>( layer ) );
1813
1814 if( cfg->m_DesignSettings.m_UserLayerNames.contains( canonicalName.ToStdString() ) )
1815 setting->label = cfg->m_DesignSettings.m_UserLayerNames[canonicalName.ToStdString()];
1816 else
1817 setting->label = board->GetStandardLayerName( layer );
1818 }
1819 else
1820 {
1821 setting->label = board->GetLayerName( layer );
1822 }
1823
1824 setting->id = layer;
1825 // Because non_cu_seq is created static, we must explicitly call wxGetTranslation for
1826 // texts which are internationalized
1827 setting->tooltip = wxGetTranslation( entry.tooltip );
1828
1829 if( setting->ctl_panel == nullptr )
1830 appendLayer( setting );
1831 else
1832 updateLayer( setting );
1833
1834 m_layerSettingsMap[layer] = setting.get();
1835
1837 {
1838 setting->ctl_text->Disable();
1839 setting->ctl_color->SetToolTip( wxEmptyString );
1840 }
1841
1842 ++layer_it;
1843 }
1844
1845 m_layersOuterSizer->AddSpacer( 10 );
1846 m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1847 m_windowLayers->FitInside(); // Updates virtual size to fit subwindows, also auto-layouts.
1848
1849 m_paneLayerDisplayOptions->SetLabel( _( "Layer Display Options" ) );
1850
1852 wxString msg;
1853
1854 if( hotkey )
1855 msg = wxString::Format( _( "Inactive layers (%s):" ), KeyNameFromKeyCode( hotkey ) );
1856 else
1857 msg = _( "Inactive layers:" );
1858
1859 m_inactiveLayersLabel->SetLabel( msg );
1860
1861 m_rbHighContrastNormal->SetLabel( _( "Normal" ) );
1862 m_rbHighContrastNormal->SetToolTip( _( "Inactive layers will be shown in full color" ) );
1863
1864 m_rbHighContrastDim->SetLabel( _( "Dim" ) );
1865 m_rbHighContrastDim->SetToolTip( _( "Inactive layers will be dimmed" ) );
1866
1867 m_rbHighContrastOff->SetLabel( _( "Hide" ) );
1868 m_rbHighContrastOff->SetToolTip( _( "Inactive layers will be hidden" ) );
1869
1870 m_cbFlipBoard->SetLabel( _( "Flip board view" ) );
1871}
1872
1873
1875{
1876 delete m_layerContextMenu;
1877 m_layerContextMenu = new wxMenu;
1878
1879 KIUI::AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_COPPER_LAYERS, _( "Show All Copper Layers" ),
1880 KiBitmap( BITMAPS::show_all_copper_layers ) );
1881 KIUI::AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_COPPER_LAYERS, _( "Hide All Copper Layers" ),
1882 KiBitmap( BITMAPS::show_no_copper_layers ) );
1883
1884 m_layerContextMenu->AppendSeparator();
1885
1886 KIUI::AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_BUT_ACTIVE, _( "Hide All Layers But Active" ),
1887 KiBitmap( BITMAPS::select_w_layer ) );
1888
1889 m_layerContextMenu->AppendSeparator();
1890
1891 KIUI::AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_NON_COPPER, _( "Show All Non Copper Layers" ),
1892 KiBitmap( BITMAPS::show_no_copper_layers ) );
1893
1894 KIUI::AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_NON_COPPER, _( "Hide All Non Copper Layers" ),
1895 KiBitmap( BITMAPS::show_all_copper_layers ) );
1896
1897 m_layerContextMenu->AppendSeparator();
1898
1900 KiBitmap( BITMAPS::show_all_layers ) );
1901
1903 KiBitmap( BITMAPS::show_no_layers ) );
1904
1905 m_layerContextMenu->AppendSeparator();
1906
1907 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT_ASSEMBLY, _( "Show Only Front Assembly Layers" ),
1908 KiBitmap( BITMAPS::show_front_assembly_layers ) );
1909
1910 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT, _( "Show Only Front Layers" ),
1911 KiBitmap( BITMAPS::show_all_front_layers ) );
1912
1913 // Only show the internal layer option if internal layers are enabled
1914 if( m_frame->GetBoard()->GetCopperLayerCount() > 2 )
1915 {
1916 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_INNER_COPPER, _( "Show Only Inner Layers" ),
1917 KiBitmap( BITMAPS::show_all_copper_layers ) );
1918 }
1919
1920 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_BACK, _( "Show Only Back Layers" ),
1921 KiBitmap( BITMAPS::show_all_back_layers ) );
1922
1923 KIUI::AddMenuItem( m_layerContextMenu, ID_PRESET_BACK_ASSEMBLY, _( "Show Only Back Assembly Layers" ),
1924 KiBitmap( BITMAPS::show_back_assembly_layers ) );
1925}
1926
1927
1928void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent )
1929{
1930 BOARD* board = m_frame->GetBoard();
1931 LSET visible = getVisibleLayers();
1932
1933 PCB_LAYER_ID current = m_frame->GetActiveLayer();
1934
1935 // The new preset. We keep the visibility state of objects:
1936 LAYER_PRESET preset;
1938
1939 switch( aEvent.GetId() )
1940 {
1942 preset.layers = presetNoLayers.layers;
1943 ApplyLayerPreset( preset );
1944 return;
1945
1947 preset.layers = presetAllLayers.layers;
1948 ApplyLayerPreset( preset );
1949 return;
1950
1952 visible |= presetAllCopper.layers;
1953 setVisibleLayers( visible );
1954 break;
1955
1957 preset.layers = presetNoLayers.layers | LSET( { current } );
1958 ApplyLayerPreset( preset );
1959 break;
1960
1962 visible &= ~presetAllCopper.layers;
1963
1964 if( !visible.test( current ) && visible.count() > 0 )
1965 m_frame->SetActiveLayer( *visible.Seq().begin() );
1966
1967 setVisibleLayers( visible );
1968 break;
1969
1971 visible &= presetAllCopper.layers;
1972
1973 if( !visible.test( current ) && visible.count() > 0 )
1974 m_frame->SetActiveLayer( *visible.Seq().begin() );
1975
1976 setVisibleLayers( visible );
1977 break;
1978
1980 visible |= ~presetAllCopper.layers;
1981
1982 setVisibleLayers( visible );
1983 break;
1984
1987 ApplyLayerPreset( preset );
1988 return;
1989
1990 case ID_PRESET_FRONT:
1991 preset.layers = presetFront.layers;
1992 ApplyLayerPreset( preset );
1993 return;
1994
1997 ApplyLayerPreset( preset );
1998 return;
1999
2000 case ID_PRESET_BACK:
2001 preset.layers = presetBack.layers;
2002 ApplyLayerPreset( preset );
2003 return;
2004
2007 ApplyLayerPreset( preset );
2008 return;
2009 }
2010
2013
2014 if( !m_isFpEditor )
2016
2018}
2019
2020
2022{
2023 return m_notebook->GetSelection();
2024}
2025
2026
2028{
2029 size_t max = m_notebook->GetPageCount();
2030
2031 if( aTab >= 0 && static_cast<size_t>( aTab ) < max )
2032 m_notebook->SetSelection( aTab );
2033}
2034
2035
2037{
2039 bool readOnly = theme->IsReadOnly();
2040 LSET visible = getVisibleLayers();
2041 GAL_SET objects = getVisibleObjects();
2042
2043 Freeze();
2044
2045 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
2046 {
2047 int layer = setting->id;
2048
2049 if( setting->ctl_visibility )
2050 setting->ctl_visibility->SetValue( visible[layer] );
2051
2052 if( setting->ctl_color )
2053 {
2054 const COLOR4D& color = theme->GetColor( layer );
2055 setting->ctl_color->SetSwatchColor( color, false );
2056 setting->ctl_color->SetReadOnly( readOnly );
2057 }
2058 }
2059
2060 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2061 {
2062 GAL_LAYER_ID layer = static_cast<GAL_LAYER_ID>( setting->id );
2063
2064 if( setting->ctl_visibility )
2065 setting->ctl_visibility->SetValue( objects.Contains( layer ) );
2066
2067 if( setting->ctl_color )
2068 {
2069 const COLOR4D& color = theme->GetColor( layer );
2070 setting->ctl_color->SetSwatchColor( color, false );
2071 setting->ctl_color->SetReadOnly( readOnly );
2072 }
2073 }
2074
2075 // Update indicators and panel background colors
2077
2078 Thaw();
2079
2080 m_windowLayers->Refresh();
2081}
2082
2083
2084void APPEARANCE_CONTROLS::onLayerLeftClick( wxMouseEvent& aEvent )
2085{
2086 wxWindow* eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() );
2087
2088 PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() );
2089
2091 return;
2092
2093 m_frame->SetActiveLayer( layer );
2094 passOnFocus();
2095}
2096
2097
2098void APPEARANCE_CONTROLS::rightClickHandler( wxMouseEvent& aEvent )
2099{
2100 wxASSERT( m_layerContextMenu );
2101 PopupMenu( m_layerContextMenu );
2102 passOnFocus();
2103};
2104
2105
2107{
2108 LSET visibleLayers = getVisibleLayers();
2109
2110 visibleLayers.set( aLayer, !visibleLayers.test( aLayer ) );
2111 setVisibleLayers( visibleLayers );
2112 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, visibleLayers.test( aLayer ) );
2113
2116}
2117
2118
2119void APPEARANCE_CONTROLS::onObjectVisibilityChanged( GAL_LAYER_ID aLayer, bool isVisible, bool isFinal )
2120{
2121 // Special-case controls
2122 switch( aLayer )
2123 {
2124 case LAYER_RATSNEST:
2125 {
2126 // don't touch the layers. ratsnest is enabled on per-item basis.
2128 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, true );
2129
2131 {
2133 m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
2136 }
2137
2138 break;
2139 }
2140
2141 case LAYER_GRID:
2142 m_frame->SetGridVisibility( isVisible );
2145 break;
2146
2147 case LAYER_FP_TEXT:
2148 // Because Footprint Text is a meta-control that also can disable values/references,
2149 // drag them along here so that the user is less likely to be confused.
2150 if( isFinal )
2151 {
2152 // Should only trigger when you actually click the Footprint Text button
2153 // Otherwise it goes into infinite recursive loop with the following case section
2155 onObjectVisibilityChanged( LAYER_FP_VALUES, isVisible, false );
2156 m_objectSettingsMap[LAYER_FP_REFERENCES]->ctl_visibility->SetValue( isVisible );
2157 m_objectSettingsMap[LAYER_FP_VALUES]->ctl_visibility->SetValue( isVisible );
2158 }
2159 break;
2160
2162 case LAYER_FP_VALUES:
2163 // In case that user changes Footprint Value/References when the Footprint Text
2164 // meta-control is disabled, we should put it back on.
2165 if( isVisible )
2166 {
2167 onObjectVisibilityChanged( LAYER_FP_TEXT, isVisible, false );
2168 m_objectSettingsMap[LAYER_FP_TEXT]->ctl_visibility->SetValue( isVisible );
2169 }
2170 break;
2171
2172 default:
2173 break;
2174 }
2175
2176 GAL_SET visible = getVisibleObjects();
2177
2178 if( visible.Contains( aLayer ) != isVisible )
2179 {
2180 visible.set( aLayer, isVisible );
2181 setVisibleObjects( visible );
2182 m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
2184 }
2185
2186 if( isFinal )
2187 {
2189 passOnFocus();
2190 }
2191}
2192
2193
2195{
2197 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2198 GAL_SET visible = getVisibleObjects();
2199 int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
2200 int labelWidth = 0;
2201
2202 int btnWidth = KiBitmapBundle( BITMAPS::visibility ).GetPreferredLogicalSizeFor( m_windowObjects ).x;
2203
2204 m_objectSettings.clear();
2205 m_objectsOuterSizer->Clear( true );
2206 m_objectsOuterSizer->AddSpacer( 5 );
2207
2208 auto appendObject =
2209 [&]( const std::unique_ptr<APPEARANCE_SETTING>& aSetting )
2210 {
2211 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2212 int layer = aSetting->id;
2213
2214 aSetting->visible = visible.Contains( ToGalLayer( layer ) );
2215 COLOR4D color = theme->GetColor( layer );
2216 COLOR4D defColor = theme->GetDefaultColor( layer );
2217
2218 if( color != COLOR4D::UNSPECIFIED )
2219 {
2220 COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer,
2221 bgColor, defColor, SWATCH_SMALL );
2222 swatch->SetToolTip( _( "Left double click or middle click for color change, "
2223 "right click for menu" ) );
2224
2225 sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
2226 aSetting->ctl_color = swatch;
2227
2228 swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged, this );
2229
2230 swatch->SetReadOnlyCallback( std::bind( &APPEARANCE_CONTROLS::onReadOnlySwatch, this ) );
2231 }
2232 else
2233 {
2234 sizer->AddSpacer( swatchWidth );
2235 }
2236
2237 BITMAP_TOGGLE* btn_visible = nullptr;
2238 wxString tip;
2239
2240 if( aSetting->can_control_visibility )
2241 {
2242 btn_visible = new BITMAP_TOGGLE( m_windowObjects, layer,
2243 KiBitmapBundle( BITMAPS::visibility ),
2244 KiBitmapBundle( BITMAPS::visibility_off ),
2245 aSetting->visible );
2246
2247 tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
2248 btn_visible->SetToolTip( tip );
2249
2250 aSetting->ctl_visibility = btn_visible;
2251
2252 btn_visible->Bind( TOGGLE_CHANGED,
2253 [&]( wxCommandEvent& aEvent )
2254 {
2255 int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
2256 bool isVisible = aEvent.GetInt();
2257 onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
2258 } );
2259 }
2260
2261 sizer->AddSpacer( 5 );
2262
2263 wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label );
2264 label->Wrap( -1 );
2265 label->SetToolTip( aSetting->tooltip );
2266
2267 if( aSetting->can_control_opacity )
2268 {
2269 label->SetMinSize( wxSize( labelWidth, -1 ) );
2270#ifdef __WXMAC__
2271 if( btn_visible )
2272 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2273 else
2274 sizer->AddSpacer( btnWidth );
2275
2276 sizer->AddSpacer( 5 );
2277 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
2278#else
2279 if( btn_visible )
2280 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2281 else
2282 sizer->AddSpacer( btnWidth );
2283
2284 sizer->AddSpacer( 5 );
2285 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2286#endif
2287
2288 wxSlider* slider = new wxSlider( m_windowObjects, wxID_ANY, 100, 0, 100,
2289 wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL );
2290#ifdef __WXMAC__
2291 slider->SetMinSize( wxSize( 80, 16 ) );
2292#else
2293 slider->SetMinSize( wxSize( 80, -1 ) );
2294#endif
2295
2296 tip.Printf( _( "Set opacity of %s" ), aSetting->label.Lower() );
2297 slider->SetToolTip( tip );
2298
2299 sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
2300 aSetting->ctl_opacity = slider;
2301
2302 auto opacitySliderHandler =
2303 [this, layer]( wxCommandEvent& aEvent )
2304 {
2305 wxSlider* ctrl = static_cast<wxSlider*>( aEvent.GetEventObject() );
2306 int value = ctrl->GetValue();
2307 onObjectOpacitySlider( layer, value / 100.0f );
2308 };
2309
2310 slider->Bind( wxEVT_SCROLL_CHANGED, opacitySliderHandler );
2311 slider->Bind( wxEVT_SCROLL_THUMBTRACK, opacitySliderHandler );
2312 slider->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
2313 }
2314 else
2315 {
2316 if( btn_visible )
2317 sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
2318 else
2319 sizer->AddSpacer( btnWidth );
2320
2321 sizer->AddSpacer( 5 );
2322 sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
2323 }
2324
2325 aSetting->ctl_text = label;
2326 m_objectsOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
2327
2328 if( !aSetting->can_control_opacity )
2329 m_objectsOuterSizer->AddSpacer( 2 );
2330 };
2331
2332 for( const APPEARANCE_SETTING& s_setting : s_objectSettings )
2333 {
2334 if( m_isFpEditor && !s_allowedInFpEditor.count( s_setting.id ) )
2335 continue;
2336
2337 m_objectSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>( s_setting ) );
2338
2339 std::unique_ptr<APPEARANCE_SETTING>& setting = m_objectSettings.back();
2340
2341 // Because s_render_rows is created static, we must explicitly call wxGetTranslation
2342 // for texts which are internationalized (tool tips and item names)
2343 setting->tooltip = wxGetTranslation( s_setting.tooltip );
2344 setting->label = wxGetTranslation( s_setting.label );
2345
2346 if( setting->can_control_opacity )
2347 {
2348 int width = m_windowObjects->GetTextExtent( setting->label ).x + 5;
2349 labelWidth = std::max( labelWidth, width );
2350 }
2351
2352 if( !s_setting.spacer )
2353 m_objectSettingsMap[ToGalLayer( setting->id )] = setting.get();
2354 }
2355
2356 for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2357 {
2358 if( setting->spacer )
2359 m_objectsOuterSizer->AddSpacer( m_pointSize / 2 );
2360 else
2361 appendObject( setting );
2362 }
2363
2364 m_objectsOuterSizer->Layout();
2365}
2366
2367
2369{
2370 GAL_SET visible = getVisibleObjects();
2371
2373
2374 for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2375 {
2376 if( setting->spacer )
2377 continue;
2378
2379 GAL_LAYER_ID layer = ToGalLayer( setting->id );
2380
2381 if( setting->ctl_visibility )
2382 setting->ctl_visibility->SetValue( visible.Contains( layer ) );
2383
2384 if( setting->ctl_color )
2385 {
2386 COLOR4D color = m_frame->GetColorSettings()->GetColor( setting->id );
2387 setting->ctl_color->SetSwatchColor( color, false );
2388 }
2389 }
2390
2391 wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
2397
2398 m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
2399 m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
2400 m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
2401 m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
2402 m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_ImageOpacity * 100 );
2403 m_objectSettingsMap[LAYER_FILLED_SHAPES]->ctl_opacity->SetValue( opts.m_FilledShapeOpacity * 100 );
2404}
2405
2406
2407void APPEARANCE_CONTROLS::buildNetClassMenu( wxMenu& aMenu, bool isDefaultClass,
2408 const wxString& aName )
2409{
2410 BOARD* board = m_frame->GetBoard();
2411 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
2412
2413 if( !isDefaultClass)
2414 {
2415 aMenu.Append( new wxMenuItem( &aMenu, ID_SET_NET_COLOR, _( "Set Netclass Color" ),
2416 wxEmptyString, wxITEM_NORMAL ) );
2417
2418 wxMenuItem* schematicColor = new wxMenuItem( &aMenu, ID_USE_SCHEMATIC_NET_COLOR,
2419 _( "Use Color from Schematic" ),
2420 wxEmptyString, wxITEM_NORMAL );
2421 std::shared_ptr<NETCLASS> nc = netSettings->GetNetClassByName( aName );
2422 const KIGFX::COLOR4D ncColor = nc->GetSchematicColor();
2423 aMenu.Append( schematicColor );
2424
2425 if( ncColor == KIGFX::COLOR4D::UNSPECIFIED )
2426 schematicColor->Enable( false );
2427
2428 aMenu.Append( new wxMenuItem( &aMenu, ID_CLEAR_NET_COLOR, _( "Clear Netclass Color" ),
2429 wxEmptyString, wxITEM_NORMAL ) );
2430 aMenu.AppendSeparator();
2431 }
2432
2433 wxString name = UnescapeString( aName );
2434
2435 aMenu.Append( new wxMenuItem( &aMenu, ID_HIGHLIGHT_NET,
2436 wxString::Format( _( "Highlight Nets in %s" ), name ),
2437 wxEmptyString, wxITEM_NORMAL ) );
2438 aMenu.Append( new wxMenuItem( &aMenu, ID_SELECT_NET,
2439 wxString::Format( _( "Select Tracks and Vias in %s" ), name ),
2440 wxEmptyString, wxITEM_NORMAL ) );
2441 aMenu.Append( new wxMenuItem( &aMenu, ID_DESELECT_NET,
2442 wxString::Format( _( "Unselect Tracks and Vias in %s" ), name ),
2443 wxEmptyString, wxITEM_NORMAL ) );
2444
2445 aMenu.AppendSeparator();
2446
2447 aMenu.Append( new wxMenuItem( &aMenu, ID_SHOW_ALL_NETS, _( "Show All Netclasses" ),
2448 wxEmptyString, wxITEM_NORMAL ) );
2449 aMenu.Append( new wxMenuItem( &aMenu, ID_HIDE_OTHER_NETS, _( "Hide All Other Netclasses" ),
2450 wxEmptyString, wxITEM_NORMAL ) );
2451
2452 aMenu.Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::onNetclassContextMenu, this );
2453
2454}
2455
2456
2458{
2459 BOARD* board = m_frame->GetBoard();
2461 COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2462
2463 // If the board isn't fully loaded, we can't yet rebuild
2464 if( !board->GetProject() )
2465 return;
2466
2467 m_staticTextNets->SetLabel( _( "Nets" ) );
2468 m_staticTextNetClasses->SetLabel( _( "Net Classes" ) );
2469
2470 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
2471
2472 const std::set<wxString>& hiddenClasses = m_frame->Prj().GetLocalSettings().m_HiddenNetclasses;
2473
2474 m_netclassOuterSizer->Clear( true );
2475
2476 auto appendNetclass =
2477 [&]( int aId, const std::shared_ptr<NETCLASS>& aClass, bool isDefaultClass = false )
2478 {
2479 wxString name = aClass->GetName();
2480
2481 m_netclassSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>() );
2482 APPEARANCE_SETTING* setting = m_netclassSettings.back().get();
2483 m_netclassSettingsMap[name] = setting;
2484
2485 setting->ctl_panel = new wxPanel( m_netclassScrolledWindow, aId );
2486 wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2487 setting->ctl_panel->SetSizer( sizer );
2488
2489 COLOR4D color = netSettings->HasNetclass( name )
2490 ? netSettings->GetNetClassByName( name )->GetPcbColor()
2491 : COLOR4D::UNSPECIFIED;
2492
2493 setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, aId, bgColor,
2494 COLOR4D::UNSPECIFIED, SWATCH_SMALL );
2495 setting->ctl_color->SetToolTip( _( "Left double click or middle click for color "
2496 "change, right click for menu" ) );
2497
2498 setting->ctl_color->Bind( COLOR_SWATCH_CHANGED,
2500
2501 // Default netclass can't have an override color
2502 if( isDefaultClass )
2503 setting->ctl_color->Hide();
2504
2505 setting->ctl_visibility = new BITMAP_TOGGLE( setting->ctl_panel, aId,
2506 KiBitmapBundle( BITMAPS::visibility ),
2507 KiBitmapBundle( BITMAPS::visibility_off ),
2508 !hiddenClasses.count( name ) );
2509
2510 wxString tip;
2511 tip.Printf( _( "Show or hide ratsnest for nets in %s" ), name );
2512 setting->ctl_visibility->SetToolTip( tip );
2513
2514 setting->ctl_text = new wxStaticText( setting->ctl_panel, aId, name );
2515 setting->ctl_text->Wrap( -1 );
2516
2517 int flags = wxALIGN_CENTER_VERTICAL;
2518
2519 sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
2520 sizer->AddSpacer( 7 );
2521 sizer->Add( setting->ctl_visibility, 0, flags, 5 );
2522 sizer->AddSpacer( 3 );
2523 sizer->Add( setting->ctl_text, 1, flags, 5 );
2524
2525 m_netclassOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 5 );
2526 m_netclassOuterSizer->AddSpacer( 2 );
2527
2528 setting->ctl_visibility->Bind( TOGGLE_CHANGED,
2530 this );
2531
2532 auto menuHandler =
2533 [&, name, isDefaultClass]( wxMouseEvent& aEvent )
2534 {
2535 wxMenu menu;
2536 buildNetClassMenu( menu, isDefaultClass, name );
2537
2539 PopupMenu( &menu );
2540 };
2541
2542 setting->ctl_panel->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2543 setting->ctl_visibility->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2544 setting->ctl_color->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2545 setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2546 };
2547
2548 std::vector<wxString> names;
2549
2550 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
2551 names.emplace_back( name );
2552
2553 std::sort( names.begin(), names.end() );
2554
2555 m_netclassIdMap.clear();
2556
2557 int idx = wxID_HIGHEST;
2558
2559 m_netclassIdMap[idx] = netSettings->GetDefaultNetclass()->GetName();
2560 appendNetclass( idx++, netSettings->GetDefaultNetclass(), true );
2561
2562 for( const wxString& name : names )
2563 {
2564 m_netclassIdMap[idx] = name;
2565 appendNetclass( idx++, netSettings->GetNetclasses().at( name ) );
2566 }
2567
2568 int hotkey;
2569 wxString msg;
2570
2571 m_paneNetDisplayOptions->SetLabel( _( "Net Display Options" ) );
2572
2574
2575 if( hotkey )
2576 msg = wxString::Format( _( "Net colors (%s):" ), KeyNameFromKeyCode( hotkey ) );
2577 else
2578 msg = _( "Net colors:" );
2579
2580 m_txtNetDisplayTitle->SetLabel( msg );
2581 m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
2582
2583 m_rbNetColorAll->SetLabel( _( "All" ) );
2584 m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
2585
2586 m_rbNetColorRatsnest->SetLabel( _( "Ratsnest" ) );
2587 m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
2588
2589 m_rbNetColorOff->SetLabel( _( "None" ) );
2590 m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
2591
2593
2594 if( hotkey )
2595 msg = wxString::Format( _( "Ratsnest display (%s):" ), KeyNameFromKeyCode( hotkey ) );
2596 else
2597 msg = _( "Ratsnest display:" );
2598
2599 m_txtRatsnestVisibility->SetLabel( msg );
2600 m_txtRatsnestVisibility->SetToolTip( _( "Choose which ratsnest lines to display" ) );
2601
2602 m_rbRatsnestAllLayers->SetLabel( _( "All" ) );
2603 m_rbRatsnestAllLayers->SetToolTip( _( "Show ratsnest lines to items on all layers" ) );
2604
2605 m_rbRatsnestVisLayers->SetLabel( _( "Visible layers" ) );
2606 m_rbRatsnestVisLayers->SetToolTip( _( "Show ratsnest lines to items on visible layers" ) );
2607
2608 m_rbRatsnestNone->SetLabel( _( "None" ) );
2609 m_rbRatsnestNone->SetToolTip( _( "Hide all ratsnest lines" ) );
2610
2611 m_netclassOuterSizer->Layout();
2612
2614 m_panelNets->GetSizer()->Layout();
2615}
2616
2617
2619{
2620 m_viewportsLabel->SetLabel( wxString::Format( _( "Presets (%s+Tab):" ),
2622
2623 m_cbLayerPresets->Clear();
2624 m_presetMRU.clear();
2625
2626 // Build the layers preset list.
2627 // By default, the presetAllLayers will be selected
2628 int idx = 0;
2629 int default_idx = 0;
2630
2631 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2632 {
2633 const wxString translatedName = wxGetTranslation( pair.first );
2634 m_cbLayerPresets->Append( wxGetTranslation( translatedName ),
2635 static_cast<void*>( &pair.second ) );
2636 m_presetMRU.push_back( translatedName );
2637
2638 if( pair.first == presetAllLayers.name )
2639 default_idx = idx;
2640
2641 idx++;
2642 }
2643
2644 m_cbLayerPresets->Append( wxT( "---" ) );
2645 m_cbLayerPresets->Append( _( "Save preset..." ) );
2646 m_cbLayerPresets->Append( _( "Delete preset..." ) );
2647
2648 // At least the built-in presets should always be present
2649 wxASSERT( !m_layerPresets.empty() );
2650
2651 // Default preset: all layers
2652 m_cbLayerPresets->SetSelection( default_idx );
2654}
2655
2656
2658{
2659 LSET visibleLayers = getVisibleLayers();
2660 GAL_SET visibleObjects = getVisibleObjects();
2661 bool flipBoard = m_cbFlipBoard->GetValue();
2662
2663 auto it = std::find_if( m_layerPresets.begin(), m_layerPresets.end(),
2664 [&]( const std::pair<const wxString, LAYER_PRESET>& aPair )
2665 {
2666 return ( aPair.second.layers == visibleLayers
2667 && aPair.second.renderLayers == visibleObjects
2668 && aPair.second.flipBoard == flipBoard );
2669 } );
2670
2671 if( it != m_layerPresets.end() )
2672 {
2673 // Select the right m_cbLayersPresets item.
2674 // but these items are translated if they are predefined items.
2675 bool do_translate = it->second.readOnly;
2676 wxString text = do_translate ? wxGetTranslation( it->first ) : it->first;
2677
2678 m_cbLayerPresets->SetStringSelection( text );
2679 }
2680 else
2681 {
2682 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2683 }
2684
2685 m_currentPreset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );
2686}
2687
2688
2690{
2691 // look at m_layerPresets to know if aName is a read only preset, or a user preset.
2692 // Read only presets have translated names in UI, so we have to use
2693 // a translated name in UI selection.
2694 // But for a user preset name we should search for aName (not translated)
2695 wxString ui_label = aName;
2696
2697 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2698 {
2699 if( pair.first != aName )
2700 continue;
2701
2702 if( pair.second.readOnly == true )
2703 ui_label = wxGetTranslation( aName );
2704
2705 break;
2706 }
2707
2708 int idx = m_cbLayerPresets->FindString( ui_label );
2709
2710 if( idx >= 0 && m_cbLayerPresets->GetSelection() != idx )
2711 {
2712 m_cbLayerPresets->SetSelection( idx );
2713 m_currentPreset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( idx ) );
2714 }
2715 else if( idx < 0 )
2716 {
2717 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2718 }
2719}
2720
2721
2722void APPEARANCE_CONTROLS::onLayerPresetChanged( wxCommandEvent& aEvent )
2723{
2724 int count = m_cbLayerPresets->GetCount();
2725 int index = m_cbLayerPresets->GetSelection();
2726
2727 auto resetSelection =
2728 [&]()
2729 {
2730 if( m_currentPreset )
2731 m_cbLayerPresets->SetStringSelection( m_currentPreset->name );
2732 else
2733 m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 );
2734 };
2735
2736 if( index == count - 3 )
2737 {
2738 // Separator: reject the selection
2739 resetSelection();
2740 return;
2741 }
2742 else if( index == count - 2 )
2743 {
2744 // Save current state to new preset
2745 wxString name;
2746
2749
2750 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Layer preset name:" ),
2751 _( "Save Layer Preset" ), name );
2752
2753 if( dlg.ShowModal() != wxID_OK )
2754 {
2755 resetSelection();
2756 return;
2757 }
2758
2759 name = dlg.GetValue();
2760 bool exists = m_layerPresets.count( name );
2761
2762 if( !exists )
2763 {
2765 UNSELECTED_LAYER, m_cbFlipBoard->GetValue() );
2766 }
2767
2768 LAYER_PRESET* preset = &m_layerPresets[name];
2769
2770 if( !exists )
2771 {
2772 index = m_cbLayerPresets->Insert( name, index - 1, static_cast<void*>( preset ) );
2773 }
2774 else if( preset->readOnly )
2775 {
2776 wxMessageBox( _( "Default presets cannot be modified.\nPlease use a different name." ),
2777 _( "Error" ), wxOK | wxICON_ERROR, wxGetTopLevelParent( this ) );
2778 resetSelection();
2779 return;
2780 }
2781 else
2782 {
2783 // Ask the user if they want to overwrite the existing preset
2784 if( !IsOK( wxGetTopLevelParent( this ), _( "Overwrite existing preset?" ) ) )
2785 {
2786 resetSelection();
2787 return;
2788 }
2789
2790 preset->layers = getVisibleLayers();
2791 preset->renderLayers = getVisibleObjects();
2792 preset->flipBoard = m_cbFlipBoard->GetValue();
2793
2794 index = m_cbLayerPresets->FindString( name );
2795
2796 if( m_presetMRU.Index( name ) != wxNOT_FOUND )
2797 m_presetMRU.Remove( name );
2798 }
2799
2800 m_currentPreset = preset;
2801 m_cbLayerPresets->SetSelection( index );
2802 m_presetMRU.Insert( name, 0 );
2803
2804 return;
2805 }
2806 else if( index == count - 1 )
2807 {
2808 // Delete a preset
2809 wxArrayString headers;
2810 std::vector<wxArrayString> items;
2811
2812 headers.Add( _( "Presets" ) );
2813
2814 for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2815 {
2816 if( !pair.second.readOnly )
2817 {
2818 wxArrayString item;
2819 item.Add( pair.first );
2820 items.emplace_back( item );
2821 }
2822 }
2823
2824 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items );
2825 dlg.SetListLabel( _( "Select preset:" ) );
2826
2827 if( dlg.ShowModal() == wxID_OK )
2828 {
2829 wxString presetName = dlg.GetTextSelection();
2830 int idx = m_cbLayerPresets->FindString( presetName );
2831
2832 if( idx != wxNOT_FOUND )
2833 {
2834 m_layerPresets.erase( presetName );
2835
2836 m_cbLayerPresets->Delete( idx );
2837 m_currentPreset = nullptr;
2838 }
2839
2840 if( m_presetMRU.Index( presetName ) != wxNOT_FOUND )
2841 m_presetMRU.Remove( presetName );
2842 }
2843
2844 resetSelection();
2845 return;
2846 }
2847
2848 // Store the objects visibility settings if the presedt is not a user preset,
2849 // to be reused when selecting a new built-in layer preset, even if a previous
2850 // user preset has changed the object visibility
2852 {
2854 }
2855
2856 LAYER_PRESET* preset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( index ) );
2857 m_currentPreset = preset;
2858
2859 m_lastSelectedUserPreset = ( !preset || preset->readOnly ) ? nullptr : preset;
2860
2861 if( preset )
2862 {
2863 // Change board layers visibility, but do not change objects visibility
2864 LAYER_PRESET curr_layers_choice = *preset;
2865
2866 // For predefined presets that do not manage objects visibility, use
2867 // the objects visibility settings of the last used predefined preset.
2868 if( curr_layers_choice.readOnly )
2869 curr_layers_choice.renderLayers = m_lastBuiltinPreset.renderLayers;
2870
2871 doApplyLayerPreset( curr_layers_choice );
2872 }
2873
2874 if( !m_currentPreset->name.IsEmpty() )
2875 {
2876 const wxString translatedName = wxGetTranslation( m_currentPreset->name );
2877
2878 if( m_presetMRU.Index( translatedName ) != wxNOT_FOUND )
2879 m_presetMRU.Remove( translatedName );
2880
2881 m_presetMRU.Insert( translatedName, 0 );
2882 }
2883
2884 passOnFocus();
2885}
2886
2887
2889{
2890 BOARD* board = m_frame->GetBoard();
2892
2893 setVisibleLayers( aPreset.layers );
2895
2896 // If the preset doesn't have an explicit active layer to restore, we can at least
2897 // force the active layer to be something in the preset's layer set
2898 PCB_LAYER_ID activeLayer = UNSELECTED_LAYER;
2899
2900 if( aPreset.activeLayer != UNSELECTED_LAYER )
2901 activeLayer = aPreset.activeLayer;
2902 else if( aPreset.layers.any() && !aPreset.layers.test( m_frame->GetActiveLayer() ) )
2903 activeLayer = *aPreset.layers.Seq().begin();
2904
2905 LSET boardLayers = board->GetLayerSet();
2906
2907 if( activeLayer != UNSELECTED_LAYER && boardLayers.Contains( activeLayer ) )
2908 m_frame->SetActiveLayer( activeLayer );
2909
2910 if( !m_isFpEditor )
2912
2913 if( aPreset.flipBoard != view->IsMirroredX() )
2914 {
2915 view->SetMirror( !view->IsMirroredX(), view->IsMirroredY() );
2916 view->RecacheAllItems();
2917 }
2918
2920
2923}
2924
2925
2927{
2928 m_viewportsLabel->SetLabel( wxString::Format( _( "Viewports (%s+Tab):" ),
2930
2931 m_cbViewports->Clear();
2932
2933 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
2934 m_cbViewports->Append( pair.first, static_cast<void*>( &pair.second ) );
2935
2936 m_cbViewports->Append( wxT( "---" ) );
2937 m_cbViewports->Append( _( "Save viewport..." ) );
2938 m_cbViewports->Append( _( "Delete viewport..." ) );
2939
2940 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2941 m_lastSelectedViewport = nullptr;
2942}
2943
2944
2946{
2947 int idx = m_cbViewports->FindString( aName );
2948
2949 if( idx >= 0 && idx < (int)m_cbViewports->GetCount() - 3 /* separator */ )
2950 {
2951 m_cbViewports->SetSelection( idx );
2952 m_lastSelectedViewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( idx ) );
2953 }
2954 else if( idx < 0 )
2955 {
2956 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 ); // separator
2957 m_lastSelectedViewport = nullptr;
2958 }
2959}
2960
2961
2962void APPEARANCE_CONTROLS::onViewportChanged( wxCommandEvent& aEvent )
2963{
2964 int count = m_cbViewports->GetCount();
2965 int index = m_cbViewports->GetSelection();
2966
2967 if( index >= 0 && index < count - 3 )
2968 {
2969 VIEWPORT* viewport = static_cast<VIEWPORT*>( m_cbViewports->GetClientData( index ) );
2970
2971 wxCHECK( viewport, /* void */ );
2972
2973 doApplyViewport( *viewport );
2974
2975 if( !viewport->name.IsEmpty() )
2976 {
2977 if( m_viewportMRU.Index( viewport->name ) != wxNOT_FOUND )
2978 m_viewportMRU.Remove( viewport->name );
2979
2980 m_viewportMRU.Insert( viewport->name, 0 );
2981 }
2982 }
2983 else if( index == count - 2 )
2984 {
2985 // Save current state to new preset
2986 wxString name;
2987
2988 wxTextEntryDialog dlg( wxGetTopLevelParent( this ), _( "Viewport name:" ), _( "Save Viewport" ), name );
2989
2990 if( dlg.ShowModal() != wxID_OK )
2991 {
2993 m_cbViewports->SetStringSelection( m_lastSelectedViewport->name );
2994 else
2995 m_cbViewports->SetSelection( m_cbViewports->GetCount() - 3 );
2996
2997 return;
2998 }
2999
3000 name = dlg.GetValue();
3001 bool exists = m_viewports.count( name );
3002
3003 if( !exists )
3004 {
3006
3007 index = m_cbViewports->Insert( name, index-1, static_cast<void*>( &m_viewports[name] ) );
3008 }
3009 else
3010 {
3012 index = m_cbViewports->FindString( name );
3013
3014 if( m_viewportMRU.Index( name ) != wxNOT_FOUND )
3015 m_viewportMRU.Remove( name );
3016 }
3017
3018 m_cbViewports->SetSelection( index );
3019 m_viewportMRU.Insert( name, 0 );
3020
3021 return;
3022 }
3023 else if( index == count - 1 )
3024 {
3025 // Delete an existing viewport
3026 wxArrayString headers;
3027 std::vector<wxArrayString> items;
3028
3029 headers.Add( _( "Viewports" ) );
3030
3031 for( std::pair<const wxString, VIEWPORT>& pair : m_viewports )
3032 {
3033 wxArrayString item;
3034 item.Add( pair.first );
3035 items.emplace_back( item );
3036 }
3037
3038 EDA_LIST_DIALOG dlg( m_frame, _( "Delete Viewport" ), headers, items );
3039 dlg.SetListLabel( _( "Select viewport:" ) );
3040
3041 if( dlg.ShowModal() == wxID_OK )
3042 {
3043 wxString viewportName = dlg.GetTextSelection();
3044 int idx = m_cbViewports->FindString( viewportName );
3045
3046 if( idx != wxNOT_FOUND )
3047 {
3048 m_viewports.erase( viewportName );
3049 m_cbViewports->Delete( idx );
3050 }
3051
3052 if( m_viewportMRU.Index( viewportName ) != wxNOT_FOUND )
3053 m_viewportMRU.Remove( viewportName );
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
3293 if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
3294 {
3296 editframe->SetElementVisibility( LAYER_RATSNEST, cfg->m_Display.m_ShowGlobalRatsnest );
3297
3298 editframe->OnDisplayOptionsChanged();
3299 editframe->GetCanvas()->RedrawRatsnest();
3300 editframe->GetCanvas()->Refresh();
3301 }
3302
3303 passOnFocus();
3304}
3305
3306
3308{
3309 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
3311 static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
3312
3313 BOARD* board = m_frame->GetBoard();
3314 std::shared_ptr<NET_SETTINGS>& netSettings = board->GetDesignSettings().m_NetSettings;
3315 APPEARANCE_SETTING* setting = nullptr;
3316
3318
3319 if( it != m_netclassSettingsMap.end() )
3320 setting = it->second;
3321
3322 auto runOnNetsOfClass =
3323 [&]( const wxString& netClassName, std::function<void( NETINFO_ITEM* )> aFunction )
3324 {
3325 for( NETINFO_ITEM* net : board->GetNetInfo() )
3326 {
3327 if( net->GetNetClass()->ContainsNetclassWithName( netClassName ) )
3328 aFunction( net );
3329 }
3330 };
3331
3332 switch( aEvent.GetId() )
3333 {
3334 case ID_SET_NET_COLOR:
3335 {
3336 if( setting )
3337 {
3338 setting->ctl_color->GetNewSwatchColor();
3339
3340 COLOR4D color = setting->ctl_color->GetSwatchColor();
3341
3342 if( color != COLOR4D::UNSPECIFIED )
3343 {
3344 netSettings->GetNetClassByName( m_contextMenuNetclass )->SetPcbColor( color );
3345 netSettings->RecomputeEffectiveNetclasses();
3346 }
3347
3348 view->UpdateAllLayersColor();
3349 }
3350
3351 break;
3352 }
3353
3354 case ID_CLEAR_NET_COLOR:
3355 {
3356 if( setting )
3357 {
3358 setting->ctl_color->SetSwatchColor( COLOR4D( 0, 0, 0, 0 ), true );
3359
3360 netSettings->GetNetClassByName( m_contextMenuNetclass )->SetPcbColor( COLOR4D::UNSPECIFIED );
3361 netSettings->RecomputeEffectiveNetclasses();
3362
3363 view->UpdateAllLayersColor();
3364 }
3365
3366 break;
3367 }
3368
3370 {
3371 if( setting )
3372 {
3373 std::shared_ptr<NETCLASS> nc = netSettings->GetNetClassByName( m_contextMenuNetclass );
3374 const KIGFX::COLOR4D ncColor = nc->GetSchematicColor();
3375
3376 setting->ctl_color->SetSwatchColor( ncColor, true );
3377
3378 netSettings->GetNetClassByName( m_contextMenuNetclass )->SetPcbColor( ncColor );
3379 netSettings->RecomputeEffectiveNetclasses();
3380
3381 view->UpdateAllLayersColor();
3382 }
3383
3384 break;
3385 }
3386
3387 case ID_HIGHLIGHT_NET:
3388 {
3389 if( !m_contextMenuNetclass.IsEmpty() )
3390 {
3391 runOnNetsOfClass( m_contextMenuNetclass,
3392 [&]( NETINFO_ITEM* aItem )
3393 {
3394 static bool first = true;
3395 int code = aItem->GetNetCode();
3396
3397 if( first )
3398 {
3399 board->SetHighLightNet( code );
3400 rs->SetHighlight( true, code );
3401 first = false;
3402 }
3403 else
3404 {
3405 board->SetHighLightNet( code, true );
3406 rs->SetHighlight( true, code, true );
3407 }
3408 } );
3409
3410 view->UpdateAllLayersColor();
3411 board->HighLightON();
3412 }
3413
3414 break;
3415 }
3416
3417 case ID_SELECT_NET:
3418 case ID_DESELECT_NET:
3419 {
3420 if( !m_contextMenuNetclass.IsEmpty() )
3421 {
3422 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
3425
3426 runOnNetsOfClass( m_contextMenuNetclass,
3427 [&]( NETINFO_ITEM* aItem )
3428 {
3429 toolMgr->RunAction( action, aItem->GetNetCode() );
3430 } );
3431 }
3432 break;
3433 }
3434
3435
3436 case ID_SHOW_ALL_NETS:
3437 {
3439 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3440 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( true );
3441
3442 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
3443 {
3444 showNetclass( name );
3445
3446 if( m_netclassSettingsMap.count( name ) )
3447 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( true );
3448 }
3449
3450 break;
3451 }
3452
3453 case ID_HIDE_OTHER_NETS:
3454 {
3455 bool showDefault = m_contextMenuNetclass == NETCLASS::Default;
3456 showNetclass( NETCLASS::Default, showDefault );
3457 wxASSERT( m_netclassSettingsMap.count( NETCLASS::Default ) );
3458 m_netclassSettingsMap.at( NETCLASS::Default )->ctl_visibility->SetValue( showDefault );
3459
3460 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
3461 {
3462 bool show = ( name == m_contextMenuNetclass );
3463
3464 showNetclass( name, show );
3465
3466 if( m_netclassSettingsMap.count( name ) )
3467 m_netclassSettingsMap.at( name )->ctl_visibility->SetValue( show );
3468 }
3469
3470 break;
3471 }
3472
3473 default:
3474 break;
3475 }
3476
3479
3480 m_contextMenuNetclass.clear();
3481}
3482
3483
3485{
3486 m_focusOwner->SetFocus();
3487}
3488
3489
3491{
3492 WX_INFOBAR* infobar = m_frame->GetInfoBar();
3493
3494 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Open Preferences" ), wxEmptyString );
3495
3496 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
3497 [&]( wxHyperlinkEvent& aEvent )
3498 {
3499 m_frame->ShowPreferences( wxEmptyString, wxEmptyString );
3500 } ) );
3501
3502 infobar->RemoveAllButtons();
3503 infobar->AddButton( button );
3504 infobar->AddCloseButton();
3505
3506 infobar->ShowMessageFor( _( "The current color theme is read-only. Create a new theme in Preferences to "
3507 "enable color editing." ),
3508 10000, wxICON_INFORMATION );
3509}
3510
3511
3513{
3514 m_paneLayerDisplayOptions->Refresh();
3515}
3516
3517
3519{
3521}
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:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:934
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:939
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Return an "English Standard" name of a PCB layer when given aLayerNumber.
Definition: board.h:839
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: board.h:639
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:2781
GAL_SET GetVisibleElements() const
Return a set of all the element categories that are visible.
Definition: board.cpp:967
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition: board.cpp:2842
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:921
int GetCopperLayerCount() const
Definition: board.cpp:859
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:979
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:680
PROJECT * GetProject() const
Definition: board.h:538
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:1024
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:907
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition: board.cpp:2855
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:946
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:110
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:393
bool Contains(GAL_LAYER_ID aPos)
Definition: layer_ids.h:427
GAL_SET & set()
Definition: layer_ids.h:409
static GAL_SET DefaultVisible()
Definition: lset.cpp:776
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:97
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:80
std::set< int > & GetHiddenNets()
Definition: pcb_painter.h:140
std::map< int, KIGFX::COLOR4D > & GetNetColorMap()
Definition: pcb_painter.h:138
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:66
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:557
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:530
void SetViewport(const BOX2D &aViewport)
Set the visible area of the VIEW.
Definition: view.cpp:542
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:775
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:400
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition: view.h:250
void RecacheAllItems()
Rebuild GAL display lists.
Definition: view.cpp:1451
bool IsMirroredY() const
Return true if view is flipped across the Y axis.
Definition: view.h:258
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:754
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:422
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:220
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:639
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:1571
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:705
static const LSET & BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
Definition: lset.cpp:553
static const LSET & BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:712
static const LSET & FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
Definition: lset.cpp:546
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:246
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:296
static const LSET & ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:726
static const LSET & AllLayersMask()
Definition: lset.cpp:624
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition: lset.cpp:591
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:560
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
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:566
static TOOL_ACTION hideNetInRatsnest
Definition: pcb_actions.h:573
static TOOL_ACTION showNetInRatsnest
Definition: pcb_actions.h:574
static TOOL_ACTION showNetInspector
Definition: pcb_actions.h:452
static TOOL_ACTION ratsnestModeCycle
Definition: pcb_actions.h:317
static TOOL_ACTION netColorModeCycle
Definition: pcb_actions.h:316
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
Definition: pcb_actions.h:82
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:374
static TOOL_ACTION deselectNet
Remove all connections belonging to a single net from the active selection.
Definition: pcb_actions.h:85
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual void OnDisplayOptionsChanged()
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual PCB_LAYER_ID GetActiveLayer() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetDrawBgColor(const COLOR4D &aColor) override
BOARD * GetBoard() const
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Update the current display options.
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
double m_TrackOpacity
Opacity override for all tracks.
double m_FilledShapeOpacity
Opacity override for graphic shapes.
double m_ZoneOpacity
Opacity override for filled zone areas.
double m_ImageOpacity
Opacity override for user images.
double m_PadOpacity
Opacity override for SMD pads and PTHs.
double m_ViaOpacity
Opacity override for all types of via.
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
The main frame for Pcbnew.
void ReCreateLayerBox(bool aForceResizeToolbar=true)
Recreate the layer box by clearing the old list and building a new one from the new layer names and c...
The project local settings are things that are attached to a particular project, but also might be pa...
std::set< wxString > m_HiddenNetclasses
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:210
Icon provider for the "standard" row indicators, for example in layer selection lists.
@ OFF
Row "off" or "deselected".
@ ON
Row "on" or "selected".
void SaveColorSettings(COLOR_SETTINGS *aSettings, const std::string &aNamespace="")
Safely save a COLOR_SETTINGS to disk, preserving any changes outside the given namespace.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Represent a single user action.
Definition: tool_action.h: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:273
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:252
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:371
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:142
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: wx_infobar.cpp:327
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: wx_infobar.cpp:361
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:251
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:372
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition: layer_ids.h:841
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:665
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_BOARD_OUTLINE_AREA
PCB board outline.
Definition: layer_ids.h:317
@ 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:328
@ 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:362
#define VIA_COPPER_LAYER_FOR(boardLayer)
Definition: layer_ids.h:361
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:359
#define PAD_COPPER_LAYER_FOR(boardLayer)
Definition: layer_ids.h:360
#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:355
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:744
@ 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...
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