diff --git a/src/config.h b/src/config.h index 9a131f2..4fb42d3 100644 --- a/src/config.h +++ b/src/config.h @@ -46,10 +46,13 @@ namespace Config { constexpr uint8_t GPS_PIN_CANDIDATE_COUNT = 1; constexpr uint32_t GPS_BAUD = 9600; - constexpr float RANGE_STEPS_KM[] = {10.0f, 25.0f, 50.0f, 100.0f}; +constexpr float RANGE_STEPS_KM[] = {10.0f, 25.0f, 50.0f, 100.0f}; constexpr uint8_t RANGE_STEP_COUNT = 4; constexpr uint8_t DEFAULT_RANGE_INDEX = 1; + constexpr uint8_t ALT_FILTER_COUNT = 3; + constexpr uint8_t DEFAULT_ALT_FILTER_INDEX = 0; + constexpr const char* ADSB_API_HOST = "opendata.adsb.fi"; constexpr uint16_t ADSB_API_PORT = 443; constexpr uint32_t FETCH_INTERVAL_MS = 8000; diff --git a/src/radar_screen.cpp b/src/radar_screen.cpp index 4b92838..c77d0fc 100644 --- a/src/radar_screen.cpp +++ b/src/radar_screen.cpp @@ -31,9 +31,10 @@ namespace { }; struct Layout { - int16_t cx, cy, radius; +int16_t cx, cy, radius; Rect rangeBtn; Rect listBtn; + Rect altBtn; Rect searchBtn; Rect helpBtn; int16_t infoTop; @@ -60,9 +61,10 @@ Layout computeLayout(int16_t top) { L.radius = min(maxRadiusByWidth, maxRadiusByHeight); L.cx = Config::SCREEN_WIDTH / 2; L.cy = top + L.radius + 6 + TOP_LABEL_MARGIN; - L.rangeBtn = {(int16_t)(Config::SCREEN_WIDTH - 70), (int16_t)(L.infoTop + 4), 62, 22}; - L.listBtn = {(int16_t)(Config::SCREEN_WIDTH - 110), (int16_t)(L.infoTop + 4), 36, 22}; - L.searchBtn = {(int16_t)(Config::SCREEN_WIDTH - 150), (int16_t)(L.infoTop + 4), 36, 22}; +L.rangeBtn = {(int16_t)(Config::SCREEN_WIDTH - 72), (int16_t)(L.infoTop + 4), 64, 22}; + L.listBtn = {128, (int16_t)(L.infoTop + 4), 36, 22}; + L.altBtn = {88, (int16_t)(L.infoTop + 4), 36, 22}; + L.searchBtn = {48, (int16_t)(L.infoTop + 4), 36, 22}; L.helpBtn = {8, (int16_t)(L.infoTop + 4), 36, 22}; return L; } @@ -863,7 +865,11 @@ void render(TFT_eSPI& tft, int16_t top) { if (SettingsStore::hideGroundVehicles() && a.category[0] == 'C') continue; - if (AirlineFilter::isHidden(a.callsign)) continue; +if (AirlineFilter::isHidden(a.callsign)) continue; + + uint8_t altMode = SettingsStore::altFilterIndex(); + if (altMode == 1 && a.altBaroFt >= (int32_t)Config::COLOR_LOW_ALT_THRESHOLD_FT) continue; + if (altMode == 2 && a.altBaroFt < (int32_t)Config::COLOR_LOW_ALT_THRESHOLD_FT) continue; visibleCount++; @@ -944,14 +950,17 @@ lastPanel.valid = false; // Info-Bar Button-Leiste: [?] [S] [L] [50km] char rangeLabel[8]; bool rangeMetric = LocationManager::useMetricUnits(); - if (rangeMetric) { +if (rangeMetric) { snprintf(rangeLabel, sizeof(rangeLabel), "%.0fkm", rangeKm); } else { snprintf(rangeLabel, sizeof(rangeLabel), "%.0fnm", Units::kmToNm(rangeKm)); } + uint8_t altIdx = SettingsStore::altFilterIndex(); + const char* altLabels[] = {"All", "<10k", ">10k"}; drawButton(tft, L.helpBtn, "?"); drawButton(tft, L.searchBtn, "S"); drawButton(tft, L.listBtn, "L"); + drawButton(tft, L.altBtn, altLabels[altIdx]); drawButton(tft, L.rangeBtn, rangeLabel); drawLegend(tft, infoTop + 44); @@ -1100,11 +1109,17 @@ bool handleTap(TFT_eSPI& tft, int16_t x, int16_t y, int16_t top) { return true; } - if (L.listBtn.contains(x, y)) { +if (L.listBtn.contains(x, y)) { bool hadSelection = runTable(tft, top); return true; } + if (L.altBtn.contains(x, y)) { + uint8_t idx = (SettingsStore::altFilterIndex() + 1) % Config::ALT_FILTER_COUNT; + SettingsStore::setAltFilterIndex(idx); + return true; + } + if (L.rangeBtn.contains(x, y)) { uint8_t idx = (SettingsStore::rangeIndex() + 1) % Config::RANGE_STEP_COUNT; SettingsStore::setRangeIndex(idx); @@ -1173,7 +1188,12 @@ bool runTable(TFT_eSPI& tft, int16_t top) { if (!table[i].valid) continue; if (table[i].distanceKm > rangeKm * 1.05f) continue; if (SettingsStore::hideGroundVehicles() && table[i].category[0] == 'C') continue; - if (AirlineFilter::isHidden(table[i].callsign)) continue; +if (AirlineFilter::isHidden(table[i].callsign)) continue; + + uint8_t altMode = SettingsStore::altFilterIndex(); + if (altMode == 1 && table[i].altBaroFt >= (int32_t)Config::COLOR_LOW_ALT_THRESHOLD_FT) continue; + if (altMode == 2 && table[i].altBaroFt < (int32_t)Config::COLOR_LOW_ALT_THRESHOLD_FT) continue; + snapshot[count++] = table[i]; } AircraftTable::unlock(); diff --git a/src/settings_store.cpp b/src/settings_store.cpp index a33f22b..d15d7c3 100644 --- a/src/settings_store.cpp +++ b/src/settings_store.cpp @@ -8,6 +8,7 @@ namespace SettingsStore { namespace { uint8_t rangeIdx = Config::DEFAULT_RANGE_INDEX; + uint8_t altFilterIdx = Config::DEFAULT_ALT_FILTER_INDEX; bool inverted = true; // Dieses Board braucht invertDisplay(true) fuer korrekte Farben (siehe main.cpp) uint8_t brightnessPct = Config::BRIGHTNESS_MAX_PERCENT; bool emergencyAlertOn = true; @@ -28,11 +29,16 @@ namespace { uint8_t unitsModeVal = 0; void applyKeyValue(const String& key, const String& value) { - if (key == "range_index") { +if (key == "range_index") { int v = value.toInt(); if (v >= 0 && v < Config::RANGE_STEP_COUNT) { rangeIdx = (uint8_t)v; } + } else if (key == "alt_filter_index") { + int v = value.toInt(); + if (v >= 0 && v < Config::ALT_FILTER_COUNT) { + altFilterIdx = (uint8_t)v; + } } else if (key == "invert") { inverted = (value.toInt() != 0); } else if (key == "brightness_percent") { @@ -114,6 +120,7 @@ void save() { File f = SD.open(Config::SD_SETTINGS_FILE, FILE_WRITE); if (!f) return; f.printf("range_index=%d\n", rangeIdx); + f.printf("alt_filter_index=%d\n", altFilterIdx); f.printf("invert=%d\n", inverted ? 1 : 0); f.printf("brightness_percent=%d\n", brightnessPct); f.printf("emergency_alert=%d\n", emergencyAlertOn ? 1 : 0); @@ -141,6 +148,15 @@ void setRangeIndex(uint8_t idx) { } } +uint8_t altFilterIndex() { return altFilterIdx; } + +void setAltFilterIndex(uint8_t idx) { + if (idx < Config::ALT_FILTER_COUNT) { + altFilterIdx = idx; + save(); + } +} + bool displayInverted() { return inverted; } void setDisplayInverted(bool inv) { diff --git a/src/settings_store.h b/src/settings_store.h index 3a4fbf7..5b49682 100644 --- a/src/settings_store.h +++ b/src/settings_store.h @@ -5,9 +5,12 @@ namespace SettingsStore { void load(); void save(); - uint8_t rangeIndex(); +uint8_t rangeIndex(); void setRangeIndex(uint8_t idx); + uint8_t altFilterIndex(); + void setAltFilterIndex(uint8_t idx); + bool displayInverted(); void setDisplayInverted(bool inverted);