~damien-moore/+junk/codeblocks

« back to all changes in this revision

Viewing changes to src/plugins/contrib/wxContribItems/wxled/gizmosled/src/ledctrl.cpp

  • Committer: Damien Moore
  • Date: 2013-10-11 14:25:27 UTC
  • Revision ID: damienlmoore@gmail.com-20131011142527-w13ki0x8yjd7973d
copy of Code::Blocks repo based on SVN rev 9395

Show diffs side-by-side

added added

removed removed

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