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 The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22
23
24/* This source module implements the layer visibility and selection widget
25 @todo make bitmap size dependent on the point size.
26*/
27
28
29//#define STAND_ALONE 1 // define to enable test program for LAYER_WIDGET
30
31
32#include "layer_widget.h"
33
34#include <bitmaps.h>
35#include <macros.h>
38#include <widgets/ui_common.h>
39#include <wx/checkbox.h>
40#include <wx/menu.h>
41
42#include <algorithm>
43
44
45const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
46
47
51static void shrinkFont( wxWindow* aControl, int aPointSize )
52{
53 wxFont font = aControl->GetFont();
54 font.SetPointSize( aPointSize );
55 aControl->SetFont( font ); // need this?
56}
57
58
59int LAYER_WIDGET::encodeId( int aColumn, int aId )
60{
61 int id = aId * LYR_COLUMN_COUNT + aColumn;
62 return id;
63}
64
65
66int LAYER_WIDGET::getDecodedId( int aControlId )
67{
68 int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
69 return id;
70}
71
72
73void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
74{
75 int row;
76 int layer;
77
78 wxWindow* eventSource = (wxWindow*) event.GetEventObject();
79
80 // if mouse event is coming from the m_LayerScrolledWindow and not one
81 // of its children, we have to find the row manually based on y coord.
82 if( eventSource == m_LayerScrolledWindow )
83 {
84 int y = event.GetY();
85
86 wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();
87
88 int height = 0;
89
90 int rowCount = GetLayerRowCount();
91
92 for( row = 0; row<rowCount; ++row )
93 {
94 if( y < height + heights[row] )
95 break;
96
97 height += heights[row];
98 }
99
100 if( row >= rowCount )
101 row = rowCount - 1;
102
103 layer = getDecodedId( getLayerComp( row, 0 )->GetId() );
104 }
105 else
106 {
107 // all nested controls on a given row will have their ID encoded with
108 // encodeId(), and the corresponding decoding is getDecodedId()
109 int id = eventSource->GetId();
110 layer = getDecodedId( id );
111 row = findLayerRow( layer );
112 }
113
114 if( OnLayerSelect( layer ) ) // if client allows this change.
115 SelectLayerRow( row );
116
117 passOnFocus();
118}
119
120
121void LAYER_WIDGET::OnRightDownLayer( wxMouseEvent& aEvent, COLOR_SWATCH* aColorSwatch,
122 const wxString& aLayerName )
123{
124 wxMenu menu;
125
127 _( "Change Layer Color for" ) + wxS( " " ) + aLayerName,
129 menu.AppendSeparator();
130
131 OnLayerRightClick( menu );
132
133 menu.Bind( wxEVT_COMMAND_MENU_SELECTED, [aColorSwatch]( wxCommandEvent& event )
134 {
135 if( event.GetId() == ID_CHANGE_LAYER_COLOR )
136 {
137 aColorSwatch->GetNewSwatchColor();
138 }
139 else
140 {
141 event.Skip();
142 }
143 } );
144
145 PopupMenu( &menu );
146 passOnFocus();
147}
148
149
150void LAYER_WIDGET::OnLayerSwatchChanged( wxCommandEvent& aEvent )
151{
152 COLOR_SWATCH* eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
153 COLOR4D newColor = eventSource->GetSwatchColor();
154 int layer = getDecodedId( eventSource->GetId() );
155
156 // tell the client code.
157 OnLayerColorChange( layer, newColor );
158
159 // notify others
160 wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
161 wxPostEvent( this, event );
162
163 passOnFocus();
164}
165
166
167void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
168{
169 wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
170 int layer = getDecodedId( eventSource->GetId() );
171
172 OnLayerVisible( layer, eventSource->IsChecked() );
173 passOnFocus();
174}
175
176
177void LAYER_WIDGET::OnRightDownRender( wxMouseEvent& aEvent, COLOR_SWATCH* aColorSwatch,
178 const wxString& aRenderName )
179{
180 wxMenu menu;
181
183 _( "Change Render Color for" ) + wxS( " " )+ aRenderName,
185
186 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
187 [aColorSwatch]( wxCommandEvent& event )
188 {
189 if( event.GetId() == ID_CHANGE_RENDER_COLOR )
190 aColorSwatch->GetNewSwatchColor();
191 else
192 event.Skip();
193 } );
194
195 PopupMenu( &menu );
196 passOnFocus();
197}
198
199
200void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
201{
202 COLOR_SWATCH* eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );
203 COLOR4D newColor = eventSource->GetSwatchColor();
204 int id = getDecodedId( eventSource->GetId() );
205
206 if( id == LAYER_PCB_BACKGROUND )
207 {
208 // Update all swatch backgrounds
209 int col = 1; // bitmap button is column 1 in layers tab
210
211 for( int row = 0; row < GetLayerRowCount(); ++row )
212 {
213 COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
214
215 if( swatch )
216 swatch->SetSwatchBackground( newColor );
217 }
218
219 col = 0; // bitmap button is column 0 in render tab
220
221 for( int row = 0; row < GetRenderRowCount(); ++row )
222 {
223 COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
224
225 if( swatch )
226 swatch->SetSwatchBackground( newColor );
227 }
228 }
229
230 // tell the client code.
231 OnRenderColorChange( id, newColor );
232
233 passOnFocus();
234}
235
236
237void LAYER_WIDGET::OnRenderCheckBox( wxCommandEvent& event )
238{
239 wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
240 int id = getDecodedId( eventSource->GetId() );
241
242 OnRenderEnable( id, eventSource->IsChecked() );
243 passOnFocus();
244}
245
246
247void LAYER_WIDGET::OnTabChange( wxNotebookEvent& event )
248{
249// wxFocusEvent event( wxEVT_SET_FOCUS );
250// m_FocusOwner->AddPendingEvent( event );
251
252 // Does not work in this context, probably because we have receive control here too early.
253 passOnFocus();
254}
255
256
257wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
258{
259 unsigned ndx = aRow * LYR_COLUMN_COUNT + aColumn;
260
261 if( ndx < m_LayersFlexGridSizer->GetChildren().GetCount() )
262 return m_LayersFlexGridSizer->GetChildren()[ndx]->GetWindow();
263
264 return nullptr;
265}
266
267
268int LAYER_WIDGET::findLayerRow( int aLayer ) const
269{
270 int count = GetLayerRowCount();
271
272 for( int row = 0; row < count; ++row )
273 {
274 // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
275 wxWindow* w = getLayerComp( row, 0 );
276 wxASSERT( w );
277
278 if( aLayer == getDecodedId( w->GetId() ) )
279 return row;
280 }
281
282 return -1;
283}
284
285
286wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
287{
288 int ndx = aRow * RND_COLUMN_COUNT + aColumn;
289
290 if( (unsigned) ndx < m_RenderFlexGridSizer->GetChildren().GetCount() )
291 return m_RenderFlexGridSizer->GetChildren()[ndx]->GetWindow();
292
293 return nullptr;
294}
295
296
297int LAYER_WIDGET::findRenderRow( int aId ) const
298{
299 int count = GetRenderRowCount();
300
301 for( int row = 0; row < count; ++row )
302 {
303 // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
304 wxWindow* w = getRenderComp( row, 0 );
305 wxASSERT( w );
306
307 if( aId == getDecodedId( w->GetId() ) )
308 return row;
309 }
310
311 return -1;
312}
313
314
315void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
316{
317 wxASSERT( aRow >= 0 );
318
319 int col;
320 int index = aRow * LYR_COLUMN_COUNT;
321 const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
322
323 // column 0
324 col = COLUMN_ICON_ACTIVE;
327 sbm->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
328 m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
329
330 // column 1 (COLUMN_COLORBM)
331 col = COLUMN_COLORBM;
332
333 auto bmb = new COLOR_SWATCH( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
335 bmb->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
336 bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnLayerSwatchChanged, this );
337 bmb->SetToolTip( _( "Left double click or middle click for color change, right click for "
338 "menu" ) );
339 m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags | wxRIGHT, 2 );
340
341 // column 2 (COLUMN_COLOR_LYR_CB)
343 wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, encodeId( col, aSpec.id ),
344 wxEmptyString );
345 cb->SetValue( aSpec.state );
346 cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnLayerCheckBox, this );
347 cb->SetToolTip( _( "Enable this for visibility" ) );
348 m_LayersFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
349
350 // column 3 (COLUMN_COLOR_LYRNAME)
353 encodeId( col, aSpec.id ),
354 aSpec.rowName, wxDefaultPosition,
355 wxDefaultSize,
356 wxST_ELLIPSIZE_MIDDLE );
357 shrinkFont( st, m_PointSize );
358 st->Bind( wxEVT_LEFT_DOWN, &LAYER_WIDGET::OnLeftDownLayers, this );
359 st->SetToolTip( aSpec.tooltip );
361 m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags | wxEXPAND );
362
363 // column 4 (COLUMN_ALPHA_INDICATOR)
367 m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
368
369 // Bind right click eventhandler to all columns
370 wxString layerName( aSpec.rowName );
371
372 sbm->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
373 {
374 OnRightDownLayer( aEvt, bmb, layerName );
375 } );
376 bmb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
377 {
378 OnRightDownLayer( aEvt, bmb, layerName );
379 } );
380 cb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
381 {
382 OnRightDownLayer( aEvt, bmb, layerName );
383 } );
384 st->Bind( wxEVT_RIGHT_DOWN, [this, bmb, layerName] ( wxMouseEvent& aEvt )
385 {
386 OnRightDownLayer( aEvt, bmb, layerName );
387 } );
388}
389
390
391void LAYER_WIDGET::updateLayerRow( int aRow, const wxString& aName )
392{
393 wxStaticText* label = dynamic_cast<wxStaticText*>( getLayerComp( aRow, COLUMN_COLOR_LYRNAME ) );
394
395 if( label )
396 label->SetLabel( aName );
397
398 INDICATOR_ICON* indicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
399
400 if( indicator )
401 {
402 if( aRow == m_CurrentRow )
404 else
406 }
407}
408
409
410void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
411{
412 wxASSERT( aRow >= 0 );
413
414 int col;
415 int index = aRow * RND_COLUMN_COUNT;
416 const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
417
418 wxString renderName( aSpec.rowName );
419 wxCheckBox* cb = nullptr;
420
421 // column 1
422 if( !aSpec.spacer )
423 {
424 col = 1;
425 cb = new wxCheckBox( m_RenderScrolledWindow, encodeId( col, aSpec.id ),
426 aSpec.rowName, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
427 shrinkFont( cb, m_PointSize );
428 cb->SetValue( aSpec.state );
429 cb->Enable( aSpec.changeable );
430 cb->Bind( wxEVT_COMMAND_CHECKBOX_CLICKED, &LAYER_WIDGET::OnRenderCheckBox, this );
431 cb->SetToolTip( aSpec.tooltip );
432 }
433
434 // column 0
435 col = 0;
436
437 if( aSpec.color != COLOR4D::UNSPECIFIED )
438 {
439 auto bmb = new COLOR_SWATCH( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ),
441 bmb->Bind( COLOR_SWATCH_CHANGED, &LAYER_WIDGET::OnRenderSwatchChanged, this );
442 bmb->SetToolTip( _( "Left double click or middle click for color change" ) );
443 m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
444
445 bmb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, renderName] ( wxMouseEvent& aEvt )
446 {
447 OnRightDownRender( aEvt, bmb, renderName );
448 } );
449 cb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, renderName] ( wxMouseEvent& aEvt )
450 {
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{
490
491 int pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
492 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
493
494 if( screenHeight <= 900 && pointSize >= FromDIP( KIUI::c_IndicatorSizeDIP ) )
495 pointSize = pointSize * 8 / 10;
496
497 m_PointSize = pointSize;
498
499 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
500
501 m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
502
503 wxFont font = m_notebook->GetFont();
504
505 // change the font size on the notebook's tabs to match aPointSize
506 font.SetPointSize( pointSize );
507 m_notebook->SetFont( font );
508
509 m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
510 wxTAB_TRAVERSAL );
511
512 wxBoxSizer* layerPanelSizer;
513 layerPanelSizer = new wxBoxSizer( wxVERTICAL );
514
515 m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition,
516 wxDefaultSize, wxNO_BORDER );
517 m_LayerScrolledWindow->SetScrollRate( 5, 5 );
518 m_LayersFlexGridSizer = new wxFlexGridSizer( 0, LYR_COLUMN_COUNT, 3, 4 );
519 m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
520 m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
521
522 // Make column 3 growable/stretchable
523 m_LayersFlexGridSizer->AddGrowableCol( 3, 1 );
524
526 m_LayerScrolledWindow->Layout();
528 layerPanelSizer->Add( m_LayerScrolledWindow, 1, wxBOTTOM | wxEXPAND | wxLEFT | wxTOP, 2 );
529
530 m_LayerPanel->SetSizer( layerPanelSizer );
531 m_LayerPanel->Layout();
532 layerPanelSizer->Fit( m_LayerPanel );
533 m_notebook->AddPage( m_LayerPanel, _( "Layers" ), true );
534 m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
535 wxTAB_TRAVERSAL );
536
537 wxBoxSizer* renderPanelSizer;
538 renderPanelSizer = new wxBoxSizer( wxVERTICAL );
539
540 m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition,
541 wxDefaultSize, wxNO_BORDER );
542 m_RenderScrolledWindow->SetScrollRate( 5, 5 );
543 m_RenderFlexGridSizer = new wxFlexGridSizer( 0, RND_COLUMN_COUNT, 3, 4 );
544 m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
545 m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
546
548 m_RenderScrolledWindow->Layout();
550 renderPanelSizer->Add( m_RenderScrolledWindow, 1, wxALL | wxEXPAND, 5 );
551
552 m_RenderingPanel->SetSizer( renderPanelSizer );
553 m_RenderingPanel->Layout();
554 renderPanelSizer->Fit( m_RenderingPanel );
555 m_notebook->AddPage( m_RenderingPanel, _( "Items" ), false );
556
557 mainSizer->Add( m_notebook, 1, wxEXPAND, 5 );
558
559 SetSizer( mainSizer );
560
561 m_FocusOwner = aFocusOwner;
562
563 m_CurrentRow = -1; // hide the arrow initially
564
565 // trap the tab changes so that we can call passOnFocus().
566 m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
567
568 Layout();
569}
570
571
576
577
579{
580 // size of m_LayerScrolledWindow --------------
581 wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
582 int totWidth = 0;
583
584 for( int i = 0; i < LYR_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
585 totWidth += widths[i];
586
587 // Account for the parent's frame:
588 totWidth += 15;
589
590 /* The minimum height is a small size to properly force computation
591 * of the panel's scrollbars (otherwise it will assume it *has* all
592 * this space) */
593 unsigned totHeight = 32;
594
595 wxSize layerz( totWidth, totHeight );
596
597 layerz += m_LayerPanel->GetWindowBorderSize();
598
599 // size of m_RenderScrolledWindow --------------
600 widths = m_RenderFlexGridSizer->GetColWidths();
601 totWidth = 0;
602
603 for( int i = 0; i < RND_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
604 totWidth += widths[i];
605
606 // account for the parent's frame, this one has void space of 10 PLUS a border:
607 totWidth += 15;
608
609 // For totHeight re-use the previous small one
610 wxSize renderz( totWidth, totHeight );
611
612 renderz += m_RenderingPanel->GetWindowBorderSize();
613
614 wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
615
616 return clientz;
617}
618
619
621{
622 int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
623 return controlCount / LYR_COLUMN_COUNT;
624}
625
626
628{
629 int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
630 return controlCount / RND_COLUMN_COUNT;
631}
632
633
635{
636 int nextRow = GetLayerRowCount();
637 insertLayerRow( nextRow, aRow );
638}
639
640
642{
643 m_LayersFlexGridSizer->Clear( true );
644}
645
646
648{
649 int nextRow = GetRenderRowCount();
650 insertRenderRow( nextRow, aRow );
651}
652
653
655{
656 m_RenderFlexGridSizer->Clear( true );
657}
658
659
661{
663
664 if( oldIndicator )
666
667 INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
668
669 if( newIndicator )
670 {
672 }
673
674 m_CurrentRow = aRow;
675
676 // give the focus back to the app.
677 passOnFocus();
678}
679
680
682{
683 int row = findLayerRow( aLayer );
684 SelectLayerRow( row );
685}
686
687
689{
690 wxWindow* w = getLayerComp( m_CurrentRow, 0 );
691
692 if( w )
693 return getDecodedId( w->GetId() );
694
695 return UNDEFINED_LAYER;
696}
697
698
699void LAYER_WIDGET::SetLayerVisible( int aLayer, bool isVisible )
700{
701 setLayerCheckbox( aLayer, isVisible );
702 OnLayerVisible( aLayer, isVisible );
703}
704
705
706void LAYER_WIDGET::setLayerCheckbox( int aLayer, bool isVisible )
707{
708 int row = findLayerRow( aLayer );
709
710 if( row >= 0 )
711 {
712 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
713 wxASSERT( cb );
714 cb->SetValue( isVisible ); // does not fire an event
715 }
716}
717
718
720{
721 int row = findLayerRow( aLayer );
722
723 if( row >= 0 )
724 {
725 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
726 wxASSERT( cb );
727 return cb->GetValue();
728 }
729
730 return false;
731}
732
733
734void LAYER_WIDGET::SetLayerColor( int aLayer, const COLOR4D& aColor )
735{
736 int row = findLayerRow( aLayer );
737
738 if( row >= 0 )
739 {
740 int col = 1; // bitmap button is column 1
741 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
742 wxASSERT( swatch );
743
744 swatch->SetSwatchColor( aColor, false );
745 }
746}
747
748
750{
751 int row = findLayerRow( aLayer );
752
753 if( row >= 0 )
754 {
755 const int col = 1; // bitmap button is column 1
756 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
757 wxASSERT( swatch );
758
759 return swatch->GetSwatchColor();
760 }
761
762 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
763}
764
765
767{
768 int row = aRow;
769
770 if( row >= 0 )
771 {
772 const int col = 0; // bitmap button (swatch) is column 0
773 auto swatch = static_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
774 wxASSERT( swatch );
775
776 return swatch->GetSwatchColor();
777 }
778
779 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
780}
781
782
783void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
784{
785 int row = findRenderRow( aId );
786
787 if( row >= 0 )
788 {
789 int col = 1; // checkbox is column 1
790 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
791 wxASSERT( cb );
792 cb->SetValue( isSet ); // does not fire an event
793 }
794}
795
796
798{
799 int row = findRenderRow( aId );
800
801 if( row >= 0 )
802 {
803 int col = 1; // checkbox is column 1
804 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
805 wxASSERT( cb );
806 return cb->GetValue();
807 }
808
809 return false; // the value of a non-existent row
810}
811
812
814{
815 m_LayersFlexGridSizer->Layout();
816 m_RenderFlexGridSizer->Layout();
817 m_LayerPanel->Layout();
818 m_RenderingPanel->Layout();
819 FitInside();
820}
821
822
824{
825 int rowCount = GetLayerRowCount();
826
827 for( int row = 0; row < rowCount ; row++ )
828 {
830
831 if( indicator )
832 {
834
835 if( row == m_CurrentRow )
837 else
839
840 indicator->SetIndicatorState( state );
841 }
842 }
843}
int index
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:100
@ color_materials
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
A simple color swatch of the kind used to set layer colors.
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.
Represent 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:101
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
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
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color of aLayer.
ROW_ICON_PROVIDER * m_IconProvider
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
virtual void OnLayerVisible(int aLayer, bool isVisible, bool isFinal=true)=0
Notify client code about a layer visibility change.
wxFlexGridSizer * m_LayersFlexGridSizer
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 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
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
virtual COLOR4D getBackgroundLayerColor()
Subclasses can override this to provide accurate representation of transparent color swatches.
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
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
wxPanel * m_LayerPanel
wxSize GetBestSize() const
Return the preferred minimum size, taking into consideration the dynamic content.
wxNotebook * m_notebook
wxScrolledWindow * m_LayerScrolledWindow
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
#define _(s)
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition layer_ids.h:277
@ UNDEFINED_LAYER
Definition layer_ids.h:57
static void shrinkFont(wxWindow *aControl, int aPointSize)
Reduce the size of the wxFont associated with aControl.
#define LYR_COLUMN_COUNT
Layer tab column count.
#define COLUMN_COLOR_LYRNAME
#define COLUMN_ALPHA_INDICATOR
#define COLUMN_COLOR_LYR_CB
#define COLUMN_ICON_ACTIVE
#define COLUMN_COLORBM
#define RND_COLUMN_COUNT
Rendering tab column count.
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
const int c_IndicatorSizeDIP
Definition ui_common.h:52
Provide all the data needed to add a row to a LAYER_WIDGET.
COLOR4D color
COLOR4D::UNSPECIFIED if none.
bool spacer
if true, this row is a spacer
wxString tooltip
if not empty, use this tooltip on row
int id
either a layer or "visible element" id
bool state
initial wxCheckBox state
wxString rowName
the prompt or layername
bool changeable
if true, the state can be changed
COLOR4D defaultColor
The default color for the row.
Functions to provide common constants and other functions to assist in making a consistent UI.