## Summary
* Custom remapper to create any variant of front button layout.
## Additional Context
* Included migration from previous frontlayout setting
* This will solve:
* https://github.com/crosspoint-reader/crosspoint-reader/issues/654
* https://github.com/crosspoint-reader/crosspoint-reader/issues/652
* https://github.com/crosspoint-reader/crosspoint-reader/issues/620
* https://github.com/crosspoint-reader/crosspoint-reader/issues/468
<img width="860" height="1147" alt="image"
src="https://github.com/user-attachments/assets/457356ed-7a7d-4e1c-8683-e187a1df47c0"
/>
---
### 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? _**< PARTIALLY >**_
109 lines
3.8 KiB
C++
109 lines
3.8 KiB
C++
#include "MappedInputManager.h"
|
|
|
|
#include "CrossPointSettings.h"
|
|
|
|
namespace {
|
|
using ButtonIndex = uint8_t;
|
|
|
|
struct SideLayoutMap {
|
|
ButtonIndex pageBack;
|
|
ButtonIndex pageForward;
|
|
};
|
|
|
|
// Order matches CrossPointSettings::SIDE_BUTTON_LAYOUT.
|
|
constexpr SideLayoutMap kSideLayouts[] = {
|
|
{HalGPIO::BTN_UP, HalGPIO::BTN_DOWN},
|
|
{HalGPIO::BTN_DOWN, HalGPIO::BTN_UP},
|
|
};
|
|
} // namespace
|
|
|
|
bool MappedInputManager::mapButton(const Button button, bool (HalGPIO::*fn)(uint8_t) const) const {
|
|
const auto sideLayout = static_cast<CrossPointSettings::SIDE_BUTTON_LAYOUT>(SETTINGS.sideButtonLayout);
|
|
const auto& side = kSideLayouts[sideLayout];
|
|
|
|
switch (button) {
|
|
case Button::Back:
|
|
// Logical Back maps to user-configured front button.
|
|
return (gpio.*fn)(SETTINGS.frontButtonBack);
|
|
case Button::Confirm:
|
|
// Logical Confirm maps to user-configured front button.
|
|
return (gpio.*fn)(SETTINGS.frontButtonConfirm);
|
|
case Button::Left:
|
|
// Logical Left maps to user-configured front button.
|
|
return (gpio.*fn)(SETTINGS.frontButtonLeft);
|
|
case Button::Right:
|
|
// Logical Right maps to user-configured front button.
|
|
return (gpio.*fn)(SETTINGS.frontButtonRight);
|
|
case Button::Up:
|
|
// Side buttons remain fixed for Up/Down.
|
|
return (gpio.*fn)(HalGPIO::BTN_UP);
|
|
case Button::Down:
|
|
// Side buttons remain fixed for Up/Down.
|
|
return (gpio.*fn)(HalGPIO::BTN_DOWN);
|
|
case Button::Power:
|
|
// Power button bypasses remapping.
|
|
return (gpio.*fn)(HalGPIO::BTN_POWER);
|
|
case Button::PageBack:
|
|
// Reader page navigation uses side buttons and can be swapped via settings.
|
|
return (gpio.*fn)(side.pageBack);
|
|
case Button::PageForward:
|
|
// Reader page navigation uses side buttons and can be swapped via settings.
|
|
return (gpio.*fn)(side.pageForward);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool MappedInputManager::wasPressed(const Button button) const { return mapButton(button, &HalGPIO::wasPressed); }
|
|
|
|
bool MappedInputManager::wasReleased(const Button button) const { return mapButton(button, &HalGPIO::wasReleased); }
|
|
|
|
bool MappedInputManager::isPressed(const Button button) const { return mapButton(button, &HalGPIO::isPressed); }
|
|
|
|
bool MappedInputManager::wasAnyPressed() const { return gpio.wasAnyPressed(); }
|
|
|
|
bool MappedInputManager::wasAnyReleased() const { return gpio.wasAnyReleased(); }
|
|
|
|
unsigned long MappedInputManager::getHeldTime() const { return gpio.getHeldTime(); }
|
|
|
|
MappedInputManager::Labels MappedInputManager::mapLabels(const char* back, const char* confirm, const char* previous,
|
|
const char* next) const {
|
|
// 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;
|
|
}
|
|
return -1;
|
|
} |