Cleanup of activities

This commit is contained in:
Dave Allie 2025-12-22 00:31:25 +11:00
parent 77c655fcf5
commit b39ce22e54
No known key found for this signature in database
GPG Key ID: F2FDDB3AD8D0276F
15 changed files with 57 additions and 45 deletions

View File

@ -1,8 +1,11 @@
#pragma once #pragma once
#include <InputManager.h>
#include <HardwareSerial.h>
#include <string>
#include <utility> #include <utility>
class InputManager;
class GfxRenderer; class GfxRenderer;
class Activity { class Activity {

View File

@ -1,6 +1,7 @@
#include "HomeActivity.h" #include "HomeActivity.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include <SD.h> #include <SD.h>
#include "config.h" #include "config.h"
@ -83,8 +84,8 @@ void HomeActivity::displayTaskLoop() {
void HomeActivity::render() const { void HomeActivity::render() const {
renderer.clearScreen(); renderer.clearScreen();
const auto pageWidth = GfxRenderer::getScreenWidth(); const auto pageWidth = renderer.getScreenWidth();
const auto pageHeight = GfxRenderer::getScreenHeight(); const auto pageHeight = renderer.getScreenHeight();
renderer.drawCenteredText(READER_FONT_ID, 10, "CrossPoint Reader", true, BOLD); renderer.drawCenteredText(READER_FONT_ID, 10, "CrossPoint Reader", true, BOLD);
// Draw selection // Draw selection

View File

@ -1,8 +1,10 @@
#include "CrossPointWebServerActivity.h" #include "CrossPointWebServerActivity.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include <WiFi.h> #include <WiFi.h>
#include "WifiSelectionActivity.h"
#include "config.h" #include "config.h"
void CrossPointWebServerActivity::taskTrampoline(void* param) { void CrossPointWebServerActivity::taskTrampoline(void* param) {

View File

@ -7,10 +7,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "../Activity.h"
#include "WifiSelectionActivity.h"
#include "activities/ActivityWithSubactivity.h" #include "activities/ActivityWithSubactivity.h"
#include "server/CrossPointWebServer.h" #include "network/CrossPointWebServer.h"
// Web server activity states // Web server activity states
enum class WebServerActivityState { enum class WebServerActivityState {

View File

@ -6,6 +6,7 @@
#include <map> #include <map>
#include "WifiCredentialStore.h" #include "WifiCredentialStore.h"
#include "activities/util/KeyboardEntryActivity.h"
#include "config.h" #include "config.h"
void WifiSelectionActivity::taskTrampoline(void* param) { void WifiSelectionActivity::taskTrampoline(void* param) {
@ -18,8 +19,10 @@ void WifiSelectionActivity::onEnter() {
renderingMutex = xSemaphoreCreateMutex(); renderingMutex = xSemaphoreCreateMutex();
// Load saved WiFi credentials // Load saved WiFi credentials - SD card operations need lock as we use SPI for both
xSemaphoreTake(renderingMutex, portMAX_DELAY);
WIFI_STORE.loadFromFile(); WIFI_STORE.loadFromFile();
xSemaphoreGive(renderingMutex);
// Reset state // Reset state
selectedNetworkIndex = 0; selectedNetworkIndex = 0;
@ -32,7 +35,6 @@ void WifiSelectionActivity::onEnter() {
usedSavedPassword = false; usedSavedPassword = false;
savePromptSelection = 0; savePromptSelection = 0;
forgetPromptSelection = 0; forgetPromptSelection = 0;
keyboard.reset();
// Trigger first update to show scanning message // Trigger first update to show scanning message
updateRequired = true; updateRequired = true;
@ -98,7 +100,7 @@ void WifiSelectionActivity::startWifiScan() {
} }
void WifiSelectionActivity::processWifiScanResults() { void WifiSelectionActivity::processWifiScanResults() {
int16_t scanResult = WiFi.scanComplete(); const int16_t scanResult = WiFi.scanComplete();
if (scanResult == WIFI_SCAN_RUNNING) { if (scanResult == WIFI_SCAN_RUNNING) {
// Scan still in progress // Scan still in progress
@ -117,7 +119,7 @@ void WifiSelectionActivity::processWifiScanResults() {
for (int i = 0; i < scanResult; i++) { for (int i = 0; i < scanResult; i++) {
std::string ssid = WiFi.SSID(i).c_str(); std::string ssid = WiFi.SSID(i).c_str();
int32_t rssi = WiFi.RSSI(i); const int32_t rssi = WiFi.RSSI(i);
// Skip hidden networks (empty SSID) // Skip hidden networks (empty SSID)
if (ssid.empty()) { if (ssid.empty()) {
@ -154,7 +156,7 @@ void WifiSelectionActivity::processWifiScanResults() {
updateRequired = true; updateRequired = true;
} }
void WifiSelectionActivity::selectNetwork(int index) { void WifiSelectionActivity::selectNetwork(const int index) {
if (index < 0 || index >= static_cast<int>(networks.size())) { if (index < 0 || index >= static_cast<int>(networks.size())) {
return; return;
} }
@ -180,11 +182,11 @@ void WifiSelectionActivity::selectNetwork(int index) {
if (selectedRequiresPassword) { if (selectedRequiresPassword) {
// Show password entry // Show password entry
state = WifiSelectionState::PASSWORD_ENTRY; state = WifiSelectionState::PASSWORD_ENTRY;
keyboard.reset(new KeyboardEntryActivity(renderer, inputManager, "Enter WiFi Password", enterNewActivity(new KeyboardEntryActivity(renderer, inputManager, "Enter WiFi Password",
"", // No initial text "", // No initial text
64, // Max password length 64, // Max password length
false // Show password by default (hard keyboard to use) false // Show password by default (hard keyboard to use)
)); ));
updateRequired = true; updateRequired = true;
} else { } else {
// Connect directly for open networks // Connect directly for open networks
@ -202,8 +204,8 @@ void WifiSelectionActivity::attemptConnection() {
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
// Get password from keyboard if we just entered it // Get password from keyboard if we just entered it
if (keyboard && !usedSavedPassword) { if (subActivity && !usedSavedPassword) {
enteredPassword = keyboard->getText(); enteredPassword = static_cast<KeyboardEntryActivity*>(subActivity.get())->getText();
} }
if (selectedRequiresPassword && !enteredPassword.empty()) { if (selectedRequiresPassword && !enteredPassword.empty()) {
@ -218,7 +220,7 @@ void WifiSelectionActivity::checkConnectionStatus() {
return; return;
} }
wl_status_t status = WiFi.status(); const wl_status_t status = WiFi.status();
if (status == WL_CONNECTED) { if (status == WL_CONNECTED) {
// Successfully connected // Successfully connected
@ -275,7 +277,8 @@ void WifiSelectionActivity::loop() {
} }
// Handle password entry state // Handle password entry state
if (state == WifiSelectionState::PASSWORD_ENTRY && keyboard) { if (state == WifiSelectionState::PASSWORD_ENTRY && subActivity) {
const auto keyboard = static_cast<KeyboardEntryActivity*>(subActivity.get());
keyboard->handleInput(); keyboard->handleInput();
if (keyboard->isComplete()) { if (keyboard->isComplete()) {
@ -285,7 +288,7 @@ void WifiSelectionActivity::loop() {
if (keyboard->isCancelled()) { if (keyboard->isCancelled()) {
state = WifiSelectionState::NETWORK_LIST; state = WifiSelectionState::NETWORK_LIST;
keyboard.reset(); exitActivity();
updateRequired = true; updateRequired = true;
return; return;
} }
@ -309,7 +312,9 @@ void WifiSelectionActivity::loop() {
} else if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) { } else if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
if (savePromptSelection == 0) { if (savePromptSelection == 0) {
// User chose "Yes" - save the password // User chose "Yes" - save the password
xSemaphoreTake(renderingMutex, portMAX_DELAY);
WIFI_STORE.addCredential(selectedSSID, enteredPassword); WIFI_STORE.addCredential(selectedSSID, enteredPassword);
xSemaphoreGive(renderingMutex);
} }
// Complete - parent will start web server // Complete - parent will start web server
onComplete(true); onComplete(true);
@ -335,7 +340,9 @@ void WifiSelectionActivity::loop() {
} else if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) { } else if (inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
if (forgetPromptSelection == 0) { if (forgetPromptSelection == 0) {
// User chose "Yes" - forget the network // User chose "Yes" - forget the network
xSemaphoreTake(renderingMutex, portMAX_DELAY);
WIFI_STORE.removeCredential(selectedSSID); WIFI_STORE.removeCredential(selectedSSID);
xSemaphoreGive(renderingMutex);
// Update the network list to reflect the change // Update the network list to reflect the change
const auto network = find_if(networks.begin(), networks.end(), const auto network = find_if(networks.begin(), networks.end(),
[this](const WifiNetworkInfo& net) { return net.ssid == selectedSSID; }); [this](const WifiNetworkInfo& net) { return net.ssid == selectedSSID; });
@ -410,15 +417,18 @@ void WifiSelectionActivity::loop() {
} }
} }
std::string WifiSelectionActivity::getSignalStrengthIndicator(int32_t rssi) const { std::string WifiSelectionActivity::getSignalStrengthIndicator(const int32_t rssi) const {
// Convert RSSI to signal bars representation // Convert RSSI to signal bars representation
if (rssi >= -50) { if (rssi >= -50) {
return "||||"; // Excellent return "||||"; // Excellent
} else if (rssi >= -60) { }
if (rssi >= -60) {
return "||| "; // Good return "||| "; // Good
} else if (rssi >= -70) { }
if (rssi >= -70) {
return "|| "; // Fair return "|| "; // Fair
} else if (rssi >= -80) { }
if (rssi >= -80) {
return "| "; // Weak return "| "; // Weak
} }
return " "; // Very weak return " "; // Very weak
@ -484,8 +494,8 @@ void WifiSelectionActivity::renderNetworkList() const {
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press OK to scan again", true, REGULAR); renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, "Press OK to scan again", true, REGULAR);
} else { } else {
// Calculate how many networks we can display // Calculate how many networks we can display
const int startY = 60; constexpr int startY = 60;
const int lineHeight = 25; constexpr int lineHeight = 25;
const int maxVisibleNetworks = (pageHeight - startY - 40) / lineHeight; const int maxVisibleNetworks = (pageHeight - startY - 40) / lineHeight;
// Calculate scroll offset to keep selected item visible // Calculate scroll offset to keep selected item visible
@ -557,8 +567,8 @@ void WifiSelectionActivity::renderPasswordEntry() const {
renderer.drawCenteredText(UI_FONT_ID, 38, networkInfo.c_str(), true, REGULAR); renderer.drawCenteredText(UI_FONT_ID, 38, networkInfo.c_str(), true, REGULAR);
// Draw keyboard // Draw keyboard
if (keyboard) { if (subActivity) {
keyboard->render(58); static_cast<KeyboardEntryActivity*>(subActivity.get())->render(58);
} }
} }
@ -593,7 +603,7 @@ void WifiSelectionActivity::renderConnected() const {
} }
renderer.drawCenteredText(UI_FONT_ID, top + 10, ssidInfo.c_str(), true, REGULAR); renderer.drawCenteredText(UI_FONT_ID, top + 10, ssidInfo.c_str(), true, REGULAR);
std::string ipInfo = "IP Address: " + connectedIP; const std::string ipInfo = "IP Address: " + connectedIP;
renderer.drawCenteredText(UI_FONT_ID, top + 40, ipInfo.c_str(), true, REGULAR); renderer.drawCenteredText(UI_FONT_ID, top + 40, ipInfo.c_str(), true, REGULAR);
renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Press any button to continue", true, REGULAR); renderer.drawCenteredText(SMALL_FONT_ID, pageHeight - 30, "Press any button to continue", true, REGULAR);
@ -617,9 +627,9 @@ void WifiSelectionActivity::renderSavePrompt() const {
// Draw Yes/No buttons // Draw Yes/No buttons
const int buttonY = top + 80; const int buttonY = top + 80;
const int buttonWidth = 60; constexpr int buttonWidth = 60;
const int buttonSpacing = 30; constexpr int buttonSpacing = 30;
const int totalWidth = buttonWidth * 2 + buttonSpacing; constexpr int totalWidth = buttonWidth * 2 + buttonSpacing;
const int startX = (pageWidth - totalWidth) / 2; const int startX = (pageWidth - totalWidth) / 2;
// Draw "Yes" button // Draw "Yes" button
@ -667,9 +677,9 @@ void WifiSelectionActivity::renderForgetPrompt() const {
// Draw Yes/No buttons // Draw Yes/No buttons
const int buttonY = top + 80; const int buttonY = top + 80;
const int buttonWidth = 60; constexpr int buttonWidth = 60;
const int buttonSpacing = 30; constexpr int buttonSpacing = 30;
const int totalWidth = buttonWidth * 2 + buttonSpacing; constexpr int totalWidth = buttonWidth * 2 + buttonSpacing;
const int startX = (pageWidth - totalWidth) / 2; const int startX = (pageWidth - totalWidth) / 2;
// Draw "Yes" button // Draw "Yes" button

View File

@ -9,8 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "../Activity.h" #include "activities/ActivityWithSubactivity.h"
#include "../util/KeyboardEntryActivity.h"
// Structure to hold WiFi network information // Structure to hold WiFi network information
struct WifiNetworkInfo { struct WifiNetworkInfo {
@ -43,7 +42,7 @@ enum class WifiSelectionState {
* *
* The onComplete callback receives true if connected successfully, false if cancelled. * The onComplete callback receives true if connected successfully, false if cancelled.
*/ */
class WifiSelectionActivity final : public Activity { class WifiSelectionActivity final : public ActivityWithSubactivity {
TaskHandle_t displayTaskHandle = nullptr; TaskHandle_t displayTaskHandle = nullptr;
SemaphoreHandle_t renderingMutex = nullptr; SemaphoreHandle_t renderingMutex = nullptr;
bool updateRequired = false; bool updateRequired = false;
@ -56,9 +55,6 @@ class WifiSelectionActivity final : public Activity {
std::string selectedSSID; std::string selectedSSID;
bool selectedRequiresPassword = false; bool selectedRequiresPassword = false;
// On-screen keyboard for password entry
std::unique_ptr<KeyboardEntryActivity> keyboard;
// Connection result // Connection result
std::string connectedIP; std::string connectedIP;
std::string connectionError; std::string connectionError;
@ -98,7 +94,7 @@ class WifiSelectionActivity final : public Activity {
public: public:
explicit WifiSelectionActivity(GfxRenderer& renderer, InputManager& inputManager, explicit WifiSelectionActivity(GfxRenderer& renderer, InputManager& inputManager,
const std::function<void(bool connected)>& onComplete) const std::function<void(bool connected)>& onComplete)
: Activity("WifiSelection", renderer, inputManager), onComplete(onComplete) {} : ActivityWithSubactivity("WifiSelection", renderer, inputManager), onComplete(onComplete) {}
void onEnter() override; void onEnter() override;
void onExit() override; void onExit() override;
void loop() override; void loop() override;

View File

@ -2,6 +2,7 @@
#include <Epub/Page.h> #include <Epub/Page.h>
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include <SD.h> #include <SD.h>
#include "Battery.h" #include "Battery.h"

View File

@ -1,6 +1,7 @@
#include "EpubReaderChapterSelectionActivity.h" #include "EpubReaderChapterSelectionActivity.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include <SD.h> #include <SD.h>
#include "config.h" #include "config.h"

View File

@ -1,6 +1,7 @@
#include "FileSelectionActivity.h" #include "FileSelectionActivity.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include <SD.h> #include <SD.h>
#include "config.h" #include "config.h"

View File

@ -1,6 +1,7 @@
#include "SettingsActivity.h" #include "SettingsActivity.h"
#include <GfxRenderer.h> #include <GfxRenderer.h>
#include <InputManager.h>
#include "CrossPointSettings.h" #include "CrossPointSettings.h"
#include "config.h" #include "config.h"

View File

@ -2,8 +2,6 @@
#include <WebServer.h> #include <WebServer.h>
#include <functional>
#include <string>
#include <vector> #include <vector>
// Structure to hold file information // Structure to hold file information