1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4
5 #include "cspecialdigit.h"
6 #include "../cdrawcontext.h"
7 #include "../cbitmap.h"
8 #include <cmath>
9
10 namespace VSTGUI {
11
12 //------------------------------------------------------------------------
13 // CSpecialDigit
14 //------------------------------------------------------------------------
15 /*! @class CSpecialDigit
16 Can be used to display a counter with maximum 7 digits.
17 All digit have the same size and are stacked in height in the bitmap.
18 */
19 //------------------------------------------------------------------------
20 /**
21 * CSpecialDigit constructor.
22 * @param size the size of this view
23 * @param listener the listener
24 * @param tag the control tag
25 * @param dwPos actual value
26 * @param iNumbers amount of numbers (max 7)
27 * @param xpos array of all X positions, can be NULL
28 * @param ypos array of all Y positions, can be NULL
29 * @param width width of one number in the bitmap
30 * @param height height of one number in the bitmap
31 * @param background bitmap
32 */
33 //------------------------------------------------------------------------
CSpecialDigit(const CRect & size,IControlListener * listener,int32_t tag,int32_t dwPos,int32_t inNumbers,int32_t * xpos,int32_t * ypos,int32_t width,int32_t height,CBitmap * background)34 CSpecialDigit::CSpecialDigit (const CRect& size, IControlListener* listener, int32_t tag, int32_t dwPos, int32_t inNumbers, int32_t* xpos, int32_t* ypos, int32_t width, int32_t height, CBitmap* background)
35 : CControl (size, listener, tag, background)
36 , iNumbers (inNumbers)
37 , width (width)
38 , height (height)
39 {
40 setValue ((float)dwPos); // actual value
41
42 if (iNumbers > 7)
43 iNumbers = 7;
44
45 if (xpos == nullptr)
46 {
47 // automatically init xpos/ypos if not provided by caller
48 const int32_t numw = (const int32_t)background->getWidth();
49 int32_t x = (int32_t)size.left;
50 for (int32_t i = 0; i < inNumbers; i++)
51 {
52 this->xpos[i] = x;
53 this->ypos[i] = (int32_t)size.top;
54 x += numw;
55 }
56 }
57 else if (xpos && ypos)
58 {
59 // store coordinates of x/y pos of each digit
60 for (int32_t i = 0; i < inNumbers; i++)
61 {
62 this->xpos[i] = xpos[i];
63 this->ypos[i] = ypos[i];
64 }
65 }
66
67 setMax ((float)pow (10.f, (float)inNumbers) - 1.0f);
68 setMin (0.0f);
69 }
70
71 //------------------------------------------------------------------------
CSpecialDigit(const CSpecialDigit & v)72 CSpecialDigit::CSpecialDigit (const CSpecialDigit& v)
73 : CControl (v)
74 , iNumbers (v.iNumbers)
75 , width (v.width)
76 , height (v.height)
77 {
78 for (int32_t i = 0; i < 7; i++)
79 {
80 xpos[i] = v.xpos[i];
81 ypos[i] = v.ypos[i];
82 }
83 }
84
85 //------------------------------------------------------------------------
draw(CDrawContext * pContext)86 void CSpecialDigit::draw (CDrawContext *pContext)
87 {
88 CPoint where;
89 CRect rectDest;
90 int32_t i, j;
91 int32_t one_digit[16] = {};
92
93 int32_t dwValue = static_cast<int32_t> (getValue ());
94 int32_t intMax = static_cast<int32_t> (getMax ());
95 if (dwValue > intMax)
96 dwValue = intMax;
97 else if (dwValue < static_cast<int32_t> (getMin ()))
98 dwValue = static_cast<int32_t> (getMin ());
99
100 for (i = 0, j = (intMax + 1) / 10; i < iNumbers; i++, j /= 10)
101 {
102 one_digit[i] = dwValue / j;
103 dwValue -= (one_digit[i] * j);
104 }
105
106 where.x = 0;
107 for (i = 0; i < iNumbers; i++)
108 {
109 j = one_digit[i];
110 if (j > 9)
111 j = 9;
112
113 rectDest.left = (CCoord)xpos[i];
114 rectDest.top = (CCoord)ypos[i];
115
116 rectDest.right = rectDest.left + width;
117 rectDest.bottom = rectDest.top + height;
118
119 // where = src from bitmap
120 where.y = (CCoord)j * height;
121 if (getDrawBackground ())
122 {
123 getDrawBackground ()->draw (pContext, rectDest, where);
124 }
125 }
126
127 setDirty (false);
128 }
129
130 } // VSTGUI
131