Amend back button handling, add "use as sleep screen" feature
This commit is contained in:
@@ -442,5 +442,7 @@ STR_UPTIME: "Uptime"
|
|||||||
STR_CHARGING: "Charging"
|
STR_CHARGING: "Charging"
|
||||||
STR_GATHERING_DATA: "Gathering data..."
|
STR_GATHERING_DATA: "Gathering data..."
|
||||||
STR_READING: "Reading..."
|
STR_READING: "Reading..."
|
||||||
|
STR_SET_SLEEP_SCREEN: "Set Sleep"
|
||||||
|
STR_SLEEP_SCREEN_SET: "Sleep screen updated!"
|
||||||
STR_WEATHER_MOON_INFO: "Moon"
|
STR_WEATHER_MOON_INFO: "Moon"
|
||||||
STR_WEATHER_SUN_INFO: "Sun"
|
STR_WEATHER_SUN_INFO: "Sun"
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <SdFat.h>
|
#include <SdFat.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#define SDCard SDCardManager::getInstance()
|
#define SDCard SDCardManager::getInstance()
|
||||||
|
|
||||||
@@ -138,6 +139,35 @@ bool HalStorage::openFileForWrite(const char* moduleName, const String& path, Ha
|
|||||||
|
|
||||||
bool HalStorage::removeDir(const char* path) { HAL_STORAGE_WRAPPED_CALL(removeDir, path); }
|
bool HalStorage::removeDir(const char* path) { HAL_STORAGE_WRAPPED_CALL(removeDir, path); }
|
||||||
|
|
||||||
|
bool HalStorage::copyFile(const char* moduleName, const std::string& srcPath, const char* dstPath) {
|
||||||
|
HalFile src, dst;
|
||||||
|
if (!openFileForRead(moduleName, srcPath, src)) return false;
|
||||||
|
if (!openFileForWrite(moduleName, dstPath, dst)) {
|
||||||
|
src.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
constexpr size_t BUF_SIZE = 4096;
|
||||||
|
auto* buf = new (std::nothrow) uint8_t[BUF_SIZE];
|
||||||
|
if (!buf) {
|
||||||
|
dst.close();
|
||||||
|
src.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ok = true;
|
||||||
|
while (src.available()) {
|
||||||
|
const auto bytesRead = src.read(buf, BUF_SIZE);
|
||||||
|
if (bytesRead <= 0) break;
|
||||||
|
if (dst.write(buf, bytesRead) != static_cast<size_t>(bytesRead)) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
dst.close();
|
||||||
|
src.close();
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
// HalFile implementation
|
// HalFile implementation
|
||||||
// Allow doing file operations while ensuring thread safety via HalStorage's mutex.
|
// Allow doing file operations while ensuring thread safety via HalStorage's mutex.
|
||||||
// Please keep the list below in sync with the HalFile.h header
|
// Please keep the list below in sync with the HalFile.h header
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class HalStorage {
|
|||||||
bool openFileForWrite(const char* moduleName, const std::string& path, HalFile& file);
|
bool openFileForWrite(const char* moduleName, const std::string& path, HalFile& file);
|
||||||
bool openFileForWrite(const char* moduleName, const String& path, HalFile& file);
|
bool openFileForWrite(const char* moduleName, const String& path, HalFile& file);
|
||||||
bool removeDir(const char* path);
|
bool removeDir(const char* path);
|
||||||
|
bool copyFile(const char* moduleName, const std::string& srcPath, const char* dstPath);
|
||||||
|
|
||||||
uint64_t sdTotalBytes() const;
|
uint64_t sdTotalBytes() const;
|
||||||
uint64_t sdUsedBytes();
|
uint64_t sdUsedBytes();
|
||||||
|
|||||||
@@ -5,9 +5,15 @@
|
|||||||
#include <HalStorage.h>
|
#include <HalStorage.h>
|
||||||
#include <I18n.h>
|
#include <I18n.h>
|
||||||
|
|
||||||
|
#include "../reader/ReaderUtils.h"
|
||||||
|
#include "CrossPointSettings.h"
|
||||||
#include "components/UITheme.h"
|
#include "components/UITheme.h"
|
||||||
#include "fontIds.h"
|
#include "fontIds.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr const char* SLEEP_BMP_PATH = "/sleep.bmp";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
BmpViewerActivity::BmpViewerActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, std::string path)
|
BmpViewerActivity::BmpViewerActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, std::string path)
|
||||||
: Activity("BmpViewer", renderer, mappedInput), filePath(std::move(path)) {}
|
: Activity("BmpViewer", renderer, mappedInput), filePath(std::move(path)) {}
|
||||||
|
|
||||||
@@ -49,7 +55,7 @@ void BmpViewerActivity::onEnter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. Prepare Rendering
|
// 4. Prepare Rendering
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", tr(STR_SET_SLEEP_SCREEN));
|
||||||
GUI.fillPopupProgress(renderer, popupRect, 50);
|
GUI.fillPopupProgress(renderer, popupRect, 50);
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
@@ -89,12 +95,44 @@ void BmpViewerActivity::onExit() {
|
|||||||
renderer.displayBuffer(HalDisplay::FULL_REFRESH);
|
renderer.displayBuffer(HalDisplay::FULL_REFRESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BmpViewerActivity::setAsSleepScreen() {
|
||||||
|
// Only copy if the source isn't already /sleep.bmp
|
||||||
|
if (filePath != SLEEP_BMP_PATH) {
|
||||||
|
if (!Storage.copyFile("BMP", filePath, SLEEP_BMP_PATH)) {
|
||||||
|
LOG_ERR("BMP", "Failed to copy %s to %s", filePath.c_str(), SLEEP_BMP_PATH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch sleep screen mode to CUSTOM so the copied image is used
|
||||||
|
SETTINGS.sleepScreen = CrossPointSettings::SLEEP_SCREEN_MODE::CUSTOM;
|
||||||
|
SETTINGS.saveToFile();
|
||||||
|
LOG_INF("BMP", "Set %s as sleep screen", filePath.c_str());
|
||||||
|
|
||||||
|
GUI.drawPopup(renderer, tr(STR_SLEEP_SCREEN_SET));
|
||||||
|
renderer.displayBuffer(HalDisplay::HALF_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
void BmpViewerActivity::loop() {
|
void BmpViewerActivity::loop() {
|
||||||
// Keep CPU awake/polling so 1st click works
|
// Keep CPU awake/polling so 1st click works
|
||||||
Activity::loop();
|
Activity::loop();
|
||||||
|
|
||||||
if (mappedInput.wasReleased(MappedInputManager::Button::Back)) {
|
// Long press BACK (1s+) goes to home screen
|
||||||
|
if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= ReaderUtils::GO_HOME_MS) {
|
||||||
onGoHome();
|
onGoHome();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Short press BACK returns to the calling activity
|
||||||
|
if (mappedInput.wasReleased(MappedInputManager::Button::Back) &&
|
||||||
|
mappedInput.getHeldTime() < ReaderUtils::GO_HOME_MS) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next/Right button: set this image as the sleep screen
|
||||||
|
if (mappedInput.wasReleased(MappedInputManager::Button::Right)) {
|
||||||
|
setAsSleepScreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,4 +16,5 @@ class BmpViewerActivity final : public Activity {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filePath;
|
std::string filePath;
|
||||||
|
void setAsSleepScreen();
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user