diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a97a015..ab9b1c62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -414,7 +414,10 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingSteps.cpp displayapp/screens/settings/SettingSetDateTime.cpp displayapp/screens/settings/SettingSetDate.cpp + displayapp/screens/settings/SettingSetSleepTime.cpp + displayapp/screens/settings/SettingSetSleepWakeTime.cpp displayapp/screens/settings/SettingSetTime.cpp + displayapp/screens/settings/SettingSetWakeTime.cpp displayapp/screens/settings/SettingChimes.cpp displayapp/screens/settings/SettingShakeThreshold.cpp displayapp/screens/settings/SettingBluetooth.cpp diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 7f58c9b3..737a61f9 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -119,6 +119,9 @@ void DateTime::UpdateTime(uint32_t systickCounter, bool forceUpdate) { } else if (hour != 0) { isMidnightAlreadyNotified = false; } + + // Finally change notification status if necessary + settingsController.SetNotificationStatusByTime(hour, minute); } const char* DateTime::MonthShortToString() const { diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 602de3a5..579bcfd5 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -203,6 +203,47 @@ namespace Pinetime { return settings.notificationStatus; }; + void SetNotificationStatusByTime(uint8_t h, uint8_t m) { + if (settings.notificationStatus == Notification::Off) { + return; + } + if (settings.sleepHour == settings.wakeHour && + settings.sleepMinute == settings.wakeMinute) { + return; + } + if (h == settings.sleepHour && m == settings.sleepMinute) { + SetNotificationStatus(Notification::Sleep); + } else if (h == settings.wakeHour && m == settings.wakeMinute) { + SetNotificationStatus(Notification::On); + } + }; + + void SetSleepTime(uint8_t h, uint8_t m) { + if (h != settings.sleepHour || m != settings.sleepMinute) { + settingsChanged = true; + } + settings.sleepHour = h; + settings.sleepMinute = m; + }; + + void SetWakeTime(uint8_t h, uint8_t m) { + if (h != settings.wakeHour || m != settings.wakeMinute) { + settingsChanged = true; + } + settings.wakeHour = h; + settings.wakeMinute = m; + }; + + void GetSleepTime(uint8_t &h, uint8_t &m) { + h = settings.sleepHour; + m = settings.sleepMinute; + }; + + void GetWakeTime(uint8_t &h, uint8_t &m) { + h = settings.wakeHour; + m = settings.wakeMinute; + }; + void SetScreenTimeOut(uint32_t timeout) { if (timeout != settings.screenTimeOut) { settingsChanged = true; @@ -325,6 +366,10 @@ namespace Pinetime { uint16_t shakeWakeThreshold = 150; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; + uint8_t sleepHour; + uint8_t sleepMinute; + uint8_t wakeHour; + uint8_t wakeMinute; }; SettingsData settings; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index ff43bb81..9e1914fc 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -48,6 +48,7 @@ #include "displayapp/screens/settings/SettingSetDateTime.h" #include "displayapp/screens/settings/SettingChimes.h" #include "displayapp/screens/settings/SettingShakeThreshold.h" +#include "displayapp/screens/settings/SettingSetSleepWakeTime.h" #include "displayapp/screens/settings/SettingBluetooth.h" #include "libs/lv_conf.h" @@ -593,6 +594,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::SettingChimes: currentScreen = std::make_unique(settingsController); break; + case Apps::SettingSetSleepWakeTime: + currentScreen = std::make_unique(this, dateTimeController, settingsController); + break; case Apps::SettingShakeThreshold: currentScreen = std::make_unique(settingsController, motionController, *systemTask); break; diff --git a/src/displayapp/apps/Apps.h.in b/src/displayapp/apps/Apps.h.in index 2104a267..3170e2d6 100644 --- a/src/displayapp/apps/Apps.h.in +++ b/src/displayapp/apps/Apps.h.in @@ -39,6 +39,7 @@ namespace Pinetime { SettingWakeUp, SettingSteps, SettingSetDateTime, + SettingSetSleepWakeTime, SettingChimes, SettingShakeThreshold, SettingBluetooth, diff --git a/src/displayapp/screens/settings/SettingSetSleepTime.cpp b/src/displayapp/screens/settings/SettingSetSleepTime.cpp new file mode 100644 index 00000000..ce920373 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetSleepTime.cpp @@ -0,0 +1,103 @@ +#include "displayapp/screens/settings/SettingSetSleepTime.h" +#include +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" +#include "components/settings/Settings.h" +#include "displayapp/InfiniTimeTheme.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + constexpr int16_t POS_Y_TEXT = -7; + + void SetTimeEventHandler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + if (event == LV_EVENT_CLICKED) { + screen->SetTime(); + } + } + + void ValueChangedHandler(void* userData) { + auto* screen = static_cast(userData); + screen->UpdateScreen(); + } +} + +SettingSetSleepTime::SettingSetSleepTime(Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime) + : dateTimeController {dateTimeController}, settingsController {settingsController}, settingSetSleepWakeTime {settingSetSleepWakeTime} { + + uint8_t h, m; + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Set sleep time"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + + lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::clock); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + lv_obj_t* staticLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(staticLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); + lv_label_set_text_static(staticLabel, "00:00:00"); + lv_obj_align(staticLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, POS_Y_TEXT); + + hourCounter.Create(); + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + hourCounter.EnableTwelveHourMode(); + } + settingsController.GetSleepTime(h, m); + hourCounter.SetValue(h); + lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_CENTER, -75, POS_Y_TEXT); + hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + minuteCounter.Create(); + minuteCounter.SetValue(m); + lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_CENTER, 0, POS_Y_TEXT); + minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + lblampm = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_label_set_text_static(lblampm, " "); + lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 75, -50); + + btnSetTime = lv_btn_create(lv_scr_act(), nullptr); + btnSetTime->user_data = this; + lv_obj_set_size(btnSetTime, 120, 50); + lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lblSetTime = lv_label_create(btnSetTime, nullptr); + lv_label_set_text_static(lblSetTime, "Set"); + lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); + lv_obj_set_style_local_text_color(lblSetTime, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_GRAY); + lv_obj_set_event_cb(btnSetTime, SetTimeEventHandler); + + UpdateScreen(); +} + +SettingSetSleepTime::~SettingSetSleepTime() { + lv_obj_clean(lv_scr_act()); +} + +void SettingSetSleepTime::UpdateScreen() { + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + if (hourCounter.GetValue() >= 12) { + lv_label_set_text_static(lblampm, "PM"); + } else { + lv_label_set_text_static(lblampm, "AM"); + } + } +} + +void SettingSetSleepTime::SetTime() { + const int hoursValue = hourCounter.GetValue(); + const int minutesValue = minuteCounter.GetValue(); + NRF_LOG_INFO("Setting sleep time to %02d:%02d:00", hoursValue, minutesValue); + settingsController.SetSleepTime(static_cast(hoursValue), + static_cast(minutesValue)); + settingSetSleepWakeTime.Quit(); +} diff --git a/src/displayapp/screens/settings/SettingSetSleepTime.h b/src/displayapp/screens/settings/SettingSetSleepTime.h new file mode 100644 index 00000000..ff723bce --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetSleepTime.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include "components/datetime/DateTimeController.h" +#include "components/settings/Settings.h" +#include "displayapp/widgets/Counter.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/widgets/DotIndicator.h" +#include "displayapp/screens/settings/SettingSetSleepWakeTime.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class SettingSetSleepTime : public Screen { + public: + SettingSetSleepTime(Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime); + ~SettingSetSleepTime() override; + + void SetTime(); + void UpdateScreen(); + + private: + Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime; + + lv_obj_t* lblampm; + lv_obj_t* btnSetTime; + lv_obj_t* lblSetTime; + Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_42); + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_42); + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingSetSleepWakeTime.cpp b/src/displayapp/screens/settings/SettingSetSleepWakeTime.cpp new file mode 100644 index 00000000..50e4774d --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetSleepWakeTime.cpp @@ -0,0 +1,54 @@ +#include "displayapp/screens/settings/SettingSetSleepWakeTime.h" +#include "displayapp/screens/settings/SettingSetSleepTime.h" +#include "displayapp/screens/settings/SettingSetWakeTime.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/ScreenList.h" +#include "components/settings/Settings.h" +#include "displayapp/widgets/DotIndicator.h" + +using namespace Pinetime::Applications::Screens; + +bool SettingSetSleepWakeTime::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +SettingSetSleepWakeTime::SettingSetSleepWakeTime(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController) + : app {app}, + dateTimeController {dateTimeController}, + settingsController {settingsController}, + screens {app, + 0, + {[this]() -> std::unique_ptr { + return screenSetSleepTime(); + }, + [this]() -> std::unique_ptr { + return screenSetWakeTime(); + }}, + Screens::ScreenListModes::UpDown} { +} + +std::unique_ptr SettingSetSleepWakeTime::screenSetSleepTime() { + Widgets::DotIndicator dotIndicator(0, 2); + dotIndicator.Create(); + return std::make_unique(dateTimeController, settingsController, *this); +} + +std::unique_ptr SettingSetSleepWakeTime::screenSetWakeTime() { + Widgets::DotIndicator dotIndicator(1, 2); + dotIndicator.Create(); + return std::make_unique(dateTimeController, settingsController, *this); +} + +SettingSetSleepWakeTime::~SettingSetSleepWakeTime() { + lv_obj_clean(lv_scr_act()); +} + +void SettingSetSleepWakeTime::Advance() { + screens.OnTouchEvent(Pinetime::Applications::TouchEvents::SwipeUp); +} + +void SettingSetSleepWakeTime::Quit() { + running = false; +} diff --git a/src/displayapp/screens/settings/SettingSetSleepWakeTime.h b/src/displayapp/screens/settings/SettingSetSleepWakeTime.h new file mode 100644 index 00000000..674ce17a --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetSleepWakeTime.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class SettingSetSleepWakeTime : public Screen { + public: + SettingSetSleepWakeTime(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController); + ~SettingSetSleepWakeTime() override; + + bool OnTouchEvent(TouchEvents event) override; + void Advance(); + void Quit(); + + private: + DisplayApp* app; + Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + + ScreenList<2> screens; + std::unique_ptr screenSetSleepTime(); + std::unique_ptr screenSetWakeTime(); + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingSetWakeTime.cpp b/src/displayapp/screens/settings/SettingSetWakeTime.cpp new file mode 100644 index 00000000..073dc645 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetWakeTime.cpp @@ -0,0 +1,103 @@ +#include "displayapp/screens/settings/SettingSetWakeTime.h" +#include +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" +#include "components/settings/Settings.h" +#include "displayapp/InfiniTimeTheme.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + constexpr int16_t POS_Y_TEXT = -7; + + void SetTimeEventHandler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + if (event == LV_EVENT_CLICKED) { + screen->SetTime(); + } + } + + void ValueChangedHandler(void* userData) { + auto* screen = static_cast(userData); + screen->UpdateScreen(); + } +} + +SettingSetWakeTime::SettingSetWakeTime(Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime) + : dateTimeController {dateTimeController}, settingsController {settingsController}, settingSetSleepWakeTime {settingSetSleepWakeTime} { + + uint8_t h, m; + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Set current time"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + + lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::clock); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + lv_obj_t* staticLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(staticLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); + lv_label_set_text_static(staticLabel, "00:00:00"); + lv_obj_align(staticLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, POS_Y_TEXT); + + settingsController.GetWakeTime(h, m); + hourCounter.Create(); + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + hourCounter.EnableTwelveHourMode(); + } + hourCounter.SetValue(h); + lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_CENTER, -75, POS_Y_TEXT); + hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + minuteCounter.Create(); + minuteCounter.SetValue(m); + lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_CENTER, 0, POS_Y_TEXT); + minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler); + + lblampm = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_label_set_text_static(lblampm, " "); + lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 75, -50); + + btnSetTime = lv_btn_create(lv_scr_act(), nullptr); + btnSetTime->user_data = this; + lv_obj_set_size(btnSetTime, 120, 50); + lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lblSetTime = lv_label_create(btnSetTime, nullptr); + lv_label_set_text_static(lblSetTime, "Set"); + lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt); + lv_obj_set_style_local_text_color(lblSetTime, LV_LABEL_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_GRAY); + lv_obj_set_event_cb(btnSetTime, SetTimeEventHandler); + + UpdateScreen(); +} + +SettingSetWakeTime::~SettingSetWakeTime() { + lv_obj_clean(lv_scr_act()); +} + +void SettingSetWakeTime::UpdateScreen() { + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + if (hourCounter.GetValue() >= 12) { + lv_label_set_text_static(lblampm, "PM"); + } else { + lv_label_set_text_static(lblampm, "AM"); + } + } +} + +void SettingSetWakeTime::SetTime() { + const int hoursValue = hourCounter.GetValue(); + const int minutesValue = minuteCounter.GetValue(); + NRF_LOG_INFO("Setting wakeup time to %02d:%02d:00", hoursValue, minutesValue); + settingsController.SetSleepTime(static_cast(hoursValue), + static_cast(minutesValue)); + settingSetSleepWakeTime.Quit(); +} diff --git a/src/displayapp/screens/settings/SettingSetWakeTime.h b/src/displayapp/screens/settings/SettingSetWakeTime.h new file mode 100644 index 00000000..0dfd9644 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSetWakeTime.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include "components/datetime/DateTimeController.h" +#include "components/settings/Settings.h" +#include "displayapp/widgets/Counter.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/widgets/DotIndicator.h" +#include "displayapp/screens/settings/SettingSetSleepWakeTime.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class SettingSetWakeTime : public Screen { + public: + SettingSetWakeTime(Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Settings& settingsController, + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime); + ~SettingSetWakeTime() override; + + void SetTime(); + void UpdateScreen(); + + private: + Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + Pinetime::Applications::Screens::SettingSetSleepWakeTime& settingSetSleepWakeTime; + + lv_obj_t* lblampm; + lv_obj_t* btnSetTime; + lv_obj_t* lblSetTime; + Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_42); + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_42); + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index a21b4ccd..c8227c0e 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -43,6 +43,7 @@ namespace Pinetime { {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, {Symbols::clock, "Chimes", Apps::SettingChimes}, + {Symbols::clock, "Sleep/Wake", Apps::SettingSetSleepWakeTime}, {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, {Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},