From bf309649826a722c1c021a633ea7f75f405e95ed Mon Sep 17 00:00:00 2001 From: pablohc Date: Sat, 9 May 2026 22:11:13 +0200 Subject: [PATCH] fix: overlap in download font list layout (#1900) ## Summary Fix font download list layout overlap in Classic and RoundedRaff themes. The font description was shown as a right-aligned value, causing text to overlap with the font name on narrow screens. ### Changes - Move font description from `rowValue` to `rowSubtitle` (second line) - Show only status ("Installed"/"Update Available") as `rowValue` - Fix Classic and RoundedRaff themes `rowValue` truncation (was fixed 60px, now dynamic) ## Screenshots ### Classic | RC 1.3.0 | #1900 | |-|-| |image|image| ### Lyra | RC 1.3.0 | #1900 | |-|-| |image|image| ### RoundedRaff | RC 1.3.0 | #1900 | |-|-| |image|image| --- ### 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? _****_ --- .../settings/FontDownloadActivity.cpp | 9 +++-- src/components/themes/BaseTheme.cpp | 40 +++++++++++++------ src/components/themes/BaseTheme.h | 2 +- src/components/themes/lyra/LyraTheme.cpp | 6 ++- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/activities/settings/FontDownloadActivity.cpp b/src/activities/settings/FontDownloadActivity.cpp index 761351c5..e7419c0e 100644 --- a/src/activities/settings/FontDownloadActivity.cpp +++ b/src/activities/settings/FontDownloadActivity.cpp @@ -377,19 +377,22 @@ void FontDownloadActivity::render(RenderLock&&) { } return families_[familyIndexFromList(index)].name; }, - nullptr, nullptr, + [this](int index) -> std::string { + if (index == 0) return ""; + return families_[familyIndexFromList(index)].description; + }, + nullptr, [this](int index) -> std::string { if (index == 0) return ""; const auto& f = families_[familyIndexFromList(index)]; if (f.hasUpdate) return tr(STR_UPDATE_AVAILABLE); if (f.installed) return tr(STR_INSTALLED); - return f.description; + return ""; }, true, [this](int index) -> bool { if (index == 0) return false; const auto& f = families_[familyIndexFromList(index)]; - // Dim installed fonts, but not those with updates available return f.installed && !f.hasUpdate; }); diff --git a/src/components/themes/BaseTheme.cpp b/src/components/themes/BaseTheme.cpp index 194896b9..7fd4ab9e 100644 --- a/src/components/themes/BaseTheme.cpp +++ b/src/components/themes/BaseTheme.cpp @@ -268,16 +268,29 @@ void BaseTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, if (selectedIndex >= 0) { renderer.fillRect(0, rect.y + selectedIndex % pageItems * rowHeight - 2, rect.width, rowHeight); } + constexpr int maxValueWidth = 200; + constexpr int minValueGap = 10; + // Draw all items const auto pageStartIndex = selectedIndex / pageItems * pageItems; for (int i = pageStartIndex; i < itemCount && i < pageStartIndex + pageItems; i++) { const int itemY = rect.y + (i % pageItems) * rowHeight; - int textWidth = contentWidth - BaseMetrics::values.contentSidePadding * 2 - (rowValue != nullptr ? 60 : 0); - // Draw name + int rowTextWidth = contentWidth - BaseMetrics::values.contentSidePadding * 2; + std::string valueText; + if (rowValue != nullptr) { + valueText = rowValue(i); + if (!valueText.empty()) { + int maxValW = std::max(0, rowTextWidth - 40 - minValueGap); + valueText = renderer.truncatedText(UI_10_FONT_ID, valueText.c_str(), maxValW); + int valueWidth = renderer.getTextWidth(UI_10_FONT_ID, valueText.c_str()) + minValueGap; + rowTextWidth -= valueWidth; + } + } + auto itemName = rowTitle(i); - auto font = (rowSubtitle != nullptr) ? UI_12_FONT_ID : UI_10_FONT_ID; - auto item = renderer.truncatedText(font, itemName.c_str(), textWidth); + auto font = UI_10_FONT_ID; + auto item = renderer.truncatedText(font, itemName.c_str(), rowTextWidth); renderer.drawText(font, rect.x + BaseMetrics::values.contentSidePadding, itemY, item.c_str(), i != selectedIndex); // Apply checkerboard dither to create gray text effect for dimmed items @@ -291,19 +304,22 @@ void BaseTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, } if (rowSubtitle != nullptr) { - // Draw subtitle std::string subtitleText = rowSubtitle(i); - auto subtitle = renderer.truncatedText(UI_10_FONT_ID, subtitleText.c_str(), textWidth); - renderer.drawText(UI_10_FONT_ID, rect.x + BaseMetrics::values.contentSidePadding, itemY + 30, subtitle.c_str(), - i != selectedIndex); + if (!subtitleText.empty()) { + auto subtitle = renderer.truncatedText(SMALL_FONT_ID, subtitleText.c_str(), rowTextWidth); + renderer.drawText(SMALL_FONT_ID, rect.x + BaseMetrics::values.contentSidePadding, itemY + 22, subtitle.c_str(), + i != selectedIndex); + } } - if (rowValue != nullptr) { - // Draw value - std::string valueText = rowValue(i); + if (!valueText.empty()) { const auto valueTextWidth = renderer.getTextWidth(UI_10_FONT_ID, valueText.c_str()); + int valueY = itemY; + if (rowSubtitle != nullptr) { + valueY = itemY + 10; + } renderer.drawText(UI_10_FONT_ID, rect.x + contentWidth - BaseMetrics::values.contentSidePadding - valueTextWidth, - itemY, valueText.c_str(), i != selectedIndex); + valueY, valueText.c_str(), i != selectedIndex); } } } diff --git a/src/components/themes/BaseTheme.h b/src/components/themes/BaseTheme.h index 6625a2be..d21821ec 100644 --- a/src/components/themes/BaseTheme.h +++ b/src/components/themes/BaseTheme.h @@ -88,7 +88,7 @@ constexpr ThemeMetrics values = {.batteryWidth = 15, .verticalSpacing = 10, .contentSidePadding = 20, .listRowHeight = 30, - .listWithSubtitleRowHeight = 65, + .listWithSubtitleRowHeight = 50, .menuRowHeight = 45, .menuSpacing = 8, .tabSpacing = 10, diff --git a/src/components/themes/lyra/LyraTheme.cpp b/src/components/themes/lyra/LyraTheme.cpp index 904ad830..7ee9ad84 100644 --- a/src/components/themes/lyra/LyraTheme.cpp +++ b/src/components/themes/lyra/LyraTheme.cpp @@ -301,8 +301,12 @@ void LyraTheme::drawList(const GfxRenderer& renderer, Rect rect, int itemCount, valueWidth + hPaddingInSelection, rowHeight, cornerRadius, Color::Black); } + int valueY = itemY + 6; + if (rowSubtitle != nullptr) { + valueY = itemY + 16; + } renderer.drawText(UI_10_FONT_ID, rect.x + contentWidth - LyraMetrics::values.contentSidePadding - valueWidth, - itemY + 6, valueText.c_str(), !(i == selectedIndex && highlightValue)); + valueY, valueText.c_str(), !(i == selectedIndex && highlightValue)); } } }