]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/gizmos/ledctrl.cpp
Updated version and other minor tweaks
[wxWidgets.git] / contrib / src / gizmos / ledctrl.cpp
CommitLineData
950e7faf
RD
1// ============================================================================
2// headers
3// ============================================================================
4
5#ifdef __GNUG__
6 #pragma implementation "wxLEDNumberCtrl.h"
7#endif
8
9#include "wx/wxprec.h"
10
11#ifdef __BORLANDC__
12 #pragma hdrstop
13#endif //__BORLANDC__
14
15#ifndef WX_PRECOMP
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/intl.h"
19#endif
20
21#include "wx/gizmos/ledctrl.h"
22
23// ----------------------------------------------------------------------------
24// constants
25// ----------------------------------------------------------------------------
26
27// A LED digit is build up like this, with maximum 7 Lines :
28//
29// 111
30// 6 2
31// 777
32// 5 3
33// 444
34//
35// Each number contains combinations of the lines, and they are set up below.
36
37const int LINE1 = 1;
38const int LINE2 = 2;
39const int LINE3 = 4;
40const int LINE4 = 8;
41const int LINE5 = 16;
42const int LINE6 = 32;
43const int LINE7 = 64;
44
45const int DIGIT0 = LINE1 | LINE2 | LINE3 | LINE4 | LINE5 | LINE6;
46const int DIGIT1 = LINE2 | LINE3;
47const int DIGIT2 = LINE1 | LINE2 | LINE4 | LINE5 | LINE7;
48const int DIGIT3 = LINE1 | LINE2 | LINE3 | LINE4 | LINE7;
49const int DIGIT4 = LINE2 | LINE3 | LINE6 | LINE7;
50const int DIGIT5 = LINE1 | LINE3 | LINE4 | LINE6 | LINE7;
51const int DIGIT6 = LINE1 | LINE3 | LINE4 | LINE5 | LINE6 | LINE7;
52const int DIGIT7 = LINE1 | LINE2 | LINE3;
53const int DIGIT8 = LINE1 | LINE2 | LINE3 | LINE4 | LINE5 | LINE6 | LINE7;
54const int DIGIT9 = LINE1 | LINE2 | LINE3 | LINE6 | LINE7;
55const int DASH = LINE7;
56
57const int DIGITALL = -1;
58
59// ============================================================================
60// wxLEDNumberCtrl class implementation
61// ============================================================================
62
63wxLEDNumberCtrl::wxLEDNumberCtrl()
64: m_Alignment(wxLED_ALIGN_LEFT),
65 m_LineMargin(-1),
66 m_DigitMargin(-1),
67 m_LineLength(-1),
68 m_LineWidth(-1),
69 m_DrawFaded(FALSE),
70 m_LeftStartPos(-1)
71{
72}
73
74
75wxLEDNumberCtrl::wxLEDNumberCtrl(wxWindow *parent, wxWindowID id,
76 const wxPoint& pos, const wxSize& size,
77 long style)
78: m_Alignment(wxLED_ALIGN_LEFT),
79 m_LineMargin(-1),
80 m_DigitMargin(-1),
81 m_LineLength(-1),
82 m_LineWidth(-1),
83 m_DrawFaded(FALSE),
84 m_LeftStartPos(-1)
85{
86 Create(parent, id, pos, size, style);
87}
88
89
90bool wxLEDNumberCtrl::Create(wxWindow *parent, wxWindowID id,
91 const wxPoint& pos, const wxSize& size,
92 long style)
93{
94 bool RetVal = wxControl::Create(parent, id, pos, size, style);
95
96 if ((style & wxLED_DRAW_FADED) != 0)
97 SetDrawFaded(TRUE);
98 if ((style & wxLED_ALIGN_MASK) != 0)
99 SetAlignment((wxLEDValueAlign)(style & wxLED_ALIGN_MASK));
100
101 SetBackgroundColour(*wxBLACK);
102 SetForegroundColour(*wxGREEN);
103
104 return RetVal;
105}
106
107
108void wxLEDNumberCtrl::SetAlignment(wxLEDValueAlign Alignment, bool Redraw)
109{
110 if (Alignment != m_Alignment)
111 {
112 m_Alignment = Alignment;
113 RecalcInternals(GetClientSize());
114
115 if (Redraw)
116 Refresh(FALSE);
117 }
118}
119
120
121void wxLEDNumberCtrl::SetDrawFaded(bool DrawFaded, bool Redraw)
122{
123 if (DrawFaded != m_DrawFaded)
124 {
125 m_DrawFaded = DrawFaded;
126
127 if (Redraw)
128 Refresh(FALSE);
129 }
130}
131
132
133void wxLEDNumberCtrl::SetValue(wxString const &Value, bool Redraw)
134{
135 if (Value != m_Value)
136 {
03342448 137#ifdef __WXDEBUG__
950e7faf
RD
138 if (!Value.IsEmpty())
139 {
140 for(size_t i=0; i<Value.Length(); i++) {
141 wxChar ch = Value[i];
142 wxASSERT_MSG((ch>='0' && ch<='9') || ch=='-' || ch==' ',
143 wxT("wxLEDNumberCtrl can only display numeric string values."));
144 }
145 }
03342448 146#endif
950e7faf
RD
147
148 m_Value = Value;
149 RecalcInternals(GetClientSize());
150
151 if (Redraw)
152 Refresh(FALSE);
153 }
154}
155
156
157BEGIN_EVENT_TABLE(wxLEDNumberCtrl, wxControl)
158 EVT_ERASE_BACKGROUND(wxLEDNumberCtrl::OnEraseBackground)
159 EVT_PAINT(wxLEDNumberCtrl::OnPaint)
160 EVT_SIZE(wxLEDNumberCtrl::OnSize)
161END_EVENT_TABLE()
162
163
164void wxLEDNumberCtrl::OnEraseBackground(wxEraseEvent &Event)
165{
166}
167
168
169void wxLEDNumberCtrl::OnPaint(wxPaintEvent &Event)
170{
171 wxPaintDC Dc(this);
172
173 int Width, Height;
174 GetClientSize(&Width, &Height);
175
176 wxBitmap *pMemoryBitmap = new wxBitmap(Width, Height);
177 wxMemoryDC MemDc;
178
179 MemDc.SelectObject(*pMemoryBitmap);
180 MemDc.BeginDrawing();
181
182 // Draw background.
183 MemDc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
184 MemDc.DrawRectangle(wxRect(0, 0, Width, Height));
185 MemDc.SetBrush(wxNullBrush);
186
187 // Iterate each digit in the value, and draw.
188 const int DigitCount = m_Value.Len();
189 for (int i = 0; i < DigitCount; ++i)
190 {
191 // Draw faded lines if wanted.
192 if (m_DrawFaded)
193 DrawDigit(MemDc, DIGITALL, i);
194
195 // Draw the digits.
03342448 196 switch (m_Value.GetChar(i))
950e7faf
RD
197 {
198 case '0' :
199 DrawDigit(MemDc, DIGIT0, i);
200 break;
201 case '1' :
202 DrawDigit(MemDc, DIGIT1, i);
203 break;
204 case '2' :
205 DrawDigit(MemDc, DIGIT2, i);
206 break;
207 case '3' :
208 DrawDigit(MemDc, DIGIT3, i);
209 break;
210 case '4' :
211 DrawDigit(MemDc, DIGIT4, i);
212 break;
213 case '5' :
214 DrawDigit(MemDc, DIGIT5, i);
215 break;
216 case '6' :
217 DrawDigit(MemDc, DIGIT6, i);
218 break;
219 case '7' :
220 DrawDigit(MemDc, DIGIT7, i);
221 break;
222 case '8' :
223 DrawDigit(MemDc, DIGIT8, i);
224 break;
225 case '9' :
226 DrawDigit(MemDc, DIGIT9, i);
227 break;
228 case '-' :
229 DrawDigit(MemDc, DASH, i);
230 break;
231 case ' ' :
232 // just skip it
233 break;
234 default :
501d97d4 235 wxFAIL_MSG(wxT("Unknown digit value"));
950e7faf
RD
236 break;
237 }
238 }
239
240 MemDc.EndDrawing();
241
242 // Blit the memory dc to screen.
243 Dc.Blit(0, 0, Width, Height, &MemDc, 0, 0, wxCOPY);
244 delete pMemoryBitmap;
245}
246
247
248void wxLEDNumberCtrl::DrawDigit(wxDC &Dc, int Digit, int Column)
249{
250 wxColour LineColor(GetForegroundColour());
251
252 if (Digit == DIGITALL)
253 {
254 const int R = LineColor.Red() / 3;
255 const int G = LineColor.Green() / 3;
256 const int B = LineColor.Blue() / 3;
257
258 LineColor.Set(R, G, B);
259 }
260
261 int XPos = m_LeftStartPos;
262
263 if (Column > 0)
264 XPos += (Column * m_LineLength) + (m_DigitMargin) * Column;
265
266 // Create a pen and draw the lines.
267 wxPen Pen(LineColor, m_LineWidth, wxSOLID);
268 Dc.SetPen(Pen);
269
270 if ((Digit & LINE1))
271 {
272 Dc.DrawLine(XPos + m_LineMargin*2, m_LineMargin,
273 XPos + m_LineLength, m_LineMargin);
274 }
275
276 if (Digit & LINE2)
277 {
278 Dc.DrawLine(XPos + m_LineLength + m_LineMargin, m_LineMargin*2,
279 XPos + m_LineLength + m_LineMargin, m_LineLength + (m_LineMargin*2));
280 }
281
282 if (Digit & LINE3)
283 {
284 Dc.DrawLine(XPos + m_LineLength + m_LineMargin, m_LineLength + (m_LineMargin*4),
285 XPos + m_LineLength + m_LineMargin, m_LineLength*2 + (m_LineMargin*3));
286 }
287
288 if (Digit & LINE4)
289 {
290 Dc.DrawLine(XPos + m_LineMargin*2, m_LineLength*2 + (m_LineMargin*4),
291 XPos + m_LineLength, m_LineLength*2 + (m_LineMargin*4));
292 }
293
294 if (Digit & LINE5)
295 {
296 Dc.DrawLine(XPos + m_LineMargin, m_LineLength + (m_LineMargin*4),
297 XPos + m_LineMargin, m_LineLength*2 + (m_LineMargin*3));
298 }
299
300 if (Digit & LINE6)
301 {
302 Dc.DrawLine(XPos + m_LineMargin, m_LineMargin*2,
303 XPos + m_LineMargin, m_LineLength + (m_LineMargin*2));
304 }
305
306 if (Digit & LINE7)
307 {
308 Dc.DrawLine(XPos + m_LineMargin*2, m_LineLength + (m_LineMargin*3),
309 XPos + m_LineMargin + m_LineLength - m_LineMargin, m_LineLength + (m_LineMargin*3));
310 }
311
312 Dc.SetPen(wxNullPen);
313}
314
315
316void wxLEDNumberCtrl::RecalcInternals(const wxSize &CurrentSize)
317{
318 const int Height = CurrentSize.GetHeight();
319
320 if ((Height * 0.07) < 1)
321 m_LineMargin = 1;
322 else
03342448 323 m_LineMargin = (int)(Height * 0.07);
950e7faf
RD
324
325 if ((Height * 0.35) < 1)
326 m_LineLength = 1;
327 else
03342448 328 m_LineLength = (int)(Height * 0.35);
950e7faf
RD
329
330 m_LineWidth = m_LineMargin;
331
332 m_DigitMargin = m_LineMargin * 4;
333
334 const int ValueWidth = (m_LineLength + m_DigitMargin) * m_Value.Len();
335 const int ClientWidth = CurrentSize.GetWidth();
336
337 switch (m_Alignment)
338 {
339 case wxLED_ALIGN_LEFT :
340 m_LeftStartPos = 0;
341 break;
342 case wxLED_ALIGN_RIGHT :
343 m_LeftStartPos = ClientWidth - ValueWidth;
344 break;
345 case wxLED_ALIGN_CENTER :
346 m_LeftStartPos = (ClientWidth - ValueWidth) / 2;
347 break;
348 default :
501d97d4 349 wxFAIL_MSG(wxT("Unknown alignent value for wxLEDNumberCtrl."));
950e7faf
RD
350 break;
351 }
352}
353
354
355void wxLEDNumberCtrl::OnSize(wxSizeEvent &Event)
356{
357 RecalcInternals(Event.GetSize());
358
359 Event.Skip();
360}