Files
firmware/src/graphics/niche/InkHUD/Persistence.h
zeropt 3371d3372c Adding support for InkHUD joystick navigation for the Seeed Wio Tracker L1 E-ink (#8678)
* TwoButtonExtened mirrors TwoButton but added joystick functionality

* basic ui navigation with a joystick

settings->joystick.enabled setting added and SETTINGS_VERSION
incremented by one in InkHUD/Persistence.h

in seeed_wio_tracker_L1_eink/nicheGraphics.h enable joystick and
disable "Next Tile" menu item in

implement prevTile and prevApplet functions in
InkHUD/WindowManager.h,cpp and InkHUD/InkHUD.h,cpp

onStickCenterShort, onStickCenterLong, onStickUp, onStickDown,
onStickLeft, and onStickRight functions added to:
- InkHUD/InkHUD.h,cpp
- InkHUD/Events.h,cpp
- InkHUD/Applet.h

change navigation actions in InkHUD/Events.cpp events based on
whether the joystick is enabled or not

in seeed_wio_tracker_L1_eink/nicheGraphics.h connect joystick events to
the new joystick handler functions

* handle joystick input in NotificationApplet and TipsApplet

Both the joystick center short press and the user button short press can
be used to advance through the Tips applet.

dismiss notifications with any joystick input

* MenuApplet controls
allows menu navigation including a back button

* add AlignStickApplet for aligning the joystick with the screen

add joystick.aligned and joystick.alignment to InkHUD/Persistence.h for
storing alignment status and relative angle

create AlignStick applet that prompts the user for a joystick input and
rotates the controls to align with the screen

AlignStick applet is run after the tips applet if the joystick is
enabled and not aligned

add menu item for opening the AlignStick applet

* update tips applet with joystick controls

* format InkHUD additions

* fix stroke consistency when resizing joystick graphic

* tweak button tips for order consistency

* increase joystick debounce

* fix comments

* remove unnecessary '+'

* remap joystick controls to match standard inkHUD behavior

Input with a joystick now behaves as follows

User Button (joystick center):
- short press in applet -> opens menu
- long press in applet -> opens menu
- short press in menu -> selects
- long press in menu -> selects

Exit Button:
- short press in applet -> switches tile
- long press in applet -> nothing for now
- short press in menu -> closes menu
- long press in menu -> nothing for now

---------

Co-authored-by: scobert <scobert57@gmail.com>
Co-authored-by: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com>
2025-12-20 15:15:42 -05:00

145 lines
5.3 KiB
C++

#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
A quick and dirty alternative to storing "device only" settings using the protobufs
Convenient during development.
Potentially a polite option, to avoid polluting the generated code with values for obscure use cases like this.
The save / load mechanism is a shared NicheGraphics feature.
*/
#pragma once
#include "configuration.h"
#include "./InkHUD.h"
#include "graphics/niche/InkHUD/MessageStore.h"
#include "graphics/niche/Utils/FlashData.h"
namespace NicheGraphics::InkHUD
{
class Persistence
{
public:
static constexpr uint8_t MAX_TILES_GLOBAL = 4;
static constexpr uint8_t MAX_USERAPPLETS_GLOBAL = 16;
// Used to invalidate old settings, if needed
// Version 0 is reserved for testing, and will always load defaults
static constexpr uint32_t SETTINGS_VERSION = 3;
struct Settings {
struct Meta {
// Used to invalidate old savefiles, if we make breaking changes
uint32_t version = SETTINGS_VERSION;
} meta;
struct UserTiles {
// How many tiles are shown
uint8_t count = 1;
// Maximum amount of tiles for this display
uint8_t maxCount = 4;
// Which tile is focused (responding to user button input)
uint8_t focused = 0;
// Which applet is displayed on which tile
// Index of array: which tile, as indexed in WindowManager::userTiles
// Value of array: which applet, as indexed in InkHUD::userApplets
uint8_t displayedUserApplet[MAX_TILES_GLOBAL] = {0, 1, 2, 3};
} userTiles;
struct UserApplets {
// Which applets are running (either displayed, or in the background)
// Index of array: which applet, as indexed in InkHUD::userApplets
// Initial value is set by the "activeByDefault" parameter of InkHUD::addApplet, in setupNicheGraphics method
bool active[MAX_USERAPPLETS_GLOBAL]{false};
// Which user applets should be automatically shown when they have important data to show
// If none set, foreground applets should remain foreground without manual user input
// If multiple applets request this at once,
// priority is the order which they were passed to InkHUD::addApplets, in setupNicheGraphics method
bool autoshow[MAX_USERAPPLETS_GLOBAL]{false};
} userApplets;
// Features which the user can enable / disable via the on-screen menu
struct OptionalFeatures {
bool notifications = true;
bool batteryIcon = false;
} optionalFeatures;
// Some menu items may not be required, based on device / configuration
// We can enable them only when needed, to de-clutter the menu
struct OptionalMenuItems {
// If aux button is used to swap between tiles, we have no need for this menu item
bool nextTile = true;
// Used if backlight present, and not controlled by AUX button
// If this item is added to menu: backlight is always active when menu is open
// The added menu items then allows the user to "Keep Backlight On", globally.
bool backlight = false;
} optionalMenuItems;
// Allows tips to be run once only
struct Tips {
// Enables the longer "tutorial" shown only on first boot
// Once tutorial has been completed, it is no longer shown
bool firstBoot = true;
// User is advised to shut down before removing device power
// Once user executes a shutdown (either via menu or client app),
// this tip is no longer shown
bool safeShutdownSeen = false;
} tips;
// Joystick settings for enabling and aligning to the screen
struct Joystick {
// Modifies the UI for joystick use
bool enabled = false;
// gets set to true when AlignStick applet is completed
bool aligned = false;
// Rotation of the joystick
// Multiples of 90 degrees clockwise
uint8_t alignment = 0;
} joystick;
// Rotation of the display
// Multiples of 90 degrees clockwise
// Most commonly: rotation is 0 when flex connector is oriented below display
uint8_t rotation = 0;
// How long do we consider another node to be "active"?
// Used when applets want to filter for "active nodes" only
uint32_t recentlyActiveSeconds = 2 * 60;
};
// Most recently received text message
// Value is updated by InkHUD::WindowManager, as a courtesy to applets
// Note: different from devicestate.rx_text_message,
// which may contain an *outgoing message* to broadcast
struct LatestMessage {
MessageStore::Message broadcast; // Most recent message received broadcast
MessageStore::Message dm; // Most recent received DM
bool wasBroadcast; // True if most recent broadcast is newer than most recent dm
};
void loadSettings();
void saveSettings();
void loadLatestMessage();
void saveLatestMessage();
// void printSettings(Settings *settings); // Debugging use only
Settings settings;
LatestMessage latestMessage;
};
} // namespace NicheGraphics::InkHUD
#endif