KiCad PCB EDA Suite
color_swatch.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3 
4  * Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <widgets/color_swatch.h>
25 
26 #include "dialog_color_picker.h"
27 #include <memory>
28 
29 wxDEFINE_EVENT(COLOR_SWATCH_CHANGED, wxCommandEvent);
30 
31 using KIGFX::COLOR4D;
32 
33 
34 const static wxSize PALETTE_SWATCH_SIZE_DU( 8, 6 );
35 const static wxSize DIALOG_SWATCH_SIZE_DU( 24, 10 );
36 
37 // See selcolor.cpp:
38 extern COLOR4D DisplayColorFrame( wxWindow* aParent, COLOR4D aOldColor );
39 
40 
46 wxBitmap COLOR_SWATCH::MakeBitmap( COLOR4D aColor, COLOR4D aBackground, wxSize aSize )
47 {
48  wxBitmap bitmap( aSize );
49  wxBrush brush;
50  wxMemoryDC iconDC;
51 
52  iconDC.SelectObject( bitmap );
53 
54  brush.SetStyle( wxBRUSHSTYLE_SOLID );
55  brush.SetColour( aBackground.WithAlpha(1.0).ToColour() );
56  iconDC.SetBrush( brush );
57  iconDC.DrawRectangle( 0, 0, aSize.x, aSize.y );
58 
59  brush.SetColour( aColor.ToColour() );
60  iconDC.SetBrush( brush );
61  iconDC.DrawRectangle( 0, 0, aSize.x, aSize.y );
62 
63  return bitmap;
64 }
65 
66 
67 COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, COLOR4D aColor, int aID, COLOR4D aBackground,
68  const COLOR4D aDefault, bool aForDialog ) :
69  wxPanel( aParent, aID ),
70  m_color( aColor ),
71  m_background( aBackground ),
72  m_default( aDefault )
73 {
74  if( aForDialog )
75  m_size = ConvertDialogToPixels( DIALOG_SWATCH_SIZE_DU );
76  else
77  m_size = ConvertDialogToPixels( PALETTE_SWATCH_SIZE_DU );
78 
79  auto sizer = new wxBoxSizer( wxHORIZONTAL );
80  SetSizer( sizer );
81 
82  wxBitmap bitmap = COLOR_SWATCH::MakeBitmap( aColor, aBackground, m_size );
83  m_swatch = new wxStaticBitmap( this, aID, bitmap );
84 
85  sizer->Add( m_swatch, 0, 0 );
86 
87  setupEvents();
88 }
89 
90 
91 COLOR_SWATCH::COLOR_SWATCH( wxWindow *aParent, wxWindowID aID, const wxPoint &aPos,
92  const wxSize &aSize, long aStyle ) :
93  wxPanel( aParent, aID, aPos, aSize, aStyle )
94 {
95  if( aSize == wxDefaultSize )
96  m_size = ConvertDialogToPixels( DIALOG_SWATCH_SIZE_DU );
97  else
98  m_size = aSize;
99 
100  SetSize( m_size );
101 
102  auto sizer = new wxBoxSizer( wxHORIZONTAL );
103  SetSizer( sizer );
104 
107  m_swatch = new wxStaticBitmap( this, aID, bitmap );
108 
109  sizer->Add( m_swatch, 0, 0 );
110 
111  setupEvents();
112 }
113 
114 
116 {
117  wxWindow* topLevelParent = GetParent();
118 
119  while( topLevelParent && !topLevelParent->IsTopLevel() )
120  topLevelParent = topLevelParent->GetParent();
121 
122  if( topLevelParent && dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
123  {
124  m_swatch->Bind( wxEVT_LEFT_DOWN,
125  [this] ( wxMouseEvent& aEvt )
126  {
128  } );
129  }
130  else
131  {
132  // forward click to any other listeners, since we don't want them
133  m_swatch->Bind( wxEVT_LEFT_DOWN, &COLOR_SWATCH::rePostEvent, this );
134 
135  // bind the events that trigger the dialog
136  m_swatch->Bind( wxEVT_LEFT_DCLICK,
137  [this] ( wxMouseEvent& aEvt )
138  {
140  } );
141  }
142 
143  m_swatch->Bind( wxEVT_MIDDLE_DOWN,
144  [this] ( wxMouseEvent& aEvt )
145  {
147  } );
148 
149  m_swatch->Bind( wxEVT_RIGHT_DOWN, &COLOR_SWATCH::rePostEvent, this );
150 }
151 
152 
153 void COLOR_SWATCH::rePostEvent( wxEvent& aEvt )
154 {
155  wxPostEvent( this, aEvt );
156 }
157 
158 
159 static void sendSwatchChangeEvent( COLOR_SWATCH& aSender )
160 {
161  wxCommandEvent changeEvt( COLOR_SWATCH_CHANGED );
162 
163  // use this class as the object (alternative might be to
164  // set a custom event class but that's more work)
165  changeEvt.SetEventObject( &aSender );
166 
167  wxPostEvent( &aSender, changeEvt );
168 }
169 
170 
171 void COLOR_SWATCH::SetSwatchColor( COLOR4D aColor, bool sendEvent )
172 {
173  m_color = aColor;
174 
175  wxBitmap bm = MakeBitmap( m_color, m_background, m_size );
176  m_swatch->SetBitmap( bm );
177 
178  if( sendEvent )
179  sendSwatchChangeEvent( *this );
180 }
181 
182 
184 {
185  m_background = aBackground;
186  wxBitmap bm = MakeBitmap( m_color, m_background, m_size );
187  m_swatch->SetBitmap( bm );
188 }
189 
190 
192 {
193  return m_color;
194 }
195 
196 
198 {
199  COLOR4D newColor = COLOR4D::UNSPECIFIED;
200 
201  DIALOG_COLOR_PICKER dialog( ::wxGetTopLevelParent( this ), m_color, true, nullptr, m_default );
202 
203  if( dialog.ShowModal() == wxID_OK )
204  newColor = dialog.GetColor();
205 
206  if( newColor != COLOR4D::UNSPECIFIED )
207  {
208  m_color = newColor;
209 
210  wxBitmap bm = MakeBitmap( newColor, m_background, m_size );
211  m_swatch->SetBitmap( bm );
212 
213  sendSwatchChangeEvent( *this );
214  }
215 }
COLOR4D DisplayColorFrame(wxWindow *aParent, COLOR4D aOldColor)
KIGFX::COLOR4D GetSwatchColor() const
void SetSwatchColor(KIGFX::COLOR4D aColor, bool sendEvent)
Set the current swatch color directly.
void setupEvents()
COLOR_SWATCH(wxWindow *aParent, KIGFX::COLOR4D aColor, int aID, KIGFX::COLOR4D aBackground, const KIGFX::COLOR4D aDefault, bool aForDialog)
Construct a COLOR_SWATCH.
static const wxSize PALETTE_SWATCH_SIZE_DU(8, 6)
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:248
void SetSwatchBackground(KIGFX::COLOR4D aBackground)
Set the swatch background color.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:308
KIGFX::COLOR4D m_default
The default color for the swatch
Definition: color_swatch.h:97
void rePostEvent(wxEvent &aEvt)
Pass unwanted events on to listeners of this object.
KIGFX::COLOR4D m_background
The background colour to show the swatch over
Definition: color_swatch.h:94
static wxBitmap MakeBitmap(KIGFX::COLOR4D aColor, KIGFX::COLOR4D aBackground, wxSize aSize)
Make a simple color swatch bitmap.
wxStaticBitmap * m_swatch
Handle of the actual swatch shown
Definition: color_swatch.h:100
wxDEFINE_EVENT(COLOR_SWATCH_CHANGED, wxCommandEvent)
static void sendSwatchChangeEvent(COLOR_SWATCH &aSender)
KIGFX::COLOR4D GetColor()
Class representing a simple color swatch, of the kind used to set layer colors.
Definition: color_swatch.h:38
void GetNewSwatchColor()
Prompt for a new colour, using the colour picker dialog.
KIGFX::COLOR4D m_color
The current colour of the swatch
Definition: color_swatch.h:91
static const wxSize DIALOG_SWATCH_SIZE_DU(24, 10)
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40