KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
6 * Copyright (C) 2010-2022 KiCad Developers, see AUTHORS.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 <bitmaps.h>
39#include <macros.h>
42#include <wx/checkbox.h>
43
44#include <algorithm>
45
46
47const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
48
49
53static void shrinkFont( wxWindow* aControl, int aPointSize )
54{
55 wxFont font = aControl->GetFont();
56 font.SetPointSize( aPointSize );
57 aControl->SetFont( font ); // need this?
58}
59
60
61int LAYER_WIDGET::encodeId( int aColumn, int aId )
62{
63 int id = aId * LYR_COLUMN_COUNT + aColumn;
64 return id;
65}
66
67
68int LAYER_WIDGET::getDecodedId( int aControlId )
69{
70 int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
71 return id;
72}
73
74
75void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
76{
77 int row;
78 int layer;
79
80 wxWindow* eventSource = (wxWindow*) event.GetEventObject();
81
82 // if mouse event is coming from the m_LayerScrolledWindow and not one
83 // of its children, we have to find the row manually based on y coord.
84 if( eventSource == m_LayerScrolledWindow )
85 {
86 int y = event.GetY();
87
88 wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();
89
90 int height = 0;
91
92 int rowCount = GetLayerRowCount();
93
94 for( row = 0; row<rowCount; ++row )
95 {
96 if( y < height + heights[row] )
97 break;
98
99 height += heights[row];
100 }
101
102 if( row >= rowCount )
103 row = rowCount - 1;
104
105 layer = getDecodedId( getLayerComp( row, 0 )->GetId() );
106 }
107 else
108 {
109 // all nested controls on a given row will have their ID encoded with
110 // encodeId(), and the corresponding decoding is getDecodedId()
111 int id = eventSource->GetId();
112 layer = getDecodedId( id );
113 row = findLayerRow( layer );
114 }
115
116 if( OnLayerSelect( layer ) ) // if client allows this change.
117 SelectLayerRow( row );
118
119 passOnFocus();
120}
121
122
123void LAYER_WIDGET::OnRightDownLayer( wxMouseEvent& aEvent, COLOR_SWATCH* aColorSwatch,
124 const wxString& aLayerName )
125{
126 wxMenu menu;
127
129 _( "Change Layer Color for" ) + wxS( " " ) + aLayerName,
130 KiBitmap( BITMAPS::color_materials ) );
131 menu.AppendSeparator();
132
133 OnLayerRightClick( menu );
134
135 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, [aColorSwatch]( wxCommandEvent& event )
136 {
137 if( event.GetId() == ID_CHANGE_LAYER_COLOR )
138 {
139 aColorSwatch->GetNewSwatchColor();
140 }
141 else
142 {
143 event.Skip();
144 }
145 } );
146
147 PopupMenu( &menu );
148 passOnFocus();
149}
150
151
152void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent )
153{
154 COLOR_SWATCH* eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
155 COLOR4D newColor = eventSource->GetSwatchColor();
156 int layer = getDecodedId( eventSource->GetId() );
157
158 // tell the client code.
159 OnLayerColorChange( layer, newColor );
160
161 // notify others
162 wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
163 wxPostEvent( this, event );
164
165 passOnFocus();
166}
167
168
169void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
170{
171 wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
172 int layer = getDecodedId( eventSource->GetId() );
173
174 OnLayerVisible( layer, eventSource->IsChecked() );
175 passOnFocus();
176}
177
178
179void LAYER_WIDGET::OnRightDownRender( wxMouseEvent& aEvent, COLOR_SWATCH* aColorSwatch,
180 const wxString& aRenderName )
181{
182 wxMenu menu;
183
185 _( "Change Render Color for" ) + wxS( " " )+ aRenderName,
186 KiBitmap( BITMAPS::color_materials ) );
187
188 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
189 [aColorSwatch]( wxCommandEvent& event )
190 {
191 if( event.GetId() == ID_CHANGE_RENDER_COLOR )
192 aColorSwatch->GetNewSwatchColor();
193 else
194 event.Skip();
195 } );
196
197 PopupMenu( &menu );
198 passOnFocus();
199}
200
201
202void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
203{
204 COLOR_SWATCH* eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
205 COLOR4D newColor = eventSource->GetSwatchColor();
206 int id = getDecodedId( eventSource->GetId() );
207
208 if( id == LAYER_PCB_BACKGROUND )
209 {
210 // Update all swatch backgrounds
211 int col = 1; // bitmap button is column 1 in layers tab
212
213 for( int row = 0; row < GetLayerRowCount(); ++row )
214 {
215 COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
216
217 if( swatch )
218 swatch->SetSwatchBackground( newColor );
219 }
220
221 col = 0; // bitmap button is column 0 in render tab
222
223 for( int row = 0; row < GetRenderRowCount(); ++row )
224 {
225 COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
226
227 if( swatch )
228 swatch->SetSwatchBackground( newColor );
229 }
230 }
231
232 // tell the client code.
233 OnRenderColorChange( id, newColor );
234
235 passOnFocus();
236}
237
238
239void LAYER_WIDGET::OnRenderCheckBox( wxCommandEvent& event )
240{
241 wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
242 int id = getDecodedId( eventSource->GetId() );
243
244 OnRenderEnable( id, eventSource->IsChecked() );
245 passOnFocus();
246}
247
248
249void LAYER_WIDGET::OnTabChange( wxNotebookEvent& event )
250{
251// wxFocusEvent event( wxEVT_SET_FOCUS );
252// m_FocusOwner->AddPendingEvent( event );
253
254 // Does not work in this context, probably because we have receive control here too early.
255 passOnFocus();
256}
257
258
259wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
260{
261 unsigned ndx = aRow * LYR_COLUMN_COUNT + aColumn;
262
263 if( ndx < m_LayersFlexGridSizer->GetChildren().GetCount() )
264 return m_LayersFlexGridSizer->GetChildren()[ndx]->GetWindow();
265
266 return nullptr;
267}
268
269
270int LAYER_WIDGET::findLayerRow( int aLayer ) const
271{
272 int count = GetLayerRowCount();
273
274 for( int row = 0; row < count; ++row )
275 {
276 // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
277 wxWindow* w = getLayerComp( row, 0 );
278 wxASSERT( w );
279
280 if( aLayer == getDecodedId( w->GetId() ) )
281 return row;
282 }
283
284 return -1;
285}
286
287
288wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
289{
290 int ndx = aRow * RND_COLUMN_COUNT + aColumn;
291
292 if( (unsigned) ndx < m_RenderFlexGridSizer->GetChildren().GetCount() )
293 return m_RenderFlexGridSizer->GetChildren()[ndx]->GetWindow();
294
295 return nullptr;
296}
297
298
299int LAYER_WIDGET::findRenderRow( int aId ) const
300{
301 int count = GetRenderRowCount();
302
303 for( int row = 0; row < count; ++row )
304 {
305 // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
306 wxWindow* w = getRenderComp( row, 0 );
307 wxASSERT( w );
308
309 if( aId == getDecodedId( w->GetId() ) )
310 return row;
311 }
312
313 return -1;
314}
315
316
317void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
318{
319 wxASSERT( aRow >= 0 );
320
321 int col;
322 int index = aRow * LYR_COLUMN_COUNT;
323 const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
324
325 // column 0
326 col = COLUMN_ICON_ACTIVE;
329 sbm->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
330 m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
331
332 // column 1 (COLUMN_COLORBM)
333 col = COLUMN_COLORBM;
334
335 auto bmb = new COLOR_SWATCH( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
337 bmb->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
338 bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnLayerSwatchChanged, this );
339 bmb->SetToolTip( _( "Left double click or middle click for color change, right click for "
340 "menu" ) );
341 m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags | wxRIGHT, 2 );
342
343 // column 2 (COLUMN_COLOR_LYR_CB)
345 wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, encodeId( col, aSpec.id ),
346 wxEmptyString );
347 cb->SetValue( aSpec.state );
348 cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnLayerCheckBox, this );
349 cb->SetToolTip( _( "Enable this for visibility" ) );
350 m_LayersFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
351
352 // column 3 (COLUMN_COLOR_LYRNAME)
355 encodeId( col, aSpec.id ),
356 aSpec.rowName, wxDefaultPosition,
357 wxDefaultSize,
358 wxST_ELLIPSIZE_MIDDLE );
359 shrinkFont( st, m_PointSize );
360 st->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
361 st->SetToolTip( aSpec.tooltip );
363 m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags | wxEXPAND );
364
365 // column 4 (COLUMN_ALPHA_INDICATOR)
369 m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
370
371 // Bind right click eventhandler to all columns
372 wxString layerName( aSpec.rowName );
373
374 sbm->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
375 {
376 OnRightDownLayer( aEvt, bmb, layerName );
377 } );
378 bmb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
379 {
380 OnRightDownLayer( aEvt, bmb, layerName );
381 } );
382 cb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
383 {
384 OnRightDownLayer( aEvt, bmb, layerName );
385 } );
386 st->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
387 {
388 OnRightDownLayer( aEvt, bmb, layerName );
389 } );
390}
391
392
393void LAYER_WIDGET::updateLayerRow( int aRow, const wxString& aName )
394{
395 wxStaticText* label = dynamic_cast<wxStaticText*>( getLayerComp( aRow, COLUMN_COLOR_LYRNAME ) );
396
397 if( label )
398 label->SetLabel( aName );
399
400 INDICATOR_ICON* indicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
401
402 if( indicator )
403 {
404 if( aRow == m_CurrentRow )
406 else
408 }
409}
410
411
412void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
413{
414 wxASSERT( aRow >= 0 );
415
416 int col;
417 int index = aRow * RND_COLUMN_COUNT;
418 const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
419
420 wxString renderName( aSpec.rowName );
421 wxCheckBox* cb = nullptr;
422
423 // column 1
424 if( !aSpec.spacer )
425 {
426 col = 1;
427 cb = new wxCheckBox( m_RenderScrolledWindow, encodeId( col, aSpec.id ),
428 aSpec.rowName, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
429 shrinkFont( cb, m_PointSize );
430 cb->SetValue( aSpec.state );
431 cb->Enable( aSpec.changeable );
432 cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnRenderCheckBox, this );
433 cb->SetToolTip( aSpec.tooltip );
434 }
435
436 // column 0
437 col = 0;
438
439 if( aSpec.color != COLOR4D::UNSPECIFIED )
440 {
441 auto bmb = new COLOR_SWATCH( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
443 bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnRenderSwatchChanged, this );
444 bmb->SetToolTip( _( "Left double click or middle click for color change" ) );
445 m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
446
447 bmb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, renderName] ( wxMouseEvent& aEvt ) {
448 OnRightDownRender( aEvt, bmb, renderName );
449 } );
450 cb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, renderName] ( wxMouseEvent& aEvt ) {
451 OnRightDownRender( aEvt, bmb, renderName );
452 } );
453
454 // could add a left click handler on the color button that toggles checkbox.
455 }
456 else // == -1, no color selection wanted
457 {
458 // need a place holder within the sizer to keep grid full.
459 wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, encodeId( col, aSpec.id ) );
460 m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
461 }
462
463 // Items have to be inserted in order
464 col = 1;
465
466 if( aSpec.spacer )
467 {
468 wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, wxID_ANY );
469 m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
470 }
471 else
472 {
473 m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
474 }
475}
476
477
479{
480 m_FocusOwner->SetFocus();
481}
482
483
484LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, wxWindowID id,
485 const wxPoint& pos, const wxSize& size, long style ) :
486 wxPanel( aParent, id, pos, size, style ),
487 m_smallestLayerString( wxT( "M...M" ) )
488{
489 int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x;
490 m_IconProvider = new ROW_ICON_PROVIDER( indicatorSize );
491
492 int pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
493 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
494
495 if( screenHeight <= 900 && pointSize >= indicatorSize )
496 pointSize = pointSize * 8 / 10;
497
498 m_PointSize = pointSize;
499
500 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
501
502 m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
503
504 wxFont font = m_notebook->GetFont();
505
506 // change the font size on the notebook's tabs to match aPointSize
507 font.SetPointSize( pointSize );
508 m_notebook->SetFont( font );
509
510 m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
511 wxTAB_TRAVERSAL );
512
513 wxBoxSizer* layerPanelSizer;
514 layerPanelSizer = new wxBoxSizer( wxVERTICAL );
515
516 m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition,
517 wxDefaultSize, wxNO_BORDER );
518 m_LayerScrolledWindow->SetScrollRate( 5, 5 );
519 m_LayersFlexGridSizer = new wxFlexGridSizer( 0, LYR_COLUMN_COUNT, 3, 4 );
520 m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
521 m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
522
523 // Make column 3 growable/stretchable
524 m_LayersFlexGridSizer->AddGrowableCol( 3, 1 );
525
527 m_LayerScrolledWindow->Layout();
529 layerPanelSizer->Add( m_LayerScrolledWindow, 1, wxBOTTOM | wxEXPAND | wxLEFT | wxTOP, 2 );
530
531 m_LayerPanel->SetSizer( layerPanelSizer );
532 m_LayerPanel->Layout();
533 layerPanelSizer->Fit( m_LayerPanel );
534 m_notebook->AddPage( m_LayerPanel, _( "Layers" ), true );
535 m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
536 wxTAB_TRAVERSAL );
537
538 wxBoxSizer* renderPanelSizer;
539 renderPanelSizer = new wxBoxSizer( wxVERTICAL );
540
541 m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition,
542 wxDefaultSize, wxNO_BORDER );
543 m_RenderScrolledWindow->SetScrollRate( 5, 5 );
544 m_RenderFlexGridSizer = new wxFlexGridSizer( 0, RND_COLUMN_COUNT, 3, 4 );
545 m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
546 m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
547
549 m_RenderScrolledWindow->Layout();
551 renderPanelSizer->Add( m_RenderScrolledWindow, 1, wxALL | wxEXPAND, 5 );
552
553 m_RenderingPanel->SetSizer( renderPanelSizer );
554 m_RenderingPanel->Layout();
555 renderPanelSizer->Fit( m_RenderingPanel );
556 m_notebook->AddPage( m_RenderingPanel, _( "Items" ), false );
557
558 mainSizer->Add( m_notebook, 1, wxEXPAND, 5 );
559
560 SetSizer( mainSizer );
561
562 m_FocusOwner = aFocusOwner;
563
564 m_CurrentRow = -1; // hide the arrow initially
565
566 // trap the tab changes so that we can call passOnFocus().
567 m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
568
569 Layout();
570}
571
572
574{
575 delete m_IconProvider;
576}
577
578
580{
581 // size of m_LayerScrolledWindow --------------
582 wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
583 int totWidth = 0;
584
585 for( int i = 0; i < LYR_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
586 totWidth += widths[i];
587
588 // Account for the parent's frame:
589 totWidth += 15;
590
591 /* The minimum height is a small size to properly force computation
592 * of the panel's scrollbars (otherwise it will assume it *has* all
593 * this space) */
594 unsigned totHeight = 32;
595
596 wxSize layerz( totWidth, totHeight );
597
598 layerz += m_LayerPanel->GetWindowBorderSize();
599
600 // size of m_RenderScrolledWindow --------------
601 widths = m_RenderFlexGridSizer->GetColWidths();
602 totWidth = 0;
603
604 for( int i = 0; i < RND_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
605 totWidth += widths[i];
606
607 // account for the parent's frame, this one has void space of 10 PLUS a border:
608 totWidth += 15;
609
610 // For totHeight re-use the previous small one
611 wxSize renderz( totWidth, totHeight );
612
613 renderz += m_RenderingPanel->GetWindowBorderSize();
614
615 wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
616
617 return clientz;
618}
619
620
622{
623 int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
624 return controlCount / LYR_COLUMN_COUNT;
625}
626
627
629{
630 int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
631 return controlCount / RND_COLUMN_COUNT;
632}
633
634
636{
637 int nextRow = GetLayerRowCount();
638 insertLayerRow( nextRow, aRow );
639}
640
641
643{
644 m_LayersFlexGridSizer->Clear( true );
645}
646
647
649{
650 int nextRow = GetRenderRowCount();
651 insertRenderRow( nextRow, aRow );
652}
653
654
656{
657 m_RenderFlexGridSizer->Clear( true );
658}
659
660
662{
664
665 if( oldIndicator )
667
668 INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
669
670 if( newIndicator )
671 {
673 }
674
675 m_CurrentRow = aRow;
676
677 // give the focus back to the app.
678 passOnFocus();
679}
680
681
683{
684 int row = findLayerRow( aLayer );
685 SelectLayerRow( row );
686}
687
688
690{
691 wxWindow* w = getLayerComp( m_CurrentRow, 0 );
692
693 if( w )
694 return getDecodedId( w->GetId() );
695
696 return UNDEFINED_LAYER;
697}
698
699
700void LAYER_WIDGET::SetLayerVisible( int aLayer, bool isVisible )
701{
702 setLayerCheckbox( aLayer, isVisible );
703 OnLayerVisible( aLayer, isVisible );
704}
705
706
707void LAYER_WIDGET::setLayerCheckbox( int aLayer, bool isVisible )
708{
709 int row = findLayerRow( aLayer );
710
711 if( row >= 0 )
712 {
713 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
714 wxASSERT( cb );
715 cb->SetValue( isVisible ); // does not fire an event
716 }
717}
718
719
721{
722 int row = findLayerRow( aLayer );
723
724 if( row >= 0 )
725 {
726 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
727 wxASSERT( cb );
728 return cb->GetValue();
729 }
730
731 return false;
732}
733
734
735void LAYER_WIDGET::SetLayerColor( int aLayer, const COLOR4D& aColor )
736{
737 int row = findLayerRow( aLayer );
738
739 if( row >= 0 )
740 {
741 int col = 1; // bitmap button is column 1
742 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
743 wxASSERT( swatch );
744
745 swatch->SetSwatchColor( aColor, false );
746 }
747}
748
749
751{
752 int row = findLayerRow( aLayer );
753
754 if( row >= 0 )
755 {
756 const int col = 1; // bitmap button is column 1
757 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
758 wxASSERT( swatch );
759
760 return swatch->GetSwatchColor();
761 }
762
763 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
764}
765
766
768{
769 int row = aRow;
770
771 if( row >= 0 )
772 {
773 const int col = 0; // bitmap button (swatch) is column 0
774 auto swatch = static_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
775 wxASSERT( swatch );
776
777 return swatch->GetSwatchColor();
778 }
779
780 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
781}
782
783
784void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
785{
786 int row = findRenderRow( aId );
787
788 if( row >= 0 )
789 {
790 int col = 1; // checkbox is column 1
791 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
792 wxASSERT( cb );
793 cb->SetValue( isSet ); // does not fire an event
794 }
795}
796
797
799{
800 int row = findRenderRow( aId );
801
802 if( row >= 0 )
803 {
804 int col = 1; // checkbox is column 1
805 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
806 wxASSERT( cb );
807 return cb->GetValue();
808 }
809
810 return false; // the value of a non-existent row
811}
812
813
815{
816 m_LayersFlexGridSizer->Layout();
817 m_RenderFlexGridSizer->Layout();
818 m_LayerPanel->Layout();
819 m_RenderingPanel->Layout();
820 FitInside();
821}
822
823
825{
826 int rowCount = GetLayerRowCount();
827
828 for( int row = 0; row < rowCount ; row++ )
829 {
831
832 if( indicator )
833 {
835
836 if( row == m_CurrentRow )
838 else
840
841 indicator->SetIndicatorState( state );
842 }
843 }
844}
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
A simple color swatch of the kind used to set layer colors.
Definition: color_swatch.h:57
void GetNewSwatchColor()
Prompt for a new colour, using the colour picker dialog.
KIGFX::COLOR4D GetSwatchColor() const
void SetSwatchBackground(const KIGFX::COLOR4D &aBackground)
Set the swatch background color.
representing a row indicator icon for use in places like the layer widget
void SetIndicatorState(ICON_ID aIconId)
Set the row indicator to the given state.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
static int getDecodedId(int aControlId)
Decode aControlId to original un-encoded value.
void SelectLayerRow(int aRow)
Change the row selection in the layer list to the given row.
wxWindow * m_FocusOwner
Definition: layer_widget.h:473
static int encodeId(int aColumn, int aId)
Allow saving a layer index within a control as its wxControl id.
void SetRenderState(int aId, bool isSet)
Set the state of the checkbox associated with aId within the Render tab group of the widget.
virtual void OnRenderEnable(int aId, bool isEnabled)=0
Notify client code whenever the user changes an rendering enable in one of the rendering checkboxes.
void insertRenderRow(int aRow, const ROW &aSpec)
void insertLayerRow(int aRow, const ROW &aSpec)
Append or insert a new row in the layer portion of the widget.
wxScrolledWindow * m_RenderScrolledWindow
Definition: layer_widget.h:470
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color of aLayer.
ROW_ICON_PROVIDER * m_IconProvider
Definition: layer_widget.h:477
bool GetRenderState(int aId)
Return the state of the checkbox associated with aId.
void OnLeftDownLayers(wxMouseEvent &event)
void setLayerCheckbox(int aLayer, bool isVisible)
int GetRenderRowCount() const
Return the number of rows in the render tab.
LAYER_WIDGET(wxWindow *aParent, wxWindow *aFocusOwner, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
wxPanel * m_RenderingPanel
Definition: layer_widget.h:469
virtual void OnLayerVisible(int aLayer, bool isVisible, bool isFinal=true)=0
Notify client code about a layer visibility change.
wxFlexGridSizer * m_LayersFlexGridSizer
Definition: layer_widget.h:468
void SelectLayer(int aLayer)
Change the row selection in the layer list to aLayer provided.
void OnRenderSwatchChanged(wxCommandEvent &aEvent)
Called when user has changed the swatch color of a render entry.
int GetLayerRowCount() const
Return the number of rows in the layer tab.
virtual ~LAYER_WIDGET()
void UpdateLayouts()
void passOnFocus()
Give away the keyboard focus up to the main parent window.
COLOR4D GetRenderColor(int aRow) const
Return the color of the Render ROW in position aRow.
void updateLayerRow(int aRow, const wxString &aName)
void OnTabChange(wxNotebookEvent &event)
int findLayerRow(int aLayer) const
Return the row index that aLayer resides in, or -1 if not found.
static const wxEventType EVT_LAYER_COLOR_CHANGE
Definition: layer_widget.h:120
int findRenderRow(int aId) const
int GetSelectedLayer()
Return the selected layer or -1 if none.
virtual void OnLayerRightClick(wxMenu &aMenu)=0
Notify client code about a layer being right-clicked.
void AppendRenderRow(const ROW &aRow)
Append a new row in the render portion of the widget.
bool IsLayerVisible(int aLayer)
Return the visible state of the layer ROW associated with aLayer id.
int m_CurrentRow
selected row of layer list
Definition: layer_widget.h:474
@ ID_CHANGE_RENDER_COLOR
Definition: layer_widget.h:461
virtual COLOR4D getBackgroundLayerColor()
Subclasses can override this to provide accurate representation of transparent color swatches.
Definition: layer_widget.h:369
void SetLayerVisible(int aLayer, bool isVisible)
Set aLayer visible or not.
void ClearLayerRows()
Empty out the layer rows.
void OnLayerSwatchChanged(wxCommandEvent &aEvent)
Called when a user changes a swatch color.
wxWindow * getLayerComp(int aRow, int aColumn) const
Return the component within the m_LayersFlexGridSizer at aRow and aCol or NULL if these parameters ar...
void UpdateLayerIcons()
Update all layer manager icons (layers only).
void AppendLayerRow(const ROW &aRow)
Append a new row in the layer portion of the widget.
wxString m_smallestLayerString
Definition: layer_widget.h:479
void ClearRenderRows()
Empty out the render rows.
virtual void OnRenderColorChange(int aId, const COLOR4D &aColor)=0
Notify client code whenever the user changes a rendering color.
virtual void OnLayerColorChange(int aLayer, const COLOR4D &aColor)=0
Notify client code about a layer color change.
COLOR4D GetLayerColor(int aLayer) const
Return the color of the layer ROW associated with aLayer id.
void OnLayerCheckBox(wxCommandEvent &event)
Handle the "is layer visible" checkbox and propagates the event to the client's notification function...
void OnRenderCheckBox(wxCommandEvent &event)
void OnRightDownLayer(wxMouseEvent &event, COLOR_SWATCH *aColorSwatch, const wxString &aLayerName)
Called when user right-clicks a layer.
wxWindow * getRenderComp(int aRow, int aColumn) const
void OnRightDownRender(wxMouseEvent &aEvent, COLOR_SWATCH *aColorSwatch, const wxString &aRenderName)
Notify when user right-clicks a render option.
virtual bool OnLayerSelect(int aLayer)=0
Notify client code whenever the user selects a different layer.
wxFlexGridSizer * m_RenderFlexGridSizer
Definition: layer_widget.h:471
wxPanel * m_LayerPanel
Definition: layer_widget.h:466
wxSize GetBestSize() const
Return the preferred minimum size, taking into consideration the dynamic content.
wxNotebook * m_notebook
Definition: layer_widget.h:465
wxScrolledWindow * m_LayerScrolledWindow
Definition: layer_widget.h:467
Icon provider for the "standard" row indicators, for example in layer selection lists.
STATE
< State constants to select the right icons
@ OFF
Row "off" or "deselected".
@ ON
Row "on" or "selected".
A version of a wxStaticText control that will request a smaller size than the full string.
void SetMinimumStringLength(const wxString &aString)
Set the string that is used for determining the requested size of the control.
@ SWATCH_SMALL
Definition: color_swatch.h:40
#define _(s)
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition: layer_ids.h:224
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
static void shrinkFont(wxWindow *aControl, int aPointSize)
Reduce the size of the wxFont associated with aControl.
#define LYR_COLUMN_COUNT
Layer tab column count.
Definition: layer_widget.h:48
#define COLUMN_COLOR_LYRNAME
Definition: layer_widget.h:54
#define COLUMN_ALPHA_INDICATOR
Definition: layer_widget.h:55
#define COLUMN_COLOR_LYR_CB
Definition: layer_widget.h:53
#define COLUMN_ICON_ACTIVE
Definition: layer_widget.h:51
#define COLUMN_COLORBM
Definition: layer_widget.h:52
#define RND_COLUMN_COUNT
Rendering tab column count.
Definition: layer_widget.h:49
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API 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: ui_common.cpp:369
Provide all the data needed to add a row to a LAYER_WIDGET.
Definition: layer_widget.h:85
COLOR4D color
COLOR4D::UNSPECIFIED if none.
Definition: layer_widget.h:88
bool spacer
if true, this row is a spacer
Definition: layer_widget.h:92
wxString tooltip
if not empty, use this tooltip on row
Definition: layer_widget.h:90
int id
either a layer or "visible element" id
Definition: layer_widget.h:87
bool state
initial wxCheckBox state
Definition: layer_widget.h:89
wxString rowName
the prompt or layername
Definition: layer_widget.h:86
bool changeable
if true, the state can be changed
Definition: layer_widget.h:91
COLOR4D defaultColor
The default color for the row.
Definition: layer_widget.h:93