1#include "EKeyboard.hpp"
7EKeyboard::EKeyboard() : EKeyboard::EKeyboard(NULL)
12EKeyboard::EKeyboard(std::function<
void(
char)> typeAction)
15 this->y = SCREEN_HEIGHT - 420;
17 this->width = SCREEN_WIDTH - 380;
19 this->typeAction = typeAction;
22 this->isAbsolute =
true;
30 if (hidden || immersiveMode)
33 CST_Rect dimens = { this->x, this->y, this->width + 305, this->height + 140 };
35 auto renderer = getRenderer();
37 CST_SetDrawColor(renderer, { 0xf9, 0xf9, 0xf9, 0xFF });
39 CST_SetDrawColor(renderer, { 0xdd, 0xdd, 0xdd, 0xFF });
44 dimens.w = RootDisplay::screenWidth;
47 CST_FillRect(renderer, &dimens);
49 for (
int y = 0; y < rowCount(); y++)
50 for (
int x = 0; x < rowLength(y) + 1; x++)
52 CST_Rect dimens2 = { this->x + kXPad + x * kXOff + y * yYOff, this->y + kYPad + y * ySpacing, keyWidth, keyWidth };
53 if (this->hasRoundedKeys) {
54 CST_roundedBoxRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0xee, 0xee, 0xee, 0xff);
56 CST_SetDrawColor(renderer, { 0xf4, 0xf4, 0xf4, 0xff });
57 CST_FillRect(renderer, &dimens2);
62 char curChar = rows[y]->at(x*2);
63 auto curCharStr = std::string(1, curChar);
64 int fHeight = CST_GetFontHeight(roundKeyFont, curCharStr.c_str());
65 int fWidth = CST_GetFontWidth(roundKeyFont, curCharStr.c_str());
69 dimens2.x + dimens2.w/2 - fWidth/2,
70 dimens2.y + dimens2.h/2 - fHeight/2,
76 CST_Rect dimensSpace = { this->x + sPos, this->y + dHeight, sWidth, textSize };
77 CST_Rect dimensEnter = { this->x + enterPos, this->y + enterHeight, enterWidth, (int)(1.5 * textSize) };
78 CST_Rect dimensTab = { this->x + dPos, this->y + enterHeight, enterWidth, (int)(1.5 * textSize) };
81 if (curRow >= 0 || index >= 0)
83 CST_Rect dimens2 = { this->x + kXPad + index * kXOff + curRow * yYOff, this->y + kYPad + curRow * ySpacing, keyWidth, keyWidth };
85 if (curRow >= rowCount())
94 dimens2 = dimensSpace;
98 dimens2 = dimensEnter;
106 if (hasRoundedKeys) {
107 CST_roundedBoxRGBA(renderer, dimensSpace.x, dimensSpace.y, dimensSpace.x + dimensSpace.w, dimensSpace.y + dimensSpace.h, 20, 0xee, 0xee, 0xee, 0xff);
108 CST_roundedBoxRGBA(renderer, dimensEnter.x, dimensEnter.y, dimensEnter.x + dimensEnter.w, dimensEnter.y + dimensEnter.h, 20, 0xee, 0xee, 0xee, 0xff);
109 CST_roundedBoxRGBA(renderer, dimensTab.x, dimensTab.y, dimensTab.x + dimensTab.w, dimensTab.y + dimensTab.h, 20, 0xee, 0xee, 0xee, 0xff);
111 CST_SetDrawColor(renderer, { 0xf4, 0xf4, 0xf4, 0xff });
112 CST_FillRect(renderer, &dimensSpace);
114 if (!preventEnterAndTab) {
115 CST_FillRect(renderer, &dimensEnter);
116 CST_FillRect(renderer, &dimensTab);
121 if (touchMode && !isTouchDrag)
123 if (hasRoundedKeys) {
124 CST_roundedBoxRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0xad, 0xd8, 0xe6, 0x90);
125 CST_roundedRectangleRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0x66, 0x7c, 0x89, 0xff);
127 CST_SetDrawColor(renderer, { 0xad, 0xd8, 0xe6, 0x90 });
128 CST_FillRect(renderer, &dimens2);
131 else if (hasRoundedKeys) {
132 CST_roundedBoxRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0xad, 0xd8, 0xe6, 0x90);
133 CST_roundedRectangleRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0x66, 0x7c, 0x89, 0xff);
136 CST_SetDrawColor(renderer, { 0xff, 0xff, 0xff, 0xff });
137 CST_FillRect(renderer, &dimens2);
141 for (
int x=-2; x<3; x++) {
142 CST_rectangleRGBA(renderer, d.x + x, d.y + x, d.x + d.w - x, d.y + d.h - x, 0x10, 0xD9, 0xD9, 0xff);
152 InputEvents::bypassKeyEvents =
false;
159 InputEvents::bypassKeyEvents =
true;
161 if (event->type == SDL_KEYDOWN)
162 return listenForPhysicalKeys(event);
163 if (event->type == SDL_KEYUP && (event->keyCode == SDLK_LSHIFT ||
164 event->keyCode == SDLK_RSHIFT ||
165 event->keyCode == SDLK_CAPSLOCK)) {
172 if (immersiveMode)
return false;
174 if (event->isTouchDown())
181 if (event->isKeyDown()) {
189 auto prevTouchDrag = isTouchDrag;
190 isTouchDrag = (
event->isTouchDrag() && (!touchMode || (curRow < 0 && index < 0))) || isTouchDrag;
191 if (prevTouchDrag != isTouchDrag && isTouchDrag) {
193 CST_LowRumble(event, 200);
197 if (!touchMode && !isTouchDrag)
199 if (curRow < 0 && index < 0)
207 if (event->isKeyDown())
209 int lastRow = curRow;
210 curRow += (
event->held(DOWN_BUTTON) -
event->held(UP_BUTTON));
211 index += (
event->held(RIGHT_BUTTON) -
event->held(LEFT_BUTTON));
213 if (curRow < 0) curRow = 0;
214 if (index < 0) index = 0;
215 if (curRow >= rowCount() + 1) curRow = rowCount();
216 if (curRow == rowCount())
219 if (lastRow < curRow && index > 0 && index < rowLength(lastRow))
225 if (index < 0) index = 0;
228 if (index > 2) index = 2;
232 if (index > rowLength(curRow))
233 index = rowLength(curRow);
235 if (lastRow == rowCount()) {
243 index = rowLength(curRow) / 2;
247 index = rowLength(curRow);
255 if (event->
held(A_BUTTON))
258 if (curRow >= rowCount())
287 int extWidth = width + 305;
289 if ((event->isTouchDown() || event->isTouchDrag()) && event->
touchIn(this->x, this->y, extWidth, height + 200))
291 for (
int y = 0; y < rowCount(); y++)
292 for (
int x = 0; x < rowLength(y) + 1; x++) {
293 auto xStart = this->x + kXPad + x * kXOff + y * yYOff;
294 auto yStart = this->y + kYPad + y * ySpacing;
295 if (event->
touchIn(xStart, yStart, keyWidth, keyWidth))
305 if (event->isTouchUp())
312 if (event->
touchIn(this->x, this->y, extWidth, height + 200))
315 for (
int y = 0; y < rowCount(); y++)
316 for (
int x = 0; x < rowLength(y) + 1; x++)
317 if (event->
touchIn(this->x + kXPad + x * kXOff + y * yYOff, this->y + kYPad + y * ySpacing, keyWidth, keyWidth))
323 if (event->
touchIn(this->x + dPos, this->y + enterHeight, enterWidth, textSize))
329 if (event->
touchIn(this->x + sPos, this->y + dHeight, sWidth, textSize))
335 if (event->
touchIn(this->x + enterPos, this->y + enterHeight, enterWidth, textSize))
353bool EKeyboard::listenForPhysicalKeys(
InputEvents* e)
358 auto keyCode = e->keyCode;
362 if (keyCode == SDLK_LSHIFT || keyCode == SDLK_RSHIFT || keyCode == SDLK_CAPSLOCK) {
368 if (keyCode == SDLK_TAB) {
372 if (keyCode == SDLK_SPACE) {
376 if (keyCode == SDLK_RETURN && !preventEnterAndTab) {
382 if (keyCode == SDLK_LALT || keyCode == SDLK_RALT) {
383 immersiveMode = !immersiveMode;
388 auto roundedOffset = hasRoundedKeys ? 1 : 0;
389 for (
int x=roundedOffset; x<KEYCODE_COUNT; x++)
392 int topRowOffset = curBreak == 0 ? roundedOffset : 0;
394 if (keyCode == usbKeys[x])
398 type(curBreak, xx - topRowOffset);
400 index = xx - topRowOffset;
404 if (xx + 1 >= breaks[curBreak]) {
414 if (keyCode == SDLK_BACKSPACE) {
420 if (keyCode == SDLK_RETURN && preventEnterAndTab) {
424 sdlevent.type = SDL_JOYBUTTONDOWN;
425 sdlevent.jbutton.button = SDL_X;
426 SDL_PushEvent(&sdlevent);
430 if (keyCode == SDLK_ESCAPE) {
433 sdlevent.type = SDL_JOYBUTTONDOWN;
434 sdlevent.jbutton.button = SDL_Y;
435 SDL_PushEvent(&sdlevent);
442void EKeyboard::updateSize()
444 this->elements.clear();
447 this->height = (304 / 900.0) * width;
451 this->keyWidth = (int)(0.08 * width);
452 this->padding = keyWidth / 2.0;
455 kXPad = (int)((23 / 400.0) * width);
456 kXOff = (int)((36.5 / 400.0) * width) + (900.0 / width) * ( 900.0 != width);
457 yYOff = (int)((22 / 400.0) * width);
458 kYPad = (int)((17 / 135.0) * height);
459 ySpacing = (int)((33 / 400.0) * width);
461 if (hasRoundedKeys) {
464 kXOff = (int)((38 / 400.0) * width) + (900.0 / width) * ( 900.0 != width);
465 yYOff = (int)((10 / 400.0) * width);
466 kYPad = (int)((0 / 135.0) * height);
467 ySpacing = (int)((37 / 400.0) * width);
473 int kXPad = (int)((30 / 400.0) * width);
474 int kXOff = (int)((22 / 400.0) * width);
478 int kYPad = (int)((14 / 400.0) * width);
480 int kYOff = (int)((33 / 400.0) * width);
482 this->textSize = 0.9375 * keyWidth;
485 dPos = (int)((13 / 400.0) * width);
486 dHeight = (int)((85 / 135.0) * height) + 145;
487 sPos = (int)((150 / 400.0) * width);
488 enterPos = dPos + 1000;
489 enterHeight = dHeight - 34;
491 dWidth = (int)(1.4125 * textSize);
492 sWidth = (int)(7.5 * textSize);
493 enterWidth = (int)(2.25 * textSize);
498 CST_Color gray = { 0x52, 0x52, 0x52, 0xff };
500 int targetHeight = -1;
503 if (!hasRoundedKeys) {
504 for (
int x = 0; x < rowCount(); x++)
506 TextElement* rowText =
new TextElement(rows[x]->c_str(), textSize, &gray, ICON);
508 if (targetHeight < 0) {
509 targetHeight = rowText->height;
511 rowText->update(
true);
512 rowText->position(kXPad + x * kXOff, kYPad + x * kYOff + targetHeight/2 - rowText->height/2);
513 this->addNode(std::unique_ptr<TextElement>(rowText));
516 CST_Color grayish = { 0x55, 0x55, 0x55, 0xff };
517 TextElement* spaceText =
new TextElement(
"space", 30, &grayish);
518 CST_Rect d4 = { this->x + sPos, this->y + dHeight, sWidth, textSize };
519 spaceText->position(d4.x + d4.w / 2 - spaceText->width / 2 - 15, 345);
520 this->addNode(std::unique_ptr<TextElement>(spaceText));
522 if (!preventEnterAndTab)
524 TextElement* enterText =
new TextElement(
"enter", 30, &grayish);
525 CST_Rect d3 = { this->x + enterPos, this->y + enterHeight, enterWidth, textSize };
526 enterText->position(d3.x + d3.w / 2 - enterText->width / 2 - 30, 327);
527 this->addNode(std::unique_ptr<TextElement>(enterText));
529 TextElement* symText =
new TextElement(hasRoundedKeys ?
"shift" :
"tab", 30, &grayish);
530 CST_Rect d5 = { this->x + dPos, this->y + enterHeight, enterWidth, textSize };
531 symText->position(d5.x + d5.w / 2 - symText->width / 2 - 30, 327);
532 this->addNode(std::unique_ptr<TextElement>(symText));
537void EKeyboard::type(
int y,
int x)
539 const char input = (*(rows[y]))[x * 2];
544void EKeyboard::just_type(
const char input)
546 if (preventEnterAndTab && (input ==
'\n' || input ==
'\t'))
551 textInput.push_back(input);
554 if (typeAction != NULL) {
560void EKeyboard::generateEKeyboard()
566 keys = string((shiftOn || capsOn) ? upper_keys : lower_keys);
572 int offset = 47 * (mode - 1) + 0x00a1;
573 char chars[47 + (mode == 2)];
574 for (
int x = 0; x < 47 + (mode == 2); x++)
576 chars[x] = offset + x;
579 keys = string(chars);
582 breaks[3] += (mode == 2);
584 for (
int& end : breaks)
586 auto roundedOffset = (hasRoundedKeys && count == 0) ? 1 : 0;
587 string* row =
new string(keys.substr(count + roundedOffset, end - roundedOffset));
588 for (
int x = 1; x < (int)row->size(); x += 2)
590 row->insert(row->begin() + x,
' ');
597 if (hasRoundedKeys && roundKeyFont == NULL) {
599 roundKeyFont = CST_CreateFont();
600 auto fontPath = RAMFS
"res/lightsans.ttf";
601 auto renderer = getRenderer();
602 CST_LoadFont(roundKeyFont, renderer, fontPath, 40, CST_MakeColor(0,0,0,255), TTF_STYLE_NORMAL);
606void EKeyboard::backspace()
610 if (!textInput.empty())
611 textInput.pop_back();
620 sdlevent.type = SDL_JOYBUTTONDOWN;
621 sdlevent.jbutton.button = SDL_B;
622 SDL_PushEvent(&sdlevent);
625const std::string& EKeyboard::getTextInput()
630EKeyboard::~EKeyboard()
632 InputEvents::bypassKeyEvents =
false;