summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/buttonhandler/ButtonHandler.cpp2
-rw-r--r--src/buttonhandler/ButtonHandler.h2
-rw-r--r--src/components/datetime/DateTimeController.cpp19
-rw-r--r--src/components/datetime/DateTimeController.h2
-rw-r--r--src/components/motion/MotionController.cpp29
-rw-r--r--src/components/motion/MotionController.h10
-rw-r--r--src/components/settings/Settings.h36
-rw-r--r--src/displayapp/Apps.h4
-rw-r--r--src/displayapp/DisplayApp.cpp13
-rw-r--r--src/displayapp/Messages.h3
-rw-r--r--src/displayapp/screens/PineTimeStyle.cpp88
-rw-r--r--src/displayapp/screens/PineTimeStyle.h3
-rw-r--r--src/displayapp/screens/WatchFaceDigital.cpp103
-rw-r--r--src/displayapp/screens/WatchFaceDigital.h3
-rw-r--r--src/displayapp/screens/settings/SettingChimes.cpp100
-rw-r--r--src/displayapp/screens/settings/SettingChimes.h27
-rw-r--r--src/displayapp/screens/settings/SettingShakeThreshold.cpp137
-rw-r--r--src/displayapp/screens/settings/SettingShakeThreshold.h36
-rw-r--r--src/displayapp/screens/settings/SettingWakeUp.cpp8
-rw-r--r--src/displayapp/screens/settings/SettingWakeUp.h2
-rw-r--r--src/displayapp/screens/settings/Settings.cpp18
-rw-r--r--src/systemtask/Messages.h2
-rw-r--r--src/systemtask/SystemTask.cpp40
-rw-r--r--src/systemtask/SystemTask.h1
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>