feat: Allow statusbar clock to be on the left (#2359)
This commit is contained in:
@@ -65,6 +65,8 @@ class CrossPointSettings {
|
|||||||
XTC_STATUS_BAR_MODE_COUNT
|
XTC_STATUS_BAR_MODE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum STATUS_BAR_CLOCK_MODE { STATUS_BAR_CLOCK_HIDE = 0, STATUS_BAR_CLOCK_RIGHT = 1, STATUS_BAR_CLOCK_LEFT = 2 };
|
||||||
|
|
||||||
enum ORIENTATION {
|
enum ORIENTATION {
|
||||||
PORTRAIT = 0, // 480x800 logical coordinates (current default)
|
PORTRAIT = 0, // 480x800 logical coordinates (current default)
|
||||||
LANDSCAPE_CW = 1, // 800x480 logical coordinates, rotated 180° (swap top/bottom)
|
LANDSCAPE_CW = 1, // 800x480 logical coordinates, rotated 180° (swap top/bottom)
|
||||||
@@ -188,7 +190,7 @@ class CrossPointSettings {
|
|||||||
uint8_t statusBarBattery = 1;
|
uint8_t statusBarBattery = 1;
|
||||||
uint8_t xtcStatusBarMode = XTC_STATUS_BAR_HIDE;
|
uint8_t xtcStatusBarMode = XTC_STATUS_BAR_HIDE;
|
||||||
// Clock display in status bar (X3 only, requires DS3231 RTC)
|
// Clock display in status bar (X3 only, requires DS3231 RTC)
|
||||||
uint8_t statusBarClock = 0;
|
uint8_t statusBarClock = STATUS_BAR_CLOCK_HIDE;
|
||||||
// Clock UTC offset in quarter-hour steps, biased by 48 so it fits in uint8_t.
|
// Clock UTC offset in quarter-hour steps, biased by 48 so it fits in uint8_t.
|
||||||
// Value 48 = UTC+0, 0 = UTC-12:00, 104 = UTC+14:00.
|
// Value 48 = UTC+0, 0 = UTC-12:00, 104 = UTC+14:00.
|
||||||
// Quarter-hour granularity supports oddball zones like Nepal (+5:45) and Chatham (+12:45).
|
// Quarter-hour granularity supports oddball zones like Nepal (+5:45) and Chatham (+12:45).
|
||||||
|
|||||||
+3
-2
@@ -244,8 +244,9 @@ inline std::vector<SettingInfo> getSettingsList(const SdCardFontRegistry* regist
|
|||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
// Clock entries (web settings only; device UI uses ClockOffsetActivity for the offset).
|
// Clock entries (web settings only; device UI uses ClockOffsetActivity for the offset).
|
||||||
// Range 0..104 = quarter-hour steps from UTC-12:00 to UTC+14:00, biased by 48.
|
// Range 0..104 = quarter-hour steps from UTC-12:00 to UTC+14:00, biased by 48.
|
||||||
SettingInfo::Toggle(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock, "statusBarClock",
|
SettingInfo::Enum(StrId::STR_CLOCK, &CrossPointSettings::statusBarClock,
|
||||||
StrId::STR_CUSTOMISE_STATUS_BAR),
|
{StrId::STR_HIDE, StrId::STR_DIR_LEFT, StrId::STR_DIR_RIGHT}, "statusBarClock",
|
||||||
|
StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Value(StrId::STR_CLOCK_UTC_OFFSET, &CrossPointSettings::clockUtcOffsetQ, {0, 104, 1},
|
SettingInfo::Value(StrId::STR_CLOCK_UTC_OFFSET, &CrossPointSettings::clockUtcOffsetQ, {0, 104, 1},
|
||||||
"clockUtcOffsetQ", StrId::STR_CUSTOMISE_STATUS_BAR),
|
"clockUtcOffsetQ", StrId::STR_CUSTOMISE_STATUS_BAR),
|
||||||
SettingInfo::Enum(StrId::STR_CLOCK_FORMAT, &CrossPointSettings::clockFormat,
|
SettingInfo::Enum(StrId::STR_CLOCK_FORMAT, &CrossPointSettings::clockFormat,
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ const StrId titleNames[TITLE_ITEMS] = {StrId::STR_BOOK, StrId::STR_CHAPTER, StrI
|
|||||||
constexpr int XTC_STATUS_BAR_ITEMS = 3;
|
constexpr int XTC_STATUS_BAR_ITEMS = 3;
|
||||||
const StrId xtcStatusBarNames[XTC_STATUS_BAR_ITEMS] = {StrId::STR_HIDE, StrId::STR_BOTTOM, StrId::STR_TOP};
|
const StrId xtcStatusBarNames[XTC_STATUS_BAR_ITEMS] = {StrId::STR_HIDE, StrId::STR_BOTTOM, StrId::STR_TOP};
|
||||||
|
|
||||||
|
constexpr int STATUS_BAR_CLOCK_ITEMS = 3;
|
||||||
|
const StrId statusBarClockNames[STATUS_BAR_CLOCK_ITEMS] = {StrId::STR_HIDE, StrId::STR_DIR_RIGHT, StrId::STR_DIR_LEFT};
|
||||||
|
|
||||||
const int verticalPreviewPadding = 50;
|
const int verticalPreviewPadding = 50;
|
||||||
const int verticalPreviewTextPadding = 40;
|
const int verticalPreviewTextPadding = 40;
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -112,6 +115,10 @@ void StatusBarSettingsActivity::onEnter() {
|
|||||||
SETTINGS.clockFormat = 0;
|
SETTINGS.clockFormat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SETTINGS.statusBarClock >= STATUS_BAR_CLOCK_ITEMS) {
|
||||||
|
SETTINGS.statusBarClock = CrossPointSettings::STATUS_BAR_CLOCK_MODE::STATUS_BAR_CLOCK_HIDE;
|
||||||
|
}
|
||||||
|
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +183,7 @@ void StatusBarSettingsActivity::handleSelection() {
|
|||||||
SETTINGS.xtcStatusBarMode = (SETTINGS.xtcStatusBarMode + 1) % XTC_STATUS_BAR_ITEMS;
|
SETTINGS.xtcStatusBarMode = (SETTINGS.xtcStatusBarMode + 1) % XTC_STATUS_BAR_ITEMS;
|
||||||
break;
|
break;
|
||||||
case ITEM_CLOCK:
|
case ITEM_CLOCK:
|
||||||
SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % 2;
|
SETTINGS.statusBarClock = (SETTINGS.statusBarClock + 1) % STATUS_BAR_CLOCK_ITEMS;
|
||||||
break;
|
break;
|
||||||
case ITEM_CLOCK_FORMAT:
|
case ITEM_CLOCK_FORMAT:
|
||||||
SETTINGS.clockFormat = (SETTINGS.clockFormat + 1) % CLOCK_FORMAT_ITEMS;
|
SETTINGS.clockFormat = (SETTINGS.clockFormat + 1) % CLOCK_FORMAT_ITEMS;
|
||||||
@@ -225,7 +232,7 @@ void StatusBarSettingsActivity::render(RenderLock&&) {
|
|||||||
case ITEM_XTC_STATUS_BAR:
|
case ITEM_XTC_STATUS_BAR:
|
||||||
return I18N.get(xtcStatusBarNames[SETTINGS.xtcStatusBarMode]);
|
return I18N.get(xtcStatusBarNames[SETTINGS.xtcStatusBarMode]);
|
||||||
case ITEM_CLOCK:
|
case ITEM_CLOCK:
|
||||||
return SETTINGS.statusBarClock ? tr(STR_SHOW) : tr(STR_HIDE);
|
return I18N.get(statusBarClockNames[SETTINGS.statusBarClock]);
|
||||||
case ITEM_CLOCK_FORMAT: {
|
case ITEM_CLOCK_FORMAT: {
|
||||||
const uint8_t fmt = SETTINGS.clockFormat < CLOCK_FORMAT_ITEMS ? SETTINGS.clockFormat : 0;
|
const uint8_t fmt = SETTINGS.clockFormat < CLOCK_FORMAT_ITEMS ? SETTINGS.clockFormat : 0;
|
||||||
return std::string(I18N.get(clockFormatNames[fmt]));
|
return std::string(I18N.get(clockFormatNames[fmt]));
|
||||||
|
|||||||
@@ -131,9 +131,10 @@ int UITheme::getStatusBarHeight() {
|
|||||||
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
const ThemeMetrics& metrics = UITheme::getInstance().getMetrics();
|
||||||
|
|
||||||
// Add status bar margin
|
// Add status bar margin
|
||||||
const bool showStatusBar = SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage ||
|
const bool showStatusBar =
|
||||||
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE ||
|
SETTINGS.statusBarChapterPageCount || SETTINGS.statusBarBookProgressPercentage ||
|
||||||
SETTINGS.statusBarBattery;
|
SETTINGS.statusBarTitle != CrossPointSettings::STATUS_BAR_TITLE::HIDE_TITLE || SETTINGS.statusBarBattery ||
|
||||||
|
SETTINGS.statusBarClock != CrossPointSettings::STATUS_BAR_CLOCK_MODE::STATUS_BAR_CLOCK_HIDE;
|
||||||
const bool showProgressBar =
|
const bool showProgressBar =
|
||||||
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
SETTINGS.statusBarProgressBar != CrossPointSettings::STATUS_BAR_PROGRESS_BAR::HIDE_PROGRESS;
|
||||||
return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) +
|
return (showStatusBar ? (metrics.statusBarVerticalMargin) : 0) +
|
||||||
|
|||||||
@@ -759,7 +759,11 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
// Draw Progress Text
|
// Draw Progress Text
|
||||||
const auto screenHeight = renderer.getScreenHeight();
|
const auto screenHeight = renderer.getScreenHeight();
|
||||||
auto textY = screenHeight - UITheme::getInstance().getStatusBarHeight() - orientedMarginBottom - paddingBottom - 4;
|
auto textY = screenHeight - UITheme::getInstance().getStatusBarHeight() - orientedMarginBottom - paddingBottom - 4;
|
||||||
int progressTextWidth = 0;
|
|
||||||
|
const int leftClusterX = metrics.statusBarHorizontalMargin + orientedMarginLeft + 1;
|
||||||
|
const int rightClusterX = renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight;
|
||||||
|
int leftClusterWidth = 0;
|
||||||
|
int rightClusterWidth = 0;
|
||||||
|
|
||||||
if (SETTINGS.statusBarBookProgressPercentage || SETTINGS.statusBarChapterPageCount) {
|
if (SETTINGS.statusBarBookProgressPercentage || SETTINGS.statusBarChapterPageCount) {
|
||||||
// Right aligned text for progress counter
|
// Right aligned text for progress counter
|
||||||
@@ -773,11 +777,10 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
snprintf(progressStr, sizeof(progressStr), "%d/%d", currentPage, pageCount);
|
snprintf(progressStr, sizeof(progressStr), "%d/%d", currentPage, pageCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr);
|
int progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progressStr);
|
||||||
renderer.drawText(
|
renderer.drawText(SMALL_FONT_ID, rightClusterX - progressTextWidth, textY, progressStr);
|
||||||
SMALL_FONT_ID,
|
|
||||||
renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight - progressTextWidth, textY,
|
rightClusterWidth += progressTextWidth;
|
||||||
progressStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Progress Bar
|
// Draw Progress Bar
|
||||||
@@ -801,34 +804,46 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw Bookmark
|
// Draw Bookmark
|
||||||
const int leftClusterX = metrics.statusBarHorizontalMargin + orientedMarginLeft + 1;
|
if (showStatusBarTextLane && isPageBookmarked) {
|
||||||
const bool showBookmarkIcon = showStatusBarTextLane && isPageBookmarked;
|
|
||||||
const int bookmarkReserveWidth = showBookmarkIcon ? (bookmarkStatusIconWidth + bookmarkStatusIconGap) : 0;
|
|
||||||
if (showBookmarkIcon) {
|
|
||||||
const int bookmarkY = textY + 5;
|
const int bookmarkY = textY + 5;
|
||||||
drawBookmarkStatusIcon(renderer, leftClusterX, bookmarkY);
|
drawBookmarkStatusIcon(renderer, leftClusterX, bookmarkY);
|
||||||
|
leftClusterWidth += bookmarkStatusIconWidth + bookmarkStatusIconGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Battery
|
// Draw Battery
|
||||||
const bool showBatteryPercentage =
|
const bool showBatteryPercentage =
|
||||||
SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER;
|
SETTINGS.hideBatteryPercentage == CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_NEVER;
|
||||||
int leftClusterWidth = bookmarkReserveWidth;
|
|
||||||
if (SETTINGS.statusBarBattery) {
|
if (SETTINGS.statusBarBattery) {
|
||||||
GUI.drawBatteryLeft(renderer,
|
GUI.drawBatteryLeft(renderer,
|
||||||
Rect{leftClusterX + bookmarkReserveWidth, textY, metrics.batteryWidth, metrics.batteryHeight},
|
Rect{leftClusterX + leftClusterWidth, textY, metrics.batteryWidth, metrics.batteryHeight},
|
||||||
showBatteryPercentage);
|
showBatteryPercentage);
|
||||||
leftClusterWidth += showBatteryPercentage ? 50 : 20;
|
int batteryWidth = metrics.batteryWidth;
|
||||||
|
|
||||||
|
if (showBatteryPercentage) {
|
||||||
|
const uint16_t percentage = powerManager.getBatteryPercentage();
|
||||||
|
// width of icon + spacing + text for layout purposes
|
||||||
|
batteryWidth +=
|
||||||
|
batteryPercentSpacing + renderer.getTextWidth(SMALL_FONT_ID, (std::to_string(percentage) + "%").c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
leftClusterWidth += batteryWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Clock (X3 only — DS3231 RTC)
|
// Draw Clock (X3 only — DS3231 RTC)
|
||||||
int clockTextWidth = 0;
|
|
||||||
if (SETTINGS.statusBarClock && halClock.isAvailable()) {
|
if (SETTINGS.statusBarClock && halClock.isAvailable()) {
|
||||||
char timeBuf[9];
|
char timeBuf[9];
|
||||||
if (halClock.formatTime(timeBuf, sizeof(timeBuf), SETTINGS.clockUtcOffsetQ, SETTINGS.clockFormat == 1)) {
|
if (halClock.formatTime(timeBuf, sizeof(timeBuf), SETTINGS.clockUtcOffsetQ, SETTINGS.clockFormat == 1)) {
|
||||||
clockTextWidth = renderer.getTextWidth(SMALL_FONT_ID, timeBuf);
|
int clockTextWidth = renderer.getTextWidth(SMALL_FONT_ID, timeBuf);
|
||||||
// Position to the left of the progress text (with a small gap)
|
int clockX = 0;
|
||||||
const int clockX = renderer.getScreenWidth() - metrics.statusBarHorizontalMargin - orientedMarginRight -
|
// Position to the left or right of the progress text (with a small gap)
|
||||||
progressTextWidth - (progressTextWidth > 0 ? 10 : 0) - clockTextWidth;
|
if (SETTINGS.statusBarClock == CrossPointSettings::STATUS_BAR_CLOCK_LEFT) {
|
||||||
|
clockX = leftClusterX + leftClusterWidth + (leftClusterWidth > 0 ? 10 : 0);
|
||||||
|
leftClusterWidth += clockTextWidth + 10;
|
||||||
|
} else if (SETTINGS.statusBarClock == CrossPointSettings::STATUS_BAR_CLOCK_RIGHT) {
|
||||||
|
clockX = rightClusterX - rightClusterWidth - (rightClusterWidth > 0 ? 10 : 0) - clockTextWidth;
|
||||||
|
rightClusterWidth += clockTextWidth + 10;
|
||||||
|
}
|
||||||
renderer.drawText(SMALL_FONT_ID, clockX, textY, timeBuf);
|
renderer.drawText(SMALL_FONT_ID, clockX, textY, timeBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -842,8 +857,7 @@ void BaseTheme::drawStatusBar(GfxRenderer& renderer, const float bookProgress, c
|
|||||||
renderer.getScreenWidth() - (metrics.statusBarHorizontalMargin * 2) - orientedMarginLeft - orientedMarginRight;
|
renderer.getScreenWidth() - (metrics.statusBarHorizontalMargin * 2) - orientedMarginLeft - orientedMarginRight;
|
||||||
|
|
||||||
const int titleMarginLeft = leftClusterWidth + 30;
|
const int titleMarginLeft = leftClusterWidth + 30;
|
||||||
const int clockReserve = clockTextWidth > 0 ? (clockTextWidth + 10) : 0;
|
const int titleMarginRight = rightClusterWidth + 30;
|
||||||
const int titleMarginRight = progressTextWidth + clockReserve + 30;
|
|
||||||
|
|
||||||
// Attempt to center title on the screen, but if title is too wide then later we will center it within the
|
// Attempt to center title on the screen, but if title is too wide then later we will center it within the
|
||||||
// available space.
|
// available space.
|
||||||
|
|||||||
Reference in New Issue
Block a user