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 {
451 OnRightDownRender( aEvt, bmb, renderName );
452 } );
453 cb->Bind( wxEVT_RIGHT_DOWN, [this, bmb, renderName] ( wxMouseEvent& aEvt )
454 {
455 OnRightDownRender( aEvt, bmb, renderName );
456 } );
457
458 // could add a left click handler on the color button that toggles checkbox.
459 }
460 else // == -1, no color selection wanted
461 {
462 // need a place holder within the sizer to keep grid full.
463 wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, encodeId( col, aSpec.id ) );
464 m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
465 }
466
467 // Items have to be inserted in order
468 col = 1;
469
470 if( aSpec.spacer )
471 {
472 wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, wxID_ANY );
473 m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
474 }
475 else
476 {
477 m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
478 }
479}
480
481
483{
484 m_FocusOwner->SetFocus();
485}
486
487
488LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, wxWindowID id,
489 const wxPoint& pos, const wxSize& size, long style ) :
490 wxPanel( aParent, id, pos, size, style ),
491 m_smallestLayerString( wxT( "M...M" ) )
492{
494
495 int pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
496 int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
497
498 if( screenHeight <= 900 && pointSize >= FromDIP( KIUI::c_IndicatorSizeDIP ) )
499 pointSize = pointSize * 8 / 10;
500
501 m_PointSize = pointSize;
502
503 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
504
505 m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
506
507 wxFont font = m_notebook->GetFont();
508
509 // change the font size on the notebook's tabs to match aPointSize
510 font.SetPointSize( pointSize );
511 m_notebook->SetFont( font );
512
513 m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
514 wxTAB_TRAVERSAL );
515
516 wxBoxSizer* layerPanelSizer;
517 layerPanelSizer = new wxBoxSizer( wxVERTICAL );
518
519 m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition,
520 wxDefaultSize, wxNO_BORDER );
521 m_LayerScrolledWindow->SetScrollRate( 5, 5 );
522 m_LayersFlexGridSizer = new wxFlexGridSizer( 0, LYR_COLUMN_COUNT, 3, 4 );
523 m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
524 m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
525
526 // Make column 3 growable/stretchable
527 m_LayersFlexGridSizer->AddGrowableCol( 3, 1 );
528
530 m_LayerScrolledWindow->Layout();
532 layerPanelSizer->Add( m_LayerScrolledWindow, 1, wxBOTTOM | wxEXPAND | wxLEFT | wxTOP, 2 );
533
534 m_LayerPanel->SetSizer( layerPanelSizer );
535 m_LayerPanel->Layout();
536 layerPanelSizer->Fit( m_LayerPanel );
537 m_notebook->AddPage( m_LayerPanel, _( "Layers" ), true );
538 m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
539 wxTAB_TRAVERSAL );
540
541 wxBoxSizer* renderPanelSizer;
542 renderPanelSizer = new wxBoxSizer( wxVERTICAL );
543
544 m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition,
545 wxDefaultSize, wxNO_BORDER );
546 m_RenderScrolledWindow->SetScrollRate( 5, 5 );
547 m_RenderFlexGridSizer = new wxFlexGridSizer( 0, RND_COLUMN_COUNT, 3, 4 );
548 m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
549 m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
550
552 m_RenderScrolledWindow->Layout();
554 renderPanelSizer->Add( m_RenderScrolledWindow, 1, wxALL | wxEXPAND, 5 );
555
556 m_RenderingPanel->SetSizer( renderPanelSizer );
557 m_RenderingPanel->Layout();
558 renderPanelSizer->Fit( m_RenderingPanel );
559 m_notebook->AddPage( m_RenderingPanel, _( "Items" ), false );
560
561 mainSizer->Add( m_notebook, 1, wxEXPAND, 5 );
562
563 SetSizer( mainSizer );
564
565 m_FocusOwner = aFocusOwner;
566
567 m_CurrentRow = -1; // hide the arrow initially
568
569 // trap the tab changes so that we can call passOnFocus().
570 m_notebook->Bind( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &LAYER_WIDGET::OnTabChange, this );
571
572 Layout();
573}
574
575
577{
578 delete m_IconProvider;
579}
580
581
583{
584 // size of m_LayerScrolledWindow --------------
585 wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
586 int totWidth = 0;
587
588 for( int i = 0; i < LYR_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
589 totWidth += widths[i];
590
591 // Account for the parent's frame:
592 totWidth += 15;
593
594 /* The minimum height is a small size to properly force computation
595 * of the panel's scrollbars (otherwise it will assume it *has* all
596 * this space) */
597 unsigned totHeight = 32;
598
599 wxSize layerz( totWidth, totHeight );
600
601 layerz += m_LayerPanel->GetWindowBorderSize();
602
603 // size of m_RenderScrolledWindow --------------
604 widths = m_RenderFlexGridSizer->GetColWidths();
605 totWidth = 0;
606
607 for( int i = 0; i < RND_COLUMN_COUNT && i < (int)widths.GetCount(); ++i )
608 totWidth += widths[i];
609
610 // account for the parent's frame, this one has void space of 10 PLUS a border:
611 totWidth += 15;
612
613 // For totHeight re-use the previous small one
614 wxSize renderz( totWidth, totHeight );
615
616 renderz += m_RenderingPanel->GetWindowBorderSize();
617
618 wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
619
620 return clientz;
621}
622
623
625{
626 int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
627 return controlCount / LYR_COLUMN_COUNT;
628}
629
630
632{
633 int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
634 return controlCount / RND_COLUMN_COUNT;
635}
636
637
639{
640 int nextRow = GetLayerRowCount();
641 insertLayerRow( nextRow, aRow );
642}
643
644
646{
647 m_LayersFlexGridSizer->Clear( true );
648}
649
650
652{
653 int nextRow = GetRenderRowCount();
654 insertRenderRow( nextRow, aRow );
655}
656
657
659{
660 m_RenderFlexGridSizer->Clear( true );
661}
662
663
665{
667
668 if( oldIndicator )
670
671 INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
672
673 if( newIndicator )
674 {
676 }
677
678 m_CurrentRow = aRow;
679
680 // give the focus back to the app.
681 passOnFocus();
682}
683
684
686{
687 int row = findLayerRow( aLayer );
688 SelectLayerRow( row );
689}
690
691
693{
694 wxWindow* w = getLayerComp( m_CurrentRow, 0 );
695
696 if( w )
697 return getDecodedId( w->GetId() );
698
699 return UNDEFINED_LAYER;
700}
701
702
703void LAYER_WIDGET::SetLayerVisible( int aLayer, bool isVisible )
704{
705 setLayerCheckbox( aLayer, isVisible );
706 OnLayerVisible( aLayer, isVisible );
707}
708
709
710void LAYER_WIDGET::setLayerCheckbox( int aLayer, bool isVisible )
711{
712 int row = findLayerRow( aLayer );
713
714 if( row >= 0 )
715 {
716 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
717 wxASSERT( cb );
718 cb->SetValue( isVisible ); // does not fire an event
719 }
720}
721
722
724{
725 int row = findLayerRow( aLayer );
726
727 if( row >= 0 )
728 {
729 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
730 wxASSERT( cb );
731 return cb->GetValue();
732 }
733
734 return false;
735}
736
737
738void LAYER_WIDGET::SetLayerColor( int aLayer, const COLOR4D& aColor )
739{
740 int row = findLayerRow( aLayer );
741
742 if( row >= 0 )
743 {
744 int col = 1; // bitmap button is column 1
745 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
746 wxASSERT( swatch );
747
748 swatch->SetSwatchColor( aColor, false );
749 }
750}
751
752
754{
755 int row = findLayerRow( aLayer );
756
757 if( row >= 0 )
758 {
759 const int col = 1; // bitmap button is column 1
760 auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
761 wxASSERT( swatch );
762
763 return swatch->GetSwatchColor();
764 }
765
766 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
767}
768
769
771{
772 int row = aRow;
773
774 if( row >= 0 )
775 {
776 const int col = 0; // bitmap button (swatch) is column 0
777 auto swatch = static_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
778 wxASSERT( swatch );
779
780 return swatch->GetSwatchColor();
781 }
782
783 return COLOR4D::UNSPECIFIED; // it's caller fault, gave me a bad layer
784}
785
786
787void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
788{
789 int row = findRenderRow( aId );
790
791 if( row >= 0 )
792 {
793 int col = 1; // checkbox is column 1
794 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
795 wxASSERT( cb );
796 cb->SetValue( isSet ); // does not fire an event
797 }
798}
799
800
802{
803 int row = findRenderRow( aId );
804
805 if( row >= 0 )
806 {
807 int col = 1; // checkbox is column 1
808 wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
809 wxASSERT( cb );
810 return cb->GetValue();
811 }
812
813 return false; // the value of a non-existent row
814}
815
816
818{
819 m_LayersFlexGridSizer->Layout();
820 m_RenderFlexGridSizer->Layout();
821 m_LayerPanel->Layout();
822 m_RenderingPanel->Layout();
823 FitInside();
824}
825
826
828{
829 int rowCount = GetLayerRowCount();
830
831 for( int row = 0; row < rowCount ; row++ )
832 {
834
835 if( indicator )
836 {
838
839 if( row == m_CurrentRow )
841 else
843
844 indicator->SetIndicatorState( state );
845 }
846 }
847}
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:221
@ 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 wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: ui_common.cpp:372
const int c_IndicatorSizeDIP
Definition: ui_common.h:52
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.