v2.2: Custom Unicode font for accented characters (DE/TR/FR/ES/IT), 4-category menu reorganization, black/green UI theme, header layout improvements
This commit is contained in:
@@ -23,20 +23,33 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr int16_t ROW_H = 26;
|
||||
constexpr int16_t ROW_GAP = 3;
|
||||
constexpr int16_t ROW_START_Y = 20;
|
||||
constexpr int16_t ROW_H = 24;
|
||||
constexpr int16_t ROW_GAP = 2;
|
||||
constexpr int16_t ROW_START_Y = 18;
|
||||
|
||||
Rect rowRect(uint8_t index) {
|
||||
return {10, (int16_t)(ROW_START_Y + index * (ROW_H + ROW_GAP)),
|
||||
(int16_t)(Config::SCREEN_WIDTH - 20), ROW_H};
|
||||
}
|
||||
|
||||
void drawButton(TFT_eSPI& tft, const Rect& r, const String& label, uint16_t bg = TFT_NAVY) {
|
||||
constexpr int16_t CAT_ROW_H = 50;
|
||||
constexpr int16_t CAT_ROW_GAP = 10;
|
||||
constexpr int16_t CAT_START_Y = 30;
|
||||
|
||||
Rect catRowRect(uint8_t index) {
|
||||
return {10, (int16_t)(CAT_START_Y + index * (CAT_ROW_H + CAT_ROW_GAP)),
|
||||
(int16_t)(Config::SCREEN_WIDTH - 20), CAT_ROW_H};
|
||||
}
|
||||
|
||||
void drawButton(TFT_eSPI& tft, const Rect& r, const String& label,
|
||||
bool active = false, bool danger = false) {
|
||||
uint16_t accent = danger ? TFT_RED : TFT_GREEN;
|
||||
uint16_t bg = active ? accent : TFT_BLACK;
|
||||
uint16_t fg = active ? TFT_BLACK : accent;
|
||||
tft.fillRoundRect(r.x, r.y, r.w, r.h, 4, bg);
|
||||
tft.drawRoundRect(r.x, r.y, r.w, r.h, 4, TFT_DARKGREY);
|
||||
tft.drawRoundRect(r.x, r.y, r.w, r.h, 4, accent);
|
||||
tft.setTextDatum(MC_DATUM);
|
||||
tft.setTextColor(TFT_WHITE, bg);
|
||||
tft.setTextColor(fg, bg);
|
||||
tft.drawString(label, r.x + r.w / 2, r.y + r.h / 2);
|
||||
tft.setTextDatum(TL_DATUM);
|
||||
}
|
||||
@@ -57,28 +70,113 @@ namespace {
|
||||
tft.setTextDatum(TL_DATUM);
|
||||
delay(1200);
|
||||
}
|
||||
|
||||
enum class Page { Main, Region, Wifi, System, Flight };
|
||||
}
|
||||
|
||||
void run(TFT_eSPI& tft) {
|
||||
uint8_t page = 0;
|
||||
Page page = Page::Main;
|
||||
bool done = false;
|
||||
|
||||
while (!done) {
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
tft.setCursor(10, 2);
|
||||
tft.println(page == 0 ? I18n::t(StringId::MENU_SETTINGS) : I18n::t(StringId::MENU_SETTINGS_PAGE2));
|
||||
|
||||
if (page == 0) {
|
||||
Rect calibBtn = rowRect(0);
|
||||
Rect invertBtn = rowRect(1);
|
||||
Rect wifiBtn = rowRect(2);
|
||||
Rect locationBtn = rowRect(3);
|
||||
Rect timeoutBtn = rowRect(4);
|
||||
Rect statsBtn = rowRect(5);
|
||||
Rect logFilesBtn = rowRect(6);
|
||||
Rect moreBtn = rowRect(7);
|
||||
Rect backBtn = rowRect(8);
|
||||
if (page == Page::Main) {
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.setCursor(10, 6);
|
||||
tft.println(I18n::t(StringId::MENU_SETTINGS));
|
||||
|
||||
Rect regionBtn = catRowRect(0);
|
||||
Rect wifiBtn = catRowRect(1);
|
||||
Rect systemBtn = catRowRect(2);
|
||||
Rect flightBtn = catRowRect(3);
|
||||
Rect backBtn = catRowRect(4);
|
||||
|
||||
drawButton(tft, regionBtn, I18n::t(StringId::MENU_CATEGORY_REGION));
|
||||
drawButton(tft, wifiBtn, I18n::t(StringId::MENU_CATEGORY_WIFI));
|
||||
drawButton(tft, systemBtn, I18n::t(StringId::MENU_CATEGORY_SYSTEM));
|
||||
drawButton(tft, flightBtn, I18n::t(StringId::MENU_CATEGORY_FLIGHT));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (regionBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Region;
|
||||
} else if (wifiBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Wifi;
|
||||
} else if (systemBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::System;
|
||||
} else if (flightBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Flight;
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
done = true;
|
||||
}
|
||||
|
||||
} else if (page == Page::Region) {
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.setCursor(10, 2);
|
||||
tft.println(I18n::t(StringId::MENU_CATEGORY_REGION));
|
||||
|
||||
Rect languageBtn = rowRect(0);
|
||||
Rect unitsBtn = rowRect(1);
|
||||
Rect backBtn = rowRect(2);
|
||||
|
||||
drawButton(tft, languageBtn, String(I18n::t(StringId::MENU_LANGUAGE)) + ": " + I18n::languageName(SettingsStore::language()));
|
||||
drawButton(tft, unitsBtn, I18n::t(StringId::MENU_UNITS));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (languageBtn.contains(tap.x, tap.y)) {
|
||||
LanguageScreen::run(tft);
|
||||
} else if (unitsBtn.contains(tap.x, tap.y)) {
|
||||
UnitsScreen::run(tft);
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Main;
|
||||
}
|
||||
|
||||
} else if (page == Page::Wifi) {
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.setCursor(10, 2);
|
||||
tft.println(I18n::t(StringId::MENU_CATEGORY_WIFI));
|
||||
|
||||
Rect wifiManageBtn = rowRect(0);
|
||||
Rect backBtn = rowRect(1);
|
||||
|
||||
drawButton(tft, wifiManageBtn, I18n::t(StringId::MENU_MANAGE_WIFI));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (wifiManageBtn.contains(tap.x, tap.y)) {
|
||||
WifiManageScreen::run(tft);
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Main;
|
||||
}
|
||||
|
||||
} else if (page == Page::System) {
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.setCursor(10, 2);
|
||||
tft.println(I18n::t(StringId::MENU_CATEGORY_SYSTEM));
|
||||
|
||||
Rect calibBtn = rowRect(0);
|
||||
Rect invertBtn = rowRect(1);
|
||||
Rect timeoutBtn = rowRect(2);
|
||||
Rect backupBtn = rowRect(3);
|
||||
Rect restoreBtn = rowRect(4);
|
||||
Rect backBtn = rowRect(5);
|
||||
|
||||
drawButton(tft, calibBtn, I18n::t(StringId::MENU_CALIBRATE));
|
||||
|
||||
@@ -87,13 +185,10 @@ void run(TFT_eSPI& tft) {
|
||||
: I18n::t(StringId::MENU_DISPLAY_NORMAL);
|
||||
drawButton(tft, invertBtn, invertLabel);
|
||||
|
||||
drawButton(tft, wifiBtn, I18n::t(StringId::MENU_MANAGE_WIFI));
|
||||
drawButton(tft, locationBtn, I18n::t(StringId::MENU_LOCATION_PRESETS));
|
||||
drawButton(tft, timeoutBtn, screenTimeoutLabel(SettingsStore::screenTimeoutMinutes()));
|
||||
drawButton(tft, statsBtn, I18n::t(StringId::MENU_STATISTICS));
|
||||
drawButton(tft, logFilesBtn, I18n::t(StringId::MENU_LOGBOOK_FILES));
|
||||
drawButton(tft, moreBtn, I18n::t(StringId::MENU_MORE_SETTINGS));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK));
|
||||
drawButton(tft, backupBtn, I18n::t(StringId::MENU_BACKUP));
|
||||
drawButton(tft, restoreBtn, I18n::t(StringId::MENU_RESTORE));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
@@ -107,89 +202,10 @@ void run(TFT_eSPI& tft) {
|
||||
bool newState = !SettingsStore::displayInverted();
|
||||
SettingsStore::setDisplayInverted(newState);
|
||||
tft.invertDisplay(newState);
|
||||
} else if (wifiBtn.contains(tap.x, tap.y)) {
|
||||
WifiManageScreen::run(tft);
|
||||
} else if (locationBtn.contains(tap.x, tap.y)) {
|
||||
LocationPresetsScreen::run(tft);
|
||||
} else if (timeoutBtn.contains(tap.x, tap.y)) {
|
||||
uint8_t current = SettingsStore::screenTimeoutMinutes();
|
||||
uint8_t next = (current >= 10) ? 0 : (current + 1);
|
||||
SettingsStore::setScreenTimeoutMinutes(next);
|
||||
} else if (statsBtn.contains(tap.x, tap.y)) {
|
||||
StatsScreen::run(tft);
|
||||
} else if (logFilesBtn.contains(tap.x, tap.y)) {
|
||||
LogbookFilesScreen::run(tft);
|
||||
} else if (moreBtn.contains(tap.x, tap.y)) {
|
||||
page = 1;
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
done = true;
|
||||
}
|
||||
} else if (page == 1) {
|
||||
Rect emergencyBtn = rowRect(0);
|
||||
Rect proximityBtn = rowRect(1);
|
||||
Rect heartbeatBtn = rowRect(2);
|
||||
Rect logbookBtn = rowRect(3);
|
||||
Rect groundBtn = rowRect(4);
|
||||
Rect airlineBtn = rowRect(5);
|
||||
Rect moreBtn = rowRect(6);
|
||||
Rect backBtn = rowRect(7);
|
||||
|
||||
drawButton(tft, emergencyBtn, I18n::t(StringId::MENU_EMERGENCY_ALERT) + onOff(SettingsStore::emergencyAlertEnabled()));
|
||||
drawButton(tft, proximityBtn, I18n::t(StringId::MENU_PROXIMITY_LED) + onOff(SettingsStore::proximityAlertEnabled()));
|
||||
drawButton(tft, heartbeatBtn, I18n::t(StringId::MENU_LED_HEARTBEAT) + onOff(SettingsStore::ledHeartbeatEnabled()));
|
||||
drawButton(tft, logbookBtn, I18n::t(StringId::MENU_FLIGHT_LOGBOOK) + onOff(SettingsStore::flightLogbookEnabled()));
|
||||
drawButton(tft, groundBtn, I18n::t(StringId::MENU_HIDE_GROUND) + onOff(SettingsStore::hideGroundVehicles()));
|
||||
drawButton(tft, airlineBtn, I18n::t(StringId::MENU_AIRLINE_FILTER));
|
||||
drawButton(tft, moreBtn, I18n::t(StringId::MENU_MORE_SETTINGS));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (emergencyBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setEmergencyAlertEnabled(!SettingsStore::emergencyAlertEnabled());
|
||||
} else if (proximityBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setProximityAlertEnabled(!SettingsStore::proximityAlertEnabled());
|
||||
} else if (heartbeatBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setLedHeartbeatEnabled(!SettingsStore::ledHeartbeatEnabled());
|
||||
} else if (logbookBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setFlightLogbookEnabled(!SettingsStore::flightLogbookEnabled());
|
||||
} else if (groundBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setHideGroundVehicles(!SettingsStore::hideGroundVehicles());
|
||||
} else if (airlineBtn.contains(tap.x, tap.y)) {
|
||||
AirlineFilterScreen::run(tft);
|
||||
} else if (moreBtn.contains(tap.x, tap.y)) {
|
||||
page = 2;
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
page = 0;
|
||||
}
|
||||
} else {
|
||||
Rect languageBtn = rowRect(0);
|
||||
Rect unitsBtn = rowRect(1);
|
||||
Rect backupBtn = rowRect(2);
|
||||
Rect restoreBtn = rowRect(3);
|
||||
Rect backBtn = rowRect(4);
|
||||
|
||||
drawButton(tft, languageBtn, String(I18n::t(StringId::MENU_LANGUAGE)) + ": " + I18n::languageName(SettingsStore::language()));
|
||||
drawButton(tft, unitsBtn, I18n::t(StringId::MENU_UNITS));
|
||||
drawButton(tft, backupBtn, I18n::t(StringId::MENU_BACKUP));
|
||||
drawButton(tft, restoreBtn, I18n::t(StringId::MENU_RESTORE),
|
||||
SettingsBackup::hasBackup() ? TFT_NAVY : TFT_DARKGREY);
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (languageBtn.contains(tap.x, tap.y)) {
|
||||
LanguageScreen::run(tft);
|
||||
} else if (unitsBtn.contains(tap.x, tap.y)) {
|
||||
UnitsScreen::run(tft);
|
||||
} else if (backupBtn.contains(tap.x, tap.y)) {
|
||||
bool ok = SettingsBackup::backup();
|
||||
showBriefMessage(tft, I18n::t(ok ? StringId::MENU_BACKUP_SAVED : StringId::MENU_BACKUP_FAILED),
|
||||
@@ -201,7 +217,62 @@ void run(TFT_eSPI& tft) {
|
||||
ok ? TFT_GREEN : TFT_RED);
|
||||
}
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
page = 1;
|
||||
page = Page::Main;
|
||||
}
|
||||
|
||||
} else { // Page::Flight
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.setCursor(10, 2);
|
||||
tft.println(I18n::t(StringId::MENU_CATEGORY_FLIGHT));
|
||||
|
||||
Rect statsBtn = rowRect(0);
|
||||
Rect logFilesBtn = rowRect(1);
|
||||
Rect logbookBtn = rowRect(2);
|
||||
Rect heartbeatBtn = rowRect(3);
|
||||
Rect proximityBtn = rowRect(4);
|
||||
Rect emergencyBtn = rowRect(5);
|
||||
Rect locationBtn = rowRect(6);
|
||||
Rect airlineBtn = rowRect(7);
|
||||
Rect groundBtn = rowRect(8);
|
||||
Rect backBtn = rowRect(9);
|
||||
|
||||
drawButton(tft, statsBtn, I18n::t(StringId::MENU_STATISTICS));
|
||||
drawButton(tft, logFilesBtn, I18n::t(StringId::MENU_LOGBOOK_FILES));
|
||||
drawButton(tft, logbookBtn, I18n::t(StringId::MENU_FLIGHT_LOGBOOK) + onOff(SettingsStore::flightLogbookEnabled()));
|
||||
drawButton(tft, heartbeatBtn, I18n::t(StringId::MENU_LED_HEARTBEAT) + onOff(SettingsStore::ledHeartbeatEnabled()));
|
||||
drawButton(tft, proximityBtn, I18n::t(StringId::MENU_PROXIMITY_LED) + onOff(SettingsStore::proximityAlertEnabled()));
|
||||
drawButton(tft, emergencyBtn, I18n::t(StringId::MENU_EMERGENCY_ALERT) + onOff(SettingsStore::emergencyAlertEnabled()));
|
||||
drawButton(tft, locationBtn, I18n::t(StringId::MENU_LOCATION_PRESETS));
|
||||
drawButton(tft, airlineBtn, I18n::t(StringId::MENU_AIRLINE_FILTER));
|
||||
drawButton(tft, groundBtn, I18n::t(StringId::MENU_HIDE_GROUND) + onOff(SettingsStore::hideGroundVehicles()));
|
||||
drawButton(tft, backBtn, I18n::t(StringId::BACK_ARROW));
|
||||
|
||||
TouchInput::Point tap;
|
||||
while (true) {
|
||||
if (TouchInput::wasTapped(tap)) break;
|
||||
delay(20);
|
||||
}
|
||||
|
||||
if (statsBtn.contains(tap.x, tap.y)) {
|
||||
StatsScreen::run(tft);
|
||||
} else if (logFilesBtn.contains(tap.x, tap.y)) {
|
||||
LogbookFilesScreen::run(tft);
|
||||
} else if (logbookBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setFlightLogbookEnabled(!SettingsStore::flightLogbookEnabled());
|
||||
} else if (heartbeatBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setLedHeartbeatEnabled(!SettingsStore::ledHeartbeatEnabled());
|
||||
} else if (proximityBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setProximityAlertEnabled(!SettingsStore::proximityAlertEnabled());
|
||||
} else if (emergencyBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setEmergencyAlertEnabled(!SettingsStore::emergencyAlertEnabled());
|
||||
} else if (locationBtn.contains(tap.x, tap.y)) {
|
||||
LocationPresetsScreen::run(tft);
|
||||
} else if (airlineBtn.contains(tap.x, tap.y)) {
|
||||
AirlineFilterScreen::run(tft);
|
||||
} else if (groundBtn.contains(tap.x, tap.y)) {
|
||||
SettingsStore::setHideGroundVehicles(!SettingsStore::hideGroundVehicles());
|
||||
} else if (backBtn.contains(tap.x, tap.y)) {
|
||||
page = Page::Main;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user