Refactor ui content rect
This commit is contained in:
@@ -139,13 +139,13 @@ void OpdsBookBrowserActivity::loop() {
|
|||||||
void OpdsBookBrowserActivity::render(RenderLock&&) {
|
void OpdsBookBrowserActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
const int midY = contentRect.y + contentRect.height / 2;
|
||||||
|
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, tr(STR_OPDS_BROWSER), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_12_FONT_ID, 15, tr(STR_OPDS_BROWSER), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
if (state == BrowserState::CHECK_WIFI) {
|
if (state == BrowserState::CHECK_WIFI) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, statusMessage.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, midY, statusMessage.c_str());
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
@@ -153,7 +153,7 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == BrowserState::LOADING) {
|
if (state == BrowserState::LOADING) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, statusMessage.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, midY, statusMessage.c_str());
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
@@ -161,8 +161,8 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == BrowserState::ERROR) {
|
if (state == BrowserState::ERROR) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 20, tr(STR_ERROR_MSG));
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 20, tr(STR_ERROR_MSG));
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 10, errorMessage.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, errorMessage.c_str());
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_RETRY), "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_RETRY), "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
@@ -170,16 +170,15 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == BrowserState::DOWNLOADING) {
|
if (state == BrowserState::DOWNLOADING) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 40, tr(STR_DOWNLOADING));
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 40, tr(STR_DOWNLOADING));
|
||||||
const auto maxWidth = pageWidth - 40;
|
// Trim long titles to keep them within the content bounds.
|
||||||
// Trim long titles to keep them within the screen bounds.
|
auto title = renderer.truncatedText(UI_10_FONT_ID, statusMessage.c_str(), contentRect.width - 40);
|
||||||
auto title = renderer.truncatedText(UI_10_FONT_ID, statusMessage.c_str(), maxWidth);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 10, title.c_str());
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 10, title.c_str());
|
|
||||||
if (downloadTotal > 0) {
|
if (downloadTotal > 0) {
|
||||||
const int barWidth = pageWidth - 100;
|
const int barWidth = contentRect.width - 100;
|
||||||
constexpr int barHeight = 20;
|
constexpr int barHeight = 20;
|
||||||
constexpr int barX = 50;
|
const int barX = contentRect.x + 50;
|
||||||
const int barY = pageHeight / 2 + 20;
|
const int barY = midY + 20;
|
||||||
GUI.drawProgressBar(renderer, Rect{barX, barY, barWidth, barHeight}, downloadProgress, downloadTotal);
|
GUI.drawProgressBar(renderer, Rect{barX, barY, barWidth, barHeight}, downloadProgress, downloadTotal);
|
||||||
}
|
}
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
@@ -196,13 +195,13 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
|
|||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
|
|
||||||
if (entries.empty()) {
|
if (entries.empty()) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, tr(STR_NO_ENTRIES));
|
renderer.drawCenteredText(UI_10_FONT_ID, midY, tr(STR_NO_ENTRIES));
|
||||||
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(contentRect.x, 60 + (selectorIndex % PAGE_ITEMS) * 30 - 2, contentRect.width - 1, 30);
|
||||||
|
|
||||||
for (size_t i = pageStartIndex; i < entries.size() && i < static_cast<size_t>(pageStartIndex + PAGE_ITEMS); i++) {
|
for (size_t i = pageStartIndex; i < entries.size() && i < static_cast<size_t>(pageStartIndex + PAGE_ITEMS); i++) {
|
||||||
const auto& entry = entries[i];
|
const auto& entry = entries[i];
|
||||||
@@ -219,8 +218,8 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto item = renderer.truncatedText(UI_10_FONT_ID, displayText.c_str(), renderer.getScreenWidth() - 40);
|
auto item = renderer.truncatedText(UI_10_FONT_ID, displayText.c_str(), contentRect.width - 40);
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 60 + (i % PAGE_ITEMS) * 30, item.c_str(),
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 60 + (i % PAGE_ITEMS) * 30, item.c_str(),
|
||||||
i != static_cast<size_t>(selectorIndex));
|
i != static_cast<size_t>(selectorIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,13 +27,14 @@ std::string BookInfoActivity::formatFileSize(const size_t bytes) {
|
|||||||
void BookInfoActivity::renderLoading() {
|
void BookInfoActivity::renderLoading() {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_INFO));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_INFO));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
renderer.drawText(UI_12_FONT_ID, metrics.contentSidePadding, contentTop, tr(STR_LOADING));
|
renderer.drawText(UI_12_FONT_ID, contentRect.x + metrics.contentSidePadding, contentTop, tr(STR_LOADING));
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
}
|
}
|
||||||
@@ -111,17 +112,17 @@ void BookInfoActivity::loop() {
|
|||||||
void BookInfoActivity::render(RenderLock&&) {
|
void BookInfoActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_INFO));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_INFO));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentBottom = pageHeight - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
const int contentBottom = contentRect.y + contentRect.height - metrics.verticalSpacing;
|
||||||
const int textX = metrics.contentSidePadding;
|
const int textX = contentRect.x + metrics.contentSidePadding;
|
||||||
const int textWidth = pageWidth - metrics.contentSidePadding * 2;
|
const int textWidth = contentRect.width - metrics.contentSidePadding * 2;
|
||||||
const int lineHeightSmall = renderer.getLineHeight(UI_10_FONT_ID);
|
const int lineHeightSmall = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const int lineHeightLarge = renderer.getLineHeight(UI_12_FONT_ID);
|
const int lineHeightLarge = renderer.getLineHeight(UI_12_FONT_ID);
|
||||||
|
|
||||||
@@ -240,7 +241,7 @@ void BookInfoActivity::render(RenderLock&&) {
|
|||||||
if (!description.empty()) {
|
if (!description.empty()) {
|
||||||
int y = topSectionBottom + metrics.verticalSpacing;
|
int y = topSectionBottom + metrics.verticalSpacing;
|
||||||
if (y + lineHeightSmall + 4 < contentBottom) {
|
if (y + lineHeightSmall + 4 < contentBottom) {
|
||||||
renderer.drawLine(textX, y, pageWidth - metrics.contentSidePadding, y);
|
renderer.drawLine(textX, y, contentRect.x + contentRect.width - metrics.contentSidePadding, y);
|
||||||
y += 4;
|
y += 4;
|
||||||
|
|
||||||
const int descMaxLines = (contentBottom - y) / lineHeightSmall;
|
const int descMaxLines = (contentBottom - y) / lineHeightSmall;
|
||||||
|
|||||||
@@ -269,20 +269,21 @@ std::string getFileName(std::string filename) {
|
|||||||
void FileBrowserActivity::render(RenderLock&&) {
|
void FileBrowserActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, true);
|
||||||
|
|
||||||
std::string folderName = (basepath == "/") ? tr(STR_SD_CARD) : basepath.substr(basepath.rfind('/') + 1);
|
std::string folderName = (basepath == "/") ? tr(STR_SD_CARD) : basepath.substr(basepath.rfind('/') + 1);
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, folderName.c_str());
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
folderName.c_str());
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing;
|
||||||
if (files.empty()) {
|
if (files.empty()) {
|
||||||
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding, contentTop + 20, tr(STR_NO_FILES_FOUND));
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + metrics.contentSidePadding, contentTop + 20,
|
||||||
|
tr(STR_NO_FILES_FOUND));
|
||||||
} else {
|
} else {
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, files.size(), selectorIndex,
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, files.size(), selectorIndex,
|
||||||
[this](int index) { return getFileName(files[index]); }, nullptr,
|
[this](int index) { return getFileName(files[index]); }, nullptr,
|
||||||
[this](int index) { return UITheme::getFileIcon(files[index]); });
|
[this](int index) { return UITheme::getFileIcon(files[index]); });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,15 +212,15 @@ void HomeActivity::loop() {
|
|||||||
|
|
||||||
void HomeActivity::render(RenderLock&&) {
|
void HomeActivity::render(RenderLock&&) {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
bool bufferRestored = coverBufferStored && restoreCoverBuffer();
|
bool bufferRestored = coverBufferStored && restoreCoverBuffer();
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.homeTopPadding}, nullptr);
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.homeTopPadding}, nullptr);
|
||||||
|
|
||||||
GUI.drawRecentBookCover(renderer, Rect{0, metrics.homeTopPadding, pageWidth, metrics.homeCoverTileHeight},
|
GUI.drawRecentBookCover(renderer,
|
||||||
|
Rect{contentRect.x, metrics.homeTopPadding, contentRect.width, metrics.homeCoverTileHeight},
|
||||||
recentBooks, selectorIndex, coverRendered, coverBufferStored, bufferRestored,
|
recentBooks, selectorIndex, coverRendered, coverBufferStored, bufferRestored,
|
||||||
std::bind(&HomeActivity::storeCoverBuffer, this));
|
std::bind(&HomeActivity::storeCoverBuffer, this));
|
||||||
|
|
||||||
@@ -237,9 +237,9 @@ void HomeActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
GUI.drawButtonMenu(
|
GUI.drawButtonMenu(
|
||||||
renderer,
|
renderer,
|
||||||
Rect{0, metrics.homeTopPadding + metrics.homeCoverTileHeight + metrics.verticalSpacing, pageWidth,
|
Rect{contentRect.x, metrics.homeTopPadding + metrics.homeCoverTileHeight + metrics.verticalSpacing,
|
||||||
pageHeight - (metrics.headerHeight + metrics.homeTopPadding + metrics.verticalSpacing * 2 +
|
contentRect.width,
|
||||||
metrics.buttonHintsHeight)},
|
contentRect.height - (metrics.headerHeight + metrics.homeTopPadding + metrics.verticalSpacing * 2)},
|
||||||
static_cast<int>(menuItems.size()), selectorIndex - recentBooks.size(),
|
static_cast<int>(menuItems.size()), selectorIndex - recentBooks.size(),
|
||||||
[&menuItems](int index) { return std::string(menuItems[index]); },
|
[&menuItems](int index) { return std::string(menuItems[index]); },
|
||||||
[&menuIcons](int index) { return menuIcons[index]; });
|
[&menuIcons](int index) { return menuIcons[index]; });
|
||||||
|
|||||||
@@ -98,21 +98,22 @@ void RecentBooksActivity::loop() {
|
|||||||
void RecentBooksActivity::render(RenderLock&&) {
|
void RecentBooksActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, true);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_MENU_RECENT_BOOKS));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_MENU_RECENT_BOOKS));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing;
|
||||||
|
|
||||||
// Recent tab
|
// Recent tab
|
||||||
if (recentBooks.empty()) {
|
if (recentBooks.empty()) {
|
||||||
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding, contentTop + 20, tr(STR_NO_RECENT_BOOKS));
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + metrics.contentSidePadding, contentTop + 20,
|
||||||
|
tr(STR_NO_RECENT_BOOKS));
|
||||||
} else {
|
} else {
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, recentBooks.size(), selectorIndex,
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, recentBooks.size(), selectorIndex,
|
||||||
[this](int index) { return recentBooks[index].title; },
|
[this](int index) { return recentBooks[index].title; },
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
const auto& book = recentBooks[index];
|
const auto& book = recentBooks[index];
|
||||||
|
|||||||
@@ -169,57 +169,59 @@ void CalibreConnectActivity::loop() {
|
|||||||
|
|
||||||
void CalibreConnectActivity::render(RenderLock&&) {
|
void CalibreConnectActivity::render(RenderLock&&) {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_CALIBRE_WIRELESS));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_CALIBRE_WIRELESS));
|
||||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const auto top = (pageHeight - height) / 2;
|
const auto top = contentRect.y + (contentRect.height - height) / 2;
|
||||||
|
|
||||||
if (state == CalibreConnectState::SERVER_STARTING) {
|
if (state == CalibreConnectState::SERVER_STARTING) {
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, top, tr(STR_CALIBRE_STARTING));
|
renderer.drawCenteredText(UI_12_FONT_ID, top, tr(STR_CALIBRE_STARTING));
|
||||||
} else if (state == CalibreConnectState::ERROR) {
|
} else if (state == CalibreConnectState::ERROR) {
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, top, tr(STR_CONNECTION_FAILED), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_12_FONT_ID, top, tr(STR_CONNECTION_FAILED), true, EpdFontFamily::BOLD);
|
||||||
} else if (state == CalibreConnectState::SERVER_RUNNING) {
|
} else if (state == CalibreConnectState::SERVER_RUNNING) {
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
GUI.drawSubHeader(
|
||||||
connectedSSID.c_str(), (std::string(tr(STR_IP_ADDRESS_PREFIX)) + connectedIP).c_str());
|
renderer,
|
||||||
|
Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
connectedSSID.c_str(), (std::string(tr(STR_IP_ADDRESS_PREFIX)) + connectedIP).c_str());
|
||||||
|
|
||||||
|
const int textX = contentRect.x + metrics.contentSidePadding;
|
||||||
|
const int textWidth = contentRect.width - metrics.contentSidePadding * 2;
|
||||||
int y = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 4;
|
int y = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 4;
|
||||||
const auto heightText12 = renderer.getTextHeight(UI_12_FONT_ID);
|
const auto heightText12 = renderer.getTextHeight(UI_12_FONT_ID);
|
||||||
renderer.drawText(UI_12_FONT_ID, metrics.contentSidePadding, y, tr(STR_CALIBRE_SETUP), true, EpdFontFamily::BOLD);
|
renderer.drawText(UI_12_FONT_ID, textX, y, tr(STR_CALIBRE_SETUP), true, EpdFontFamily::BOLD);
|
||||||
y += heightText12 + metrics.verticalSpacing * 2;
|
y += heightText12 + metrics.verticalSpacing * 2;
|
||||||
|
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y, tr(STR_CALIBRE_INSTRUCTION_1));
|
renderer.drawText(SMALL_FONT_ID, textX, y, tr(STR_CALIBRE_INSTRUCTION_1));
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y + height, tr(STR_CALIBRE_INSTRUCTION_2));
|
renderer.drawText(SMALL_FONT_ID, textX, y + height, tr(STR_CALIBRE_INSTRUCTION_2));
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y + height * 2, tr(STR_CALIBRE_INSTRUCTION_3));
|
renderer.drawText(SMALL_FONT_ID, textX, y + height * 2, tr(STR_CALIBRE_INSTRUCTION_3));
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y + height * 3, tr(STR_CALIBRE_INSTRUCTION_4));
|
renderer.drawText(SMALL_FONT_ID, textX, y + height * 3, tr(STR_CALIBRE_INSTRUCTION_4));
|
||||||
|
|
||||||
y += height * 3 + metrics.verticalSpacing * 4;
|
y += height * 3 + metrics.verticalSpacing * 4;
|
||||||
renderer.drawText(UI_12_FONT_ID, metrics.contentSidePadding, y, tr(STR_CALIBRE_STATUS), true, EpdFontFamily::BOLD);
|
renderer.drawText(UI_12_FONT_ID, textX, y, tr(STR_CALIBRE_STATUS), true, EpdFontFamily::BOLD);
|
||||||
y += heightText12 + metrics.verticalSpacing * 2;
|
y += heightText12 + metrics.verticalSpacing * 2;
|
||||||
|
|
||||||
if (lastProgressTotal > 0 && lastProgressReceived <= lastProgressTotal) {
|
if (lastProgressTotal > 0 && lastProgressReceived <= lastProgressTotal) {
|
||||||
std::string label = tr(STR_CALIBRE_RECEIVING);
|
std::string label = tr(STR_CALIBRE_RECEIVING);
|
||||||
if (!currentUploadName.empty()) {
|
if (!currentUploadName.empty()) {
|
||||||
label += ": " + currentUploadName;
|
label += ": " + currentUploadName;
|
||||||
label = renderer.truncatedText(SMALL_FONT_ID, label.c_str(), pageWidth - metrics.contentSidePadding * 2,
|
label = renderer.truncatedText(SMALL_FONT_ID, label.c_str(), textWidth, EpdFontFamily::REGULAR);
|
||||||
EpdFontFamily::REGULAR);
|
|
||||||
}
|
}
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y, label.c_str());
|
renderer.drawText(SMALL_FONT_ID, textX, y, label.c_str());
|
||||||
GUI.drawProgressBar(renderer,
|
GUI.drawProgressBar(renderer,
|
||||||
Rect{metrics.contentSidePadding, y + height + metrics.verticalSpacing,
|
Rect{contentRect.x + metrics.contentSidePadding, y + height + metrics.verticalSpacing,
|
||||||
pageWidth - metrics.contentSidePadding * 2, metrics.progressBarHeight},
|
textWidth, metrics.progressBarHeight},
|
||||||
lastProgressReceived, lastProgressTotal);
|
lastProgressReceived, lastProgressTotal);
|
||||||
y += height + metrics.verticalSpacing * 2 + metrics.progressBarHeight;
|
y += height + metrics.verticalSpacing * 2 + metrics.progressBarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastCompleteAt > 0 && (millis() - lastCompleteAt) < 6000) {
|
if (lastCompleteAt > 0 && (millis() - lastCompleteAt) < 6000) {
|
||||||
std::string msg = std::string(tr(STR_CALIBRE_RECEIVED)) + lastCompleteName;
|
std::string msg = std::string(tr(STR_CALIBRE_RECEIVED)) + lastCompleteName;
|
||||||
msg = renderer.truncatedText(SMALL_FONT_ID, msg.c_str(), pageWidth - metrics.contentSidePadding * 2,
|
msg = renderer.truncatedText(SMALL_FONT_ID, msg.c_str(), textWidth, EpdFontFamily::REGULAR);
|
||||||
EpdFontFamily::REGULAR);
|
renderer.drawText(SMALL_FONT_ID, textX, y, msg.c_str());
|
||||||
renderer.drawText(SMALL_FONT_ID, metrics.contentSidePadding, y, msg.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_EXIT), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_EXIT), "", "", "");
|
||||||
|
|||||||
@@ -348,19 +348,20 @@ void CrossPointWebServerActivity::render(RenderLock&&) {
|
|||||||
if (state == WebServerActivityState::SERVER_RUNNING || state == WebServerActivityState::AP_STARTING) {
|
if (state == WebServerActivityState::SERVER_RUNNING || state == WebServerActivityState::AP_STARTING) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight},
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
isApMode ? tr(STR_HOTSPOT_MODE) : tr(STR_FILE_TRANSFER), nullptr);
|
isApMode ? tr(STR_HOTSPOT_MODE) : tr(STR_FILE_TRANSFER), nullptr);
|
||||||
|
|
||||||
if (state == WebServerActivityState::SERVER_RUNNING) {
|
if (state == WebServerActivityState::SERVER_RUNNING) {
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
GUI.drawSubHeader(
|
||||||
connectedSSID.c_str());
|
renderer,
|
||||||
|
Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
connectedSSID.c_str());
|
||||||
renderServerRunning();
|
renderServerRunning();
|
||||||
} else {
|
} else {
|
||||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const auto top = (pageHeight - height) / 2;
|
const auto top = contentRect.y + (contentRect.height - height) / 2;
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_STARTING_HOTSPOT));
|
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_STARTING_HOTSPOT));
|
||||||
}
|
}
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
@@ -369,12 +370,13 @@ void CrossPointWebServerActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
void CrossPointWebServerActivity::renderServerRunning() const {
|
void CrossPointWebServerActivity::renderServerRunning() const {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight},
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
isApMode ? tr(STR_HOTSPOT_MODE) : tr(STR_FILE_TRANSFER), nullptr);
|
isApMode ? tr(STR_HOTSPOT_MODE) : tr(STR_FILE_TRANSFER), nullptr);
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
GUI.drawSubHeader(
|
||||||
connectedSSID.c_str());
|
renderer, Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
connectedSSID.c_str());
|
||||||
|
|
||||||
int startY = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 2;
|
int startY = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 2;
|
||||||
int height10 = renderer.getLineHeight(UI_10_FONT_ID);
|
int height10 = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
@@ -424,7 +426,7 @@ void CrossPointWebServerActivity::renderServerRunning() const {
|
|||||||
|
|
||||||
// Show QR code for URL
|
// Show QR code for URL
|
||||||
std::string webInfo = "http://" + connectedIP + "/";
|
std::string webInfo = "http://" + connectedIP + "/";
|
||||||
const Rect qrBounds((pageWidth - QR_CODE_WIDTH) / 2, startY, QR_CODE_WIDTH, QR_CODE_HEIGHT);
|
const Rect qrBounds(contentRect.x + (contentRect.width - QR_CODE_WIDTH) / 2, startY, QR_CODE_WIDTH, QR_CODE_HEIGHT);
|
||||||
QrUtils::drawQrCode(renderer, qrBounds, webInfo);
|
QrUtils::drawQrCode(renderer, qrBounds, webInfo);
|
||||||
startY += QR_CODE_HEIGHT + metrics.verticalSpacing * 2;
|
startY += QR_CODE_HEIGHT + metrics.verticalSpacing * 2;
|
||||||
|
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ void NetworkModeSelectionActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_FILE_TRANSFER));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_FILE_TRANSFER));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing * 2;
|
||||||
// Menu items and descriptions
|
// Menu items and descriptions
|
||||||
static constexpr StrId menuItems[MENU_ITEM_COUNT] = {StrId::STR_JOIN_NETWORK, StrId::STR_CALIBRE_WIRELESS,
|
static constexpr StrId menuItems[MENU_ITEM_COUNT] = {StrId::STR_JOIN_NETWORK, StrId::STR_CALIBRE_WIRELESS,
|
||||||
StrId::STR_CREATE_HOTSPOT};
|
StrId::STR_CREATE_HOTSPOT};
|
||||||
@@ -73,8 +73,8 @@ void NetworkModeSelectionActivity::render(RenderLock&&) {
|
|||||||
static constexpr UIIcon menuIcons[MENU_ITEM_COUNT] = {UIIcon::Wifi, UIIcon::Library, UIIcon::Hotspot};
|
static constexpr UIIcon menuIcons[MENU_ITEM_COUNT] = {UIIcon::Wifi, UIIcon::Library, UIIcon::Hotspot};
|
||||||
|
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(MENU_ITEM_COUNT), selectedIndex,
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, static_cast<int>(MENU_ITEM_COUNT),
|
||||||
[](int index) { return std::string(I18N.get(menuItems[index])); },
|
selectedIndex, [](int index) { return std::string(I18N.get(menuItems[index])); },
|
||||||
[](int index) { return std::string(I18N.get(menuDescs[index])); }, [](int index) { return menuIcons[index]; });
|
[](int index) { return std::string(I18N.get(menuDescs[index])); }, [](int index) { return menuIcons[index]; });
|
||||||
|
|
||||||
// Draw help text at bottom
|
// Draw help text at bottom
|
||||||
|
|||||||
@@ -472,16 +472,16 @@ void WifiSelectionActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
// Draw header
|
// Draw header
|
||||||
char countStr[32];
|
char countStr[32];
|
||||||
snprintf(countStr, sizeof(countStr), tr(STR_NETWORKS_FOUND), networks.size());
|
snprintf(countStr, sizeof(countStr), tr(STR_NETWORKS_FOUND), networks.size());
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_WIFI_NETWORKS),
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
countStr);
|
tr(STR_WIFI_NETWORKS), countStr);
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
GUI.drawSubHeader(
|
||||||
cachedMacAddress.c_str());
|
renderer, Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
cachedMacAddress.c_str());
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case WifiSelectionState::AUTO_CONNECTING:
|
case WifiSelectionState::AUTO_CONNECTING:
|
||||||
@@ -515,20 +515,19 @@ void WifiSelectionActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
void WifiSelectionActivity::renderNetworkList() const {
|
void WifiSelectionActivity::renderNetworkList() const {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
if (networks.empty()) {
|
if (networks.empty()) {
|
||||||
// No networks found or scan failed
|
// No networks found or scan failed
|
||||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const auto top = (pageHeight - height) / 2;
|
const auto top = (contentRect.y + contentRect.height - height) / 2;
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_NO_NETWORKS));
|
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_NO_NETWORKS));
|
||||||
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, tr(STR_PRESS_OK_SCAN));
|
renderer.drawCenteredText(SMALL_FONT_ID, top + height + 10, tr(STR_PRESS_OK_SCAN));
|
||||||
} else {
|
} else {
|
||||||
int contentTop = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
|
int contentTop = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
|
||||||
int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing * 2;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(networks.size()),
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, static_cast<int>(networks.size()),
|
||||||
selectedNetworkIndex, [this](int index) { return networks[index].ssid; }, nullptr, nullptr,
|
selectedNetworkIndex, [this](int index) { return networks[index].ssid; }, nullptr, nullptr,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
auto network = networks[index];
|
auto network = networks[index];
|
||||||
@@ -537,9 +536,10 @@ void WifiSelectionActivity::renderNetworkList() const {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.drawHelpText(renderer,
|
GUI.drawHelpText(
|
||||||
Rect{0, pageHeight - metrics.buttonHintsHeight - metrics.contentSidePadding - 15, pageWidth, 20},
|
renderer,
|
||||||
tr(STR_NETWORK_LEGEND));
|
Rect{contentRect.x, contentRect.y + contentRect.height - metrics.contentSidePadding - 15, contentRect.width, 20},
|
||||||
|
tr(STR_NETWORK_LEGEND));
|
||||||
|
|
||||||
const bool hasSavedPassword = !networks.empty() && networks[selectedNetworkIndex].hasSavedPassword;
|
const bool hasSavedPassword = !networks.empty() && networks[selectedNetworkIndex].hasSavedPassword;
|
||||||
const char* forgetLabel = hasSavedPassword ? tr(STR_FORGET_BUTTON) : "";
|
const char* forgetLabel = hasSavedPassword ? tr(STR_FORGET_BUTTON) : "";
|
||||||
|
|||||||
@@ -10,17 +10,10 @@
|
|||||||
int EpubReaderChapterSelectionActivity::getTotalItems() const { return epub->getTocItemsCount(); }
|
int EpubReaderChapterSelectionActivity::getTotalItems() const { return epub->getTocItemsCount(); }
|
||||||
|
|
||||||
int EpubReaderChapterSelectionActivity::getPageItems() const {
|
int EpubReaderChapterSelectionActivity::getPageItems() const {
|
||||||
// Layout constants used in renderScreen
|
|
||||||
constexpr int lineHeight = 30;
|
constexpr int lineHeight = 30;
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const int screenHeight = renderer.getScreenHeight();
|
const int startY = 60 + contentRect.y;
|
||||||
const auto orientation = renderer.getOrientation();
|
const int availableHeight = contentRect.y + contentRect.height - startY - lineHeight;
|
||||||
// In inverted portrait, the button hints are drawn near the logical top.
|
|
||||||
// Reserve vertical space so list items do not collide with the hints.
|
|
||||||
const bool isPortraitInverted = orientation == GfxRenderer::Orientation::PortraitInverted;
|
|
||||||
const int hintGutterHeight = isPortraitInverted ? 50 : 0;
|
|
||||||
const int startY = 60 + hintGutterHeight;
|
|
||||||
const int availableHeight = screenHeight - startY - lineHeight;
|
|
||||||
// Clamp to at least one item to avoid division by zero and empty paging.
|
// Clamp to at least one item to avoid division by zero and empty paging.
|
||||||
return std::max(1, availableHeight / lineHeight);
|
return std::max(1, availableHeight / lineHeight);
|
||||||
}
|
}
|
||||||
@@ -89,43 +82,33 @@ void EpubReaderChapterSelectionActivity::loop() {
|
|||||||
void EpubReaderChapterSelectionActivity::render(RenderLock&&) {
|
void EpubReaderChapterSelectionActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto orientation = renderer.getOrientation();
|
|
||||||
// Landscape orientation: reserve a horizontal gutter for button hints.
|
|
||||||
const bool isLandscapeCw = orientation == GfxRenderer::Orientation::LandscapeClockwise;
|
|
||||||
const bool isLandscapeCcw = orientation == GfxRenderer::Orientation::LandscapeCounterClockwise;
|
|
||||||
// Inverted portrait: reserve vertical space for hints at the top.
|
|
||||||
const bool isPortraitInverted = orientation == GfxRenderer::Orientation::PortraitInverted;
|
|
||||||
const int hintGutterWidth = (isLandscapeCw || isLandscapeCcw) ? 30 : 0;
|
|
||||||
// Landscape CW places hints on the left edge; CCW keeps them on the right.
|
|
||||||
const int contentX = isLandscapeCw ? hintGutterWidth : 0;
|
|
||||||
const int contentWidth = pageWidth - hintGutterWidth;
|
|
||||||
const int hintGutterHeight = isPortraitInverted ? 50 : 0;
|
|
||||||
const int contentY = hintGutterHeight;
|
|
||||||
const int pageItems = getPageItems();
|
const int pageItems = getPageItems();
|
||||||
const int totalItems = getTotalItems();
|
const int totalItems = getTotalItems();
|
||||||
|
|
||||||
// Manual centering to honor content gutters.
|
// Manual centering to honor content gutters.
|
||||||
const int titleX =
|
const int titleX =
|
||||||
contentX + (contentWidth - renderer.getTextWidth(UI_12_FONT_ID, tr(STR_SELECT_CHAPTER), EpdFontFamily::BOLD)) / 2;
|
contentRect.x +
|
||||||
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentY, tr(STR_SELECT_CHAPTER), true, EpdFontFamily::BOLD);
|
(contentRect.width - renderer.getTextWidth(UI_12_FONT_ID, tr(STR_SELECT_CHAPTER), EpdFontFamily::BOLD)) / 2;
|
||||||
|
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentRect.y, tr(STR_SELECT_CHAPTER), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
||||||
// Highlight only the content area, not the hint gutters.
|
// Highlight only the content area, not the hint gutters.
|
||||||
renderer.fillRect(contentX, 60 + contentY + (selectorIndex % pageItems) * 30 - 2, contentWidth - 1, 30);
|
renderer.fillRect(contentRect.x, 60 + contentRect.y + (selectorIndex % pageItems) * 30 - 2, contentRect.width - 1,
|
||||||
|
30);
|
||||||
|
|
||||||
for (int i = 0; i < pageItems; i++) {
|
for (int i = 0; i < pageItems; i++) {
|
||||||
int itemIndex = pageStartIndex + i;
|
int itemIndex = pageStartIndex + i;
|
||||||
if (itemIndex >= totalItems) break;
|
if (itemIndex >= totalItems) break;
|
||||||
const int displayY = 60 + contentY + i * 30;
|
const int displayY = 60 + contentRect.y + i * 30;
|
||||||
const bool isSelected = (itemIndex == selectorIndex);
|
const bool isSelected = (itemIndex == selectorIndex);
|
||||||
|
|
||||||
auto item = epub->getTocItem(itemIndex);
|
auto item = epub->getTocItem(itemIndex);
|
||||||
|
|
||||||
// Indent per TOC level while keeping content within the gutter-safe region.
|
// Indent per TOC level while keeping content within the gutter-safe region.
|
||||||
const int indentSize = contentX + 20 + (item.level - 1) * 15;
|
const int indentSize = contentRect.x + 20 + (item.level - 1) * 15;
|
||||||
const std::string chapterName =
|
const std::string chapterName =
|
||||||
renderer.truncatedText(UI_10_FONT_ID, item.title.c_str(), contentWidth - 40 - indentSize);
|
renderer.truncatedText(UI_10_FONT_ID, item.title.c_str(), contentRect.width - 40 - indentSize);
|
||||||
|
|
||||||
renderer.drawText(UI_10_FONT_ID, indentSize, displayY, chapterName.c_str(), !isSelected);
|
renderer.drawText(UI_10_FONT_ID, indentSize, displayY, chapterName.c_str(), !isSelected);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,19 +64,19 @@ void EpubReaderFootnotesActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
constexpr int startY = 50;
|
constexpr int startY = 50;
|
||||||
constexpr int lineHeight = 36;
|
constexpr int lineHeight = 36;
|
||||||
const int screenWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
constexpr int marginLeft = 20;
|
constexpr int marginLeft = 20;
|
||||||
|
|
||||||
const int visibleCount = std::max(1, (renderer.getScreenHeight() - startY) / lineHeight);
|
const int visibleCount = std::max(1, (contentRect.height - startY) / lineHeight);
|
||||||
if (selectedIndex < scrollOffset) scrollOffset = selectedIndex;
|
if (selectedIndex < scrollOffset) scrollOffset = selectedIndex;
|
||||||
if (selectedIndex >= scrollOffset + visibleCount) scrollOffset = selectedIndex - visibleCount + 1;
|
if (selectedIndex >= scrollOffset + visibleCount) scrollOffset = selectedIndex - visibleCount + 1;
|
||||||
|
|
||||||
for (int i = scrollOffset; i < static_cast<int>(footnotes.size()) && i < scrollOffset + visibleCount; i++) {
|
for (int i = scrollOffset; i < static_cast<int>(footnotes.size()) && i < scrollOffset + visibleCount; i++) {
|
||||||
const int y = startY + (i - scrollOffset) * lineHeight;
|
const int y = contentRect.y + startY + (i - scrollOffset) * lineHeight;
|
||||||
const bool isSelected = (i == selectedIndex);
|
const bool isSelected = (i == selectedIndex);
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
renderer.fillRect(0, y, screenWidth, lineHeight, true);
|
renderer.fillRect(contentRect.x, y, contentRect.width, lineHeight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show footnote number and abbreviated href
|
// Show footnote number and abbreviated href
|
||||||
@@ -84,7 +84,7 @@ void EpubReaderFootnotesActivity::render(RenderLock&&) {
|
|||||||
if (label.empty()) {
|
if (label.empty()) {
|
||||||
label = tr(STR_LINK);
|
label = tr(STR_LINK);
|
||||||
}
|
}
|
||||||
renderer.drawText(UI_10_FONT_ID, marginLeft, y + 4, label.c_str(), !isSelected);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + marginLeft, y + 4, label.c_str(), !isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), "", "");
|
||||||
|
|||||||
@@ -86,29 +86,16 @@ void EpubReaderMenuActivity::loop() {
|
|||||||
|
|
||||||
void EpubReaderMenuActivity::render(RenderLock&&) {
|
void EpubReaderMenuActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto orientation = renderer.getOrientation();
|
|
||||||
// Landscape orientation: button hints are drawn along a vertical edge, so we
|
|
||||||
// reserve a horizontal gutter to prevent overlap with menu content.
|
|
||||||
const bool isLandscapeCw = orientation == GfxRenderer::Orientation::LandscapeClockwise;
|
|
||||||
const bool isLandscapeCcw = orientation == GfxRenderer::Orientation::LandscapeCounterClockwise;
|
|
||||||
// Inverted portrait: button hints appear near the logical top, so we reserve
|
|
||||||
// vertical space to keep the header and list clear.
|
|
||||||
const bool isPortraitInverted = orientation == GfxRenderer::Orientation::PortraitInverted;
|
|
||||||
const int hintGutterWidth = (isLandscapeCw || isLandscapeCcw) ? 30 : 0;
|
|
||||||
// Landscape CW places hints on the left edge; CCW keeps them on the right.
|
|
||||||
const int contentX = isLandscapeCw ? hintGutterWidth : 0;
|
|
||||||
const int contentWidth = pageWidth - hintGutterWidth;
|
|
||||||
const int hintGutterHeight = isPortraitInverted ? 50 : 0;
|
|
||||||
const int contentY = hintGutterHeight;
|
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
const std::string truncTitle =
|
const std::string truncTitle =
|
||||||
renderer.truncatedText(UI_12_FONT_ID, title.c_str(), contentWidth - 40, EpdFontFamily::BOLD);
|
renderer.truncatedText(UI_12_FONT_ID, title.c_str(), contentRect.width - 40, EpdFontFamily::BOLD);
|
||||||
// Manual centering so we can respect the content gutter.
|
// Manual centering so we can respect the content gutter.
|
||||||
const int titleX =
|
const int titleX =
|
||||||
contentX + (contentWidth - renderer.getTextWidth(UI_12_FONT_ID, truncTitle.c_str(), EpdFontFamily::BOLD)) / 2;
|
contentRect.x +
|
||||||
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentY, truncTitle.c_str(), true, EpdFontFamily::BOLD);
|
(contentRect.width - renderer.getTextWidth(UI_12_FONT_ID, truncTitle.c_str(), EpdFontFamily::BOLD)) / 2;
|
||||||
|
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentRect.y, truncTitle.c_str(), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
// Progress summary
|
// Progress summary
|
||||||
std::string progressLine;
|
std::string progressLine;
|
||||||
@@ -120,7 +107,7 @@ void EpubReaderMenuActivity::render(RenderLock&&) {
|
|||||||
renderer.drawCenteredText(UI_10_FONT_ID, 45, progressLine.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, 45, progressLine.c_str());
|
||||||
|
|
||||||
// Menu Items
|
// Menu Items
|
||||||
const int startY = 75 + contentY;
|
const int startY = 75 + contentRect.y;
|
||||||
constexpr int lineHeight = 30;
|
constexpr int lineHeight = 30;
|
||||||
|
|
||||||
for (size_t i = 0; i < menuItems.size(); ++i) {
|
for (size_t i = 0; i < menuItems.size(); ++i) {
|
||||||
@@ -129,23 +116,23 @@ void EpubReaderMenuActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// Highlight only the content area so we don't paint over hint gutters.
|
// Highlight only the content area so we don't paint over hint gutters.
|
||||||
renderer.fillRect(contentX, displayY, contentWidth - 1, lineHeight, true);
|
renderer.fillRect(contentRect.x, displayY, contentRect.width - 1, lineHeight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.drawText(UI_10_FONT_ID, contentX + 20, displayY, I18N.get(menuItems[i].labelId), !isSelected);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, displayY, I18N.get(menuItems[i].labelId), !isSelected);
|
||||||
|
|
||||||
if (menuItems[i].action == MenuAction::ROTATE_SCREEN) {
|
if (menuItems[i].action == MenuAction::ROTATE_SCREEN) {
|
||||||
// Render current orientation value on the right edge of the content area.
|
// Render current orientation value on the right edge of the content area.
|
||||||
const char* value = I18N.get(orientationLabels[pendingOrientation]);
|
const char* value = I18N.get(orientationLabels[pendingOrientation]);
|
||||||
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
||||||
renderer.drawText(UI_10_FONT_ID, contentX + contentWidth - 20 - width, displayY, value, !isSelected);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + contentRect.width - 20 - width, displayY, value, !isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menuItems[i].action == MenuAction::AUTO_PAGE_TURN) {
|
if (menuItems[i].action == MenuAction::AUTO_PAGE_TURN) {
|
||||||
// Render current page turn value on the right edge of the content area.
|
// Render current page turn value on the right edge of the content area.
|
||||||
const auto value = pageTurnLabels[selectedPageTurnOption];
|
const auto value = pageTurnLabels[selectedPageTurnOption];
|
||||||
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
const auto width = renderer.getTextWidth(UI_10_FONT_ID, value);
|
||||||
renderer.drawText(UI_10_FONT_ID, contentX + contentWidth - 20 - width, displayY, value, !isSelected);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + contentRect.width - 20 - width, displayY, value, !isSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ void EpubReaderPercentSelectionActivity::render(RenderLock&&) {
|
|||||||
renderer.drawCenteredText(UI_12_FONT_ID, 90, percentText.c_str(), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_12_FONT_ID, 90, percentText.c_str(), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
// Draw slider track.
|
// Draw slider track.
|
||||||
const int screenWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
constexpr int barWidth = 360;
|
constexpr int barWidth = 360;
|
||||||
constexpr int barHeight = 16;
|
constexpr int barHeight = 16;
|
||||||
const int barX = (screenWidth - barWidth) / 2;
|
const int barX = contentRect.x + (contentRect.width - barWidth) / 2;
|
||||||
const int barY = 140;
|
const int barY = 140;
|
||||||
|
|
||||||
renderer.drawRect(barX, barY, barWidth, barHeight);
|
renderer.drawRect(barX, barY, barWidth, barHeight);
|
||||||
|
|||||||
@@ -221,10 +221,10 @@ void KOReaderSyncActivity::onExit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KOReaderSyncActivity::render(RenderLock&&) {
|
void KOReaderSyncActivity::render(RenderLock&&) {
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, tr(STR_KOREADER_SYNC), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_12_FONT_ID, 15 + contentRect.y, tr(STR_KOREADER_SYNC), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
if (state == NO_CREDENTIALS) {
|
if (state == NO_CREDENTIALS) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, 280, tr(STR_NO_CREDENTIALS_MSG), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_10_FONT_ID, 280, tr(STR_NO_CREDENTIALS_MSG), true, EpdFontFamily::BOLD);
|
||||||
@@ -257,45 +257,46 @@ void KOReaderSyncActivity::render(RenderLock&&) {
|
|||||||
: (std::string(tr(STR_SECTION_PREFIX)) + std::to_string(currentSpineIndex + 1));
|
: (std::string(tr(STR_SECTION_PREFIX)) + std::to_string(currentSpineIndex + 1));
|
||||||
|
|
||||||
// Remote progress - chapter and page
|
// Remote progress - chapter and page
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 160, tr(STR_REMOTE_LABEL), true);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 160, tr(STR_REMOTE_LABEL), true);
|
||||||
char remoteChapterStr[128];
|
char remoteChapterStr[128];
|
||||||
snprintf(remoteChapterStr, sizeof(remoteChapterStr), " %s", remoteChapter.c_str());
|
snprintf(remoteChapterStr, sizeof(remoteChapterStr), " %s", remoteChapter.c_str());
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 185, remoteChapterStr);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 185, remoteChapterStr);
|
||||||
char remotePageStr[64];
|
char remotePageStr[64];
|
||||||
snprintf(remotePageStr, sizeof(remotePageStr), tr(STR_PAGE_OVERALL_FORMAT), remotePosition.pageNumber + 1,
|
snprintf(remotePageStr, sizeof(remotePageStr), tr(STR_PAGE_OVERALL_FORMAT), remotePosition.pageNumber + 1,
|
||||||
remoteProgress.percentage * 100);
|
remoteProgress.percentage * 100);
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 210, remotePageStr);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 210, remotePageStr);
|
||||||
|
|
||||||
if (!remoteProgress.device.empty()) {
|
if (!remoteProgress.device.empty()) {
|
||||||
char deviceStr[64];
|
char deviceStr[64];
|
||||||
snprintf(deviceStr, sizeof(deviceStr), tr(STR_DEVICE_FROM_FORMAT), remoteProgress.device.c_str());
|
snprintf(deviceStr, sizeof(deviceStr), tr(STR_DEVICE_FROM_FORMAT), remoteProgress.device.c_str());
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 235, deviceStr);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 235, deviceStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local progress - chapter and page
|
// Local progress - chapter and page
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 270, tr(STR_LOCAL_LABEL), true);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 270, tr(STR_LOCAL_LABEL), true);
|
||||||
char localChapterStr[128];
|
char localChapterStr[128];
|
||||||
snprintf(localChapterStr, sizeof(localChapterStr), " %s", localChapter.c_str());
|
snprintf(localChapterStr, sizeof(localChapterStr), " %s", localChapter.c_str());
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 295, localChapterStr);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 295, localChapterStr);
|
||||||
char localPageStr[64];
|
char localPageStr[64];
|
||||||
snprintf(localPageStr, sizeof(localPageStr), tr(STR_PAGE_TOTAL_OVERALL_FORMAT), currentPage + 1, totalPagesInSpine,
|
snprintf(localPageStr, sizeof(localPageStr), tr(STR_PAGE_TOTAL_OVERALL_FORMAT), currentPage + 1, totalPagesInSpine,
|
||||||
localProgress.percentage * 100);
|
localProgress.percentage * 100);
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, 320, localPageStr);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, 320, localPageStr);
|
||||||
|
|
||||||
const int optionY = 350;
|
const int optionY = 350;
|
||||||
const int optionHeight = 30;
|
const int optionHeight = 30;
|
||||||
|
|
||||||
// Apply option
|
// Apply option
|
||||||
if (selectedOption == 0) {
|
if (selectedOption == 0) {
|
||||||
renderer.fillRect(0, optionY - 2, pageWidth - 1, optionHeight);
|
renderer.fillRect(contentRect.x, optionY - 2, contentRect.width - 1, optionHeight);
|
||||||
}
|
}
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, optionY, tr(STR_APPLY_REMOTE), selectedOption != 0);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, optionY, tr(STR_APPLY_REMOTE), selectedOption != 0);
|
||||||
|
|
||||||
// Upload option
|
// Upload option
|
||||||
if (selectedOption == 1) {
|
if (selectedOption == 1) {
|
||||||
renderer.fillRect(0, optionY + optionHeight - 2, pageWidth - 1, optionHeight);
|
renderer.fillRect(contentRect.x, optionY + optionHeight - 2, contentRect.width - 1, optionHeight);
|
||||||
}
|
}
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, optionY + optionHeight, tr(STR_UPLOAD_LOCAL), selectedOption != 1);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, optionY + optionHeight, tr(STR_UPLOAD_LOCAL),
|
||||||
|
selectedOption != 1);
|
||||||
|
|
||||||
// Bottom button hints
|
// Bottom button hints
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
||||||
|
|||||||
@@ -25,17 +25,17 @@ void QrDisplayActivity::loop() {
|
|||||||
|
|
||||||
void QrDisplayActivity::render(RenderLock&&) {
|
void QrDisplayActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
auto metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_DISPLAY_QR), nullptr);
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_DISPLAY_QR), nullptr);
|
||||||
|
|
||||||
const int availableWidth = pageWidth - 40;
|
|
||||||
const int availableHeight = pageHeight - metrics.topPadding - metrics.headerHeight - metrics.verticalSpacing * 2 - 40;
|
|
||||||
const int startY = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int startY = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
|
const int availableHeight = contentRect.height - startY - metrics.verticalSpacing;
|
||||||
|
|
||||||
const Rect qrBounds(20, startY, availableWidth, availableHeight);
|
const Rect qrBounds(contentRect.x + metrics.contentSidePadding, startY,
|
||||||
|
contentRect.width - metrics.contentSidePadding * 2, availableHeight);
|
||||||
QrUtils::drawQrCode(renderer, qrBounds, textPayload);
|
QrUtils::drawQrCode(renderer, qrBounds, textPayload);
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||||||
|
|||||||
@@ -11,15 +11,9 @@
|
|||||||
|
|
||||||
int XtcReaderChapterSelectionActivity::getPageItems() const {
|
int XtcReaderChapterSelectionActivity::getPageItems() const {
|
||||||
constexpr int lineHeight = 30;
|
constexpr int lineHeight = 30;
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const int screenHeight = renderer.getScreenHeight();
|
constexpr int startY = 60;
|
||||||
const auto orientation = renderer.getOrientation();
|
const int availableHeight = contentRect.height - startY - lineHeight;
|
||||||
// In inverted portrait, the hint row is drawn near the logical top.
|
|
||||||
// Reserve vertical space so the list starts below the hints.
|
|
||||||
const bool isPortraitInverted = orientation == GfxRenderer::Orientation::PortraitInverted;
|
|
||||||
const int hintGutterHeight = isPortraitInverted ? 50 : 0;
|
|
||||||
const int startY = 60 + hintGutterHeight;
|
|
||||||
const int availableHeight = screenHeight - startY - lineHeight;
|
|
||||||
// Clamp to at least one item to prevent empty page math.
|
// Clamp to at least one item to prevent empty page math.
|
||||||
return std::max(1, availableHeight / lineHeight);
|
return std::max(1, availableHeight / lineHeight);
|
||||||
}
|
}
|
||||||
@@ -93,48 +87,35 @@ void XtcReaderChapterSelectionActivity::loop() {
|
|||||||
void XtcReaderChapterSelectionActivity::render(RenderLock&&) {
|
void XtcReaderChapterSelectionActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto orientation = renderer.getOrientation();
|
|
||||||
// Landscape orientation: reserve a horizontal gutter for button hints.
|
|
||||||
const bool isLandscapeCw = orientation == GfxRenderer::Orientation::LandscapeClockwise;
|
|
||||||
const bool isLandscapeCcw = orientation == GfxRenderer::Orientation::LandscapeCounterClockwise;
|
|
||||||
// Inverted portrait: reserve vertical space for hints at the top.
|
|
||||||
const bool isPortraitInverted = orientation == GfxRenderer::Orientation::PortraitInverted;
|
|
||||||
const int hintGutterWidth = (isLandscapeCw || isLandscapeCcw) ? 30 : 0;
|
|
||||||
// Landscape CW places hints on the left edge; CCW keeps them on the right.
|
|
||||||
const int contentX = isLandscapeCw ? hintGutterWidth : 0;
|
|
||||||
const int contentWidth = pageWidth - hintGutterWidth;
|
|
||||||
const int hintGutterHeight = isPortraitInverted ? 50 : 0;
|
|
||||||
const int contentY = hintGutterHeight;
|
|
||||||
const int pageItems = getPageItems();
|
const int pageItems = getPageItems();
|
||||||
// Manual centering to honor content gutters.
|
|
||||||
const int titleX =
|
const int titleX =
|
||||||
contentX + (contentWidth - renderer.getTextWidth(UI_12_FONT_ID, tr(STR_SELECT_CHAPTER), EpdFontFamily::BOLD)) / 2;
|
contentRect.x +
|
||||||
renderer.drawText(UI_12_FONT_ID, titleX, 15 + contentY, tr(STR_SELECT_CHAPTER), true, EpdFontFamily::BOLD);
|
(contentRect.width - renderer.getTextWidth(UI_12_FONT_ID, tr(STR_SELECT_CHAPTER), EpdFontFamily::BOLD)) / 2;
|
||||||
|
renderer.drawText(UI_12_FONT_ID, titleX, contentRect.y + 15, tr(STR_SELECT_CHAPTER), true, EpdFontFamily::BOLD);
|
||||||
|
|
||||||
const auto& chapters = xtc->getChapters();
|
const auto& chapters = xtc->getChapters();
|
||||||
if (chapters.empty()) {
|
if (chapters.empty()) {
|
||||||
// Center the empty state within the gutter-safe content region.
|
const int emptyX =
|
||||||
const int emptyX = contentX + (contentWidth - renderer.getTextWidth(UI_10_FONT_ID, tr(STR_NO_CHAPTERS))) / 2;
|
contentRect.x + (contentRect.width - renderer.getTextWidth(UI_10_FONT_ID, tr(STR_NO_CHAPTERS))) / 2;
|
||||||
renderer.drawText(UI_10_FONT_ID, emptyX, 120 + contentY, tr(STR_NO_CHAPTERS));
|
renderer.drawText(UI_10_FONT_ID, emptyX, contentRect.y + 120, tr(STR_NO_CHAPTERS));
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
||||||
// Highlight only the content area, not the hint gutters.
|
renderer.fillRect(contentRect.x, contentRect.y + 60 + (selectorIndex % pageItems) * 30 - 2, contentRect.width - 1,
|
||||||
renderer.fillRect(contentX, 60 + contentY + (selectorIndex % pageItems) * 30 - 2, contentWidth - 1, 30);
|
30);
|
||||||
for (int i = pageStartIndex; i < static_cast<int>(chapters.size()) && i < pageStartIndex + pageItems; i++) {
|
for (int i = pageStartIndex; i < static_cast<int>(chapters.size()) && i < pageStartIndex + pageItems; i++) {
|
||||||
const auto& chapter = chapters[i];
|
const auto& chapter = chapters[i];
|
||||||
const char* title = chapter.name.empty() ? tr(STR_UNNAMED) : chapter.name.c_str();
|
const char* title = chapter.name.empty() ? tr(STR_UNNAMED) : chapter.name.c_str();
|
||||||
renderer.drawText(UI_10_FONT_ID, contentX + 20, 60 + contentY + (i % pageItems) * 30, title, i != selectorIndex);
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + 20, contentRect.y + 60 + (i % pageItems) * 30, title,
|
||||||
|
i != selectorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip button hints in landscape CW mode (they overlap content)
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
||||||
if (renderer.getOrientation() != GfxRenderer::LandscapeClockwise) {
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SELECT), tr(STR_DIR_UP), tr(STR_DIR_DOWN));
|
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,19 +105,20 @@ void ButtonRemapActivity::render(RenderLock&&) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_REMAP_FRONT_BUTTONS));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
tr(STR_REMAP_FRONT_BUTTONS));
|
||||||
tr(STR_REMAP_PROMPT));
|
GUI.drawSubHeader(
|
||||||
|
renderer, Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
tr(STR_REMAP_PROMPT));
|
||||||
|
|
||||||
int topOffset = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
|
int topOffset = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
|
||||||
int contentHeight = pageHeight - topOffset - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
int contentHeight = contentRect.height - topOffset - metrics.verticalSpacing;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, topOffset, pageWidth, contentHeight}, kRoleCount, currentStep,
|
renderer, Rect{contentRect.x, topOffset, contentRect.width, contentHeight}, kRoleCount, currentStep,
|
||||||
[&](int index) { return getRoleName(static_cast<uint8_t>(index)); }, nullptr, nullptr,
|
[&](int index) { return getRoleName(static_cast<uint8_t>(index)); }, nullptr, nullptr,
|
||||||
[&](int index) {
|
[&](int index) {
|
||||||
uint8_t assignedButton = tempMapping[static_cast<uint8_t>(index)];
|
uint8_t assignedButton = tempMapping[static_cast<uint8_t>(index)];
|
||||||
@@ -128,16 +129,19 @@ void ButtonRemapActivity::render(RenderLock&&) {
|
|||||||
// Temporary warning banner for duplicates.
|
// Temporary warning banner for duplicates.
|
||||||
if (!errorMessage.empty()) {
|
if (!errorMessage.empty()) {
|
||||||
GUI.drawHelpText(renderer,
|
GUI.drawHelpText(renderer,
|
||||||
Rect{0, pageHeight - metrics.buttonHintsHeight - metrics.contentSidePadding - 15, pageWidth, 20},
|
Rect{contentRect.x, contentRect.y + contentRect.height - metrics.contentSidePadding - 15,
|
||||||
|
contentRect.width, 20},
|
||||||
errorMessage.c_str());
|
errorMessage.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provide side button actions at the bottom of the screen (split across two lines).
|
// Provide side button actions at the bottom of the screen (split across two lines).
|
||||||
|
GUI.drawHelpText(
|
||||||
|
renderer,
|
||||||
|
Rect{contentRect.x, topOffset + 4 * metrics.listRowHeight + 4 * metrics.verticalSpacing, contentRect.width, 20},
|
||||||
|
tr(STR_REMAP_RESET_HINT));
|
||||||
GUI.drawHelpText(renderer,
|
GUI.drawHelpText(renderer,
|
||||||
Rect{0, topOffset + 4 * metrics.listRowHeight + 4 * metrics.verticalSpacing, pageWidth, 20},
|
Rect{contentRect.x, topOffset + 4 * metrics.listRowHeight + 5 * metrics.verticalSpacing + 20,
|
||||||
tr(STR_REMAP_RESET_HINT));
|
contentRect.width, 20},
|
||||||
GUI.drawHelpText(renderer,
|
|
||||||
Rect{0, topOffset + 4 * metrics.listRowHeight + 5 * metrics.verticalSpacing + 20, pageWidth, 20},
|
|
||||||
tr(STR_REMAP_CANCEL_HINT));
|
tr(STR_REMAP_CANCEL_HINT));
|
||||||
|
|
||||||
// Live preview of logical labels under front buttons.
|
// Live preview of logical labels under front buttons.
|
||||||
|
|||||||
@@ -92,16 +92,17 @@ void CalibreSettingsActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_OPDS_BROWSER));
|
tr(STR_OPDS_BROWSER));
|
||||||
GUI.drawSubHeader(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight},
|
GUI.drawSubHeader(
|
||||||
tr(STR_CALIBRE_URL_HINT));
|
renderer, Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
tr(STR_CALIBRE_URL_HINT));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing + metrics.tabBarHeight;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing + metrics.tabBarHeight;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing * 2;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(MENU_ITEMS),
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, static_cast<int>(MENU_ITEMS),
|
||||||
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
|
|||||||
@@ -20,19 +20,19 @@ void ClearCacheActivity::onExit() { Activity::onExit(); }
|
|||||||
|
|
||||||
void ClearCacheActivity::render(RenderLock&&) {
|
void ClearCacheActivity::render(RenderLock&&) {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_CLEAR_READING_CACHE));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_CLEAR_READING_CACHE));
|
||||||
|
|
||||||
|
const int midY = contentRect.y + contentRect.height / 2;
|
||||||
if (state == WARNING) {
|
if (state == WARNING) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 60, tr(STR_CLEAR_CACHE_WARNING_1), true);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 60, tr(STR_CLEAR_CACHE_WARNING_1), true);
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 30, tr(STR_CLEAR_CACHE_WARNING_2), true,
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 30, tr(STR_CLEAR_CACHE_WARNING_2), true, EpdFontFamily::BOLD);
|
||||||
EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, tr(STR_CLEAR_CACHE_WARNING_3), true);
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 10, tr(STR_CLEAR_CACHE_WARNING_3), true);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY + 30, tr(STR_CLEAR_CACHE_WARNING_4), true);
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 30, tr(STR_CLEAR_CACHE_WARNING_4), true);
|
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_CANCEL), tr(STR_CLEAR_BUTTON), "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_CANCEL), tr(STR_CLEAR_BUTTON), "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
@@ -41,18 +41,18 @@ void ClearCacheActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == CLEARING) {
|
if (state == CLEARING) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, tr(STR_CLEARING_CACHE));
|
renderer.drawCenteredText(UI_10_FONT_ID, midY, tr(STR_CLEARING_CACHE));
|
||||||
renderer.displayBuffer();
|
renderer.displayBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == SUCCESS) {
|
if (state == SUCCESS) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 20, tr(STR_CACHE_CLEARED), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 20, tr(STR_CACHE_CLEARED), true, EpdFontFamily::BOLD);
|
||||||
std::string resultText = std::to_string(clearedCount) + " " + std::string(tr(STR_ITEMS_REMOVED));
|
std::string resultText = std::to_string(clearedCount) + " " + std::string(tr(STR_ITEMS_REMOVED));
|
||||||
if (failedCount > 0) {
|
if (failedCount > 0) {
|
||||||
resultText += ", " + std::to_string(failedCount) + " " + std::string(tr(STR_FAILED_LOWER));
|
resultText += ", " + std::to_string(failedCount) + " " + std::string(tr(STR_FAILED_LOWER));
|
||||||
}
|
}
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 10, resultText.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, resultText.c_str());
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
@@ -61,9 +61,8 @@ void ClearCacheActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state == FAILED) {
|
if (state == FAILED) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 - 20, tr(STR_CLEAR_CACHE_FAILED), true,
|
renderer.drawCenteredText(UI_10_FONT_ID, midY - 20, tr(STR_CLEAR_CACHE_FAILED), true, EpdFontFamily::BOLD);
|
||||||
EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, tr(STR_CHECK_SERIAL_OUTPUT));
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2 + 10, tr(STR_CHECK_SERIAL_OUTPUT));
|
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ void KOReaderAuthActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_KOREADER_AUTH));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_KOREADER_AUTH));
|
||||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const auto top = (pageHeight - height) / 2;
|
const auto top = contentRect.y + (contentRect.height - height) / 2;
|
||||||
|
|
||||||
if (state == AUTHENTICATING) {
|
if (state == AUTHENTICATING) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, statusMessage.c_str());
|
renderer.drawCenteredText(UI_10_FONT_ID, top, statusMessage.c_str());
|
||||||
|
|||||||
@@ -115,15 +115,15 @@ void KOReaderSettingsActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_KOREADER_SYNC));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_KOREADER_SYNC));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing * 2;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(MENU_ITEMS),
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, static_cast<int>(MENU_ITEMS),
|
||||||
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
|
|||||||
@@ -61,18 +61,18 @@ void LanguageSelectActivity::handleSelection() {
|
|||||||
void LanguageSelectActivity::render(RenderLock&&) {
|
void LanguageSelectActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
auto metrics = UITheme::getInstance().getMetrics();
|
auto metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_LANGUAGE));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_LANGUAGE));
|
||||||
|
|
||||||
// Current language marker
|
// Current language marker
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing;
|
||||||
const auto currentLang = static_cast<uint8_t>(I18N.getLanguage());
|
const auto currentLang = static_cast<uint8_t>(I18N.getLanguage());
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, totalItems, selectedIndex,
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, totalItems, selectedIndex,
|
||||||
[this](int index) { return I18N.getLanguageName(static_cast<Language>(SORTED_LANGUAGE_INDICES[index])); },
|
[this](int index) { return I18N.getLanguageName(static_cast<Language>(SORTED_LANGUAGE_INDICES[index])); },
|
||||||
nullptr, nullptr,
|
nullptr, nullptr,
|
||||||
[this, currentLang](int index) { return SORTED_LANGUAGE_INDICES[index] == currentLang ? tr(STR_SELECTED) : ""; },
|
[this, currentLang](int index) { return SORTED_LANGUAGE_INDICES[index] == currentLang ? tr(STR_SELECTED) : ""; },
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ void OtaUpdateActivity::onExit() {
|
|||||||
|
|
||||||
void OtaUpdateActivity::render(RenderLock&&) {
|
void OtaUpdateActivity::render(RenderLock&&) {
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_UPDATE));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_UPDATE));
|
||||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||||
const auto top = (pageHeight - height) / 2;
|
const auto top = contentRect.y + (contentRect.height - height) / 2;
|
||||||
|
|
||||||
float updaterProgress = 0;
|
float updaterProgress = 0;
|
||||||
if (state == UPDATE_IN_PROGRESS) {
|
if (state == UPDATE_IN_PROGRESS) {
|
||||||
@@ -99,9 +99,10 @@ void OtaUpdateActivity::render(RenderLock&&) {
|
|||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_CHECKING_UPDATE));
|
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_CHECKING_UPDATE));
|
||||||
} else if (state == WAITING_CONFIRMATION) {
|
} else if (state == WAITING_CONFIRMATION) {
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_NEW_UPDATE), true, EpdFontFamily::BOLD);
|
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_NEW_UPDATE), true, EpdFontFamily::BOLD);
|
||||||
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding, top + height + metrics.verticalSpacing,
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + metrics.contentSidePadding, top + height + metrics.verticalSpacing,
|
||||||
(std::string(tr(STR_CURRENT_VERSION)) + CROSSPOINT_VERSION).c_str());
|
(std::string(tr(STR_CURRENT_VERSION)) + CROSSPOINT_VERSION).c_str());
|
||||||
renderer.drawText(UI_10_FONT_ID, metrics.contentSidePadding, top + height * 2 + metrics.verticalSpacing * 2,
|
renderer.drawText(UI_10_FONT_ID, contentRect.x + metrics.contentSidePadding,
|
||||||
|
top + height * 2 + metrics.verticalSpacing * 2,
|
||||||
(std::string(tr(STR_NEW_VERSION)) + updater.getLatestVersion()).c_str());
|
(std::string(tr(STR_NEW_VERSION)) + updater.getLatestVersion()).c_str());
|
||||||
|
|
||||||
const auto labels = mappedInput.mapLabels(tr(STR_CANCEL), tr(STR_UPDATE), "", "");
|
const auto labels = mappedInput.mapLabels(tr(STR_CANCEL), tr(STR_UPDATE), "", "");
|
||||||
@@ -110,10 +111,10 @@ void OtaUpdateActivity::render(RenderLock&&) {
|
|||||||
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_UPDATING));
|
renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_UPDATING));
|
||||||
|
|
||||||
int y = top + height + metrics.verticalSpacing;
|
int y = top + height + metrics.verticalSpacing;
|
||||||
GUI.drawProgressBar(
|
GUI.drawProgressBar(renderer,
|
||||||
renderer,
|
Rect{contentRect.x + metrics.contentSidePadding, y,
|
||||||
Rect{metrics.contentSidePadding, y, pageWidth - metrics.contentSidePadding * 2, metrics.progressBarHeight},
|
contentRect.width - metrics.contentSidePadding * 2, metrics.progressBarHeight},
|
||||||
static_cast<int>(updaterProgress * 100), 100);
|
static_cast<int>(updaterProgress * 100), 100);
|
||||||
|
|
||||||
y += metrics.progressBarHeight + metrics.verticalSpacing;
|
y += metrics.progressBarHeight + metrics.verticalSpacing;
|
||||||
renderer.drawCenteredText(UI_10_FONT_ID, y,
|
renderer.drawCenteredText(UI_10_FONT_ID, y,
|
||||||
|
|||||||
@@ -202,28 +202,28 @@ void SettingsActivity::toggleCurrentSetting() {
|
|||||||
void SettingsActivity::render(RenderLock&&) {
|
void SettingsActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_SETTINGS_TITLE),
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
CROSSPOINT_VERSION);
|
tr(STR_SETTINGS_TITLE), CROSSPOINT_VERSION);
|
||||||
|
|
||||||
std::vector<TabInfo> tabs;
|
std::vector<TabInfo> tabs;
|
||||||
tabs.reserve(categoryCount);
|
tabs.reserve(categoryCount);
|
||||||
for (int i = 0; i < categoryCount; i++) {
|
for (int i = 0; i < categoryCount; i++) {
|
||||||
tabs.push_back({I18N.get(categoryNames[i]), selectedCategoryIndex == i});
|
tabs.push_back({I18N.get(categoryNames[i]), selectedCategoryIndex == i});
|
||||||
}
|
}
|
||||||
GUI.drawTabBar(renderer, Rect{0, metrics.topPadding + metrics.headerHeight, pageWidth, metrics.tabBarHeight}, tabs,
|
GUI.drawTabBar(
|
||||||
selectedSettingIndex == 0);
|
renderer, Rect{contentRect.x, metrics.topPadding + metrics.headerHeight, contentRect.width, metrics.tabBarHeight},
|
||||||
|
tabs, selectedSettingIndex == 0);
|
||||||
|
|
||||||
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing;
|
||||||
const auto& settings = *currentSettings;
|
const auto& settings = *currentSettings;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer,
|
renderer,
|
||||||
Rect{0, metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing, pageWidth,
|
Rect{contentRect.x, contentTop, contentRect.width,
|
||||||
pageHeight - (metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.buttonHintsHeight +
|
contentRect.height -
|
||||||
metrics.verticalSpacing * 2)},
|
(metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight + metrics.verticalSpacing * 2)},
|
||||||
settingsCount, selectedSettingIndex - 1,
|
settingsCount, selectedSettingIndex - 1,
|
||||||
[&settings](int index) { return std::string(I18N.get(settings[index].nameId)); }, nullptr, nullptr,
|
[&settings](int index) { return std::string(I18N.get(settings[index].nameId)); }, nullptr, nullptr,
|
||||||
[&settings](int i) {
|
[&settings](int i) {
|
||||||
|
|||||||
@@ -118,15 +118,15 @@ void StatusBarSettingsActivity::render(RenderLock&&) {
|
|||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
auto metrics = UITheme::getInstance().getMetrics();
|
auto metrics = UITheme::getInstance().getMetrics();
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_CUSTOMISE_STATUS_BAR));
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
tr(STR_CUSTOMISE_STATUS_BAR));
|
||||||
|
|
||||||
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
|
||||||
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing * 2;
|
const int contentHeight = contentRect.height - contentTop - metrics.verticalSpacing * 2;
|
||||||
GUI.drawList(
|
GUI.drawList(
|
||||||
renderer, Rect{0, contentTop, pageWidth, contentHeight}, static_cast<int>(MENU_ITEMS),
|
renderer, Rect{contentRect.x, contentTop, contentRect.width, contentHeight}, static_cast<int>(MENU_ITEMS),
|
||||||
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ void ConfirmationActivity::onEnter() {
|
|||||||
inputArmed = false;
|
inputArmed = false;
|
||||||
|
|
||||||
lineHeight = renderer.getLineHeight(fontId);
|
lineHeight = renderer.getLineHeight(fontId);
|
||||||
const int maxWidth = renderer.getScreenWidth() - (margin * 2);
|
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
|
||||||
|
const int maxWidth = contentRect.width - (margin * 2);
|
||||||
|
|
||||||
if (!heading.empty()) {
|
if (!heading.empty()) {
|
||||||
safeHeading = renderer.truncatedText(fontId, heading.c_str(), maxWidth, EpdFontFamily::BOLD);
|
safeHeading = renderer.truncatedText(fontId, heading.c_str(), maxWidth, EpdFontFamily::BOLD);
|
||||||
@@ -28,7 +29,7 @@ void ConfirmationActivity::onEnter() {
|
|||||||
if (!safeBody.empty()) totalHeight += lineHeight;
|
if (!safeBody.empty()) totalHeight += lineHeight;
|
||||||
if (!safeHeading.empty() && !safeBody.empty()) totalHeight += spacing;
|
if (!safeHeading.empty() && !safeBody.empty()) totalHeight += spacing;
|
||||||
|
|
||||||
startY = (renderer.getScreenHeight() - totalHeight) / 2;
|
startY = contentRect.y + (contentRect.height - totalHeight) / 2;
|
||||||
|
|
||||||
requestUpdate(true);
|
requestUpdate(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,11 +192,11 @@ void KeyboardEntryActivity::loop() {
|
|||||||
void KeyboardEntryActivity::render(RenderLock&&) {
|
void KeyboardEntryActivity::render(RenderLock&&) {
|
||||||
renderer.clearScreen();
|
renderer.clearScreen();
|
||||||
|
|
||||||
const auto pageWidth = renderer.getScreenWidth();
|
|
||||||
const auto pageHeight = renderer.getScreenHeight();
|
|
||||||
const auto& metrics = UITheme::getInstance().getMetrics();
|
const auto& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = UITheme::getContentRect(renderer, true, true);
|
||||||
|
|
||||||
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, title.c_str());
|
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.headerHeight},
|
||||||
|
title.c_str());
|
||||||
|
|
||||||
// Draw input field
|
// Draw input field
|
||||||
const int lineHeight = renderer.getLineHeight(UI_12_FONT_ID);
|
const int lineHeight = renderer.getLineHeight(UI_12_FONT_ID);
|
||||||
@@ -221,11 +221,13 @@ void KeyboardEntryActivity::render(RenderLock&&) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
std::string lineText = displayText.substr(lineStartIdx, lineEndIdx - lineStartIdx);
|
std::string lineText = displayText.substr(lineStartIdx, lineEndIdx - lineStartIdx);
|
||||||
textWidth = renderer.getTextWidth(UI_12_FONT_ID, lineText.c_str());
|
textWidth = renderer.getTextWidth(UI_12_FONT_ID, lineText.c_str());
|
||||||
if (textWidth <= pageWidth - 2 * metrics.contentSidePadding) {
|
if (textWidth <= contentRect.width - 2 * metrics.contentSidePadding) {
|
||||||
if (metrics.keyboardCenteredText) {
|
if (metrics.keyboardCenteredText) {
|
||||||
renderer.drawCenteredText(UI_12_FONT_ID, inputStartY + inputHeight, lineText.c_str());
|
const int centeredX = contentRect.x + (contentRect.width - textWidth) / 2;
|
||||||
|
renderer.drawText(UI_12_FONT_ID, centeredX, inputStartY + inputHeight, lineText.c_str());
|
||||||
} else {
|
} else {
|
||||||
renderer.drawText(UI_12_FONT_ID, metrics.contentSidePadding, inputStartY + inputHeight, lineText.c_str());
|
renderer.drawText(UI_12_FONT_ID, contentRect.x + metrics.contentSidePadding, inputStartY + inputHeight,
|
||||||
|
lineText.c_str());
|
||||||
}
|
}
|
||||||
if (lineEndIdx == displayText.length()) {
|
if (lineEndIdx == displayText.length()) {
|
||||||
break;
|
break;
|
||||||
@@ -239,11 +241,11 @@ void KeyboardEntryActivity::render(RenderLock&&) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.drawTextField(renderer, Rect{0, inputStartY, pageWidth, inputHeight}, textWidth);
|
GUI.drawTextField(renderer, Rect{contentRect.x, inputStartY, contentRect.width, inputHeight}, textWidth);
|
||||||
|
|
||||||
// Draw keyboard - use compact spacing to fit 5 rows on screen
|
// Draw keyboard - use compact spacing to fit 5 rows on screen
|
||||||
const int keyboardStartY = metrics.keyboardBottomAligned
|
const int keyboardStartY = metrics.keyboardBottomAligned
|
||||||
? pageHeight - metrics.buttonHintsHeight - metrics.verticalSpacing -
|
? contentRect.y + contentRect.height - metrics.verticalSpacing -
|
||||||
(metrics.keyboardKeyHeight + metrics.keyboardKeySpacing) * NUM_ROWS
|
(metrics.keyboardKeyHeight + metrics.keyboardKeySpacing) * NUM_ROWS
|
||||||
: inputStartY + inputHeight + metrics.verticalSpacing * 4;
|
: inputStartY + inputHeight + metrics.verticalSpacing * 4;
|
||||||
const int keyWidth = metrics.keyboardKeyWidth;
|
const int keyWidth = metrics.keyboardKeyWidth;
|
||||||
@@ -252,9 +254,9 @@ void KeyboardEntryActivity::render(RenderLock&&) {
|
|||||||
|
|
||||||
const char* const* layout = shiftState ? keyboardShift : keyboard;
|
const char* const* layout = shiftState ? keyboardShift : keyboard;
|
||||||
|
|
||||||
// Calculate left margin to center the longest row (13 keys)
|
// Calculate left margin to center the longest row (13 keys) within the content area
|
||||||
const int maxRowWidth = KEYS_PER_ROW * (keyWidth + keySpacing);
|
const int maxRowWidth = KEYS_PER_ROW * (keyWidth + keySpacing);
|
||||||
const int leftMargin = (pageWidth - maxRowWidth) / 2;
|
const int leftMargin = contentRect.x + (contentRect.width - maxRowWidth) / 2;
|
||||||
|
|
||||||
for (int row = 0; row < NUM_ROWS; row++) {
|
for (int row = 0; row < NUM_ROWS; row++) {
|
||||||
const int rowY = keyboardStartY + row * (keyHeight + keySpacing);
|
const int rowY = keyboardStartY + row * (keyHeight + keySpacing);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ void UITheme::setTheme(CrossPointSettings::UI_THEME type) {
|
|||||||
int UITheme::getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
|
int UITheme::getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
|
||||||
bool hasSubtitle) {
|
bool hasSubtitle) {
|
||||||
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const Rect contentRect = getContentRect(renderer, hasButtonHints, /*hasSideHints=*/false);
|
||||||
int reservedHeight = metrics.topPadding;
|
int reservedHeight = metrics.topPadding;
|
||||||
if (hasHeader) {
|
if (hasHeader) {
|
||||||
reservedHeight += metrics.headerHeight + metrics.verticalSpacing;
|
reservedHeight += metrics.headerHeight + metrics.verticalSpacing;
|
||||||
@@ -59,13 +60,43 @@ int UITheme::getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader
|
|||||||
reservedHeight += metrics.tabBarHeight;
|
reservedHeight += metrics.tabBarHeight;
|
||||||
}
|
}
|
||||||
if (hasButtonHints) {
|
if (hasButtonHints) {
|
||||||
reservedHeight += metrics.verticalSpacing + metrics.buttonHintsHeight;
|
reservedHeight += metrics.verticalSpacing;
|
||||||
}
|
}
|
||||||
const int availableHeight = renderer.getScreenHeight() - reservedHeight;
|
const int availableHeight = contentRect.height - reservedHeight;
|
||||||
int rowHeight = hasSubtitle ? metrics.listWithSubtitleRowHeight : metrics.listRowHeight;
|
int rowHeight = hasSubtitle ? metrics.listWithSubtitleRowHeight : metrics.listRowHeight;
|
||||||
return availableHeight / rowHeight;
|
return availableHeight / rowHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect UITheme::getContentRect(const GfxRenderer& renderer, bool hasBottomHints, bool hasSideHints) {
|
||||||
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
const int bh = hasBottomHints ? metrics.buttonHintsHeight : 0;
|
||||||
|
const int sw = hasSideHints ? metrics.sideButtonHintsWidth : 0;
|
||||||
|
|
||||||
|
int top = 0, right = 0, bottom = 0, left = 0;
|
||||||
|
switch (renderer.getOrientation()) {
|
||||||
|
case GfxRenderer::Portrait:
|
||||||
|
bottom = bh;
|
||||||
|
right = sw;
|
||||||
|
break;
|
||||||
|
case GfxRenderer::PortraitInverted:
|
||||||
|
top = bh;
|
||||||
|
left = sw;
|
||||||
|
break;
|
||||||
|
case GfxRenderer::LandscapeClockwise:
|
||||||
|
left = bh;
|
||||||
|
bottom = sw;
|
||||||
|
break;
|
||||||
|
case GfxRenderer::LandscapeCounterClockwise:
|
||||||
|
right = bh;
|
||||||
|
top = sw;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int w = renderer.getScreenWidth();
|
||||||
|
const int h = renderer.getScreenHeight();
|
||||||
|
return Rect{left, top, w - left - right, h - top - bottom};
|
||||||
|
}
|
||||||
|
|
||||||
std::string UITheme::getCoverThumbPath(std::string coverBmpPath, int coverHeight) {
|
std::string UITheme::getCoverThumbPath(std::string coverBmpPath, int coverHeight) {
|
||||||
size_t pos = coverBmpPath.find("[HEIGHT]", 0);
|
size_t pos = coverBmpPath.find("[HEIGHT]", 0);
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ class UITheme {
|
|||||||
void setTheme(CrossPointSettings::UI_THEME type);
|
void setTheme(CrossPointSettings::UI_THEME type);
|
||||||
static int getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
|
static int getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
|
||||||
bool hasSubtitle);
|
bool hasSubtitle);
|
||||||
|
// Returns the drawable content Rect accounting for screen orientation and visible button hints.
|
||||||
|
// Bottom hints occupy the physical bottom edge; side hints occupy the physical right edge.
|
||||||
|
// The mapping to logical edges is orientation-dependent.
|
||||||
|
static Rect getContentRect(const GfxRenderer& renderer, bool hasBottomHints, bool hasSideHints);
|
||||||
static std::string getCoverThumbPath(std::string coverBmpPath, int coverHeight);
|
static std::string getCoverThumbPath(std::string coverBmpPath, int coverHeight);
|
||||||
static UIIcon getFileIcon(const std::string& filename);
|
static UIIcon getFileIcon(const std::string& filename);
|
||||||
static int getStatusBarHeight();
|
static int getStatusBarHeight();
|
||||||
|
|||||||
@@ -273,9 +273,9 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount,
|
|||||||
rect.width -
|
rect.width -
|
||||||
(totalPages > 1 ? (LyraMetrics::values.scrollBarWidth + LyraMetrics::values.scrollBarRightOffset) : 1);
|
(totalPages > 1 ? (LyraMetrics::values.scrollBarWidth + LyraMetrics::values.scrollBarRightOffset) : 1);
|
||||||
if (selectedIndex >= 0) {
|
if (selectedIndex >= 0) {
|
||||||
renderer.fillRoundedRect(LyraMetrics::values.contentSidePadding, rect.y + selectedIndex % pageItems * rowHeight,
|
renderer.fillRoundedRect(
|
||||||
contentWidth - LyraMetrics::values.contentSidePadding * 2, rowHeight, cornerRadius,
|
rect.x + LyraMetrics::values.contentSidePadding, rect.y + selectedIndex % pageItems * rowHeight,
|
||||||
Color::LightGray);
|
contentWidth - LyraMetrics::values.contentSidePadding * 2, rowHeight, cornerRadius, Color::LightGray);
|
||||||
}
|
}
|
||||||
|
|
||||||
int textX = rect.x + LyraMetrics::values.contentSidePadding + hPaddingInSelection;
|
int textX = rect.x + LyraMetrics::values.contentSidePadding + hPaddingInSelection;
|
||||||
@@ -336,7 +336,7 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount,
|
|||||||
if (!valueText.empty()) {
|
if (!valueText.empty()) {
|
||||||
if (i == selectedIndex && highlightValue) {
|
if (i == selectedIndex && highlightValue) {
|
||||||
renderer.fillRoundedRect(
|
renderer.fillRoundedRect(
|
||||||
contentWidth - LyraMetrics::values.contentSidePadding - hPaddingInSelection - valueWidth, itemY,
|
rect.x + contentWidth - LyraMetrics::values.contentSidePadding - hPaddingInSelection - valueWidth, itemY,
|
||||||
valueWidth + hPaddingInSelection, rowHeight, cornerRadius, Color::Black);
|
valueWidth + hPaddingInSelection, rowHeight, cornerRadius, Color::Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user