mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
Compare commits
2 Commits
bf145817eb
...
18e14d0327
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18e14d0327 | ||
|
|
6192b979bc |
@ -419,11 +419,11 @@ bool Epub::generateCoverBmp(bool cropped) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Epub::getThumbBmpPath(int height) const { return cachePath + "/thumb_" + std::to_string(height) + ".bmp"; }
|
||||
std::string Epub::getThumbBmpPath() const { return cachePath + "/thumb.bmp"; }
|
||||
|
||||
bool Epub::generateThumbBmp(int height) const {
|
||||
bool Epub::generateThumbBmp() const {
|
||||
// Already generated, return true
|
||||
if (SdMan.exists(getThumbBmpPath(height).c_str())) {
|
||||
if (SdMan.exists(getThumbBmpPath().c_str())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -455,14 +455,14 @@ bool Epub::generateThumbBmp(int height) const {
|
||||
}
|
||||
|
||||
FsFile thumbBmp;
|
||||
if (!SdMan.openFileForWrite("EBP", getThumbBmpPath(height), thumbBmp)) {
|
||||
if (!SdMan.openFileForWrite("EBP", getThumbBmpPath(), thumbBmp)) {
|
||||
coverJpg.close();
|
||||
return false;
|
||||
}
|
||||
// Use smaller target size for Continue Reading card (half of screen: 240x400)
|
||||
// Generate 1-bit BMP for fast home screen rendering (no gray passes needed)
|
||||
int THUMB_TARGET_WIDTH = height * 0.6;
|
||||
int THUMB_TARGET_HEIGHT = height;
|
||||
constexpr int THUMB_TARGET_WIDTH = 240;
|
||||
constexpr int THUMB_TARGET_HEIGHT = 400;
|
||||
const bool success = JpegToBmpConverter::jpegFileTo1BitBmpStreamWithSize(coverJpg, thumbBmp, THUMB_TARGET_WIDTH,
|
||||
THUMB_TARGET_HEIGHT);
|
||||
coverJpg.close();
|
||||
@ -471,7 +471,7 @@ bool Epub::generateThumbBmp(int height) const {
|
||||
|
||||
if (!success) {
|
||||
Serial.printf("[%lu] [EBP] Failed to generate thumb BMP from JPG cover image\n", millis());
|
||||
SdMan.remove(getThumbBmpPath(height).c_str());
|
||||
SdMan.remove(getThumbBmpPath().c_str());
|
||||
}
|
||||
Serial.printf("[%lu] [EBP] Generated thumb BMP from JPG cover image, success: %s\n", millis(),
|
||||
success ? "yes" : "no");
|
||||
|
||||
@ -47,8 +47,8 @@ class Epub {
|
||||
const std::string& getLanguage() const;
|
||||
std::string getCoverBmpPath(bool cropped = false) const;
|
||||
bool generateCoverBmp(bool cropped = false) const;
|
||||
std::string getThumbBmpPath(int height) const;
|
||||
bool generateThumbBmp(int height) const;
|
||||
std::string getThumbBmpPath() const;
|
||||
bool generateThumbBmp() const;
|
||||
uint8_t* readItemContentsToBytes(const std::string& itemHref, size_t* size = nullptr,
|
||||
bool trailingNullByte = false) const;
|
||||
bool readItemContentsToStream(const std::string& itemHref, Print& out, size_t chunkSize) const;
|
||||
|
||||
@ -293,11 +293,11 @@ bool Xtc::generateCoverBmp() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Xtc::getThumbBmpPath(int height) const { return cachePath + "/thumb_" + std::to_string(height) + ".bmp"; }
|
||||
std::string Xtc::getThumbBmpPath() const { return cachePath + "/thumb.bmp"; }
|
||||
|
||||
bool Xtc::generateThumbBmp(int height) const {
|
||||
bool Xtc::generateThumbBmp() const {
|
||||
// Already generated
|
||||
if (SdMan.exists(getThumbBmpPath(height).c_str())) {
|
||||
if (SdMan.exists(getThumbBmpPath().c_str())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -325,8 +325,8 @@ bool Xtc::generateThumbBmp(int height) const {
|
||||
const uint8_t bitDepth = parser->getBitDepth();
|
||||
|
||||
// Calculate target dimensions for thumbnail (fit within 240x400 Continue Reading card)
|
||||
int THUMB_TARGET_WIDTH = height * 0.6;
|
||||
int THUMB_TARGET_HEIGHT = height;
|
||||
constexpr int THUMB_TARGET_WIDTH = 240;
|
||||
constexpr int THUMB_TARGET_HEIGHT = 400;
|
||||
|
||||
// Calculate scale factor
|
||||
float scaleX = static_cast<float>(THUMB_TARGET_WIDTH) / pageInfo.width;
|
||||
@ -340,7 +340,7 @@ bool Xtc::generateThumbBmp(int height) const {
|
||||
if (generateCoverBmp()) {
|
||||
FsFile src, dst;
|
||||
if (SdMan.openFileForRead("XTC", getCoverBmpPath(), src)) {
|
||||
if (SdMan.openFileForWrite("XTC", getThumbBmpPath(height), dst)) {
|
||||
if (SdMan.openFileForWrite("XTC", getThumbBmpPath(), dst)) {
|
||||
uint8_t buffer[512];
|
||||
while (src.available()) {
|
||||
size_t bytesRead = src.read(buffer, sizeof(buffer));
|
||||
@ -351,7 +351,7 @@ bool Xtc::generateThumbBmp(int height) const {
|
||||
src.close();
|
||||
}
|
||||
Serial.printf("[%lu] [XTC] Copied cover to thumb (no scaling needed)\n", millis());
|
||||
return SdMan.exists(getThumbBmpPath(height).c_str());
|
||||
return SdMan.exists(getThumbBmpPath().c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -385,7 +385,7 @@ bool Xtc::generateThumbBmp(int height) const {
|
||||
|
||||
// Create thumbnail BMP file - use 1-bit format for fast home screen rendering (no gray passes)
|
||||
FsFile thumbBmp;
|
||||
if (!SdMan.openFileForWrite("XTC", getThumbBmpPath(height), thumbBmp)) {
|
||||
if (!SdMan.openFileForWrite("XTC", getThumbBmpPath(), thumbBmp)) {
|
||||
Serial.printf("[%lu] [XTC] Failed to create thumb BMP file\n", millis());
|
||||
free(pageBuffer);
|
||||
return false;
|
||||
@ -550,7 +550,7 @@ bool Xtc::generateThumbBmp(int height) const {
|
||||
free(pageBuffer);
|
||||
|
||||
Serial.printf("[%lu] [XTC] Generated thumb BMP (%dx%d): %s\n", millis(), thumbWidth, thumbHeight,
|
||||
getThumbBmpPath(height).c_str());
|
||||
getThumbBmpPath().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -63,8 +63,8 @@ class Xtc {
|
||||
std::string getCoverBmpPath() const;
|
||||
bool generateCoverBmp() const;
|
||||
// Thumbnail support (for Continue Reading card)
|
||||
std::string getThumbBmpPath(int height) const;
|
||||
bool generateThumbBmp(int height) const;
|
||||
std::string getThumbBmpPath() const;
|
||||
bool generateThumbBmp() const;
|
||||
|
||||
// Page access
|
||||
uint32_t getPageCount() const;
|
||||
|
||||
@ -8,14 +8,13 @@
|
||||
|
||||
#include "CrossPointSettings.h"
|
||||
#include "CrossPointState.h"
|
||||
#include "components/UITheme.h"
|
||||
#include "fontIds.h"
|
||||
#include "images/CrossLarge.h"
|
||||
#include "util/StringUtils.h"
|
||||
|
||||
void SleepActivity::onEnter() {
|
||||
Activity::onEnter();
|
||||
UITheme::drawPopup(renderer, "Entering Sleep...");
|
||||
renderPopup("Entering Sleep...");
|
||||
|
||||
if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) {
|
||||
return renderBlankSleepScreen();
|
||||
@ -32,6 +31,20 @@ void SleepActivity::onEnter() {
|
||||
renderDefaultSleepScreen();
|
||||
}
|
||||
|
||||
void SleepActivity::renderPopup(const char* message) const {
|
||||
const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD);
|
||||
constexpr int margin = 20;
|
||||
const int x = (renderer.getScreenWidth() - textWidth - margin * 2) / 2;
|
||||
constexpr int y = 117;
|
||||
const int w = textWidth + margin * 2;
|
||||
const int h = renderer.getLineHeight(UI_12_FONT_ID) + margin * 2;
|
||||
// renderer.clearScreen();
|
||||
renderer.fillRect(x - 5, y - 5, w + 10, h + 10, true);
|
||||
renderer.fillRect(x + 5, y + 5, w - 10, h - 10, false);
|
||||
renderer.drawText(UI_12_FONT_ID, x + margin, y + margin, message, true, EpdFontFamily::BOLD);
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
|
||||
void SleepActivity::renderCustomSleepScreen() const {
|
||||
// Check if we have a /sleep directory
|
||||
auto dir = SdMan.open("/sleep");
|
||||
|
||||
@ -10,6 +10,7 @@ class SleepActivity final : public Activity {
|
||||
void onEnter() override;
|
||||
|
||||
private:
|
||||
void renderPopup(const char* message) const;
|
||||
void renderDefaultSleepScreen() const;
|
||||
void renderCustomSleepScreen() const;
|
||||
void renderCoverSleepScreen() const;
|
||||
|
||||
@ -34,16 +34,20 @@ int HomeActivity::getMenuItemCount() const {
|
||||
return count;
|
||||
}
|
||||
|
||||
void HomeActivity::loadRecentBooks(int maxBooks, int coverHeight, PopupCallbacks& popupCallbacks) {
|
||||
void HomeActivity::loadRecentBooks(int maxBooks) { //}, PopupCallbacks& popupCallbacks) {
|
||||
recentsLoading = true;
|
||||
|
||||
recentBooks.clear();
|
||||
const auto& books = RECENT_BOOKS.getBooks();
|
||||
recentBooks.reserve(std::min(static_cast<int>(books.size()), maxBooks));
|
||||
|
||||
int progress = 0;
|
||||
bool loadingPopupDisplayed = false;
|
||||
// if (books.size() > 0) {
|
||||
// popupCallbacks.setup();
|
||||
// }
|
||||
|
||||
for (const auto& path : books) {
|
||||
// popupCallbacks.update(recentBooks.size() * 30); // TODO improve progress calculation
|
||||
|
||||
// Limit to maximum number of recent books
|
||||
if (recentBooks.size() >= maxBooks) {
|
||||
break;
|
||||
@ -57,16 +61,15 @@ void HomeActivity::loadRecentBooks(int maxBooks, int coverHeight, PopupCallbacks
|
||||
std::string lastBookTitle = "";
|
||||
std::string lastBookAuthor = "";
|
||||
std::string coverBmpPath = "";
|
||||
std::string lastBookFileName = "";
|
||||
const size_t lastSlash = path.find_last_of('/');
|
||||
if (lastSlash != std::string::npos) {
|
||||
lastBookFileName = path.substr(lastSlash + 1);
|
||||
lastBookTitle = path.substr(lastSlash + 1);
|
||||
}
|
||||
|
||||
Serial.printf("Loading recent book: %s\n", path.c_str());
|
||||
|
||||
// If epub, try to load the metadata for title/author and cover
|
||||
if (StringUtils::checkFileExtension(lastBookFileName, ".epub")) {
|
||||
if (StringUtils::checkFileExtension(lastBookTitle, ".epub")) {
|
||||
Epub epub(path, "/.crosspoint");
|
||||
epub.load(false);
|
||||
if (!epub.getTitle().empty()) {
|
||||
@ -76,20 +79,11 @@ void HomeActivity::loadRecentBooks(int maxBooks, int coverHeight, PopupCallbacks
|
||||
lastBookAuthor = std::string(epub.getAuthor());
|
||||
}
|
||||
// Try to generate thumbnail image for Continue Reading card
|
||||
coverBmpPath = epub.getThumbBmpPath(coverHeight);
|
||||
if (!SdMan.exists(coverBmpPath.c_str())) {
|
||||
if (loadingPopupDisplayed) {
|
||||
popupCallbacks.update(progress * 30);
|
||||
} else {
|
||||
popupCallbacks.setup();
|
||||
loadingPopupDisplayed = true;
|
||||
}
|
||||
if (!epub.generateThumbBmp(coverHeight)) {
|
||||
coverBmpPath = "";
|
||||
}
|
||||
if (epub.generateThumbBmp()) {
|
||||
coverBmpPath = epub.getThumbBmpPath();
|
||||
}
|
||||
} else if (StringUtils::checkFileExtension(lastBookFileName, ".xtch") ||
|
||||
StringUtils::checkFileExtension(lastBookFileName, ".xtc")) {
|
||||
} else if (StringUtils::checkFileExtension(lastBookTitle, ".xtch") ||
|
||||
StringUtils::checkFileExtension(lastBookTitle, ".xtc")) {
|
||||
// Handle XTC file
|
||||
Xtc xtc(path, "/.crosspoint");
|
||||
if (xtc.load()) {
|
||||
@ -97,33 +91,19 @@ void HomeActivity::loadRecentBooks(int maxBooks, int coverHeight, PopupCallbacks
|
||||
lastBookTitle = std::string(xtc.getTitle());
|
||||
}
|
||||
// Try to generate thumbnail image for Continue Reading card
|
||||
coverBmpPath = xtc.getThumbBmpPath(coverHeight);
|
||||
if (!SdMan.exists(coverBmpPath.c_str())) {
|
||||
if (loadingPopupDisplayed) {
|
||||
popupCallbacks.update(progress * 30);
|
||||
} else {
|
||||
popupCallbacks.setup();
|
||||
loadingPopupDisplayed = true;
|
||||
}
|
||||
if (!xtc.generateThumbBmp(coverHeight)) {
|
||||
coverBmpPath = "";
|
||||
}
|
||||
if (xtc.generateThumbBmp()) {
|
||||
coverBmpPath = xtc.getThumbBmpPath();
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBookTitle.empty()) {
|
||||
// Remove extension from title if we don't have metadata
|
||||
if (StringUtils::checkFileExtension(lastBookFileName, ".xtch")) {
|
||||
lastBookFileName.resize(lastBookFileName.length() - 5);
|
||||
} else if (StringUtils::checkFileExtension(lastBookFileName, ".xtc")) {
|
||||
lastBookFileName.resize(lastBookFileName.length() - 4);
|
||||
}
|
||||
lastBookTitle = lastBookFileName;
|
||||
// Remove extension from title if we don't have metadata
|
||||
if (StringUtils::checkFileExtension(lastBookTitle, ".xtch")) {
|
||||
lastBookTitle.resize(lastBookTitle.length() - 5);
|
||||
} else if (StringUtils::checkFileExtension(lastBookTitle, ".xtc")) {
|
||||
lastBookTitle.resize(lastBookTitle.length() - 4);
|
||||
}
|
||||
}
|
||||
|
||||
recentBooks.push_back(RecentBookInfo{lastBookTitle, lastBookAuthor, coverBmpPath, path});
|
||||
progress++;
|
||||
}
|
||||
|
||||
Serial.printf("Recent books loaded: %d\n", recentBooks.size());
|
||||
@ -265,26 +245,26 @@ void HomeActivity::displayTaskLoop() {
|
||||
|
||||
void HomeActivity::render() {
|
||||
auto metrics = UITheme::getMetrics();
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
bool bufferRestored = coverBufferStored && restoreCoverBuffer();
|
||||
if (!firstRenderDone || (recentsLoaded && !recentsDisplayed)) {
|
||||
if (!bufferRestored || !firstRenderDone) {
|
||||
renderer.clearScreen();
|
||||
}
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
UITheme::drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.homeTopPadding}, nullptr);
|
||||
|
||||
if (hasContinueReading) {
|
||||
if (recentsLoaded) {
|
||||
recentsDisplayed = true;
|
||||
UITheme::drawRecentBookCover(renderer, Rect{0, metrics.homeTopPadding, pageWidth, metrics.homeCoverHeight},
|
||||
recentBooks, selectorIndex, coverRendered, coverBufferStored, bufferRestored,
|
||||
std::bind(&HomeActivity::storeCoverBuffer, this));
|
||||
} else if (!recentsLoading && firstRenderDone) {
|
||||
recentsLoading = true;
|
||||
PopupCallbacks popupCallbacks = UITheme::drawPopupWithProgress(renderer, "Loading...");
|
||||
loadRecentBooks(metrics.homeRecentBooksCount, metrics.homeCoverHeight, popupCallbacks);
|
||||
// PopupCallbacks popupCallbacks = UITheme::drawPopupWithProgress(renderer, "Loading...");
|
||||
loadRecentBooks(metrics.homeRecentBooksCount); //, popupCallbacks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ class HomeActivity final : public Activity {
|
||||
bool hasContinueReading = false;
|
||||
bool recentsLoading = false;
|
||||
bool recentsLoaded = false;
|
||||
bool recentsDisplayed = false;
|
||||
bool firstRenderDone = false;
|
||||
bool hasOpdsUrl = false;
|
||||
bool coverRendered = false; // Track if cover has been rendered once
|
||||
@ -37,10 +36,10 @@ class HomeActivity final : public Activity {
|
||||
[[noreturn]] void displayTaskLoop();
|
||||
void render();
|
||||
int getMenuItemCount() const;
|
||||
bool storeCoverBuffer(); // Store frame buffer for cover image
|
||||
bool restoreCoverBuffer(); // Restore frame buffer from stored cover
|
||||
void freeCoverBuffer(); // Free the stored cover buffer
|
||||
void loadRecentBooks(int maxBooks, int coverHeight, PopupCallbacks& popupCallbacks);
|
||||
bool storeCoverBuffer(); // Store frame buffer for cover image
|
||||
bool restoreCoverBuffer(); // Restore frame buffer from stored cover
|
||||
void freeCoverBuffer(); // Free the stored cover buffer
|
||||
void loadRecentBooks(int maxBooks); //, PopupCallbacks& popupCallbacks);
|
||||
|
||||
public:
|
||||
explicit HomeActivity(
|
||||
|
||||
@ -112,12 +112,6 @@ void UITheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount,
|
||||
}
|
||||
}
|
||||
|
||||
void UITheme::drawPopup(GfxRenderer& renderer, const char* message) {
|
||||
if (currentTheme != nullptr) {
|
||||
currentTheme->drawPopup(renderer, message);
|
||||
}
|
||||
}
|
||||
|
||||
PopupCallbacks UITheme::drawPopupWithProgress(GfxRenderer& renderer, const std::string& title) {
|
||||
if (currentTheme != nullptr) {
|
||||
return currentTheme->drawPopupWithProgress(renderer, title);
|
||||
|
||||
@ -86,6 +86,5 @@ class UITheme {
|
||||
static void drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount, int selectedIndex,
|
||||
const std::function<std::string(int index)>& buttonLabel, bool hasIcon,
|
||||
const std::function<std::string(int index)>& rowIcon);
|
||||
static void drawPopup(GfxRenderer& renderer, const char* message);
|
||||
static PopupCallbacks drawPopupWithProgress(GfxRenderer& renderer, const std::string& title);
|
||||
};
|
||||
@ -106,9 +106,9 @@ void BaseTheme::drawButtonHints(const GfxRenderer& renderer, const char* btn1, c
|
||||
|
||||
void BaseTheme::drawSideButtonHints(const GfxRenderer& renderer, const char* topBtn, const char* bottomBtn) {
|
||||
const int screenWidth = renderer.getScreenWidth();
|
||||
constexpr int buttonWidth = BaseMetrics::values.sideButtonHintsWidth; // Width on screen (height when rotated)
|
||||
constexpr int buttonHeight = 80; // Height on screen (width when rotated)
|
||||
constexpr int buttonX = 4; // Distance from right edge
|
||||
constexpr int buttonWidth = BaseMetrics::values.buttonHintsHeight; // Width on screen (height when rotated)
|
||||
constexpr int buttonHeight = 80; // Height on screen (width when rotated)
|
||||
constexpr int buttonX = 5; // Distance from right edge
|
||||
// Position for the button group - buttons share a border so they're adjacent
|
||||
constexpr int topButtonY = 345; // Top button position
|
||||
|
||||
@ -165,32 +165,20 @@ void BaseTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount,
|
||||
|
||||
const int totalPages = (itemCount + pageItems - 1) / pageItems;
|
||||
if (totalPages > 1) {
|
||||
constexpr int indicatorWidth = 20;
|
||||
constexpr int arrowSize = 6;
|
||||
constexpr int margin = 15; // Offset from right edge
|
||||
|
||||
const int centerX = rect.x + rect.width - indicatorWidth / 2 - margin;
|
||||
const int indicatorTop = rect.y + 60; // Offset to avoid overlapping side button hints
|
||||
const int indicatorBottom = rect.y + rect.height - 30;
|
||||
|
||||
// Draw up arrow at top (^) - narrow point at top, wide base at bottom
|
||||
for (int i = 0; i < arrowSize; ++i) {
|
||||
const int lineWidth = 1 + i * 2;
|
||||
const int startX = centerX - i;
|
||||
renderer.drawLine(startX, indicatorTop + i, startX + lineWidth - 1, indicatorTop + i);
|
||||
}
|
||||
|
||||
// Draw down arrow at bottom (v) - wide base at top, narrow point at bottom
|
||||
for (int i = 0; i < arrowSize; ++i) {
|
||||
const int lineWidth = 1 + (arrowSize - 1 - i) * 2;
|
||||
const int startX = centerX - (arrowSize - 1 - i);
|
||||
renderer.drawLine(startX, indicatorBottom - arrowSize + 1 + i, startX + lineWidth - 1,
|
||||
indicatorBottom - arrowSize + 1 + i);
|
||||
}
|
||||
// Draw scroll bar
|
||||
const int scrollBarHeight = (rect.height * pageItems) / itemCount;
|
||||
const int currentPage = selectedIndex / pageItems;
|
||||
const int scrollBarY = rect.y + ((rect.height - scrollBarHeight) * currentPage) / (totalPages - 1);
|
||||
const int scrollBarX = rect.x + rect.width - BaseMetrics::values.scrollBarRightOffset;
|
||||
renderer.drawLine(scrollBarX, rect.y, scrollBarX, rect.y + rect.height, true);
|
||||
renderer.fillRect(scrollBarX - BaseMetrics::values.scrollBarWidth, scrollBarY, BaseMetrics::values.scrollBarWidth,
|
||||
scrollBarHeight, true);
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
int contentWidth = rect.width - BaseMetrics::values.sideButtonHintsWidth - 5;
|
||||
int contentWidth =
|
||||
rect.width -
|
||||
(totalPages > 1 ? (BaseMetrics::values.scrollBarWidth + BaseMetrics::values.scrollBarRightOffset) : 1);
|
||||
renderer.fillRect(0, rect.y + selectedIndex % pageItems * rowHeight - 2, contentWidth, rowHeight);
|
||||
// Draw all items
|
||||
const auto pageStartIndex = selectedIndex / pageItems * pageItems;
|
||||
@ -576,20 +564,6 @@ void BaseTheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTheme::drawPopup(GfxRenderer& renderer, const char* message) {
|
||||
const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD);
|
||||
constexpr int margin = 20;
|
||||
const int x = (renderer.getScreenWidth() - textWidth - margin * 2) / 2;
|
||||
constexpr int y = 117;
|
||||
const int w = textWidth + margin * 2;
|
||||
const int h = renderer.getLineHeight(UI_12_FONT_ID) + margin * 2;
|
||||
// renderer.clearScreen();
|
||||
renderer.fillRect(x - 5, y - 5, w + 10, h + 10, true);
|
||||
renderer.fillRect(x + 5, y + 5, w - 10, h - 10, false);
|
||||
renderer.drawText(UI_12_FONT_ID, x + margin, y + margin, message, true, EpdFontFamily::BOLD);
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
|
||||
PopupCallbacks BaseTheme::drawPopupWithProgress(GfxRenderer& renderer, const std::string& title) {
|
||||
// Progress bar dimensions
|
||||
constexpr int barWidth = 200;
|
||||
|
||||
@ -31,7 +31,7 @@ constexpr ThemeMetrics values = {.batteryWidth = 15,
|
||||
.homeCoverHeight = 400,
|
||||
.homeRecentBooksCount = 1,
|
||||
.buttonHintsHeight = 40,
|
||||
.sideButtonHintsWidth = 30,
|
||||
.sideButtonHintsWidth = 20,
|
||||
.versionTextRightX = 20,
|
||||
.versionTextY = 738};
|
||||
}
|
||||
@ -59,6 +59,5 @@ class BaseTheme {
|
||||
virtual void drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount, int selectedIndex,
|
||||
const std::function<std::string(int index)>& buttonLabel, bool hasIcon,
|
||||
const std::function<std::string(int index)>& rowIcon);
|
||||
virtual void drawPopup(GfxRenderer& renderer, const char* message);
|
||||
virtual PopupCallbacks drawPopupWithProgress(GfxRenderer& renderer, const std::string& title);
|
||||
};
|
||||
@ -57,8 +57,6 @@ void LyraTheme::drawBattery(const GfxRenderer& renderer, Rect rect, const bool s
|
||||
}
|
||||
|
||||
void LyraTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* title) {
|
||||
renderer.fillRect(rect.x, rect.y, rect.width, rect.height, false);
|
||||
|
||||
const bool showBatteryPercentage =
|
||||
SETTINGS.hideBatteryPercentage != CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_ALWAYS;
|
||||
int batteryX = rect.x + rect.width - LyraMetrics::values.contentSidePadding - LyraMetrics::values.batteryWidth;
|
||||
@ -316,18 +314,4 @@ void LyraTheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount
|
||||
// Invert text when the tile is selected, to contrast with the filled background
|
||||
renderer.drawText(UI_12_FONT_ID, textX, textY, label, true);
|
||||
}
|
||||
}
|
||||
|
||||
void LyraTheme::drawPopup(GfxRenderer& renderer, const char* message) {
|
||||
const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD);
|
||||
constexpr int margin = 20;
|
||||
const int x = (renderer.getScreenWidth() - textWidth - margin * 2) / 2;
|
||||
constexpr int y = 117;
|
||||
const int w = textWidth + margin * 2;
|
||||
const int h = renderer.getLineHeight(UI_12_FONT_ID) + margin * 2;
|
||||
|
||||
renderer.fillRect(x - 5, y - 5, w + 10, h + 10, false);
|
||||
renderer.drawRect(x + 5, y + 5, w - 10, h - 10, true);
|
||||
renderer.drawText(UI_12_FONT_ID, x + margin, y + margin, message, true, EpdFontFamily::BOLD);
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
@ -49,5 +49,4 @@ class LyraTheme : public BaseTheme {
|
||||
void drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std::vector<RecentBookInfo>& recentBooks,
|
||||
const int selectorIndex, bool& coverRendered, bool& coverBufferStored, bool& bufferRestored,
|
||||
std::function<bool()> storeCoverBuffer) override;
|
||||
void drawPopup(GfxRenderer& renderer, const char* message) override;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user