diff --git a/README.md b/README.md index 9c22d78..fe3653a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ You can flash the firmware directly from your browser to your CYD display withou 2. Insert a FAT32-formatted microSD card into your display. 3. On first boot: Calibrate the touchscreen and configure your Wi-Fi via the built-in on-screen keyboard. +**Tip:** for the best experience, set your exact location as a Location Preset (Menu → Flight Options → Location Presets → "+" → Search by address). Just type your address and the device looks up the exact coordinates for you automatically - no need to look anything up yourself. This is much more accurate than automatic IP-based location, which can easily be off by 20-30 km - you might hear a plane outside your window while the radar screen stays empty because the device thinks you're somewhere else entirely. With your precise location set, the proximity LED blinks in sync with aircraft you can actually hear overhead. You'll also be prompted to set this up right during first-time setup. + --- ## Features diff --git a/src/first_run_location_screen.cpp b/src/first_run_location_screen.cpp index 260d38c..4c8ddf0 100644 --- a/src/first_run_location_screen.cpp +++ b/src/first_run_location_screen.cpp @@ -56,11 +56,23 @@ void run(TFT_eSPI& tft) { tft.println(I18n::t(StringId::FIRST_RUN_LOCATION_TITLE)); tft.setTextColor(TFT_WHITE, TFT_BLACK); - layoutWrapped(tft, 10, 40, (int16_t)(Config::SCREEN_WIDTH - 20), 18, - I18n::t(StringId::FIRST_RUN_LOCATION_BODY)); + int16_t textEndY = layoutWrapped(tft, 10, 40, (int16_t)(Config::SCREEN_WIDTH - 20), 18, + I18n::t(StringId::FIRST_RUN_LOCATION_BODY)); - Rect setBtn = {10, (int16_t)(Config::SCREEN_HEIGHT - 96), (int16_t)(Config::SCREEN_WIDTH - 20), 40}; - Rect skipBtn = {10, (int16_t)(Config::SCREEN_HEIGHT - 50), (int16_t)(Config::SCREEN_WIDTH - 20), 40}; + // Buttons folgen direkt unter dem Text (mit etwas Abstand) statt an + // einer fest einprogrammierten Position - eine laengere Uebersetzung + // hat sonst den Text bis unter/hinter die Buttons laufen lassen + // (auf Deutsch beobachtet: Text unlesbar hinter "Adresse eingeben"/ + // "Ueberspringen"). Nach unten hin trotzdem an den Bildschirmrand + // geklemmt, falls ein Text ausnahmsweise doch sehr lang waere. + constexpr int16_t BTN_H = 40; + constexpr int16_t BTN_GAP = 8; + int16_t setY = textEndY + 14; + int16_t maxSetY = (int16_t)(Config::SCREEN_HEIGHT - (2 * BTN_H + BTN_GAP + 10)); + if (setY > maxSetY) setY = maxSetY; + + Rect setBtn = {10, setY, (int16_t)(Config::SCREEN_WIDTH - 20), BTN_H}; + Rect skipBtn = {10, (int16_t)(setY + BTN_H + BTN_GAP), (int16_t)(Config::SCREEN_WIDTH - 20), BTN_H}; drawButton(tft, setBtn, I18n::t(StringId::FIRST_RUN_LOCATION_SET_BTN)); drawButton(tft, skipBtn, I18n::t(StringId::FIRST_RUN_LOCATION_SKIP_BTN)); diff --git a/src/i18n.h b/src/i18n.h index 9afe262..c932ee3 100644 --- a/src/i18n.h +++ b/src/i18n.h @@ -246,6 +246,14 @@ enum class StringId : uint8_t { FIRST_RUN_LOCATION_SET_BTN, FIRST_RUN_LOCATION_SKIP_BTN, + // Zusaetzlicher Info-Absatz im Standort-Presets-Screen (Menue > + // Flugoptionen > Standort-Presets > "?") - weist auf den "Per Adresse + // suchen"-Weg beim "+"-Button hin (deutlich genauer als die + // automatische IP-Standortbestimmung). Ergaenzt die knappe Erwaehnung + // in LOCATION_INFO_PARA3 um denselben anschaulichen Vergleich wie im + // Ersteinrichtungs-Screen (FIRST_RUN_LOCATION_BODY) und im README. + LOCATION_INFO_PARA6, + COUNT }; diff --git a/src/i18n_de.h b/src/i18n_de.h index 33e7261..00bd3e2 100644 --- a/src/i18n_de.h +++ b/src/i18n_de.h @@ -216,9 +216,11 @@ static const char* const I18N_DE[] = { "Erneut versuchen", "Abbrechen", "Exakten Standort einrichten", - "Die automatische IP-Standortbestimmung kann leicht 20-30 km danebenliegen - du hörst vielleicht ein Flugzeug, während der Radar leer bleibt. Trage jetzt deine Adresse für exakte Koordinaten ein, für ein deutlich besseres Erlebnis. Die Näherungs-LED blinkt dann wirklich im Takt mit dem Flugzeug über dir. Du kannst das auch später jederzeit über Menü > Flugoptionen > Standort-Presets nachholen.", + "Automatische IP-Ortung kann 20-30 km danebenliegen. Adresse eintragen für exakte Koordinaten - die Näherungs-LED blinkt dann wirklich im Takt mit dem Flugzeug über dir. Später jederzeit über Standort-Presets nachholbar.", "Adresse eingeben", "Überspringen", + + "Tipp: Über den Button \"Per Adresse suchen\" beim Anlegen eines Presets (\"+\") bekommst du sofort exakte Koordinaten für deine Adresse - viel genauer als die automatische IP-Standortbestimmung, die leicht 20-30 km danebenliegen kann. Mit dem exakten Standort als Preset blinkt die Näherungs-LED wirklich im Takt mit dem Flugzeug, das du gerade über dir hörst.", }; static_assert(sizeof(I18N_DE) / sizeof(I18N_DE[0]) == (size_t)StringId::COUNT, diff --git a/src/i18n_en.h b/src/i18n_en.h index 12149e2..dace06a 100644 --- a/src/i18n_en.h +++ b/src/i18n_en.h @@ -217,9 +217,11 @@ static const char* const I18N_EN[] = { "Try again", "Cancel", "Set Your Exact Location", - "Automatic IP-based location can easily be 20-30 km off - you might hear a plane overhead while the radar stays empty. Enter your address now for exact coordinates and a much better experience. The proximity LED will then really blink in sync with the aircraft above you. You can also do this later anytime via Menu > Flight Options > Location Presets.", + "Automatic IP-based location can be 20-30 km off. Enter your address for exact coordinates - the proximity LED will then really blink in sync with the aircraft above you. You can do this later anytime via Location Presets.", "Enter Address", "Skip", + + "Tip: use the \"Search by address\" button when adding a preset (\"+\") to get exact coordinates for your address instantly - much more accurate than automatic IP-based location, which can easily be 20-30 km off. With your exact location set, the proximity LED really does blink in sync with the aircraft you can hear overhead.", }; static_assert(sizeof(I18N_EN) / sizeof(I18N_EN[0]) == (size_t)StringId::COUNT, diff --git a/src/i18n_es.h b/src/i18n_es.h index c9de7e1..44f51ad 100644 --- a/src/i18n_es.h +++ b/src/i18n_es.h @@ -216,9 +216,11 @@ static const char* const I18N_ES[] = { "Intentar de nuevo", "Cancelar", "Configura tu ubicación exacta", - "La geolocalización automática por IP puede fallar fácilmente por 20-30 km - podrías oír un avión mientras el radar permanece vacío. Introduce tu dirección ahora para obtener coordenadas exactas y una experiencia mucho mejor. El LED de proximidad parpadeará entonces realmente al ritmo del avión que tienes encima. También puedes hacerlo más tarde en cualquier momento desde Menú > Opciones de vuelo > Ubicaciones guardadas.", + "La geolocalización por IP puede fallar por 20-30 km. Introduce tu dirección para coordenadas exactas - el LED de proximidad parpadeará al ritmo del avión que tienes encima. Puedes hacerlo después desde Ubicaciones guardadas.", "Introducir dirección", "Omitir", + + "Consejo: usa el botón \"Buscar por dirección\" al añadir un preset (\"+\") para obtener al instante coordenadas exactas de tu dirección - mucho más preciso que la geolocalización automática por IP, que puede fallar fácilmente por 20-30 km. Con tu ubicación exacta configurada, el LED de proximidad realmente parpadea al ritmo del avión que oyes encima de ti.", }; static_assert(sizeof(I18N_ES) / sizeof(I18N_ES[0]) == (size_t)StringId::COUNT, diff --git a/src/i18n_fr.h b/src/i18n_fr.h index f4065b4..b49d362 100644 --- a/src/i18n_fr.h +++ b/src/i18n_fr.h @@ -216,9 +216,11 @@ static const char* const I18N_FR[] = { "Réessayer", "Annuler", "Définissez votre position exacte", - "La localisation automatique par IP peut facilement se tromper de 20 à 30 km - vous pourriez entendre un avion alors que le radar reste vide. Entrez votre adresse maintenant pour des coordonnées exactes et une bien meilleure expérience. La LED de proximité clignotera alors vraiment en rythme avec l'avion au-dessus de vous. Vous pouvez aussi le faire plus tard via Menu > Options de vol > Positions enregistrées.", + "La localisation automatique par IP peut se tromper de 20 à 30 km. Entrez votre adresse pour des coordonnées exactes - la LED de proximité clignotera alors vraiment en rythme avec l'avion au-dessus de vous. Possible plus tard via Positions enregistrées.", "Entrer l'adresse", "Passer", + + "Astuce : utilisez le bouton \"Rechercher par adresse\" lors de l'ajout d'un preset (\"+\") pour obtenir instantanément des coordonnées exactes pour votre adresse - bien plus précis que la localisation automatique par IP, qui peut facilement se tromper de 20 à 30 km. Avec votre position exacte enregistrée, la LED de proximité clignote vraiment en rythme avec l'avion que vous entendez au-dessus de vous.", }; static_assert(sizeof(I18N_FR) / sizeof(I18N_FR[0]) == (size_t)StringId::COUNT, diff --git a/src/i18n_it.h b/src/i18n_it.h index 37011af..6340695 100644 --- a/src/i18n_it.h +++ b/src/i18n_it.h @@ -216,9 +216,11 @@ static const char* const I18N_IT[] = { "Riprova", "Annulla", "Imposta la tua posizione esatta", - "La geolocalizzazione IP automatica può sbagliare facilmente di 20-30 km - potresti sentire un aereo mentre il radar resta vuoto. Inserisci ora il tuo indirizzo per coordinate esatte e un'esperienza molto migliore. Il LED di prossimità lampeggerà allora davvero al ritmo dell'aereo sopra di te. Puoi farlo anche più tardi in qualsiasi momento tramite Menu > Opzioni di volo > Posizioni salvate.", + "La geolocalizzazione IP può sbagliare di 20-30 km. Inserisci il tuo indirizzo per coordinate esatte - il LED di prossimità lampeggerà al ritmo dell'aereo sopra di te. Puoi farlo anche più tardi da Posizioni salvate.", "Inserisci indirizzo", "Salta", + + "Suggerimento: usa il pulsante \"Cerca per indirizzo\" quando aggiungi un preset (\"+\") per ottenere subito coordinate esatte per il tuo indirizzo - molto più preciso della geolocalizzazione IP automatica, che può sbagliare facilmente di 20-30 km. Con la tua posizione esatta impostata, il LED di prossimità lampeggia davvero al ritmo dell'aereo che senti sopra di te.", }; static_assert(sizeof(I18N_IT) / sizeof(I18N_IT[0]) == (size_t)StringId::COUNT, diff --git a/src/i18n_tr.h b/src/i18n_tr.h index 8394e0a..c18ff51 100644 --- a/src/i18n_tr.h +++ b/src/i18n_tr.h @@ -216,9 +216,11 @@ static const char* const I18N_TR[] = { "Tekrar dene", "İptal", "Tam Konumunuzu Ayarlayın", - "Otomatik IP tabanlı konum belirleme kolayca 20-30 km sapabilir - üstünüzden geçen bir uçağı duyarken radar boş kalabilir. Tam koordinatlar ve çok daha iyi bir deneyim için şimdi adresinizi girin. Yakınlık LED'i o zaman gerçekten üstünüzdeki uçakla aynı ritimde yanıp söner. Bunu daha sonra istediğiniz zaman Menü > Uçuş Seçenekleri > Konum ön ayarları üzerinden de yapabilirsiniz.", + "Otomatik IP konumu 20-30 km sapabilir. Tam koordinatlar için adresinizi girin - yakınlık LED'i o zaman gerçekten üstünüzdeki uçakla aynı ritimde yanıp söner. Daha sonra Konum ön ayarları üzerinden de yapılabilir.", "Adres Gir", "Atla", + + "İpucu: bir ön ayar eklerken (\"+\") \"Adresle ara\" düğmesini kullanarak adresiniz için anında tam koordinatlar elde edin - otomatik IP tabanlı konum belirlemeden çok daha doğru, o kolayca 20-30 km sapabilir. Tam konumunuz ayarlandığında, yakınlık LED'i üstünüzden duyduğunuz uçakla gerçekten aynı ritimde yanıp söner.", }; static_assert(sizeof(I18N_TR) / sizeof(I18N_TR[0]) == (size_t)StringId::COUNT, diff --git a/src/location_presets_screen.cpp b/src/location_presets_screen.cpp index 71f847b..b0c3441 100644 --- a/src/location_presets_screen.cpp +++ b/src/location_presets_screen.cpp @@ -434,6 +434,8 @@ namespace { totalH = layoutWrapped(tft, 10, totalH, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA4), 0, 0, 0, false); totalH += 8; totalH = layoutWrapped(tft, 10, totalH, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA5), 0, 0, 0, false); + totalH += 8; + totalH = layoutWrapped(tft, 10, totalH, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA6), 0, 0, 0, false); int16_t maxScroll = totalH - VIEW_BOTTOM; if (maxScroll < 0) maxScroll = 0; @@ -463,7 +465,9 @@ namespace { y += 8; y = layoutWrapped(tft, 10, y, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA4), scrollY, VIEW_TOP, VIEW_BOTTOM, true); y += 8; - layoutWrapped(tft, 10, y, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA5), scrollY, VIEW_TOP, VIEW_BOTTOM, true); + y = layoutWrapped(tft, 10, y, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA5), scrollY, VIEW_TOP, VIEW_BOTTOM, true); + y += 8; + layoutWrapped(tft, 10, y, textMaxWidth, LINE_H, I18n::t(StringId::LOCATION_INFO_PARA6), scrollY, VIEW_TOP, VIEW_BOTTOM, true); drawButton(tft, backBtn, I18n::t(StringId::BACK)); if (scrollable) {