UI_Lib  a1366e08a59cc549a65fa26081e6409aa12f26d5
This is a user interface library for graphical LCDs. It offers many different controls and indicators that can be nested depending on the element types.
Loading...
Searching...
No Matches
NumericControl.cpp
1/*
2 * NumericControl.cpp
3 */
4
6#include "Core/UI_Manager.h"
7#include "Core/UI_Icons.h"
8#include <math.h>
9
10template <class T>
11NumericControl<T>::NumericControl(T* valuePointer, const char* baseUnit, T minValue, T maxValue, int numFractionalDigits, void* controlContext, void(*onValueChanged)(void* controlContext), VirtualKeys* virtualKeys, uint16_t locX, uint16_t locY, uint8_t maxStringBufferLength) : NumericIndicator<T>(valuePointer, baseUnit, maxValue, numFractionalDigits, locX, locY, maxStringBufferLength)
12{
13 this->Type = UI_CONTROL;
14 _lastDrawnEditMode = false;
16 _minValue = minValue;
17 _controlContext = controlContext;
18 _onValueChanged = onValueChanged;
19 _virtualKeys = virtualKeys;
20}
21
22template <class T>
23void NumericControl<T>::Draw(bool redraw)
24{
25 if (this->Visible)
26 {
28 if(redraw)
29 {
30 this->_lastDrawnVisible = true;
33 UiManager.Gfx->fillRect(this->LocX, this->LocY, this->Width, this->Height, UiManager.ColorBackground);
34
35 if (this->IsInEditMode)
36 {
37 UiManager.Gfx->fillRect(this->LocX + UiManager.ElementMargin, this->LocY + UiManager.ElementMargin, this->Width - 2 * UiManager.ElementMargin, this->Height - 2 * UiManager.ElementMargin, UiManager.ColorForeground);
38 UiManager.Gfx->setTextColor(UiManager.ColorForegroundEditMode);
39 }
40 else
41 {
42 UiManager.Gfx->drawFastHLine(this->LocX + UiManager.ElementMargin + 1, this->LocY + this->Height - UiManager.ElementMargin - UiManager.ElementPadding, this->Width - 2 * UiManager.ElementMargin - 2, UiManager.ColorForeground);
43 }
44
46
47 if(this->IsInEditMode)
48 {
49 uint16_t character_width, character_space_width, dot_width, minus_width;
50 UiManager.Gfx->getTextBounds("0", 0, 0, nullptr, nullptr, &character_width, nullptr);
51 UiManager.Gfx->getTextBounds("00", 0, 0, nullptr, nullptr, &character_space_width, nullptr);
52 character_space_width -= 2* character_width; // subtract the with of both "0" characters to get only the space between the characters
53 UiManager.Gfx->getTextBounds(".", 0, 0, nullptr, nullptr, &dot_width, nullptr);
54 UiManager.Gfx->getTextBounds("-", 0, 0, nullptr, nullptr, &minus_width, nullptr);
55 dot_width += 2 * character_space_width; // some space between the dot and the characters
56
57 uint8_t cursorDigitIndex = (-CurrentDigitPosition + (this->_numDigits - this->_numFractionalDigits)) + (((this->_numFractionalDigits + this->_unitPrefixPower) == 0 && this->_numFractionalDigits != 0) ? 1 : 0) - 1; // if (this->_numFractionalDigits + this->_unitPrefixPower) == 0, no comma is available
58 uint16_t cursorXpos = this->LocX + minus_width + 2 + character_space_width + UiManager.ElementMargin + UiManager.ElementPadding + cursorDigitIndex * (character_width + character_space_width) + (CurrentDigitPosition < this->_unitPrefixPower ? dot_width : 0) - 1; // if (CurrentDigitPosition < _unitPrefixPower) cursor is right of comma
59
60 UiManager.Gfx->fillRect(cursorXpos, this->LocY + this->Height - UiManager.ElementMargin - UiManager.ElementPadding, character_width, 2, UiManager.ColorForegroundEditMode); // Draw cursor
61
62 // Reset text color back to default foreground
63 UiManager.Gfx->setTextColor(UiManager.ColorForeground);
64
65 if(_virtualKeys != NULL && !UiManager.AreVirtualKeysShown)
66 {
67 UiManager.Gfx->drawXBitmap(this->LocX + this->Width - 2 * UiManager.ElementMargin - UiManager.ElementPadding - icon_pencil_width, this->LocY + (this->Height / 2) - (icon_pencil_height / 2), icon_pencil_bits, icon_pencil_width, icon_pencil_height, UiManager.ColorForegroundEditMode);
68 }
69 }
70 }
71 }
72 else if(!this->Visible && this->_lastDrawnVisible) // clear only when the Visible property changes from true to false
73 {
74 this->_lastDrawnVisible = false;
75 UiManager.Gfx->fillRect(this->LocX, this->LocY, this->Width, this->Height, UiManager.ColorBackground);
76 }
77}
78
79template <class T>
81{
82 if (value > this->_maxValue) { value = this->_maxValue; }
83 else if (value < _minValue) { value = _minValue; }
84 return value;
85}
86
87template <class T>
88uint8_t NumericControl<T>::extractDigit(T number, int8_t position)
89{
90 float divisor = pow(10, position);
91 uint32_t truncated = uint32_t((abs(number) / divisor) + 0.1f); // +0.1f not really clean workaround. Is there some rounding problem?
92 return truncated % 10;
93}
94
95
96template <class T>
98{
99 switch (key)
100 {
101 case KEYLEFT:
102 return CursorLeft();
103 case KEYRIGHT:
104 return CursorRight();
105 case KEYUP:
106 return ValueUp();
107 case KEYDOWN:
108 return ValueDown();
109 case KEYOK:
111 return true;
112 case KEYKILO:
113 return KeyKilo();
114 case KEYMILLI:
115 return KeyMilli();
116 case KEYX1:
117 return KeyX1();
118 case KEYMINUS:
119 return KeyMinus();
120 case KEY0:
121 case KEY1:
122 case KEY2:
123 case KEY3:
124 case KEY4:
125 case KEY5:
126 case KEY6:
127 case KEY7:
128 case KEY8:
129 case KEY9:
130 return KeyNumeric(key);
131 default:
132 return false;
133 }
134}
135
136template <class T>
137bool NumericControl<T>::TouchInput(uint16_t x, uint16_t y, TouchTypes touchType)
138{
139 if(this->HitTest(x, y))
140 {
141 switch (touchType)
142 {
143 case TOUCH_NORMAL:
144 {
145 bool touchWasOnEditIcon = this->IsInEditMode && (_virtualKeys != NULL) && !UiManager.AreVirtualKeysShown && (x >= (this->LocX + (this->Width / 2)));
146 if(touchWasOnEditIcon)
147 {
148 _virtualKeys->ShowVirtualKeys(this);
149 }
150 return true;
151 }
152 case TOUCH_LONG:
153 {
155 return true;
156 }
157 default: break;
158 }
159 }
160 return false;
161}
162
163template <class T>
165{
166 if (this->IsInEditMode)
167 {
168 float multiplicator = pow(10, 3 - this->_unitPrefixPower);
169 (*this->_valuePointer) = coerceValue((*this->_valuePointer) * multiplicator);
170
171 if (_onValueChanged != NULL && multiplicator != 1) { _onValueChanged(_controlContext); }
172 return true;
173 }
174 return false;
175}
176
177template <class T>
179{
180 if (this->IsInEditMode)
181 {
182 float multiplicator = pow(10, -3 - this->_unitPrefixPower);
183 (*this->_valuePointer) = coerceValue((*this->_valuePointer) * multiplicator);
184
185 if (_onValueChanged != NULL && multiplicator != 1) { _onValueChanged(_controlContext); }
186 return true;
187 }
188 return false;
189}
190
191template <class T>
193{
194 if (this->IsInEditMode)
195 {
196 float multiplicator = pow(10, 0 - this->_unitPrefixPower);
197 (*this->_valuePointer) = coerceValue((*this->_valuePointer) * multiplicator);
198
199 if (_onValueChanged != NULL && multiplicator != 1) { _onValueChanged(_controlContext); }
200 return true;
201 }
202 return false;
203}
204
205template <class T>
207{
208 if (this->IsInEditMode)
209 {
210 (*this->_valuePointer) = coerceValue(-(*this->_valuePointer));
211
212 if (_onValueChanged != NULL && (*this->_valuePointer) != 0) { _onValueChanged(_controlContext); }
213 return true;
214 }
215 return false;
216}
217
218template <class T>
220{
221 if (this->IsInEditMode)
222 {
223 T oldValue = *this->_valuePointer;
224
225 uint8_t keyNum = Keys_GetKeyNumInt(key);
226 if(keyNum < 0 || keyNum > 9) { return false; } // if the keyNum isn't in the range 0..9, the given key is no numeric key
227
228 uint8_t digit = extractDigit(oldValue, CurrentDigitPosition);
229 float multiplicator = pow(10, CurrentDigitPosition) * (oldValue < 0 ? -1.0f : 1.0f);
230 (*this->_valuePointer) = coerceValue(oldValue - (digit * multiplicator) + (keyNum * multiplicator));
231 if (CurrentDigitPosition > -this->_numFractionalDigits) { CurrentDigitPosition--; } // Move cursor right
232
233 if (_onValueChanged != NULL && oldValue != (*this->_valuePointer)) { _onValueChanged(_controlContext); }
234 return true;
235 }
236 return false;
237}
238
239template <class T>
241{
242 if (this->IsInEditMode)
243 {
244 float deltaValue = pow(10, CurrentDigitPosition);
245 (*this->_valuePointer) = coerceValue((*this->_valuePointer) + deltaValue);
246
247 if (_onValueChanged != NULL && deltaValue != 0) { _onValueChanged(_controlContext); }
248 return true;
249 }
250 return false;
251}
252
253template <class T>
255{
256 if (this->IsInEditMode)
257 {
258 float deltaValue = pow(10, CurrentDigitPosition);
259 (*this->_valuePointer) = coerceValue((*this->_valuePointer) - deltaValue);
260
261 if (_onValueChanged != NULL && deltaValue != 0) { _onValueChanged(_controlContext); }
262 return true;
263 }
264 return false;
265}
266
267template <class T>
269{
270 if (this->IsInEditMode)
271 {
272 if (CurrentDigitPosition < (this->_numDigits - this->_numFractionalDigits - 1))
273 {
275 }
276 return true;
277 }
278 return false;
279}
280
281template <class T>
283{
284 if (this->IsInEditMode)
285 {
287 {
289 }
290 return true;
291 }
292 return false;
293}
294
295template <class T>
297{
298 UiManager.UpdateIsInEditModeElement(this, !this->IsInEditMode);
299}
300
301template <class T>
303{
305
306 if(_virtualKeys != NULL)
307 {
308 // If the NumericControl has a virtual keyboard assigned, reserve place for a region to show an edit icon
309 this->Width += icon_pencil_width;
310 }
311}
@ KEY6
Number 6 key.
Definition Keys.h:24
@ KEY2
Number 2 key.
Definition Keys.h:20
@ KEYOK
OK (Enter) key.
Definition Keys.h:36
@ KEY4
Number 4 key.
Definition Keys.h:22
@ KEY5
Number 5 key.
Definition Keys.h:23
@ KEYDOWN
Down arrow key.
Definition Keys.h:35
@ KEYMINUS
Minus (negate) key.
Definition Keys.h:31
@ KEY9
Number 9 key.
Definition Keys.h:27
@ KEY8
Number 8 key.
Definition Keys.h:26
@ KEYUP
Up arrow key.
Definition Keys.h:34
@ KEYLEFT
Left arrow key.
Definition Keys.h:32
@ KEY3
Number 3 key.
Definition Keys.h:21
@ KEY1
Number 1 key.
Definition Keys.h:19
@ KEYMILLI
Milli (/1000) key.
Definition Keys.h:29
@ KEY0
Number 0 key.
Definition Keys.h:18
@ KEYRIGHT
Right arrow key.
Definition Keys.h:33
@ KEY7
Number 7 key.
Definition Keys.h:25
@ KEYX1
x1 (*1) key
Definition Keys.h:30
@ KEYKILO
Kilo (*1000) key.
Definition Keys.h:28
enum Keys Keys_t
Available input keys.
uint8_t Keys_GetKeyNumInt(Keys_t key)
Get a number from the key for all numeric keys (KEY0 .
Definition Keys.cpp:7
Containing a class for a numeric control that is showing a numeric variable value and offers the poss...
TouchTypes
Available touch types.
Definition TouchTypes.h:13
@ TOUCH_LONG
Long touch.
Definition TouchTypes.h:15
@ TOUCH_NORMAL
Normal touch.
Definition TouchTypes.h:14
Containing icons for the UI_Lib.
#define icon_pencil_height
Height of the pencil icon.
Definition UI_Icons.h:24
#define icon_pencil_width
Width of the pencil icon.
Definition UI_Icons.h:23
Containing a class that is used to handle the drawing and key handling of all UI_Elements.
UI_Manager UiManager
Access object for the singleton instance of the UI_Manager.
Definition UI_Manager.cpp:7
@ UI_CONTROL
Control elements are used to show informations and offer the possibility to change some values.
Definition UIElementType.h:16
bool KeyMilli()
Milli key is used to change the prefix to milli.
Definition NumericControl.cpp:178
T _minValue
Minimum value that can be handled by this numeric control.
Definition NumericControl.h:20
bool CursorLeft()
Left key is used to move the cursor position left.
Definition NumericControl.cpp:268
VirtualKeys * _virtualKeys
Pointer to a VirtualKeys UIElement.
Definition NumericControl.h:44
bool ValueDown()
Down key is used to decrement the digit at the current cursor position.
Definition NumericControl.cpp:254
NumericControl(T *valuePointer, const char *baseUnit, T minValue, T maxValue, int numFractionalDigits, void *controlContext=NULL, void(*onValueChanged)(void *controlContext)=NULL, VirtualKeys *virtualKeys=NULL, uint16_t locX=0, uint16_t locY=0, uint8_t maxStringBufferLength=DEFAULT_NUMERIC_INDICATOR_STRING_LENGTH)
Constructor of the NumericControl.
Definition NumericControl.cpp:11
virtual bool KeyInput(Keys_t key) override
Definition NumericControl.cpp:97
bool ValueUp()
Up key is used to increment the digit at the current cursor position.
Definition NumericControl.cpp:240
virtual void Draw(bool redraw) override
Method used for drawing of the NumericControl.
Definition NumericControl.cpp:23
virtual void RecalculateDimensions() override
Recalculate the Height and Width of the UIElement.
Definition NumericControl.cpp:302
bool KeyNumeric(Keys_t key)
Numeric keys (KEY0 .
Definition NumericControl.cpp:219
bool _lastDrawnEditMode
The EditMode that was last drawn.
Definition NumericControl.h:22
bool KeyMinus()
Minus key is used to toggle the sign of the controlled value.
Definition NumericControl.cpp:206
int8_t _lastDrawnCurrentDigitPosition
The CurrentDigitPosition that was last drawn.
Definition NumericControl.h:23
uint8_t extractDigit(T number, int8_t position)
Extract the digit at the requested position from the number.
Definition NumericControl.cpp:88
void(* _onValueChanged)(void *controlContext)
Function pointer for _onValueChanged event.
Definition NumericControl.h:42
T coerceValue(T value)
Limit the value to be between _minValue and _maxValue.
Definition NumericControl.cpp:80
bool KeyKilo()
Kilo key is used to change the prefix to kilo.
Definition NumericControl.cpp:164
void ToggleEditMode()
Toggle the control between display and edit mode.
Definition NumericControl.cpp:296
void * _controlContext
Context pointer that is returned with the _onValueChanged function pointer.
Definition NumericControl.h:41
bool CursorRight()
Right key is used to move the cursor position right.
Definition NumericControl.cpp:282
bool KeyX1()
X1 key is used to change the prefix to none.
Definition NumericControl.cpp:192
virtual bool TouchInput(uint16_t x, uint16_t y, TouchTypes touchType) override
Process a touch input at the given point (x, y)
Definition NumericControl.cpp:137
int8_t CurrentDigitPosition
Position of the currently controlled digit.
Definition NumericControl.h:47
virtual void RecalculateDimensions() override
Recalculate the Height and Width of the UIElement.
Definition NumericIndicator.cpp:124
T _maxValue
Maximum value that can be shown by this numeric indicator.
Definition NumericIndicator.h:37
uint8_t _numFractionalDigits
Number of fractional digits that are shown by this indicator.
Definition NumericIndicator.h:38
uint8_t _numDigits
Number of digits calculated from the maxValue (_numFractionalDigits + numNonFractionalDigits).
Definition NumericIndicator.h:39
virtual void Draw(bool redraw) override
Method used for drawing of the NumericIndicator.
Definition NumericIndicator.cpp:81
NumericIndicator(T *valuePointer, const char *baseUnit, T maxValue, unsigned char numFractionalDigits, uint16_t locX=0, uint16_t locY=0, uint8_t maxStringBufferLength=DEFAULT_NUMERIC_INDICATOR_STRING_LENGTH)
Constructor of the NumericIndicator.
Definition NumericIndicator.cpp:69
T * _valuePointer
Pointer to the numeric variable that is shown by this indicator.
Definition NumericIndicator.h:35
int8_t _unitPrefixPower
Current display prefix power (m = -3, k = 3, M = 6)
Definition NumericIndicator.h:42
T _lastValueDraw
Last drawn numeric value.
Definition NumericIndicator.h:36
bool _lastDrawnVisible
The Visible value that was last drawn.
Definition UIElement.h:26
bool IsInEditMode
Is the UIElement in edit mode?
Definition UIElement.h:35
UIElementType Type
Element type (control, indicator, container)
Definition UIElement.h:29
bool HitTest(uint16_t x, uint16_t y)
Check if the given point (x, y) is inside this UIElement.
Definition UIElement.h:109
uint16_t Height
Drawing height of the UIElement.
Definition UIElement.h:33
uint16_t LocY
Y Location of the upper left corner of the UIElement.
Definition UIElement.h:31
bool Visible
The UIElement is only drawn if the visibility is set to true.
Definition UIElement.h:34
uint16_t Width
Drawing width of the UIElement.
Definition UIElement.h:32
uint16_t LocX
X Location of the upper left corner of the UIElement.
Definition UIElement.h:30
Class for a control that can be used to emulate key presses via touch inputs.
Definition VirtualKeys.h:18