## Summary **What is the goal of this PR?** This change avoids the pattern of creating a `std::string` using `.substr` in order to compare against a file extension literal. ```c++ std::string path; if (path.length() >= 4 && path.substr(path.length() - 4) == ".ext") ``` The `checkFileExtension` utility has moved from StringUtils to FsHelpers, to be available to code in lib/. The signature now accepts a `std::string_view` instead of `std::string`, which makes the single implementation reusable for Arduino `String`. Added utility functions for commonly repeated extensions. These changes **save about 2 KB of flash (5,999,427 to 5,997,343)**. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**NO**_
112 lines
3.8 KiB
C++
112 lines
3.8 KiB
C++
#include "UITheme.h"
|
|
|
|
#include <FsHelpers.h>
|
|
#include <GfxRenderer.h>
|
|
#include <Logging.h>
|
|
|
|
#include <memory>
|
|
|
|
#include "MappedInputManager.h"
|
|
#include "RecentBooksStore.h"
|
|
#include "components/themes/BaseTheme.h"
|
|
#include "components/themes/lyra/Lyra3CoversTheme.h"
|
|
#include "components/themes/lyra/LyraTheme.h"
|
|
|
|
namespace {
|
|
constexpr int SKIP_PAGE_MS = 700;
|
|
} // namespace
|
|
|
|
UITheme UITheme::instance;
|
|
|
|
UITheme::UITheme() {
|
|
auto themeType = static_cast<CrossPointSettings::UI_THEME>(SETTINGS.uiTheme);
|
|
setTheme(themeType);
|
|
}
|
|
|
|
void UITheme::reload() {
|
|
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:
|
|
LOG_DBG("UI", "Using Classic theme");
|
|
currentTheme = std::make_unique<BaseTheme>();
|
|
currentMetrics = &BaseMetrics::values;
|
|
break;
|
|
case CrossPointSettings::UI_THEME::LYRA:
|
|
LOG_DBG("UI", "Using Lyra theme");
|
|
currentTheme = std::make_unique<LyraTheme>();
|
|
currentMetrics = &LyraMetrics::values;
|
|
break;
|
|
case CrossPointSettings::UI_THEME::LYRA_3_COVERS:
|
|
LOG_DBG("UI", "Using Lyra 3 Covers theme");
|
|
currentTheme = std::make_unique<Lyra3CoversTheme>();
|
|
currentMetrics = &Lyra3CoversMetrics::values;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int UITheme::getNumberOfItemsPerPage(const GfxRenderer& renderer, bool hasHeader, bool hasTabBar, bool hasButtonHints,
|
|
bool hasSubtitle) {
|
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
|
int reservedHeight = metrics.topPadding;
|
|
if (hasHeader) {
|
|
reservedHeight += metrics.headerHeight + metrics.verticalSpacing;
|
|
}
|
|
if (hasTabBar) {
|
|
reservedHeight += metrics.tabBarHeight;
|
|
}
|
|
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;
|
|
}
|
|
|
|
UIIcon UITheme::getFileIcon(const std::string& filename) {
|
|
if (filename.back() == '/') {
|
|
return Folder;
|
|
}
|
|
if (FsHelpers::hasEpubExtension(filename) || FsHelpers::hasXtcExtension(filename)) {
|
|
return Book;
|
|
}
|
|
if (FsHelpers::hasTxtExtension(filename) || FsHelpers::hasMarkdownExtension(filename)) {
|
|
return Text;
|
|
}
|
|
if (FsHelpers::hasBmpExtension(filename)) {
|
|
return Image;
|
|
}
|
|
return File;
|
|
}
|
|
|
|
int UITheme::getStatusBarHeight() {
|
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
|
|
|
// Add status bar margin
|
|
const bool showStatusBar = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage ||
|
|
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
|
SETTINGS.statusBarBattery;
|
|
const bool showProgressBar =
|
|
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
|
return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) +
|
|
(showProgressBar ? (((SETTINGS.statusBarProgressBarThickness + 1) * 2) + metrics.progressBarMarginTop) : 0);
|
|
}
|
|
|
|
int UITheme::getProgressBarHeight() {
|
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
|
const bool showProgressBar =
|
|
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
|
return (showProgressBar ? (((SETTINGS.statusBarProgressBarThickness + 1) * 2) + metrics.progressBarMarginTop) : 0);
|
|
}
|