feat: add shift lock to KeyboardEntryActivity (#513)

## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)
Add shift lock to KeyboardEntryActivity


https://github.com/user-attachments/assets/00973866-6b87-4d5b-a3bf-6f4f85a5e0a6

(Apologies for the graininess of the video - I was struggling to get it
below 10mb)

* **What changes are included?**
  * Relax shift disable criteria to include any character
* Add third shift option `LOCK` which is not disabled on character
entry.


## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**NO**_
This commit is contained in:
James Whyte 2026-02-05 13:02:43 +00:00 committed by GitHub
parent d35bda8023
commit 20c5d8ccf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 9 deletions

View File

@ -14,6 +14,9 @@ const char* const KeyboardEntryActivity::keyboard[NUM_ROWS] = {
const char* const KeyboardEntryActivity::keyboardShift[NUM_ROWS] = {"~!@#$%^&*()_+", "QWERTYUIOP{}|", "ASDFGHJKL:\"",
"ZXCVBNM<>?", "SPECIAL ROW"};
// Shift state strings
const char* const KeyboardEntryActivity::shiftString[3] = {"shift", "SHIFT", "LOCK"};
void KeyboardEntryActivity::taskTrampoline(void* param) {
auto* self = static_cast<KeyboardEntryActivity*>(param);
self->displayTaskLoop();
@ -81,7 +84,7 @@ int KeyboardEntryActivity::getRowLength(const int row) const {
}
char KeyboardEntryActivity::getSelectedChar() const {
const char* const* layout = shiftActive ? keyboardShift : keyboard;
const char* const* layout = shiftState ? keyboardShift : keyboard;
if (selectedRow < 0 || selectedRow >= NUM_ROWS) return '\0';
if (selectedCol < 0 || selectedCol >= getRowLength(selectedRow)) return '\0';
@ -93,8 +96,8 @@ void KeyboardEntryActivity::handleKeyPress() {
// Handle special row (bottom row with shift, space, backspace, done)
if (selectedRow == SPECIAL_ROW) {
if (selectedCol >= SHIFT_COL && selectedCol < SPACE_COL) {
// Shift toggle
shiftActive = !shiftActive;
// Shift toggle (0 = lower case, 1 = upper case, 2 = shift lock)
shiftState = (shiftState + 1) % 3;
return;
}
@ -131,9 +134,9 @@ void KeyboardEntryActivity::handleKeyPress() {
if (maxLength == 0 || text.length() < maxLength) {
text += c;
// Auto-disable shift after typing a letter
if (shiftActive && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
shiftActive = false;
// Auto-disable shift after typing a character in non-lock mode
if (shiftState == 1) {
shiftState = 0;
}
}
}
@ -298,7 +301,7 @@ void KeyboardEntryActivity::render() const {
constexpr int keyHeight = 18;
constexpr int keySpacing = 3;
const char* const* layout = shiftActive ? keyboardShift : keyboard;
const char* const* layout = shiftState ? keyboardShift : keyboard;
// Calculate left margin to center the longest row (13 keys)
constexpr int maxRowWidth = KEYS_PER_ROW * (keyWidth + keySpacing);
@ -319,7 +322,7 @@ void KeyboardEntryActivity::render() const {
// SHIFT key (logical col 0, spans 2 key widths)
const bool shiftSelected = (selectedRow == 4 && selectedCol >= SHIFT_COL && selectedCol < SPACE_COL);
renderItemWithSelector(currentX + 2, rowY, shiftActive ? "SHIFT" : "shift", shiftSelected);
renderItemWithSelector(currentX + 2, rowY, shiftString[shiftState], shiftSelected);
currentX += 2 * (keyWidth + keySpacing);
// Space bar (logical cols 2-6, spans 5 key widths)

View File

@ -70,7 +70,7 @@ class KeyboardEntryActivity : public Activity {
// Keyboard state
int selectedRow = 0;
int selectedCol = 0;
bool shiftActive = false;
int shiftState = 0; // 0 = lower case, 1 = upper case, 2 = shift lock)
// Callbacks
OnCompleteCallback onComplete;
@ -81,6 +81,7 @@ class KeyboardEntryActivity : public Activity {
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];
// Special key positions (bottom row)
static constexpr int SPECIAL_ROW = 4;