-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathItemInputCharset.h
178 lines (170 loc) · 5.8 KB
/
ItemInputCharset.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#ifndef ItemInputCharset_H
#define ItemInputCharset_H
#include "ItemInput.h"
#include "LcdMenu.h"
#include <utils/utils.h>
class ItemInputCharset : public ItemInput {
private:
const char* charset;
// Active index of the charset
int8_t charsetPosition = -1;
bool charEdit = false;
public:
/**
* @brief Construct a new ItemInputCharset object with an initial value.
*
* @param text The text to renderer for the item.
* @param value The initial value for the input.
* @param charset The charset to use for input.
* @param callback A reference to the callback function to be invoked when
* the input is submitted.
*/
ItemInputCharset(const char* text, char* value, const char* charset, fptrStr callback)
: ItemInput(text, value, callback), charset(charset) {}
/**
* @brief Construct a new ItemInputCharset object with no initial value.
* @param text The text to renderer for the item.
* @param charset The charset to use for input.
* @param callback A reference to the callback function to be invoked when
* the input is submitted.
*/
ItemInputCharset(const char* text, const char* charset, fptrStr callback)
: ItemInputCharset(text, (char*)"", charset, callback) {}
protected:
bool process(LcdMenu* menu, const unsigned char command) override {
MenuRenderer* renderer = menu->getRenderer();
if (renderer->isInEditMode()) {
switch (command) {
case ENTER:
if (charEdit) {
commitCharEdit(renderer);
}
return true;
case BACK:
if (charEdit) {
abortCharEdit(renderer);
} else {
ItemInput::back(renderer);
}
return true;
case UP:
if (!charEdit) {
initCharEdit();
}
showPreviousChar(renderer);
LOG(F("ItemInputCharset::up"), charset[charsetPosition]);
return true;
case DOWN:
if (!charEdit) {
initCharEdit();
}
showNextChar(renderer);
LOG(F("ItemInputCharset::down"), charset[charsetPosition]);
return true;
case LEFT:
if (charEdit) {
abortCharEdit(renderer);
}
ItemInput::left(renderer);
return true;
case RIGHT:
if (charEdit) {
abortCharEdit(renderer);
}
ItemInput::right(renderer);
return true;
case BACKSPACE:
ItemInput::backspace(renderer);
return true;
case CLEAR:
ItemInput::clear(renderer);
return true;
default:
return false;
}
} else {
switch (command) {
case ENTER:
ItemInput::enter(renderer);
return true;
default:
return false;
}
}
}
/**
* @brief Initialize `char edit mode`.
* Set `charEdit` flag and search for currently selected char in charset.
*/
void initCharEdit() {
charEdit = true;
if (cursor < strlen(value)) {
char* e = strchr(charset, value[cursor]);
if (e != NULL) {
charsetPosition = (int)(e - charset);
return;
}
}
}
/**
* @brief Stop `char edit mode` and abort all mde changes.
* Unset `charEdit` flag and draw actual char from `value`.
*/
void abortCharEdit(MenuRenderer* renderer) {
charEdit = false;
uint8_t cursorCol = renderer->getCursorCol();
if (cursor < strlen(value)) {
renderer->draw(value[cursor]);
} else {
renderer->draw(' ');
}
renderer->moveCursor(cursorCol, renderer->getCursorRow());
LOG(F("ItemInputCharset::abortCharEdit"));
}
/**
* @brief Commit char edit mode.
* Replace char at cursor position with selected char from charset.
*/
void commitCharEdit(MenuRenderer* renderer) {
uint8_t length = strlen(value);
if (cursor < length) {
value[cursor] = charset[charsetPosition];
} else {
char* buf = new char[length + 2];
concat(value, charset[charsetPosition], buf);
value = buf;
}
abortCharEdit(renderer);
LOG(F("ItemInputCharset::commitCharEdit"), charset[charsetPosition]);
ItemInput::right(renderer);
}
/**
* @brief Show next char from charset.
*/
void showNextChar(MenuRenderer* renderer) {
if (charset[charsetPosition + 1] == '\0') {
charsetPosition = 0;
} else {
charsetPosition++;
}
drawChar(renderer);
}
/**
* @brief Show previous char from charset.
*/
void showPreviousChar(MenuRenderer* renderer) {
if (charsetPosition <= 0) {
charsetPosition = strlen(charset) - 1;
} else {
charsetPosition--;
}
drawChar(renderer);
}
void drawChar(MenuRenderer* renderer) {
renderer->moveCursor(renderer->getCursorCol(), renderer->getCursorRow());
renderer->draw(charset[charsetPosition]);
renderer->moveCursor(renderer->getCursorCol(), renderer->getCursorRow());
}
};
#define ITEM_INPUT_CHARSET(...) (new ItemInputCharset(__VA_ARGS__))
#endif