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