feat(ui): runtime joystick rotation independent of display rotation

Add NodePrefs::joystick_rotation (0-3 steps CW), persisted in DataStore
alongside display_rotation. rotateJoystickKey() now takes a runtime rot
parameter instead of compile-time JOYSTICK_ROTATION macro. UITask::loop()
reads joystick_rotation from NodePrefs each frame. Settings screen exposes
"Joystick" rotation item on any build with UI_HAS_JOYSTICK. JOYSTICK_ROTATION
macro still works as compile-time default for legacy/non-prefs builds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-23 15:20:40 +02:00
co-authored by Claude Sonnet 4.6
parent 85cfb6f1af
commit fea1be8e81
5 changed files with 70 additions and 6 deletions
@@ -23,6 +23,9 @@ class SettingsScreen : public UIScreen {
FONT,
#if defined(EINK_DISPLAY_MODEL)
ROTATION,
#endif
#if defined(UI_HAS_JOYSTICK)
JOY_ROTATION,
#endif
// Sound section
SECTION_SOUND,
@@ -443,6 +446,14 @@ class SettingsScreen : public UIScreen {
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
uint8_t r = p ? (p->display_rotation & 3) : 0;
display.print(ROT_LABELS[r]); }
#endif
#if defined(UI_HAS_JOYSTICK)
} else if (item == JOY_ROTATION) {
display.print("Joystick");
display.setCursor(display.valCol(), y);
{ static const char* ROT_LABELS[] = { "0 deg", "90 deg", "180 deg", "270 deg" };
uint8_t r = p ? (p->joystick_rotation & 3) : 0;
display.print(ROT_LABELS[r]); }
#endif
} else if (item == DM_FILTER) {
display.print("DM");
@@ -666,6 +677,13 @@ public:
_dirty = true;
return true;
}
#endif
#if defined(UI_HAS_JOYSTICK)
if (_selected == JOY_ROTATION && p && (left || right || enter)) {
p->joystick_rotation = (p->joystick_rotation + (left ? 3 : 1)) & 3;
_dirty = true;
return true;
}
#endif
if (_selected == DM_FILTER && p && (left || right || enter)) {
p->dm_show_all = p->dm_show_all ? 0 : 1;