KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <kiplatform/ui.h>
22#include <wx/event.h>
23#include <wx/settings.h>
24#include <wx/sizer.h>
25#include <wx/statbmp.h>
26
27INDICATOR_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 wxBoxSizer* 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.GetLogicalSize() );
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.GetLogicalSize() );
61}
62
63
64wxImage createBlankImage( int size )
65{
66 wxImage image( size, size );
67
68 image.InitAlpha();
69
70 for( int y = 0; y < size; ++y )
71 {
72 for( int x = 0; x < size; ++x )
73 image.SetAlpha( x, y, wxIMAGE_ALPHA_TRANSPARENT );
74 }
75
76#ifdef __WXMSW__
77 // wxWidgets on Windows chokes on an empty fully transparent bitmap and draws it
78 // as a black box
79 image.SetRGB( size / 2, size / 2, 128, 128, 128 );
80 image.SetAlpha( size / 2, size / 2, 10 );
81#endif
82
83 return image;
84}
85
86
87// Create an arrow icon of a particular size, colour and direction. 0 points up, 1 points
88// right, and so forth.
89wxBitmap createArrow( int size, double aScaleFactor, int aDirection, const wxColour& aColour )
90{
91 wxImage image = createBlankImage( size );
92
93 int startX = ( size - 1 ) / 2;
94 int len = 1;
95
96 int startY = aDirection % 2;
97
98 for( int y = startY; y < startY + ( size / 2 ); ++y )
99 {
100 for( int x = startX; x < startX + len; ++x )
101 {
102 image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() );
103 image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE );
104 }
105
106 // Next row will start one pixel back and be two pixels longer
107 startX -= 1;
108 len += 2;
109 }
110
111 for( int i = 0; i < aDirection; ++i )
112 image = image.Rotate90();
113
114 wxBitmap bmp( image );
115 bmp.SetScaleFactor( aScaleFactor );
116 return bmp;
117}
118
119
120// Create a turndown icon of a particular size, colour and direction. 0 points up,
121// 1 points right, and so forth.
122wxBitmap createTurndown( int size, double aScaleFactor, int aDirection, const wxColour& aColour )
123{
124 wxImage image = createBlankImage( size );
125
126 const unsigned char opacity = 0.70 * wxIMAGE_ALPHA_OPAQUE;
127 const int padding_start = 0 * aScaleFactor + 0.5;
128 const int padding_end = 2 * aScaleFactor + 0.5;
129
130 int startX = ( size - 1 ) / 2;
131 int len = 1;
132
133 int startY = padding_start;
134
135 for( int y = 0; y < size - padding_end; ++y )
136 {
137 for( int x = 0; x < len; ++x )
138 {
139 image.SetRGB( x + startX, y + startY, aColour.Red(), aColour.Green(), aColour.Blue() );
140 image.SetAlpha( x + startX, y + startY, ( y % 2 ) || ( ( x > 0 ) && ( x < len - 1 ) ) ? opacity : opacity / 2);
141 }
142
143 // Next row will start one pixel back and be two pixels longer
144 if( y % 2 )
145 {
146 startX -= 1;
147 len += 2;
148 }
149 }
150
151 for( int i = 0; i < aDirection; ++i )
152 image = image.Rotate90();
153
154 wxBitmap bmp( image );
155 bmp.SetScaleFactor( aScaleFactor );
156 return bmp;
157}
158
159
160// Create a diamond icon of a particular size and colour.
161wxBitmap createDiamond( int size, double aScaleFactor, wxColour aColour )
162{
163 wxImage image = createBlankImage( size );
164
165 int startX = size / 2 - 1;
166 int len = 1;
167
168 int startY = 2;
169
170 for( int y = startY; y < size && len > 0; ++y )
171 {
172 for( int x = startX; x < startX + len; ++x )
173 {
174 image.SetRGB( x, y, aColour.Red(), aColour.Green(), aColour.Blue() );
175 image.SetAlpha( x, y, wxIMAGE_ALPHA_OPAQUE );
176 }
177
178 // Next row will start one pixel back and be two pixels longer
179 if( y < ( size / 2) - 1 )
180 {
181 startX -= 1;
182 len += 2;
183 }
184 else
185 {
186 startX += 1;
187 len -= 2;
188 }
189 }
190
191 wxBitmap bmp( image );
192 bmp.SetScaleFactor( aScaleFactor );
193 return bmp;
194}
195
196
197ROW_ICON_PROVIDER::ROW_ICON_PROVIDER( int aSizeDIP, wxWindow* aWindow )
198{
199 auto toPhys =
200 [&]( int dip )
201 {
202 return aWindow->ToPhys( aWindow->FromDIP( dip ) );
203 };
204
205 double scale = aWindow->GetDPIScaleFactor();
206 wxColour shadowColor = wxSystemSettings::GetColour( wxSYS_COLOUR_3DDKSHADOW );
207 wxColour textColor = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXTEXT );
208
209 m_blankBitmap = wxBitmap( createBlankImage( toPhys( aSizeDIP ) ) );
210 m_blankBitmap.SetScaleFactor( scale );
211
212 m_rightArrowBitmap = createArrow( toPhys( aSizeDIP ), scale, 1, wxColour( 64, 72, 255 ) );
213 m_upArrowBitmap = createArrow( toPhys( aSizeDIP - 2 ), scale, 0, shadowColor );
214 m_downArrowBitmap = createArrow( toPhys( aSizeDIP - 2 ), scale, 2, shadowColor );
215 m_dotBitmap = createDiamond( toPhys( aSizeDIP ), scale, wxColour( 128, 144, 255 ) );
216 m_closedBitmap = createTurndown( toPhys( aSizeDIP ), scale, 1, textColor );
217 m_openBitmap = createTurndown( toPhys( aSizeDIP ), scale, 2, textColor );
218}
219
220
222{
223 switch( aId )
224 {
225 case STATE::UP: return m_upArrowBitmap;
226 case STATE::DOWN: return m_downArrowBitmap;
227 case STATE::ON: return m_rightArrowBitmap;
228 case STATE::DIMMED: return m_dotBitmap;
229 case STATE::OFF: return m_blankBitmap;
230 case STATE::OPEN: return m_openBitmap;
231 case STATE::CLOSED: return m_closedBitmap;
232 default: return m_blankBitmap;
233 }
234}
A simple object that can provide fixed bitmaps for use as row indicators.
ICON_PROVIDER & m_iconProvider
int ICON_ID
An id that refers to a certain icon state.
INDICATOR_ICON(wxWindow *aParent, ICON_PROVIDER &aIconProvider, ICON_ID aInitialIcon, int aID)
void SetIndicatorState(ICON_ID aIconId)
Set the row indicator to the given state.
ICON_ID m_currentId
Handle on the bitmap widget.
wxStaticBitmap * m_bitmap
Object that delivers icons for the indicator.
const wxBitmap & GetIndicatorIcon(INDICATOR_ICON::ICON_ID aIconId) const override
Get a reference to the row icon in the given mode.
wxBitmap m_rightArrowBitmap
@ UP
Row above design alpha.
@ OPEN
Tree control open.
@ CLOSED
Tree control closed.
@ DIMMED
Row "dimmed".
@ DOWN
Row below design alpha.
@ OFF
Row "off" or "deselected".
@ ON
Row "on" or "selected".
ROW_ICON_PROVIDER(int aSizeDIP, wxWindow *aWindow)
wxBitmap createTurndown(int size, double aScaleFactor, int aDirection, const wxColour &aColour)
wxBitmap createArrow(int size, double aScaleFactor, int aDirection, const wxColour &aColour)
wxBitmap createDiamond(int size, double aScaleFactor, wxColour aColour)
wxImage createBlankImage(int size)
const int scale