Merge pull request #90 from jpirnay/refactor-activities

refactor: Refactor activities to consistently use helpers
This commit is contained in:
jpirnay
2026-04-16 14:51:54 +02:00
committed by GitHub
13 changed files with 301 additions and 271 deletions
+2
View File
@@ -110,6 +110,7 @@ STR_TIME_TO_SLEEP: "Time to Sleep"
STR_SHOW_HIDDEN_FILES: "Show Hidden Files"
STR_SHOW_FILE_EXTENSIONS: "Show File Extensions"
STR_USE_CLOCK: "Use Clock"
STR_USE_WEATHER: "Use Weather"
STR_CLOCK_SETTINGS: "Clock Settings"
STR_CLOCK_SETTINGS_WARNING: "Uses more battery; clock may drift"
STR_CLOCK: "Clock"
@@ -379,6 +380,7 @@ STR_AUTO_TURN_ENABLED: "Auto Turn Enabled: "
STR_AUTO_TURN_PAGES_PER_MIN: "Auto Turn (Pages Per Minute)"
STR_WEATHER: "Weather"
STR_WEATHER_LOCATION: "Location"
STR_WEATHER_UNITS: "Units"
STR_WEATHER_NO_LOCATION: "No location set for weather"
STR_WEATHER_FETCH_FAILED: "Failed to fetch weather"
STR_WEATHER_SETTINGS: "Weather Settings"
+26
View File
@@ -44,6 +44,18 @@ STR_CONNECT_WIFI_HINT: "Connectez un appareil à ce WiFi"
STR_OPEN_URL_HINT: "Ouvrez cette URL dans un navigateur"
STR_OR_HTTP_PREFIX: "ou http://"
STR_SCAN_QR_HINT: "ou scannez le QR code :"
STR_KEYBOARD_HELP_URL_LINE_1: "Mode URL : Espace bascule les snippets URL."
STR_KEYBOARD_HELP_URL_LINE_2: "Utilisez une grille 3×3 pour protocoles, hôtes et domaines."
STR_KEYBOARD_HELP_URL_LINE_3: "Appuyez sur ABC pour quitter le mode URL."
STR_KEYBOARD_HELP_CURSOR_LINE_1: "Mode curseur : appui long Haut, court Bas pour quitter."
STR_KEYBOARD_HELP_CURSOR_LINE_2: "Gauche/Droite déplace le curseur ; Confirmer bascule [abc]/[***]."
STR_KEYBOARD_HELP_CURSOR_LINE_3: "Le curseur bloc met en surbrillance le caractère sélectionné."
STR_KEYBOARD_HELP_PASSWORD_LINE_1: "Mode mot de passe masque le texte avec * et révèle un caractère."
STR_KEYBOARD_HELP_PASSWORD_LINE_2: "Utilisez le mode curseur au-delà de la fin pour basculer [abc]/[***]."
STR_KEYBOARD_HELP_PASSWORD_LINE_3: "Appui long sur Suppr efface tout le texte."
STR_KEYBOARD_HELP_DEFAULT_LINE_1: "Appui long sur Haut pour le mode curseur ; Gauche/Droite déplace le curseur."
STR_KEYBOARD_HELP_DEFAULT_LINE_2: "Maintenez Confirmer pour des caractères alternatifs en mode ABC."
STR_KEYBOARD_HELP_DEFAULT_LINE_3: "Shift change la casse ; Espace insère un espace normal."
STR_RSSI: "RSSI"
STR_NO_SIGNAL: "Pas de signal"
STR_SIGNAL_QUALITY_POOR: "Faible"
@@ -340,6 +352,7 @@ STR_OVERLAY_READING_PROGRESS: "Progression : Page %lu/%u - %.0f%%"
STR_OVERLAY_READING_PROGRESS_NO_TOTAL: "Progression : Page %lu"
STR_OVERLAY_CHAPTER_PAGE_SUFFIX: " - Page %d/%d - %.0f%%"
STR_USE_CLOCK: "Afficher l'horloge"
STR_USE_WEATHER: "Afficher la météo"
STR_CLOCK_SETTINGS: "Réglages horloge"
STR_CLOCK_SETTINGS_WARNING: "Consomme plus de batterie ; l'heure peut dériver"
STR_CLOCK: "Horloge"
@@ -377,6 +390,16 @@ STR_DST_ACTIVE: "Heure d'été : active"
STR_DST_INACTIVE: "Heure d'été : inactive"
STR_DST_UNKNOWN: "Heure d'été : inconnue"
STR_SYSTEM_INFO: "Informations système"
STR_APP_PARTITION: "Partition de l'application"
STR_DEVICE: "Appareil"
STR_FLASH_TOTAL: "Flash total"
STR_MEM_COMBINED: "Libre / Min / Max"
STR_SEC_VERSION: "Version"
STR_SEC_CHIP: "Chip"
STR_SEC_FLASH: "Flash"
STR_SEC_MEMORY: "Mémoire"
STR_SEC_RUNTIME: "Exécution"
STR_SEC_STORAGE: "Stockage"
STR_LOAD_XTC_FAILED: "Échec du chargement XTC"
STR_LOAD_EPUB_FAILED: "Échec du chargement EPUB"
STR_FW_VERSION: "Version FW"
@@ -393,6 +416,7 @@ STR_GATHERING_DATA: "Collecte des données…"
STR_SD_UPDATE_PROMPT: "Appuyez sur mise à jour"
STR_WEATHER: "Météo"
STR_WEATHER_LOCATION: "Lieu"
STR_WEATHER_UNITS: "Unités"
STR_WEATHER_NO_LOCATION: "Aucun lieu défini pour la météo"
STR_WEATHER_FETCH_FAILED: "Échec du chargement météo"
STR_WEATHER_SETTINGS: "Réglages météo"
@@ -483,6 +507,8 @@ STR_SLEEP_SCREEN_SET: "Écran de veille mis à jour !"
STR_IMAGE_DISPLAY_BW: ">> N/B"
STR_IMAGE_DISPLAY_GRAYSCALE: ">> Niveaux de gris"
STR_READER_BOOKMARKS: "Signets & notes de bas de page"
STR_GLOBAL_BOOKMARKS: "Signets"
STR_NO_GLOBAL_BOOKMARKS: "Aucun signet pour l'instant"
STR_READER_UTILS: "Utilitaire"
STR_STARRED_PAGES: "Pages marquées"
STR_STAR_PAGE: "Marquer la page"
+26
View File
@@ -358,6 +358,8 @@ STR_SLEEP_SCREEN_SET: "Standby-Bild aktualisiert!"
STR_IMAGE_DISPLAY_BW: ">> S/W"
STR_IMAGE_DISPLAY_GRAYSCALE: ">> Grau"
STR_READER_BOOKMARKS: "Lesezeichen & Fußnoten"
STR_GLOBAL_BOOKMARKS: "Lesezeichen"
STR_NO_GLOBAL_BOOKMARKS: "Noch keine Lesezeichen"
STR_READER_UTILS: "Hilfsfunktionen"
STR_STARRED_PAGES: "Markierte Seiten"
STR_STAR_PAGE: "Seite markieren"
@@ -384,6 +386,7 @@ STR_MENU_KOSYNC_AUTH: "Anmelden / Registrieren"
STR_WEATHER: "Wetter"
STR_WEATHER_LOCATION: "Ort"
STR_WEATHER_UNITS: "Einheiten"
STR_WEATHER_NO_LOCATION: "Kein Ort für Wetter festgelegt"
STR_WEATHER_FETCH_FAILED: "Wetterdaten konnten nicht geladen werden"
STR_WEATHER_SETTINGS: "Wettereinstellungen"
@@ -466,6 +469,7 @@ STR_WEATHER_DESC_THUNDERSTORM_HEAVY_HAIL: "Gewitter mit starkem Hagel"
STR_WEATHER_DESC_UNKNOWN: "Unbekannt"
STR_CREATE_FALLBACK_FOR_INVALID_TOC: "Ersatz für ungültiges Inhaltsverzeichnis erstellen"
STR_USE_CLOCK: "Uhr anzeigen"
STR_USE_WEATHER: "Wetter verwenden"
STR_CLOCK_SETTINGS: "Uhr-Einstellungen"
STR_CLOCK_SETTINGS_WARNING: "Verbraucht mehr Akku; Uhr kann abweichen"
STR_CLOCK: "Uhr"
@@ -509,3 +513,25 @@ STR_OVERLAY_OFF: "Aus"
STR_OVERLAY_READING_PROGRESS: "Lesefortschritt: Seite %lu/%u - %.0f%%"
STR_OVERLAY_READING_PROGRESS_NO_TOTAL: "Lesefortschritt: Seite %lu"
STR_OVERLAY_CHAPTER_PAGE_SUFFIX: " - Seite %d/%d - %.0f%%"
STR_APP_PARTITION: "App-Partition"
STR_DEVICE: "Gerät"
STR_FLASH_TOTAL: "Gesamter Flash"
STR_MEM_COMBINED: "Frei / Min / Max"
STR_SEC_VERSION: "Version"
STR_SEC_CHIP: "Chip"
STR_SEC_FLASH: "Flash"
STR_SEC_MEMORY: "Speicher"
STR_SEC_RUNTIME: "Laufzeit"
STR_SEC_STORAGE: "Speicherplatz"
STR_KEYBOARD_HELP_URL_LINE_1: "URL-Modus: Leer schaltet URL-Snippets um."
STR_KEYBOARD_HELP_URL_LINE_2: "Nutzt 3×3-Raster für Protokolle, Hosts und Domains."
STR_KEYBOARD_HELP_URL_LINE_3: "Drücke ABC, um den URL-Modus zu verlassen."
STR_KEYBOARD_HELP_CURSOR_LINE_1: "Cursor-Modus: Hoch lange drücken, Ende mit Runter."
STR_KEYBOARD_HELP_CURSOR_LINE_2: "Links/Rechts bewegt Cursor; Bestätigen schaltet [abc]/[***] um."
STR_KEYBOARD_HELP_CURSOR_LINE_3: "Der Blockcursor markiert das ausgewählte Zeichen."
STR_KEYBOARD_HELP_PASSWORD_LINE_1: "Passwortmodus versteckt Text mit * und zeigt ein Zeichen an."
STR_KEYBOARD_HELP_PASSWORD_LINE_2: "Am Textende rechts drücken für [abc] bzw. [***]."
STR_KEYBOARD_HELP_PASSWORD_LINE_3: "Entf lang drücken löscht alles."
STR_KEYBOARD_HELP_DEFAULT_LINE_1: "Hoch lang drücken für Cursor-Modus; <- -> bewegt den Cursor."
STR_KEYBOARD_HELP_DEFAULT_LINE_2: "Lange Bestätigen drücken für alternative Zeichen."
STR_KEYBOARD_HELP_DEFAULT_LINE_3: "umsch für Groß-/Kleinschreibung"
+26
View File
@@ -44,6 +44,18 @@ STR_CONNECT_WIFI_HINT: "Connettere il dispositivo a questa rete WiFi"
STR_OPEN_URL_HINT: "Aprire questo URL nel browser"
STR_OR_HTTP_PREFIX: "o http://"
STR_SCAN_QR_HINT: "oppure scansionare il codice QR col telefono:"
STR_KEYBOARD_HELP_URL_LINE_1: "Modalità URL: Spazio alterna gli snippet URL."
STR_KEYBOARD_HELP_URL_LINE_2: "Usa una griglia 3×3 per protocolli, host e domini."
STR_KEYBOARD_HELP_URL_LINE_3: "Premi ABC per uscire dalla modalità URL."
STR_KEYBOARD_HELP_CURSOR_LINE_1: "Modalità cursore: tieni premuto Su, breve Giù per uscire."
STR_KEYBOARD_HELP_CURSOR_LINE_2: "Sinistra/Destra sposta il cursore; Conferma alterna [abc]/[***]."
STR_KEYBOARD_HELP_CURSOR_LINE_3: "Il cursore blocco evidenzia il carattere selezionato."
STR_KEYBOARD_HELP_PASSWORD_LINE_1: "Modalità password nasconde il testo con * e mostra un carattere."
STR_KEYBOARD_HELP_PASSWORD_LINE_2: "Usa la modalità cursore oltre la fine per alternare [abc]/[***]."
STR_KEYBOARD_HELP_PASSWORD_LINE_3: "Tieni premuto Canc per cancellare tutto il testo."
STR_KEYBOARD_HELP_DEFAULT_LINE_1: "Tieni premuto Su per la modalità cursore; Sinistra/Destra sposta il cursore."
STR_KEYBOARD_HELP_DEFAULT_LINE_2: "Tieni premuto Conferma per caratteri alternativi in modalità ABC."
STR_KEYBOARD_HELP_DEFAULT_LINE_3: "Shift cambia maiuscole/minuscole; Spazio inserisce uno spazio normale."
STR_RSSI: "RSSI"
STR_NO_SIGNAL: "Nessun segnale"
STR_SIGNAL_QUALITY_POOR: "Scarso"
@@ -322,6 +334,7 @@ STR_IMAGE_DITHER_ATKINSON: "Atkinson"
STR_IMAGE_DITHER_DIFFUSED_BAYER: "Bayer diffuso"
STR_CREATE_FALLBACK_FOR_INVALID_TOC: "Crea fallback per TOC non valido"
STR_USE_CLOCK: "Mostra orologio"
STR_USE_WEATHER: "Usa meteo"
STR_CLOCK_SETTINGS: "Impostazioni orologio"
STR_CLOCK_SETTINGS_WARNING: "Consuma più batteria; l'orologio può scorrere"
STR_CLOCK: "Orologio"
@@ -370,6 +383,7 @@ STR_MAPPING_REMOTE: "Mappatura posizione remota..."
STR_MAPPING_LOCAL: "Calcolo posizione locale..."
STR_WEATHER: "Meteo"
STR_WEATHER_LOCATION: "Località"
STR_WEATHER_UNITS: "Unità"
STR_WEATHER_NO_LOCATION: "Nessuna località impostata"
STR_WEATHER_FETCH_FAILED: "Impossibile recuperare il meteo"
STR_WEATHER_SETTINGS: "Impostazioni meteo"
@@ -458,6 +472,16 @@ STR_OVERLAY_READING_PROGRESS: "Avanzamento lettura: Pagina %lu/%u - %.0f%%"
STR_OVERLAY_READING_PROGRESS_NO_TOTAL: "Avanzamento lettura: Pagina %lu"
STR_OVERLAY_CHAPTER_PAGE_SUFFIX: " - Pagina %d/%d - %.0f%%"
STR_SYSTEM_INFO: "Informazioni di sistema"
STR_APP_PARTITION: "Partizione app"
STR_DEVICE: "Dispositivo"
STR_FLASH_TOTAL: "Flash totale"
STR_MEM_COMBINED: "Libero / Min / Max"
STR_SEC_VERSION: "Versione"
STR_SEC_CHIP: "Chip"
STR_SEC_FLASH: "Flash"
STR_SEC_MEMORY: "Memoria"
STR_SEC_RUNTIME: "Runtime"
STR_SEC_STORAGE: "Archiviazione"
STR_LOAD_XTC_FAILED: "Impossibile caricare file XTC"
STR_LOAD_EPUB_FAILED: "Impossibile caricare file EPUB"
STR_FW_VERSION: "Versione FW"
@@ -481,6 +505,8 @@ STR_SLEEP_SCREEN_SET: "Schermo standby aggiornato!"
STR_IMAGE_DISPLAY_BW: ">> B/N"
STR_IMAGE_DISPLAY_GRAYSCALE: ">> Gradazioni di grigio"
STR_READER_BOOKMARKS: "Segnalibri e note"
STR_GLOBAL_BOOKMARKS: "Segnalibri"
STR_NO_GLOBAL_BOOKMARKS: "Ancora nessun segnalibro"
STR_READER_UTILS: "Utilità"
STR_STARRED_PAGES: "Pagine contrassegnate"
STR_STAR_PAGE: "Contrassegna pagina"
+26
View File
@@ -44,6 +44,18 @@ STR_CONNECT_WIFI_HINT: "Подключите устройство к этой с
STR_OPEN_URL_HINT: "Откройте этот адрес в браузере"
STR_OR_HTTP_PREFIX: "или http://"
STR_SCAN_QR_HINT: "или отсканируйте QR-код:"
STR_KEYBOARD_HELP_URL_LINE_1: "Режим URL: пробел переключает фрагменты URL."
STR_KEYBOARD_HELP_URL_LINE_2: "Используйте сетку 3×3 для протоколов, хостов и доменов."
STR_KEYBOARD_HELP_URL_LINE_3: "Нажмите ABC, чтобы выйти из режима URL."
STR_KEYBOARD_HELP_CURSOR_LINE_1: "Режим курсора: длинное нажатие Вверх, короткое Вниз для выхода."
STR_KEYBOARD_HELP_CURSOR_LINE_2: "Влево/Вправо перемещает курсор; Подтвердить переключает [abc]/[***]."
STR_KEYBOARD_HELP_CURSOR_LINE_3: "Блочный курсор выделяет выбранный символ."
STR_KEYBOARD_HELP_PASSWORD_LINE_1: "Режим пароля скрывает текст * и показывает один символ."
STR_KEYBOARD_HELP_PASSWORD_LINE_2: "Используйте режим курсора за концом, чтобы переключить [abc]/[***]."
STR_KEYBOARD_HELP_PASSWORD_LINE_3: "Долгое нажатие Del удаляет весь текст."
STR_KEYBOARD_HELP_DEFAULT_LINE_1: "Долгое нажатие Вверх для режима курсора; Влево/Вправо перемещает курсор."
STR_KEYBOARD_HELP_DEFAULT_LINE_2: "Удерживайте Подтвердить для альтернативного ввода в режиме ABC."
STR_KEYBOARD_HELP_DEFAULT_LINE_3: "Shift переключает регистр; Пробел вставляет обычный пробел."
STR_RSSI: "RSSI"
STR_NO_SIGNAL: "Нет сигнала"
STR_SIGNAL_QUALITY_POOR: "Плохо"
@@ -337,6 +349,7 @@ STR_OVERLAY_READING_PROGRESS: "Прогресс: Стр. %lu/%u - %.0f%%"
STR_OVERLAY_READING_PROGRESS_NO_TOTAL: "Прогресс: Стр. %lu"
STR_OVERLAY_CHAPTER_PAGE_SUFFIX: " - Стр. %d/%d - %.0f%%"
STR_USE_CLOCK: "Показывать часы"
STR_USE_WEATHER: "Использовать погоду"
STR_CLOCK_SETTINGS: "Настройки часов"
STR_CLOCK_SETTINGS_WARNING: "Расходует больше батареи; часы могут отставать"
STR_CLOCK: "Часы"
@@ -374,6 +387,16 @@ STR_DST_ACTIVE: "Летнее время: вкл"
STR_DST_INACTIVE: "Летнее время: выкл"
STR_DST_UNKNOWN: "Летнее время: неизвестно"
STR_SYSTEM_INFO: "Информация о системе"
STR_APP_PARTITION: "Раздел приложения"
STR_DEVICE: "Устройство"
STR_FLASH_TOTAL: "Всего Flash"
STR_MEM_COMBINED: "Свободно / Мин / Макс"
STR_SEC_VERSION: "Версия"
STR_SEC_CHIP: "Чип"
STR_SEC_FLASH: "Flash"
STR_SEC_MEMORY: "Память"
STR_SEC_RUNTIME: "Время работы"
STR_SEC_STORAGE: "Хранилище"
STR_LOAD_XTC_FAILED: "Ошибка загрузки файла XTC"
STR_LOAD_EPUB_FAILED: "Ошибка загрузки файла EPUB"
STR_FW_VERSION: "Версия ПО"
@@ -390,6 +413,7 @@ STR_GATHERING_DATA: "Сбор данных..."
STR_SD_UPDATE_PROMPT: "Нажмите обновить"
STR_WEATHER: "Погода"
STR_WEATHER_LOCATION: "Местоположение"
STR_WEATHER_UNITS: "Единицы"
STR_WEATHER_NO_LOCATION: "Местоположение не задано"
STR_WEATHER_FETCH_FAILED: "Ошибка загрузки погоды"
STR_WEATHER_SETTINGS: "Настройки погоды"
@@ -483,6 +507,8 @@ STR_SLEEP_SCREEN_SET: "Экран сна обновлён!"
STR_IMAGE_DISPLAY_BW: ">> Ч/Б"
STR_IMAGE_DISPLAY_GRAYSCALE: ">> Оттенки серого"
STR_READER_BOOKMARKS: "Закладки и сноски"
STR_GLOBAL_BOOKMARKS: "Закладки"
STR_NO_GLOBAL_BOOKMARKS: "Пока нет закладок"
STR_READER_UTILS: "Утилиты"
STR_STARRED_PAGES: "Отмеченные страницы"
STR_STAR_PAGE: "Отметить страницу"
+26
View File
@@ -44,6 +44,18 @@ STR_CONNECT_WIFI_HINT: "Conecte su dispositivo a esta red Wi-Fi"
STR_OPEN_URL_HINT: "Abra esta dirección en su navegador"
STR_OR_HTTP_PREFIX: "o http://"
STR_SCAN_QR_HINT: "o escanee el código QR con su móvil:"
STR_KEYBOARD_HELP_URL_LINE_1: "Modo URL: Espacio cambia fragmentos de URL."
STR_KEYBOARD_HELP_URL_LINE_2: "Use una cuadrícula 3×3 para protocolos, hosts y dominios."
STR_KEYBOARD_HELP_URL_LINE_3: "Presione ABC para salir del modo URL."
STR_KEYBOARD_HELP_CURSOR_LINE_1: "Modo cursor: presione largo Arriba, corto Abajo para salir."
STR_KEYBOARD_HELP_CURSOR_LINE_2: "Izquierda/Derecha mueve el cursor; Confirmar alterna [abc]/[***]."
STR_KEYBOARD_HELP_CURSOR_LINE_3: "El cursor bloque resalta el carácter seleccionado."
STR_KEYBOARD_HELP_PASSWORD_LINE_1: "Modo contraseña oculta texto con * y muestra un carácter."
STR_KEYBOARD_HELP_PASSWORD_LINE_2: "Use el modo cursor más allá del final para alternar [abc]/[***]."
STR_KEYBOARD_HELP_PASSWORD_LINE_3: "Presione largo Supr para borrar todo el texto."
STR_KEYBOARD_HELP_DEFAULT_LINE_1: "Presione largo Arriba para modo cursor; Izquierda/Derecha mueve el cursor."
STR_KEYBOARD_HELP_DEFAULT_LINE_2: "Mantenga pulsado Confirmar para caracteres alternativos en modo ABC."
STR_KEYBOARD_HELP_DEFAULT_LINE_3: "Shift cambia mayúsculas/minúsculas; Espacio inserta un espacio normal."
STR_CALIBRE_WIRELESS: "Calibre inalámbrico"
STR_CALIBRE_WEB_URL: "OPDS URL"
STR_NETWORK_LEGEND: "* (Cifrado) | + (Guardado)"
@@ -334,6 +346,7 @@ STR_OVERLAY_READING_PROGRESS: "Progreso: Página %lu/%u - %.0f%%"
STR_OVERLAY_READING_PROGRESS_NO_TOTAL: "Progreso: Página %lu"
STR_OVERLAY_CHAPTER_PAGE_SUFFIX: " - Página %d/%d - %.0f%%"
STR_USE_CLOCK: "Mostrar reloj"
STR_USE_WEATHER: "Usar clima"
STR_CLOCK_SETTINGS: "Ajustes de reloj"
STR_CLOCK_SETTINGS_WARNING: "Consume más batería; el reloj puede desviarse"
STR_CLOCK: "Reloj"
@@ -371,6 +384,16 @@ STR_DST_ACTIVE: "Horario de verano: activo"
STR_DST_INACTIVE: "Horario de verano: inactivo"
STR_DST_UNKNOWN: "Horario de verano: desconocido"
STR_SYSTEM_INFO: "Información del sistema"
STR_APP_PARTITION: "Partición de la app"
STR_DEVICE: "Dispositivo"
STR_FLASH_TOTAL: "Flash total"
STR_MEM_COMBINED: "Libre / Min / Máx"
STR_SEC_VERSION: "Versión"
STR_SEC_CHIP: "Chip"
STR_SEC_FLASH: "Flash"
STR_SEC_MEMORY: "Memoria"
STR_SEC_RUNTIME: "Tiempo de ejecución"
STR_SEC_STORAGE: "Almacenamiento"
STR_LOAD_XTC_FAILED: "Error al cargar archivo XTC"
STR_LOAD_EPUB_FAILED: "Error al cargar archivo EPUB"
STR_FW_VERSION: "Versión FW"
@@ -387,6 +410,7 @@ STR_GATHERING_DATA: "Recopilando datos..."
STR_SD_UPDATE_PROMPT: "Presiona actualizar"
STR_WEATHER: "Clima"
STR_WEATHER_LOCATION: "Ubicación"
STR_WEATHER_UNITS: "Unidades"
STR_WEATHER_NO_LOCATION: "No se ha configurado ubicación"
STR_WEATHER_FETCH_FAILED: "Error al obtener datos del clima"
STR_WEATHER_SETTINGS: "Ajustes del clima"
@@ -483,6 +507,8 @@ STR_SLEEP_SCREEN_SET: "Pantalla de suspensión actualizada!"
STR_IMAGE_DISPLAY_BW: ">> N/B"
STR_IMAGE_DISPLAY_GRAYSCALE: ">> Escala de grises"
STR_READER_BOOKMARKS: "Marcadores y notas"
STR_GLOBAL_BOOKMARKS: "Marcadores"
STR_NO_GLOBAL_BOOKMARKS: "Aún no hay marcadores"
STR_READER_UTILS: "Utilidades"
STR_STARRED_PAGES: "Páginas marcadas"
STR_STAR_PAGE: "Marcar página"
+2
View File
@@ -271,6 +271,8 @@ class CrossPointSettings {
// Use clock and keep the LP timer running during deep sleep (GPIO13 HIGH)
// so time can be accurately restored on wake. Increases sleep current by ~3-4 mA.
uint8_t useClock = 0;
// Show the Weather home screen menu item (1 = enabled, 0 = hidden)
uint8_t useWeather = 1;
~CrossPointSettings() = default;
+1
View File
@@ -143,6 +143,7 @@ inline const std::vector<SettingInfo> list = {
StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST},
"timeZone", StrId::STR_CAT_SYSTEM),
SettingInfo::Toggle(StrId::STR_USE_CLOCK, &CrossPointSettings::useClock, "useClock", StrId::STR_CAT_SYSTEM),
SettingInfo::Toggle(StrId::STR_USE_WEATHER, &CrossPointSettings::useWeather, "useWeather", StrId::STR_CAT_SYSTEM),
// --- KOReader Sync (web-only, uses KOReaderCredentialStore) ---
SettingInfo::DynamicString(
+16 -4
View File
@@ -100,7 +100,10 @@ int getHomeCoverRenderHeight(const HomeScreenLayout& layout) {
} // namespace
int HomeActivity::getMenuItemCount() const {
int count = 5; // File Browser, Recents, File transfer, Weather, Settings
int count = 4; // File Browser, Recents, File transfer, Settings
if (SETTINGS.useWeather) {
count++;
}
if (!recentBooks.empty()) {
count += recentBooks.size();
}
@@ -283,12 +286,13 @@ void HomeActivity::loop() {
int idx = 0;
int menuSelectedIndex = selectorIndex - static_cast<int>(recentBooks.size());
const bool hasGlobalBookmarks = !GLOBAL_BOOKMARKS.isEmpty();
const bool hasWeather = SETTINGS.useWeather;
const int fileBrowserIdx = idx++;
const int recentsIdx = idx++;
const int globalBookmarksIdx = hasGlobalBookmarks ? idx++ : -1;
const int opdsLibraryIdx = hasOpdsUrl ? idx++ : -1;
const int fileTransferIdx = idx++;
const int weatherIdx = idx++;
const int weatherIdx = hasWeather ? idx++ : -1;
const int settingsIdx = idx;
if (selectorIndex < recentBooks.size()) {
@@ -321,9 +325,17 @@ void HomeActivity::render(RenderLock&&) {
GUI.drawHeader(renderer, Rect{contentRect.x, metrics.topPadding, contentRect.width, metrics.homeTopPadding}, nullptr);
// Build menu items dynamically
const char* weatherMenuLabel = SETTINGS.useWeather ? tr(STR_WEATHER) : tr(STR_SETTINGS_TITLE);
const UIIcon weatherMenuIcon = SETTINGS.useWeather ? Weather : Settings;
std::vector<const char*> menuItems = {tr(STR_BROWSE_FILES), tr(STR_MENU_RECENT_BOOKS), tr(STR_FILE_TRANSFER),
tr(STR_WEATHER), tr(STR_SETTINGS_TITLE)};
std::vector<UIIcon> menuIcons = {Folder, Recent, Transfer, Weather, Settings};
weatherMenuLabel, tr(STR_SETTINGS_TITLE)};
std::vector<UIIcon> menuIcons = {Folder, Recent, Transfer, weatherMenuIcon, Settings};
if (!SETTINGS.useWeather) {
menuItems.erase(menuItems.begin() + 3);
menuIcons.erase(menuIcons.begin() + 3);
}
int insertAfterRecents = 2;
if (!GLOBAL_BOOKMARKS.isEmpty()) {
+32 -100
View File
@@ -6,7 +6,6 @@
#include "CrossPointSettings.h"
#include "DetectTimezoneActivity.h"
#include "MappedInputManager.h"
#include "SyncTimeActivity.h"
#include "components/UITheme.h"
#include "fontIds.h"
@@ -19,94 +18,48 @@ const StrId timeZoneNames[CrossPointSettings::TIMEZONE_COUNT] = {
StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST};
} // namespace
std::string ClockSettingsActivity::MenuItem::getTitle() const {
const auto t = I18N.get(labelId);
return isSeparator ? UITheme::makeSeparatorTitle(t) : t;
void ClockSettingsActivity::buildMenuItems() {
menuItems.push_back(SettingInfo::Separator(StrId::STR_SETTINGS_TITLE));
menuItems.push_back(
SettingInfo::Toggle(StrId::STR_USE_CLOCK, &CrossPointSettings::useClock, "useClock", StrId::STR_CAT_SYSTEM));
menuItems.push_back(SettingInfo::Enum(StrId::STR_CLOCK_FORMAT, &CrossPointSettings::clockFormat12h,
{StrId::STR_24H, StrId::STR_12H}, "clockFormat12h", StrId::STR_CAT_SYSTEM));
menuItems.push_back(
SettingInfo::Enum(StrId::STR_TIMEZONE, &CrossPointSettings::timeZone,
{StrId::STR_TZ_UTC, StrId::STR_TZ_CET, StrId::STR_TZ_EET, StrId::STR_TZ_MSK,
StrId::STR_TZ_UTC_PLUS4, StrId::STR_TZ_IST, StrId::STR_TZ_UTC_PLUS7, StrId::STR_TZ_UTC_PLUS8,
StrId::STR_TZ_UTC_PLUS9, StrId::STR_TZ_AEST, StrId::STR_TZ_NZST, StrId::STR_TZ_UTC_MINUS3,
StrId::STR_TZ_EST, StrId::STR_TZ_CST, StrId::STR_TZ_MST, StrId::STR_TZ_PST},
"timeZone", StrId::STR_CAT_SYSTEM));
menuItems.push_back(SettingInfo::Action(StrId::STR_DETECT_TIMEZONE, SettingAction::DetectTimezone)
.withSubcategory(StrId::STR_READER_TOOLS));
menuItems.push_back(SettingInfo::Action(StrId::STR_SYNC_TIME, SettingAction::SyncTime));
}
std::vector<ClockSettingsActivity::MenuItem> ClockSettingsActivity::buildMenuItems() {
std::vector<MenuItem> items;
items.reserve(7);
// Settings
items.push_back(MenuItem::separator(StrId::STR_SETTINGS_TITLE));
items.push_back({Action::USE_CLOCK, StrId::STR_USE_CLOCK});
items.push_back({Action::CLOCK_FORMAT, StrId::STR_CLOCK_FORMAT});
items.push_back({Action::TIMEZONE, StrId::STR_TIMEZONE});
// Tools
items.push_back(MenuItem::separator(StrId::STR_READER_TOOLS));
items.push_back({Action::DETECT_TIMEZONE, StrId::STR_DETECT_TIMEZONE});
items.push_back({Action::SYNC_TIME, StrId::STR_SYNC_TIME});
return items;
}
void ClockSettingsActivity::onEnter() {
Activity::onEnter();
const auto pred = UITheme::makeSelectablePredicate(static_cast<int>(menuItems.size()),
[this](int i) { return menuItems[i].getTitle(); });
buttonNavigator.setSelectablePredicate(pred, static_cast<int>(menuItems.size()));
if (!pred(selectedIndex)) {
selectedIndex = buttonNavigator.nextIndex(selectedIndex);
void ClockSettingsActivity::onActionSelected(int index) {
const auto& item = menuItems[index];
if (item.nameId == StrId::STR_DETECT_TIMEZONE) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<DetectTimezoneActivity>(renderer, mappedInput), resultHandler);
} else if (item.nameId == StrId::STR_SYNC_TIME) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<SyncTimeActivity>(renderer, mappedInput), resultHandler);
}
requestUpdate();
}
void ClockSettingsActivity::onExit() { Activity::onExit(); }
void ClockSettingsActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
finish();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
handleSelection();
requestUpdate();
return;
}
buttonNavigator.onNextRelease([this] {
selectedIndex = buttonNavigator.nextIndex(selectedIndex);
requestUpdate();
});
buttonNavigator.onPreviousRelease([this] {
selectedIndex = buttonNavigator.previousIndex(selectedIndex);
requestUpdate();
});
buttonNavigator.onNextContinuous([this] {
selectedIndex = buttonNavigator.nextIndex(selectedIndex);
requestUpdate();
});
buttonNavigator.onPreviousContinuous([this] {
selectedIndex = buttonNavigator.previousIndex(selectedIndex);
requestUpdate();
});
}
void ClockSettingsActivity::handleSelection() {
const auto action = menuItems[selectedIndex].action;
if (action == Action::USE_CLOCK) {
SETTINGS.useClock = (SETTINGS.useClock + 1) % 2;
void ClockSettingsActivity::onSettingToggled(int index) {
const auto& item = menuItems[index];
if (item.nameId == StrId::STR_USE_CLOCK) {
if (!SETTINGS.useClock) {
SETTINGS.statusBarClock = 0;
}
SETTINGS.saveToFile();
} else if (action == Action::CLOCK_FORMAT) {
SETTINGS.clockFormat12h = (SETTINGS.clockFormat12h + 1) % 2;
SETTINGS.saveToFile();
} else if (action == Action::TIMEZONE) {
SETTINGS.timeZone = (SETTINGS.timeZone + 1) % CrossPointSettings::TIMEZONE_COUNT;
} else if (item.nameId == StrId::STR_TIMEZONE) {
HalClock::applyTimezone(SETTINGS.timeZone);
SETTINGS.saveToFile();
} else if (action == Action::SYNC_TIME) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<SyncTimeActivity>(renderer, mappedInput), resultHandler);
} else if (action == Action::DETECT_TIMEZONE) {
auto resultHandler = [](const ActivityResult&) { SETTINGS.saveToFile(); };
startActivityForResult(std::make_unique<DetectTimezoneActivity>(renderer, mappedInput), resultHandler);
} else if (item.nameId == StrId::STR_CLOCK_FORMAT) {
SETTINGS.saveToFile();
}
}
@@ -129,28 +82,7 @@ void ClockSettingsActivity::render(RenderLock&&) {
const int contentHeight = contentRect.height - (metrics.topPadding + metrics.headerHeight + metrics.tabBarHeight +
metrics.verticalSpacing * 2);
GUI.drawList(
renderer, Rect(contentRect.x, contentTop, contentRect.width, contentHeight), static_cast<int>(menuItems.size()),
selectedIndex, [this](int index) { return menuItems[index].getTitle(); }, nullptr, nullptr,
[this](int index) {
const auto action = menuItems[index].action;
switch (action) {
case Action::USE_CLOCK:
return std::string(SETTINGS.useClock ? tr(STR_STATE_ON) : tr(STR_STATE_OFF));
case Action::CLOCK_FORMAT:
return std::string(SETTINGS.clockFormat12h ? tr(STR_12H) : tr(STR_24H));
case Action::TIMEZONE: {
const auto tzIndex = static_cast<size_t>(SETTINGS.timeZone);
if (tzIndex < (sizeof(timeZoneNames) / sizeof(timeZoneNames[0]))) {
return std::string(I18N.get(timeZoneNames[tzIndex]));
}
return std::string(tr(STR_TZ_UTC));
}
default:
return std::string("");
}
},
true);
drawMenuList(Rect{contentRect.x, contentTop, contentRect.width, contentHeight});
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);
+11 -28
View File
@@ -1,35 +1,18 @@
#pragma once
#include <I18n.h>
#include <functional>
#include <vector>
#include "activities/Activity.h"
#include "util/ButtonNavigator.h"
class ClockSettingsActivity final : public Activity {
enum class Action { USE_CLOCK, CLOCK_FORMAT, TIMEZONE, SYNC_TIME, DETECT_TIMEZONE, NONE };
struct MenuItem {
Action action;
StrId labelId;
bool isSeparator = false;
static MenuItem separator(StrId label) { return {Action::NONE, label, true}; }
[[nodiscard]] std::string getTitle() const;
};
ButtonNavigator buttonNavigator;
int selectedIndex = 0;
const std::vector<MenuItem> menuItems;
static std::vector<MenuItem> buildMenuItems();
void handleSelection();
#include "../MenuListActivity.h"
class ClockSettingsActivity final : public MenuListActivity {
public:
explicit ClockSettingsActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
: Activity("ClockSettings", renderer, mappedInput), menuItems(buildMenuItems()) {}
void onEnter() override;
void onExit() override;
void loop() override;
: MenuListActivity("ClockSettings", renderer, mappedInput) {
buildMenuItems();
}
void render(RenderLock&&) override;
private:
void buildMenuItems();
void onActionSelected(int index) override;
void onSettingToggled(int index) override;
};
@@ -13,29 +13,29 @@
#include "components/UITheme.h"
#include "fontIds.h"
namespace {
const StrId menuNames[] = {
StrId::STR_WEATHER_LOCATION, // 0: Search city
StrId::STR_WEATHER_LATITUDE, // 1: Manual latitude
StrId::STR_WEATHER_LONGITUDE, // 2: Manual longitude
StrId::STR_WEATHER_TEMP_UNIT, // 3: Temperature unit
StrId::STR_WEATHER_WIND_UNIT, // 4: Wind speed unit
StrId::STR_WEATHER_PRECIP_UNIT, // 5: Precipitation unit
};
} // namespace
void WeatherSettingsActivity::buildMenuItems() {
menuItems.push_back(SettingInfo::Separator(StrId::STR_SETTINGS_TITLE));
menuItems.push_back(SettingInfo::Toggle(StrId::STR_USE_WEATHER, &CrossPointSettings::useWeather, "useWeather",
StrId::STR_CAT_SYSTEM));
void WeatherSettingsActivity::onEnter() {
Activity::onEnter();
selectedIndex = 0;
showingSearchResults = false;
requestUpdate();
menuItems.push_back(SettingInfo::Separator(StrId::STR_WEATHER_LOCATION));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_LOCATION, SettingAction::None));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_LATITUDE, SettingAction::None));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_LONGITUDE, SettingAction::None));
menuItems.push_back(SettingInfo::Separator(StrId::STR_WEATHER_UNITS));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_TEMP_UNIT, SettingAction::None));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_WIND_UNIT, SettingAction::None));
menuItems.push_back(SettingInfo::Action(StrId::STR_WEATHER_PRECIP_UNIT, SettingAction::None));
}
void WeatherSettingsActivity::onExit() { Activity::onExit(); }
void WeatherSettingsActivity::onEnter() {
MenuListActivity::onEnter();
showingSearchResults = false;
}
void WeatherSettingsActivity::loop() {
if (showingSearchResults) {
// Handle search results navigation
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
showingSearchResults = false;
requestUpdate();
@@ -43,7 +43,7 @@ void WeatherSettingsActivity::loop() {
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
if (!searchResults.empty() && selectedIndex < searchResults.size()) {
if (!searchResults.empty() && selectedIndex < static_cast<int>(searchResults.size())) {
const auto& result = searchResults[selectedIndex];
WEATHER_SETTINGS.setLocation(result.latitude, result.longitude, result.name + ", " + result.country);
WEATHER_SETTINGS.saveToFile();
@@ -69,50 +69,89 @@ void WeatherSettingsActivity::loop() {
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
finish();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
handleSelection();
return;
}
buttonNavigator.onNext([this] {
selectedIndex = (selectedIndex + 1) % MENU_ITEMS;
requestUpdate();
});
buttonNavigator.onPrevious([this] {
selectedIndex = (selectedIndex + MENU_ITEMS - 1) % MENU_ITEMS;
requestUpdate();
});
MenuListActivity::loop();
}
void WeatherSettingsActivity::handleSelection() {
switch (selectedIndex) {
case 0:
launchCitySearch();
break;
case 1:
launchLatitudeEntry();
break;
case 2:
launchLongitudeEntry();
break;
case 3:
toggleTempUnit();
break;
case 4:
toggleWindUnit();
break;
case 5:
togglePrecipUnit();
break;
std::string WeatherSettingsActivity::getItemValueString(int index) const {
const auto& item = menuItems[index];
switch (item.nameId) {
case StrId::STR_WEATHER_LOCATION: {
auto name = WEATHER_SETTINGS.getLocationName();
return name.empty() ? std::string(tr(STR_NOT_SET)) : name;
}
case StrId::STR_WEATHER_LATITUDE: {
char buf[16];
snprintf(buf, sizeof(buf), "%.4f", WEATHER_SETTINGS.getLatitude());
return std::string(buf);
}
case StrId::STR_WEATHER_LONGITUDE: {
char buf[16];
snprintf(buf, sizeof(buf), "%.4f", WEATHER_SETTINGS.getLongitude());
return std::string(buf);
}
case StrId::STR_WEATHER_TEMP_UNIT:
return WEATHER_SETTINGS.getTempUnit() == WeatherTempUnit::CELSIUS ? "C" : "F";
case StrId::STR_WEATHER_WIND_UNIT:
switch (WEATHER_SETTINGS.getWindUnit()) {
case WeatherWindUnit::KMH:
return "km/h";
case WeatherWindUnit::MS:
return "m/s";
case WeatherWindUnit::MPH:
return "mph";
case WeatherWindUnit::KNOTS:
return "kn";
}
return "km/h";
case StrId::STR_WEATHER_PRECIP_UNIT:
return WEATHER_SETTINGS.getPrecipUnit() == WeatherPrecipUnit::MM ? "mm" : "in";
default:
return MenuListActivity::getItemValueString(index);
}
}
void WeatherSettingsActivity::onActionSelected(int index) {
const auto& item = menuItems[index];
if (item.nameId == StrId::STR_WEATHER_LOCATION) {
launchCitySearch();
} else if (item.nameId == StrId::STR_WEATHER_LATITUDE) {
launchLatitudeEntry();
} else if (item.nameId == StrId::STR_WEATHER_LONGITUDE) {
launchLongitudeEntry();
} else if (item.nameId == StrId::STR_WEATHER_TEMP_UNIT) {
auto current = WEATHER_SETTINGS.getTempUnit();
WEATHER_SETTINGS.setTempUnit(current == WeatherTempUnit::CELSIUS ? WeatherTempUnit::FAHRENHEIT
: WeatherTempUnit::CELSIUS);
WEATHER_SETTINGS.saveToFile();
requestUpdate();
} else if (item.nameId == StrId::STR_WEATHER_WIND_UNIT) {
auto current = static_cast<uint8_t>(WEATHER_SETTINGS.getWindUnit());
WEATHER_SETTINGS.setWindUnit(static_cast<WeatherWindUnit>((current + 1) % 4));
WEATHER_SETTINGS.saveToFile();
requestUpdate();
} else if (item.nameId == StrId::STR_WEATHER_PRECIP_UNIT) {
auto current = WEATHER_SETTINGS.getPrecipUnit();
WEATHER_SETTINGS.setPrecipUnit(current == WeatherPrecipUnit::MM ? WeatherPrecipUnit::INCH : WeatherPrecipUnit::MM);
WEATHER_SETTINGS.saveToFile();
requestUpdate();
}
}
void WeatherSettingsActivity::onSettingToggled(int index) {
if (menuItems[index].nameId == StrId::STR_USE_WEATHER) {
SETTINGS.saveToFile();
}
}
void WeatherSettingsActivity::onBackPressed() {
if (showingSearchResults) {
showingSearchResults = false;
requestUpdate();
return;
}
finish();
}
void WeatherSettingsActivity::launchCitySearch() {
startActivityForResult(std::make_unique<KeyboardEntryActivity>(renderer, mappedInput, tr(STR_WEATHER_SEARCH_CITY), "",
64, InputType::Text),
@@ -122,7 +161,6 @@ void WeatherSettingsActivity::launchCitySearch() {
const auto& kb = std::get<KeyboardResult>(result.data);
if (kb.text.empty()) return;
// Need WiFi for geocoding
if (WiFi.status() != WL_CONNECTED || WiFi.localIP() == IPAddress(0, 0, 0, 0)) {
startActivityForResult(std::make_unique<WifiSelectionActivity>(renderer, mappedInput),
[this, query = kb.text](const ActivityResult& wifiResult) {
@@ -181,28 +219,6 @@ void WeatherSettingsActivity::launchLongitudeEntry() {
});
}
void WeatherSettingsActivity::toggleTempUnit() {
auto current = WEATHER_SETTINGS.getTempUnit();
WEATHER_SETTINGS.setTempUnit(current == WeatherTempUnit::CELSIUS ? WeatherTempUnit::FAHRENHEIT
: WeatherTempUnit::CELSIUS);
WEATHER_SETTINGS.saveToFile();
requestUpdate();
}
void WeatherSettingsActivity::toggleWindUnit() {
auto current = static_cast<uint8_t>(WEATHER_SETTINGS.getWindUnit());
WEATHER_SETTINGS.setWindUnit(static_cast<WeatherWindUnit>((current + 1) % 4));
WEATHER_SETTINGS.saveToFile();
requestUpdate();
}
void WeatherSettingsActivity::togglePrecipUnit() {
auto current = WEATHER_SETTINGS.getPrecipUnit();
WEATHER_SETTINGS.setPrecipUnit(current == WeatherPrecipUnit::MM ? WeatherPrecipUnit::INCH : WeatherPrecipUnit::MM);
WEATHER_SETTINGS.saveToFile();
requestUpdate();
}
void WeatherSettingsActivity::render(RenderLock&&) {
renderer.clearScreen();
@@ -210,7 +226,6 @@ void WeatherSettingsActivity::render(RenderLock&&) {
const Rect contentRect = UITheme::getContentRect(renderer, true, false);
if (showingSearchResults) {
// Display search results
GUI.drawHeader(renderer,
Rect(contentRect.x, contentRect.y + metrics.topPadding, contentRect.width, metrics.headerHeight),
tr(STR_WEATHER_SEARCH_RESULTS));
@@ -241,7 +256,6 @@ void WeatherSettingsActivity::render(RenderLock&&) {
return;
}
// Main settings menu
GUI.drawHeader(renderer,
Rect(contentRect.x, contentRect.y + metrics.topPadding, contentRect.width, metrics.headerHeight),
tr(STR_WEATHER_SETTINGS));
@@ -250,46 +264,7 @@ void WeatherSettingsActivity::render(RenderLock&&) {
const int contentHeight =
contentRect.height - (metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing * 2);
GUI.drawList(
renderer, Rect(contentRect.x, contentTop, contentRect.width, contentHeight), MENU_ITEMS,
static_cast<int>(selectedIndex), [](int index) { return std::string(I18N.get(menuNames[index])); }, nullptr,
nullptr,
[this](int index) -> std::string {
switch (index) {
case 0: {
auto name = WEATHER_SETTINGS.getLocationName();
return name.empty() ? std::string(tr(STR_NOT_SET)) : name;
}
case 1: {
char buf[16];
snprintf(buf, sizeof(buf), "%.4f", WEATHER_SETTINGS.getLatitude());
return std::string(buf);
}
case 2: {
char buf[16];
snprintf(buf, sizeof(buf), "%.4f", WEATHER_SETTINGS.getLongitude());
return std::string(buf);
}
case 3:
return WEATHER_SETTINGS.getTempUnit() == WeatherTempUnit::CELSIUS ? "C" : "F";
case 4:
switch (WEATHER_SETTINGS.getWindUnit()) {
case WeatherWindUnit::KMH:
return "km/h";
case WeatherWindUnit::MS:
return "m/s";
case WeatherWindUnit::MPH:
return "mph";
case WeatherWindUnit::KNOTS:
return "kn";
}
return "km/h";
case 5:
return WEATHER_SETTINGS.getPrecipUnit() == WeatherPrecipUnit::MM ? "mm" : "in";
}
return "";
},
true);
drawMenuList(Rect{contentRect.x, contentTop, contentRect.width, contentHeight});
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);
@@ -5,42 +5,35 @@
#include <string>
#include <vector>
#include "../Activity.h"
#include "util/ButtonNavigator.h"
#include "../MenuListActivity.h"
/**
* Settings submenu for weather configuration.
* Supports city search via geocoding, manual lat/lon entry, and unit selection.
*/
class WeatherSettingsActivity final : public Activity {
class WeatherSettingsActivity final : public MenuListActivity {
public:
explicit WeatherSettingsActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
: Activity("WeatherSettings", renderer, mappedInput) {}
: MenuListActivity("WeatherSettings", renderer, mappedInput) {
buildMenuItems();
}
void onEnter() override;
void onExit() override;
void loop() override;
void render(RenderLock&&) override;
private:
ButtonNavigator buttonNavigator;
int selectedIndex = 0;
// City search results (populated when user searches)
std::vector<GeocodingResult> searchResults;
bool showingSearchResults = false;
bool searchInProgress = false;
std::string searchQuery;
static constexpr int MENU_ITEMS = 6; // Location, Lat, Lon, TempUnit, WindUnit, PrecipUnit
void buildMenuItems();
void onActionSelected(int index) override;
std::string getItemValueString(int index) const override;
void onBackPressed() override;
void onSettingToggled(int index) override;
void handleSelection();
void launchCitySearch();
void launchLatitudeEntry();
void launchLongitudeEntry();
void toggleTempUnit();
void toggleWindUnit();
void togglePrecipUnit();
bool preventAutoSleep() override { return true; }
};