Xteink-X4-crosspoint-reader/src/components/UITheme.cpp
2026-02-01 21:58:55 +07:00

145 lines
5.5 KiB
C++

#include "UITheme.h"
#include <GfxRenderer.h>
#include <memory>
#include "RecentBooksStore.h"
#include "components/themes/BaseTheme.h"
#include "components/themes/lyra/LyraTheme.h"
std::unique_ptr<BaseTheme> currentTheme = nullptr;
const ThemeMetrics* UITheme::currentMetrics = &BaseMetrics::values;
// Initialize theme based on settings
void UITheme::initialize() {
auto themeType = static_cast<CrossPointSettings::UI_THEME>(SETTINGS.uiTheme);
setTheme(themeType);
}
void UITheme::setTheme(CrossPointSettings::UI_THEME type) {
switch (type) {
case CrossPointSettings::UI_THEME::CLASSIC:
Serial.printf("[%lu] [UI] Using Classic theme\n", millis());
currentTheme = std::unique_ptr<BaseTheme>(new BaseTheme());
currentMetrics = &BaseMetrics::values;
break;
case CrossPointSettings::UI_THEME::LYRA:
Serial.printf("[%lu] [UI] Using Lyra theme\n", millis());
currentTheme = std::unique_ptr<BaseTheme>(new LyraTheme());
currentMetrics = &LyraMetrics::values;
break;
}
}
int UITheme::getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
bool hasSubtitle) {
const ThemeMetrics& metrics = UITheme::getMetrics();
int reservedHeight = metrics.topPadding;
if (hasHeader) {
reservedHeight += metrics.headerHeight;
}
if (hasTabBar) {
reservedHeight += metrics.tabBarHeight + metrics.verticalSpacing;
}
if (hasButtonHints) {
reservedHeight += metrics.verticalSpacing + metrics.buttonHintsHeight;
}
const int availableHeight = renderer.getScreenHeight() - reservedHeight;
int rowHeight = hasSubtitle ? metrics.listWithSubtitleRowHeight : metrics.listRowHeight;
return availableHeight / rowHeight;
}
std::string UITheme::getCoverThumbPath(std::string coverBmpPath, int coverHeight) {
size_t pos = coverBmpPath.find("[HEIGHT]", 0);
if (pos != std::string::npos) {
coverBmpPath.replace(pos, 8, std::to_string(coverHeight));
}
return coverBmpPath;
}
// Forward all component methods to the current theme
void UITheme::drawProgressBar(const GfxRenderer& renderer, Rect rect, size_t current, size_t total) {
if (currentTheme != nullptr) {
currentTheme->drawProgressBar(renderer, rect, current, total);
}
}
void UITheme::drawBattery(const GfxRenderer& renderer, Rect rect, bool showPercentage) {
if (currentTheme != nullptr) {
currentTheme->drawBattery(renderer, rect, showPercentage);
}
}
void UITheme::drawButtonHints(GfxRenderer& renderer, const char* btn1, const char* btn2, const char* btn3,
const char* btn4) {
if (currentTheme != nullptr) {
currentTheme->drawButtonHints(renderer, btn1, btn2, btn3, btn4);
}
}
void UITheme::drawSideButtonHints(const GfxRenderer& renderer, const char* topBtn, const char* bottomBtn) {
if (currentTheme != nullptr) {
currentTheme->drawSideButtonHints(renderer, topBtn, bottomBtn);
}
}
void UITheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, int selectedIndex,
const std::function<std::string(int index)>& rowTitle, bool hasSubtitle,
const std::function<std::string(int index)>& rowSubtitle, bool hasIcon,
const std::function<std::string(int index)>& rowIcon, bool hasValue,
const std::function<std::string(int index)>& rowValue) {
if (currentTheme != nullptr) {
currentTheme->drawList(renderer, rect, itemCount, selectedIndex, rowTitle, hasSubtitle, rowSubtitle, hasIcon,
rowIcon, hasValue, rowValue);
}
}
void UITheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* title) {
if (currentTheme != nullptr) {
currentTheme->drawHeader(renderer, rect, title);
}
}
void UITheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const std::vector<TabInfo>& tabs,
bool selected) {
if (currentTheme != nullptr) {
currentTheme->drawTabBar(renderer, rect, tabs, selected);
}
}
void UITheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std::vector<RecentBook>& recentBooks,
const int selectorIndex, bool& coverRendered, bool& coverBufferStored,
bool& bufferRestored, std::function<bool()> storeCoverBuffer) {
if (currentTheme != nullptr) {
currentTheme->drawRecentBookCover(renderer, rect, recentBooks, selectorIndex, coverRendered, coverBufferStored,
bufferRestored, storeCoverBuffer);
}
}
void UITheme::drawButtonMenu(GfxRenderer& renderer, Rect rect, int buttonCount, int selectedIndex,
const std::function<std::string(int index)>& buttonLabel, bool hasIcon,
const std::function<std::string(int index)>& rowIcon) {
if (currentTheme != nullptr) {
currentTheme->drawButtonMenu(renderer, rect, buttonCount, selectedIndex, buttonLabel, hasIcon, rowIcon);
}
}
Rect UITheme::drawPopup(const GfxRenderer& renderer, const char* message) {
if (currentTheme != nullptr) {
return currentTheme->drawPopup(renderer, message);
}
return Rect{0, 0, 0, 0};
}
void UITheme::fillPopupProgress(const GfxRenderer& renderer, const Rect& layout, const int progress) {
if (currentTheme != nullptr) {
currentTheme->fillPopupProgress(renderer, layout, progress);
}
}
void UITheme::drawBookProgressBar(const GfxRenderer& renderer, const size_t bookProgress) {
if (currentTheme != nullptr) {
currentTheme->drawBookProgressBar(renderer, bookProgress);
}
}