KiCad PCB EDA Suite
layer_widget.cpp
Go to the documentation of this file.
1 
2 /*
3  * This program source code file is part of KiCad, a free EDA CAD application.
4  *
5  * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 
28 /* This source module implements the layer visibility and selection widget
29  @todo make bitmap size dependent on the point size.
30 */
31 
32 
33 //#define STAND_ALONE 1 // define to enable test program for LAYER_WIDGET
34 
35 
36 #include <layer_widget.h>
37 
38 #include <macros.h>
39 #include <common.h>
40 
41 #include <widgets/color_swatch.h>
42 #include <widgets/indicator_icon.h>
43 
44 #include <algorithm>
45 
46 
47 const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
48 
49 /*
50  * Icon providers for the row icons
51  */
52 static ROW_ICON_PROVIDER defaultRowIcons( false );
54 
59 static void shrinkFont( wxWindow* aControl, int aPointSize )
60 {
61  wxFont font = aControl->GetFont();
62  font.SetPointSize( aPointSize );
63  aControl->SetFont( font ); // need this?
64 }
65 
66 
67 int LAYER_WIDGET::encodeId( int aColumn, int aId )
68 {
69  int id = aId * LYR_COLUMN_COUNT + aColumn;
70  return id;
71 }
72 
73 
75 {
76  int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
77  return id;
78 }
79 
80 
81 void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
82 {
83  int row;
84  LAYER_NUM layer;
85 
86  wxWindow* eventSource = (wxWindow*) event.GetEventObject();
87 
88  // if mouse event is coming from the m_LayerScrolledWindow and not one
89  // of its children, we have to find the row manually based on y coord.
90  if( eventSource == m_LayerScrolledWindow )
91  {
92  int y = event.GetY();
93 
94  wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();
95 
96  int height = 0;
97 
98  int rowCount = GetLayerRowCount();
99  for( row = 0; row<rowCount; ++row )
100  {
101  if( y < height + heights[row] )
102  break;
103 
104  height += heights[row];
105  }
106 
107  if( row >= rowCount )
108  row = rowCount - 1;
109 
110  layer = getDecodedId( getLayerComp( row, 0 )->GetId() );
111  }
112 
113  else
114  {
115  // all nested controls on a given row will have their ID encoded with
116  // encodeId(), and the corresponding decoding is getDecodedId()
117  int id = eventSource->GetId();
118  layer = getDecodedId( id );
119  row = findLayerRow( layer );
120  }
121 
122  if( OnLayerSelect( layer ) ) // if client allows this change.
123  SelectLayerRow( row );
124 
125  passOnFocus();
126 }
127 
128 
129 void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent )
130 {
131  auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
132 
133  COLOR4D newColor = eventSource->GetSwatchColor();
134 
135  LAYER_NUM layer = getDecodedId( eventSource->GetId() );
136 
137  // tell the client code.
138  OnLayerColorChange( layer, newColor );
139 
140  // notify others
141  wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
142  wxPostEvent( this, event );
143 
144  passOnFocus();
145 }
146 
147 
148 void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
149 {
150  wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
151  LAYER_NUM layer = getDecodedId( eventSource->GetId() );
152  OnLayerVisible( layer, eventSource->IsChecked() );
153  passOnFocus();
154 }
155 
156 
157 void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
158 {
159  auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
160 
161  COLOR4D newColor = eventSource->GetSwatchColor();
162 
163  LAYER_NUM id = getDecodedId( eventSource->GetId() );
164 
165  // tell the client code.
166  OnRenderColorChange( id, newColor );
167 
168  passOnFocus();
169 }
170 
171 
172 void LAYER_WIDGET::OnRenderCheckBox( wxCommandEvent& event )
173 {
174  wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
175  LAYER_NUM id = getDecodedId( eventSource->GetId() );
176  OnRenderEnable( id, eventSource->IsChecked() );
177  passOnFocus();
178 }
179 
180 
181 void LAYER_WIDGET::OnTabChange( wxNotebookEvent& event )
182 {
183 // wxFocusEvent event( wxEVT_SET_FOCUS );
184 // m_FocusOwner->AddPendingEvent( event );
185 
186  passOnFocus(); // does not work in this context, probably because we have receive control here too early.
187 }
188 
189 
190 wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
191 {
192  unsigned ndx = aRow * LYR_COLUMN_COUNT + aColumn;
193 
194  if( ndx < m_LayersFlexGridSizer->GetChildren().GetCount() )
195  return m_LayersFlexGridSizer->GetChildren()[ndx]->GetWindow();
196 
197  return NULL;
198 }
199 
200 
202 {
203  int count = GetLayerRowCount();
204 
205  for( int row = 0; row < count; ++row )
206  {
207  // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
208  wxWindow* w = getLayerComp( row, 0 );
209  wxASSERT( w );
210 
211  if( aLayer == getDecodedId( w->GetId() ))
212  return row;
213  }
214 
215  return -1;
216 }
217 
218 
219 wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
220 {
221  int ndx = aRow * RND_COLUMN_COUNT + aColumn;
222 
223  if( (unsigned) ndx < m_RenderFlexGridSizer->GetChildren().GetCount() )
224  return m_RenderFlexGridSizer->GetChildren()[ndx]->GetWindow();
225 
226  return NULL;
227 }
228 
229 
230 int LAYER_WIDGET::findRenderRow( int aId ) const
231 {
232  int count = GetRenderRowCount();
233 
234  for( int row = 0; row < count; ++row )
235  {
236  // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
237  wxWindow* w = getRenderComp( row, 0 );
238  wxASSERT( w );
239 
240  if( aId == getDecodedId( w->GetId() ))
241  return row;
242  }
243 
244  return -1;
245 }
246 
247 
248 void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
249 {
250  wxASSERT( aRow >= 0 );
251 
252  int col;
253  int index = aRow * LYR_COLUMN_COUNT;
254  const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
255 
256  auto& iconProvider = useAlternateBitmap(aRow) ? alternativeRowIcons : defaultRowIcons;
257 
258  // column 0
259  col = COLUMN_ICON_ACTIVE;
260  auto sbm = new INDICATOR_ICON( m_LayerScrolledWindow, iconProvider,
262  encodeId( col, aSpec.id ) );
263  sbm->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
264  m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
265 
266  // column 1 (COLUMN_COLORBM)
267  col = COLUMN_COLORBM;
268 
269  auto bmb = new COLOR_SWATCH( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
271  bmb->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
272  bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnLayerSwatchChanged, this );
273  bmb->SetToolTip( _("Left double click or middle click for color change, right click for menu" ) );
274  m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
275 
276  // column 2 (COLUMN_COLOR_LYR_CB)
277  col = COLUMN_COLOR_LYR_CB;
278  wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, encodeId( col, aSpec.id ), wxEmptyString );
279  cb->SetValue( aSpec.state );
280  cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnLayerCheckBox, this );
281  cb->SetToolTip( _( "Enable this for visibility" ) );
282  m_LayersFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
283 
284  // column 3 (COLUMN_COLOR_LYRNAME)
285  col = COLUMN_COLOR_LYRNAME;
286  wxStaticText* st = new wxStaticText( m_LayerScrolledWindow, encodeId( col, aSpec.id ), aSpec.rowName );
287  shrinkFont( st, m_PointSize );
288  st->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
289  st->SetToolTip( aSpec.tooltip );
290  m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags );
291 }
292 
293 
294 void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
295 {
296  wxASSERT( aRow >= 0 );
297 
298  int col;
299  int index = aRow * RND_COLUMN_COUNT;
300  const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
301 
302  // column 0
303  col = 0;
304  if( aSpec.color != COLOR4D::UNSPECIFIED )
305  {
306  auto bmb = new COLOR_SWATCH( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
308  bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnRenderSwatchChanged, this );
309  bmb->SetToolTip( _( "Left double click or middle click for color change" ) );
310  m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
311 
312  // could add a left click handler on the color button that toggles checkbox.
313  }
314  else // == -1, no color selection wanted
315  {
316  // need a place holder within the sizer to keep grid full.
317  wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, encodeId( col, aSpec.id ) );
318  m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
319  }
320 
321  // column 1
322  col = 1;
323  wxCheckBox* cb = new wxCheckBox( m_RenderScrolledWindow, encodeId( col, aSpec.id ),
324  aSpec.rowName, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
325  shrinkFont( cb, m_PointSize );
326  cb->SetValue( aSpec.state );
327  cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnRenderCheckBox, this );
328  cb->SetToolTip( aSpec.tooltip );
329  m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
330 }
331 
332 
334 {
335  m_FocusOwner->SetFocus();
336 }
337 
338 
339 //-----<public>-------------------------------------------------------
340 
341 LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPointSize,
342  wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) :
343  wxPanel( aParent, id, pos, size, style )
344 {
345  wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
346 
347  m_notebook = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP );
348 
349  wxFont font = m_notebook->GetFont();
350 
351  if( aPointSize == -1 )
352  {
353  m_PointSize = font.GetPointSize();
354  }
355  else
356  {
357  m_PointSize = aPointSize;
358 
359  // change the font size on the notebook's tabs to match aPointSize
360  font.SetPointSize( aPointSize );
361  m_notebook->SetFont( font );
362  m_notebook->SetNormalFont( font );
363  m_notebook->SetSelectedFont( font );
364  m_notebook->SetMeasuringFont( font );
365  }
366 
367  m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
368 
369  wxBoxSizer* bSizer3;
370  bSizer3 = new wxBoxSizer( wxVERTICAL );
371 
372  m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
373  m_LayerScrolledWindow->SetScrollRate( 5, 5 );
374  m_LayersFlexGridSizer = new wxFlexGridSizer( 0, 4, 0, 1 );
375  m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
376  m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
377 
379  m_LayerScrolledWindow->Layout();
381  bSizer3->Add( m_LayerScrolledWindow, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 2 );
382 
383  m_LayerPanel->SetSizer( bSizer3 );
384  m_LayerPanel->Layout();
385  bSizer3->Fit( m_LayerPanel );
386  m_notebook->AddPage( m_LayerPanel, _( "Layer" ), true );
387  m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
388 
389  wxBoxSizer* bSizer4;
390  bSizer4 = new wxBoxSizer( wxVERTICAL );
391 
392  m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
393  m_RenderScrolledWindow->SetScrollRate( 5, 5 );
394  m_RenderFlexGridSizer = new wxFlexGridSizer( 0, 2, 0, 1 );
395  m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
396  m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
397 
399  m_RenderScrolledWindow->Layout();
401  bSizer4->Add( m_RenderScrolledWindow, 1, wxALL|wxEXPAND, 5 );
402 
403  m_RenderingPanel->SetSizer( bSizer4 );
404  m_RenderingPanel->Layout();
405  bSizer4->Fit( m_RenderingPanel );
406  m_notebook->AddPage( m_RenderingPanel, _( "Render" ), false );
407 
408  boxSizer->Add( m_notebook, 1, wxEXPAND | wxALL, 5 );
409 
410  SetSizer( boxSizer );
411 
412  m_FocusOwner = aFocusOwner;
413 
414  m_CurrentRow = -1; // hide the arrow initially
415 
416  // trap the tab changes so that we can call passOnFocus().
417  m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
418 
419  Layout();
420 }
421 
422 
424 {
425 }
426 
427 
429 {
430  // size of m_LayerScrolledWindow --------------
431  wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
432  int totWidth = 0;
433 
434  if( widths.GetCount() )
435  {
436  for( int i = 0; i < LYR_COLUMN_COUNT; ++i )
437  {
438  totWidth += widths[i] + m_LayersFlexGridSizer->GetHGap();
439  // printf("widths[%d]:%d\n", i, widths[i] );
440  }
441  }
442 
443  // Account for the parent's frame:
444  totWidth += 10;
445 
446 
447  /* The minimum height is a small size to properly force computation
448  * of the panel's scrollbars (otherwise it will assume it *has* all
449  * this space) */
450  unsigned totHeight = 32;
451 
452  wxSize layerz( totWidth, totHeight );
453 
454  layerz += m_LayerPanel->GetWindowBorderSize();
455 
456 
457  // size of m_RenderScrolledWindow --------------
458  widths = m_RenderFlexGridSizer->GetColWidths();
459  totWidth = 0;
460 
461  if( widths.GetCount() )
462  {
463  for( int i = 0; i < RND_COLUMN_COUNT; ++i )
464  {
465  totWidth += widths[i] + m_RenderFlexGridSizer->GetHGap();
466  // printf("widths[%d]:%d\n", i, widths[i] );
467  }
468  }
469  // account for the parent's frame, this one has void space of 10 PLUS a border:
470  totWidth += 20;
471 
472  // For totHeight re-use the previous small one
473  wxSize renderz( totWidth, totHeight );
474 
475  renderz += m_RenderingPanel->GetWindowBorderSize();
476 
477  wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
478 
479  return clientz;
480 }
481 
482 
484 {
485  int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
486  return controlCount / LYR_COLUMN_COUNT;
487 }
488 
489 
491 {
492  int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
493  return controlCount / RND_COLUMN_COUNT;
494 }
495 
496 
498 {
499  int nextRow = GetLayerRowCount();
500  insertLayerRow( nextRow, aRow );
501  UpdateLayouts();
502 }
503 
504 
506 {
507  m_LayersFlexGridSizer->Clear( true );
508 }
509 
510 
512 {
513  int nextRow = GetRenderRowCount();
514  insertRenderRow( nextRow, aRow );
515  UpdateLayouts();
516 }
517 
518 
520 {
521  m_RenderFlexGridSizer->Clear( true );
522 }
523 
524 
526 {
527  // enable the layer tab at index 0
528  m_notebook->SetSelection( 0 );
529 
530  INDICATOR_ICON* oldIndicator = (INDICATOR_ICON*) getLayerComp( m_CurrentRow, 0 );
531  if( oldIndicator )
533 
534  INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
535  if( newIndicator )
536  {
538 
539  // Make sure the desired layer row is visible.
540  // It seems that as of 2.8.2, setting the focus does this.
541  // I don't expect the scrolling to be needed at all because
542  // the minimum window size may end up being established so that the
543  // scroll bars will not be visible.
544  getLayerComp( aRow, 1 )->SetFocus();
545  }
546 
547  m_CurrentRow = aRow;
548 
549  // give the focus back to the app.
550  passOnFocus();
551 }
552 
553 
555 {
556  int row = findLayerRow( aLayer );
557  SelectLayerRow( row );
558 }
559 
560 
562 {
563  wxWindow* w = getLayerComp( m_CurrentRow, 0 );
564  if( w )
565  return getDecodedId( w->GetId() );
566 
567  return UNDEFINED_LAYER;
568 }
569 
570 
571 void LAYER_WIDGET::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
572 {
573  int row = findLayerRow( aLayer );
574  if( row >= 0 )
575  {
576  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
577  wxASSERT( cb );
578  cb->SetValue( isVisible ); // does not fire an event
579  }
580 }
581 
582 
584 {
585  int row = findLayerRow( aLayer );
586  if( row >= 0 )
587  {
588  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
589  wxASSERT( cb );
590  return cb->GetValue();
591  }
592  return false;
593 }
594 
595 
597 {
598  int row = findLayerRow( aLayer );
599  if( row >= 0 )
600  {
601  int col = 1; // bitmap button is column 1
602  auto bmb = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
603  wxASSERT( bmb );
604 
605  bmb->SetSwatchColor( aColor, false );
606  }
607 }
608 
609 
611 {
612  int row = findLayerRow( aLayer );
613  if( row >= 0 )
614  {
615  int col = 1; // bitmap button is column 1
616  wxBitmapButton* bmb = (wxBitmapButton*) getLayerComp( row, col );
617  wxASSERT( bmb );
618 
619  wxString colorTxt = bmb->GetName();
620  return ColorFromInt( strtoul( TO_UTF8(colorTxt), NULL, 0 ) );
621  }
622 
623  return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
624 }
625 
626 
627 void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
628 {
629  int row = findRenderRow( aId );
630 
631  if( row >= 0 )
632  {
633  int col = 1; // checkbox is column 1
634  wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
635  wxASSERT( cb );
636  cb->SetValue( isSet ); // does not fire an event
637  }
638 }
639 
640 
642 {
643  int row = findRenderRow( aId );
644 
645  if( row >= 0 )
646  {
647  int col = 1; // checkbox is column 1
648  wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
649  wxASSERT( cb );
650  return cb->GetValue();
651  }
652 
653  return false; // the value of a non-existent row
654 }
655 
656 
658 {
659  m_LayersFlexGridSizer->Layout();
660  m_RenderFlexGridSizer->Layout();
661  m_LayerPanel->Layout();
662  m_RenderingPanel->Layout();
663  FitInside();
664 }
665 
666 
668 {
669  int rowCount = GetLayerRowCount();
670 
671  for( int row = 0; row < rowCount ; row++ )
672  {
674 
675  if( indicator )
676  {
677  auto state = ( row == m_CurrentRow ) ? ROW_ICON_PROVIDER::STATE::ON
679  indicator->SetIndicatorState( state );
680  }
681  }
682 }
683 
684 
685 #if defined(STAND_ALONE)
686 
687 #include <wx/aui/aui.h>
688 
689 
696 class MYFRAME : public wxFrame
697 {
698  // example of how to derive from LAYER_WIDGET in order to provide the
699  // abstract methods.
700  class MYLAYERS : public LAYER_WIDGET
701  {
702  public:
703  // your constructor could take a BOARD argument. here I leave it
704  // out because this source module wants to know nothing of BOARDs
705  // to maximize re-use.
706  MYLAYERS( wxWindow* aParent ) :
707  LAYER_WIDGET( aParent, aParent )
708  {
709  }
710 
711  void OnLayerColorChange( int aLayer, COLOR4D aColor )
712  {
713  printf( "OnLayerColorChange( aLayer:%d, aColor:%d )\n", aLayer, aColor );
714 
715  /* a test trigger only
716  if( aLayer == 2 )
717  {
718  ClearLayerRows();
719  printf(" GetLayerRowCount(): %d\n", GetLayerRowCount() );
720  }
721  */
722  }
723 
724  bool OnLayerSelect( LAYER_NUM aLayer )
725  {
726  printf( "OnLayerSelect( aLayer:%d )\n", aLayer );
727  return true;
728  }
729 
730  void OnLayerVisible( LAYER_NUM aLayer, bool isVisible, bool isFinal )
731  {
732  printf( "OnLayerVisible( aLayer:%d, isVisible:%d isFinal:%d)\n", aLayer, isVisible, isFinal );
733  }
734 
735  void OnRenderColorChange( int aId, COLOR4D aColor )
736  {
737  printf( "OnRenderColorChange( aId:%d, aColor:%d )\n", aId, aColor );
738  }
739 
740  void OnRenderEnable( int aId, bool isEnabled )
741  {
742  printf( "OnRenderEnable( aId:%d, isEnabled:%d )\n", aId, isEnabled );
743  }
744  };
745 
746 
747 public:
748  MYFRAME( wxWindow * parent ) :
749  wxFrame( parent, -1, wxT( "wxAUI Test" ), wxDefaultPosition,
750  wxSize( 800, 600 ), wxDEFAULT_FRAME_STYLE )
751  {
752  // notify wxAUI which frame to use
753  m_mgr.SetManagedWindow( this );
754 
755  MYLAYERS* lw = new MYLAYERS( this );
756 
757  // add some layer rows
758  static const LAYER_WIDGET::ROW layerRows[] = {
759  LAYER_WIDGET::ROW( wxT("layer 1"), 0, RED, wxT("RED"), false ),
760  LAYER_WIDGET::ROW( wxT("layer 2"), 1, GREEN, wxT("GREEN"), true ),
761  LAYER_WIDGET::ROW( wxT("brown_layer"), 2, BROWN, wxT("BROWN"), true ),
762  LAYER_WIDGET::ROW( wxT("layer_4_you"), 3, BLUE, wxT("BLUE"), false ),
763  };
764 
765  lw->AppendLayerRows( layerRows, DIM(layerRows) );
766 
767  // add some render rows
768  static const LAYER_WIDGET::ROW renderRows[] = {
769  LAYER_WIDGET::ROW( wxT("With Very Large Ears"), 0, COLOR4D::UNSPECIFIED, wxT("Spock here") ),
770  LAYER_WIDGET::ROW( wxT("With Legs"), 1, YELLOW ),
771  LAYER_WIDGET::ROW( wxT("With Oval Eyes"), 1, BROWN, wxT("My eyes are upon you") ),
772  };
773 
774  lw->AppendRenderRows( renderRows, DIM(renderRows) );
775 
776  lw->SelectLayerRow( 1 );
777 
778  wxAuiPaneInfo li;
779  li.MinSize( lw->GetBestSize() );
780  li.BestSize( lw->GetBestSize() );
781  li.Left();
782 // li.MaximizeButton( true );
783 // li.MinimizeButton( true );
784  li.CloseButton( false );
785  li.Caption( wxT( "Layers" ) );
786  m_mgr.AddPane( lw, li );
787 
788 
789  wxTextCtrl* text2 = new wxTextCtrl( this, -1, wxT( "Pane 2 - sample text" ),
790  wxDefaultPosition, wxSize( 200, 150 ),
791  wxNO_BORDER | wxTE_MULTILINE );
792  m_mgr.AddPane( text2, wxBOTTOM, wxT( "Pane Number Two" ) );
793 
794  wxTextCtrl* text3 = new wxTextCtrl( this, -1, wxT( "Main content window" ),
795  wxDefaultPosition, wxSize( 200, 150 ),
796  wxNO_BORDER | wxTE_MULTILINE );
797  m_mgr.AddPane( text3, wxCENTER );
798 
799  // tell the manager to "commit" all the changes just made
800  m_mgr.Update();
801  }
802 
803  ~MYFRAME()
804  {
805  // deinitialize the frame manager
806  m_mgr.UnInit();
807  }
808 
809 private:
810  wxAuiManager m_mgr;
811 };
812 
813 
814 // our normal wxApp-derived class, as usual
815 class MyApp : public wxApp
816 {
817 public:
818 
819  bool OnInit()
820  {
821  wxFrame* frame = new MYFRAME( NULL );
822 
823  SetTopWindow( frame );
824  frame->Show();
825  return true;
826  }
827 };
828 
829 DECLARE_APP( MyApp );
830 IMPLEMENT_APP( MyApp );
831 
832 #endif // STAND_ALONE
Definition: colors.h:57
#define COLUMN_COLOR_LYRNAME
Definition: layer_widget.h:53
#define DIM(x)
of elements in an array
Definition: macros.h:98
void OnLeftDownLayers(wxMouseEvent &event)
void SetIndicatorState(ICON_ID aIconId)
Sets the row indiciator to the given state.
wxAuiNotebook * m_notebook
Definition: layer_widget.h:107
#define LYR_COLUMN_COUNT
Layer tab column count.
Definition: layer_widget.h:47
int m_CurrentRow
selected row of layer list
Definition: layer_widget.h:116
void insertRenderRow(int aRow, const ROW &aSpec)
Icon provider for the "standard" row indicators, for example in layer selection lists.
Struct ROW provides all the data needed to add a row to a LAYER_WIDGET.
Definition: layer_widget.h:84
int findRenderRow(int aId) const
virtual void OnRenderColorChange(int aId, COLOR4D aColor)=0
Function OnRenderColorChange is called to notify client code whenever the user changes a rendering co...
EDA_COLOR_T ColorFromInt(int aColor)
Checked cast. Use only when necessary (usually I/O)
Definition: colors.h:81
bool GetRenderState(int aId)
Function GetRenderState returns the state of the checkbox associated with aId.
void UpdateLayouts()
virtual void OnLayerVisible(LAYER_NUM aLayer, bool isVisible, bool isFinal=true)=0
Function OnLayerVisible is called to notify client code about a layer visibility change.
void OnTabChange(wxNotebookEvent &event)
static const wxEventType EVT_LAYER_COLOR_CHANGE
Definition: layer_widget.h:103
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor returns the color of the layer ROW associated with aLayer id.
#define OFF
wxScrolledWindow * m_RenderScrolledWindow
Definition: layer_widget.h:112
wxFlexGridSizer * m_LayersFlexGridSizer
Definition: layer_widget.h:110
virtual bool useAlternateBitmap(int aRow)
Virtual Function useAlternateBitmap.
Definition: layer_widget.h:127
int findLayerRow(LAYER_NUM aLayer) const
Function findLayerRow returns the row index that aLayer resides in, or -1 if not found.
static void shrinkFont(wxWindow *aControl, int aPointSize)
Function shrinkFont reduces the size of the wxFont associated with aControl.
wxSize GetBestSize() const
Function GetBestSize returns the preferred minimum size, taking into consideration the dynamic conten...
void ClearRenderRows()
Function ClearRenderRows empties out the render rows.
#define RND_COLUMN_COUNT
Rendering tab column count.
Definition: layer_widget.h:48
wxFlexGridSizer * m_RenderFlexGridSizer
Definition: layer_widget.h:113
bool state
initial wxCheckBox state
Definition: layer_widget.h:89
void ClearLayerRows()
Function ClearLayerRows empties out the layer rows.
wxString tooltip
if not empty, use this tooltip on row
Definition: layer_widget.h:90
This file contains miscellaneous commonly used macros and functions.
virtual void OnLayerColorChange(int aLayer, COLOR4D aColor)=0
Function OnLayerColorChange is called to notify client code about a layer color change.
void OnRenderCheckBox(wxCommandEvent &event)
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void OnLayerCheckBox(wxCommandEvent &event)
Function OnLayerCheckBox handles the "is layer visible" checkbox and propogates the event to the clie...
void AppendRenderRow(const ROW &aRow)
Function AppendRenderRow appends a new row in the render portion of the widget.
static int encodeId(int aColumn, int aId)
Function encodeId is here to allow saving a layer index within a control as its wxControl id...
COLOR4D color
COLOR4D::UNSPECIFIED if none.
Definition: layer_widget.h:88
Class representing a row indicator icon for use in places like the layer widget.
#define COLUMN_ICON_ACTIVE
Definition: layer_widget.h:50
int GetRenderRowCount() const
Function GetRenderRowCount returns the number of rows in the render tab.
#define COLUMN_COLORBM
Definition: layer_widget.h:51
void SetLayerColor(LAYER_NUM aLayer, COLOR4D aColor)
Function SetLayerColor changes the color of aLayer.
static ROW_ICON_PROVIDER alternativeRowIcons(true)
virtual bool AreArbitraryColorsAllowed()
Subclasses can override this to provide logic for allowing arbitrary color selection via wxColourPick...
Definition: layer_widget.h:133
wxPanel * m_RenderingPanel
Definition: layer_widget.h:111
void AppendLayerRow(const ROW &aRow)
Function AppendLayerRow appends a new row in the layer portion of the widget.
void UpdateLayerIcons()
Function UpdateLayerIcons Update all layer manager icons (layers only) Useful when loading a file or ...
wxScrolledWindow * m_LayerScrolledWindow
Definition: layer_widget.h:109
virtual void OnRenderEnable(int aId, bool isEnabled)=0
Function OnRenderEnable is called to notify client code whenever the user changes an rendering enable...
wxWindow * getLayerComp(int aRow, int aColumn) const
Function getLayerComp returns the component within the m_LayersFlexGridSizer at aRow and aCol or NULL...
Definition: colors.h:60
int GetLayerRowCount() const
Function GetLayerRowCount returns the number of rows in the layer tab.
void SelectLayerRow(int aRow)
Function SelectLayerRow changes the row selection in the layer list to the given row.
void OnRenderSwatchChanged(wxCommandEvent &aEvent)
Function OnRenderSwatchChanged Called when user has changed the swatch color of a render entry...
static LAYER_NUM getDecodedId(int aControlId)
Function getDecodedId decodes aControlId to original un-encoded value.
virtual ~LAYER_WIDGET()
wxWindow * m_FocusOwner
Definition: layer_widget.h:115
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
void passOnFocus()
Function passOnFocus gives away the keyboard focus up to the main parent window.
LAYER_NUM GetSelectedLayer()
Function GetSelectedLayer returns the selected layer or -1 if none.
bool IsLayerVisible(LAYER_NUM aLayer)
Function IsLayerVisible returns the visible state of the layer ROW associated with aLayer id...
Class LAYER_WIDGET is abstract and is used to manage a list of layers, with the notion of a "current"...
Definition: layer_widget.h:76
static ROW_ICON_PROVIDER defaultRowIcons(false)
Definition: colors.h:58
#define COLUMN_COLOR_LYR_CB
Definition: layer_widget.h:52
#define max(a, b)
Definition: auxiliary.h:86
wxString rowName
the prompt or layername
Definition: layer_widget.h:86
IMPLEMENT_APP(APP_KICAD)
Class representing a simple color swatch, of the kind used to set layer colors.
Definition: color_swatch.h:38
The common library.
void insertLayerRow(int aRow, const ROW &aSpec)
Function insertLayerRow appends or inserts a new row in the layer portion of the widget.
#define ON
void SetLayerVisible(LAYER_NUM aLayer, bool isVisible)
Function SetLayerVisible sets aLayer visible or not.
void OnLayerSwatchChanged(wxCommandEvent &aEvent)
Function OnSwatchChanged() is called when a user changes a swatch color.
virtual bool OnLayerSelect(int aLayer)=0
Function OnLayerSelect is called to notify client code whenever the user selects a different layer...
void SetRenderState(int aId, bool isSet)
Function SetRenderState sets the state of the checkbox associated with aId within the Render tab grou...
Definition: colors.h:68
void SelectLayer(LAYER_NUM aLayer)
Function SelectLayer changes the row selection in the layer list to aLayer provided.
int id
either a layer or "visible element" id
Definition: layer_widget.h:87
wxPanel * m_LayerPanel
Definition: layer_widget.h:108
LAYER_WIDGET(wxWindow *aParent, wxWindow *aFocusOwner, int aPointSize=-1, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
Constructor.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
wxWindow * getRenderComp(int aRow, int aColumn) const
Definition: colors.h:62