mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 19:02:00 +00:00
feat: flashlight - the whole screen white at full brightness
L2: a Flashlight app on Home (a lightbulb icon added to the fonts): a white layer over everything, the backlight at 100 %, no auto-off; a tap, the side or the top button puts it away and the brightness back. L1: Tools > System > Flashlight, the whole OLED lit at full contrast until a key. Not on e-ink. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
// Tools › Flashlight: the whole panel lit at full brightness, kept on (no
|
||||
// auto-off) until a key. Not on e-ink, which gives no light. Leaving it, by
|
||||
// a key or anything that changes the screen, puts the brightness back
|
||||
// (UITask::setCurrScreen).
|
||||
// Included by UITask.cpp.
|
||||
|
||||
class FlashlightScreen : public UIScreen {
|
||||
UITask* _task;
|
||||
|
||||
public:
|
||||
FlashlightScreen(UITask* task) : _task(task) {}
|
||||
|
||||
int render(DisplayDriver& display) override {
|
||||
display.setBrightness(4);
|
||||
display.setColor(DisplayDriver::LIGHT);
|
||||
display.fillRect(0, 0, display.width(), display.height());
|
||||
return 1000;
|
||||
}
|
||||
|
||||
bool handleInput(char c) override {
|
||||
(void)c;
|
||||
_task->leaveTool();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
enum Action {
|
||||
ACT_NEARBY, ACT_LIVESHARE, ACT_TRAIL, ACT_LOCATOR, ACT_COMPASS,
|
||||
ACT_BOT, ACT_AUTOADVERT, ACT_REPEATER, ACT_ADMIN,
|
||||
ACT_CLOCK, ACT_RINGTONE
|
||||
ACT_CLOCK, ACT_RINGTONE, ACT_FLASHLIGHT
|
||||
#if defined(PIN_GPIO1)
|
||||
, ACT_GPIO
|
||||
#endif
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
case ACT_ADMIN: task->pickAdminTarget(); break; // Admin is remote-only: pick a node first
|
||||
case ACT_CLOCK: task->gotoClockTools(); break;
|
||||
case ACT_RINGTONE: task->gotoRingtoneEditor(); break;
|
||||
case ACT_FLASHLIGHT: task->gotoFlashlight(); break;
|
||||
#if defined(PIN_GPIO1)
|
||||
case ACT_GPIO: task->gotoGpioScreen(); break;
|
||||
#endif
|
||||
@@ -135,6 +136,9 @@ const ToolsScreen::Tool ToolsScreen::COMMS_TOOLS[] = {
|
||||
const ToolsScreen::Tool ToolsScreen::SYSTEM_TOOLS[] = {
|
||||
{ "Clock Tools", ACT_CLOCK },
|
||||
{ "Ringtone Editor", ACT_RINGTONE },
|
||||
#if !defined(EINK_DISPLAY_MODEL) // Features::IS_EINK: no light to give
|
||||
{ "Flashlight", ACT_FLASHLIGHT },
|
||||
#endif
|
||||
#if defined(PIN_GPIO1)
|
||||
{ "GPIO", ACT_GPIO },
|
||||
#endif
|
||||
|
||||
@@ -105,6 +105,7 @@ static const telemetry::Style L1_INFO = { "\xc2\xb0", true, false, 5 };
|
||||
#if defined(PIN_GPIO1)
|
||||
#include "GpioScreen.h"
|
||||
#endif
|
||||
#include "FlashlightScreen.h"
|
||||
#include "ToolsScreen.h"
|
||||
#include "CalendarView.h" // the month under a tall clock, Clock tools › Calendar
|
||||
#include "ClockToolsScreen.h" // Alarm / Timer / Stopwatch / Calendar (Clock page › Enter)
|
||||
@@ -226,6 +227,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
status_screen = new StatusScreen(this);
|
||||
repeater_screen = new RepeaterScreen(this);
|
||||
clock_tools = new ClockToolsScreen(this, node_prefs);
|
||||
if (!Features::IS_EINK) flashlight = new FlashlightScreen(this);
|
||||
#if defined(PIN_GPIO1)
|
||||
gpio_screen = new GpioScreen(this, node_prefs);
|
||||
#endif
|
||||
@@ -273,6 +275,7 @@ void UITask::gotoStatusScreen(uint8_t tab) {
|
||||
}
|
||||
void UITask::gotoRepeaterScreen() { setCurrScreen(repeater_screen); }
|
||||
void UITask::gotoClockTools() { setCurrScreen(clock_tools); }
|
||||
void UITask::gotoFlashlight() { setCurrScreen(flashlight); }
|
||||
void UITask::gotoGpioScreen() {
|
||||
#if defined(PIN_GPIO1)
|
||||
setCurrScreen(gpio_screen);
|
||||
@@ -729,6 +732,7 @@ void UITask::setCurrScreen(UIScreen* c) {
|
||||
// begin()) stays nullptr thanks to the in-class initialisers. Bail here so
|
||||
// that mistake is an inert no-op instead of a null deref in render()/poll().
|
||||
if (!c) return;
|
||||
if (flashlight && curr == flashlight && c != flashlight) applyBrightness(); // its full brightness goes with it
|
||||
curr = c;
|
||||
c->onShow(); // central per-visit reset hook (see UIScreen::onShow)
|
||||
_next_refresh = 0;
|
||||
@@ -1440,6 +1444,10 @@ void UITask::loop() {
|
||||
_auto_off = millis() + AUTO_OFF_MILLIS;
|
||||
}
|
||||
#endif
|
||||
if (flashlight && curr == flashlight) { // a torch stays lit; after it, the usual timeout
|
||||
uint32_t aoff = autoOffMillis();
|
||||
_auto_off = millis() + (aoff > 0 ? aoff : AUTO_OFF_MILLIS);
|
||||
}
|
||||
if (!_locked && autoOffMillis() > 0 && (int32_t)(millis() - _auto_off) >= 0 && !isRinging()) {
|
||||
_display->turnOff();
|
||||
#ifdef PIN_LED
|
||||
|
||||
@@ -131,6 +131,7 @@ class UITask : public UITaskBase, public UiCoreHost {
|
||||
UIScreen* status_screen = nullptr; // Home › Status (radio, GPS, sky, power, mesh, system)
|
||||
UIScreen* repeater_screen = nullptr;
|
||||
UIScreen* clock_tools = nullptr;
|
||||
UIScreen* flashlight = nullptr; // not on e-ink (Features::IS_EINK)
|
||||
#if defined(PIN_GPIO1)
|
||||
UIScreen* gpio_screen = nullptr;
|
||||
#endif
|
||||
@@ -386,6 +387,7 @@ public:
|
||||
void gotoRepeaterScreen();
|
||||
void gotoGpioScreen(); // no-op on boards without user GPIO pins (see PIN_GPIO1)
|
||||
void gotoClockTools(); // Alarm / Timer / Stopwatch (from the home Clock page)
|
||||
void gotoFlashlight();
|
||||
// Wake the display for an alarm/timer ring (force an immediate refresh).
|
||||
void wakeForAlarm();
|
||||
// Clear any active alert overlay early (alarm dismiss).
|
||||
|
||||
Reference in New Issue
Block a user