From 492e79f9c0784b8aedd9485b5234ec8ac01db72b Mon Sep 17 00:00:00 2001 From: Arthur Tazhitdinov Date: Mon, 26 Jan 2026 14:18:12 +0500 Subject: [PATCH] rectangular frame for popups --- lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h | 2 +- lib/GfxRenderer/GfxRenderer.cpp | 167 ------------------ lib/GfxRenderer/GfxRenderer.h | 4 - src/ScreenComponents.cpp | 33 ++-- src/ScreenComponents.h | 4 - src/activities/boot_sleep/SleepActivity.cpp | 5 +- src/activities/reader/EpubReaderActivity.cpp | 2 +- 7 files changed, 16 insertions(+), 201 deletions(-) diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h index 89355e50..456b19f8 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h @@ -2,8 +2,8 @@ #include -#include #include +#include #include #include diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 7a343ad2..cb268fc8 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -2,19 +2,6 @@ #include -namespace { -int clampRoundedRadius(const int width, const int height, int radius) { - if (radius <= 0) { - return 0; - } - const int maxRadius = (std::min(width, height) - 1) / 2; - if (maxRadius <= 0) { - return 0; - } - return radius > maxRadius ? maxRadius : radius; -} -} // namespace - void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); } void GfxRenderer::rotateCoordinates(const int x, const int y, int* rotatedX, int* rotatedY) const { @@ -151,158 +138,6 @@ void GfxRenderer::drawRect(const int x, const int y, const int width, const int drawLine(x, y, x, y + height - 1, state); } -void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, const int height, int radius, - const bool state) const { - if (width <= 0 || height <= 0) { - return; - } - - radius = clampRoundedRadius(width, height, radius); - if (radius <= 0) { - drawRect(x, y, width, height, state); - return; - } - - const int right = x + width - 1; - const int bottom = y + height - 1; - const int x0 = x + radius; - const int x1 = right - radius; - const int y0 = y + radius; - const int y1 = bottom - radius; - - if (x0 <= x1) { - drawLine(x0, y, x1, y, state); - drawLine(x0, bottom, x1, bottom, state); - } - if (y0 <= y1) { - drawLine(x, y0, x, y1, state); - drawLine(right, y0, right, y1, state); - } - - const int cxLeft = x + radius; - const int cxRight = right - radius; - const int cyTop = y + radius; - const int cyBottom = bottom - radius; - - auto plotCornerPoints = [&](const int offsetX, const int offsetY) { - drawPixel(cxLeft - offsetX, cyTop - offsetY, state); - drawPixel(cxRight + offsetX, cyTop - offsetY, state); - drawPixel(cxRight + offsetX, cyBottom + offsetY, state); - drawPixel(cxLeft - offsetX, cyBottom + offsetY, state); - - if (offsetX == offsetY) { - return; - } - - drawPixel(cxLeft - offsetY, cyTop - offsetX, state); - drawPixel(cxRight + offsetY, cyTop - offsetX, state); - drawPixel(cxRight + offsetY, cyBottom + offsetX, state); - drawPixel(cxLeft - offsetY, cyBottom + offsetX, state); - }; - - int f = 1 - radius; - int ddF_x = 1; - int ddF_y = -2 * radius; - int offsetX = 0; - int offsetY = radius; - - while (offsetX <= offsetY) { - plotCornerPoints(offsetX, offsetY); - if (f >= 0) { - offsetY--; - ddF_y += 2; - f += ddF_y; - } - offsetX++; - ddF_x += 2; - f += ddF_x; - plotCornerPoints(offsetX, offsetY); - } -} - -void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, const int height, int radius, - const bool state) const { - if (width <= 0 || height <= 0) { - return; - } - - radius = clampRoundedRadius(width, height, radius); - if (radius <= 0) { - fillRect(x, y, width, height, state); - return; - } - - const int right = x + width - 1; - const int bottom = y + height - 1; - const int innerTop = y + radius; - const int innerBottom = bottom - radius; - - if (innerBottom >= innerTop) { - fillRect(x, innerTop, width, innerBottom - innerTop + 1, state); - } - - int f = 1 - radius; - int ddF_x = 1; - int ddF_y = -2 * radius; - int offsetX = 0; - int offsetY = radius; - - while (offsetX <= offsetY) { - int left = x + radius - offsetX; - int rightSpan = right - radius + offsetX; - int topY = innerTop - offsetY; - int bottomY = innerBottom + offsetY; - drawLine(left, topY, rightSpan, topY, state); - drawLine(left, bottomY, rightSpan, bottomY, state); - - if (offsetX != offsetY) { - left = x + radius - offsetY; - rightSpan = right - radius + offsetY; - topY = innerTop - offsetX; - bottomY = innerBottom + offsetX; - drawLine(left, topY, rightSpan, topY, state); - drawLine(left, bottomY, rightSpan, bottomY, state); - } - - if (f >= 0) { - offsetY--; - ddF_y += 2; - f += ddF_y; - } - offsetX++; - ddF_x += 2; - f += ddF_x; - } -} - -void GfxRenderer::drawRoundedRectFrame(const int x, const int y, const int width, const int height, int radius, - int thickness, const bool frameState, const bool fillState) const { - if (width <= 0 || height <= 0) { - return; - } - - const int maxThickness = (std::min(width, height) - 1) / 2; - thickness = std::min(thickness, maxThickness); - if (thickness <= 0) { - fillRoundedRect(x, y, width, height, radius, fillState); - return; - } - - fillRoundedRect(x, y, width, height, radius, frameState); - - const int inset = thickness * 2; - const int innerX = x + thickness; - const int innerY = y + thickness; - const int innerW = width - inset; - const int innerH = height - inset; - if (innerW <= 0 || innerH <= 0) { - return; - } - - const int innerRadius = radius - thickness; - fillRoundedRect(innerX, innerY, innerW, innerH, innerRadius, fillState); -} - void GfxRenderer::fillRect(const int x, const int y, const int width, const int height, const bool state) const { for (int fillY = y; fillY < y + height; fillY++) { drawLine(x, fillY, x + width - 1, fillY, state); @@ -807,8 +642,6 @@ uint8_t* GfxRenderer::getFrameBuffer() const { return einkDisplay.getFrameBuffer size_t GfxRenderer::getBufferSize() { return EInkDisplay::BUFFER_SIZE; } -void GfxRenderer::grayscaleRevert() const { einkDisplay.grayscaleRevert(); } - void GfxRenderer::copyGrayscaleLsbBuffers() const { einkDisplay.copyGrayscaleLsbBuffers(einkDisplay.getFrameBuffer()); } void GfxRenderer::copyGrayscaleMsbBuffers() const { einkDisplay.copyGrayscaleMsbBuffers(einkDisplay.getFrameBuffer()); } diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index 1c6fc4ea..dc0dfa03 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -64,10 +64,6 @@ class GfxRenderer { void drawPixel(int x, int y, bool state = true) const; void drawLine(int x1, int y1, int x2, int y2, bool state = true) const; void drawRect(int x, int y, int width, int height, bool state = true) const; - void drawRoundedRect(int x, int y, int width, int height, int radius, bool state = true) const; - void fillRoundedRect(int x, int y, int width, int height, int radius, bool state = true) const; - void drawRoundedRectFrame(int x, int y, int width, int height, int radius, int thickness = 1, - bool frameState = true, bool fillState = false) const; void fillRect(int x, int y, int width, int height, bool state = true) const; void drawImage(const uint8_t bitmap[], int x, int y, int width, int height) const; void drawBitmap(const Bitmap& bitmap, int x, int y, int maxWidth, int maxHeight, float cropX = 0, diff --git a/src/ScreenComponents.cpp b/src/ScreenComponents.cpp index e3eed0d6..4f163af1 100644 --- a/src/ScreenComponents.cpp +++ b/src/ScreenComponents.cpp @@ -43,38 +43,31 @@ void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left, } ScreenComponents::PopupLayout ScreenComponents::drawPopup(const GfxRenderer& renderer, const char* message) { - constexpr int margin = 12; - constexpr int frameThickness = 4; - constexpr int frameInset = frameThickness / 2; - constexpr int frameRadius = 8; - constexpr int bottomOffset = 20; + constexpr int margin = 15; + constexpr int y = 60; const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, message, EpdFontFamily::BOLD); - const int w = std::max(textWidth, POPUP_DEFAULT_MIN_WIDTH) + margin * 2; - const int h = std::max(renderer.getLineHeight(UI_12_FONT_ID) + margin * 2, POPUP_DEFAULT_MIN_HEIGHT); - const int x = std::max(0, (renderer.getScreenWidth() - w) / 2); - const int y = std::max(0, renderer.getScreenHeight() - h - margin - bottomOffset); + const int textHeight = renderer.getLineHeight(UI_12_FONT_ID); + const int w = textWidth + margin * 2; + const int h = textHeight + margin * 2; + const int x = (renderer.getScreenWidth() - w) / 2; - renderer.drawRoundedRectFrame(x - frameInset, y - frameInset, w + frameInset * 2, h + frameInset * 2, - frameRadius, frameThickness, true, false); + renderer.fillRect(x - 2, y - 2, w + 4, h + 4, true); // frame thickness 2 + renderer.fillRect(x, y, w, h, false); const int textX = x + (w - textWidth) / 2; - renderer.drawText(UI_12_FONT_ID, textX, y + margin - 2, message, true, EpdFontFamily::BOLD); + const int textY = y + margin - 2; + renderer.drawText(UI_12_FONT_ID, textX, textY, message, true, EpdFontFamily::BOLD); renderer.displayBuffer(); return {x, y, w, h}; } void ScreenComponents::fillPopupProgress(const GfxRenderer& renderer, const PopupLayout& layout, const int progress) { - constexpr int barWidth = POPUP_DEFAULT_MIN_WIDTH; - constexpr int barHeight = POPUP_DEFAULT_BAR_HEIGHT; + constexpr int barHeight = 4; + const int barWidth = layout.width - 30; // twice the margin in drawPopup to match text width const int barX = layout.x + (layout.width - barWidth) / 2; - const int barY = layout.y + layout.height - 13; + const int barY = layout.y + layout.height - 10; int fillWidth = barWidth * progress / 100; - if (fillWidth < 0) { - fillWidth = 0; - } else if (fillWidth > barWidth) { - fillWidth = barWidth; - } renderer.fillRect(barX, barY, fillWidth, barHeight, true); diff --git a/src/ScreenComponents.h b/src/ScreenComponents.h index 00f3ee81..ba69f1a6 100644 --- a/src/ScreenComponents.h +++ b/src/ScreenComponents.h @@ -13,10 +13,6 @@ struct TabInfo { class ScreenComponents { public: - static constexpr int POPUP_DEFAULT_MIN_WIDTH = 130; - static constexpr int POPUP_DEFAULT_MIN_HEIGHT = 50; - static constexpr int POPUP_DEFAULT_BAR_HEIGHT = 4; - struct PopupLayout { int x; int y; diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index 738c1c0c..50b06a90 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -8,19 +8,16 @@ #include "CrossPointSettings.h" #include "CrossPointState.h" +#include "ScreenComponents.h" #include "fontIds.h" #include "images/CrossLarge.h" #include "util/StringUtils.h" -#include "ScreenComponents.h" void SleepActivity::onEnter() { Activity::onEnter(); ScreenComponents::drawPopup(renderer, "Sleeping"); - // debug delay to see sleep screen - delay(5000); - if (SETTINGS.sleepScreen == CrossPointSettings::SLEEP_SCREEN_MODE::BLANK) { return renderBlankSleepScreen(); } diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 196a7455..e77e559b 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -286,7 +286,7 @@ void EpubReaderActivity::renderScreen() { Serial.printf("[%lu] [ERS] Cache not found, building...\n", millis()); pagesUntilFullRefresh = 0; - const auto popupLayout = ScreenComponents::drawPopup(renderer, "Rendering"); + const auto popupLayout = ScreenComponents::drawPopup(renderer, "Indexing..."); const auto progressCallback = [this, popupLayout](int progress) { ScreenComponents::fillPopupProgress(renderer, popupLayout, progress); };