mirror of
https://github.com/pelgraine/Meck.git
synced 2026-03-28 17:42:44 +01:00
213 lines
7.8 KiB
C++
213 lines
7.8 KiB
C++
#pragma once
|
|
|
|
#include <MeshCore.h>
|
|
#include <helpers/ui/DisplayDriver.h>
|
|
#include <helpers/ui/UIScreen.h>
|
|
#include <helpers/SensorManager.h>
|
|
#include <helpers/BaseSerialInterface.h>
|
|
#include <Arduino.h>
|
|
#include <helpers/sensors/LPPDataHelpers.h>
|
|
|
|
#ifndef LED_STATE_ON
|
|
#define LED_STATE_ON 1
|
|
#endif
|
|
|
|
#ifdef PIN_BUZZER
|
|
#include <helpers/ui/buzzer.h>
|
|
#endif
|
|
#ifdef PIN_VIBRATION
|
|
#include <helpers/ui/GenericVibration.h>
|
|
#endif
|
|
|
|
#include "../AbstractUITask.h"
|
|
#include "../NodePrefs.h"
|
|
|
|
#ifdef HAS_4G_MODEM
|
|
#include "SMSScreen.h"
|
|
#endif
|
|
|
|
#ifdef MECK_WEB_READER
|
|
#include "WebReaderScreen.h"
|
|
#endif
|
|
|
|
// MapScreen.h included in UITask.cpp and main.cpp only (PNGdec headers
|
|
// conflict with BLE if pulled into the global include chain)
|
|
|
|
class UITask : public AbstractUITask {
|
|
DisplayDriver* _display;
|
|
SensorManager* _sensors;
|
|
#ifdef PIN_BUZZER
|
|
genericBuzzer buzzer;
|
|
#endif
|
|
#ifdef PIN_VIBRATION
|
|
GenericVibration vibration;
|
|
#endif
|
|
unsigned long _next_refresh, _auto_off;
|
|
unsigned long _kb_flash_off_at; // Keyboard flash turn-off timer
|
|
#ifdef HAS_4G_MODEM
|
|
bool _incomingCallRinging; // Currently ringing (incoming call)
|
|
unsigned long _nextCallFlash; // Next LED toggle time
|
|
bool _callFlashState; // Current LED state during ring
|
|
#endif
|
|
NodePrefs* _node_prefs;
|
|
char _alert[80];
|
|
unsigned long _alert_expiry;
|
|
int _msgcount;
|
|
unsigned long ui_started_at, next_batt_chck;
|
|
uint8_t _low_batt_count = 0; // Consecutive low-voltage readings for debounce
|
|
int next_backlight_btn_check = 0;
|
|
#ifdef PIN_STATUS_LED
|
|
int led_state = 0;
|
|
int next_led_change = 0;
|
|
int last_led_increment = 0;
|
|
#endif
|
|
|
|
#ifdef PIN_USER_BTN_ANA
|
|
unsigned long _analogue_pin_read_millis = millis();
|
|
#endif
|
|
|
|
UIScreen* splash;
|
|
UIScreen* home;
|
|
UIScreen* msg_preview;
|
|
UIScreen* channel_screen; // Channel message history screen
|
|
UIScreen* contacts_screen; // Contacts list screen
|
|
UIScreen* text_reader; // *** NEW: Text reader screen ***
|
|
UIScreen* notes_screen; // Notes editor screen
|
|
UIScreen* settings_screen; // Settings/onboarding screen
|
|
UIScreen* audiobook_screen; // Audiobook player screen (null if not available)
|
|
#ifdef HAS_4G_MODEM
|
|
UIScreen* sms_screen; // SMS messaging screen (4G variant only)
|
|
#endif
|
|
UIScreen* repeater_admin; // Repeater admin screen
|
|
UIScreen* discovery_screen; // Node discovery scan screen
|
|
#ifdef MECK_WEB_READER
|
|
UIScreen* web_reader; // Web reader screen (lazy-init, WiFi required)
|
|
#endif
|
|
UIScreen* map_screen; // Map tile screen (GPS + SD card tiles)
|
|
UIScreen* curr;
|
|
|
|
void userLedHandler();
|
|
|
|
// Button action handlers
|
|
char checkDisplayOn(char c);
|
|
char handleLongPress(char c);
|
|
char handleDoubleClick(char c);
|
|
char handleTripleClick(char c);
|
|
|
|
void setCurrScreen(UIScreen* c);
|
|
|
|
public:
|
|
|
|
UITask(mesh::MainBoard* board, BaseSerialInterface* serial) : AbstractUITask(board, serial), _display(NULL), _sensors(NULL) {
|
|
next_batt_chck = _next_refresh = 0;
|
|
_kb_flash_off_at = 0;
|
|
#ifdef HAS_4G_MODEM
|
|
_incomingCallRinging = false;
|
|
_nextCallFlash = 0;
|
|
_callFlashState = false;
|
|
#endif
|
|
ui_started_at = 0;
|
|
curr = NULL;
|
|
}
|
|
void begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs);
|
|
|
|
void gotoHomeScreen();
|
|
void gotoChannelScreen(); // Navigate to channel message screen
|
|
void gotoContactsScreen(); // Navigate to contacts list
|
|
void gotoTextReader(); // *** NEW: Navigate to text reader ***
|
|
void gotoNotesScreen(); // Navigate to notes editor
|
|
void gotoSettingsScreen(); // Navigate to settings
|
|
void gotoOnboarding(); // Navigate to settings in onboarding mode
|
|
void gotoAudiobookPlayer(); // Navigate to audiobook player
|
|
void gotoRepeaterAdmin(int contactIdx); // Navigate to repeater admin
|
|
void gotoDiscoveryScreen(); // Navigate to node discovery scan
|
|
#if HAS_GPS
|
|
void gotoMapScreen(); // Navigate to map tile screen
|
|
#endif
|
|
#ifdef MECK_WEB_READER
|
|
void gotoWebReader(); // Navigate to web reader (browser)
|
|
#endif
|
|
#ifdef HAS_4G_MODEM
|
|
void gotoSMSScreen();
|
|
bool isOnSMSScreen() const { return curr == sms_screen; }
|
|
SMSScreen* getSMSScreen() const { return (SMSScreen*)sms_screen; }
|
|
#endif
|
|
void showAlert(const char* text, int duration_millis) override;
|
|
void forceRefresh() override { _next_refresh = 100; }
|
|
// Wake display and extend auto-off timer. Call this when handling keys
|
|
// outside of injectKey() to prevent display auto-off during direct input.
|
|
void keepAlive() {
|
|
if (_display != NULL && !_display->isOn()) _display->turnOn();
|
|
_auto_off = millis() + 15000; // matches AUTO_OFF_MILLIS default
|
|
}
|
|
int getMsgCount() const { return _msgcount; }
|
|
int getUnreadMsgCount() const; // Per-channel unread tracking (standalone)
|
|
bool hasDisplay() const { return _display != NULL; }
|
|
bool isButtonPressed() const;
|
|
bool isOnChannelScreen() const { return curr == channel_screen; }
|
|
bool isOnContactsScreen() const { return curr == contacts_screen; }
|
|
bool isOnTextReader() const { return curr == text_reader; } // *** NEW ***
|
|
bool isOnNotesScreen() const { return curr == notes_screen; }
|
|
bool isOnSettingsScreen() const { return curr == settings_screen; }
|
|
bool isOnAudiobookPlayer() const { return curr == audiobook_screen; }
|
|
bool isOnRepeaterAdmin() const { return curr == repeater_admin; }
|
|
bool isOnDiscoveryScreen() const { return curr == discovery_screen; }
|
|
bool isOnMapScreen() const { return curr == map_screen; }
|
|
#ifdef MECK_WEB_READER
|
|
bool isOnWebReader() const { return curr == web_reader; }
|
|
#endif
|
|
|
|
#ifdef MECK_AUDIO_VARIANT
|
|
// Check if audio is playing/paused in the background (for status indicators)
|
|
bool isAudioPlayingInBackground() const;
|
|
bool isAudioPausedInBackground() const;
|
|
#endif
|
|
uint8_t getChannelScreenViewIdx() const;
|
|
|
|
void toggleBuzzer();
|
|
bool getGPSState();
|
|
void toggleGPS();
|
|
|
|
// Check if home screen is in an editing mode (e.g. UTC offset editor)
|
|
bool isEditingHomeScreen() const;
|
|
|
|
// Inject a key press from external source (e.g., keyboard)
|
|
void injectKey(char c);
|
|
|
|
// Add a sent message to the channel screen history
|
|
void addSentChannelMessage(uint8_t channel_idx, const char* sender, const char* text) override;
|
|
|
|
// Mark channel as read when BLE companion app syncs messages
|
|
void markChannelReadFromBLE(uint8_t channel_idx) override;
|
|
|
|
// Repeater admin callbacks
|
|
void onAdminLoginResult(bool success, uint8_t permissions, uint32_t server_time) override;
|
|
void onAdminCliResponse(const char* from_name, const char* text) override;
|
|
void onAdminTelemetryResult(const uint8_t* data, uint8_t len) override;
|
|
|
|
// Get current screen for checking state
|
|
UIScreen* getCurrentScreen() const { return curr; }
|
|
UIScreen* getMsgPreviewScreen() const { return msg_preview; }
|
|
UIScreen* getTextReaderScreen() const { return text_reader; } // *** NEW ***
|
|
UIScreen* getNotesScreen() const { return notes_screen; }
|
|
UIScreen* getContactsScreen() const { return contacts_screen; }
|
|
UIScreen* getChannelScreen() const { return channel_screen; }
|
|
UIScreen* getSettingsScreen() const { return settings_screen; }
|
|
UIScreen* getAudiobookScreen() const { return audiobook_screen; }
|
|
void setAudiobookScreen(UIScreen* s) { audiobook_screen = s; }
|
|
UIScreen* getRepeaterAdminScreen() const { return repeater_admin; }
|
|
UIScreen* getDiscoveryScreen() const { return discovery_screen; }
|
|
UIScreen* getMapScreen() const { return map_screen; }
|
|
#ifdef MECK_WEB_READER
|
|
UIScreen* getWebReaderScreen() const { return web_reader; }
|
|
#endif
|
|
|
|
// from AbstractUITask
|
|
void msgRead(int msgcount) override;
|
|
void newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount,
|
|
const uint8_t* path = nullptr, int8_t snr = 0) override;
|
|
void notify(UIEventType t = UIEventType::none) override;
|
|
void loop() override;
|
|
|
|
void shutdown(bool restart = false);
|
|
}; |