KiCad PCB EDA Suite
appearance_controls.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
5  * Copyright (C) 2020 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>
25 #include <dialog_helpers.h>
26 #include <footprint_edit_frame.h>
27 #include <menus_helpers.h>
28 #include <pcb_display_options.h>
29 #include <pcb_edit_frame.h>
30 #include <pcb_painter.h>
31 #include <pcbnew_settings.h>
33 #include <tool/tool_manager.h>
34 #include <tools/pcb_actions.h>
35 #include <widgets/bitmap_button.h>
36 #include <widgets/bitmap_toggle.h>
38 #include <widgets/color_swatch.h>
42 #include <widgets/indicator_icon.h>
43 #include <widgets/infobar.h>
44 #include <widgets/wx_grid.h>
45 #include <wx/hyperlink.h>
46 #include <wx/statline.h>
47 
48 
49 NET_GRID_TABLE::NET_GRID_TABLE( PCB_BASE_FRAME* aFrame, wxColor aBackgroundColor ) :
50  wxGridTableBase(),
51  m_frame( aFrame )
52 {
53  m_defaultAttr = new wxGridCellAttr;
54  m_defaultAttr->SetBackgroundColour( aBackgroundColor );
55 
56  m_labelAttr = new wxGridCellAttr;
57  m_labelAttr->SetRenderer( new GRID_CELL_ESCAPED_TEXT_RENDERER );
58  m_labelAttr->SetBackgroundColour( aBackgroundColor );
59 }
60 
61 
63 {
64  m_defaultAttr->DecRef();
65  m_labelAttr->DecRef();
66 }
67 
68 
69 wxGridCellAttr* NET_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
70 {
71  switch( aCol )
72  {
73  case COL_COLOR:
74  m_defaultAttr->IncRef();
75  return m_defaultAttr;
76 
77  case COL_VISIBILITY:
78  m_defaultAttr->IncRef();
79  return m_defaultAttr;
80 
81  case COL_LABEL:
82  m_labelAttr->IncRef();
83  return m_labelAttr;
84 
85  default:
86  wxFAIL;
87  return nullptr;
88  }
89 }
90 
91 
92 wxString NET_GRID_TABLE::GetValue( int aRow, int aCol )
93 {
94  wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
95 
96  switch( aCol )
97  {
98  case COL_COLOR:
99  return m_nets[aRow].color.ToWxString( wxC2S_CSS_SYNTAX );
100 
101  case COL_VISIBILITY:
102  return m_nets[aRow].visible ? "1" : "0";
103 
104  case COL_LABEL:
105  return m_nets[aRow].name;
106 
107  default:
108  return wxEmptyString;
109  }
110 }
111 
112 
113 void NET_GRID_TABLE::SetValue( int aRow, int aCol, const wxString& aValue )
114 {
115  wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
116 
117  NET_GRID_ENTRY& net = m_nets[aRow];
118 
119  switch( aCol )
120  {
121  case COL_COLOR:
122  net.color.SetFromWxString( aValue );
123  updateNetColor( net );
124  break;
125 
126  case COL_VISIBILITY:
127  net.visible = ( aValue != "0" );
128  updateNetVisibility( net );
129  break;
130 
131  case COL_LABEL:
132  net.name = aValue;
133  break;
134 
135  default:
136  break;
137  }
138 }
139 
140 
141 wxString NET_GRID_TABLE::GetTypeName( int aRow, int aCol )
142 {
143  switch( aCol )
144  {
145  case COL_COLOR:
146  return wxT( "COLOR4D" );
147 
148  case COL_VISIBILITY:
149  return wxGRID_VALUE_BOOL;
150 
151  case COL_LABEL:
152  default:
153  return wxGRID_VALUE_STRING;
154  }
155 }
156 
157 
158 bool 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 
167 void 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;
173  updateNetVisibility( m_nets[aRow] );
174 }
175 
176 
177 void* 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 
187 void 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  if( GetView() )
197  {
198  wxGridTableMessage msg( this, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES );
199  GetView()->ProcessTableMessage( msg );
200  }
201 }
202 
203 
205 {
206  wxASSERT( static_cast<size_t>( aRow ) < m_nets.size() );
207  return m_nets[aRow];
208 }
209 
210 
211 int NET_GRID_TABLE::GetRowByNetcode( int aCode ) const
212 {
213  auto it = std::find_if( m_nets.cbegin(), m_nets.cend(),
214  [aCode]( const NET_GRID_ENTRY& aEntry )
215  {
216  return aEntry.code == aCode;
217  } );
218 
219  if( it == m_nets.cend() )
220  return -1;
221 
222  return std::distance( m_nets.cbegin(), it );
223 }
224 
225 
227 {
228  BOARD* board = m_frame->GetBoard();
229  const NETNAMES_MAP& nets = board->GetNetInfo().NetsByName();
230 
231  KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
233 
234  std::set<int>& hiddenNets = rs->GetHiddenNets();
235  std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
236 
237  int deleted = m_nets.size();
238  m_nets.clear();
239 
240  if( GetView() )
241  {
242  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, deleted );
243  GetView()->ProcessTableMessage( msg );
244  }
245 
246  for( const std::pair<const wxString, NETINFO_ITEM*>& pair : nets )
247  {
248  int netCode = pair.second->GetNetCode();
249 
250  if( netCode > 0 && !pair.first.StartsWith( "unconnected-(" ) )
251  {
252  COLOR4D color = netColors.count( netCode ) ? netColors.at( netCode ) :
253  COLOR4D::UNSPECIFIED;
254 
255  bool visible = hiddenNets.count( netCode ) == 0;
256 
257  m_nets.emplace_back( NET_GRID_ENTRY( netCode, pair.first, color, visible ) );
258  }
259  }
260 
261  // TODO(JE) move to ::Compare so we can re-sort easily
262  std::sort( m_nets.begin(), m_nets.end(),
263  []( const NET_GRID_ENTRY& a, const NET_GRID_ENTRY& b )
264  {
265  return a.name < b.name;
266  } );
267 
268  if( GetView() )
269  {
270  wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_nets.size() );
271  GetView()->ProcessTableMessage( msg );
272  }
273 }
274 
275 
277 {
278  for( NET_GRID_ENTRY& net : m_nets )
279  {
280  net.visible = true;
281  updateNetVisibility( net );
282  }
283 
284  if( GetView() )
285  GetView()->ForceRefresh();
286 }
287 
288 
290 {
291  for( NET_GRID_ENTRY& net : m_nets )
292  {
293  net.visible = ( net.code == aNet.code );
294  updateNetVisibility( net );
295  }
296 
297  if( GetView() )
298  GetView()->ForceRefresh();
299 }
300 
301 
303 {
305  m_frame->GetToolManager()->RunAction( action, true, aNet.code );
306 }
307 
308 
310 {
311  KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
313 
314  std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
315 
316  if( aNet.color != COLOR4D::UNSPECIFIED )
317  netColors[aNet.code] = aNet.color;
318  else
319  netColors.erase( aNet.code );
320 
323  m_frame->GetCanvas()->Refresh();
324 }
325 
326 
329 
330 #define RR APPEARANCE_CONTROLS::APPEARANCE_SETTING // Render Row abbreviation to reduce source width
331 
332  // text id tooltip opacity slider
333  RR( _( "Tracks" ), LAYER_TRACKS, _( "Show tracks" ), true ),
334  RR( _( "Vias" ), LAYER_VIAS, _( "Show all vias" ), true ),
335  RR( _( "Pads" ), LAYER_PADS, _( "Show all pads" ), true ),
336  RR( _( "Zones" ), LAYER_ZONES, _( "Show copper zones" ), true ),
337  RR(),
338  RR( _( "Footprints Front" ), LAYER_MOD_FR, _( "Show footprints that are on board's front" ) ),
339  RR( _( "Footprints Back" ), LAYER_MOD_BK, _( "Show footprints that are on board's back" ) ),
340  RR( _( "Through-hole Pads" ),LAYER_PADS_TH, _( "Show through-hole pads" ) ),
341  RR( _( "Values" ), LAYER_MOD_VALUES, _( "Show footprint values" ) ),
342  RR( _( "References" ), LAYER_MOD_REFERENCES, _( "Show footprint references" ) ),
343  RR( _( "Footprint Text" ), LAYER_MOD_TEXT_FR, _( "Show all footprint text" ) ),
344  RR( _( "Hidden Text" ), LAYER_MOD_TEXT_INVISIBLE, _( "Show footprint text marked as invisible" ) ),
345  RR(),
346  RR(),
347  RR( _( "Ratsnest" ), LAYER_RATSNEST, _( "Show unconnected nets as a ratsnest") ),
348  RR( _( "No-Connects" ), LAYER_NO_CONNECTS, _( "Show a marker on pads which have no net connected" ) ),
349  RR( _( "DRC Warnings" ), LAYER_DRC_WARNING, _( "DRC violations with a Warning severity" ) ),
350  RR( _( "DRC Errors" ), LAYER_DRC_ERROR, _( "DRC violations with an Error severity" ) ),
351  RR( _( "DRC Exclusions" ), LAYER_DRC_EXCLUSION, _( "DRC violations which have been individually excluded" ) ),
352  RR( _( "Anchors" ), LAYER_ANCHOR, _( "Show footprint and text origins as a cross" ) ),
353  RR( _( "Drawing Sheet" ), LAYER_DRAWINGSHEET, _( "Show drawing sheet borders and title block" ) ),
354  RR( _( "Grid" ), LAYER_GRID, _( "Show the (x,y) grid dots" ) )
355 };
356 
358 static std::set<int> s_allowedInFpEditor =
359  {
360  LAYER_TRACKS,
361  LAYER_VIAS,
362  LAYER_PADS,
363  LAYER_ZONES,
368  LAYER_GRID
369  };
370 
371 // These are the built-in layer presets that cannot be deleted
372 
374 
376 
377 LAYER_PRESET APPEARANCE_CONTROLS::presetAllCopper( _( "All Copper Layers" ),
378  LSET::AllCuMask().set( Edge_Cuts ) );
379 
380 LAYER_PRESET APPEARANCE_CONTROLS::presetInnerCopper( _( "Inner Copper Layers" ),
381  LSET::InternalCuMask().set( Edge_Cuts ) );
382 
384  LSET::FrontMask().set( Edge_Cuts ) );
385 
388 
390  LSET::BackMask().set( Edge_Cuts ) );
391 
394 
395 
397  bool aFpEditorMode ) :
398  APPEARANCE_CONTROLS_BASE( aParent ),
399  m_frame( aParent ),
400  m_focusOwner( aFocusOwner ),
401  m_board( nullptr ),
402  m_isFpEditor( aFpEditorMode ),
403  m_currentPreset( nullptr ),
404  m_lastSelectedUserPreset( nullptr ),
405  m_layerContextMenu( nullptr )
406 {
407  int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x;
408  m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize );
409  int pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
410  int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
411 
412  m_layerPanelColour = m_panelLayers->GetBackgroundColour().ChangeLightness( 110 );
413 
414  m_layersOuterSizer = new wxBoxSizer( wxVERTICAL );
415  m_windowLayers->SetSizer( m_layersOuterSizer );
416  m_windowLayers->SetScrollRate( 0, 5 );
417  m_windowLayers->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
418 
419  m_objectsOuterSizer = new wxBoxSizer( wxVERTICAL );
421  m_windowObjects->SetScrollRate( 0, 5 );
422  m_windowObjects->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
423 
424  createControls();
425 
428 
431 
432  m_txtNetFilter->SetHint( _( "Filter nets" ) );
433 
434  if( screenHeight <= 900 && pointSize >= indicatorSize )
435  pointSize = pointSize * 8 / 10;
436 
437  m_pointSize = pointSize;
438  wxFont font = m_notebook->GetFont();
439 
440 #ifdef __WXMAC__
441  font.SetPointSize( m_pointSize );
442  m_notebook->SetFont( font );
443 #endif
444 
445  auto setHighContrastMode =
446  [&]( HIGH_CONTRAST_MODE aMode )
447  {
449  opts.m_ContrastModeDisplay = aMode;
450 
451  m_frame->SetDisplayOptions( opts );
452  passOnFocus();
453  };
454 
455  m_rbHighContrastNormal->Bind( wxEVT_RADIOBUTTON,
456  [=]( wxCommandEvent& aEvent )
457  {
458  setHighContrastMode( HIGH_CONTRAST_MODE::NORMAL );
459  } );
460 
461  m_rbHighContrastDim->Bind( wxEVT_RADIOBUTTON,
462  [=]( wxCommandEvent& aEvent )
463  {
464  setHighContrastMode( HIGH_CONTRAST_MODE::DIMMED );
465  } );
466 
467  m_rbHighContrastOff->Bind( wxEVT_RADIOBUTTON,
468  [=]( wxCommandEvent& aEvent )
469  {
470  setHighContrastMode( HIGH_CONTRAST_MODE::HIDDEN );
471  } );
472 
473  m_cbLayerPresets->Bind( wxEVT_CHOICE, &APPEARANCE_CONTROLS::onLayerPresetChanged, this );
474 
475  m_btnNetInspector->Bind( wxEVT_BUTTON,
476  [&]( wxCommandEvent& aEvent )
477  {
479  passOnFocus();
480  } );
481 
482  m_btnConfigureNetClasses->Bind( wxEVT_BUTTON,
483  [&]( wxCommandEvent& aEvent )
484  {
485  // This panel should only be visible in the PCB_EDIT_FRAME anyway
486  if( PCB_EDIT_FRAME* editframe = dynamic_cast<PCB_EDIT_FRAME*>( m_frame ) )
487  editframe->ShowBoardSetupDialog( _( "Net Classes" ) );
488 
489  passOnFocus();
490  } );
491 
492  m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
493  m_cbFlipBoard->Bind( wxEVT_CHECKBOX,
494  [&]( wxCommandEvent& aEvent )
495  {
497  } );
498 
501 
502  m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor );
503 
504  // TODO(JE) Update background color of swatch renderer when theme changes
505  m_netsGrid->RegisterDataType( wxT( "COLOR4D" ),
508 
509  m_netsTable = new NET_GRID_TABLE( m_frame, m_panelNets->GetBackgroundColour() );
510  m_netsGrid->SetTable( m_netsTable, true );
512 
513  m_netsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
514  m_netsGrid->SetSelectionForeground( m_netsGrid->GetDefaultCellTextColour() );
515  m_netsGrid->SetSelectionBackground( m_panelNets->GetBackgroundColour() );
516 
517  const int cellPadding = 6;
518 #ifdef __WXMAC__
519  const int rowHeightPadding = 5;
520 #else
521  const int rowHeightPadding = 3;
522 #endif
523 
524  wxSize size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU );
525  m_netsGrid->SetColSize( NET_GRID_TABLE::COL_COLOR, size.x + cellPadding );
526 
527  size = KiBitmap( visibility_xpm ).GetSize();
528  m_netsGrid->SetColSize( NET_GRID_TABLE::COL_VISIBILITY, size.x + cellPadding );
529 
530  m_netsGrid->SetDefaultCellFont( font );
531  m_netsGrid->SetDefaultRowSize( font.GetPixelSize().y + rowHeightPadding );
532 
533  m_netsGrid->GetGridWindow()->Bind( wxEVT_MOTION,
535 
536  // To handle middle click on color swatches
537  m_netsGrid->GetGridWindow()->Bind( wxEVT_MIDDLE_UP,
539 
540  m_netsGrid->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
541  m_netclassScrolledWindow->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT );
542 
543  if( m_isFpEditor )
544  m_notebook->RemovePage( 2 );
545 
547  rebuildObjects();
548  OnBoardChanged();
549 
550  Bind( wxEVT_COMMAND_MENU_SELECTED, &APPEARANCE_CONTROLS::OnLayerContextMenu, this,
552 }
553 
554 
556 {
557  delete m_iconProvider;
558 }
559 
560 
562 {
563  // Create layer display options
565  _( "Layer Display Options" ) );
567  m_paneLayerDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
568 
569  wxWindow* layerDisplayPane = m_paneLayerDisplayOptions->GetPane();
570 
571  wxBoxSizer* layerDisplayOptionsSizer;
572  layerDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
573 
574  m_staticTextContrastModeTitle = new wxStaticText( layerDisplayPane, wxID_ANY,
575  _( "Non-active layers:" ), wxDefaultPosition,
576  wxDefaultSize, 0 );
577  m_staticTextContrastModeTitle->Wrap( -1 );
578  layerDisplayOptionsSizer->Add( m_staticTextContrastModeTitle, 0,
579  wxEXPAND | wxBOTTOM | wxLEFT, 2 );
580 
581  wxBoxSizer* contrastModeSizer;
582  contrastModeSizer = new wxBoxSizer( wxHORIZONTAL );
583 
584  m_rbHighContrastNormal = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Normal" ),
585  wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
586  m_rbHighContrastNormal->SetValue( true );
587  m_rbHighContrastNormal->SetToolTip( _( "Non-active layers will be shown in full color" ) );
588 
589  contrastModeSizer->Add( m_rbHighContrastNormal, 0, wxRIGHT, 4 );
590 
591  m_rbHighContrastDim = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Dim" ),
592  wxDefaultPosition, wxDefaultSize, 0 );
593  m_rbHighContrastDim->SetToolTip( _( "Non-active layers will be dimmed" ) );
594 
595  contrastModeSizer->Add( m_rbHighContrastDim, 0, wxRIGHT | wxLEFT, 10 );
596 
597  m_rbHighContrastOff = new wxRadioButton( layerDisplayPane, wxID_ANY, _( "Hide" ),
598  wxDefaultPosition, wxDefaultSize, 0 );
599  m_rbHighContrastOff->SetToolTip( _( "Non-active layers will be hidden" ) );
600 
601  contrastModeSizer->Add( m_rbHighContrastOff, 0, 0, 5 );
602 
603  layerDisplayOptionsSizer->Add( contrastModeSizer, 0, wxEXPAND, 5 );
604 
605  m_layerDisplaySeparator = new wxStaticLine( layerDisplayPane, wxID_ANY, wxDefaultPosition,
606  wxDefaultSize, wxLI_HORIZONTAL );
607  layerDisplayOptionsSizer->Add( m_layerDisplaySeparator, 0, wxEXPAND | wxTOP | wxBOTTOM, 5 );
608 
609  m_cbFlipBoard = new wxCheckBox( layerDisplayPane, wxID_ANY, _( "Flip board view" ),
610  wxDefaultPosition, wxDefaultSize, 0 );
611  layerDisplayOptionsSizer->Add( m_cbFlipBoard, 0, 0, 5 );
612 
613  layerDisplayPane->SetSizer( layerDisplayOptionsSizer );
614  layerDisplayPane->Layout();
615  layerDisplayOptionsSizer->Fit( layerDisplayPane );
616 
617  m_panelLayersSizer->Add( m_paneLayerDisplayOptions, 0, wxEXPAND | wxTOP, 5 );
618 
619  m_paneLayerDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
620  [&]( wxCommandEvent& aEvent )
621  {
622  Freeze();
623  m_panelLayers->Fit();
624  m_sizerOuter->Layout();
625  Thaw();
626  } );
627 
628  // Create net display options
629 
631  _( "Net Display Options" ) );
633  m_paneNetDisplayOptions->SetBackgroundColour( m_notebook->GetThemeBackgroundColour() );
634 
635  wxWindow* netDisplayPane = m_paneNetDisplayOptions->GetPane();
636  wxBoxSizer* netDisplayOptionsSizer = new wxBoxSizer( wxVERTICAL );
637 
639 
640  m_txtNetDisplayTitle = new wxStaticText( netDisplayPane, wxID_ANY, _( "Net colors:" ),
641  wxDefaultPosition, wxDefaultSize, 0 );
642  m_txtNetDisplayTitle->Wrap( -1 );
643  m_txtNetDisplayTitle->SetToolTip( _( "Choose when to show net and netclass colors" ) );
644 
645  netDisplayOptionsSizer->Add( m_txtNetDisplayTitle, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
646 
647  wxBoxSizer* netColorSizer = new wxBoxSizer( wxHORIZONTAL );
648 
649  m_rbNetColorAll = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All" ), wxDefaultPosition,
650  wxDefaultSize, wxRB_GROUP );
651  m_rbNetColorAll->SetToolTip( _( "Net and netclass colors are shown on all copper items" ) );
652 
653  netColorSizer->Add( m_rbNetColorAll, 0, wxRIGHT, 10 );
654 
655  m_rbNetColorRatsnest = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Ratsnest" ),
656  wxDefaultPosition, wxDefaultSize, 0 );
657  m_rbNetColorRatsnest->SetValue( true );
658  m_rbNetColorRatsnest->SetToolTip( _( "Net and netclass colors are shown on the ratsnest only" ) );
659 
660  netColorSizer->Add( m_rbNetColorRatsnest, 0, wxRIGHT, 4 );
661 
662  m_rbNetColorOff = new wxRadioButton( netDisplayPane, wxID_ANY, _( "None" ), wxDefaultPosition,
663  wxDefaultSize, 0 );
664  m_rbNetColorOff->SetToolTip( _( "Net and netclass colors are not shown" ) );
665 
666  netColorSizer->Add( m_rbNetColorOff, 0, 0, 5 );
667 
668  netDisplayOptionsSizer->Add( netColorSizer, 0, wxEXPAND | wxBOTTOM, 5 );
669 
671 
672  m_txtRatsnestVisibility = new wxStaticText( netDisplayPane, wxID_ANY, _( "Ratsnest display:" ),
673  wxDefaultPosition, wxDefaultSize, 0 );
674  m_txtRatsnestVisibility->Wrap( -1 );
675  m_txtRatsnestVisibility->SetToolTip( _( "Choose what ratsnest lines to display" ) );
676 
677  netDisplayOptionsSizer->Add( m_txtRatsnestVisibility, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2 );
678 
679  wxBoxSizer* ratsnestDisplayModeSizer = new wxBoxSizer( wxHORIZONTAL );
680 
681  m_rbRatsnestAllLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "All layers" ),
682  wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
683  m_rbRatsnestAllLayers->SetToolTip( _( "Ratsnest lines are shown to items on all layers" ) );
684  m_rbRatsnestAllLayers->SetValue( true );
685 
686  ratsnestDisplayModeSizer->Add( m_rbRatsnestAllLayers, 0, wxRIGHT, 10 );
687 
688  m_rbRatsnestVisibleLayers = new wxRadioButton( netDisplayPane, wxID_ANY, _( "Visible layers" ),
689  wxDefaultPosition, wxDefaultSize, 0 );
690  m_rbRatsnestVisibleLayers->SetToolTip( _( "Ratsnest lines are shown to items on visible layers" ) );
691 
692  ratsnestDisplayModeSizer->Add( m_rbRatsnestVisibleLayers, 0, wxRIGHT, 4 );
693 
694  netDisplayOptionsSizer->Add( ratsnestDisplayModeSizer, 0, wxEXPAND | wxBOTTOM, 5 );
695 
697 
698  netDisplayPane->SetSizer( netDisplayOptionsSizer );
699  netDisplayPane->Layout();
700  netDisplayOptionsSizer->Fit( netDisplayPane );
701 
702  m_netsTabOuterSizer->Add( m_paneNetDisplayOptions, 0, wxEXPAND | wxTOP, 5 );
703 
704  m_paneNetDisplayOptions->Bind( WX_COLLAPSIBLE_PANE_CHANGED,
705  [&]( wxCommandEvent& aEvent )
706  {
707  Freeze();
708  m_panelNetsAndClasses->Fit();
709  m_sizerOuter->Layout();
710  passOnFocus();
711  Thaw();
712  } );
713 
714  m_rbNetColorAll->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorModeChanged, this );
715  m_rbNetColorOff->Bind( wxEVT_RADIOBUTTON, &APPEARANCE_CONTROLS::onNetColorModeChanged, this );
716  m_rbNetColorRatsnest->Bind( wxEVT_RADIOBUTTON,
718 
719  m_rbRatsnestAllLayers->Bind( wxEVT_RADIOBUTTON,
721  m_rbRatsnestVisibleLayers->Bind( wxEVT_RADIOBUTTON,
723 }
724 
725 
727 {
728  wxSize size( 220, 480 );
729  // TODO(JE) appropriate logic
730  return size;
731 }
732 
733 
734 void APPEARANCE_CONTROLS::OnNotebookPageChanged( wxNotebookEvent& aEvent )
735 {
736  // Work around wxMac issue where the notebook pages are blank
737 #ifdef __WXMAC__
738  int page = aEvent.GetSelection();
739 
740  if( page >= 0 )
741  m_notebook->ChangeSelection( static_cast<unsigned>( page ) );
742 #endif
743 
744 #ifndef __WXMSW__
745  // Because wxWidgets is broken and will send click events to children of the collapsible
746  // panes even if they are collapsed without this
747  Freeze();
748  m_panelLayers->Fit();
749  m_panelNetsAndClasses->Fit();
750  m_sizerOuter->Layout();
751  Thaw();
752 #endif
753 
754  Bind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
755 }
756 
757 
758 void APPEARANCE_CONTROLS::idleFocusHandler( wxIdleEvent& aEvent )
759 {
760  passOnFocus();
761  Unbind( wxEVT_IDLE, &APPEARANCE_CONTROLS::idleFocusHandler, this );
762 }
763 
764 
765 void APPEARANCE_CONTROLS::OnSetFocus( wxFocusEvent& aEvent )
766 {
767 #ifdef __WXMSW__
768  // In wxMSW, buttons won't process events unless they have focus, so we'll let it take the
769  // focus and give it back to the parent in the button event handler.
770  if( wxBitmapButton* btn = dynamic_cast<wxBitmapButton*>( aEvent.GetEventObject() ) )
771  {
772  wxCommandEvent evt( wxEVT_BUTTON );
773  wxPostEvent( btn, evt );
774  }
775 #endif
776 
777  passOnFocus();
778  aEvent.Skip();
779 }
780 
781 
782 void APPEARANCE_CONTROLS::OnSize( wxSizeEvent& aEvent )
783 {
784  aEvent.Skip();
785 }
786 
787 
788 void APPEARANCE_CONTROLS::OnNetGridClick( wxGridEvent& event )
789 {
790  int row = event.GetRow();
791  int col = event.GetCol();
792 
793  switch( col )
794  {
796  m_netsTable->SetValueAsBool( row, col, !m_netsTable->GetValueAsBool( row, col ) );
797  m_netsGrid->ForceRefresh();
798  break;
799 
800  default:
801  break;
802  }
803 }
804 
805 
807 {
808  int row = event.GetRow();
809  int col = event.GetCol();
810 
811  switch( col )
812  {
814  m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
815  break;
816 
817  default:
818  break;
819  }
820 }
821 
822 
824 {
825  m_netsGrid->SelectRow( event.GetRow() );
826 
827  wxString netName = m_netsGrid->GetCellValue( event.GetRow(), NET_GRID_TABLE::COL_LABEL );
828  wxMenu menu;
829 
830  menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR,
831  _( "Set net color" ), wxEmptyString, wxITEM_NORMAL ) );
832  menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
833  wxString::Format( _( "Highlight %s" ), netName ),
834  wxEmptyString, wxITEM_NORMAL ) );
835  menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
836  wxString::Format( _( "Select tracks and vias in %s" ), netName ),
837  wxEmptyString, wxITEM_NORMAL ) );
838  menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
839  wxString::Format( _( "Deselect tracks and vias in %s" ), netName ),
840  wxEmptyString, wxITEM_NORMAL ) );
841 
842  menu.AppendSeparator();
843 
844  menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS,
845  _( "Show all nets" ), wxEmptyString, wxITEM_NORMAL ) );
846  menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS,
847  _( "Hide all other nets" ), wxEmptyString,
848  wxITEM_NORMAL ) );
849 
850  menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
852 
853  PopupMenu( &menu );
854 }
855 
856 
857 void APPEARANCE_CONTROLS::OnNetGridMouseEvent( wxMouseEvent& aEvent )
858 {
859  wxPoint pos = m_netsGrid->CalcUnscrolledPosition( aEvent.GetPosition() );
860  wxGridCellCoords cell = m_netsGrid->XYToCell( pos );
861 
862  if( aEvent.Moving() || aEvent.Entering() )
863  {
864  aEvent.Skip();
865 
866  if( !cell )
867  {
868  m_netsGrid->GetGridWindow()->UnsetToolTip();
869  return;
870  }
871 
872  if( cell == m_hoveredCell )
873  return;
874 
875  m_hoveredCell = cell;
876 
877  NET_GRID_ENTRY& net = m_netsTable->GetEntry( cell.GetRow() );
878 
879  wxString name = net.name;
880  wxString showOrHide = net.visible ? _( "Click to hide ratsnest for %s" )
881  : _( "Click to show ratsnest for %s" );
882  wxString tip;
883 
884  if( cell.GetCol() == NET_GRID_TABLE::COL_VISIBILITY )
885  tip.Printf( showOrHide, name );
886  else if( cell.GetCol() == NET_GRID_TABLE::COL_COLOR )
887  tip = _( "Left double click or middle click for color change, "
888  "right click for menu" );
889 
890  m_netsGrid->GetGridWindow()->SetToolTip( tip );
891  }
892  else if( aEvent.Leaving() )
893  {
894  m_netsGrid->UnsetToolTip();
895  aEvent.Skip();
896  }
897  else if( aEvent.Dragging() )
898  {
899  // not allowed
900  CallAfter( [&]()
901  {
902  m_netsGrid->ClearSelection();
903  } );
904  }
905  else if( aEvent.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !!cell )
906  {
907  int row = cell.GetRow();
908  int col = cell.GetCol();
909 
910  if(col == NET_GRID_TABLE::COL_COLOR )
911  m_netsGrid->GetCellEditor( row, col )->BeginEdit( row, col, m_netsGrid );
912 
913  aEvent.Skip();
914  }
915  else
916  {
917  aEvent.Skip();
918  }
919 }
920 
921 
923 {
924  Freeze();
925  rebuildLayers();
929  rebuildNets();
932 
934 
935  m_board = m_frame->GetBoard();
936 
937  if( m_board )
938  m_board->AddListener( this );
939 
940  Thaw();
941  Refresh();
942 }
943 
944 
946 {
948 }
949 
950 
951 void APPEARANCE_CONTROLS::OnNetVisibilityChanged( int aNetCode, bool aVisibility )
952 {
953  int row = m_netsTable->GetRowByNetcode( aNetCode );
954 
955  if( row >= 0 )
956  {
958  m_netsGrid->ForceRefresh();
959  }
960 }
961 
962 
964 {
965  return aBoardItem->Type() == PCB_NETINFO_T;
966 }
967 
968 
969 bool APPEARANCE_CONTROLS::doesBoardItemNeedRebuild( std::vector<BOARD_ITEM*>& aBoardItems )
970 {
971  bool rebuild = std::any_of( aBoardItems.begin(), aBoardItems.end(),
972  []( const BOARD_ITEM* a )
973  {
974  return a->Type() == PCB_NETINFO_T;
975  } );
976 
977 
978  return rebuild;
979 }
980 
981 
983 {
984  if( doesBoardItemNeedRebuild( aBoardItem ) )
986 }
987 
988 
989 void APPEARANCE_CONTROLS::OnBoardItemsAdded( BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems )
990 {
991  if( doesBoardItemNeedRebuild( aBoardItems ) )
992  {
994  }
995 }
996 
997 
999 {
1000  if( doesBoardItemNeedRebuild( aBoardItem ) )
1002 }
1003 
1004 
1006  BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems )
1007 {
1008  if( doesBoardItemNeedRebuild( aBoardItems ) )
1009  {
1011  }
1012 }
1013 
1014 
1016 {
1017  if( doesBoardItemNeedRebuild( aBoardItem ) )
1019 }
1020 
1021 
1023  BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItems )
1024 {
1025  if( doesBoardItemNeedRebuild( aBoardItems ) )
1026  {
1028  }
1029 }
1030 
1031 
1033 {
1034  Freeze();
1035  rebuildNets();
1036  Thaw();
1037 }
1038 
1039 
1041 {
1044 }
1045 
1046 
1048 {
1049  for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1050  {
1051  setting->ctl_panel->SetBackgroundColour( m_layerPanelColour );
1052  setting->ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
1053  }
1054 
1055  wxChar r, g, b;
1056 
1057  r = m_layerPanelColour.Red();
1058  g = m_layerPanelColour.Green();
1059  b = m_layerPanelColour.Blue();
1060 
1061  if( r < 240 || g < 240 || b < 240 )
1062  {
1063  r = wxChar( std::min( (int) r + 15, 255 ) );
1064  g = wxChar( std::min( (int) g + 15, 255 ) );
1065  b = wxChar( std::min( (int) b + 15, 255 ) );
1066  }
1067  else
1068  {
1069  r = wxChar( std::max( (int) r - 15, 0 ) );
1070  g = wxChar( std::max( (int) g - 15, 0 ) );
1071  b = wxChar( std::max( (int) b - 15, 0 ) );
1072  }
1073 
1074  PCB_LAYER_ID current = m_frame->GetActiveLayer();
1075 
1076  if( !m_layerSettingsMap.count( current ) )
1077  {
1078  wxASSERT( m_layerSettingsMap.count( F_Cu ) );
1079  current = F_Cu;
1080  }
1081 
1082  APPEARANCE_SETTING* newSetting = m_layerSettingsMap[ current ];
1083 
1084  newSetting->ctl_panel->SetBackgroundColour( wxColour( r, g, b ) );
1086 
1087  Refresh();
1088 }
1089 
1090 
1091 void APPEARANCE_CONTROLS::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
1092 {
1093  LSET visible = getVisibleLayers();
1094  PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
1095 
1096  if( visible.test( layer ) == isVisible )
1097  return;
1098 
1099  visible.set( layer, isVisible );
1100  setVisibleLayers( visible );
1101 
1102  m_frame->GetCanvas()->GetView()->SetLayerVisible( layer, isVisible );
1103 
1105 }
1106 
1107 
1109 {
1110  if( m_objectSettingsMap.count( aLayer ) )
1111  {
1112  APPEARANCE_SETTING* setting = m_objectSettingsMap.at( aLayer );
1113  setting->ctl_visibility->SetValue( isVisible );
1114  }
1115 
1116  m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
1117 
1118  m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1119  m_frame->GetCanvas()->Refresh();
1120 }
1121 
1122 
1124 {
1125  if( m_isFpEditor )
1126  {
1127  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1128 
1129  for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1130  view->SetLayerVisible( layer, aLayers.Contains( layer ) );
1131  }
1132  else
1133  {
1134  m_frame->GetBoard()->SetVisibleLayers( aLayers );
1135  }
1136 }
1137 
1138 
1140 {
1141  if( m_isFpEditor )
1142  {
1143  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1144 
1145  for( size_t i = 0; i < GAL_LAYER_INDEX( LAYER_ZONE_START ); i++ )
1146  view->SetLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ), aLayers.test( i ) );
1147  }
1148  else
1149  {
1150  // Ratsnest visibility is controlled by the ratsnest option, and not by the preset
1151  if( m_frame->IsType( FRAME_PCB_EDITOR ) )
1152  {
1154  aLayers.set( LAYER_RATSNEST, opt.m_ShowGlobalRatsnest );
1155  }
1156 
1157  m_frame->GetBoard()->SetVisibleElements( aLayers );
1158  }
1159 }
1160 
1161 
1163 {
1164  if( m_isFpEditor )
1165  {
1166  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1167  LSET set;
1168 
1169  for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1170  set.set( layer, view->IsLayerVisible( layer ) );
1171 
1172  return set;
1173  }
1174  else
1175  {
1176  return m_frame->GetBoard()->GetVisibleLayers();
1177  }
1178 }
1179 
1180 
1182 {
1183  if( m_isFpEditor )
1184  {
1185  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
1186  GAL_SET set;
1187  set.reset();
1188 
1189  for( size_t i = 0; i < set.size(); i++ )
1190  set.set( i, view->IsLayerVisible( GAL_LAYER_ID_START + GAL_LAYER_ID( i ) ) );
1191 
1192  return set;
1193  }
1194  else
1195  {
1196  return m_frame->GetBoard()->GetVisibleElements();
1197  }
1198 }
1199 
1200 
1202 {
1203  // TODO(JE) Is this even needed if the layer alphas are getting directly updated?
1204  // Maybe we just need the "down" arrow to indicate if the alpha is below 1
1205 
1206 #if 0
1207  static constexpr double alphaEpsilon = 0.04;
1208 
1209  PCB_LAYER_ID current = m_frame->GetActiveLayer();
1211  KIGFX::PCB_PAINTER* painter =
1212  static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetCanvas()->GetView()->GetPainter() );
1213  KIGFX::PCB_RENDER_SETTINGS* rs = painter->GetSettings();
1214 
1215  for( APPEARANCE_SETTING& setting : m_layerSettings )
1216  {
1217  if( !setting.ctl_indicator )
1218  continue;
1219 
1220  COLOR4D layerColor = theme->GetColor( setting.id );
1221  COLOR4D screenColor = rs->GetLayerColor( setting.id );
1222 
1223  if( std::abs( screenColor.a - layerColor.a ) > alphaEpsilon )
1224  {
1225  if( screenColor.a < layerColor.a )
1226  setting.ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DOWN );
1227  else
1228  setting.ctl_indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::UP );
1229  }
1230  else
1231  {
1232  setting.ctl_indicator->SetIndicatorState( setting.id == current ?
1234  ROW_ICON_PROVIDER::STATE::OFF );
1235  }
1236  }
1237 #endif
1238 }
1239 
1240 
1242 {
1243  const PCB_DISPLAY_OPTIONS& options = m_frame->GetDisplayOptions();
1244 
1245  switch( options.m_ContrastModeDisplay )
1246  {
1247  case HIGH_CONTRAST_MODE::NORMAL: m_rbHighContrastNormal->SetValue( true ); break;
1248  case HIGH_CONTRAST_MODE::DIMMED: m_rbHighContrastDim->SetValue( true ); break;
1249  case HIGH_CONTRAST_MODE::HIDDEN: m_rbHighContrastOff->SetValue( true ); break;
1250  }
1251 
1252  switch( options.m_NetColorMode )
1253  {
1254  case NET_COLOR_MODE::ALL: m_rbNetColorAll->SetValue( true ); break;
1255  case NET_COLOR_MODE::RATSNEST: m_rbNetColorRatsnest->SetValue( true ); break;
1256  case NET_COLOR_MODE::OFF: m_rbNetColorOff->SetValue( true ); break;
1257  }
1258 
1259  m_cbFlipBoard->SetValue( m_frame->GetCanvas()->GetView()->IsMirroredX() );
1260 
1261  if( !m_isFpEditor )
1262  {
1263  if( options.m_RatsnestMode == RATSNEST_MODE::ALL )
1264  m_rbRatsnestAllLayers->SetValue( true );
1265  else
1266  m_rbRatsnestVisibleLayers->SetValue( true );
1267 
1268  wxASSERT( m_objectSettingsMap.count( LAYER_RATSNEST ) );
1270  ratsnest->ctl_visibility->SetValue( options.m_ShowGlobalRatsnest );
1271  }
1272 }
1273 
1274 
1275 std::vector<LAYER_PRESET> APPEARANCE_CONTROLS::GetUserLayerPresets() const
1276 {
1277  std::vector<LAYER_PRESET> ret;
1278 
1279  for( const auto& pair : m_layerPresets )
1280  if( !pair.second.readOnly )
1281  ret.emplace_back( pair.second );
1282 
1283  return ret;
1284 }
1285 
1286 
1287 void APPEARANCE_CONTROLS::SetUserLayerPresets( std::vector<LAYER_PRESET>& aPresetList )
1288 {
1289  // Reset to defaults
1291 
1292  for( const LAYER_PRESET& preset : aPresetList )
1293  {
1294  if( m_layerPresets.count( preset.name ) )
1295  continue;
1296 
1297  m_layerPresets[preset.name] = preset;
1298 
1299  m_presetMRU.Add( preset.name );
1300  }
1301 
1303 }
1304 
1305 
1307 {
1308  m_layerPresets.clear();
1309  m_presetMRU.clear();
1310 
1311  // Load the read-only defaults
1314  presetBackAssembly } )
1315  {
1316  m_layerPresets[preset.name] = preset;
1317  m_layerPresets[preset.name].readOnly = true;
1318 
1319  m_presetMRU.Add( preset.name );
1320  }
1321 }
1322 
1323 
1324 void APPEARANCE_CONTROLS::ApplyLayerPreset( const wxString& aPresetName )
1325 {
1326  updateLayerPresetSelection( aPresetName );
1327 
1328  wxCommandEvent dummy;
1330 }
1331 
1332 
1334 {
1335  if( m_layerPresets.count( aPreset.name ) )
1336  m_currentPreset = &m_layerPresets[aPreset.name];
1337  else
1338  m_currentPreset = nullptr;
1339 
1341  : nullptr;
1342 
1343  updateLayerPresetSelection( aPreset.name );
1344  doApplyLayerPreset( aPreset );
1345 }
1346 
1347 
1349 {
1350  BOARD* board = m_frame->GetBoard();
1351  LSET enabled = board->GetEnabledLayers();
1352  LSET visible = getVisibleLayers();
1353 
1355  COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
1356  bool firstLayer = true;
1357  bool readOnly = theme->IsReadOnly();
1358 
1359 #ifdef __WXMAC__
1360  wxSizerItem* m_windowLayersSizerItem = m_panelLayersSizer->GetItem( m_windowLayers );
1361  m_windowLayersSizerItem->SetFlag( m_windowLayersSizerItem->GetFlag() & ~wxTOP );
1362 #endif
1363 
1364  m_layerSettings.clear();
1365  m_layerSettingsMap.clear();
1366  m_layersOuterSizer->Clear( true );
1367 
1368  auto appendLayer =
1369  [&]( std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1370  {
1371  int layer = aSetting->id;
1372 
1373  wxPanel* panel = new wxPanel( m_windowLayers, layer );
1374  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
1375  panel->SetSizer( sizer );
1376 
1377  panel->SetBackgroundColour( m_layerPanelColour );
1378 
1379  aSetting->visible = visible[layer];
1380 
1381  // TODO(JE) consider restyling this indicator
1382  INDICATOR_ICON* indicator = new INDICATOR_ICON( panel, *m_iconProvider,
1383  ROW_ICON_PROVIDER::STATE::OFF,
1384  layer );
1385 
1386  COLOR_SWATCH* swatch = new COLOR_SWATCH( panel, COLOR4D::UNSPECIFIED, layer,
1387  bgColor, theme->GetColor( layer ),
1388  SWATCH_SMALL );
1389  swatch->SetToolTip( _( "Double click or middle click for color change, "
1390  "right click for menu" ) );
1391 
1392  BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( panel, layer,
1395  aSetting->visible );
1396  btn_visible->SetToolTip( _( "Show or hide this layer" ) );
1397 
1398  wxStaticText* label = new wxStaticText( panel, layer, aSetting->label );
1399  label->Wrap( -1 );
1400  label->SetToolTip( aSetting->tooltip );
1401 
1402  int topMargin = firstLayer ? 2 : 1;
1403  firstLayer = false;
1404 
1405  sizer->AddSpacer( 1 );
1406  sizer->Add( indicator, 0, wxALIGN_CENTER_VERTICAL | wxTOP, topMargin );
1407  sizer->AddSpacer( 5 );
1408  sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL | wxTOP, topMargin );
1409  sizer->AddSpacer( 6 );
1410  sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxTOP, topMargin );
1411  sizer->AddSpacer( 5 );
1412  sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxTOP, topMargin );
1413 
1414  m_layersOuterSizer->Add( panel, 0, wxEXPAND, 0 );
1415 
1416  aSetting->ctl_panel = panel;
1417  aSetting->ctl_indicator = indicator;
1418  aSetting->ctl_visibility = btn_visible;
1419  aSetting->ctl_color = swatch;
1420  aSetting->ctl_text = label;
1421 
1422  panel->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this );
1423  indicator->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this );
1424  swatch->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this );
1425  label->Bind( wxEVT_LEFT_DOWN, &APPEARANCE_CONTROLS::onLayerClick, this );
1426 
1427  btn_visible->Bind( TOGGLE_CHANGED,
1428  [&]( wxCommandEvent& aEvent )
1429  {
1430  wxObject* btn = aEvent.GetEventObject();
1431  int layId = static_cast<wxWindow*>( btn )->GetId();
1432  bool isVisible = aEvent.GetInt();
1433 
1434  wxASSERT( layId >= 0 && layId < PCB_LAYER_ID_COUNT );
1435 
1437  {
1438  static_cast<BITMAP_TOGGLE*>( btn )->SetValue( !isVisible );
1439  return;
1440  }
1441 
1442  onLayerVisibilityChanged( static_cast<PCB_LAYER_ID>( layId ),
1443  isVisible, true );
1444  } );
1445 
1446  swatch->Bind( COLOR_SWATCH_CHANGED, &APPEARANCE_CONTROLS::OnColorSwatchChanged,
1447  this );
1449  this ) );
1450  swatch->SetReadOnly( readOnly );
1451 
1452  auto rightClickHandler =
1453  [&]( wxMouseEvent& aEvent )
1454  {
1455  wxASSERT( m_layerContextMenu );
1456  PopupMenu( m_layerContextMenu );
1457  passOnFocus();
1458  };
1459 
1460  panel->Bind( wxEVT_RIGHT_DOWN, rightClickHandler );
1461  indicator->Bind( wxEVT_RIGHT_DOWN, rightClickHandler );
1462  swatch->Bind( wxEVT_RIGHT_DOWN, rightClickHandler );
1463  btn_visible->Bind( wxEVT_RIGHT_DOWN, rightClickHandler );
1464  label->Bind( wxEVT_RIGHT_DOWN, rightClickHandler );
1465  };
1466 
1467  wxString dsc;
1468 
1469  // show all coppers first, with front on top, back on bottom, then technical layers
1470  for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack )
1471  {
1472  PCB_LAYER_ID layer = *cu_stack;
1473 
1474  switch( layer )
1475  {
1476  case F_Cu: dsc = _( "Front copper layer" ); break;
1477  case B_Cu: dsc = _( "Back copper layer" ); break;
1478  default: dsc = _( "Inner copper layer" ); break;
1479  }
1480 
1481  m_layerSettings.emplace_back(
1482  std::make_unique<APPEARANCE_SETTING>( board->GetLayerName( layer ), layer, dsc ) );
1483 
1484  std::unique_ptr<APPEARANCE_SETTING>& setting = m_layerSettings.back();
1485 
1486  m_layerSettingsMap[layer] = setting.get();
1487 
1488  appendLayer( setting );
1489 
1491  {
1492  setting->ctl_text->Disable();
1493  setting->ctl_color->SetToolTip( wxEmptyString );
1494  }
1495  }
1496 
1497  // technical layers are shown in this order:
1498  // Because they are static, wxGetTranslation must be explicitly
1499  // called for tooltips.
1500  static const struct {
1501  PCB_LAYER_ID layerId;
1502  wxString tooltip;
1503  } non_cu_seq[] = {
1504  { F_Adhes, _( "Adhesive on board's front" ) },
1505  { B_Adhes, _( "Adhesive on board's back" ) },
1506  { F_Paste, _( "Solder paste on board's front" ) },
1507  { B_Paste, _( "Solder paste on board's back" ) },
1508  { F_SilkS, _( "Silkscreen on board's front" ) },
1509  { B_SilkS, _( "Silkscreen on board's back" ) },
1510  { F_Mask, _( "Solder mask on board's front" ) },
1511  { B_Mask, _( "Solder mask on board's back" ) },
1512  { Dwgs_User, _( "Explanatory drawings" ) },
1513  { Cmts_User, _( "Explanatory comments" ) },
1514  { Eco1_User, _( "User defined meaning" ) },
1515  { Eco2_User, _( "User defined meaning" ) },
1516  { Edge_Cuts, _( "Board's perimeter definition" ) },
1517  { Margin, _( "Board's edge setback outline" ) },
1518  { F_CrtYd, _( "Footprint courtyards on board's front" ) },
1519  { B_CrtYd, _( "Footprint courtyards on board's back" ) },
1520  { F_Fab, _( "Footprint assembly on board's front" ) },
1521  { B_Fab, _( "Footprint assembly on board's back" ) },
1522  { User_1, _( "User defined layer 1" ) },
1523  { User_2, _( "User defined layer 2" ) },
1524  { User_3, _( "User defined layer 3" ) },
1525  { User_4, _( "User defined layer 4" ) },
1526  { User_5, _( "User defined layer 5" ) },
1527  { User_6, _( "User defined layer 6" ) },
1528  { User_7, _( "User defined layer 7" ) },
1529  { User_8, _( "User defined layer 8" ) },
1530  { User_9, _( "User defined layer 9" ) },
1531  };
1532 
1533  for( const auto& entry : non_cu_seq )
1534  {
1535  PCB_LAYER_ID layer = entry.layerId;
1536 
1537  if( !enabled[layer] )
1538  continue;
1539 
1540  m_layerSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>(
1541  board->GetLayerName( layer ), layer, wxGetTranslation( entry.tooltip ) ) );
1542 
1543  std::unique_ptr<APPEARANCE_SETTING>& setting = m_layerSettings.back();
1544 
1545  m_layerSettingsMap[layer] = setting.get();
1546 
1547  appendLayer( setting );
1548 
1550  {
1551  setting->ctl_text->Disable();
1552  setting->ctl_color->SetToolTip( wxEmptyString );
1553  }
1554  }
1555 
1556  m_layersOuterSizer->AddSpacer( 10 );
1557  m_windowLayers->SetBackgroundColour( m_layerPanelColour );
1558  m_windowLayers->Layout();
1559 }
1560 
1561 
1563 {
1564  delete m_layerContextMenu;
1565  m_layerContextMenu = new wxMenu;
1566 
1568  _( "Show All Copper Layers" ),
1571  _( "Hide All Copper Layers" ),
1573 
1574  m_layerContextMenu->AppendSeparator();
1575 
1577  _( "Hide All Layers But Active" ),
1579 
1580  m_layerContextMenu->AppendSeparator();
1581 
1582  AddMenuItem( m_layerContextMenu, ID_SHOW_ALL_NON_COPPER, _( "Show All Non Copper Layers" ),
1584 
1585  AddMenuItem( m_layerContextMenu, ID_HIDE_ALL_NON_COPPER, _( "Hide All Non Copper Layers" ),
1587 
1588  m_layerContextMenu->AppendSeparator();
1589 
1590  AddMenuItem( m_layerContextMenu, ID_PRESET_ALL_LAYERS, _( "Show All Layers" ),
1592 
1593  AddMenuItem( m_layerContextMenu, ID_PRESET_NO_LAYERS, _( "Hide All Layers" ),
1595 
1596  m_layerContextMenu->AppendSeparator();
1597 
1599  _( "Show Only Front Assembly Layers" ), KiBitmap( show_front_assembly_layers_xpm ) );
1600 
1601  AddMenuItem( m_layerContextMenu, ID_PRESET_FRONT, _( "Show Only Front Layers" ),
1603 
1604  // Only show the internal layer option if internal layers are enabled
1605  if( m_frame->GetBoard()->GetCopperLayerCount() > 2 )
1606  {
1607  AddMenuItem( m_layerContextMenu, ID_PRESET_INNER_COPPER, _( "Show Only Inner Layers" ),
1609  }
1610 
1611  AddMenuItem( m_layerContextMenu, ID_PRESET_BACK, _( "Show Only Back Layers" ),
1613 
1614  AddMenuItem( m_layerContextMenu, ID_PRESET_BACK_ASSEMBLY, _( "Show Only Back Assembly Layers" ),
1616 }
1617 
1618 
1619 void APPEARANCE_CONTROLS::OnLayerContextMenu( wxCommandEvent& aEvent )
1620 {
1621  BOARD* board = m_frame->GetBoard();
1622  LSET visible = getVisibleLayers();
1623 
1624  PCB_LAYER_ID current = m_frame->GetActiveLayer();
1625 
1626  switch( aEvent.GetId() )
1627  {
1628  case ID_PRESET_NO_LAYERS:
1630  return;
1631 
1632  case ID_PRESET_ALL_LAYERS:
1634  return;
1635 
1637  {
1638  visible |= presetAllCopper.layers;
1639  setVisibleLayers( visible );
1640  break;
1641  }
1642 
1645  SetLayerVisible( current, true );
1646  break;
1647 
1649  {
1650  visible &= ~presetAllCopper.layers;
1651 
1652  if( !visible.test( current ) )
1653  m_frame->SetActiveLayer( *visible.Seq().begin() );
1654 
1655  setVisibleLayers( visible );
1656  break;
1657  }
1658 
1660  {
1661  visible &= presetAllCopper.layers;
1662 
1663  if( !visible.test( current ) )
1664  m_frame->SetActiveLayer( *visible.Seq().begin() );
1665 
1666  setVisibleLayers( visible );
1667  break;
1668  }
1669 
1671  {
1672  visible |= ~presetAllCopper.layers;
1673 
1674  setVisibleLayers( visible );
1675  break;
1676  }
1677 
1680  return;
1681 
1682  case ID_PRESET_FRONT:
1684  return;
1685 
1688  return;
1689 
1690  case ID_PRESET_BACK:
1692  return;
1693 
1696  return;
1697  }
1698 
1701 
1702  if( !m_isFpEditor )
1703  m_frame->GetCanvas()->SyncLayersVisibility( board );
1704 
1705  m_frame->GetCanvas()->Refresh();
1706 }
1707 
1708 
1710 {
1711  return m_notebook->GetSelection();
1712 }
1713 
1714 
1716 {
1717  size_t max = m_notebook->GetPageCount();
1718 
1719  if( aTab >= 0 && static_cast<size_t>( aTab ) < max )
1720  m_notebook->SetSelection( aTab );
1721 }
1722 
1723 
1725 {
1727  bool readOnly = theme->IsReadOnly();
1728  LSET visible = getVisibleLayers();
1729  GAL_SET objects = getVisibleObjects();
1730 
1731  Freeze();
1732 
1733  for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_layerSettings )
1734  {
1735  LAYER_NUM layer = setting->id;
1736 
1737  if( setting->ctl_visibility )
1738  setting->ctl_visibility->SetValue( visible[layer] );
1739 
1740  if( setting->ctl_color )
1741  {
1742  const COLOR4D& color = theme->GetColor( layer );
1743  setting->ctl_color->SetSwatchColor( color, false );
1744  setting->ctl_color->SetReadOnly( readOnly );
1745  }
1746  }
1747 
1748  for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
1749  {
1750  GAL_LAYER_ID layer = static_cast<GAL_LAYER_ID>( setting->id );
1751 
1752  if( setting->ctl_visibility )
1753  setting->ctl_visibility->SetValue( objects.Contains( layer ) );
1754 
1755  if( setting->ctl_color )
1756  {
1757  const COLOR4D& color = theme->GetColor( layer );
1758  setting->ctl_color->SetSwatchColor( color, false );
1759  setting->ctl_color->SetReadOnly( readOnly );
1760  }
1761  }
1762 
1763  // Update indicators and panel background colors
1764  OnLayerChanged();
1765 
1766  Thaw();
1767 
1768  m_windowLayers->Refresh();
1769 }
1770 
1771 
1772 void APPEARANCE_CONTROLS::onLayerClick( wxMouseEvent& aEvent )
1773 {
1774  auto eventSource = static_cast<wxWindow*>( aEvent.GetEventObject() );
1775 
1776  PCB_LAYER_ID layer = ToLAYER_ID( eventSource->GetId() );
1777 
1778  if( m_isFpEditor && LSET::ForbiddenFootprintLayers().test( layer ) )
1779  return;
1780 
1781  m_frame->SetActiveLayer( layer );
1782  passOnFocus();
1783 }
1784 
1785 
1787  bool isFinal )
1788 {
1789  LSET visibleLayers = getVisibleLayers();
1790 
1791  if( visibleLayers.test( aLayer ) != isVisible )
1792  {
1793  visibleLayers.set( aLayer, isVisible );
1794 
1795  setVisibleLayers( visibleLayers );
1796 
1797  m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1798  }
1799 
1801 
1802  if( isFinal )
1803  m_frame->GetCanvas()->Refresh();
1804 }
1805 
1806 
1808  bool isFinal )
1809 {
1810  // Special-case controls
1811  switch( aLayer )
1812  {
1813  case LAYER_RATSNEST:
1814  {
1815  // don't touch the layers. ratsnest is enabled on per-item basis.
1817  m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, true );
1818 
1819  if( m_frame->IsType( FRAME_PCB_EDITOR ) )
1820  {
1822  opt.m_ShowGlobalRatsnest = isVisible;
1823  m_frame->SetDisplayOptions( opt );
1824  m_frame->GetBoard()->SetElementVisibility( aLayer, isVisible );
1826  }
1827 
1828  break;
1829  }
1830 
1831  case LAYER_GRID:
1832  m_frame->SetGridVisibility( isVisible );
1833  m_frame->GetCanvas()->Refresh();
1835  break;
1836 
1837  case LAYER_MOD_TEXT_FR:
1838  // Because Footprint Text is a meta-control that also can disable values/references,
1839  // drag them along here so that the user is less likely to be confused.
1840  onObjectVisibilityChanged( LAYER_MOD_REFERENCES, isVisible, false );
1841  onObjectVisibilityChanged( LAYER_MOD_VALUES, isVisible, false );
1842  m_objectSettingsMap[LAYER_MOD_REFERENCES]->ctl_visibility->SetValue( isVisible );
1843  m_objectSettingsMap[LAYER_MOD_VALUES]->ctl_visibility->SetValue( isVisible );
1844  break;
1845 
1846  default:
1847  break;
1848  }
1849 
1850  GAL_SET visible = getVisibleObjects();
1851 
1852  if( visible.Contains( aLayer ) != isVisible )
1853  {
1854  visible.set( aLayer, isVisible );
1855  setVisibleObjects( visible );
1856  m_frame->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
1858  }
1859 
1860  if( isFinal )
1861  {
1862  m_frame->GetCanvas()->Refresh();
1863  passOnFocus();
1864  }
1865 }
1866 
1867 
1869 {
1871  COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
1872  GAL_SET visible = getVisibleObjects();
1873  int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
1874  int labelWidth = 0;
1875 
1876  m_objectSettings.clear();
1877  m_objectsOuterSizer->Clear( true );
1878  m_objectsOuterSizer->AddSpacer( 5 );
1879 
1880  auto appendObject =
1881  [&]( const std::unique_ptr<APPEARANCE_SETTING>& aSetting )
1882  {
1883  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
1884  int layer = aSetting->id;
1885 
1886  aSetting->visible = visible.Contains( ToGalLayer( layer ) );
1887  COLOR4D color = theme->GetColor( layer );
1888  COLOR4D defColor = theme->GetDefaultColor( layer );
1889 
1890  if( color != COLOR4D::UNSPECIFIED )
1891  {
1892  COLOR_SWATCH* swatch = new COLOR_SWATCH( m_windowObjects, color, layer,
1893  bgColor, defColor, SWATCH_SMALL );
1894  swatch->SetToolTip( _( "Left double click or middle click for color change, "
1895  "right click for menu" ) );
1896 
1897  sizer->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 0 );
1898  aSetting->ctl_color = swatch;
1899 
1900  swatch->Bind( COLOR_SWATCH_CHANGED,
1902 
1904  this ) );
1905  }
1906  else
1907  {
1908  sizer->AddSpacer( swatchWidth );
1909  }
1910 
1911  BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( m_windowObjects, layer,
1914  aSetting->visible );
1915 
1916  wxString tip;
1917  tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
1918  btn_visible->SetToolTip( tip );
1919 
1920  aSetting->ctl_visibility = btn_visible;
1921 
1922  sizer->AddSpacer( 5 );
1923 
1924  btn_visible->Bind( TOGGLE_CHANGED,
1925  [&]( wxCommandEvent& aEvent )
1926  {
1927  int id = static_cast<wxWindow*>( aEvent.GetEventObject() )->GetId();
1928  bool isVisible = aEvent.GetInt();
1929  onObjectVisibilityChanged( ToGalLayer( id ), isVisible, true );
1930  } );
1931 
1932  wxStaticText* label = new wxStaticText( m_windowObjects, layer, aSetting->label );
1933  label->Wrap( -1 );
1934  label->SetToolTip( aSetting->tooltip );
1935 
1936  if( aSetting->can_control_opacity )
1937  {
1938  label->SetMinSize( wxSize( labelWidth, -1 ) );
1939 #ifdef __WXMAC__
1940  sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
1941  sizer->AddSpacer( 5 );
1942  sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, 10 );
1943 #else
1944  sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
1945  sizer->AddSpacer( 5 );
1946  sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
1947 #endif
1948 
1949  wxSlider* slider = new wxSlider( m_windowObjects, wxID_ANY, 100, 0, 100,
1950  wxDefaultPosition, wxDefaultSize,
1951  wxSL_HORIZONTAL );
1952 #ifdef __WXMAC__
1953  slider->SetMinSize( wxSize( 80, 22 ) );
1954 #else
1955  slider->SetMinSize( wxSize( 80, -1 ) );
1956 #endif
1957 
1958  tip.Printf( _( "Set opacity of %s" ), aSetting->label.Lower() );
1959  slider->SetToolTip( tip );
1960 
1961  sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
1962  aSetting->ctl_opacity = slider;
1963 
1964  auto opacitySliderHandler =
1965  [=]( wxCommandEvent& aEvent )
1966  {
1967  wxSlider* ctrl = static_cast<wxSlider*>( aEvent.GetEventObject() );
1968  int value = ctrl->GetValue();
1969  onObjectOpacitySlider( layer, value / 100.0f );
1970  };
1971 
1972  slider->Bind( wxEVT_SCROLL_CHANGED, opacitySliderHandler );
1973  slider->Bind( wxEVT_SCROLL_THUMBTRACK, opacitySliderHandler );
1974  slider->Bind( wxEVT_SET_FOCUS, &APPEARANCE_CONTROLS::OnSetFocus, this );
1975  }
1976  else
1977  {
1978  sizer->Add( btn_visible, 0, wxALIGN_CENTER_VERTICAL, 0 );
1979  sizer->AddSpacer( 5 );
1980  sizer->Add( label, 0, wxALIGN_CENTER_VERTICAL, 0 );
1981  }
1982 
1983  aSetting->ctl_text = label;
1984  m_objectsOuterSizer->Add( sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
1985  m_objectsOuterSizer->AddSpacer( 1 );
1986  };
1987 
1988  for( const APPEARANCE_SETTING& s_setting : s_objectSettings )
1989  {
1990  if( m_isFpEditor && !s_allowedInFpEditor.count( s_setting.id ) )
1991  continue;
1992 
1993  if( !s_setting.spacer )
1994  {
1995  m_objectSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>( s_setting ) );
1996 
1997  std::unique_ptr<APPEARANCE_SETTING>& setting = m_objectSettings.back();
1998 
1999  // Because s_render_rows is created static, we must explicitly call
2000  // wxGetTranslation for texts which are internationalized (tool tips
2001  // and item names)
2002  setting->tooltip = wxGetTranslation( s_setting.tooltip );
2003  setting->label = wxGetTranslation( s_setting.label );
2004 
2005  if( setting->can_control_opacity )
2006  {
2007  int width = m_windowObjects->GetTextExtent( setting->label ).x;
2008  labelWidth = std::max( labelWidth, width );
2009  }
2010 
2011  m_objectSettingsMap[ToGalLayer( setting->id )] = setting.get();
2012  }
2013  }
2014 
2015  for( const std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2016  {
2017  if( setting->spacer )
2018  m_objectsOuterSizer->AddSpacer( m_pointSize );
2019  else
2020  appendObject( setting );
2021  }
2022 
2023  m_objectsOuterSizer->Layout();
2024 }
2025 
2026 
2028 {
2029  GAL_SET visible = getVisibleObjects();
2030 
2032 
2033  for( std::unique_ptr<APPEARANCE_SETTING>& setting : m_objectSettings )
2034  {
2035  if( setting->spacer )
2036  continue;
2037 
2038  GAL_LAYER_ID layer = ToGalLayer( setting->id );
2039 
2040  if( setting->ctl_visibility )
2041  setting->ctl_visibility->SetValue( visible.Contains( layer ) );
2042 
2043  if( setting->ctl_color )
2044  {
2045  COLOR4D color = m_frame->GetColorSettings()->GetColor( setting->id );
2046  setting->ctl_color->SetSwatchColor( color, false );
2047  }
2048  }
2049 
2050  wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
2051  && m_objectSettingsMap.count( LAYER_VIAS )
2052  && m_objectSettingsMap.count( LAYER_PADS )
2053  && m_objectSettingsMap.count( LAYER_ZONES ) );
2054 
2055  m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
2056  m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
2057  m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
2058  m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
2059 }
2060 
2061 
2063 {
2064  BOARD* board = m_frame->GetBoard();
2066  COLOR4D bgColor = theme->GetColor( LAYER_PCB_BACKGROUND );
2067 
2068  // If the board isn't fully loaded, we can't yet rebuild
2069  if( !board->GetProject() )
2070  return;
2071 
2072  KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
2074 
2075  std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
2076 
2077  m_netclassOuterSizer->Clear( true );
2078 
2079  auto appendNetclass =
2080  [&]( int aId, const NETCLASSPTR& aClass, bool isDefaultClass = false )
2081  {
2082  wxString name = aClass->GetName();
2083 
2084  m_netclassSettings.emplace_back( std::make_unique<APPEARANCE_SETTING>() );
2085  APPEARANCE_SETTING* setting = m_netclassSettings.back().get();
2086  m_netclassSettingsMap[name] = setting;
2087 
2088  setting->ctl_panel = new wxPanel( m_netclassScrolledWindow, aId );
2089  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
2090  setting->ctl_panel->SetSizer( sizer );
2091  COLOR4D color = netclassColors.count( name ) ? netclassColors.at( name ) :
2092  COLOR4D::UNSPECIFIED;
2093 
2094  setting->ctl_color = new COLOR_SWATCH( setting->ctl_panel, color, aId, bgColor,
2095  COLOR4D::UNSPECIFIED, SWATCH_SMALL );
2096  setting->ctl_color->SetToolTip( _( "Left double click or middle click for color "
2097  "change, right click for menu" ) );
2098 
2099  setting->ctl_color->Bind( COLOR_SWATCH_CHANGED,
2101 
2102  // Default netclass can't have an override color
2103  if( isDefaultClass )
2104  setting->ctl_color->Hide();
2105 
2106  setting->ctl_visibility =
2107  new BITMAP_TOGGLE( setting->ctl_panel, aId, KiBitmap( visibility_xpm ),
2108  KiBitmap( visibility_off_xpm ), true );
2109 
2110  wxString tip;
2111  tip.Printf( _( "Show or hide ratsnest for nets in %s" ), name );
2112  setting->ctl_visibility->SetToolTip( tip );
2113 
2114  setting->ctl_text = new wxStaticText( setting->ctl_panel, aId, name );
2115  setting->ctl_text->Wrap( -1 );
2116 
2117  int flags = wxALIGN_CENTER_VERTICAL;
2118 
2119  sizer->Add( setting->ctl_color, 0, flags | wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
2120  sizer->AddSpacer( 7 );
2121  sizer->Add( setting->ctl_visibility, 0, flags, 5 );
2122  sizer->AddSpacer( 3 );
2123  sizer->Add( setting->ctl_text, 1, flags, 5 );
2124 
2125  m_netclassOuterSizer->Add( setting->ctl_panel, 0, wxEXPAND, 5 );
2126  m_netclassOuterSizer->AddSpacer( 1 );
2127 
2128  setting->ctl_visibility->Bind( TOGGLE_CHANGED,
2130  this );
2131 
2132  auto menuHandler =
2133  [&, name, isDefaultClass]( wxMouseEvent& aEvent )
2134  {
2136 
2137  wxMenu menu;
2138 
2139  if( !isDefaultClass)
2140  {
2141  menu.Append( new wxMenuItem( &menu, ID_SET_NET_COLOR,
2142  _( "Set netclass color" ), wxEmptyString,
2143  wxITEM_NORMAL ) );
2144  }
2145 
2146  menu.Append( new wxMenuItem( &menu, ID_HIGHLIGHT_NET,
2147  wxString::Format( _( "Highlight nets in %s" ), name ),
2148  wxEmptyString, wxITEM_NORMAL ) );
2149  menu.Append( new wxMenuItem( &menu, ID_SELECT_NET,
2150  wxString::Format( _( "Select tracks and vias in %s" ),
2151  name ),
2152  wxEmptyString, wxITEM_NORMAL ) );
2153  menu.Append( new wxMenuItem( &menu, ID_DESELECT_NET,
2154  wxString::Format( _( "Deselect tracks and vias in %s" ),
2155  name ),
2156  wxEmptyString, wxITEM_NORMAL ) );
2157 
2158  menu.AppendSeparator();
2159 
2160  menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_NETS,
2161  _( "Show all netclasses" ), wxEmptyString,
2162  wxITEM_NORMAL ) );
2163  menu.Append( new wxMenuItem( &menu, ID_HIDE_OTHER_NETS,
2164  _( "Hide all other netclasses" ), wxEmptyString,
2165  wxITEM_NORMAL ) );
2166 
2167  menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
2169 
2170  PopupMenu( &menu );
2171  };
2172 
2173  setting->ctl_panel->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2174  setting->ctl_visibility->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2175  setting->ctl_color->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2176  setting->ctl_text->Bind( wxEVT_RIGHT_DOWN, menuHandler );
2177  };
2178 
2179  const NETCLASS_MAP& classes = board->GetDesignSettings().GetNetClasses().NetClasses();
2180 
2181  std::vector<wxString> names;
2182 
2183  for( const auto& pair : classes )
2184  names.emplace_back( pair.first );
2185 
2186  std::sort( names.begin(), names.end() );
2187 
2188  m_netclassIdMap.clear();
2189 
2190  int idx = wxID_HIGHEST;
2191 
2192  NETCLASSPTR defaultClass = board->GetDesignSettings().GetNetClasses().GetDefault();
2193 
2194  m_netclassIdMap[idx] = defaultClass->GetName();
2195  appendNetclass( idx++, defaultClass, true );
2196 
2197  for( const wxString& name : names )
2198  {
2199  m_netclassIdMap[idx] = name;
2200  appendNetclass( idx++, classes.at( name ) );
2201  }
2202 
2203  m_netclassOuterSizer->Layout();
2204 
2205  m_netsTable->Rebuild();
2206  m_panelNets->GetSizer()->Layout();
2207 }
2208 
2209 
2211 {
2212  m_cbLayerPresets->Clear();
2213 
2214  for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2215  m_cbLayerPresets->Append( pair.first, static_cast<void*>( &pair.second ) );
2216 
2217  m_cbLayerPresets->Append( wxT( "-----" ) );
2218  m_cbLayerPresets->Append( _( "Save preset..." ) );
2219  m_cbLayerPresets->Append( _( "Delete preset..." ) );
2220 
2221  m_cbLayerPresets->SetSelection( 0 );
2222 
2223  // At least the build in presets should always be present
2224  wxASSERT( !m_layerPresets.empty() );
2225 
2226  // Default preset: all layers
2228 }
2229 
2230 
2232 {
2233  LSET visibleLayers = getVisibleLayers();
2234  GAL_SET visibleObjects = getVisibleObjects();
2235 
2236  auto it = std::find_if( m_layerPresets.begin(), m_layerPresets.end(),
2237  [&]( const std::pair<const wxString, LAYER_PRESET>& aPair )
2238  {
2239  return ( aPair.second.layers == visibleLayers
2240  && aPair.second.renderLayers == visibleObjects );
2241  } );
2242 
2243  if( it != m_layerPresets.end() )
2244  m_cbLayerPresets->SetStringSelection( it->first );
2245  else
2246  m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2247 
2248  m_currentPreset = static_cast<LAYER_PRESET*>(
2249  m_cbLayerPresets->GetClientData( m_cbLayerPresets->GetSelection() ) );
2250 }
2251 
2252 
2254 {
2255  int idx = m_cbLayerPresets->FindString( aName );
2256 
2257  if( idx >= 0 && m_cbLayerPresets->GetSelection() != idx )
2258  {
2259  m_cbLayerPresets->SetSelection( idx );
2260  m_currentPreset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( idx ) );
2261  }
2262  else if( idx < 0 )
2263  {
2264  m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 ); // separator
2265  }
2266 }
2267 
2268 
2269 void APPEARANCE_CONTROLS::onLayerPresetChanged( wxCommandEvent& aEvent )
2270 {
2271  int count = m_cbLayerPresets->GetCount();
2272  int index = m_cbLayerPresets->GetSelection();
2273 
2274  auto resetSelection =
2275  [&]()
2276  {
2277  if( m_currentPreset )
2278  m_cbLayerPresets->SetStringSelection( m_currentPreset->name );
2279  else
2280  m_cbLayerPresets->SetSelection( m_cbLayerPresets->GetCount() - 3 );
2281  };
2282 
2283  if( index == count - 3 )
2284  {
2285  // Separator: reject the selection
2286  resetSelection();
2287  return;
2288  }
2289  else if( index == count - 2 )
2290  {
2291  // Save current state to new preset
2292  wxString name;
2293 
2296 
2297  wxTextEntryDialog dlg( this, _( "Layer preset name:" ), _( "Save Layer Preset" ), name );
2298 
2299  if( dlg.ShowModal() != wxID_OK )
2300  {
2301  resetSelection();
2302  return;
2303  }
2304 
2305  name = dlg.GetValue();
2306  bool exists = m_layerPresets.count( name );
2307 
2308  if( !exists )
2311 
2312  LAYER_PRESET* preset = &m_layerPresets[name];
2313  m_currentPreset = preset;
2314 
2315  if( !exists )
2316  {
2317  index = m_cbLayerPresets->Insert( name, index - 1, static_cast<void*>( preset ) );
2318  }
2319  else
2320  {
2321  index = m_cbLayerPresets->FindString( name );
2322  m_presetMRU.Remove( name );
2323  }
2324 
2325  m_cbLayerPresets->SetSelection( index );
2326  m_presetMRU.Insert( name, 0 );
2327 
2328  return;
2329  }
2330  else if( index == count - 1 )
2331  {
2332  // Delete a preset
2333  wxArrayString headers;
2334  std::vector<wxArrayString> items;
2335 
2336  headers.Add( _( "Presets" ) );
2337 
2338  for( std::pair<const wxString, LAYER_PRESET>& pair : m_layerPresets )
2339  {
2340  if( !pair.second.readOnly )
2341  {
2342  wxArrayString item;
2343  item.Add( pair.first );
2344  items.emplace_back( item );
2345  }
2346  }
2347 
2348  EDA_LIST_DIALOG dlg( m_frame, _( "Delete Preset" ), headers, items, wxEmptyString );
2349  dlg.SetListLabel( _( "Select preset:" ) );
2350 
2351  if( dlg.ShowModal() == wxID_OK )
2352  {
2353  wxString presetName = dlg.GetTextSelection();
2354  int idx = m_cbLayerPresets->FindString( presetName );
2355 
2356  if( idx != wxNOT_FOUND )
2357  {
2358  m_layerPresets.erase( presetName );
2359 
2360  m_cbLayerPresets->Delete( idx );
2361  m_currentPreset = nullptr;
2362 
2363  m_presetMRU.Remove( presetName );
2364  }
2365  }
2366 
2367  resetSelection();
2368  return;
2369  }
2370 
2371  LAYER_PRESET* preset = static_cast<LAYER_PRESET*>( m_cbLayerPresets->GetClientData( index ) );
2372  m_currentPreset = preset;
2373 
2374  m_lastSelectedUserPreset = ( !preset || preset->readOnly ) ? nullptr : preset;
2375 
2376  if( preset )
2377  doApplyLayerPreset( *preset );
2378 
2379  if( !m_currentPreset->name.IsEmpty() )
2380  {
2381  m_presetMRU.Remove( m_currentPreset->name );
2382  m_presetMRU.Insert( m_currentPreset->name, 0 );
2383  }
2384 
2385  passOnFocus();
2386 }
2387 
2388 
2390 {
2391  BOARD* board = m_frame->GetBoard();
2392 
2393  setVisibleLayers( aPreset.layers );
2394  setVisibleObjects( aPreset.renderLayers );
2395 
2396  // If the preset doesn't have an explicit active layer to restore, we can at least
2397  // force the active layer to be something in the preset's layer set
2398  PCB_LAYER_ID activeLayer = UNSELECTED_LAYER;
2399 
2400  if( aPreset.activeLayer != UNSELECTED_LAYER )
2401  activeLayer = aPreset.activeLayer;
2402  else if( aPreset.layers.any() && !aPreset.layers.test( m_frame->GetActiveLayer() ) )
2403  activeLayer = *aPreset.layers.Seq().begin();
2404 
2405  LSET boardLayers = board->GetLayerSet();
2406 
2407  if( activeLayer != UNSELECTED_LAYER && boardLayers.Contains( activeLayer ) )
2408  m_frame->SetActiveLayer( activeLayer );
2409 
2410  if( !m_isFpEditor )
2411  m_frame->GetCanvas()->SyncLayersVisibility( board );
2412 
2413  m_frame->GetCanvas()->Refresh();
2414 
2416 }
2417 
2418 
2419 void APPEARANCE_CONTROLS::OnColorSwatchChanged( wxCommandEvent& aEvent )
2420 {
2421  COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
2422  COLOR4D newColor = swatch->GetSwatchColor();
2423  LAYER_NUM layer = swatch->GetId();
2424 
2426  cs->SetColor( layer, newColor );
2427 
2429 
2430  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
2431  view->UpdateLayerColor( layer );
2432  view->UpdateLayerColor( GetNetnameLayer( layer ) );
2433 
2434  if( IsCopperLayer( layer ) )
2435  view->UpdateLayerColor( ZONE_LAYER_FOR( layer ) );
2436 
2437  // Update the bitmap of the layer box
2438  if( m_frame->IsType( FRAME_PCB_EDITOR ) )
2439  static_cast<PCB_EDIT_FRAME*>( m_frame )->ReCreateLayerBox( false );
2440 
2441  m_frame->GetCanvas()->Refresh();
2442 
2443  if( layer == LAYER_PCB_BACKGROUND )
2444  m_frame->SetDrawBgColor( newColor );
2445 
2446  passOnFocus();
2447 }
2448 
2449 
2450 void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
2451 {
2453 
2454  switch( aLayer )
2455  {
2456  case static_cast<int>( LAYER_TRACKS ): options.m_TrackOpacity = aOpacity; break;
2457  case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
2458  case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
2459  case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
2460  default: return;
2461  }
2462 
2463  m_frame->SetDisplayOptions( options );
2464  passOnFocus();
2465 }
2466 
2467 
2468 void APPEARANCE_CONTROLS::onNetContextMenu( wxCommandEvent& aEvent )
2469 {
2470  wxASSERT( m_netsGrid->GetSelectedRows().size() == 1 );
2471 
2472  int row = m_netsGrid->GetSelectedRows()[0];
2473  NET_GRID_ENTRY& net = m_netsTable->GetEntry( row );
2474 
2475  m_netsGrid->ClearSelection();
2476 
2477  switch( aEvent.GetId() )
2478  {
2479  case ID_SET_NET_COLOR:
2480  {
2481  wxGridCellEditor* editor = m_netsGrid->GetCellEditor( row, NET_GRID_TABLE::COL_COLOR );
2482  editor->BeginEdit( row, NET_GRID_TABLE::COL_COLOR, m_netsGrid );
2483  break;
2484  }
2485 
2486  case ID_HIGHLIGHT_NET:
2487  {
2489  m_frame->GetCanvas()->Refresh();
2490  break;
2491  }
2492 
2493  case ID_SELECT_NET:
2494  {
2496  m_frame->GetCanvas()->Refresh();
2497  break;
2498  }
2499 
2500  case ID_DESELECT_NET:
2501  {
2503  m_frame->GetCanvas()->Refresh();
2504  break;
2505  }
2506 
2507  case ID_SHOW_ALL_NETS:
2509  break;
2510 
2511  case ID_HIDE_OTHER_NETS:
2512  m_netsTable->HideOtherNets( net );
2513  break;
2514 
2515  default:
2516  break;
2517  }
2518 
2519  passOnFocus();
2520 }
2521 
2522 
2524 {
2525  wxString className = netclassNameFromEvent( aEvent );
2526  bool show = aEvent.GetInt();
2527  showNetclass( className, show );
2528  passOnFocus();
2529 }
2530 
2531 
2532 void APPEARANCE_CONTROLS::showNetclass( const wxString& aClassName, bool aShow )
2533 {
2534  BOARD* board = m_frame->GetBoard();
2535  NETINFO_LIST& nets = board->GetNetInfo();
2536  NETCLASSES& classes = board->GetDesignSettings().GetNetClasses();
2537  NETCLASSPTR netclass = classes.Find( aClassName );
2538  TOOL_MANAGER* manager = m_frame->GetToolManager();
2539 
2540  if( !netclass )
2541  return;
2542 
2543  NETCLASS* defaultClass = classes.GetDefaultPtr();
2544 
2545  if( netclass == classes.GetDefault() )
2546  {
2547  const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet;
2548 
2549  for( NETINFO_ITEM* net : nets )
2550  {
2551  if( net->GetNetClass() == defaultClass )
2552  {
2553  manager->RunAction( action, true, net->GetNetCode() );
2554 
2555  int row = m_netsTable->GetRowByNetcode( net->GetNetCode() );
2556 
2557  if( row >= 0 )
2559  }
2560  }
2561  }
2562  else
2563  {
2564  const TOOL_ACTION& action = aShow ? PCB_ACTIONS::showNet : PCB_ACTIONS::hideNet;
2565 
2566  for( const wxString& member : *netclass )
2567  {
2568  if( NETINFO_ITEM* net = nets.GetNetItem( member ) )
2569  {
2570  int code = net->GetNetCode();
2571  manager->RunAction( action, true, code );
2572 
2573  int row = m_netsTable->GetRowByNetcode( code );
2574 
2575  if( row >= 0 )
2577  }
2578  }
2579  }
2580 
2581  m_netsGrid->ForceRefresh();
2582 }
2583 
2584 
2585 void APPEARANCE_CONTROLS::onNetclassColorChanged( wxCommandEvent& aEvent )
2586 {
2587  KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
2589 
2590  std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
2591 
2592  COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
2593  wxString className = netclassNameFromEvent( aEvent );
2594 
2595  netclassColors[className] = swatch->GetSwatchColor();
2596 
2599  m_frame->GetCanvas()->Refresh();
2600 }
2601 
2602 
2604 {
2605  COLOR_SWATCH* s = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
2606  int classId = s->GetId();
2607 
2608  wxASSERT( m_netclassIdMap.count( classId ) );
2609  return m_netclassIdMap.at( classId );
2610 }
2611 
2612 
2613 void APPEARANCE_CONTROLS::onNetColorModeChanged( wxCommandEvent& aEvent )
2614 {
2616 
2617  if( m_rbNetColorAll->GetValue() )
2619  else if( m_rbNetColorRatsnest->GetValue() )
2621  else
2623 
2624  m_frame->SetDisplayOptions( options );
2626  passOnFocus();
2627 }
2628 
2629 
2630 void APPEARANCE_CONTROLS::onRatsnestModeChanged( wxCommandEvent& aEvent )
2631 {
2633 
2634  if( m_rbRatsnestAllLayers->GetValue() )
2636  else
2638 
2639  m_frame->SetDisplayOptions( options );
2641  passOnFocus();
2642 }
2643 
2644 
2645 void APPEARANCE_CONTROLS::onNetclassContextMenu( wxCommandEvent& aEvent )
2646 {
2647  KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
2649  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
2650 
2651  BOARD* board = m_frame->GetBoard();
2652  NETINFO_LIST& nets = board->GetNetInfo();
2653  NETCLASSES& classes = board->GetDesignSettings().GetNetClasses();
2654  NETCLASSPTR netclass = classes.Find( m_contextMenuNetclass );
2655 
2658 
2659  NETCLASSPTR defaultClass = classes.GetDefault();
2660  wxString defaultClassName = defaultClass->GetName();
2661 
2662  auto runOnNetsOfClass =
2663  [&]( NETCLASSPTR aClass, std::function<void( NETINFO_ITEM* )> aFunction )
2664  {
2665  if( aClass == defaultClass )
2666  {
2667  for( NETINFO_ITEM* net : nets )
2668  if( net->GetNetClass() == defaultClass.get() )
2669  aFunction( net );
2670  }
2671  else
2672  {
2673  for( const wxString& netName : *aClass )
2674  aFunction( nets.GetNetItem( netName ) );
2675  }
2676  };
2677 
2678  switch( aEvent.GetId() )
2679  {
2680  case ID_SET_NET_COLOR:
2681  {
2682  if( setting )
2683  {
2684  setting->ctl_color->GetNewSwatchColor();
2685 
2686  COLOR4D color = setting->ctl_color->GetSwatchColor();
2687 
2688  std::map<wxString, KIGFX::COLOR4D>& netclassColors = rs->GetNetclassColorMap();
2689 
2690  if( color != COLOR4D::UNSPECIFIED )
2691  netclassColors[m_contextMenuNetclass] = color;
2692  else
2693  netclassColors.erase( m_contextMenuNetclass );
2694 
2695  view->UpdateAllLayersColor();
2696  }
2697 
2698  break;
2699  }
2700 
2701  case ID_HIGHLIGHT_NET:
2702  {
2703  if( netclass )
2704  {
2705  runOnNetsOfClass( netclass,
2706  [&]( NETINFO_ITEM* aItem )
2707  {
2708  if( !aItem )
2709  return;
2710 
2711  static bool first = true;
2712  int code = aItem->GetNetCode();
2713 
2714  if( first )
2715  {
2716  board->SetHighLightNet( code );
2717  rs->SetHighlight( true, code );
2718  first = false;
2719  }
2720  else
2721  {
2722  board->SetHighLightNet( code, true );
2723  rs->SetHighlight( true, code, true );
2724  }
2725  } );
2726 
2727  view->UpdateAllLayersColor();
2728  board->HighLightON();
2729  }
2730  break;
2731  }
2732 
2733  case ID_SELECT_NET:
2734  case ID_DESELECT_NET:
2735  {
2736  if( netclass )
2737  {
2738  TOOL_ACTION& action = aEvent.GetId() == ID_SELECT_NET ? PCB_ACTIONS::selectNet :
2740  runOnNetsOfClass( netclass,
2741  [&]( NETINFO_ITEM* aItem )
2742  {
2743  if( !aItem )
2744  return;
2745 
2746  int code = aItem->GetNetCode();
2747  m_frame->GetToolManager()->RunAction( action, true, code );
2748  } );
2749  }
2750  break;
2751  }
2752 
2753  case ID_SHOW_ALL_NETS:
2754  {
2755  showNetclass( defaultClassName );
2756  wxASSERT( m_netclassSettingsMap.count( defaultClassName ) );
2757  m_netclassSettingsMap.at( defaultClassName )->ctl_visibility->SetValue( true );
2758 
2759  for( const auto& pair : classes.NetClasses() )
2760  {
2761  showNetclass( pair.first );
2762 
2763  if( m_netclassSettingsMap.count( pair.first ) )
2764  m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( true );
2765  }
2766 
2767  break;
2768  }
2769 
2770  case ID_HIDE_OTHER_NETS:
2771  {
2772  bool showDefault = m_contextMenuNetclass == defaultClassName;
2773  showNetclass( defaultClassName, showDefault );
2774  wxASSERT( m_netclassSettingsMap.count( defaultClassName ) );
2775  m_netclassSettingsMap.at( defaultClassName )->ctl_visibility->SetValue( showDefault );
2776 
2777  for( const auto& pair : classes.NetClasses() )
2778  {
2779  bool show = pair.first == m_contextMenuNetclass;
2780 
2781  showNetclass( pair.first, show );
2782 
2783  if( m_netclassSettingsMap.count( pair.first ) )
2784  m_netclassSettingsMap.at( pair.first )->ctl_visibility->SetValue( show );
2785  }
2786 
2787  break;
2788  }
2789 
2790  default:
2791  break;
2792  }
2793 
2795  m_frame->GetCanvas()->Refresh();
2796 
2797  m_contextMenuNetclass.clear();
2798 }
2799 
2800 
2802 {
2803  m_focusOwner->SetFocus();
2804 }
2805 
2806 
2808 {
2809  WX_INFOBAR* infobar = m_frame->GetInfoBar();
2810 
2811  wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Open Preferences" ),
2812  wxEmptyString );
2813 
2814  button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
2815  [&]( wxHyperlinkEvent& aEvent )
2816  {
2817  wxCommandEvent dummy;
2819  } ) );
2820 
2821  infobar->RemoveAllButtons();
2822  infobar->AddButton( button );
2823  infobar->AddCloseButton();
2824 
2825  infobar->ShowMessageFor( _( "The current color theme is read-only. Create a new theme in "
2826  "Preferences to enable color editing." ),
2827  10000, wxICON_INFORMATION );
2828 }
static std::set< int > s_allowedInFpEditor
These GAL layers are shown in the Objects tab in the footprint editor.
void OnSize(wxSizeEvent &aEvent) override
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
void ShowMessageFor(const wxString &aMessage, int aTime, int aFlags=wxICON_INFORMATION)
Show the infobar with the provided message and icon for a specific period of time.
Definition: infobar.cpp:113
static LAYER_PRESET presetFrontAssembly
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:1953
A saved set of layers that are visible.
std::set< int > & GetHiddenNets()
Definition: pcb_painter.h:187
Virtual layers for stacking zones and tracks on a given copper layer.
bool SetBackgroundColour(const wxColour &aColor) override
void SetIndicatorState(ICON_ID aIconId)
Set the row indicator to the given state.
wxSize GetBestSize() const
Update the panel contents from the application and board models.
void onObjectOpacitySlider(int aLayer, float aOpacity)
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:170
show a marker on pads with no nets
std::map< PCB_LAYER_ID, APPEARANCE_SETTING * > m_layerSettingsMap
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: infobar.cpp:236
void OnNetGridMouseEvent(wxMouseEvent &aEvent)
#define RR
Icon provider for the "standard" row indicators, for example in layer selection lists.
KIGFX::COLOR4D GetSwatchColor() const
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
static COLOR4D VoidToColor(void *aColor)
void SetElementVisibility(GAL_LAYER_ID aLayer, bool aNewState)
Change the visibility of an element category.
Definition: board.cpp:513
Class APPEARANCE_CONTROLS_BASE.
NETCLASSPTR Find(const wxString &aName) const
Search this container for a NETCLASS given by aName.
Definition: netclass.cpp:132
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:342
void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
void * GetValueAsCustom(int aRow, int aCol, const wxString &aTypeName) override
void HideOtherNets(const NET_GRID_ENTRY &aNet)
void ApplyLayerPreset(const wxString &aPresetName)
Ratsnest lines are drawn to items on visible layers only.
multilayer pads, usually with holes
#define ON
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
#define ZONE_LAYER_FOR(copperLayer)
Macro for getting the zone layer for a given copper layer.
WX_COLLAPSIBLE_PANE * m_paneLayerDisplayOptions
void SetValueAsCustom(int aRow, int aCol, const wxString &aTypeName, void *aValue) override
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:888
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_layerSettings
GAL_LAYER_ID ToGalLayer(int aInteger)
static TOOL_ACTION hideNet
Definition: pcb_actions.h:451
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: bitmap.cpp:221
double m_TrackOpacity
Opacity override for all tracks.
anchor of items having an anchor point (texts, footprints)
Control for copper zone opacity/visibility (color ignored)
NETCLASS_MAP & NetClasses()
Provide public access to m_NetClasses so it gets swigged.
Definition: netclass.h:290
LAYER_PRESET * m_lastSelectedUserPreset
The last user (non-read-only) preset selected by the user.
std::map< wxString, KIGFX::COLOR4D > & GetNetclassColorMap()
Definition: pcb_painter.h:183
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void OnBoardItemsChanged(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
Update the colors on all the widgets from the new chosen color theme.
std::map< int, wxString > m_netclassIdMap
Stores wxIDs for each netclass for control event mapping.
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
Definition: pcb_actions.h:81
bool Contains(PCB_LAYER_ID aLayer)
See if the layer set contains a PCB layer.
void onNetColorModeChanged(wxCommandEvent &aEvent)
int color
Definition: DXF_plotter.cpp:60
wxRadioButton * m_rbNetColorOff
double m_ViaOpacity
Opacity override for all types of via.
wxStaticLine * m_layerDisplaySeparator
void idleFocusHandler(wxIdleEvent &aEvent)
const BITMAP_OPAQUE show_no_copper_layers_xpm[1]
Net/netclass colors are shown on all net copper.
Net/netclass colors are shown on ratsnest lines only.
wxRadioButton * m_rbRatsnestAllLayers
show footprints on back
PROJECT * GetProject() const
Definition: board.h:430
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings Returns a bit-mask of all t...
Definition: board.cpp:461
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
COLOR4D color
void SetVisibleElements(const GAL_SET &aMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:480
show footprints values (when texts are visibles)
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
static void * ColorToVoid(COLOR4D &aColor)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
A dialog which shows:
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:752
NET_GRID_TABLE(PCB_BASE_FRAME *aFrame, wxColor aBackgroundColor)
void SetValue(bool aValue)
Read the checkbox state.
wxRadioButton * m_rbHighContrastOff
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions)
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings Returns a bit-mask of all t...
Definition: board.cpp:447
wxGridCellAttr * m_defaultAttr
void SetDrawBgColor(COLOR4D aColor) override
void OnNetGridClick(wxGridEvent &event) override
void SetReadOnly(bool aReadOnly=true)
Definition: color_swatch.h:104
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:65
const BITMAP_OPAQUE show_back_assembly_layers_xpm[1]
int code
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:411
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:241
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
GAL_SET renderLayers
Render layers (e.g. object types) that are visible.
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:874
PCB_LAYER_ID activeLayer
Optional layer to set active when this preset is loaded.
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:108
std::map< GAL_LAYER_ID, APPEARANCE_SETTING * > m_objectSettingsMap
const BITMAP_OPAQUE show_all_copper_layers_xpm[1]
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:207
A checkbox control except with custom bitmaps for the checked and unchecked states.
Definition: bitmap_toggle.h:41
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
bool visible
wxScrolledWindow * m_netclassScrolledWindow
Ratsnest lines are drawn to items on all layers (default)
Auxiliary rendering target (noncached)
Definition: definitions.h:49
PCB_BASE_FRAME * m_frame
const NETNAMES_MAP & NetsByName() const
Return the name map, at least for python.
Definition: netinfo.h:358
void OnBoardItemsRemoved(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
show footprints on front
virtual COLOR_SETTINGS * GetColorSettings() const override
Helper to retrieve the current color settings.
virtual PCB_LAYER_ID GetActiveLayer() const
const BITMAP_OPAQUE list_nets_16_xpm[1]
wxString name
A name for this layer set.
void onRatsnestModeChanged(wxCommandEvent &aEvent)
PCB specific render settings.
Definition: pcb_painter.h:64
Master controller class:
Definition: tool_manager.h:52
void showNetclass(const wxString &aClassName, bool aShow=true)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:82
RATSNEST_MODE m_RatsnestMode
Ratsnest draw mode (all layers vs only visible layers)
const BITMAP_OPAQUE show_front_assembly_layers_xpm[1]
void UpdateDisplayOptions()
Return a list of the layer presets created by the user.
static LSET BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
Definition: lset.cpp:696
Container for display options like enable/disable some optional drawings.
Non-active layers are dimmed (old high-contrast mode)
PCB_LAYER_ID
A quick note on layer IDs:
representing a row indicator icon for use in places like the layer widget
double a
Alpha component.
Definition: color4d.h:361
void OnBoardNetSettingsChanged(BOARD &aBoard) override
LSET is a set of PCB_LAYER_IDs.
static LAYER_PRESET presetNoLayers
A container for NETCLASS instances.
Definition: netclass.h:218
void OnNetGridDoubleClick(wxGridEvent &event) override
GRID_BITMAP_TOGGLE_RENDERER * m_toggleGridRenderer
const BITMAP_OPAQUE show_all_back_layers_xpm[1]
bool readOnly
True if this is a read-only (built-in) preset.
void onNetclassVisibilityChanged(wxCommandEvent &aEvent)
void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
const BITMAP_OPAQUE select_w_layer_xpm[1]
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:247
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:574
wxGridCellAttr * m_labelAttr
Container for NETINFO_ITEM elements, which are the nets.
Definition: netinfo.h:315
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
std::map< wxString, APPEARANCE_SETTING * > m_netclassSettingsMap
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings changes the bit-mask of vis...
Definition: board.cpp:473
std::map< wxString, LAYER_PRESET > m_layerPresets
GAL_SET GetVisibleElements() const
Returns a set of all the element categories that are visible.
Definition: board.cpp:501
void OnSetFocus(wxFocusEvent &aEvent) override
ROW_ICON_PROVIDER * m_iconProvider
void setVisibleLayers(LSET aLayers)
void doApplyLayerPreset(const LAYER_PRESET &aPreset)
Meta control for all pads opacity/visibility (color ignored)
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
Non-active layers are shown normally (no high-contrast mode)
HIGH_CONTRAST_MODE
Determine how inactive layers should be displayed.
COLOR4D GetDefaultColor(int aLayer)
Helper for storing and iterating over GAL_LAYER_IDs.
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:710
const BITMAP_OPAQUE show_all_layers_xpm[1]
LAYER_PRESET * m_currentPreset
Helper dialog and control classes.
wxRadioButton * m_rbHighContrastNormal
static GAL_SET DefaultVisible()
Definition: lset.cpp:933
void SetPadding(int aPadding)
Set the amount of padding present on each side of the bitmap.
void onLayerClick(wxMouseEvent &aEvent)
wxStaticText * m_txtNetDisplayTitle
void onNetContextMenu(wxCommandEvent &aEvent)
static LSET FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
Definition: lset.cpp:682
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
wxBoxSizer * m_objectsOuterSizer
NETCLASSES & GetNetClasses() const
static LSET AllLayersMask()
Definition: lset.cpp:787
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:387
const BITMAP_OPAQUE visibility_xpm[1]
Definition: visibility.cpp:32
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind) override
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
LSET layers
Board layers that are visible.
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
NETCLASS * GetDefaultPtr() const
Definition: netclass.h:258
void SyncLayersVisibility(const BOARD *aBoard)
Update "visibility" property of each layer of a given BOARD.
void SetUserLayerPresets(std::vector< LAYER_PRESET > &aPresetList)
int GetTabIndex() const
Set the current notebook tab.
Container for an appearance setting (can control a single board layer, or GAL layer,...
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
APPEARANCE_CONTROLS(PCB_BASE_FRAME *aParent, wxWindow *aFocusOwner, bool aFpEditor=false)
std::vector< LAYER_PRESET > GetUserLayerPresets() const
Update the current layer presets from those saved in the project file.
void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_netclassSettings
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:277
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
double m_ZoneOpacity
Opacity override for filled zone areas.
void UpdateColors()
Update the color settings in the painter and GAL.
int LAYER_NUM
This can be replaced with int and removed.
void onLayerPresetChanged(wxCommandEvent &aEvent) override
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition: view.h:237
wxRadioButton * m_rbHighContrastDim
layer for drc markers which have been individually excluded
NET_GRID_ENTRY & GetEntry(int aRow)
bool GetValueAsBool(int aRow, int aCol) override
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
layer for drc markers with SEVERITY_WARNING
int GetRowByNetcode(int aCode) const
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:749
void SetValueAsBool(int aRow, int aCol, bool aValue) override
void OnNetVisibilityChanged(int aNetCode, bool aVisibility)
Notifies the panel when a net has been hidden or shown via the external tool.
void updateLayerPresetSelection(const wxString &aName)
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:71
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
static LAYER_PRESET presetInnerCopper
COLOR4D GetColor(int aLayer) const
Handle the data for a net.
Definition: netinfo.h:64
double m_PadOpacity
Opacity override for SMD pads and PTHs.
static TOOL_ACTION showNet
Definition: pcb_actions.h:452
int GetId() const
Return the unique id of the TOOL_ACTION object.
Definition: tool_action.h:103
Meta control for all vias opacity/visibility.
static TOOL_ACTION highlightNet
Definition: pcb_actions.h:446
bool IsType(FRAME_T aType) const
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
const char * name
Definition: DXF_plotter.cpp:59
static LAYER_PRESET presetBackAssembly
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
void setVisibleObjects(GAL_SET aObjects)
std::vector< std::unique_ptr< APPEARANCE_SETTING > > m_objectSettings
void SetBitmap(const wxBitmap &aBmp)
Set the bitmap shown when the button is enabled.
#define _(s)
Definition: 3d_actions.cpp:33
Net (and netclass) colors are not shown.
static TOOL_ACTION listNets
Definition: pcb_actions.h:341
const BITMAP_OPAQUE options_generic_16_xpm[1]
A toggle button renderer for a wxGrid, similar to BITMAP_TOGGLE.
class NETINFO_ITEM, a description of a net
Definition: typeinfo.h:107
Represent a single user action.
Definition: tool_action.h:49
NET_GRID_TABLE * m_netsTable
wxString GetTypeName(int aRow, int aCol) override
int GetCopperLayerCount() const
Definition: board.cpp:435
wxString netclassNameFromEvent(wxEvent &aEvent)
wxString GetValue(int aRow, int aCol) override
The main frame for Pcbnew.
Class representing a simple color swatch, of the kind used to set layer colors.
Definition: color_swatch.h:57
void SetValue(int aRow, int aCol, const wxString &aValue) override
void OnNotebookPageChanged(wxNotebookEvent &event) override
bool IsReadOnly() const
Definition: json_settings.h:74
void onObjectVisibilityChanged(GAL_LAYER_ID aLayer, bool isVisible, bool isFinal)
void onNetclassColorChanged(wxCommandEvent &aEvent)
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:881
static const wxSize SWATCH_SIZE_SMALL_DU(8, 6)
static TOOL_ACTION deselectNet
Remove all connections belonging to a single net from the active selection.
Definition: pcb_actions.h:84
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
void OnPreferences(wxCommandEvent &event)
wxString name
void GetNewSwatchColor()
Prompt for a new colour, using the colour picker dialog.
void OnBoardItemsAdded(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
Color settings are a bit different than most of the settings objects in that there can be more than o...
wxGridCellCoords m_hoveredCell
Grid cell that is being hovered over, for tooltips.
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
WX_INFOBAR * GetInfoBar()
wxBoxSizer * m_layersOuterSizer
std::vector< NET_GRID_ENTRY > m_nets
void SetLayerVisible(LAYER_NUM aLayer, bool isVisible)
const BITMAP_OPAQUE show_all_front_layers_xpm[1]
wxString m_contextMenuNetclass
The name of the netclass that was right-clicked.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
drawingsheet frame and titleblock
void onNetclassContextMenu(wxCommandEvent &aEvent)
Non-active layers are hidden.
void OnNetGridRightClick(wxGridEvent &event) override
std::map< int, KIGFX::COLOR4D > & GetNetColorMap()
Definition: pcb_painter.h:185
static TOOL_ACTION flipBoard
Definition: pcb_actions.h:295
BOARD * GetBoard() const
PCB_BASE_FRAME * m_frame
void OnColorSwatchChanged(wxCommandEvent &aEvent)
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
void onLayerVisibilityChanged(PCB_LAYER_ID aLayer, bool isVisible, bool isFinal)
void OnLayerContextMenu(wxCommandEvent &aEvent)
Return the index of the current tab (0-2).
NETINFO_ITEM * GetNetItem(int aNetCode) const
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:770
void Collapse(bool aCollapse=true)
static LAYER_PRESET presetFront
void OnColorThemeChanged()
Update the widget when the active board layer is changed.
wxStaticText * m_txtRatsnestVisibility
A better wxCollapsiblePane that.
static LAYER_PRESET presetAllCopper
void updateNetColor(const NET_GRID_ENTRY &aNet)
static const APPEARANCE_SETTING s_objectSettings[]
Template for object appearance settings.
Definition of PCB_DISPLAY_OPTIONS class.
bool doesBoardItemNeedRebuild(BOARD_ITEM *aBoardItem)
static LAYER_PRESET presetAllLayers
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905
virtual void SetGridVisibility(bool aVisible)
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
const BITMAP_OPAQUE visibility_off_xpm[1]
void updateNetVisibility(const NET_GRID_ENTRY &aNet)
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:49
show footprints references (when texts are visibles)
wxStaticText * m_staticTextContrastModeTitle
layer for drc markers with SEVERITY_ERROR
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:178
void SetObjectVisible(GAL_LAYER_ID aLayer, bool isVisible=true)
Update the manual layer alpha overrides.
const BITMAP_OPAQUE show_no_layers_xpm[1]
A text renderer that can unescape text for display This is useful where it's desired to keep the unde...
WX_COLLAPSIBLE_PANE * m_paneNetDisplayOptions
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162
wxRadioButton * m_rbRatsnestVisibleLayers
void SetColor(int aLayer, COLOR4D aColor)
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:404
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: infobar.cpp:267
static LAYER_PRESET presetBack
wxRadioButton * m_rbNetColorRatsnest
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98
wxRadioButton * m_rbNetColorAll
void SetListLabel(const wxString &aLabel)
bool Contains(GAL_LAYER_ID aPos)
int GetNetCode() const
Definition: netinfo.h:113