libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiKeyboard.cpp
1/****************************************************************************
2 * libgui
3 *
4 * Daryl Borth 2009-2026
5 * GuiKeyboard.cpp
6 ***************************************************************************/
7
8#include "Gui.h"
9
10#define KB_FONTSIZE 20
11
12static char tmptxt[MAX_KEYBOARD_DISPLAY+1];
13
14static const char * GetDisplayText(const char * t)
15{
16 if(!t)
17 return nullptr;
18
19 strncpy(tmptxt, t, MAX_KEYBOARD_DISPLAY);
20 tmptxt[MAX_KEYBOARD_DISPLAY] = '\0';
21 return &tmptxt[0];
22}
23
24GuiKeyboard::GuiKeyboard(char * t, uint32_t max)
25{
26 width = 540;
27 height = 400;
28 shift = 0;
29 caps = 0;
30 selectable = true;
31 focus = 0; // allow focus
32 alignmentHor = ALIGN_H::CENTRE;
33 alignmentVert = ALIGN_V::MIDDLE;
34 snprintf(kbtextstr, 255, "%s", t);
35 kbtextmaxlen = max;
36
37 Key thekeys[KB_ROWS][KB_COLUMNS] = {
38 {
39 {'1','!'},
40 {'2','@'},
41 {'3','#'},
42 {'4','$'},
43 {'5','%'},
44 {'6','^'},
45 {'7','&'},
46 {'8','*'},
47 {'9','('},
48 {'0',')'},
49 {'\0','\0'}
50 },
51 {
52 {'q','Q'},
53 {'w','W'},
54 {'e','E'},
55 {'r','R'},
56 {'t','T'},
57 {'y','Y'},
58 {'u','U'},
59 {'i','I'},
60 {'o','O'},
61 {'p','P'},
62 {'-','_'}
63 },
64 {
65 {'a','A'},
66 {'s','S'},
67 {'d','D'},
68 {'f','F'},
69 {'g','G'},
70 {'h','H'},
71 {'j','J'},
72 {'k','K'},
73 {'l','L'},
74 {';',':'},
75 {'\'','"'}
76 },
77
78 {
79 {'z','Z'},
80 {'x','X'},
81 {'c','C'},
82 {'v','V'},
83 {'b','B'},
84 {'n','N'},
85 {'m','M'},
86 {',','<'},
87 {'.','>'},
88 {'/','?'},
89 {'\0','\0'}
90 }
91 };
92 memcpy(keys, thekeys, sizeof(thekeys));
93
94 keyTextbox = new GuiImageData(keyboard_textbox_png);
95 keyTextboxImg = new GuiImage(keyTextbox);
96 keyTextboxImg->setAlignment(ALIGN_H::CENTRE, ALIGN_V::TOP);
97 keyTextboxImg->setPosition(0, 0);
98 this->append(keyTextboxImg);
99
100 kbText = new GuiText(GetDisplayText(kbtextstr), KB_FONTSIZE, (PixelColor){0, 0, 0, 0xff});
101 kbText->setAlignment(ALIGN_H::CENTRE, ALIGN_V::TOP);
102 kbText->setPosition(0, 13);
103 this->append(kbText);
104
105 key = new GuiImageData(keyboard_key_png);
106 keyOver = new GuiImageData(keyboard_key_over_png);
107 keyMedium = new GuiImageData(keyboard_mediumkey_png);
108 keyMediumOver = new GuiImageData(keyboard_mediumkey_over_png);
109 keyLarge = new GuiImageData(keyboard_largekey_png);
110 keyLargeOver = new GuiImageData(keyboard_largekey_over_png);
111
112 keySoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND::PCM);
113 keySoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND::PCM);
114
115 trigA = new GuiTrigger;
116 trigA->setPrimaryTrigger();
117
118 keyBackImg = new GuiImage(keyMedium);
119 keyBackOverImg = new GuiImage(keyMediumOver);
120 keyBackText = new GuiText("Back", KB_FONTSIZE, (PixelColor){0, 0, 0, 0xff});
121 keyBack = new GuiButton(keyMedium->getWidth(), keyMedium->getHeight());
122 keyBack->setImage(keyBackImg);
123 keyBack->setImageOver(keyBackOverImg);
124 keyBack->setLabel(keyBackText);
125 keyBack->setSoundOver(keySoundOver);
126 keyBack->setSoundClick(keySoundClick);
127 keyBack->setTrigger(trigA);
128 keyBack->setPosition(10*42+40, 0*42+80);
129 keyBack->setEffectGrow();
130 this->append(keyBack);
131
132 keyCapsImg = new GuiImage(keyMedium);
133 keyCapsOverImg = new GuiImage(keyMediumOver);
134 keyCapsText = new GuiText("Caps", KB_FONTSIZE, (PixelColor){0, 0, 0, 0xff});
135 keyCaps = new GuiButton(keyMedium->getWidth(), keyMedium->getHeight());
136 keyCaps->setImage(keyCapsImg);
137 keyCaps->setImageOver(keyCapsOverImg);
138 keyCaps->setLabel(keyCapsText);
139 keyCaps->setSoundOver(keySoundOver);
140 keyCaps->setSoundClick(keySoundClick);
141 keyCaps->setTrigger(trigA);
142 keyCaps->setPosition(0, 2*42+80);
143 keyCaps->setEffectGrow();
144 this->append(keyCaps);
145
146 keyShiftImg = new GuiImage(keyMedium);
147 keyShiftOverImg = new GuiImage(keyMediumOver);
148 keyShiftText = new GuiText("Shift", KB_FONTSIZE, (PixelColor){0, 0, 0, 0xff});
149 keyShift = new GuiButton(keyMedium->getWidth(), keyMedium->getHeight());
150 keyShift->setImage(keyShiftImg);
151 keyShift->setImageOver(keyShiftOverImg);
152 keyShift->setLabel(keyShiftText);
153 keyShift->setSoundOver(keySoundOver);
154 keyShift->setSoundClick(keySoundClick);
155 keyShift->setTrigger(trigA);
156 keyShift->setPosition(21, 3*42+80);
157 keyShift->setEffectGrow();
158 this->append(keyShift);
159
160 keySpaceImg = new GuiImage(keyLarge);
161 keySpaceOverImg = new GuiImage(keyLargeOver);
162 keySpace = new GuiButton(keyLarge->getWidth(), keyLarge->getHeight());
163 keySpace->setImage(keySpaceImg);
164 keySpace->setImageOver(keySpaceOverImg);
165 keySpace->setSoundOver(keySoundOver);
166 keySpace->setSoundClick(keySoundClick);
167 keySpace->setTrigger(trigA);
168 keySpace->setPosition(0, 4*42+80);
169 keySpace->setAlignment(ALIGN_H::CENTRE, ALIGN_V::TOP);
170 keySpace->setEffectGrow();
171 this->append(keySpace);
172
173 char txt[2] = { 0, 0 };
174
175 for(int i=0; i<KB_ROWS; i++)
176 {
177 for(int j=0; j<KB_COLUMNS; j++)
178 {
179 if(keys[i][j].ch != '\0')
180 {
181 txt[0] = keys[i][j].ch;
182 keyImg[i][j] = new GuiImage(key);
183 keyImgOver[i][j] = new GuiImage(keyOver);
184 keyTxt[i][j] = new GuiText(txt, KB_FONTSIZE, (PixelColor){0, 0, 0, 0xff});
185 keyTxt[i][j]->setAlignment(ALIGN_H::CENTRE, ALIGN_V::BOTTOM);
186 keyTxt[i][j]->setPosition(0, -10);
187 keyBtn[i][j] = new GuiButton(key->getWidth(), key->getHeight());
188 keyBtn[i][j]->setImage(keyImg[i][j]);
189 keyBtn[i][j]->setImageOver(keyImgOver[i][j]);
190 keyBtn[i][j]->setSoundOver(keySoundOver);
191 keyBtn[i][j]->setSoundClick(keySoundClick);
192 keyBtn[i][j]->setTrigger(trigA);
193 keyBtn[i][j]->setLabel(keyTxt[i][j]);
194 keyBtn[i][j]->setPosition(j*42+21*i+40, i*42+80);
195 keyBtn[i][j]->setEffectGrow();
196 this->append(keyBtn[i][j]);
197 }
198 }
199 }
200}
201
202GuiKeyboard::~GuiKeyboard()
203{
204 delete kbText;
205 delete keyTextbox;
206 delete keyTextboxImg;
207 delete keyCapsText;
208 delete keyCapsImg;
209 delete keyCapsOverImg;
210 delete keyCaps;
211 delete keyShiftText;
212 delete keyShiftImg;
213 delete keyShiftOverImg;
214 delete keyShift;
215 delete keyBackText;
216 delete keyBackImg;
217 delete keyBackOverImg;
218 delete keyBack;
219 delete keySpaceImg;
220 delete keySpaceOverImg;
221 delete keySpace;
222 delete key;
223 delete keyOver;
224 delete keyMedium;
225 delete keyMediumOver;
226 delete keyLarge;
227 delete keyLargeOver;
228 delete keySoundOver;
229 delete keySoundClick;
230 delete trigA;
231
232 for(int i=0; i<KB_ROWS; i++)
233 {
234 for(int j=0; j<KB_COLUMNS; j++)
235 {
236 if(keys[i][j].ch != '\0')
237 {
238 delete keyImg[i][j];
239 delete keyImgOver[i][j];
240 delete keyTxt[i][j];
241 delete keyBtn[i][j];
242 }
243 }
244 }
245}
246
248{
249 if(_elements.size() == 0 || (state == STATE::DISABLED && parentElement))
250 return;
251
252 for (uint8_t i = 0; i < _elements.size(); i++)
253 {
254 _elements.at(i)->update(c);
255 }
256
257 bool update = false;
258
259 if(keySpace->getState() == STATE::CLICKED)
260 {
261 size_t len = strlen(kbtextstr);
262 if(len < kbtextmaxlen-1)
263 {
264 kbtextstr[len] = ' ';
265 kbtextstr[len+1] = '\0';
266 kbText->setText(kbtextstr);
267 }
268 keySpace->setState(STATE::SELECTED, c->getChannel());
269 }
270 else if(keyBack->getState() == STATE::CLICKED)
271 {
272 size_t len = strlen(kbtextstr);
273 if(len > 0)
274 {
275 kbtextstr[len-1] = '\0';
276 kbText->setText(GetDisplayText(kbtextstr));
277 }
278 keyBack->setState(STATE::SELECTED, c->getChannel());
279 }
280 else if(keyShift->getState() == STATE::CLICKED)
281 {
282 shift ^= 1;
283 keyShift->setState(STATE::SELECTED, c->getChannel());
284 update = true;
285 }
286 else if(keyCaps->getState() == STATE::CLICKED)
287 {
288 caps ^= 1;
289 keyCaps->setState(STATE::SELECTED, c->getChannel());
290 update = true;
291 }
292
293 char txt[2] = { 0, 0 };
294
295 startloop:
296
297 for(int i=0; i<KB_ROWS; i++)
298 {
299 for(int j=0; j<KB_COLUMNS; j++)
300 {
301 if(keys[i][j].ch != '\0')
302 {
303 if(update)
304 {
305 if(shift || caps)
306 txt[0] = keys[i][j].chShift;
307 else
308 txt[0] = keys[i][j].ch;
309
310 keyTxt[i][j]->setText(txt);
311 }
312
313 if(keyBtn[i][j]->getState() == STATE::CLICKED)
314 {
315 size_t len = strlen(kbtextstr);
316
317 if(len < kbtextmaxlen-1)
318 {
319 if(shift || caps)
320 {
321 kbtextstr[len] = keys[i][j].chShift;
322 }
323 else
324 {
325 kbtextstr[len] = keys[i][j].ch;
326 }
327 kbtextstr[len+1] = '\0';
328 }
329 kbText->setText(GetDisplayText(kbtextstr));
330 keyBtn[i][j]->setState(STATE::SELECTED, c->getChannel());
331
332 if(shift)
333 {
334 shift ^= 1;
335 update = true;
336 goto startloop;
337 }
338 }
339 }
340 }
341 }
342
343 this->toggleFocus(c);
344
345 if(focus) // only send actions to this window if it's in focus
346 {
347 // pad/joystick navigation
348 if(c->right())
349 this->moveSelectionHor(1);
350 else if(c->left())
351 this->moveSelectionHor(-1);
352 else if(c->down())
353 this->moveSelectionVert(1);
354 else if(c->up())
355 this->moveSelectionVert(-1);
356 }
357}
Umbrella header for the platform-agnostic libgui core.
Display, manage, and manipulate buttons in the GUI.
Definition GuiButton.h:13
bool selectable
Whether or not this element selectable (can change to SELECTED state)
Definition GuiElement.h:293
STATE getState()
Gets the element's current state.
void setTrigger(GuiTrigger *t)
Set a new GuiTrigger for the element.
int width
Element width.
Definition GuiElement.h:268
ALIGN_H alignmentHor
Horizontal element alignment, respective to parent element (LEFT, RIGHT, CENTRE)
Definition GuiElement.h:289
int height
Element height.
Definition GuiElement.h:269
GuiElement * parentElement
Parent element.
Definition GuiElement.h:265
ALIGN_V alignmentVert
Horizontal element alignment, respective to parent element (TOP, BOTTOM, MIDDLE)
Definition GuiElement.h:290
int focus
Element focus (-1 = focus disabled, 0 = not focused, 1 = focused)
Definition GuiElement.h:267
STATE state
Element state (DEFAULT, SELECTED, CLICKED, DISABLED)
Definition GuiElement.h:291
void setPosition(int x, int y)
Sets the element's position.
void setEffectGrow()
Shortcut to SetEffectOnOver(EFFECT::SCALE, 4, 110)
Decodes compressed image data (PNG) into a platform-native texture created from it.
Display, manage, and manipulate images in the GUI.
Definition GuiImage.h:18
GuiKeyboard(char *t, uint32_t m)
char kbtextstr[256]
Current entered text - read this after the keyboard closes.
Definition GuiKeyboard.h:30
void update(InputController *c)
Called constantly to allow the element to respond to the current input data.
Sound conversion and playback.
Definition GuiSound.h:27
Display, manage, and manipulate text in the GUI.
Definition GuiText.h:10
void setAlignment(ALIGN_H hor, ALIGN_V vert)
Sets the text alignment.
Definition GuiText.cpp:297
Input-condition matcher attached to a GuiElement (via setSimpleTrigger() etc.) and evaluated against ...
Definition GuiTrigger.h:34
void setPrimaryTrigger(int ch=-1)
Semantic Triggers.
void toggleFocus(InputController *c)
Changes window focus to the next focusable window or element If no element is in focus,...
void append(GuiElement *e)
Appends a GuiElement to the GuiWindow.
Definition GuiWindow.cpp:31
void moveSelectionVert(int d)
Moves the selected element to the element above or below.
std::vector< GuiElement * > _elements
Contains all elements within the GuiWindow.
Definition GuiWindow.h:93
void moveSelectionHor(int d)
Moves the selected element to the element to the left or right.
Logical controller for one input channel.
int getChannel() const
8-bit-per-channel RGBA color used by the video interfaces.
Definition Mesh.h:16