refactor: redesign on-screen keyboard with 10-col layout, symbol mode, long-press, visual improvements

This commit is contained in:
pablohc
2026-04-12 23:08:50 +02:00
committed by jpirnay
parent 4449b807a4
commit 53d621a91f
7 changed files with 380 additions and 249 deletions
+111 -31
View File
@@ -1,6 +1,7 @@
#pragma once
#include <GfxRenderer.h>
#include <cstdint>
#include <functional>
#include <string>
#include <utility>
@@ -8,21 +9,15 @@
#include "../Activity.h"
#include "util/ButtonNavigator.h"
/**
* Reusable keyboard entry activity for text input.
* Can be started from any activity that needs text entry via startActivityForResult()
*/
struct KeyDef {
char primary;
char secondary;
};
enum SpecialKeyType { SpecShift, SpecMode, SpecSpace, SpecDel, SpecOk };
class KeyboardEntryActivity : public Activity {
public:
/**
* Constructor
* @param renderer Reference to the GfxRenderer for drawing
* @param mappedInput Reference to MappedInputManager for handling input
* @param title Title to display above the keyboard
* @param initialText Initial text to show in the input field
* @param maxLength Maximum length of input text (0 for unlimited)
* @param isPassword If true, display asterisks instead of actual characters
*/
explicit KeyboardEntryActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
std::string title = "Enter Text", std::string initialText = "",
const size_t maxLength = 0, const bool isPassword = false)
@@ -32,7 +27,6 @@ class KeyboardEntryActivity : public Activity {
maxLength(maxLength),
isPassword(isPassword) {}
// Activity overrides
void onEnter() override;
void onExit() override;
void loop() override;
@@ -46,30 +40,116 @@ class KeyboardEntryActivity : public Activity {
ButtonNavigator buttonNavigator;
// Keyboard state
int selectedRow = 0;
int selectedCol = 0;
int shiftState = 0; // 0 = lower case, 1 = upper case, 2 = shift lock)
int shiftState = 0;
bool symMode = false;
bool confirmHeld = false;
bool confirmLongHandled = false;
// Handlers
void onComplete(std::string text);
void onCancel();
// Keyboard layout
static constexpr int NUM_ROWS = 5;
static constexpr int KEYS_PER_ROW = 13; // Max keys per row (rows 0 and 1 have 13 keys)
static const char* const keyboard[NUM_ROWS];
static const char* const keyboardShift[NUM_ROWS];
static const char* const shiftString[3];
static constexpr uint16_t LONG_PRESS_MS = 500;
// Special key positions (bottom row)
static constexpr int SPECIAL_ROW = 4;
static constexpr int SHIFT_COL = 0;
static constexpr int SPACE_COL = 2;
static constexpr int BACKSPACE_COL = 7;
static constexpr int DONE_COL = 9;
static constexpr int COLS = 10;
static constexpr int ABC_ROWS = 4;
static constexpr int SYM_ROWS = 4;
static constexpr int BOTTOM_KEY_COUNT = 5;
static constexpr KeyDef abcLayout[ABC_ROWS][COLS] = {
{{'0', ')'},
{'1', '!'},
{'2', '@'},
{'3', '#'},
{'4', '$'},
{'5', '%'},
{'6', '^'},
{'7', '&'},
{'8', '*'},
{'9', '('}},
{{'q', 'Q'},
{'w', 'W'},
{'e', 'E'},
{'r', 'R'},
{'t', 'T'},
{'y', 'Y'},
{'u', 'U'},
{'i', 'I'},
{'o', 'O'},
{'p', 'P'}},
{{'a', 'A'},
{'s', 'S'},
{'d', 'D'},
{'f', 'F'},
{'g', 'G'},
{'h', 'H'},
{'j', 'J'},
{'k', 'K'},
{'l', 'L'},
{'-', '_'}},
{{'z', 'Z'},
{'x', 'X'},
{'c', 'C'},
{'v', 'V'},
{'b', 'B'},
{'n', 'N'},
{'m', 'M'},
{'=', '+'},
{'.', '>'},
{',', '<'}},
};
static constexpr KeyDef symLayout[SYM_ROWS][COLS] = {
{{'0', '\0'},
{'1', '\0'},
{'2', '\0'},
{'3', '\0'},
{'4', '\0'},
{'5', '\0'},
{'6', '\0'},
{'7', '\0'},
{'8', '\0'},
{'9', '\0'}},
{{')', '\0'},
{'!', '\0'},
{'@', '\0'},
{'#', '\0'},
{'$', '\0'},
{'%', '\0'},
{'^', '\0'},
{'&', '\0'},
{'*', '\0'},
{'(', '\0'}},
{{'-', '\0'},
{'_', '\0'},
{'=', '\0'},
{'+', '\0'},
{'[', '\0'},
{']', '\0'},
{'{', '\0'},
{'}', '\0'},
{';', '\0'},
{':', '\0'}},
{{'\'', '\0'},
{'"', '\0'},
{'/', '\0'},
{'\\', '\0'},
{'|', '\0'},
{'?', '\0'},
{'.', '\0'},
{',', '\0'},
{'~', '\0'},
{'`', '\0'}},
};
static const char* const shiftString[2];
int getContentRowCount() const;
int getTotalRowCount() const;
bool isBottomRow(int row) const;
char getSelectedChar() const;
bool handleKeyPress(); // false if onComplete was triggered
int getRowLength(int row) const;
char getAlternativeChar() const;
bool handleKeyPress();
bool insertChar(char c);
};