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->Enable( aSpec.changeable );
328  cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnRenderCheckBox, this );
329  cb->SetToolTip( aSpec.tooltip );
330  m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
331 }
332 
333 
335 {
336  m_FocusOwner->SetFocus();
337 }
338 
339 
340 //-----<public>-------------------------------------------------------
341 
342 LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPointSize,
343  wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) :
344  wxPanel( aParent, id, pos, size, style )
345 {
346  wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
347 
348  m_notebook = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP );
349 
350  wxFont font = m_notebook->GetFont();
351 
352  if( aPointSize == -1 )
353  {
354  m_PointSize = font.GetPointSize();
355  }
356  else
357  {
358  m_PointSize = aPointSize;
359 
360  // change the font size on the notebook's tabs to match aPointSize
361  font.SetPointSize( aPointSize );
362  m_notebook->SetFont( font );
363  m_notebook->SetNormalFont( font );
364  m_notebook->SetSelectedFont( font );
365  m_notebook->SetMeasuringFont( font );
366  }
367 
368  m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
369 
370  wxBoxSizer* bSizer3;
371  bSizer3 = new wxBoxSizer( wxVERTICAL );
372 
373  m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
374  m_LayerScrolledWindow->SetScrollRate( 5, 5 );
375  m_LayersFlexGridSizer = new wxFlexGridSizer( 0, 4, 0, 1 );
376  m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
377  m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
378 
380  m_LayerScrolledWindow->Layout();
382  bSizer3->Add( m_LayerScrolledWindow, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 2 );
383 
384  m_LayerPanel->SetSizer( bSizer3 );
385  m_LayerPanel->Layout();
386  bSizer3->Fit( m_LayerPanel );
387  m_notebook->AddPage( m_LayerPanel, _( "Layer" ), true );
388  m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
389 
390  wxBoxSizer* bSizer4;
391  bSizer4 = new wxBoxSizer( wxVERTICAL );
392 
393  m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
394  m_RenderScrolledWindow->SetScrollRate( 5, 5 );
395  m_RenderFlexGridSizer = new wxFlexGridSizer( 0, 2, 0, 1 );
396  m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
397  m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
398 
400  m_RenderScrolledWindow->Layout();
402  bSizer4->Add( m_RenderScrolledWindow, 1, wxALL|wxEXPAND, 5 );
403 
404  m_RenderingPanel->SetSizer( bSizer4 );
405  m_RenderingPanel->Layout();
406  bSizer4->Fit( m_RenderingPanel );
407  m_notebook->AddPage( m_RenderingPanel, _( "Render" ), false );
408 
409  boxSizer->Add( m_notebook, 1, wxEXPAND | wxALL, 5 );
410 
411  SetSizer( boxSizer );
412 
413  m_FocusOwner = aFocusOwner;
414 
415  m_CurrentRow = -1; // hide the arrow initially
416 
417  // trap the tab changes so that we can call passOnFocus().
418  m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
419 
420  Layout();
421 }
422 
423 
425 {
426 }
427 
428 
430 {
431  // size of m_LayerScrolledWindow --------------
432  wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
433  int totWidth = 0;
434 
435  if( widths.GetCount() )
436  {
437  for( int i = 0; i < LYR_COLUMN_COUNT; ++i )
438  {
439  totWidth += widths[i] + m_LayersFlexGridSizer->GetHGap();
440  // printf("widths[%d]:%d\n", i, widths[i] );
441  }
442  }
443 
444  // Account for the parent's frame:
445  totWidth += 10;
446 
447 
448  /* The minimum height is a small size to properly force computation
449  * of the panel's scrollbars (otherwise it will assume it *has* all
450  * this space) */
451  unsigned totHeight = 32;
452 
453  wxSize layerz( totWidth, totHeight );
454 
455  layerz += m_LayerPanel->GetWindowBorderSize();
456 
457 
458  // size of m_RenderScrolledWindow --------------
459  widths = m_RenderFlexGridSizer->GetColWidths();
460  totWidth = 0;
461 
462  if( widths.GetCount() )
463  {
464  for( int i = 0; i < RND_COLUMN_COUNT; ++i )
465  {
466  totWidth += widths[i] + m_RenderFlexGridSizer->GetHGap();
467  // printf("widths[%d]:%d\n", i, widths[i] );
468  }
469  }
470  // account for the parent's frame, this one has void space of 10 PLUS a border:
471  totWidth += 20;
472 
473  // For totHeight re-use the previous small one
474  wxSize renderz( totWidth, totHeight );
475 
476  renderz += m_RenderingPanel->GetWindowBorderSize();
477 
478  wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
479 
480  return clientz;
481 }
482 
483 
485 {
486  int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
487  return controlCount / LYR_COLUMN_COUNT;
488 }
489 
490 
492 {
493  int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
494  return controlCount / RND_COLUMN_COUNT;
495 }
496 
497 
499 {
500  int nextRow = GetLayerRowCount();
501  insertLayerRow( nextRow, aRow );
502  UpdateLayouts();
503 }
504 
505 
507 {
508  m_LayersFlexGridSizer->Clear( true );
509 }
510 
511 
513 {
514  int nextRow = GetRenderRowCount();
515  insertRenderRow( nextRow, aRow );
516  UpdateLayouts();
517 }
518 
519 
521 {
522  m_RenderFlexGridSizer->Clear( true );
523 }
524 
525 
527 {
528  // enable the layer tab at index 0
529  m_notebook->SetSelection( 0 );
530 
531  INDICATOR_ICON* oldIndicator = (INDICATOR_ICON*) getLayerComp( m_CurrentRow, 0 );
532  if( oldIndicator )
534 
535  INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
536  if( newIndicator )
537  {
539 
540  // Make sure the desired layer row is visible.
541  // It seems that as of 2.8.2, setting the focus does this.
542  // I don't expect the scrolling to be needed at all because
543  // the minimum window size may end up being established so that the
544  // scroll bars will not be visible.
545  getLayerComp( aRow, 1 )->SetFocus();
546  }
547 
548  m_CurrentRow = aRow;
549 
550  // give the focus back to the app.
551  passOnFocus();
552 }
553 
554 
556 {
557  int row = findLayerRow( aLayer );
558  SelectLayerRow( row );
559 }
560 
561 
563 {
564  wxWindow* w = getLayerComp( m_CurrentRow, 0 );
565  if( w )
566  return getDecodedId( w->GetId() );
567 
568  return UNDEFINED_LAYER;
569 }
570 
571 
572 void LAYER_WIDGET::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
573 {
574  int row = findLayerRow( aLayer );
575  if( row >= 0 )
576  {
577  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
578  wxASSERT( cb );
579  cb->SetValue( isVisible ); // does not fire an event
580  }
581 }
582 
583 
585 {
586  int row = findLayerRow( aLayer );
587  if( row >= 0 )
588  {
589  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
590  wxASSERT( cb );
591  return cb->GetValue();
592  }
593  return false;
594 }
595 
596 
598 {
599  int row = findLayerRow( aLayer );
600  if( row >= 0 )
601  {
602  int col = 1; // bitmap button is column 1
603  auto bmb = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
604  wxASSERT( bmb );
605 
606  bmb->SetSwatchColor( aColor, false );
607  }
608 }
609 
610 
612 {
613  int row = findLayerRow( aLayer );
614  if( row >= 0 )
615  {
616  int col = 1; // bitmap button is column 1
617  wxBitmapButton* bmb = (wxBitmapButton*) getLayerComp( row, col );
618  wxASSERT( bmb );
619 
620  wxString colorTxt = bmb->GetName();
621  return ColorFromInt( strtoul( TO_UTF8(colorTxt), NULL, 0 ) );
622  }
623 
624  return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
625 }
626 
627 
628 void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
629 {
630  int row = findRenderRow( aId );
631 
632  if( row >= 0 )
633  {
634  int col = 1; // checkbox is column 1
635  wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
636  wxASSERT( cb );
637  cb->SetValue( isSet ); // does not fire an event
638  }
639 }
640 
641 
643 {
644  int row = findRenderRow( aId );
645 
646  if( row >= 0 )
647  {
648  int col = 1; // checkbox is column 1
649  wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
650  wxASSERT( cb );
651  return cb->GetValue();
652  }
653 
654  return false; // the value of a non-existent row
655 }
656 
657 
659 {
660  m_LayersFlexGridSizer->Layout();
661  m_RenderFlexGridSizer->Layout();
662  m_LayerPanel->Layout();
663  m_RenderingPanel->Layout();
664  FitInside();
665 }
666 
667 
669 {
670  int rowCount = GetLayerRowCount();
671 
672  for( int row = 0; row < rowCount ; row++ )
673  {
675 
676  if( indicator )
677  {
678  auto state = ( row == m_CurrentRow ) ? ROW_ICON_PROVIDER::STATE::ON
680  indicator->SetIndicatorState( state );
681  }
682  }
683 }
684 
685 
686 #if defined(STAND_ALONE)
687 
688 #include <wx/aui/aui.h>
689 
690 
697 class MYFRAME : public wxFrame
698 {
699  // example of how to derive from LAYER_WIDGET in order to provide the
700  // abstract methods.
701  class MYLAYERS : public LAYER_WIDGET
702  {
703  public:
704  // your constructor could take a BOARD argument. here I leave it
705  // out because this source module wants to know nothing of BOARDs
706  // to maximize re-use.
707  MYLAYERS( wxWindow* aParent ) :
708  LAYER_WIDGET( aParent, aParent )
709  {
710  }
711 
712  void OnLayerColorChange( int aLayer, COLOR4D aColor )
713  {
714  printf( "OnLayerColorChange( aLayer:%d, aColor:%d )\n", aLayer, aColor );
715 
716  /* a test trigger only
717  if( aLayer == 2 )
718  {
719  ClearLayerRows();
720  printf(" GetLayerRowCount(): %d\n", GetLayerRowCount() );
721  }
722  */
723  }
724 
725  bool OnLayerSelect( LAYER_NUM aLayer )
726  {
727  printf( "OnLayerSelect( aLayer:%d )\n", aLayer );
728  return true;
729  }
730 
731  void OnLayerVisible( LAYER_NUM aLayer, bool isVisible, bool isFinal )
732  {
733  printf( "OnLayerVisible( aLayer:%d, isVisible:%d isFinal:%d)\n", aLayer, isVisible, isFinal );
734  }
735 
736  void OnRenderColorChange( int aId, COLOR4D aColor )
737  {
738  printf( "OnRenderColorChange( aId:%d, aColor:%d )\n", aId, aColor );
739  }
740 
741  void OnRenderEnable( int aId, bool isEnabled )
742  {
743  printf( "OnRenderEnable( aId:%d, isEnabled:%d )\n", aId, isEnabled );
744  }
745  };
746 
747 
748 public:
749  MYFRAME( wxWindow * parent ) :
750  wxFrame( parent, -1, wxT( "wxAUI Test" ), wxDefaultPosition,
751  wxSize( 800, 600 ), wxDEFAULT_FRAME_STYLE )
752  {
753  // notify wxAUI which frame to use
754  m_mgr.SetManagedWindow( this );
755 
756  MYLAYERS* lw = new MYLAYERS( this );
757 
758  // add some layer rows
759  static const LAYER_WIDGET::ROW layerRows[] = {
760  LAYER_WIDGET::ROW( wxT("layer 1"), 0, RED, wxT("RED"), false ),
761  LAYER_WIDGET::ROW( wxT("layer 2"), 1, GREEN, wxT("GREEN"), true ),
762  LAYER_WIDGET::ROW( wxT("brown_layer"), 2, BROWN, wxT("BROWN"), true ),
763  LAYER_WIDGET::ROW( wxT("layer_4_you"), 3, BLUE, wxT("BLUE"), false ),
764  };
765 
766  lw->AppendLayerRows( layerRows, DIM(layerRows) );
767 
768  // add some render rows
769  static const LAYER_WIDGET::ROW renderRows[] = {
770  LAYER_WIDGET::ROW( wxT("With Very Large Ears"), 0, COLOR4D::UNSPECIFIED, wxT("Spock here") ),
771  LAYER_WIDGET::ROW( wxT("With Legs"), 1, YELLOW ),
772  LAYER_WIDGET::ROW( wxT("With Oval Eyes"), 1, BROWN, wxT("My eyes are upon you") ),
773  };
774 
775  lw->AppendRenderRows( renderRows, DIM(renderRows) );
776 
777  lw->SelectLayerRow( 1 );
778 
779  wxAuiPaneInfo li;
780  li.MinSize( lw->GetBestSize() );
781  li.BestSize( lw->GetBestSize() );
782  li.Left();
783 // li.MaximizeButton( true );
784 // li.MinimizeButton( true );
785  li.CloseButton( false );
786  li.Caption( wxT( "Layers" ) );
787  m_mgr.AddPane( lw, li );
788 
789 
790  wxTextCtrl* text2 = new wxTextCtrl( this, -1, wxT( "Pane 2 - sample text" ),
791  wxDefaultPosition, wxSize( 200, 150 ),
792  wxNO_BORDER | wxTE_MULTILINE );
793  m_mgr.AddPane( text2, wxBOTTOM, wxT( "Pane Number Two" ) );
794 
795  wxTextCtrl* text3 = new wxTextCtrl( this, -1, wxT( "Main content window" ),
796  wxDefaultPosition, wxSize( 200, 150 ),
797  wxNO_BORDER | wxTE_MULTILINE );
798  m_mgr.AddPane( text3, wxCENTER );
799 
800  // tell the manager to "commit" all the changes just made
801  m_mgr.Update();
802  }
803 
804  ~MYFRAME()
805  {
806  // deinitialize the frame manager
807  m_mgr.UnInit();
808  }
809 
810 private:
811  wxAuiManager m_mgr;
812 };
813 
814 
815 // our normal wxApp-derived class, as usual
816 class MyApp : public wxApp
817 {
818 public:
819 
820  bool OnInit()
821  {
822  wxFrame* frame = new MYFRAME( NULL );
823 
824  SetTopWindow( frame );
825  frame->Show();
826  return true;
827  }
828 };
829 
830 DECLARE_APP( MyApp );
831 IMPLEMENT_APP( MyApp );
832 
833 #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:109
#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:118
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)
bool changeable
if true, the state can be changed
Definition: layer_widget.h:91
static const wxEventType EVT_LAYER_COLOR_CHANGE
Definition: layer_widget.h:105
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:114
wxFlexGridSizer * m_LayersFlexGridSizer
Definition: layer_widget.h:112
virtual bool useAlternateBitmap(int aRow)
Virtual Function useAlternateBitmap.
Definition: layer_widget.h:129
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:115
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:135
wxPanel * m_RenderingPanel
Definition: layer_widget.h:113
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:111
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:117
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:110
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