KiCad PCB EDA Suite
indicator_icon.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-2018 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/indicator_icon.h>
25 
26 
27 INDICATOR_ICON::INDICATOR_ICON( wxWindow* aParent, ICON_PROVIDER& aIconProvider,
28  ICON_ID aInitialIcon, int aID ):
29  wxPanel( aParent, aID ),
30  m_iconProvider( aIconProvider ),
31  m_currentId( aInitialIcon )
32 {
33  auto sizer = new wxBoxSizer( wxHORIZONTAL );
34  SetSizer( sizer );
35 
36  const wxBitmap& icon = m_iconProvider.GetIndicatorIcon( m_currentId );
37 
38  m_bitmap = new wxStaticBitmap( this, aID, icon, wxDefaultPosition, icon.GetSize() );
39 
40  sizer->Add( m_bitmap, 0, 0 );
41 
42  auto evtSkipper = [this] ( wxEvent& aEvent )
43  {
44  wxPostEvent( this, aEvent );
45  };
46 
47  m_bitmap->Bind( wxEVT_LEFT_DOWN, evtSkipper );
48 }
49 
50 
52 {
53  if( aIconId == m_currentId )
54  return;
55 
56  m_currentId = aIconId;
57 
58  const wxBitmap& icon = m_iconProvider.GetIndicatorIcon( m_currentId );
59  m_bitmap->SetBitmap( icon );
60  m_bitmap->SetSize( icon.GetSize() );
61 }
62 
63 
65 {
66  return m_currentId;
67 }
68 
69 
70 wxImage createBlankImage( int size )
71 {
72  wxImage image( size, size );
73 
74  image.InitAlpha();
75  for( int y = 0; y < size; ++y )
76  for( int x = 0; x < size; ++x )
77  image.SetAlpha( x, y, wxIMAGE_ALPHA_TRANSPARENT );
78 
79 #ifdef __WXMSW__
80  // wxWidgets on Windows chokes on an empty fully transparent bitmap and draws it
81  // as a black box
82  image.SetRGB( size / 2, size / 2, 128, 128, 128 );
83  image.SetAlpha( size / 2, size / 2, 10 );
84 #endif
85 
86  return image;
87 }
88 
89 
90 // Create an arrow icon of a particular size, colour and direction. 0 points up, 1 points
91 // right, and so forth.
92 wxBitmap createArrow( int size, int aDirection, wxColour aColour )
93 {
94  wxImage image = createBlankImage( size );
95 
96  int startX = size / 2 - 1;
97  int len = 1;
98 
99  int startY = aDirection % 2;
100 
101  for( int y = startY; y < startY + ( size / 2 ); ++y )
102  {
103  for( int x = startX; x < startX + len; ++x )
104  {
105  image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() );
106  image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE );
107  }
108 
109  // Next row will start one pixel back and be two pixels longer
110  startX -= 1;
111  len += 2;
112  }
113 
114  for( int i = 0; i < aDirection; ++i )
115  image = image.Rotate90();
116 
117  return wxBitmap( image );
118 }
119 
120 
121 // Create a diamond icon of a particular size and colour.
122 wxBitmap createDiamond( int size, wxColour aColour )
123 {
124  wxImage image = createBlankImage( size );
125 
126  int startX = size / 2 - 1;
127  int len = 1;
128 
129  int startY = 2;
130 
131  for( int y = startY; y < size && len > 0; ++y )
132  {
133  for( int x = startX; x < startX + len; ++x )
134  {
135  image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() );
136  image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE );
137  }
138 
139  // Next row will start one pixel back and be two pixels longer
140  if( y < ( size / 2) - 1 )
141  {
142  startX -= 1;
143  len += 2;
144  }
145  else
146  {
147  startX += 1;
148  len -= 2;
149  }
150  }
151 
152  return wxBitmap( image );
153 }
154 
155 
157 {
158  m_blankBitmap = wxBitmap( createBlankImage( aSize ) );
159  m_rightArrowBitmap = createArrow( aSize, 1, wxColour( 64, 72, 255 ) );
160  m_upArrowBitmap = createArrow( aSize - 2, 0, wxSystemSettings().GetColour( wxSYS_COLOUR_3DDKSHADOW ) );
161  m_downArrowBitmap = createArrow( aSize - 2, 2, wxSystemSettings().GetColour( wxSYS_COLOUR_3DDKSHADOW ) );
162  m_dotBitmap = createDiamond( aSize, wxColour( 128, 144, 255 ) );
163 }
164 
165 
167 {
168  switch( aId )
169  {
170  case STATE::UP: return m_upArrowBitmap;
171  case STATE::DOWN: return m_downArrowBitmap;
172  case STATE::ON: return m_rightArrowBitmap;
173  case STATE::DIMMED: return m_dotBitmap;
174  case STATE::OFF: return m_blankBitmap;
175  default: return m_blankBitmap;
176  }
177 }
wxBitmap createArrow(int size, int aDirection, wxColour aColour)
void SetIndicatorState(ICON_ID aIconId)
Sets the row indiciator to the given state.
virtual const wxBitmap & GetIndicatorIcon(ICON_ID aIconId) const =0
Gets a reference to the row icon in the given mode.
wxStaticBitmap * m_bitmap
Handle on the bitmap widget
int ICON_ID
An id that refers to a certain icon state.
#define ON
wxBitmap m_upArrowBitmap
wxBitmap m_downArrowBitmap
INDICATOR_ICON(wxWindow *aParent, ICON_PROVIDER &aIconProvider, ICON_ID aInitialIcon, int aID)
ICON_PROVIDER & m_iconProvider
An class that delivers icons for the indictor (currently just uses a default implementation).
const wxBitmap & GetIndicatorIcon(INDICATOR_ICON::ICON_ID aIconId) const override
A simple object that can provide fixed bitmaps for use as row indicators.
ROW_ICON_PROVIDER(int aSize)
ICON_ID GetIndicatorState() const
ICON_ID m_currentId
Is the icon currently "on"
wxBitmap createDiamond(int size, wxColour aColour)
wxImage createBlankImage(int size)
wxBitmap m_rightArrowBitmap