Files
Crosspoint/src/activities/settings/LanguageSelectActivity.cpp
T
zgredex bc57e5d64b fix: jump page on hold in font family and language selection (#1925)
## Summary
- Holding the navigation button in **Settings → Reader → Font family**
now advances the selection by a full visible page instead of one item at
a time.
- Same fix applied to **Settings → Language**, which had the same
one-item-only behavior.
- Mirrors the pattern already used in font download (ceb3fed) and
chapter selection screens.

## Test plan
- [ ] Settings → Reader → Font family: tap moves by one item; hold jumps
a page (wraps at ends)
- [ ] Settings → Language: tap moves by one item; hold jumps a page
(wraps at ends)
2026-05-12 17:37:56 -04:00

105 lines
3.3 KiB
C++

#include "LanguageSelectActivity.h"
#include <GfxRenderer.h>
#include <I18n.h>
#include <algorithm>
#include <iterator>
#include "CrossPointSettings.h"
#include "I18nKeys.h"
#include "MappedInputManager.h"
#include "fontIds.h"
void LanguageSelectActivity::onEnter() {
Activity::onEnter();
// Set current selection based on current language
const auto currentLang = static_cast<uint8_t>(I18N.getLanguage());
const auto* begin = std::begin(SORTED_LANGUAGE_INDICES);
const auto* end = std::end(SORTED_LANGUAGE_INDICES);
const auto* it = std::find(begin, end, currentLang);
selectedIndex = (it != end) ? std::distance(begin, it) : 0;
requestUpdate();
}
void LanguageSelectActivity::onExit() { Activity::onExit(); }
void LanguageSelectActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
onBack();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
handleSelection();
return;
}
const int pageItems = UITheme::getNumberOfItemsPerPage(renderer, true, false, true, false);
// Handle navigation
buttonNavigator.onNextRelease([this] {
selectedIndex = ButtonNavigator::nextIndex(static_cast<int>(selectedIndex), totalItems);
requestUpdate();
});
buttonNavigator.onPreviousRelease([this] {
selectedIndex = ButtonNavigator::previousIndex(static_cast<int>(selectedIndex), totalItems);
requestUpdate();
});
buttonNavigator.onNextContinuous([this, pageItems] {
selectedIndex = ButtonNavigator::nextPageIndex(static_cast<int>(selectedIndex), totalItems, pageItems);
requestUpdate();
});
buttonNavigator.onPreviousContinuous([this, pageItems] {
selectedIndex = ButtonNavigator::previousPageIndex(static_cast<int>(selectedIndex), totalItems, pageItems);
requestUpdate();
});
}
void LanguageSelectActivity::handleSelection() {
const uint8_t langIndex = SORTED_LANGUAGE_INDICES[selectedIndex];
{
RenderLock lock(*this);
I18N.setLanguage(static_cast<Language>(langIndex));
}
SETTINGS.language = langIndex;
SETTINGS.saveToFile();
// Return to previous page
onBack();
}
void LanguageSelectActivity::render(RenderLock&&) {
renderer.clearScreen();
const auto pageWidth = renderer.getScreenWidth();
const auto pageHeight = renderer.getScreenHeight();
auto metrics = UITheme::getInstance().getMetrics();
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_LANGUAGE));
// Current language marker
const int contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing;
const int contentHeight = pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing;
const auto currentLang = static_cast<uint8_t>(I18N.getLanguage());
GUI.drawList(
renderer, Rect{0, contentTop, pageWidth, contentHeight}, totalItems, selectedIndex,
[this](int index) { return I18N.getLanguageName(static_cast<Language>(SORTED_LANGUAGE_INDICES[index])); },
nullptr, nullptr,
[this, currentLang](int index) { return SORTED_LANGUAGE_INDICES[index] == currentLang ? tr(STR_SELECTED) : ""; },
true);
// Button hints
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();
}