diff options
26 files changed, 544 insertions, 152 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b5880666..8846531e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(pinetime VERSION 1.7.1 LANGUAGES C CXX ASM) +project(pinetime VERSION 1.8.0 LANGUAGES C CXX ASM) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 14) @@ -100,7 +100,7 @@ else() endif() set(VERSION_EDIT_WARNING "// Do not edit this file, it is automatically generated by CMAKE!") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/Version.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docker/post_build.sh.in ${CMAKE_CURRENT_BINARY_DIR}/post_build.sh) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47da4a8a..aec6ce04 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -447,6 +447,8 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingSteps.cpp displayapp/screens/settings/SettingSetDate.cpp displayapp/screens/settings/SettingSetTime.cpp + displayapp/screens/settings/SettingChimes.cpp + displayapp/screens/settings/SettingShakeThreshold.cpp ## Watch faces displayapp/icons/bg_clock.c @@ -610,6 +612,7 @@ list(APPEND RECOVERYLOADER_SOURCE_FILES set(INCLUDE_FILES + ${CMAKE_CURRENT_BINARY_DIR}/src/Version.h BootloaderVersion.h logging/Logger.h logging/NrfLogger.h @@ -708,6 +711,7 @@ set(INCLUDE_FILES ) include_directories( + ${CMAKE_BINARY_DIR}/src # include generated files like Version.h . ../ libs/ diff --git a/src/buttonhandler/ButtonHandler.cpp b/src/buttonhandler/ButtonHandler.cpp index 02ee22cf..3c2bc72c 100644 --- a/src/buttonhandler/ButtonHandler.cpp +++ b/src/buttonhandler/ButtonHandler.cpp @@ -1,4 +1,4 @@ -#include "ButtonHandler.h" +#include "buttonhandler/ButtonHandler.h" using namespace Pinetime::Controllers; diff --git a/src/buttonhandler/ButtonHandler.h b/src/buttonhandler/ButtonHandler.h index 44b20f19..5802b998 100644 --- a/src/buttonhandler/ButtonHandler.h +++ b/src/buttonhandler/ButtonHandler.h @@ -1,6 +1,6 @@ #pragma once -#include "ButtonActions.h" +#include "buttonhandler/ButtonActions.h" #include "systemtask/SystemTask.h" #include <FreeRTOS.h> #include <timers.h> diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 4ac9e1f1..673903cb 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -75,6 +75,24 @@ void DateTime::UpdateTime(uint32_t systickCounter) { minute = time.minutes().count(); second = time.seconds().count(); + if (minute == 0 && !isHourAlreadyNotified) { + isHourAlreadyNotified = true; + if (systemTask != nullptr) { + systemTask->PushMessage(System::Messages::OnNewHour); + } + } else if (minute != 0) { + isHourAlreadyNotified = false; + } + + if ((minute == 0 || minute == 30) && !isHalfHourAlreadyNotified) { + isHalfHourAlreadyNotified = true; + if (systemTask != nullptr) { + systemTask->PushMessage(System::Messages::OnNewHalfHour); + } + } else if (minute != 0 && minute != 30) { + isHalfHourAlreadyNotified = false; + } + // Notify new day to SystemTask if (hour == 0 and not isMidnightAlreadyNotified) { isMidnightAlreadyNotified = true; @@ -100,4 +118,3 @@ const char* DateTime::MonthShortToStringLow(Months month) { void DateTime::Register(Pinetime::System::SystemTask* systemTask) { this->systemTask = systemTask; } - diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h index 77ed68e8..cbc80447 100644 --- a/src/components/datetime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h @@ -86,6 +86,8 @@ namespace Pinetime { std::chrono::seconds uptime {0}; bool isMidnightAlreadyNotified = false; + bool isHourAlreadyNotified = true; + bool isHalfHourAlreadyNotified = true; System::SystemTask* systemTask = nullptr; }; } diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 97a8feb2..7dd32127 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -1,5 +1,5 @@ #include "components/motion/MotionController.h" - +#include "os/os_cputime.h" using namespace Pinetime::Controllers; void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) { @@ -7,7 +7,7 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) service->OnNewStepCountValue(nbSteps); } - if(service != nullptr && (this->x != x || this->y != y || this->z != z)) { + if (service != nullptr && (this->x != x || this->y != y || this->z != z)) { service->OnNewMotionValues(x, y, z); } @@ -21,7 +21,7 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) } } -bool MotionController::ShouldWakeUp(bool isSleeping) { +bool MotionController::Should_RaiseWake(bool isSleeping) { if ((x + 335) <= 670 && z < 0) { if (not isSleeping) { if (y <= 0) { @@ -43,6 +43,29 @@ bool MotionController::ShouldWakeUp(bool isSleeping) { } return false; } + +bool MotionController::Should_ShakeWake(uint16_t thresh) { + bool wake = false; + auto diff = xTaskGetTickCount() - lastShakeTime; + lastShakeTime = xTaskGetTickCount(); + /* Currently Polling at 10hz, If this ever goes faster scalar and EMA might need adjusting */ + int32_t speed = std::abs(z + (y / 2) + (x / 4) - lastYForShake - lastZForShake) / diff * 100; + //(.2 * speed) + ((1 - .2) * accumulatedspeed); + // implemented without floats as .25Alpha + accumulatedspeed = (speed / 5) + ((accumulatedspeed / 5) * 4); + + if (accumulatedspeed > thresh) { + wake = true; + } + lastXForShake = x / 4; + lastYForShake = y / 2; + lastZForShake = z; + return wake; +} +int32_t MotionController::currentShakeSpeed() { + return accumulatedspeed; +} + void MotionController::IsSensorOk(bool isOk) { isSensorOk = isOk; } diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index 3eac7176..f80b11b9 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -35,8 +35,10 @@ namespace Pinetime { uint32_t GetTripSteps() const { return currentTripSteps; } - bool ShouldWakeUp(bool isSleeping); + bool Should_ShakeWake(uint16_t thresh); + bool Should_RaiseWake(bool isSleeping); + int32_t currentShakeSpeed(); void IsSensorOk(bool isOk); bool IsSensorOk() const { return isSensorOk; @@ -59,6 +61,12 @@ namespace Pinetime { bool isSensorOk = false; DeviceTypes deviceType = DeviceTypes::Unknown; Pinetime::Controllers::MotionService* service = nullptr; + + int16_t lastXForShake = 0; + int16_t lastYForShake = 0; + int16_t lastZForShake = 0; + int32_t accumulatedspeed = 0; + uint32_t lastShakeTime = 0; }; } }
\ No newline at end of file diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 2d7973d8..6de44aac 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -11,10 +11,12 @@ namespace Pinetime { public: enum class ClockType : uint8_t { H24, H12 }; enum class Notification : uint8_t { ON, OFF }; + enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, + Shake = 3, }; enum class Colors : uint8_t { White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange @@ -40,6 +42,16 @@ namespace Pinetime { return settings.clockFace; }; + void SetChimeOption(ChimesOption chimeOption) { + if (chimeOption != settings.chimesOption) { + settingsChanged = true; + } + settings.chimesOption = chimeOption; + }; + ChimesOption GetChimeOption() const { + return settings.chimesOption; + }; + void SetPTSColorTime(Colors colorTime) { if (colorTime != settings.PTS.ColorTime) settingsChanged = true; @@ -108,10 +120,23 @@ namespace Pinetime { } settings.screenTimeOut = timeout; }; + uint32_t GetScreenTimeOut() const { return settings.screenTimeOut; }; + void SetShakeThreshold(uint16_t thresh){ + if(settings.shakeWakeThreshold != thresh){ + settings.shakeWakeThreshold = thresh; + settingsChanged = true; + } + + } + + int16_t GetShakeThreshold() const{ + return settings.shakeWakeThreshold; + } + void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { if (enabled != isWakeUpModeOn(wakeUp)) { settingsChanged = true; @@ -126,13 +151,13 @@ namespace Pinetime { case WakeUpMode::DoubleTap: settings.wakeUpMode.set(static_cast<size_t>(WakeUpMode::SingleTap), false); break; - case WakeUpMode::RaiseWrist: + default: break; } } }; - std::bitset<3> getWakeUpModes() const { + std::bitset<4> getWakeUpModes() const { return settings.wakeUpMode; } @@ -162,7 +187,7 @@ namespace Pinetime { private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0002; + static constexpr uint32_t settingsVersion = 0x0003; struct SettingsData { uint32_t version = settingsVersion; uint32_t stepsGoal = 10000; @@ -172,11 +197,12 @@ namespace Pinetime { Notification notificationStatus = Notification::ON; uint8_t clockFace = 0; + ChimesOption chimesOption = ChimesOption::None; PineTimeStyle PTS; - std::bitset<3> wakeUpMode {0}; - + std::bitset<4> wakeUpMode {0}; + uint16_t shakeWakeThreshold = 150; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; }; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index c77bd29f..b876020e 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -36,7 +36,9 @@ namespace Pinetime { SettingSteps, SettingSetDate, SettingSetTime, - Error, + SettingChimes, + SettingShakeThreshold, + Error }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 383badf1..cc544fdb 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -47,6 +47,8 @@ #include "displayapp/screens/settings/SettingSteps.h" #include "displayapp/screens/settings/SettingSetDate.h" #include "displayapp/screens/settings/SettingSetTime.h" +#include "displayapp/screens/settings/SettingChimes.h" +#include "displayapp/screens/settings/SettingShakeThreshold.h" #include "libs/lv_conf.h" @@ -292,6 +294,9 @@ void DisplayApp::Refresh() { // Added to remove warning // What should happen here? break; + case Messages::Clock: + LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None); + break; } } @@ -415,6 +420,14 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique<Screens::SettingSetTime>(this, dateTimeController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; + case Apps::SettingChimes: + currentScreen = std::make_unique<Screens::SettingChimes>(this, settingsController); + ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; + case Apps::SettingShakeThreshold: + currentScreen = std::make_unique<Screens::SettingShakeThreshold>(this, settingsController,motionController,*systemTask); + ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; case Apps::BatteryInfo: currentScreen = std::make_unique<Screens::BatteryInfo>(this, batteryController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index b22d6c3c..a3a78cc9 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -20,7 +20,8 @@ namespace Pinetime { DimScreen, RestoreBrightness, ShowPairingKey, - AlarmTriggered + AlarmTriggered, + Clock }; } } diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp index b2b972dc..7ce0bc0d 100644 --- a/src/displayapp/screens/PineTimeStyle.cpp +++ b/src/displayapp/screens/PineTimeStyle.cpp @@ -60,12 +60,6 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, settingsController {settingsController}, motionController {motionController} { - displayedChar[0] = 0; - displayedChar[1] = 0; - displayedChar[2] = 0; - displayedChar[3] = 0; - displayedChar[4] = 0; - // Create a 200px wide background rectangle timebar = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_style_local_bg_color(timebar, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorBG())); @@ -77,19 +71,19 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, timeDD1 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); lv_obj_set_style_local_text_color(timeDD1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); - lv_label_set_text(timeDD1, "00"); + lv_label_set_text_static(timeDD1, "00"); lv_obj_align(timeDD1, timebar, LV_ALIGN_IN_TOP_MID, 5, 5); timeDD2 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &open_sans_light); lv_obj_set_style_local_text_color(timeDD2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); - lv_label_set_text(timeDD2, "00"); + lv_label_set_text_static(timeDD2, "00"); lv_obj_align(timeDD2, timebar, LV_ALIGN_IN_BOTTOM_MID, 5, -5); timeAMPM = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Convert(settingsController.GetPTSColorTime())); lv_obj_set_style_local_text_line_space(timeAMPM, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, -3); - lv_label_set_text(timeAMPM, ""); + lv_label_set_text_static(timeAMPM, ""); lv_obj_align(timeAMPM, timebar, LV_ALIGN_IN_BOTTOM_LEFT, 2, -20); // Create a 40px wide bar down the right side of the screen @@ -102,17 +96,17 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, // Display icons batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_label_set_text_static(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2); lv_obj_set_auto_realign(batteryIcon, true); bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); - lv_label_set_text(bleIcon, ""); + lv_label_set_text_static(bleIcon, ""); notificationIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); - lv_label_set_text(notificationIcon, ""); + lv_label_set_text_static(notificationIcon, ""); // Calendar icon calendarOuter = lv_obj_create(lv_scr_act(), nullptr); @@ -154,17 +148,17 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, // Display date dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_label_set_text(dateDayOfWeek, "THU"); + lv_label_set_text_static(dateDayOfWeek, "THU"); lv_obj_align(dateDayOfWeek, sidebar, LV_ALIGN_CENTER, 0, -34); dateDay = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(dateDay, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_label_set_text(dateDay, "25"); + lv_label_set_text_static(dateDay, "25"); lv_obj_align(dateDay, sidebar, LV_ALIGN_CENTER, 0, 3); dateMonth = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(dateMonth, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - lv_label_set_text(dateMonth, "MAR"); + lv_label_set_text_static(dateMonth, "MAR"); lv_obj_align(dateMonth, sidebar, LV_ALIGN_CENTER, 0, 32); // Step count gauge @@ -199,7 +193,7 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app, lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); - lv_label_set_text(backgroundLabel, ""); + lv_label_set_text_static(backgroundLabel, ""); btnNextTime = lv_btn_create(lv_scr_act(), nullptr); btnNextTime->user_data = this; @@ -339,7 +333,7 @@ bool PineTimeStyle::OnButtonPushed() { void PineTimeStyle::SetBatteryIcon() { auto batteryPercent = batteryPercentRemaining.Get(); - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + lv_label_set_text_static(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); } void PineTimeStyle::AlignIcons() { @@ -357,7 +351,7 @@ void PineTimeStyle::Refresh() { isCharging = batteryController.IsCharging(); if (isCharging.IsUpdated()) { if (isCharging.Get()) { - lv_label_set_text(batteryIcon, Symbols::plug); + lv_label_set_text_static(batteryIcon, Symbols::plug); } else { SetBatteryIcon(); } @@ -371,13 +365,13 @@ void PineTimeStyle::Refresh() { bleState = bleController.IsConnected(); if (bleState.IsUpdated()) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); + lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get())); AlignIcons(); } notificationState = notificatioManager.AreNewNotificationsAvailable(); if (notificationState.IsUpdated()) { - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); + lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); AlignIcons(); } @@ -394,45 +388,31 @@ void PineTimeStyle::Refresh() { auto day = static_cast<unsigned>(yearMonthDay.day()); auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding()); - int hour = time.hours().count(); - auto minute = time.minutes().count(); - - char minutesChar[3]; - sprintf(minutesChar, "%02d", static_cast<int>(minute)); - - char hoursChar[3]; - char ampmChar[5]; - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - sprintf(hoursChar, "%02d", hour); - } else { - if (hour == 0 && hour != 12) { - hour = 12; - sprintf(ampmChar, "A\nM"); - } else if (hour == 12 && hour != 0) { - hour = 12; - sprintf(ampmChar, "P\nM"); - } else if (hour < 12 && hour != 0) { - sprintf(ampmChar, "A\nM"); - } else if (hour > 12 && hour != 0) { - hour = hour - 12; - sprintf(ampmChar, "P\nM"); - } - sprintf(hoursChar, "%02d", hour); - } + uint8_t hour = time.hours().count(); + uint8_t minute = time.minutes().count(); - if (hoursChar[0] != displayedChar[0] or hoursChar[1] != displayedChar[1] or minutesChar[0] != displayedChar[2] or - minutesChar[1] != displayedChar[3]) { - displayedChar[0] = hoursChar[0]; - displayedChar[1] = hoursChar[1]; - displayedChar[2] = minutesChar[0]; - displayedChar[3] = minutesChar[1]; + if (displayedHour != hour || displayedMinute != minute) { + displayedHour = hour; + displayedMinute = minute; if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + char ampmChar[4] = "A\nM"; + if (hour == 0) { + hour = 12; + } else if (hour == 12) { + ampmChar[0] = 'P'; + } else if (hour > 12) { + hour = hour - 12; + ampmChar[0] = 'P'; + } lv_label_set_text(timeAMPM, ampmChar); + // Should be padded with blank spaces, but the space character doesn't exist in the font + lv_label_set_text_fmt(timeDD1, "%02d", hour); + lv_label_set_text_fmt(timeDD2, "%02d", minute); + } else { + lv_label_set_text_fmt(timeDD1, "%02d", hour); + lv_label_set_text_fmt(timeDD2, "%02d", minute); } - - lv_label_set_text_fmt(timeDD1, "%s", hoursChar); - lv_label_set_text_fmt(timeDD2, "%s", minutesChar); } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index df8b7d5a..1b972ce1 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -39,7 +39,8 @@ namespace Pinetime { void UpdateSelected(lv_obj_t *object, lv_event_t event); private: - char displayedChar[5]; + uint8_t displayedHour = -1; + uint8_t displayedMinute = -1; uint16_t currentYear = 1970; Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 4d9eaf37..b3cb0f91 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -35,22 +35,22 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, settingsController.SetClockFace(0); batteryIcon = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_label_set_text_static(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); batteryPlug = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); - lv_label_set_text(batteryPlug, Symbols::plug); + lv_label_set_text_static(batteryPlug, Symbols::plug); lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0082FC)); - lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_label_set_text_static(bleIcon, Symbols::bluetooth); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); notificationIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); + lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false)); lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); label_date = lv_label_create(lv_scr_act(), nullptr); @@ -71,26 +71,26 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); lv_obj_set_size(backgroundLabel, 240, 240); lv_obj_set_pos(backgroundLabel, 0, 0); - lv_label_set_text(backgroundLabel, ""); + lv_label_set_text_static(backgroundLabel, ""); heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(heartbeatIcon, Symbols::heartBeat); + lv_label_set_text_static(heartbeatIcon, Symbols::heartBeat); lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); heartbeatValue = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B)); - lv_label_set_text(heartbeatValue, ""); + lv_label_set_text_static(heartbeatValue, ""); lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); stepValue = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); - lv_label_set_text(stepValue, "0"); + lv_label_set_text_static(stepValue, "0"); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); stepIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7)); - lv_label_set_text(stepIcon, Symbols::shoe); + lv_label_set_text_static(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); @@ -105,7 +105,7 @@ WatchFaceDigital::~WatchFaceDigital() { void WatchFaceDigital::Refresh() { powerPresent = batteryController.IsPowerPresent(); if (powerPresent.IsUpdated()) { - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get())); + lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get())); } batteryPercentRemaining = batteryController.PercentRemaining(); @@ -116,20 +116,20 @@ void WatchFaceDigital::Refresh() { } else { lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); } - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + lv_label_set_text_static(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); } bleState = bleController.IsConnected(); if (bleState.IsUpdated()) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); + lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get())); } - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_realign(batteryIcon); + lv_obj_realign(batteryPlug); + lv_obj_realign(bleIcon); notificationState = notificatioManager.AreNewNotificationsAvailable(); if (notificationState.IsUpdated()) { - lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); + lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get())); } currentDateTime = dateTimeController.CurrentDateTime(); @@ -146,62 +146,41 @@ void WatchFaceDigital::Refresh() { auto day = static_cast<unsigned>(yearMonthDay.day()); auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding()); - int hour = time.hours().count(); - auto minute = time.minutes().count(); - - char minutesChar[3]; - sprintf(minutesChar, "%02d", static_cast<int>(minute)); - - char hoursChar[3]; - char ampmChar[3]; - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - sprintf(hoursChar, "%02d", hour); - } else { - if (hour == 0 && hour != 12) { - hour = 12; - sprintf(ampmChar, "AM"); - } else if (hour == 12 && hour != 0) { - hour = 12; - sprintf(ampmChar, "PM"); - } else if (hour < 12 && hour != 0) { - sprintf(ampmChar, "AM"); - } else if (hour > 12 && hour != 0) { - hour = hour - 12; - sprintf(ampmChar, "PM"); - } - sprintf(hoursChar, "%02d", hour); - } + uint8_t hour = time.hours().count(); + uint8_t minute = time.minutes().count(); - if ((hoursChar[0] != displayedChar[0]) or (hoursChar[1] != displayedChar[1]) or (minutesChar[0] != displayedChar[2]) or - (minutesChar[1] != displayedChar[3])) { - displayedChar[0] = hoursChar[0]; - displayedChar[1] = hoursChar[1]; - displayedChar[2] = minutesChar[0]; - displayedChar[3] = minutesChar[1]; + if (displayedHour != hour || displayedMinute != minute) { + displayedHour = hour; + displayedMinute = minute; if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { - lv_label_set_text(label_time_ampm, ampmChar); - if (hoursChar[0] == '0') { - hoursChar[0] = ' '; + char ampmChar[3] = "AM"; + if (hour == 0) { + hour = 12; + } else if (hour == 12) { + ampmChar[0] = 'P'; + } else if (hour > 12) { + hour = hour - 12; + ampmChar[0] = 'P'; } - } - - lv_label_set_text_fmt(label_time, "%s:%s", hoursChar, minutesChar); - - if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) { + lv_label_set_text(label_time_ampm, ampmChar); + lv_label_set_text_fmt(label_time, "%2d:%02d", hour, minute); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 0); } else { + lv_label_set_text_fmt(label_time, "%02d:%02d", hour, minute); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); } } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - lv_label_set_text_fmt(label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); + lv_label_set_text_fmt( + label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); } else { - lv_label_set_text_fmt(label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); + lv_label_set_text_fmt( + label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); } - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); + lv_obj_realign(label_date); currentYear = year; currentMonth = month; @@ -221,15 +200,15 @@ void WatchFaceDigital::Refresh() { lv_label_set_text_static(heartbeatValue, ""); } - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); - lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + lv_obj_realign(heartbeatIcon); + lv_obj_realign(heartbeatValue); } stepCount = motionController.NbSteps(); motionSensorOk = motionController.IsSensorOk(); if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) { lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get()); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); - lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_realign(stepValue); + lv_obj_realign(stepIcon); } } diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 627154c8..ab3a0285 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -35,7 +35,8 @@ namespace Pinetime { void Refresh() override; private: - char displayedChar[5] {}; + uint8_t displayedHour = -1; + uint8_t displayedMinute = -1; uint16_t currentYear = 1970; Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; diff --git a/src/displayapp/screens/settings/SettingChimes.cpp b/src/displayapp/screens/settings/SettingChimes.cpp new file mode 100644 index 00000000..543b5e0e --- /dev/null +++ b/src/displayapp/screens/settings/SettingChimes.cpp @@ -0,0 +1,100 @@ +#include "displayapp/screens/settings/SettingChimes.h" +#include <lvgl/lvgl.h> +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Styles.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t* obj, lv_event_t event) { + SettingChimes* screen = static_cast<SettingChimes*>(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingChimes::SettingChimes(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), settingsController {settingsController} { + + lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 60); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 50); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Chimes"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 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); + + optionsTotal = 0; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Off"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + SetRadioButtonStyle(cbOption[optionsTotal]); + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::None) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Every hour"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + SetRadioButtonStyle(cbOption[optionsTotal]); + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Every 30 mins"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + SetRadioButtonStyle(cbOption[optionsTotal]); + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; +} + +SettingChimes::~SettingChimes() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingChimes::UpdateSelected(lv_obj_t* object, lv_event_t event) { + if (event == LV_EVENT_VALUE_CHANGED) { + for (uint8_t i = 0; i < optionsTotal; i++) { + if (object == cbOption[i]) { + lv_checkbox_set_checked(cbOption[i], true); + if (i == 0) { + settingsController.SetChimeOption(Controllers::Settings::ChimesOption::None); + } + if (i == 1) { + settingsController.SetChimeOption(Controllers::Settings::ChimesOption::Hours); + } + if (i == 2) { + settingsController.SetChimeOption(Controllers::Settings::ChimesOption::HalfHours); + } + } else { + lv_checkbox_set_checked(cbOption[i], false); + } + } + } +} diff --git a/src/displayapp/screens/settings/SettingChimes.h b/src/displayapp/screens/settings/SettingChimes.h new file mode 100644 index 00000000..653f87f7 --- /dev/null +++ b/src/displayapp/screens/settings/SettingChimes.h @@ -0,0 +1,27 @@ +#pragma once + +#include <cstdint> +#include <lvgl/lvgl.h> +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingChimes : public Screen { + public: + SettingChimes(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + ~SettingChimes() override; + + void UpdateSelected(lv_obj_t* object, lv_event_t event); + + private: + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t* cbOption[2]; + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.cpp b/src/displayapp/screens/settings/SettingShakeThreshold.cpp new file mode 100644 index 00000000..1791b550 --- /dev/null +++ b/src/displayapp/screens/settings/SettingShakeThreshold.cpp @@ -0,0 +1,137 @@ +#include "SettingShakeThreshold.h" +#include <lvgl/lvgl.h> +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + SettingShakeThreshold* screen = static_cast<SettingShakeThreshold*>(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingShakeThreshold::SettingShakeThreshold(DisplayApp* app, + Controllers::Settings& settingsController, + Controllers::MotionController& motionController, + System::SystemTask& systemTask) + : Screen(app), settingsController {settingsController}, motionController {motionController}, systemTask {systemTask} { + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Wake Sensitivity"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); + + positionArc = lv_arc_create(lv_scr_act(), nullptr); + positionArc->user_data = this; + + lv_obj_set_event_cb(positionArc, event_handler); + lv_arc_set_bg_angles(positionArc, 180, 360); + lv_arc_set_range(positionArc, 0, 4095); + lv_arc_set_adjustable(positionArc, true); + lv_obj_set_width(positionArc, lv_obj_get_width(lv_scr_act()) - 10); + lv_obj_set_height(positionArc, 240); + lv_obj_align(positionArc, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 0); + + animArc = lv_arc_create(positionArc, positionArc); + lv_arc_set_adjustable(animArc, false); + lv_obj_set_width(animArc, lv_obj_get_width(positionArc)); + lv_obj_set_height(animArc, lv_obj_get_height(positionArc)); + lv_obj_align_mid(animArc, positionArc, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0); + lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_OPA_70); + lv_obj_set_style_local_line_opa(animArc, LV_ARC_PART_KNOB, LV_STATE_DEFAULT, LV_OPA_0); + lv_obj_set_style_local_line_color(animArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); + lv_obj_set_style_local_bg_color(animArc, LV_ARC_PART_BG, LV_STATE_CHECKED, LV_COLOR_TRANSP); + + animArc->user_data = this; + lv_obj_set_click(animArc, false); + + calButton = lv_btn_create(lv_scr_act(), nullptr); + calButton->user_data = this; + lv_obj_set_event_cb(calButton, event_handler); + lv_obj_set_height(calButton, 80); + lv_obj_set_width(calButton, 200); + lv_obj_align(calButton, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_btn_set_checkable(calButton, true); + calLabel = lv_label_create(calButton, NULL); + lv_label_set_text(calLabel, "Calibrate"); + + lv_arc_set_value(positionArc, settingsController.GetShakeThreshold()); + + vDecay = xTaskGetTickCount(); + calibrating = false; + EnableForCal = false; + if(!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)){ + EnableForCal = true; + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,true); + } + refreshTask = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); +} + +SettingShakeThreshold::~SettingShakeThreshold() { + settingsController.SetShakeThreshold(lv_arc_get_value(positionArc)); + + if(EnableForCal){ + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,false); + EnableForCal = false; + } + lv_task_del(refreshTask); + settingsController.SaveSettings(); + lv_obj_clean(lv_scr_act()); +} + +void SettingShakeThreshold::Refresh() { + + if (calibrating == 1) { + if (xTaskGetTickCount() - vCalTime > pdMS_TO_TICKS(2000)) { + vCalTime = xTaskGetTickCount(); + calibrating = 2; + lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_RED); + lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_RED); + lv_label_set_text(calLabel, "Shake!!"); + } + } + if (calibrating == 2) { + + if ((motionController.currentShakeSpeed() - 300) > lv_arc_get_value(positionArc)) { + lv_arc_set_value(positionArc, (int16_t) motionController.currentShakeSpeed() - 300); + } + if (xTaskGetTickCount() - vCalTime > pdMS_TO_TICKS(7500)) { + lv_btn_set_state(calButton, LV_STATE_DEFAULT); + lv_event_send(calButton, LV_EVENT_VALUE_CHANGED, NULL); + } + } + if (motionController.currentShakeSpeed() - 300 > lv_arc_get_value(animArc)) { + lv_arc_set_value(animArc, (uint16_t) motionController.currentShakeSpeed() - 300); + vDecay = xTaskGetTickCount(); + } else if ((xTaskGetTickCount() - vDecay) > pdMS_TO_TICKS(1500)) { + lv_arc_set_value(animArc, lv_arc_get_value(animArc) - 25); + } +} + +void SettingShakeThreshold::UpdateSelected(lv_obj_t* object, lv_event_t event) { + + switch (event) { + case LV_EVENT_VALUE_CHANGED: { + if (object == calButton) { + if (lv_btn_get_state(calButton) == LV_BTN_STATE_CHECKED_RELEASED && calibrating == 0) { + lv_arc_set_value(positionArc, 0); + calibrating = 1; + vCalTime = xTaskGetTickCount(); + lv_label_set_text(calLabel, "Ready!"); + lv_obj_set_click(positionArc, false); + lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); + lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); + } else if (lv_btn_get_state(calButton) == LV_BTN_STATE_RELEASED) { + calibrating = 0; + lv_obj_set_click(positionArc, true); + lv_label_set_text(calLabel, "Calibrate"); + } + break; + } + } + } +} diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.h b/src/displayapp/screens/settings/SettingShakeThreshold.h new file mode 100644 index 00000000..b9ddd8b4 --- /dev/null +++ b/src/displayapp/screens/settings/SettingShakeThreshold.h @@ -0,0 +1,36 @@ +#pragma once + +#include <cstdint> +#include <lvgl/lvgl.h> +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" +#include <components/motion/MotionController.h> +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingShakeThreshold : public Screen { + public: + SettingShakeThreshold(DisplayApp* app, + Pinetime::Controllers::Settings& settingsController, + Controllers::MotionController& motionController, + System::SystemTask& systemTask); + + ~SettingShakeThreshold() override; + void Refresh() override; + void UpdateSelected(lv_obj_t* object, lv_event_t event); + + private: + Controllers::Settings& settingsController; + Controllers::MotionController& motionController; + System::SystemTask& systemTask; + uint8_t calibrating; + bool EnableForCal; + uint32_t vDecay,vCalTime; + lv_obj_t *positionArc, *animArc,*calButton, *calLabel; + lv_task_t* refreshTask; + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 8339d9ad..e1b6e36e 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -65,6 +65,14 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: lv_checkbox_set_checked(cbOption[optionsTotal], true); } optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Shake Wake"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; } SettingWakeUp::~SettingWakeUp() { diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index b9a31dc9..cd244ae5 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -20,7 +20,7 @@ namespace Pinetime { private: Controllers::Settings& settingsController; uint8_t optionsTotal; - lv_obj_t* cbOption[4]; + lv_obj_t* cbOption[5]; // When UpdateSelected is called, it uses lv_checkbox_set_checked, // which can cause extra events to be fired, // which might trigger UpdateSelected again, causing a loop. diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index 31ee8831..7bc90b47 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -47,12 +47,10 @@ std::unique_ptr<Screen> Settings::CreateScreen1() { std::unique_ptr<Screen> Settings::CreateScreen2() { - std::array<Screens::List::Applications, 4> applications {{ - {Symbols::shoe, "Steps", Apps::SettingSteps}, - {Symbols::clock, "Set date", Apps::SettingSetDate}, - {Symbols::clock, "Set time", Apps::SettingSetTime}, - {Symbols::batteryHalf, "Battery", Apps::BatteryInfo} - }}; + std::array<Screens::List::Applications, 4> applications {{{Symbols::shoe, "Steps", Apps::SettingSteps}, + {Symbols::clock, "Set date", Apps::SettingSetDate}, + {Symbols::clock, "Set time", Apps::SettingSetTime}, + {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}}}; return std::make_unique<Screens::List>(1, 3, app, settingsController, applications); } @@ -60,11 +58,11 @@ std::unique_ptr<Screen> Settings::CreateScreen2() { std::unique_ptr<Screen> Settings::CreateScreen3() { std::array<Screens::List::Applications, 4> applications {{ + {Symbols::clock, "Chimes", Apps::SettingChimes}, + {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, - {Symbols::list, "About", Apps::SysInfo}, - {Symbols::none, "None", Apps::None}, - {Symbols::none, "None", Apps::None} + {Symbols::list, "About", Apps::SysInfo} }}; return std::make_unique<Screens::List>(2, 3, app, settingsController, applications); -}
\ No newline at end of file +} diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index cc30fdc6..4d5ab4ce 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -21,6 +21,8 @@ namespace Pinetime { EnableSleeping, DisableSleeping, OnNewDay, + OnNewHour, + OnNewHalfHour, OnChargingEvent, OnPairing, SetOffAlarm, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 0eb07618..fc3e8405 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -344,18 +344,18 @@ void SystemTask::Work() { xTimerStart(dimTimer, 0); break; case Messages::StartFileTransfer: - NRF_LOG_INFO("[systemtask] FS Started"); + NRF_LOG_INFO("[systemtask] FS Started"); doNotGoToSleep = true; if (isSleeping && !isWakingUp) GoToRunning(); - //TODO add intent of fs access icon or something + // TODO add intent of fs access icon or something break; case Messages::StopFileTransfer: NRF_LOG_INFO("[systemtask] FS Stopped"); doNotGoToSleep = false; xTimerStart(dimTimer, 0); - //TODO add intent of fs access icon or something - break; + // TODO add intent of fs access icon or something + break; case Messages::OnTouchEvent: if (touchHandler.GetNewTouchInfo()) { touchHandler.UpdateLvglTouchPoint(); @@ -404,6 +404,26 @@ void SystemTask::Work() { // Remember we'll have to reset the counter next time we're awake stepCounterMustBeReset = true; break; + case Messages::OnNewHour: + using Pinetime::Controllers::AlarmController; + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (isSleeping && !isWakingUp) { + GoToRunning(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock); + } + motorController.RunForDuration(35); + } + break; + case Messages::OnNewHalfHour: + using Pinetime::Controllers::AlarmController; + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (isSleeping && !isWakingUp) { + GoToRunning(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock); + } + motorController.RunForDuration(35); + } + break; case Messages::OnChargingEvent: batteryController.ReadPowerState(); motorController.RunForDuration(15); @@ -458,10 +478,10 @@ void SystemTask::UpdateMotion() { return; } - if (isSleeping && !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) { + if (isSleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) || + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake))) { return; } - if (stepCounterMustBeReset) { motionSensor.ResetStepCounter(); stepCounterMustBeReset = false; @@ -471,7 +491,13 @@ void SystemTask::UpdateMotion() { motionController.IsSensorOk(motionSensor.IsOk()); motionController.Update(motionValues.x, motionValues.y, motionValues.z, motionValues.steps); - if (motionController.ShouldWakeUp(isSleeping)) { + + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) && + motionController.Should_RaiseWake(isSleeping)) { + GoToRunning(); + } + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) && + motionController.Should_ShakeWake(settingsController.GetShakeThreshold())) { GoToRunning(); } } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index e2e6de7f..abeffd2f 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -3,6 +3,7 @@ #include <memory> #include <FreeRTOS.h> +#include <queue.h> #include <task.h> #include <timers.h> #include <heartratetask/HeartRateTask.h> |