Support swapping the functionality of the front buttons (#133)

## Summary

**What is the goal of this PR?** 

Adds a setting to swap the front buttons. The default functionality are:
Back/Confirm/Left/Right. When this setting is enabled they become:
Left/Right/Back/Confirm. This makes it more comfortable to use when
holding in your right hand since your thumb can more easily rest on the
next button. The original firmware has a similar setting.

**What changes are included?**

- Add the new setting.
- Create a mapper to dynamically switch the buttons based on the
setting.
- Use mapper on the various activity screens.
- Update the button hints to reflect the swapped buttons.

## Additional Context

Full disclosure: I used Codex CLI to put this PR together, but did
review it to make sure it makes sense.

Also tested on my device:
https://share.cleanshot.com/k76891NY
This commit is contained in:
dangson
2025-12-28 21:59:14 -06:00
committed by GitHub
parent 534504cf7a
commit 140d8749a6
35 changed files with 285 additions and 140 deletions

View File

@@ -72,7 +72,7 @@ void OtaUpdateActivity::onEnter() {
// Launch WiFi selection subactivity
Serial.printf("[%lu] [OTA] Launching WifiSelectionActivity...\n", millis());
enterNewActivity(new WifiSelectionActivity(renderer, inputManager,
enterNewActivity(new WifiSelectionActivity(renderer, mappedInput,
[this](const bool connected) { onWifiSelectionComplete(connected); }));
}
@@ -191,7 +191,7 @@ void OtaUpdateActivity::loop() {
}
if (state == WAITING_CONFIRMATION) {
if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
Serial.printf("[%lu] [OTA] New update available, starting download...\n", millis());
xSemaphoreTake(renderingMutex, portMAX_DELAY);
state = UPDATE_IN_PROGRESS;
@@ -215,7 +215,7 @@ void OtaUpdateActivity::loop() {
updateRequired = true;
}
if (inputManager.wasPressed(InputManager::BTN_BACK)) {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
goBack();
}
@@ -223,14 +223,14 @@ void OtaUpdateActivity::loop() {
}
if (state == FAILED) {
if (inputManager.wasPressed(InputManager::BTN_BACK)) {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
goBack();
}
return;
}
if (state == NO_UPDATE) {
if (inputManager.wasPressed(InputManager::BTN_BACK)) {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
goBack();
}
return;