From 9d13f7a859b2c04eac98116f76d5ad22cc27d283 Mon Sep 17 00:00:00 2001 From: JustScott Date: Mon, 3 Feb 2025 12:06:58 -0600 Subject: [PATCH 1/4] Add time since last weather update to weather app --- src/displayapp/screens/Weather.cpp | 23 +++++++++++++++++++++-- src/displayapp/screens/Weather.h | 9 +++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 25464c70cf..ceb0892c39 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -35,8 +35,10 @@ namespace { } } -Weather::Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) - : settingsController {settingsController}, weatherService {weatherService} { +Weather::Weather(Controllers::Settings& settingsController, + Controllers::SimpleWeatherService& weatherService, + Controllers::DateTime& dateTimeController) + : settingsController {settingsController}, weatherService {weatherService}, dateTimeController {dateTimeController} { temperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); @@ -45,6 +47,11 @@ Weather::Weather(Controllers::Settings& settingsController, Controllers::SimpleW lv_obj_align(temperature, nullptr, LV_ALIGN_CENTER, 0, -30); lv_obj_set_auto_realign(temperature, true); + lastUpdated = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(lastUpdated, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); + lv_label_set_text_fmt(lastUpdated, ""); + lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -40, 0); + minTemperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(minTemperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); lv_label_set_text(minTemperature, ""); @@ -137,6 +144,18 @@ void Weather::Refresh() { lv_label_set_text_fmt(temperature, "%d°%c", temp, tempUnit); lv_label_set_text_fmt(minTemperature, "%d°", minTemp); lv_label_set_text_fmt(maxTemperature, "%d°", maxTemp); + + int64_t secondsSinceEpoch = dateTimeController.CurrentDateTime().time_since_epoch().count() / 1000000000; + int64_t secondsSinceWeatherUpdate = secondsSinceEpoch - optCurrentWeather->timestamp; + if (secondsSinceWeatherUpdate < 0) { + lv_label_set_text_fmt(lastUpdated, "0s old", secondsSinceWeatherUpdate); + } else if (secondsSinceWeatherUpdate < 60) { + lv_label_set_text_fmt(lastUpdated, "%ds old", secondsSinceWeatherUpdate); + } else if (secondsSinceWeatherUpdate > 59 && secondsSinceWeatherUpdate < 3600) { + lv_label_set_text_fmt(lastUpdated, "%dm old", secondsSinceWeatherUpdate / 60); + } else if (secondsSinceWeatherUpdate > 3599) { + lv_label_set_text_fmt(lastUpdated, "%dh old", secondsSinceWeatherUpdate / 3600); + } } else { lv_label_set_text(icon, ""); lv_label_set_text(condition, ""); diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 6975311e06..2d41555bbc 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -4,6 +4,7 @@ #include #include "displayapp/screens/Screen.h" #include "components/ble/SimpleWeatherService.h" +#include "components/datetime/DateTimeController.h" #include "displayapp/apps/Apps.h" #include "displayapp/Controllers.h" #include "Symbols.h" @@ -20,7 +21,9 @@ namespace Pinetime { class Weather : public Screen { public: - Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService); + Weather(Controllers::Settings& settingsController, + Controllers::SimpleWeatherService& weatherService, + Controllers::DateTime& dateTimeController); ~Weather() override; void Refresh() override; @@ -28,6 +31,7 @@ namespace Pinetime { private: Controllers::Settings& settingsController; Controllers::SimpleWeatherService& weatherService; + Controllers::DateTime& dateTimeController; Utility::DirtyValue> currentWeather {}; Utility::DirtyValue> currentForecast {}; @@ -35,6 +39,7 @@ namespace Pinetime { lv_obj_t* icon; lv_obj_t* condition; lv_obj_t* temperature; + lv_obj_t* lastUpdated; lv_obj_t* minTemperature; lv_obj_t* maxTemperature; lv_obj_t* forecast; @@ -49,7 +54,7 @@ namespace Pinetime { static constexpr const char* icon = Screens::Symbols::cloudSunRain; static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::Weather(controllers.settingsController, *controllers.weatherController); + return new Screens::Weather(controllers.settingsController, *controllers.weatherController, controllers.dateTimeController); }; }; } From b542e26c269355d74ded5a5d151e91281e97d714 Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 4 Feb 2025 22:48:27 -0600 Subject: [PATCH 2/4] Replace 'old' with 'ago' and adjust positioning --- src/displayapp/screens/Weather.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index ceb0892c39..055b3b07f7 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -44,13 +44,13 @@ Weather::Weather(Controllers::Settings& settingsController, lv_obj_set_style_local_text_color(temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_obj_set_style_local_text_font(temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text(temperature, "---"); - lv_obj_align(temperature, nullptr, LV_ALIGN_CENTER, 0, -30); + lv_obj_align(temperature, nullptr, LV_ALIGN_CENTER, 0, -32); lv_obj_set_auto_realign(temperature, true); lastUpdated = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(lastUpdated, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); lv_label_set_text_fmt(lastUpdated, ""); - lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -40, 0); + lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -40, -1); minTemperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(minTemperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); @@ -148,13 +148,13 @@ void Weather::Refresh() { int64_t secondsSinceEpoch = dateTimeController.CurrentDateTime().time_since_epoch().count() / 1000000000; int64_t secondsSinceWeatherUpdate = secondsSinceEpoch - optCurrentWeather->timestamp; if (secondsSinceWeatherUpdate < 0) { - lv_label_set_text_fmt(lastUpdated, "0s old", secondsSinceWeatherUpdate); + lv_label_set_text_fmt(lastUpdated, "0s ago", secondsSinceWeatherUpdate); } else if (secondsSinceWeatherUpdate < 60) { - lv_label_set_text_fmt(lastUpdated, "%ds old", secondsSinceWeatherUpdate); + lv_label_set_text_fmt(lastUpdated, "%ds ago", secondsSinceWeatherUpdate); } else if (secondsSinceWeatherUpdate > 59 && secondsSinceWeatherUpdate < 3600) { - lv_label_set_text_fmt(lastUpdated, "%dm old", secondsSinceWeatherUpdate / 60); + lv_label_set_text_fmt(lastUpdated, "%dm ago", secondsSinceWeatherUpdate / 60); } else if (secondsSinceWeatherUpdate > 3599) { - lv_label_set_text_fmt(lastUpdated, "%dh old", secondsSinceWeatherUpdate / 3600); + lv_label_set_text_fmt(lastUpdated, "%dh ago", secondsSinceWeatherUpdate / 3600); } } else { lv_label_set_text(icon, ""); From 6cd398826b407136b4a79bd99fc8bd93c66f009d Mon Sep 17 00:00:00 2001 From: JustScott Date: Fri, 7 Feb 2025 04:38:50 -0600 Subject: [PATCH 3/4] Updated labels, improved/simplified logic, and improved positioning Use "Now" for the label until 31 seconds, then display the live time. --- src/displayapp/screens/Weather.cpp | 31 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 055b3b07f7..29ce2f28dc 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -50,7 +50,6 @@ Weather::Weather(Controllers::Settings& settingsController, lastUpdated = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(lastUpdated, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); lv_label_set_text_fmt(lastUpdated, ""); - lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -40, -1); minTemperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(minTemperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); @@ -145,21 +144,33 @@ void Weather::Refresh() { lv_label_set_text_fmt(minTemperature, "%d°", minTemp); lv_label_set_text_fmt(maxTemperature, "%d°", maxTemp); - int64_t secondsSinceEpoch = dateTimeController.CurrentDateTime().time_since_epoch().count() / 1000000000; - int64_t secondsSinceWeatherUpdate = secondsSinceEpoch - optCurrentWeather->timestamp; - if (secondsSinceWeatherUpdate < 0) { - lv_label_set_text_fmt(lastUpdated, "0s ago", secondsSinceWeatherUpdate); - } else if (secondsSinceWeatherUpdate < 60) { + std::chrono::seconds secondsSinceEpoch = + std::chrono::duration_cast(dateTimeController.CurrentDateTime().time_since_epoch()); + int32_t secondsSinceWeatherUpdate = secondsSinceEpoch.count() - optCurrentWeather->timestamp; + int8_t minutesSinceWeatherUpdate = secondsSinceWeatherUpdate / 60; + int8_t hoursSinceWeatherUpdate = secondsSinceWeatherUpdate / 3600; + + lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -31, -1); + if ((secondsSinceWeatherUpdate > 9 && secondsSinceWeatherUpdate < 60) || + (minutesSinceWeatherUpdate > 9 && minutesSinceWeatherUpdate < 60) || hoursSinceWeatherUpdate > 9) { + lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -41, -1); + } + + if (hoursSinceWeatherUpdate > 0) { + lv_label_set_text_fmt(lastUpdated, "%dh ago", hoursSinceWeatherUpdate); + } else if (minutesSinceWeatherUpdate > 0) { + lv_label_set_text_fmt(lastUpdated, "%dm ago", minutesSinceWeatherUpdate); + } else if (secondsSinceWeatherUpdate > 30) { lv_label_set_text_fmt(lastUpdated, "%ds ago", secondsSinceWeatherUpdate); - } else if (secondsSinceWeatherUpdate > 59 && secondsSinceWeatherUpdate < 3600) { - lv_label_set_text_fmt(lastUpdated, "%dm ago", secondsSinceWeatherUpdate / 60); - } else if (secondsSinceWeatherUpdate > 3599) { - lv_label_set_text_fmt(lastUpdated, "%dh ago", secondsSinceWeatherUpdate / 3600); + } else if (secondsSinceWeatherUpdate < 31) { + lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -18, -1); + lv_label_set_text_fmt(lastUpdated, "Now", secondsSinceWeatherUpdate); } } else { lv_label_set_text(icon, ""); lv_label_set_text(condition, ""); lv_label_set_text(temperature, "---"); + lv_label_set_text(lastUpdated, ""); lv_obj_set_style_local_text_color(temperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_label_set_text(minTemperature, ""); lv_label_set_text(maxTemperature, ""); From cb4e7d655b5fd867074755f82bc7f481acfffad4 Mon Sep 17 00:00:00 2001 From: JustScott Date: Sat, 8 Feb 2025 12:13:59 -0600 Subject: [PATCH 4/4] Fixed positioning Move from `lv_obj_align` to `lv_obj_set_pos` to avoid weird positioning errors when changing the position more than once. --- src/displayapp/screens/Weather.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 29ce2f28dc..c8debd81f0 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -49,7 +49,7 @@ Weather::Weather(Controllers::Settings& settingsController, lastUpdated = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(lastUpdated, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); - lv_label_set_text_fmt(lastUpdated, ""); + lv_label_set_text(lastUpdated, ""); minTemperature = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(minTemperature, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::bg); @@ -150,20 +150,30 @@ void Weather::Refresh() { int8_t minutesSinceWeatherUpdate = secondsSinceWeatherUpdate / 60; int8_t hoursSinceWeatherUpdate = secondsSinceWeatherUpdate / 3600; - lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -31, -1); - if ((secondsSinceWeatherUpdate > 9 && secondsSinceWeatherUpdate < 60) || - (minutesSinceWeatherUpdate > 9 && minutesSinceWeatherUpdate < 60) || hoursSinceWeatherUpdate > 9) { - lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -41, -1); - } + constexpr uint8_t Y_POSITION = 108; + constexpr uint8_t X_SINGLE_DIGIT_POSITION = 90; + constexpr uint8_t X_TWO_DIGIT_POSITION = 78; + constexpr uint8_t X_NOW_POSITION = 102; + + lv_obj_set_pos(lastUpdated, X_SINGLE_DIGIT_POSITION, Y_POSITION); if (hoursSinceWeatherUpdate > 0) { + if (hoursSinceWeatherUpdate > 9) { + lv_obj_set_pos(lastUpdated, X_TWO_DIGIT_POSITION, Y_POSITION); + } lv_label_set_text_fmt(lastUpdated, "%dh ago", hoursSinceWeatherUpdate); } else if (minutesSinceWeatherUpdate > 0) { + if (minutesSinceWeatherUpdate > 9 && minutesSinceWeatherUpdate < 60) { + lv_obj_set_pos(lastUpdated, X_TWO_DIGIT_POSITION, Y_POSITION); + } lv_label_set_text_fmt(lastUpdated, "%dm ago", minutesSinceWeatherUpdate); } else if (secondsSinceWeatherUpdate > 30) { + if (secondsSinceWeatherUpdate > 9 && secondsSinceWeatherUpdate < 60) { + lv_obj_set_pos(lastUpdated, X_TWO_DIGIT_POSITION, Y_POSITION); + } lv_label_set_text_fmt(lastUpdated, "%ds ago", secondsSinceWeatherUpdate); } else if (secondsSinceWeatherUpdate < 31) { - lv_obj_align(lastUpdated, nullptr, LV_ALIGN_CENTER, -18, -1); + lv_obj_set_pos(lastUpdated, X_NOW_POSITION, Y_POSITION); lv_label_set_text_fmt(lastUpdated, "Now", secondsSinceWeatherUpdate); } } else {