From ded49c09d18ed812ac2ce514b228c2e16092521a Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Sun, 30 Aug 2026 00:04:38 +0100 Subject: [PATCH 1/4] Digital Watchface click on weather and steps --- src/displayapp/DisplayApp.cpp | 6 ++++++ src/displayapp/screens/Steps.cpp | 6 ++++-- src/displayapp/screens/Steps.h | 5 +++-- src/displayapp/screens/WatchFaceDigital.cpp | 23 +++++++++++++++++++++ src/displayapp/screens/WatchFaceDigital.h | 3 +++ src/displayapp/screens/Weather.cpp | 6 ++++-- src/displayapp/screens/Weather.h | 5 +++-- 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 84fa603622..af179a001f 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -651,6 +651,12 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::FlashLight: currentScreen = std::make_unique(*systemTask, brightnessController); break; + case Apps::Weather: + currentScreen = std::make_unique(this, settingsController, *controllers.weatherController); + break; + case Apps::Steps: + currentScreen = std::make_unique(this, motionController, settingsController); + break; default: { const auto* d = std::ranges::find_if(userApps, [app](const AppDescription& appDescription) { return appDescription.app == app; diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index 2e73dab512..89c5ad9ba8 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -16,8 +16,10 @@ static void lap_event_handler(lv_obj_t* obj, lv_event_t event) { steps->lapBtnEventHandler(event); } -Steps::Steps(Controllers::MotionController& motionController, Controllers::Settings& settingsController) - : motionController {motionController}, settingsController {settingsController} { +Steps::Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController) + : app {app}, + motionController {motionController}, + settingsController {settingsController} { stepsArc = lv_arc_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index 4824be6aad..817a44583d 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -19,13 +19,14 @@ namespace Pinetime { class Steps : public Screen { public: - Steps(Controllers::MotionController& motionController, Controllers::Settings& settingsController); + Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController); ~Steps() override; void Refresh() override; void lapBtnEventHandler(lv_event_t event); private: + DisplayApp* app; Controllers::MotionController& motionController; Controllers::Settings& settingsController; @@ -50,7 +51,7 @@ namespace Pinetime { static constexpr const char* icon = Screens::Symbols::shoe; static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::Steps(controllers.motionController, controllers.settingsController); + return new Screens::Steps(controllers.displayApp, controllers.motionController, controllers.settingsController); }; static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) { diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index a037abfe16..f2ff9e7466 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -16,6 +16,13 @@ using namespace Pinetime::Applications::Screens; +namespace { + void ButtonEventHandler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + screen->OnButtonEvent(obj, event); + } +} + WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, @@ -42,6 +49,10 @@ WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); weatherIcon = lv_label_create(lv_scr_act(), nullptr); + weatherIcon->user_data = this; + lv_obj_set_click(weatherIcon, true); + lv_obj_set_ext_click_area(weatherIcon, 25, 25, 25, 25); + lv_obj_set_event_cb(weatherIcon, ButtonEventHandler); lv_obj_set_style_local_text_color(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999)); lv_obj_set_style_local_text_font(weatherIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &fontawesome_weathericons); lv_label_set_text(weatherIcon, ""); @@ -82,6 +93,10 @@ WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); stepIcon = lv_label_create(lv_scr_act(), nullptr); + stepIcon->user_data = this; + lv_obj_set_click(stepIcon, true); + lv_obj_set_ext_click_area(stepIcon, 0, 25, 25, 0); + lv_obj_set_event_cb(stepIcon, ButtonEventHandler); lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); lv_label_set_text_static(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); @@ -192,3 +207,11 @@ void WatchFaceDigital::Refresh() { lv_obj_realign(weatherIcon); } } + +void WatchFaceDigital::OnButtonEvent(lv_obj_t* object, lv_event_t event) { + if (object == stepIcon && event == LV_EVENT_PRESSED) { + app->StartApp(Apps::Steps, DisplayApp::FullRefreshDirections::Up); + } else if (object == weatherIcon && event == LV_EVENT_PRESSED) { + app->StartApp(Apps::Weather, DisplayApp::FullRefreshDirections::Up); + } +} diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index e3a1ac649a..0607e724d1 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -39,9 +39,12 @@ namespace Pinetime { Controllers::SimpleWeatherService& weather); ~WatchFaceDigital() override; + void OnButtonEvent(lv_obj_t* object, lv_event_t event); + void Refresh() override; private: + DisplayApp* app; uint8_t displayedHour = -1; uint8_t displayedMinute = -1; diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index de32a1538b..d40b6c566c 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -24,8 +24,10 @@ namespace { } } -Weather::Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) - : settingsController {settingsController}, weatherService {weatherService} { +Weather::Weather(DisplayApp* app, Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) + : app {app}, + settingsController {settingsController}, + weatherService {weatherService} { 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); diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 03266be105..9aeccd5d27 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -20,12 +20,13 @@ namespace Pinetime { class Weather : public Screen { public: - Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService); + Weather(DisplayApp* app, Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService); ~Weather() override; void Refresh() override; private: + DisplayApp* app; Controllers::Settings& settingsController; Controllers::SimpleWeatherService& weatherService; @@ -49,7 +50,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.displayApp, controllers.settingsController, *controllers.weatherController); }; static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) { From 2974b378f89f53911b0ea6a30e66944b2cd22736 Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Sun, 30 Aug 2026 12:06:34 +0100 Subject: [PATCH 2/4] Digital Watchface click on weather and steps --- src/displayapp/screens/Steps.cpp | 4 +--- src/displayapp/screens/Weather.cpp | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index 89c5ad9ba8..ac0900d619 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -17,9 +17,7 @@ static void lap_event_handler(lv_obj_t* obj, lv_event_t event) { } Steps::Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController) - : app {app}, - motionController {motionController}, - settingsController {settingsController} { + : app {app}, motionController {motionController}, settingsController {settingsController} { stepsArc = lv_arc_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index d40b6c566c..3beccfccf7 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -25,9 +25,7 @@ namespace { } Weather::Weather(DisplayApp* app, Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) - : app {app}, - settingsController {settingsController}, - weatherService {weatherService} { + : app {app}, settingsController {settingsController}, weatherService {weatherService} { 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); From b78b9225ae427f3fa7ff4515f625053631e9eecd Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Mon, 31 Aug 2026 21:11:39 +0100 Subject: [PATCH 3/4] Change to LV_EVENT_CLICKED so swipe up and down works better --- src/displayapp/screens/WatchFaceDigital.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index f2ff9e7466..49015b8d83 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -209,9 +209,12 @@ void WatchFaceDigital::Refresh() { } void WatchFaceDigital::OnButtonEvent(lv_obj_t* object, lv_event_t event) { - if (object == stepIcon && event == LV_EVENT_PRESSED) { + if (event != LV_EVENT_CLICKED) { + return; + } + if (object == stepIcon) { app->StartApp(Apps::Steps, DisplayApp::FullRefreshDirections::Up); - } else if (object == weatherIcon && event == LV_EVENT_PRESSED) { + } else if (object == weatherIcon) { app->StartApp(Apps::Weather, DisplayApp::FullRefreshDirections::Up); } } From d5103f2aff35643c8128d6b05c37f519646f8794 Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Tue, 1 Sep 2026 07:11:01 +0100 Subject: [PATCH 4/4] Refactor to fix some edge cases where click was not working --- src/displayapp/DisplayApp.cpp | 4 ++-- src/displayapp/screens/Steps.cpp | 4 ++-- src/displayapp/screens/Steps.h | 5 ++--- src/displayapp/screens/WatchFaceDigital.cpp | 6 ++++-- src/displayapp/screens/WatchFaceDigital.h | 6 ++++-- src/displayapp/screens/Weather.cpp | 4 ++-- src/displayapp/screens/Weather.h | 5 ++--- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index af179a001f..657b3aa8ef 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -652,10 +652,10 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio currentScreen = std::make_unique(*systemTask, brightnessController); break; case Apps::Weather: - currentScreen = std::make_unique(this, settingsController, *controllers.weatherController); + currentScreen = std::make_unique(settingsController, *controllers.weatherController); break; case Apps::Steps: - currentScreen = std::make_unique(this, motionController, settingsController); + currentScreen = std::make_unique(motionController, settingsController); break; default: { const auto* d = std::ranges::find_if(userApps, [app](const AppDescription& appDescription) { diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp index ac0900d619..2e73dab512 100644 --- a/src/displayapp/screens/Steps.cpp +++ b/src/displayapp/screens/Steps.cpp @@ -16,8 +16,8 @@ static void lap_event_handler(lv_obj_t* obj, lv_event_t event) { steps->lapBtnEventHandler(event); } -Steps::Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController) - : app {app}, motionController {motionController}, settingsController {settingsController} { +Steps::Steps(Controllers::MotionController& motionController, Controllers::Settings& settingsController) + : motionController {motionController}, settingsController {settingsController} { stepsArc = lv_arc_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index 817a44583d..4824be6aad 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -19,14 +19,13 @@ namespace Pinetime { class Steps : public Screen { public: - Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings& settingsController); + Steps(Controllers::MotionController& motionController, Controllers::Settings& settingsController); ~Steps() override; void Refresh() override; void lapBtnEventHandler(lv_event_t event); private: - DisplayApp* app; Controllers::MotionController& motionController; Controllers::Settings& settingsController; @@ -51,7 +50,7 @@ namespace Pinetime { static constexpr const char* icon = Screens::Symbols::shoe; static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::Steps(controllers.displayApp, controllers.motionController, controllers.settingsController); + return new Screens::Steps(controllers.motionController, controllers.settingsController); }; static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) { diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 49015b8d83..16e7b344b7 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -23,7 +23,8 @@ namespace { } } -WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, +WatchFaceDigital::WatchFaceDigital(DisplayApp* app, + Controllers::DateTime& dateTimeController, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, @@ -32,7 +33,8 @@ WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, Controllers::SimpleWeatherService& weatherService) - : currentDateTime {{}}, + : app {app}, + currentDateTime {{}}, dateTimeController {dateTimeController}, notificationManager {notificationManager}, settingsController {settingsController}, diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 0607e724d1..5a60c955f0 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -28,7 +28,8 @@ namespace Pinetime { class WatchFaceDigital : public Screen { public: - WatchFaceDigital(Controllers::DateTime& dateTimeController, + WatchFaceDigital(DisplayApp* app, + Controllers::DateTime& dateTimeController, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, @@ -86,7 +87,8 @@ namespace Pinetime { static constexpr const char* name = "Digital"; static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::WatchFaceDigital(controllers.dateTimeController, + return new Screens::WatchFaceDigital(controllers.displayApp, + controllers.dateTimeController, controllers.batteryController, controllers.bleController, controllers.alarmController, diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp index 3beccfccf7..de32a1538b 100644 --- a/src/displayapp/screens/Weather.cpp +++ b/src/displayapp/screens/Weather.cpp @@ -24,8 +24,8 @@ namespace { } } -Weather::Weather(DisplayApp* app, Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) - : app {app}, settingsController {settingsController}, weatherService {weatherService} { +Weather::Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService) + : settingsController {settingsController}, weatherService {weatherService} { 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); diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 9aeccd5d27..03266be105 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -20,13 +20,12 @@ namespace Pinetime { class Weather : public Screen { public: - Weather(DisplayApp* app, Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService); + Weather(Controllers::Settings& settingsController, Controllers::SimpleWeatherService& weatherService); ~Weather() override; void Refresh() override; private: - DisplayApp* app; Controllers::Settings& settingsController; Controllers::SimpleWeatherService& weatherService; @@ -50,7 +49,7 @@ namespace Pinetime { static constexpr const char* icon = Screens::Symbols::cloudSunRain; static Screens::Screen* Create(AppControllers& controllers) { - return new Screens::Weather(controllers.displayApp, controllers.settingsController, *controllers.weatherController); + return new Screens::Weather(controllers.settingsController, *controllers.weatherController); }; static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {