1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2014-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 #include <layer_ids.h>
26 #include <bitmaps.h>
27 
28 #include <wx/dcmemory.h>
29 #include <wx/odcombo.h>
30 #include <wx/menuitem.h>
31 
32 #include <widgets/layer_box_selector.h>
33 
34 
LAYER_SELECTOR()35 LAYER_SELECTOR::LAYER_SELECTOR()
36 {
37     m_layerhotkeys = true;
38 }
39 
40 
SetLayersHotkeys(bool value)41 bool LAYER_SELECTOR::SetLayersHotkeys( bool value )
42 {
43     m_layerhotkeys = value;
44     return m_layerhotkeys;
45 }
46 
47 
DrawColorSwatch(wxBitmap & aLayerbmp,const COLOR4D & aBackground,const COLOR4D & aColor)48 void LAYER_SELECTOR::DrawColorSwatch( wxBitmap& aLayerbmp, const COLOR4D& aBackground,
49                                       const COLOR4D& aColor )
50 {
51     wxMemoryDC bmpDC;
52     wxBrush    brush;
53 
54     // Prepare Bitmap
55     bmpDC.SelectObject( aLayerbmp );
56 
57     brush.SetStyle( wxBRUSHSTYLE_SOLID );
58 
59     if( aBackground != COLOR4D::UNSPECIFIED )
60     {
61         brush.SetColour( aBackground.WithAlpha( 1.0 ).ToColour() );
62         bmpDC.SetBrush( brush );
63         bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() );
64     }
65 
66     brush.SetColour( aColor.ToColour() );
67     bmpDC.SetBrush( brush );
68     bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() );
69 
70     bmpDC.SetBrush( *wxTRANSPARENT_BRUSH );
71     bmpDC.SetPen( *wxBLACK_PEN );
72     bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() );
73 }
74 
75 
LAYER_BOX_SELECTOR(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,int n,const wxString choices[])76 LAYER_BOX_SELECTOR::LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id,
77                                         const wxPoint& pos, const wxSize& size,
78                                         int n, const wxString choices[] ) :
79     wxBitmapComboBox( parent, id, wxEmptyString, pos, size, n, choices, wxCB_READONLY ),
80     LAYER_SELECTOR()
81 {
82     if( choices != nullptr )
83         ResyncBitmapOnly();
84 
85     GetParent()->Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( LAYER_BOX_SELECTOR::onKeyDown ),
86                           nullptr, this );
87 }
88 
89 
LAYER_BOX_SELECTOR(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,const wxArrayString & choices)90 LAYER_BOX_SELECTOR::LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id,
91                                         const wxPoint& pos, const wxSize& size,
92                                         const wxArrayString& choices ) :
93     wxBitmapComboBox( parent, id, wxEmptyString, pos, size, choices, wxCB_READONLY ),
94     LAYER_SELECTOR()
95 {
96     if( !choices.IsEmpty() )
97         ResyncBitmapOnly();
98 
99     GetParent()->Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( LAYER_BOX_SELECTOR::onKeyDown ),
100                           nullptr, this );
101 }
102 
103 
~LAYER_BOX_SELECTOR()104 LAYER_BOX_SELECTOR::~LAYER_BOX_SELECTOR()
105 {
106     GetParent()->Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( LAYER_BOX_SELECTOR::onKeyDown ),
107                              nullptr, this );
108 }
109 
110 
GetChoice()111 int LAYER_BOX_SELECTOR::GetChoice()
112 {
113     return GetSelection();
114 }
115 
116 
GetLayerSelection() const117 LAYER_NUM LAYER_BOX_SELECTOR::GetLayerSelection() const
118 {
119     if( GetSelection() < 0 )
120         return UNDEFINED_LAYER;
121 
122     return (LAYER_NUM)(intptr_t) GetClientData( GetSelection() );
123 }
124 
125 
SetLayerSelection(LAYER_NUM layer)126 int LAYER_BOX_SELECTOR::SetLayerSelection( LAYER_NUM layer )
127 {
128     int elements = GetCount();
129 
130     for( int i = 0; i < elements; i++ )
131     {
132         if( GetClientData( (unsigned) i ) == (void*)(intptr_t) layer )
133         {
134             if( GetSelection() != i )   // Element (i) is not selected
135             {
136                 SetSelection( i );
137                 return i;
138             }
139             else
140                 return i;               //If element already selected; do nothing
141         }
142     }
143 
144     // Not Found
145     SetSelection( -1 );
146     return -1;
147 }
148 
149 
ResyncBitmapOnly()150 void LAYER_BOX_SELECTOR::ResyncBitmapOnly()
151 {
152     int elements = GetCount();
153 
154     for( LAYER_NUM i = 0; i < elements; ++i )
155     {
156         wxBitmap layerbmp( 14, 14 );
157         DrawColorSwatch( layerbmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( i ) );
158     }
159 }
160 
161 
onKeyDown(wxKeyEvent & aEvent)162 void LAYER_BOX_SELECTOR::onKeyDown( wxKeyEvent& aEvent )
163 {
164 #ifdef __WXOSX_MAC__
165     if( aEvent.GetKeyCode() == WXK_ESCAPE && IsPopupShown() )
166     {
167         Dismiss();
168         return;
169     }
170 #endif
171 
172     aEvent.Skip();
173 }
174