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