mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 15:17:37 +03:00
style: improve EPUB reader footer layout with delimiter line and consistent spacing
This commit is contained in:
parent
39bc87d3a6
commit
00369161f9
@ -134,8 +134,8 @@ void HomeActivity::render() const {
|
|||||||
const auto pageWidth = renderer.getScreenWidth();
|
const auto pageWidth = renderer.getScreenWidth();
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
const auto pageHeight = renderer.getScreenHeight();
|
||||||
|
|
||||||
constexpr int margin = 20;
|
constexpr int margin = 16;
|
||||||
constexpr int bottomMargin = 60;
|
constexpr int bottomMargin = 56;
|
||||||
|
|
||||||
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
||||||
const int bookWidth = pageWidth / 2;
|
const int bookWidth = pageWidth / 2;
|
||||||
@ -279,8 +279,8 @@ void HomeActivity::render() const {
|
|||||||
|
|
||||||
// --- Bottom menu tiles (indices 1-3) ---
|
// --- Bottom menu tiles (indices 1-3) ---
|
||||||
const int menuTileWidth = pageWidth - 2 * margin;
|
const int menuTileWidth = pageWidth - 2 * margin;
|
||||||
constexpr int menuTileHeight = 50;
|
constexpr int menuTileHeight = 44;
|
||||||
constexpr int menuSpacing = 10;
|
constexpr int menuSpacing = 8;
|
||||||
constexpr int totalMenuHeight = 3 * menuTileHeight + 2 * menuSpacing;
|
constexpr int totalMenuHeight = 3 * menuTileHeight + 2 * menuSpacing;
|
||||||
|
|
||||||
int menuStartY = bookY + bookHeight + 20;
|
int menuStartY = bookY + bookHeight + 20;
|
||||||
@ -316,7 +316,7 @@ void HomeActivity::render() const {
|
|||||||
const auto labels = mappedInput.mapLabels("", "Confirm", "Up", "Down");
|
const auto labels = mappedInput.mapLabels("", "Confirm", "Up", "Down");
|
||||||
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
|
|
||||||
ScreenComponents::drawBattery(renderer, 20, pageHeight - 70);
|
ScreenComponents::drawBattery(renderer, margin, pageHeight - 68);
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,13 @@ constexpr unsigned long skipChapterMs = 700;
|
|||||||
constexpr unsigned long goHomeMs = 1000;
|
constexpr unsigned long goHomeMs = 1000;
|
||||||
constexpr int topPadding = 5;
|
constexpr int topPadding = 5;
|
||||||
constexpr int horizontalPadding = 5;
|
constexpr int horizontalPadding = 5;
|
||||||
constexpr int statusBarMargin = 19;
|
// Footer layout: total height reserved for footer area
|
||||||
|
// contentGap = space between last line of book text and delimiter line
|
||||||
|
// lineToText = space between delimiter line and footer text
|
||||||
|
// footerTextHeight ~= 12px for small font
|
||||||
|
constexpr int footerHeight = 34; // total footer area height (includes bottom margin)
|
||||||
|
constexpr int contentGap = 6; // gap above delimiter line
|
||||||
|
constexpr int lineToText = 6; // gap below delimiter line to text
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void EpubReaderActivity::taskTrampoline(void* param) {
|
void EpubReaderActivity::taskTrampoline(void* param) {
|
||||||
@ -256,7 +262,7 @@ void EpubReaderActivity::renderScreen() {
|
|||||||
orientedMarginTop += topPadding;
|
orientedMarginTop += topPadding;
|
||||||
orientedMarginLeft += horizontalPadding;
|
orientedMarginLeft += horizontalPadding;
|
||||||
orientedMarginRight += horizontalPadding;
|
orientedMarginRight += horizontalPadding;
|
||||||
orientedMarginBottom += statusBarMargin;
|
orientedMarginBottom += footerHeight + contentGap;
|
||||||
|
|
||||||
if (!section) {
|
if (!section) {
|
||||||
const auto filepath = epub->getSpineItem(currentSpineIndex).href;
|
const auto filepath = epub->getSpineItem(currentSpineIndex).href;
|
||||||
@ -419,9 +425,20 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
|
|||||||
const bool showChapterTitle = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS ||
|
const bool showChapterTitle = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS ||
|
||||||
SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL;
|
SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL;
|
||||||
|
|
||||||
// Position status bar near the bottom of the logical screen, regardless of orientation
|
// Footer layout calculation:
|
||||||
|
// Screen bottom -> viewable margin -> footer text -> lineToText -> line -> contentGap -> book content
|
||||||
|
// orientedMarginBottom already includes (footerHeight + contentGap)
|
||||||
|
// So book content ends at: screenHeight - orientedMarginBottom
|
||||||
|
// Line should be at: screenHeight - orientedMarginBottom + contentGap (just below content)
|
||||||
|
// Footer text at: lineY + lineToText + some offset for text baseline
|
||||||
|
|
||||||
const auto screenHeight = renderer.getScreenHeight();
|
const auto screenHeight = renderer.getScreenHeight();
|
||||||
const auto textY = screenHeight - orientedMarginBottom - 4;
|
const int contentBottom = screenHeight - orientedMarginBottom;
|
||||||
|
const int lineY = contentBottom + contentGap;
|
||||||
|
const int textY = lineY + lineToText;
|
||||||
|
|
||||||
|
renderer.drawLine(orientedMarginLeft, lineY, renderer.getScreenWidth() - orientedMarginRight, lineY);
|
||||||
|
|
||||||
int progressTextWidth = 0;
|
int progressTextWidth = 0;
|
||||||
|
|
||||||
if (showProgress) {
|
if (showProgress) {
|
||||||
|
|||||||
@ -8,16 +8,17 @@
|
|||||||
namespace {
|
namespace {
|
||||||
// Time threshold for treating a long press as a page-up/page-down
|
// Time threshold for treating a long press as a page-up/page-down
|
||||||
constexpr int SKIP_PAGE_MS = 700;
|
constexpr int SKIP_PAGE_MS = 700;
|
||||||
|
constexpr int headerY = 16;
|
||||||
|
constexpr int separatorY = 42;
|
||||||
|
constexpr int listStartY = 54;
|
||||||
|
constexpr int rowHeight = 28;
|
||||||
|
constexpr int horizontalMargin = 16;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int EpubReaderChapterSelectionActivity::getPageItems() const {
|
int EpubReaderChapterSelectionActivity::getPageItems() const {
|
||||||
// Layout constants used in renderScreen
|
|
||||||
constexpr int startY = 60;
|
|
||||||
constexpr int lineHeight = 30;
|
|
||||||
|
|
||||||
const int screenHeight = renderer.getScreenHeight();
|
const int screenHeight = renderer.getScreenHeight();
|
||||||
const int availableHeight = screenHeight - startY;
|
const int availableHeight = screenHeight - listStartY;
|
||||||
int items = availableHeight / lineHeight;
|
int items = availableHeight / rowHeight;
|
||||||
|
|
||||||
// Ensure we always have at least one item per page to avoid division by zero
|
// Ensure we always have at least one item per page to avoid division by zero
|
||||||
if (items < 1) {
|
if (items < 1) {
|
||||||
@ -121,17 +122,25 @@ void EpubReaderChapterSelectionActivity::renderScreen() {
|
|||||||
const auto pageWidth = renderer.getScreenWidth();
|
const auto pageWidth = renderer.getScreenWidth();
|
||||||
const int pageItems = getPageItems();
|
const int pageItems = getPageItems();
|
||||||
|
|
||||||
|
// Draw header with book title
|
||||||
const std::string title =
|
const std::string title =
|
||||||
renderer.truncatedText(UI_12_FONT_ID, epub->getTitle().c_str(), pageWidth - 40, EpdFontFamily::BOLD);
|
renderer.truncatedText(UI_12_FONT_ID, epub->getTitle().c_str(), pageWidth - horizontalMargin * 2, EpdFontFamily::BOLD);
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, title.c_str(), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_12_FONT_ID, headerY, title.c_str(), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
|
// Subtle separator line under header
|
||||||
|
renderer.drawLine(horizontalMargin, separatorY, pageWidth - horizontalMargin, separatorY);
|
||||||
|
|
||||||
|
// Draw selection highlight
|
||||||
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
||||||
renderer.fillRect(0, 60 + (selectorIndex % pageItems) * 30 - 2, pageWidth - 1, 30);
|
renderer.fillRect(0, listStartY + (selectorIndex % pageItems) * rowHeight - 2, pageWidth - 1, rowHeight);
|
||||||
|
|
||||||
|
// Draw chapter list
|
||||||
for (int tocIndex = pageStartIndex; tocIndex < epub->getTocItemsCount() && tocIndex < pageStartIndex + pageItems;
|
for (int tocIndex = pageStartIndex; tocIndex < epub->getTocItemsCount() && tocIndex < pageStartIndex + pageItems;
|
||||||
tocIndex++) {
|
tocIndex++) {
|
||||||
auto item = epub->getTocItem(tocIndex);
|
auto item = epub->getTocItem(tocIndex);
|
||||||
renderer.drawText(UI_10_FONT_ID, 20 + (item.level - 1) * 15, 60 + (tocIndex % pageItems) * 30, item.title.c_str(),
|
const int indentPx = (item.level - 1) * 12;
|
||||||
tocIndex != selectorIndex);
|
renderer.drawText(UI_10_FONT_ID, horizontalMargin + 4 + indentPx, listStartY + (tocIndex % pageItems) * rowHeight,
|
||||||
|
item.title.c_str(), tocIndex != selectorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
|
|||||||
@ -7,9 +7,14 @@
|
|||||||
#include "fontIds.h"
|
#include "fontIds.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int PAGE_ITEMS = 23;
|
constexpr int PAGE_ITEMS = 20;
|
||||||
constexpr int SKIP_PAGE_MS = 700;
|
constexpr int SKIP_PAGE_MS = 700;
|
||||||
constexpr unsigned long GO_HOME_MS = 1000;
|
constexpr unsigned long GO_HOME_MS = 1000;
|
||||||
|
constexpr int headerY = 16;
|
||||||
|
constexpr int separatorY = 42;
|
||||||
|
constexpr int listStartY = 54;
|
||||||
|
constexpr int rowHeight = 28;
|
||||||
|
constexpr int horizontalMargin = 16;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void sortFileList(std::vector<std::string>& strs) {
|
void sortFileList(std::vector<std::string>& strs) {
|
||||||
@ -173,23 +178,28 @@ void FileSelectionActivity::render() const {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const auto pageWidth = renderer.getScreenWidth();
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Books", true, EpdFontFamily::BOLD);
|
|
||||||
|
// Draw header
|
||||||
|
renderer.drawCenteredText(UI_12_FONT_ID, headerY, "Books", true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
|
// Subtle separator line under header
|
||||||
|
renderer.drawLine(horizontalMargin, separatorY, pageWidth - horizontalMargin, separatorY);
|
||||||
|
|
||||||
// Help text
|
// Help text
|
||||||
const auto labels = mappedInput.mapLabels("« Home", "Open", "", "");
|
const auto labels = mappedInput.mapLabels("« Home", "Open", "", "");
|
||||||
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
|
|
||||||
if (files.empty()) {
|
if (files.empty()) {
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 60, "No books found");
|
renderer.drawText(UI_10_FONT_ID, horizontalMargin + 4, listStartY, "No books found");
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pageStartIndex = selectorIndex / PAGE_ITEMS * PAGE_ITEMS;
|
const auto pageStartIndex = selectorIndex / PAGE_ITEMS * PAGE_ITEMS;
|
||||||
renderer.fillRect(0, 60 + (selectorIndex % PAGE_ITEMS) * 30 - 2, pageWidth - 1, 30);
|
renderer.fillRect(0, listStartY + (selectorIndex % PAGE_ITEMS) * rowHeight - 2, pageWidth - 1, rowHeight);
|
||||||
for (int i = pageStartIndex; i < files.size() && i < pageStartIndex + PAGE_ITEMS; i++) {
|
for (int i = pageStartIndex; i < files.size() && i < pageStartIndex + PAGE_ITEMS; i++) {
|
||||||
auto item = renderer.truncatedText(UI_10_FONT_ID, files[i].c_str(), renderer.getScreenWidth() - 40);
|
auto item = renderer.truncatedText(UI_10_FONT_ID, files[i].c_str(), pageWidth - horizontalMargin * 2 - 8);
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 60 + (i % PAGE_ITEMS) * 30, item.c_str(), i != selectorIndex);
|
renderer.drawText(UI_10_FONT_ID, horizontalMargin + 4, listStartY + (i % PAGE_ITEMS) * rowHeight, item.c_str(), i != selectorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user