2025-12-28 21:59:14 -06:00
|
|
|
#include "MappedInputManager.h"
|
|
|
|
|
|
2025-12-30 15:09:30 +10:00
|
|
|
#include "CrossPointSettings.h"
|
|
|
|
|
|
2026-01-27 17:53:13 +05:00
|
|
|
namespace {
|
|
|
|
|
using ButtonIndex = uint8_t;
|
|
|
|
|
|
|
|
|
|
struct SideLayoutMap {
|
|
|
|
|
ButtonIndex pageBack;
|
|
|
|
|
ButtonIndex pageForward;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Order matches CrossPointSettings::SIDE_BUTTON_LAYOUT.
|
|
|
|
|
constexpr SideLayoutMap kSideLayouts[] = {
|
2026-01-27 18:50:15 +01:00
|
|
|
{HalGPIO::BTN_UP, HalGPIO::BTN_DOWN},
|
|
|
|
|
{HalGPIO::BTN_DOWN, HalGPIO::BTN_UP},
|
2026-01-27 17:53:13 +05:00
|
|
|
};
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::mapButton(const Button button, bool (HalGPIO::*fn)(uint8_t) const) const {
|
2025-12-29 11:17:10 +01:00
|
|
|
const auto sideLayout = static_cast<CrossPointSettings::SIDE_BUTTON_LAYOUT>(SETTINGS.sideButtonLayout);
|
2026-01-27 17:53:13 +05:00
|
|
|
const auto& side = kSideLayouts[sideLayout];
|
2025-12-28 21:59:14 -06:00
|
|
|
|
|
|
|
|
switch (button) {
|
|
|
|
|
case Button::Back:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Logical Back maps to user-configured front button.
|
|
|
|
|
return (gpio.*fn)(SETTINGS.frontButtonBack);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Confirm:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Logical Confirm maps to user-configured front button.
|
|
|
|
|
return (gpio.*fn)(SETTINGS.frontButtonConfirm);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Left:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Logical Left maps to user-configured front button.
|
|
|
|
|
return (gpio.*fn)(SETTINGS.frontButtonLeft);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Right:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Logical Right maps to user-configured front button.
|
|
|
|
|
return (gpio.*fn)(SETTINGS.frontButtonRight);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Up:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Side buttons remain fixed for Up/Down.
|
2026-01-27 18:50:15 +01:00
|
|
|
return (gpio.*fn)(HalGPIO::BTN_UP);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Down:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Side buttons remain fixed for Up/Down.
|
2026-01-27 18:50:15 +01:00
|
|
|
return (gpio.*fn)(HalGPIO::BTN_DOWN);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::Power:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Power button bypasses remapping.
|
2026-01-27 18:50:15 +01:00
|
|
|
return (gpio.*fn)(HalGPIO::BTN_POWER);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::PageBack:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Reader page navigation uses side buttons and can be swapped via settings.
|
2026-01-27 18:50:15 +01:00
|
|
|
return (gpio.*fn)(side.pageBack);
|
2025-12-28 21:59:14 -06:00
|
|
|
case Button::PageForward:
|
2026-02-05 14:37:17 +03:00
|
|
|
// Reader page navigation uses side buttons and can be swapped via settings.
|
2026-01-27 18:50:15 +01:00
|
|
|
return (gpio.*fn)(side.pageForward);
|
2025-12-28 21:59:14 -06:00
|
|
|
}
|
|
|
|
|
|
2026-01-27 17:53:13 +05:00
|
|
|
return false;
|
2025-12-28 21:59:14 -06:00
|
|
|
}
|
|
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::wasPressed(const Button button) const { return mapButton(button, &HalGPIO::wasPressed); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::wasReleased(const Button button) const { return mapButton(button, &HalGPIO::wasReleased); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::isPressed(const Button button) const { return mapButton(button, &HalGPIO::isPressed); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::wasAnyPressed() const { return gpio.wasAnyPressed(); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
bool MappedInputManager::wasAnyReleased() const { return gpio.wasAnyReleased(); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
2026-01-27 18:50:15 +01:00
|
|
|
unsigned long MappedInputManager::getHeldTime() const { return gpio.getHeldTime(); }
|
2025-12-28 21:59:14 -06:00
|
|
|
|
|
|
|
|
MappedInputManager::Labels MappedInputManager::mapLabels(const char* back, const char* confirm, const char* previous,
|
|
|
|
|
const char* next) const {
|
2026-02-05 14:37:17 +03:00
|
|
|
// Build the label order based on the configured hardware mapping.
|
|
|
|
|
auto labelForHardware = [&](uint8_t hw) -> const char* {
|
|
|
|
|
// Compare against configured logical roles and return the matching label.
|
|
|
|
|
if (hw == SETTINGS.frontButtonBack) {
|
|
|
|
|
return back;
|
|
|
|
|
}
|
|
|
|
|
if (hw == SETTINGS.frontButtonConfirm) {
|
|
|
|
|
return confirm;
|
|
|
|
|
}
|
|
|
|
|
if (hw == SETTINGS.frontButtonLeft) {
|
|
|
|
|
return previous;
|
|
|
|
|
}
|
|
|
|
|
if (hw == SETTINGS.frontButtonRight) {
|
|
|
|
|
return next;
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {labelForHardware(HalGPIO::BTN_BACK), labelForHardware(HalGPIO::BTN_CONFIRM),
|
|
|
|
|
labelForHardware(HalGPIO::BTN_LEFT), labelForHardware(HalGPIO::BTN_RIGHT)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int MappedInputManager::getPressedFrontButton() const {
|
|
|
|
|
// Scan the raw front buttons in hardware order.
|
|
|
|
|
// This bypasses remapping so the remap activity can capture physical presses.
|
|
|
|
|
if (gpio.wasPressed(HalGPIO::BTN_BACK)) {
|
|
|
|
|
return HalGPIO::BTN_BACK;
|
|
|
|
|
}
|
|
|
|
|
if (gpio.wasPressed(HalGPIO::BTN_CONFIRM)) {
|
|
|
|
|
return HalGPIO::BTN_CONFIRM;
|
|
|
|
|
}
|
|
|
|
|
if (gpio.wasPressed(HalGPIO::BTN_LEFT)) {
|
|
|
|
|
return HalGPIO::BTN_LEFT;
|
|
|
|
|
}
|
|
|
|
|
if (gpio.wasPressed(HalGPIO::BTN_RIGHT)) {
|
|
|
|
|
return HalGPIO::BTN_RIGHT;
|
2025-12-28 21:59:14 -06:00
|
|
|
}
|
2026-02-05 14:37:17 +03:00
|
|
|
return -1;
|
2026-01-27 18:50:15 +01:00
|
|
|
}
|