mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-27 04:02:05 +00:00
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>
This commit is contained in:
@@ -88,8 +88,14 @@ class Applet : public GFX
|
||||
virtual void onForeground() {}
|
||||
virtual void onBackground() {}
|
||||
virtual void onShutdown() {}
|
||||
virtual void onButtonShortPress() {} // (System Applets only)
|
||||
virtual void onButtonLongPress() {} // (System Applets only)
|
||||
virtual void onButtonShortPress() {}
|
||||
virtual void onButtonLongPress() {}
|
||||
virtual void onExitShort() {}
|
||||
virtual void onExitLong() {}
|
||||
virtual void onNavUp() {}
|
||||
virtual void onNavDown() {}
|
||||
virtual void onNavLeft() {}
|
||||
virtual void onNavRight() {}
|
||||
|
||||
virtual bool approveNotification(Notification &n); // Allow an applet to veto a notification
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
||||
|
||||
#include "./AlignStickApplet.h"
|
||||
|
||||
using namespace NicheGraphics;
|
||||
|
||||
InkHUD::AlignStickApplet::AlignStickApplet()
|
||||
{
|
||||
if (!settings->joystick.aligned)
|
||||
bringToForeground();
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onRender()
|
||||
{
|
||||
setFont(fontMedium);
|
||||
printAt(0, 0, "Align Joystick:");
|
||||
setFont(fontSmall);
|
||||
std::string instructions = "Move joystick in the direction indicated";
|
||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), instructions);
|
||||
|
||||
// Size of the region in which the joystick graphic should fit
|
||||
uint16_t joyXLimit = X(0.8);
|
||||
uint16_t contentH = fontMedium.lineHeight() * 1.5 + fontSmall.lineHeight() * 1;
|
||||
if (getTextWidth(instructions) > width())
|
||||
contentH += fontSmall.lineHeight();
|
||||
uint16_t freeY = height() - contentH - fontSmall.lineHeight() * 1.2;
|
||||
uint16_t joyYLimit = freeY * 0.8;
|
||||
|
||||
// Use the shorter of the two
|
||||
uint16_t joyWidth = joyXLimit < joyYLimit ? joyXLimit : joyYLimit;
|
||||
|
||||
// Center the joystick graphic
|
||||
uint16_t centerX = X(0.5);
|
||||
uint16_t centerY = contentH + freeY * 0.5;
|
||||
|
||||
// Draw joystick graphic
|
||||
drawStick(centerX, centerY, joyWidth);
|
||||
|
||||
setFont(fontSmall);
|
||||
printAt(X(0.5), Y(1.0) - fontSmall.lineHeight() * 0.2, "Long press to skip", CENTER, BOTTOM);
|
||||
}
|
||||
|
||||
// Draw a scalable joystick graphic
|
||||
void InkHUD::AlignStickApplet::drawStick(uint16_t centerX, uint16_t centerY, uint16_t width)
|
||||
{
|
||||
if (width < 9) // too small to draw
|
||||
return;
|
||||
|
||||
else if (width < 40) { // only draw up arrow
|
||||
uint16_t chamfer = width < 20 ? 1 : 2;
|
||||
|
||||
// Draw filled up arrow
|
||||
drawDirection(centerX, centerY - width / 4, Direction::UP, width, chamfer, BLACK);
|
||||
|
||||
} else { // large enough to draw the full thing
|
||||
uint16_t chamfer = width < 80 ? 1 : 2;
|
||||
uint16_t stroke = 3; // pixels
|
||||
uint16_t arrowW = width * 0.22;
|
||||
uint16_t hollowW = arrowW - stroke * 2;
|
||||
|
||||
// Draw center circle
|
||||
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2), BLACK);
|
||||
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2) - stroke, WHITE);
|
||||
|
||||
// Draw filled up arrow
|
||||
drawDirection(centerX, centerY - width / 2, Direction::UP, arrowW, chamfer, BLACK);
|
||||
|
||||
// Draw down arrow
|
||||
drawDirection(centerX, centerY + width / 2, Direction::DOWN, arrowW, chamfer, BLACK);
|
||||
drawDirection(centerX, centerY + width / 2 - stroke, Direction::DOWN, hollowW, 0, WHITE);
|
||||
|
||||
// Draw left arrow
|
||||
drawDirection(centerX - width / 2, centerY, Direction::LEFT, arrowW, chamfer, BLACK);
|
||||
drawDirection(centerX - width / 2 + stroke, centerY, Direction::LEFT, hollowW, 0, WHITE);
|
||||
|
||||
// Draw right arrow
|
||||
drawDirection(centerX + width / 2, centerY, Direction::RIGHT, arrowW, chamfer, BLACK);
|
||||
drawDirection(centerX + width / 2 - stroke, centerY, Direction::RIGHT, hollowW, 0, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a scalable joystick direction arrow
|
||||
// a right-triangle with blunted tips
|
||||
/*
|
||||
_ <--point
|
||||
^ / \
|
||||
| / \
|
||||
size / \
|
||||
| / \
|
||||
v |_________|
|
||||
|
||||
*/
|
||||
void InkHUD::AlignStickApplet::drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size,
|
||||
uint16_t chamfer, Color color)
|
||||
{
|
||||
uint16_t chamferW = chamfer * 2 + 1;
|
||||
uint16_t triangleW = size - chamferW;
|
||||
|
||||
// Draw arrow
|
||||
switch (direction) {
|
||||
case Direction::UP:
|
||||
fillRect(pointX - chamfer, pointY, chamferW, triangleW, color);
|
||||
fillRect(pointX - chamfer - triangleW, pointY + triangleW, chamferW + triangleW * 2, chamferW, color);
|
||||
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY + triangleW, pointX - chamfer,
|
||||
pointY + triangleW, color);
|
||||
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY + triangleW, pointX + chamfer,
|
||||
pointY + triangleW, color);
|
||||
break;
|
||||
case Direction::DOWN:
|
||||
fillRect(pointX - chamfer, pointY - triangleW + 1, chamferW, triangleW, color);
|
||||
fillRect(pointX - chamfer - triangleW, pointY - size + 1, chamferW + triangleW * 2, chamferW, color);
|
||||
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY - triangleW, pointX - chamfer,
|
||||
pointY - triangleW, color);
|
||||
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY - triangleW, pointX + chamfer,
|
||||
pointY - triangleW, color);
|
||||
break;
|
||||
case Direction::LEFT:
|
||||
fillRect(pointX, pointY - chamfer, triangleW, chamferW, color);
|
||||
fillRect(pointX + triangleW, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
|
||||
fillTriangle(pointX, pointY - chamfer, pointX + triangleW, pointY - chamfer - triangleW, pointX + triangleW,
|
||||
pointY - chamfer, color);
|
||||
fillTriangle(pointX, pointY + chamfer, pointX + triangleW, pointY + chamfer + triangleW, pointX + triangleW,
|
||||
pointY + chamfer, color);
|
||||
break;
|
||||
case Direction::RIGHT:
|
||||
fillRect(pointX - triangleW + 1, pointY - chamfer, triangleW, chamferW, color);
|
||||
fillRect(pointX - size + 1, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
|
||||
fillTriangle(pointX, pointY - chamfer, pointX - triangleW, pointY - chamfer - triangleW, pointX - triangleW,
|
||||
pointY - chamfer, color);
|
||||
fillTriangle(pointX, pointY + chamfer, pointX - triangleW, pointY + chamfer + triangleW, pointX - triangleW,
|
||||
pointY + chamfer, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onForeground()
|
||||
{
|
||||
// Prevent most other applets from requesting update, and skip their rendering entirely
|
||||
// Another system applet with a higher precedence can potentially ignore this
|
||||
SystemApplet::lockRendering = true;
|
||||
SystemApplet::lockRequests = true;
|
||||
|
||||
handleInput = true; // Intercept the button input for our applet
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onBackground()
|
||||
{
|
||||
// Allow normal update behavior to resume
|
||||
SystemApplet::lockRendering = false;
|
||||
SystemApplet::lockRequests = false;
|
||||
SystemApplet::handleInput = false;
|
||||
|
||||
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
|
||||
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onButtonLongPress()
|
||||
{
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onExitLong()
|
||||
{
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onNavUp()
|
||||
{
|
||||
settings->joystick.aligned = true;
|
||||
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onNavDown()
|
||||
{
|
||||
inkhud->rotateJoystick(2); // 180 deg
|
||||
settings->joystick.aligned = true;
|
||||
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onNavLeft()
|
||||
{
|
||||
inkhud->rotateJoystick(3); // 270 deg
|
||||
settings->joystick.aligned = true;
|
||||
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::AlignStickApplet::onNavRight()
|
||||
{
|
||||
inkhud->rotateJoystick(1); // 90 deg
|
||||
settings->joystick.aligned = true;
|
||||
|
||||
sendToBackground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifdef MESHTASTIC_INCLUDE_INKHUD
|
||||
|
||||
/*
|
||||
|
||||
System Applet for manually aligning the joystick with the screen
|
||||
|
||||
should be run at startup if the joystick is enabled
|
||||
and not aligned to the screen
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "graphics/niche/InkHUD/SystemApplet.h"
|
||||
|
||||
namespace NicheGraphics::InkHUD
|
||||
{
|
||||
|
||||
class AlignStickApplet : public SystemApplet
|
||||
{
|
||||
public:
|
||||
AlignStickApplet();
|
||||
|
||||
void onRender() override;
|
||||
void onForeground() override;
|
||||
void onBackground() override;
|
||||
void onButtonLongPress() override;
|
||||
void onExitLong() override;
|
||||
void onNavUp() override;
|
||||
void onNavDown() override;
|
||||
void onNavLeft() override;
|
||||
void onNavRight() override;
|
||||
|
||||
protected:
|
||||
enum Direction {
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
};
|
||||
|
||||
void drawStick(uint16_t centerX, uint16_t centerY, uint16_t width);
|
||||
void drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size, uint16_t chamfer, Color color);
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::InkHUD
|
||||
|
||||
#endif
|
||||
@@ -30,6 +30,7 @@ enum MenuAction {
|
||||
TOGGLE_AUTOSHOW_APPLET,
|
||||
SET_RECENTS,
|
||||
ROTATE,
|
||||
ALIGN_JOYSTICK,
|
||||
LAYOUT,
|
||||
TOGGLE_BATTERY_ICON,
|
||||
TOGGLE_NOTIFICATIONS,
|
||||
|
||||
@@ -178,6 +178,10 @@ void InkHUD::MenuApplet::execute(MenuItem item)
|
||||
inkhud->rotate();
|
||||
break;
|
||||
|
||||
case ALIGN_JOYSTICK:
|
||||
inkhud->openAlignStick();
|
||||
break;
|
||||
|
||||
case LAYOUT:
|
||||
// Todo: smarter incrementing of tile count
|
||||
settings->userTiles.count++;
|
||||
@@ -287,14 +291,17 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
||||
// items.push_back(MenuItem("Display Off", MenuPage::EXIT)); // TODO
|
||||
items.push_back(MenuItem("Save & Shut Down", MenuAction::SHUTDOWN));
|
||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||
previousPage = MenuPage::EXIT;
|
||||
break;
|
||||
|
||||
case SEND:
|
||||
populateSendPage();
|
||||
previousPage = MenuPage::ROOT;
|
||||
break;
|
||||
|
||||
case CANNEDMESSAGE_RECIPIENT:
|
||||
populateRecipientPage();
|
||||
previousPage = MenuPage::OPTIONS;
|
||||
break;
|
||||
|
||||
case OPTIONS:
|
||||
@@ -321,6 +328,8 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
||||
if (settings->userTiles.maxCount > 1)
|
||||
items.push_back(MenuItem("Layout", MenuAction::LAYOUT, MenuPage::OPTIONS));
|
||||
items.push_back(MenuItem("Rotate", MenuAction::ROTATE, MenuPage::OPTIONS));
|
||||
if (settings->joystick.enabled)
|
||||
items.push_back(MenuItem("Align Joystick", MenuAction::ALIGN_JOYSTICK, MenuPage::EXIT));
|
||||
items.push_back(MenuItem("Notifications", MenuAction::TOGGLE_NOTIFICATIONS, MenuPage::OPTIONS,
|
||||
&settings->optionalFeatures.notifications));
|
||||
items.push_back(MenuItem("Battery Icon", MenuAction::TOGGLE_BATTERY_ICON, MenuPage::OPTIONS,
|
||||
@@ -332,20 +341,24 @@ void InkHUD::MenuApplet::showPage(MenuPage page)
|
||||
items.push_back(
|
||||
MenuItem("12-Hour Clock", MenuAction::TOGGLE_12H_CLOCK, MenuPage::OPTIONS, &config.display.use_12h_clock));
|
||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||
previousPage = MenuPage::ROOT;
|
||||
break;
|
||||
|
||||
case APPLETS:
|
||||
populateAppletPage();
|
||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||
previousPage = MenuPage::OPTIONS;
|
||||
break;
|
||||
|
||||
case AUTOSHOW:
|
||||
populateAutoshowPage();
|
||||
items.push_back(MenuItem("Exit", MenuPage::EXIT));
|
||||
previousPage = MenuPage::OPTIONS;
|
||||
break;
|
||||
|
||||
case RECENTS:
|
||||
populateRecentsPage();
|
||||
previousPage = MenuPage::OPTIONS;
|
||||
break;
|
||||
|
||||
case EXIT:
|
||||
@@ -479,12 +492,21 @@ void InkHUD::MenuApplet::onButtonShortPress()
|
||||
// Push the auto-close timer back
|
||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||
|
||||
// Move menu cursor to next entry, then update
|
||||
if (cursorShown)
|
||||
cursor = (cursor + 1) % items.size();
|
||||
else
|
||||
cursorShown = true;
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
if (!settings->joystick.enabled) {
|
||||
// Move menu cursor to next entry, then update
|
||||
if (cursorShown)
|
||||
cursor = (cursor + 1) % items.size();
|
||||
else
|
||||
cursorShown = true;
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
} else {
|
||||
if (cursorShown)
|
||||
execute(items.at(cursor));
|
||||
else
|
||||
showPage(MenuPage::EXIT);
|
||||
if (!wantsToRender())
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onButtonLongPress()
|
||||
@@ -504,6 +526,62 @@ void InkHUD::MenuApplet::onButtonLongPress()
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onExitShort()
|
||||
{
|
||||
// Exit the menu
|
||||
showPage(MenuPage::EXIT);
|
||||
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onNavUp()
|
||||
{
|
||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||
|
||||
// Move menu cursor to previous entry, then update
|
||||
if (cursor == 0)
|
||||
cursor = items.size() - 1;
|
||||
else
|
||||
cursor--;
|
||||
|
||||
if (!cursorShown)
|
||||
cursorShown = true;
|
||||
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onNavDown()
|
||||
{
|
||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||
|
||||
// Move menu cursor to next entry, then update
|
||||
if (cursorShown)
|
||||
cursor = (cursor + 1) % items.size();
|
||||
else
|
||||
cursorShown = true;
|
||||
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onNavLeft()
|
||||
{
|
||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||
|
||||
// Go to the previous menu page
|
||||
showPage(previousPage);
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
void InkHUD::MenuApplet::onNavRight()
|
||||
{
|
||||
OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
|
||||
|
||||
if (cursorShown)
|
||||
execute(items.at(cursor));
|
||||
if (!wantsToRender())
|
||||
requestUpdate(Drivers::EInk::UpdateTypes::FAST);
|
||||
}
|
||||
|
||||
// Dynamically create MenuItem entries for activating / deactivating Applets, for the "Applet Selection" submenu
|
||||
void InkHUD::MenuApplet::populateAppletPage()
|
||||
{
|
||||
@@ -796,4 +874,4 @@ void InkHUD::MenuApplet::freeCannedMessageResources()
|
||||
cm.recipientItems.clear();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,11 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
||||
void onBackground() override;
|
||||
void onButtonShortPress() override;
|
||||
void onButtonLongPress() override;
|
||||
void onExitShort() override;
|
||||
void onNavUp() override;
|
||||
void onNavDown() override;
|
||||
void onNavLeft() override;
|
||||
void onNavRight() override;
|
||||
void onRender() override;
|
||||
|
||||
void show(Tile *t); // Open the menu, onto a user tile
|
||||
@@ -52,6 +57,7 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
||||
void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data
|
||||
|
||||
MenuPage currentPage = MenuPage::ROOT;
|
||||
MenuPage previousPage = MenuPage::EXIT;
|
||||
uint8_t cursor = 0; // Which menu item is currently highlighted
|
||||
bool cursorShown = false; // Is *any* item highlighted? (Root menu: no initial selection)
|
||||
|
||||
@@ -97,4 +103,4 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
|
||||
|
||||
} // namespace NicheGraphics::InkHUD
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -153,6 +153,42 @@ void InkHUD::NotificationApplet::onButtonLongPress()
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onExitShort()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onExitLong()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onNavUp()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onNavDown()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onNavLeft()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
void InkHUD::NotificationApplet::onNavRight()
|
||||
{
|
||||
dismiss();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FULL);
|
||||
}
|
||||
|
||||
// Ask the WindowManager to check whether any displayed applets are already displaying the info from this notification
|
||||
// Called internally when we first get a "notifiable event", and then again before render,
|
||||
// in case autoshow swapped which applet was displayed
|
||||
|
||||
@@ -31,6 +31,12 @@ class NotificationApplet : public SystemApplet
|
||||
void onBackground() override;
|
||||
void onButtonShortPress() override;
|
||||
void onButtonLongPress() override;
|
||||
void onExitShort() override;
|
||||
void onExitLong() override;
|
||||
void onNavUp() override;
|
||||
void onNavDown() override;
|
||||
void onNavLeft() override;
|
||||
void onNavRight() override;
|
||||
|
||||
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
|
||||
|
||||
|
||||
@@ -112,12 +112,21 @@ void InkHUD::TipsApplet::onRender()
|
||||
setFont(fontSmall);
|
||||
int16_t cursorY = fontMedium.lineHeight() * 1.5;
|
||||
|
||||
printAt(0, cursorY, "User Button");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- short press: next");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- long press: select / open menu");
|
||||
cursorY += fontSmall.lineHeight() * 1.5;
|
||||
if (!settings->joystick.enabled) {
|
||||
printAt(0, cursorY, "User Button");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- short press: next");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- long press: select / open menu");
|
||||
} else {
|
||||
printAt(0, cursorY, "Joystick");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- open menu / select");
|
||||
cursorY += fontSmall.lineHeight() * 1.5;
|
||||
printAt(0, cursorY, "Exit Button");
|
||||
cursorY += fontSmall.lineHeight() * 1.2;
|
||||
printAt(0, cursorY, "- switch tile / close menu");
|
||||
}
|
||||
|
||||
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
||||
} break;
|
||||
@@ -127,8 +136,13 @@ void InkHUD::TipsApplet::onRender()
|
||||
printAt(0, 0, "Tip: Rotation");
|
||||
|
||||
setFont(fontSmall);
|
||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
||||
"To rotate the display, use the InkHUD menu. Long-press the user button > Options > Rotate.");
|
||||
if (!settings->joystick.enabled) {
|
||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
||||
"To rotate the display, use the InkHUD menu. Long-press the user button > Options > Rotate.");
|
||||
} else {
|
||||
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
|
||||
"To rotate the display, use the InkHUD menu. Press the user button > Options > Rotate.");
|
||||
}
|
||||
|
||||
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
|
||||
|
||||
@@ -232,4 +246,10 @@ void InkHUD::TipsApplet::onButtonShortPress()
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
// Functions the same as the user button in this instance
|
||||
void InkHUD::TipsApplet::onExitShort()
|
||||
{
|
||||
onButtonShortPress();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -36,6 +36,7 @@ class TipsApplet : public SystemApplet
|
||||
void onForeground() override;
|
||||
void onBackground() override;
|
||||
void onButtonShortPress() override;
|
||||
void onExitShort() override;
|
||||
|
||||
protected:
|
||||
void renderWelcome(); // Very first screen of tutorial
|
||||
|
||||
@@ -55,10 +55,15 @@ void InkHUD::Events::onButtonShort()
|
||||
}
|
||||
|
||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
||||
if (consumer)
|
||||
// or open menu if joystick is enabled
|
||||
if (consumer) {
|
||||
consumer->onButtonShortPress();
|
||||
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
||||
inkhud->nextApplet();
|
||||
} else if (!dismissedExt) { // Don't change applet if this button press silenced the external notification module
|
||||
if (!settings->joystick.enabled)
|
||||
inkhud->nextApplet();
|
||||
else
|
||||
inkhud->openMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onButtonLong()
|
||||
@@ -83,6 +88,156 @@ void InkHUD::Events::onButtonLong()
|
||||
inkhud->openMenu();
|
||||
}
|
||||
|
||||
void InkHUD::Events::onExitShort()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Short tone
|
||||
playChirp();
|
||||
// Cancel any beeping, buzzing, blinking
|
||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
||||
bool dismissedExt = dismissExternalNotification();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no system applet is handling input, default behavior instead is change tiles
|
||||
if (consumer)
|
||||
consumer->onExitShort();
|
||||
else if (!dismissedExt) // Don't change tile if this button press silenced the external notification module
|
||||
inkhud->nextTile();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onExitLong()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Slightly longer than playChirp
|
||||
playBoop();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (consumer)
|
||||
consumer->onExitLong();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onNavUp()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Short tone
|
||||
playChirp();
|
||||
// Cancel any beeping, buzzing, blinking
|
||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
||||
bool dismissedExt = dismissExternalNotification();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (consumer)
|
||||
consumer->onNavUp();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onNavDown()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Short tone
|
||||
playChirp();
|
||||
// Cancel any beeping, buzzing, blinking
|
||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
||||
bool dismissedExt = dismissExternalNotification();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (consumer)
|
||||
consumer->onNavDown();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onNavLeft()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Short tone
|
||||
playChirp();
|
||||
// Cancel any beeping, buzzing, blinking
|
||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
||||
bool dismissedExt = dismissExternalNotification();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
||||
if (consumer)
|
||||
consumer->onNavLeft();
|
||||
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
||||
inkhud->prevApplet();
|
||||
}
|
||||
}
|
||||
|
||||
void InkHUD::Events::onNavRight()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
// Audio feedback (via buzzer)
|
||||
// Short tone
|
||||
playChirp();
|
||||
// Cancel any beeping, buzzing, blinking
|
||||
// Some button handling suppressed if we are dismissing an external notification (see below)
|
||||
bool dismissedExt = dismissExternalNotification();
|
||||
|
||||
// Check which system applet wants to handle the button press (if any)
|
||||
SystemApplet *consumer = nullptr;
|
||||
for (SystemApplet *sa : inkhud->systemApplets) {
|
||||
if (sa->handleInput) {
|
||||
consumer = sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no system applet is handling input, default behavior instead is to cycle applets
|
||||
if (consumer)
|
||||
consumer->onNavRight();
|
||||
else if (!dismissedExt) // Don't change applet if this button press silenced the external notification module
|
||||
inkhud->nextApplet();
|
||||
}
|
||||
}
|
||||
|
||||
// Callback for deepSleepObserver
|
||||
// Returns 0 to signal that we agree to sleep now
|
||||
int InkHUD::Events::beforeDeepSleep(void *unused)
|
||||
|
||||
@@ -29,6 +29,12 @@ class Events
|
||||
|
||||
void onButtonShort(); // User button: short press
|
||||
void onButtonLong(); // User button: long press
|
||||
void onExitShort(); // Exit button: short press
|
||||
void onExitLong(); // Exit button: long press
|
||||
void onNavUp(); // Navigate up
|
||||
void onNavDown(); // Navigate down
|
||||
void onNavLeft(); // Navigate left
|
||||
void onNavRight(); // Navigate right
|
||||
|
||||
int beforeDeepSleep(void *unused); // Prepare for shutdown
|
||||
int beforeReboot(void *unused); // Prepare for reboot
|
||||
|
||||
@@ -80,6 +80,94 @@ void InkHUD::InkHUD::longpress()
|
||||
events->onButtonLong();
|
||||
}
|
||||
|
||||
// Call this when your exit button gets a short press
|
||||
void InkHUD::InkHUD::exitShort()
|
||||
{
|
||||
events->onExitShort();
|
||||
}
|
||||
|
||||
// Call this when your exit button gets a long press
|
||||
void InkHUD::InkHUD::exitLong()
|
||||
{
|
||||
events->onExitLong();
|
||||
}
|
||||
|
||||
// Call this when your joystick gets an up input
|
||||
void InkHUD::InkHUD::navUp()
|
||||
{
|
||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
||||
case 1: // 90 deg
|
||||
events->onNavLeft();
|
||||
break;
|
||||
case 2: // 180 deg
|
||||
events->onNavDown();
|
||||
break;
|
||||
case 3: // 270 deg
|
||||
events->onNavRight();
|
||||
break;
|
||||
default: // 0 deg
|
||||
events->onNavUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call this when your joystick gets a down input
|
||||
void InkHUD::InkHUD::navDown()
|
||||
{
|
||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
||||
case 1: // 90 deg
|
||||
events->onNavRight();
|
||||
break;
|
||||
case 2: // 180 deg
|
||||
events->onNavUp();
|
||||
break;
|
||||
case 3: // 270 deg
|
||||
events->onNavLeft();
|
||||
break;
|
||||
default: // 0 deg
|
||||
events->onNavDown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call this when your joystick gets a left input
|
||||
void InkHUD::InkHUD::navLeft()
|
||||
{
|
||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
||||
case 1: // 90 deg
|
||||
events->onNavDown();
|
||||
break;
|
||||
case 2: // 180 deg
|
||||
events->onNavRight();
|
||||
break;
|
||||
case 3: // 270 deg
|
||||
events->onNavUp();
|
||||
break;
|
||||
default: // 0 deg
|
||||
events->onNavLeft();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Call this when your joystick gets a right input
|
||||
void InkHUD::InkHUD::navRight()
|
||||
{
|
||||
switch ((persistence->settings.rotation + persistence->settings.joystick.alignment) % 4) {
|
||||
case 1: // 90 deg
|
||||
events->onNavUp();
|
||||
break;
|
||||
case 2: // 180 deg
|
||||
events->onNavLeft();
|
||||
break;
|
||||
case 3: // 270 deg
|
||||
events->onNavDown();
|
||||
break;
|
||||
default: // 0 deg
|
||||
events->onNavRight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Cycle the next user applet to the foreground
|
||||
// Only activated applets are cycled
|
||||
// If user has a multi-applet layout, the applets will cycle on the "focused tile"
|
||||
@@ -88,6 +176,14 @@ void InkHUD::InkHUD::nextApplet()
|
||||
windowManager->nextApplet();
|
||||
}
|
||||
|
||||
// Cycle the previous user applet to the foreground
|
||||
// Only activated applets are cycled
|
||||
// If user has a multi-applet layout, the applets will cycle on the "focused tile"
|
||||
void InkHUD::InkHUD::prevApplet()
|
||||
{
|
||||
windowManager->prevApplet();
|
||||
}
|
||||
|
||||
// Show the menu (on the the focused tile)
|
||||
// The applet previously displayed there will be restored once the menu closes
|
||||
void InkHUD::InkHUD::openMenu()
|
||||
@@ -95,6 +191,12 @@ void InkHUD::InkHUD::openMenu()
|
||||
windowManager->openMenu();
|
||||
}
|
||||
|
||||
// Bring AlignStick applet to the foreground
|
||||
void InkHUD::InkHUD::openAlignStick()
|
||||
{
|
||||
windowManager->openAlignStick();
|
||||
}
|
||||
|
||||
// In layouts where multiple applets are shown at once, change which tile is focused
|
||||
// The focused tile in the one which cycles applets on button short press, and displays menu on long press
|
||||
void InkHUD::InkHUD::nextTile()
|
||||
@@ -102,12 +204,26 @@ void InkHUD::InkHUD::nextTile()
|
||||
windowManager->nextTile();
|
||||
}
|
||||
|
||||
// In layouts where multiple applets are shown at once, change which tile is focused
|
||||
// The focused tile in the one which cycles applets on button short press, and displays menu on long press
|
||||
void InkHUD::InkHUD::prevTile()
|
||||
{
|
||||
windowManager->prevTile();
|
||||
}
|
||||
|
||||
// Rotate the display image by 90 degrees
|
||||
void InkHUD::InkHUD::rotate()
|
||||
{
|
||||
windowManager->rotate();
|
||||
}
|
||||
|
||||
// rotate the joystick in 90 degree increments
|
||||
void InkHUD::InkHUD::rotateJoystick(uint8_t angle)
|
||||
{
|
||||
persistence->settings.joystick.alignment += angle;
|
||||
persistence->settings.joystick.alignment %= 4;
|
||||
}
|
||||
|
||||
// Show / hide the battery indicator in top-right
|
||||
void InkHUD::InkHUD::toggleBatteryIcon()
|
||||
{
|
||||
|
||||
@@ -55,15 +55,25 @@ class InkHUD
|
||||
|
||||
void shortpress();
|
||||
void longpress();
|
||||
void exitShort();
|
||||
void exitLong();
|
||||
void navUp();
|
||||
void navDown();
|
||||
void navLeft();
|
||||
void navRight();
|
||||
|
||||
// Trigger UI changes
|
||||
// - called by various InkHUD components
|
||||
// - suitable(?) for use by aux button, connected in variant nicheGraphics.h
|
||||
|
||||
void nextApplet();
|
||||
void prevApplet();
|
||||
void openMenu();
|
||||
void openAlignStick();
|
||||
void nextTile();
|
||||
void prevTile();
|
||||
void rotate();
|
||||
void rotateJoystick(uint8_t angle = 1); // rotate 90 deg by default
|
||||
void toggleBatteryIcon();
|
||||
|
||||
// Updating the display
|
||||
|
||||
@@ -29,7 +29,7 @@ class Persistence
|
||||
|
||||
// Used to invalidate old settings, if needed
|
||||
// Version 0 is reserved for testing, and will always load defaults
|
||||
static constexpr uint32_t SETTINGS_VERSION = 2;
|
||||
static constexpr uint32_t SETTINGS_VERSION = 3;
|
||||
|
||||
struct Settings {
|
||||
struct Meta {
|
||||
@@ -96,6 +96,19 @@ class Persistence
|
||||
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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "./WindowManager.h"
|
||||
|
||||
#include "./Applets/System/AlignStick/AlignStickApplet.h"
|
||||
#include "./Applets/System/BatteryIcon/BatteryIconApplet.h"
|
||||
#include "./Applets/System/Logo/LogoApplet.h"
|
||||
#include "./Applets/System/Menu/MenuApplet.h"
|
||||
@@ -98,6 +99,38 @@ void InkHUD::WindowManager::nextTile()
|
||||
userTiles.at(settings->userTiles.focused)->requestHighlight();
|
||||
}
|
||||
|
||||
// Focus on a different tile but decrement index
|
||||
void InkHUD::WindowManager::prevTile()
|
||||
{
|
||||
// Close the menu applet if open
|
||||
// We don't *really* want to do this, but it simplifies handling *a lot*
|
||||
MenuApplet *menu = (MenuApplet *)inkhud->getSystemApplet("Menu");
|
||||
bool menuWasOpen = false;
|
||||
if (menu->isForeground()) {
|
||||
menu->sendToBackground();
|
||||
menuWasOpen = true;
|
||||
}
|
||||
|
||||
// Swap to next tile
|
||||
if (settings->userTiles.focused == 0)
|
||||
settings->userTiles.focused = settings->userTiles.count - 1;
|
||||
else
|
||||
settings->userTiles.focused--;
|
||||
|
||||
// Make sure that we don't get stuck on the placeholder tile
|
||||
refocusTile();
|
||||
|
||||
if (menuWasOpen)
|
||||
menu->show(userTiles.at(settings->userTiles.focused));
|
||||
|
||||
// Ask the tile to draw an indicator showing which tile is now focused
|
||||
// Requests a render
|
||||
// We only draw this indicator if the device uses an aux button to switch tiles.
|
||||
// Assume aux button is used to switch tiles if the "next tile" menu item is hidden
|
||||
if (!settings->optionalMenuItems.nextTile)
|
||||
userTiles.at(settings->userTiles.focused)->requestHighlight();
|
||||
}
|
||||
|
||||
// Show the menu (on the the focused tile)
|
||||
// The applet previously displayed there will be restored once the menu closes
|
||||
void InkHUD::WindowManager::openMenu()
|
||||
@@ -106,6 +139,15 @@ void InkHUD::WindowManager::openMenu()
|
||||
menu->show(userTiles.at(settings->userTiles.focused));
|
||||
}
|
||||
|
||||
// Bring the AlignStick applet to the foreground
|
||||
void InkHUD::WindowManager::openAlignStick()
|
||||
{
|
||||
if (settings->joystick.enabled) {
|
||||
AlignStickApplet *alignStick = (AlignStickApplet *)inkhud->getSystemApplet("AlignStick");
|
||||
alignStick->bringToForeground();
|
||||
}
|
||||
}
|
||||
|
||||
// On the currently focussed tile: cycle to the next available user applet
|
||||
// Applets available for this must be activated, and not already displayed on another tile
|
||||
void InkHUD::WindowManager::nextApplet()
|
||||
@@ -155,6 +197,59 @@ void InkHUD::WindowManager::nextApplet()
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FAST); // bringToForeground already requested, but we're manually forcing FAST
|
||||
}
|
||||
|
||||
// On the currently focussed tile: cycle to the previous available user applet
|
||||
// Applets available for this must be activated, and not already displayed on another tile
|
||||
void InkHUD::WindowManager::prevApplet()
|
||||
{
|
||||
Tile *t = userTiles.at(settings->userTiles.focused);
|
||||
|
||||
// Abort if zero applets available
|
||||
// nullptr means WindowManager::refocusTile determined that there were no available applets
|
||||
if (!t->getAssignedApplet())
|
||||
return;
|
||||
|
||||
// Find the index of the applet currently shown on the tile
|
||||
uint8_t appletIndex = -1;
|
||||
for (uint8_t i = 0; i < inkhud->userApplets.size(); i++) {
|
||||
if (inkhud->userApplets.at(i) == t->getAssignedApplet()) {
|
||||
appletIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirm that we did find the applet
|
||||
assert(appletIndex != (uint8_t)-1);
|
||||
|
||||
// Iterate forward through the WindowManager::applets, looking for the previous valid applet
|
||||
Applet *prevValidApplet = nullptr;
|
||||
for (uint8_t i = 1; i < inkhud->userApplets.size(); i++) {
|
||||
uint8_t newAppletIndex = 0;
|
||||
if (i > appletIndex)
|
||||
newAppletIndex = inkhud->userApplets.size() + appletIndex - i;
|
||||
else
|
||||
newAppletIndex = (appletIndex - i);
|
||||
Applet *a = inkhud->userApplets.at(newAppletIndex);
|
||||
|
||||
// Looking for an applet which is active (enabled by user), but currently in background
|
||||
if (a->isActive() && !a->isForeground()) {
|
||||
prevValidApplet = a;
|
||||
settings->userTiles.displayedUserApplet[settings->userTiles.focused] =
|
||||
newAppletIndex; // Remember this setting between boots!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirm that we found another applet
|
||||
if (!prevValidApplet)
|
||||
return;
|
||||
|
||||
// Hide old applet, show new applet
|
||||
t->getAssignedApplet()->sendToBackground();
|
||||
t->assignApplet(prevValidApplet);
|
||||
prevValidApplet->bringToForeground();
|
||||
inkhud->forceUpdate(EInk::UpdateTypes::FAST); // bringToForeground already requested, but we're manually forcing FAST
|
||||
}
|
||||
|
||||
// Rotate the display image by 90 degrees
|
||||
void InkHUD::WindowManager::rotate()
|
||||
{
|
||||
@@ -338,6 +433,8 @@ void InkHUD::WindowManager::createSystemApplets()
|
||||
addSystemApplet("Logo", new LogoApplet, new Tile);
|
||||
addSystemApplet("Pairing", new PairingApplet, new Tile);
|
||||
addSystemApplet("Tips", new TipsApplet, new Tile);
|
||||
if (settings->joystick.enabled)
|
||||
addSystemApplet("AlignStick", new AlignStickApplet, new Tile);
|
||||
|
||||
addSystemApplet("Menu", new MenuApplet, nullptr);
|
||||
|
||||
@@ -360,6 +457,8 @@ void InkHUD::WindowManager::placeSystemTiles()
|
||||
inkhud->getSystemApplet("Logo")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||
inkhud->getSystemApplet("Pairing")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||
inkhud->getSystemApplet("Tips")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||
if (settings->joystick.enabled)
|
||||
inkhud->getSystemApplet("AlignStick")->getTile()->setRegion(0, 0, inkhud->width(), inkhud->height());
|
||||
|
||||
inkhud->getSystemApplet("Notification")->getTile()->setRegion(0, 0, inkhud->width(), 20);
|
||||
|
||||
|
||||
@@ -28,8 +28,11 @@ class WindowManager
|
||||
// - call these to make stuff change
|
||||
|
||||
void nextTile();
|
||||
void prevTile();
|
||||
void openMenu();
|
||||
void openAlignStick();
|
||||
void nextApplet();
|
||||
void prevApplet();
|
||||
void rotate();
|
||||
void toggleBatteryIcon();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user