diff --git a/src/components/timer/Timer.cpp b/src/components/timer/Timer.cpp index 3ccffc7c04..1136321df3 100644 --- a/src/components/timer/Timer.cpp +++ b/src/components/timer/Timer.cpp @@ -15,7 +15,7 @@ void Timer::StartTimer(std::chrono::milliseconds duration) { // nullopt if timer stopped (StopTimer called / StartTimer not yet called) // otherwise TimerStatus with the ticks until/since expiry (depending on state of expired flag) -std::optional Timer::GetTimerState() { +std::optional Timer::GetTimerState() const { if (IsRunning()) { TickType_t remainingTime = expiry - xTaskGetTickCount(); return std::make_optional( @@ -38,7 +38,7 @@ void Timer::StopTimer() { triggered = false; } -bool Timer::IsRunning() { +bool Timer::IsRunning() const { return (xTimerIsTimerActive(timer) == pdTRUE); } diff --git a/src/components/timer/Timer.h b/src/components/timer/Timer.h index d43c7970e7..2391b06e48 100644 --- a/src/components/timer/Timer.h +++ b/src/components/timer/Timer.h @@ -21,9 +21,9 @@ namespace Pinetime { void StopTimer(); - std::optional GetTimerState(); + std::optional GetTimerState() const; - bool IsRunning(); + bool IsRunning() const; void ResetExpiredTime(); diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 35330fb7f7..af6f689242 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -532,6 +532,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio batteryController, bleController, alarmController, + timer, dateTimeController, filesystem, std::move(apps)); @@ -586,7 +587,8 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio motorController, settingsController, bleController, - alarmController); + alarmController, + timer); break; case Apps::Settings: currentScreen = std::make_unique(this, settingsController); diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index fb46b41384..90ea40ee9b 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -22,6 +22,7 @@ ApplicationList::ApplicationList(DisplayApp* app, const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, const Pinetime::Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, Controllers::DateTime& dateTimeController, Pinetime::Controllers::FS& filesystem, std::array&& apps) @@ -30,6 +31,7 @@ ApplicationList::ApplicationList(DisplayApp* app, batteryController {batteryController}, bleController {bleController}, alarmController {alarmController}, + timer {timer}, dateTimeController {dateTimeController}, filesystem {filesystem}, apps {std::move(apps)}, @@ -62,6 +64,7 @@ std::unique_ptr ApplicationList::CreateScreen(unsigned int screenNum) co batteryController, bleController, alarmController, + timer, dateTimeController, pageApps); } diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 4a57d7c034..457c4bb1ed 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -19,6 +19,7 @@ namespace Pinetime { const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, const Pinetime::Controllers::AlarmController& alarmController, + const Pinetime::Controllers::Timer& timer, Controllers::DateTime& dateTimeController, Pinetime::Controllers::FS& filesystem, std::array&& apps); @@ -34,6 +35,7 @@ namespace Pinetime { const Pinetime::Controllers::Battery& batteryController; const Pinetime::Controllers::Ble& bleController; const Pinetime::Controllers::AlarmController& alarmController; + const Pinetime::Controllers::Timer& timer; Controllers::DateTime& dateTimeController; Pinetime::Controllers::FS& filesystem; std::array apps; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 45f715b55a..e47587c2e2 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -30,12 +30,13 @@ Tile::Tile(uint8_t screenID, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, Controllers::DateTime& dateTimeController, std::array& applications) : app {app}, dateTimeController {dateTimeController}, pageIndicator(screenID, numScreens), - statusIcons(batteryController, bleController, alarmController) { + statusIcons(batteryController, bleController, alarmController, timer, settingsController) { settingsController.SetAppMenu(screenID); @@ -86,7 +87,7 @@ Tile::Tile(uint8_t screenID, btnm1->user_data = this; lv_obj_set_event_cb(btnm1, event_handler); - taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_MID, this); + taskUpdate = lv_task_create(lv_update_task, 500, LV_TASK_PRIO_MID, this); UpdateScreen(); } diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index c16151d0e1..e54dfd5659 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -29,6 +29,7 @@ namespace Pinetime { const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, Controllers::DateTime& dateTimeController, std::array& applications); diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 3163c6e750..8cdbceb087 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -20,6 +20,7 @@ WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, Controllers::NotificationManager& notificationManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, @@ -32,7 +33,7 @@ WatchFaceDigital::WatchFaceDigital(Controllers::DateTime& dateTimeController, heartRateController {heartRateController}, motionController {motionController}, weatherService {weatherService}, - statusIcons(batteryController, bleController, alarmController) { + statusIcons(batteryController, bleController, alarmController, timer, settingsController) { statusIcons.Create(); diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index e3a1ac649a..bfc55de663 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -21,6 +21,7 @@ namespace Pinetime { class NotificationManager; class HeartRateController; class MotionController; + class Timer; } namespace Applications { @@ -32,6 +33,7 @@ namespace Pinetime { const Controllers::Battery& batteryController, const Controllers::Ble& bleController, const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, Controllers::NotificationManager& notificationManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, @@ -87,6 +89,7 @@ namespace Pinetime { controllers.batteryController, controllers.bleController, controllers.alarmController, + controllers.timer, controllers.notificationManager, controllers.settingsController, controllers.heartRateController, diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index c5c3071aef..89dab5c053 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -34,13 +34,14 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, Controllers::MotorController& motorController, Pinetime::Controllers::Settings& settingsController, const Controllers::Ble& bleController, - const Controllers::AlarmController& alarmController) + const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer) : app {app}, dateTimeController {dateTimeController}, brightness {brightness}, motorController {motorController}, settingsController {settingsController}, - statusIcons(batteryController, bleController, alarmController) { + statusIcons(batteryController, bleController, alarmController, timer, settingsController) { statusIcons.Create(); @@ -119,7 +120,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); lv_label_set_text_static(lbl_btn, Symbols::settings); - taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_MID, this); + taskUpdate = lv_task_create(lv_update_task, 500, LV_TASK_PRIO_MID, this); UpdateScreen(); } diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h index 87c126b7fa..203e051f37 100644 --- a/src/displayapp/screens/settings/QuickSettings.h +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -24,7 +24,8 @@ namespace Pinetime { Controllers::MotorController& motorController, Pinetime::Controllers::Settings& settingsController, const Controllers::Ble& bleController, - const Controllers::AlarmController& alarmController); + const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer); ~QuickSettings() override; diff --git a/src/displayapp/widgets/StatusIcons.cpp b/src/displayapp/widgets/StatusIcons.cpp index 777731a59f..ce6af588f0 100644 --- a/src/displayapp/widgets/StatusIcons.cpp +++ b/src/displayapp/widgets/StatusIcons.cpp @@ -6,8 +6,15 @@ using namespace Pinetime::Applications::Widgets; StatusIcons::StatusIcons(const Controllers::Battery& batteryController, const Controllers::Ble& bleController, - const Controllers::AlarmController& alarmController) - : batteryIcon(true), batteryController {batteryController}, bleController {bleController}, alarmController {alarmController} { + const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, + const Controllers::Settings& settingsController) + : batteryIcon(true), + batteryController {batteryController}, + bleController {bleController}, + alarmController {alarmController}, + timer {timer}, + settingsController {settingsController} { } void StatusIcons::Create() { @@ -17,12 +24,29 @@ void StatusIcons::Create() { lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + timerContainer = lv_cont_create(container, nullptr); + lv_cont_set_layout(timerContainer, LV_LAYOUT_ROW_TOP); + lv_cont_set_fit(timerContainer, LV_FIT_TIGHT); + lv_obj_set_style_local_pad_inner(timerContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 1); + lv_obj_set_style_local_bg_opa(timerContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + + timerIcon = lv_label_create(timerContainer, nullptr); + lv_label_set_text_static(timerIcon, Screens::Symbols::hourGlass); + lv_obj_set_style_local_text_color(timerIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999)); + + timeRemaining = lv_label_create(timerContainer, nullptr); + lv_obj_set_style_local_text_color(timeRemaining, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999)); + lv_obj_set_style_local_text_letter_space(timeRemaining, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -1); + bleIcon = lv_label_create(container, nullptr); lv_label_set_text_static(bleIcon, Screens::Symbols::bluetooth); batteryPlug = lv_label_create(container, nullptr); lv_label_set_text_static(batteryPlug, Screens::Symbols::plug); + soloTimerIcon = lv_label_create(container, nullptr); + lv_label_set_text_static(soloTimerIcon, Screens::Symbols::hourGlass); + alarmIcon = lv_label_create(container, nullptr); lv_label_set_text_static(alarmIcon, Screens::Symbols::bell); @@ -54,5 +78,61 @@ void StatusIcons::Update() { lv_obj_set_hidden(bleIcon, !bleState.Get()); } + if (timer.IsRunning()) { + uint8_t activeIconCounter = 0; + uint8_t maxIcons = 0; + lv_obj_t* child = lv_obj_get_child(container, NULL); + + while (child != NULL) { + if (!lv_obj_get_hidden(child)) { + activeIconCounter++; + } + child = lv_obj_get_child(container, child); + } + + // Subtract batteryIcon as it doesn't count (always active) + activeIconCounter--; + + // Subtract individually because switching pages initially sets all icons + // to visible. This causes soloTimerIcon to briefly appear before the + // timerContainer is set to visible. + if (!lv_obj_get_hidden(timerContainer)) { + activeIconCounter--; + } + if (!lv_obj_get_hidden(soloTimerIcon)) { + activeIconCounter--; + } + + std::chrono::seconds secondsRemaining = + std::chrono::duration_cast(timer.GetTimerState().value_or(Controllers::Timer::TimerStatus {}).distanceToExpiry); + uint8_t timerMinutes = (secondsRemaining.count() % 3600) / 60; + uint8_t timerSeconds = secondsRemaining.count() % 60; + if (timerMinutes > 0) { + maxIcons = 2; + lv_label_set_text_fmt(timeRemaining, "%02d:%02d", timerMinutes, timerSeconds); + } else { + maxIcons = 4; + lv_label_set_text_fmt(timeRemaining, "%02d", timerSeconds); + } + + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { + maxIcons++; + if (timerMinutes > 0) { + maxIcons++; + } + } + + if (activeIconCounter > maxIcons) { + lv_obj_set_hidden(timerContainer, true); + lv_obj_set_hidden(soloTimerIcon, false); + } else { + lv_obj_set_hidden(soloTimerIcon, true); + lv_obj_set_hidden(timerContainer, false); + } + } else { + lv_obj_set_hidden(soloTimerIcon, true); + lv_obj_set_hidden(timerContainer, true); + } + lv_obj_realign(container); } diff --git a/src/displayapp/widgets/StatusIcons.h b/src/displayapp/widgets/StatusIcons.h index 5524e996c5..343562b21d 100644 --- a/src/displayapp/widgets/StatusIcons.h +++ b/src/displayapp/widgets/StatusIcons.h @@ -6,6 +6,7 @@ #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/alarm/AlarmController.h" +#include "components/settings/Settings.h" #include "displayapp/screens/BatteryIcon.h" #include "utility/DirtyValue.h" @@ -16,7 +17,9 @@ namespace Pinetime { public: StatusIcons(const Controllers::Battery& batteryController, const Controllers::Ble& bleController, - const Controllers::AlarmController& alarmController); + const Controllers::AlarmController& alarmController, + const Controllers::Timer& timer, + const Controllers::Settings& settingsController); void Align(); void Create(); @@ -31,6 +34,8 @@ namespace Pinetime { const Pinetime::Controllers::Battery& batteryController; const Controllers::Ble& bleController; const Controllers::AlarmController& alarmController; + const Controllers::Timer& timer; + const Controllers::Settings& settingsController; Utility::DirtyValue batteryPercentRemaining {}; Utility::DirtyValue powerPresent {}; @@ -38,10 +43,14 @@ namespace Pinetime { Utility::DirtyValue bleRadioEnabled {}; Utility::DirtyValue alarmEnabled {}; + lv_obj_t* container; + lv_obj_t* timerContainer; + lv_obj_t* timerIcon; + lv_obj_t* timeRemaining; lv_obj_t* bleIcon; - lv_obj_t* alarmIcon; lv_obj_t* batteryPlug; - lv_obj_t* container; + lv_obj_t* soloTimerIcon; + lv_obj_t* alarmIcon; }; } }