aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy6
-rw-r--r--doc/contribute.md24
-rw-r--r--doc/gettingStarted/gettingStarted-1.0.md6
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/components/motion/MotionController.h6
-rw-r--r--src/components/settings/Settings.h10
-rw-r--r--src/displayapp/Apps.h4
-rw-r--r--src/displayapp/DisplayApp.cpp53
-rw-r--r--src/displayapp/DisplayApp.h2
-rw-r--r--src/displayapp/DisplayAppRecovery.cpp7
-rw-r--r--src/displayapp/fonts/jetbrains_mono_42.c258
-rw-r--r--src/displayapp/screens/ApplicationList.cpp4
-rw-r--r--src/displayapp/screens/Motion.cpp19
-rw-r--r--src/displayapp/screens/Motion.h2
-rw-r--r--src/displayapp/screens/Notifications.cpp10
-rw-r--r--src/displayapp/screens/Steps.cpp72
-rw-r--r--src/displayapp/screens/Steps.h39
-rw-r--r--src/displayapp/screens/settings/SettingSteps.cpp98
-rw-r--r--src/displayapp/screens/settings/SettingSteps.h32
-rw-r--r--src/displayapp/screens/settings/Settings.cpp10
-rw-r--r--src/libs/lv_conf.h1
-rw-r--r--src/logging/NrfLogger.cpp5
22 files changed, 605 insertions, 66 deletions
diff --git a/.clang-tidy b/.clang-tidy
index d6036802..8a7d38f0 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -22,5 +22,9 @@ Checks: '*,
-hicpp-no-assembler,
-hicpp-avoid-c-arrays,
-hicpp-uppercase-literal-suffix,
+ -hicpp-no-array-decay,
-cert-err58-cpp,
- -cert-err60-cpp' \ No newline at end of file
+ -cert-err60-cpp'
+CheckOptions:
+ - key: readability-function-cognitive-complexity.Threshold
+ value: 100 \ No newline at end of file
diff --git a/doc/contribute.md b/doc/contribute.md
index 7958eea1..09d20774 100644
--- a/doc/contribute.md
+++ b/doc/contribute.md
@@ -2,13 +2,13 @@
## Report bugs
You use your Pinetime and find a bug in the firmware? [Create an issue on Github](https://github.com/JF002/InfiniTime/issues) explaining the bug, how to reproduce it, the version of the firmware you use...
## Write and improve documentation
-Documentation might be incomplete, or not clear enough, and it is always possible to improve it with better wording, pictures, photo, video,...
+Documentation might be incomplete, or not clear enough, and it is always possible to improve it with better wording, pictures, photo, video,...
As the documentation is part of the source code, you can submit your improvements to the documentation by submitting a pull request (see below).
## Fix bugs, add functionalities and improve the code
You want to fix a bug, add a cool new functionality or improve the code? See *How to submit a pull request below*.
## Spread the word
-Pinetime is a cool open source project that deserves to be know. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open-source firmware for a smartwatch!
+The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open-source firmware for a smartwatch!
# How to submit a pull request ?
@@ -21,28 +21,28 @@ Pinetime is a cool open source project that deserves to be know. Talk about it a
- Write documentation related to your new feature is applicable;
- Create the pull-request and write a great description about it : what does your PR do, why, how,... Add pictures and video if possible;
- Wait for someone to review your PR and take part in the review process;
- - You PR will eventually be merged :)
+ - Your PR will eventually be merged :)
-Your contribution is more than welcome!
+Your contribution is more than welcome!
If you want to fix a bug, add a functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, **focus on only one topic, bug or feature**. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch per topic.
When your feature branch is ready, **make sure it actually works** and **do not forget to write documentation** about it if it's relevant.
-I **strongly discourage to create a PR containing modifications that haven't been tested**. If, for any reason, you cannot test your modifications but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedbacks about your code.
+I **strongly discourage to create a PR containing modifications that haven't been tested**. If, for any reason, you cannot test your modifications but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedback about your code.
Also, before submitting your PR, check the coding style of your code against the **coding conventions** detailed below. This project also provides [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy) configuration files. You can use them to ensure correct formatting of your code.
Do not forget to check the files you are going to commit and remove those who are not necessary (config files from your IDE, for example). Remove old comments, commented code,...
-Then, you can submit a pull-request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how is it designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of you work.
+Then, you can submit a pull-request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how is it designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of your work.
-Other contributors can post comments about the pull request, maybe ask for more info or adjustements in the code.
+Other contributors can post comments about the pull request, maybe ask for more info or adjustments in the code.
-Once the pull request is reviewed an accepted, it'll be merge in **develop** and will be released in the next release version of the firmware.
+Once the pull request is reviewed and accepted, it'll be merge in **develop** and will be released in the next release version of the firmware.
## Why all these rules?
-Reviewing pull-requests is a **very time consuming task** for the creator of this project ([JF002](https://github.com/JF002)) and for other contributors who take the time to review them. Every little thing you do to make their lifes easier will **increase the chances your PR will be merge quickly**.
+Reviewing pull-requests is a **very time consuming task** for the creator of this project ([JF002](https://github.com/JF002)) and for other contributors who take the time to review them. Every little thing you do to make their lives easier will **increase the chances your PR will be merge quickly**.
When reviewing PR, the author and contributors will first look at the **description**. If it's easy to understand what the PR does, why the modification is needed or interesting and how it's done, a good part of the work is already done : we understand the PR and its context.
@@ -58,12 +58,12 @@ It's totally normal for a PR to need some more work even after it was created, t
## Language
The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction.
-It's OK to include C code if this code comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK.
+It's OK to include C code if this code comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK.
## Coding style
-The most important rule to follow is to try to keep the code as easy to read and maintain as possible.
+The most important rule to follow is to try to keep the code as easy to read and maintain as possible.
- - **Identation** : 2 spaces, no tabulation
+ - **Indentation** : 2 spaces, no tabulation
- **Opening brace** at the end of the line
- **Naming** : Choose self-describing variable name
- **class** : PascalCase
diff --git a/doc/gettingStarted/gettingStarted-1.0.md b/doc/gettingStarted/gettingStarted-1.0.md
index 6b1a746a..2ac22b97 100644
--- a/doc/gettingStarted/gettingStarted-1.0.md
+++ b/doc/gettingStarted/gettingStarted-1.0.md
@@ -8,9 +8,9 @@ Basically, a **firmware** is just a software running on the embedded hardware of
**InfiniTime** is based on 3 distinct **firmwares**:
- **[InfiniTime](https://github.com/JF002/InfiniTime)** itself, this is the *application firmware* running on the PineTime. This is the main firmware which provides most of the functionalities you'll use on a daily basis : bluetooth low-energy (BLE) connectivity, applications, watchfaces,...
- **[The bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader)** is responsible for safely applying **updates** of the *application firmware*, reverting them in case of issues and load the recovery firmware when requested.
- - **The recovery firmware** is a specific *application firmware* than can be loaded by the bootloader on user request. This firmware can be useful in case of serious issue, when the main application firmware cannot perform an OTA update correctly. Currently, this recovery firmwarae is based on [InfiniTime 0.14.1](https://github.com/JF002/InfiniTime/releases/tag/0.14.1).
+ - **The recovery firmware** is a specific *application firmware* than can be loaded by the bootloader on user request. This firmware can be useful in case of serious issue, when the main application firmware cannot perform an OTA update correctly. Currently, this recovery firmware is based on [InfiniTime 0.14.1](https://github.com/JF002/InfiniTime/releases/tag/0.14.1).
-**OTA** and **DFU** refer to the update of the firmware over BLE (**B**luetooth **L**ow **E**nergy). **OTA** means **O**ver **T**he **A**ir, this is a functionality that allows the user to update the firmware how their device using a wireless communication like BLE. When we talk about **DFU** (**D**igital **F**irmware **U**pdate), we refer to the file format and protocol used to send the update of the firmware to the watch over-the-air. InfiniTime implement the (legacy) DFU protocol from Nordi Semiconductor (NRF).
+**OTA** and **DFU** refer to the update of the firmware over BLE (**B**luetooth **L**ow **E**nergy). **OTA** means **O**ver **T**he **A**ir, this is a functionality that allows the user to update the firmware how their device using a wireless communication like BLE. When we talk about **DFU** (**D**igital **F**irmware **U**pdate), we refer to the file format and protocol used to send the update of the firmware to the watch over-the-air. InfiniTime implement the (legacy) DFU protocol from Nordic Semiconductor (NRF).
## How to check the version of InfiniTime and the bootloader?
Since September 2020, all PineTimes (devkits or sealed) are flashed using the **[first iteration of the bootloader](https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.7)** and **[InfiniTime 0.7.1](https://github.com/JF002/InfiniTime/releases/tag/0.7.1)**. There was no recovery firmware at that time.
@@ -52,7 +52,7 @@ If your PineTime is currently running InfiniTime 0.7.1 and the old bootloader, w
Using the companion app of your choice, you'll need to apply the OTA procedure for these 3 firmwares in this sequence (failing to follow this specific order might temporarily or permanently brick your device):
- 1. Flash the latest version of InfiniTime. The file to upload is named **pinetime-mcuboot-app-dfu-x.y.z.zip. Here is the link to [InfiniTime 1.0](https://github.com/JF002/InfiniTime/releases/download/1.0.0/pinetime-mcuboot-app-dfu-1.0.0.zip.
+ 1. Flash the latest version of InfiniTime. The file to upload is named **pinetime-mcuboot-app-dfu-x.y.z.zip**. Here is the link to [InfiniTime 1.0](https://github.com/JF002/InfiniTime/releases/download/1.0.0/pinetime-mcuboot-app-dfu-1.0.0.zip).
2. Update the bootloader by applying the OTA procedure with the file named [**reloader-mcuboot.zip** from the repo of the bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader/releases/download/1.0.0/reloader-mcuboot.zip).
3. Install the recovery firmware by applying the OTA procedure with the file named [**pinetime-mcuboot-recovery-loader-dfu-0.14.1.zip** from the version 0.14.1 of InfiniTime](https://github.com/JF002/InfiniTime/releases/download/0.14.1/pinetime-mcuboot-recovery-loader-dfu-0.14.1.zip).
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9dacf378..acbfba18 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -406,6 +406,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/FlashLight.cpp
displayapp/screens/List.cpp
displayapp/screens/BatteryInfo.cpp
+ displayapp/screens/Steps.cpp
## Settings
displayapp/screens/settings/QuickSettings.cpp
@@ -414,6 +415,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/settings/SettingTimeFormat.cpp
displayapp/screens/settings/SettingWakeUp.cpp
displayapp/screens/settings/SettingDisplay.cpp
+ displayapp/screens/settings/SettingSteps.cpp
## Watch faces
displayapp/icons/bg_clock.c
@@ -466,6 +468,7 @@ list(APPEND SOURCE_FILES
displayapp/fonts/jetbrains_mono_extrabold_compressed.c
displayapp/fonts/jetbrains_mono_bold_20.c
displayapp/fonts/jetbrains_mono_76.c
+ displayapp/fonts/jetbrains_mono_42.c
displayapp/fonts/lv_font_sys_48.c
displayapp/lv_pinetime_theme.c
diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h
index bf644812..3a238262 100644
--- a/src/components/motion/MotionController.h
+++ b/src/components/motion/MotionController.h
@@ -8,13 +8,13 @@ namespace Pinetime {
public:
void Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps);
- uint16_t X() const {
+ int16_t X() const {
return x;
}
- uint16_t Y() const {
+ int16_t Y() const {
return y;
}
- uint16_t Z() const {
+ int16_t Z() const {
return z;
}
uint32_t NbSteps() const {
diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h
index 18c87fd4..4409425b 100644
--- a/src/components/settings/Settings.h
+++ b/src/components/settings/Settings.h
@@ -86,6 +86,14 @@ namespace Pinetime {
return settings.brightLevel;
};
+ void SetStepsGoal( uint32_t goal ) {
+ if ( goal != settings.stepsGoal )
+ settingsChanged = true;
+ settings.stepsGoal = goal;
+ };
+
+ uint32_t GetStepsGoal() const { return settings.stepsGoal; };
+
private:
Pinetime::Drivers::SpiNorFlash& spiNorFlash;
struct SettingsData {
@@ -95,7 +103,7 @@ namespace Pinetime {
uint8_t clockFace = 0;
- uint32_t stepsGoal = 1000;
+ uint32_t stepsGoal = 10000;
uint32_t screenTimeOut = 15000;
WakeUpMode wakeUpMode = WakeUpMode::None;
diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h
index 936a3ae8..09a20181 100644
--- a/src/displayapp/Apps.h
+++ b/src/displayapp/Apps.h
@@ -21,12 +21,14 @@ namespace Pinetime {
Navigation,
StopWatch,
Motion,
+ Steps,
QuickSettings,
Settings,
SettingWatchFace,
SettingTimeFormat,
SettingDisplay,
- SettingWakeUp
+ SettingWakeUp,
+ SettingSteps
};
}
}
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index 3a20c766..a6c4a3ec 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -25,6 +25,7 @@
#include "displayapp/screens/Twos.h"
#include "displayapp/screens/FlashLight.h"
#include "displayapp/screens/BatteryInfo.h"
+#include "displayapp/screens/Steps.h"
#include "drivers/Cst816s.h"
#include "drivers/St7789.h"
@@ -37,6 +38,7 @@
#include "displayapp/screens/settings/SettingTimeFormat.h"
#include "displayapp/screens/settings/SettingWakeUp.h"
#include "displayapp/screens/settings/SettingDisplay.h"
+#include "displayapp/screens/settings/SettingSteps.h"
using namespace Pinetime::Applications;
using namespace Pinetime::Applications::Display;
@@ -65,7 +67,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
notificationManager {notificationManager},
heartRateController {heartRateController},
settingsController {settingsController},
- motorController{motorController},
+ motorController {motorController},
motionController {motionController} {
msgQueue = xQueueCreate(queueSize, itemSize);
// Start clock when smartwatch boots
@@ -73,8 +75,9 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
}
void DisplayApp::Start() {
- if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle))
+ if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) {
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
+ }
}
void DisplayApp::Process(void* instance) {
@@ -85,7 +88,7 @@ void DisplayApp::Process(void* instance) {
// Send a dummy notification to unlock the lvgl display driver for the first iteration
xTaskNotifyGive(xTaskGetCurrentTaskHandle());
- while (1) {
+ while (true) {
app->Refresh();
}
}
@@ -213,7 +216,7 @@ void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction)
LoadApp(app, direction);
}
-void DisplayApp::returnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent) {
+void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent) {
returnToApp = app;
returnDirection = direction;
returnTouchEvent = touchEvent;
@@ -224,12 +227,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
SetFullRefresh(direction);
// default return to launcher
- returnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::SwipeDown);
switch (app) {
case Apps::Launcher:
currentScreen = std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, dateTimeController);
- returnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::None:
case Apps::Clock:
@@ -245,7 +248,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
case Apps::FirmwareValidation:
currentScreen = std::make_unique<Screens::FirmwareValidation>(this, validator);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::FirmwareUpdate:
currentScreen = std::make_unique<Screens::FirmwareUpdate>(this, bleController);
@@ -254,54 +257,58 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
case Apps::Notifications:
currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal);
- returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
+ ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break;
case Apps::NotificationsPreview:
currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview);
- returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
+ ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break;
// Settings
case Apps::QuickSettings:
- currentScreen =
- std::make_unique<Screens::QuickSettings>(this, batteryController, dateTimeController, brightnessController, motorController, settingsController);
- returnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft);
+ currentScreen = std::make_unique<Screens::QuickSettings>(
+ this, batteryController, dateTimeController, brightnessController, motorController, settingsController);
+ ReturnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft);
break;
case Apps::Settings:
currentScreen = std::make_unique<Screens::Settings>(this, settingsController);
- returnApp(Apps::QuickSettings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::QuickSettings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SettingWatchFace:
currentScreen = std::make_unique<Screens::SettingWatchFace>(this, settingsController);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SettingTimeFormat:
currentScreen = std::make_unique<Screens::SettingTimeFormat>(this, settingsController);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SettingWakeUp:
currentScreen = std::make_unique<Screens::SettingWakeUp>(this, settingsController);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ break;
+ case Apps::SettingSteps:
+ currentScreen = std::make_unique<Screens::SettingSteps>(this, settingsController);
+ 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);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SysInfo:
currentScreen =
std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog);
- returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
+ ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
//
case Apps::FlashLight:
currentScreen = std::make_unique<Screens::FlashLight>(this, systemTask, brightnessController);
- returnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None);
+ ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None);
break;
case Apps::StopWatch:
currentScreen = std::make_unique<Screens::StopWatch>(this);
@@ -327,6 +334,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
case Apps::Motion:
currentScreen = std::make_unique<Screens::Motion>(this, motionController);
break;
+ case Apps::Steps:
+ currentScreen = std::make_unique<Screens::Steps>(this, motionController, settingsController);
+ break;
}
currentApp = app;
}
@@ -349,8 +359,9 @@ TouchEvents DisplayApp::OnTouchEvent() {
if (info.isTouch) {
switch (info.gesture) {
case Pinetime::Drivers::Cst816S::Gestures::SingleTap:
- if (touchMode == TouchModes::Gestures)
+ if (touchMode == TouchModes::Gestures) {
lvgl.SetNewTapEvent(info.x, info.y);
+ }
return TouchEvents::Tap;
case Pinetime::Drivers::Cst816S::Gestures::LongPress:
return TouchEvents::LongTap;
diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h
index 75e52755..ffe27cf1 100644
--- a/src/displayapp/DisplayApp.h
+++ b/src/displayapp/DisplayApp.h
@@ -103,7 +103,7 @@ namespace Pinetime {
static void Process(void* instance);
void InitHw();
void Refresh();
- void returnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent);
+ void ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent);
void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction);
};
}
diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp
index 6db987fa..a132a47c 100644
--- a/src/displayapp/DisplayAppRecovery.cpp
+++ b/src/displayapp/DisplayAppRecovery.cpp
@@ -37,7 +37,7 @@ void DisplayApp::Process(void* instance) {
xTaskNotifyGive(xTaskGetCurrentTaskHandle());
app->InitHw();
- while (1) {
+ while (true) {
app->Refresh();
}
}
@@ -51,10 +51,11 @@ void DisplayApp::Refresh() {
if (xQueueReceive(msgQueue, &msg, 200)) {
switch (msg) {
case Display::Messages::UpdateBleConnection:
- if (bleController.IsConnected())
+ if (bleController.IsConnected()) {
DisplayLogo(colorBlue);
- else
+ } else {
DisplayLogo(colorWhite);
+ }
break;
case Display::Messages::BleFirmwareUpdateStarted:
DisplayLogo(colorGreen);
diff --git a/src/displayapp/fonts/jetbrains_mono_42.c b/src/displayapp/fonts/jetbrains_mono_42.c
new file mode 100644
index 00000000..6f25f5ab
--- /dev/null
+++ b/src/displayapp/fonts/jetbrains_mono_42.c
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Size: 42 px
+ * Bpp: 1
+ * Opts:
+ ******************************************************************************/
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+#include "lvgl.h"
+#else
+#include "lvgl/lvgl.h"
+#endif
+
+#ifndef JETBRAINS_MONO_42
+#define JETBRAINS_MONO_42 1
+#endif
+
+#if JETBRAINS_MONO_42
+
+/*-----------------
+ * BITMAPS
+ *----------------*/
+
+/*Store the image of the glyphs*/
+static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
+ /* U+0025 "%" */
+ 0x1f, 0x80, 0x7, 0x3f, 0xc0, 0xe, 0x7f, 0xe0,
+ 0x1c, 0xf0, 0xf0, 0x1c, 0xe0, 0x70, 0x38, 0xe0,
+ 0x70, 0x70, 0xe0, 0x70, 0x70, 0xe0, 0x70, 0xe0,
+ 0xe0, 0x71, 0xc0, 0xe0, 0x71, 0xc0, 0xf0, 0xf3,
+ 0x80, 0x7f, 0xe7, 0x0, 0x3f, 0xc7, 0x0, 0x1f,
+ 0x8e, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x3c, 0x0,
+ 0x0, 0x38, 0x0, 0x0, 0x71, 0xf8, 0x0, 0xe3,
+ 0xfc, 0x0, 0xe7, 0xfe, 0x1, 0xcf, 0xf, 0x3,
+ 0x8e, 0x7, 0x3, 0x8e, 0x7, 0x7, 0xe, 0x7,
+ 0xe, 0xe, 0x7, 0xe, 0xe, 0x7, 0x1c, 0xe,
+ 0x7, 0x38, 0xf, 0xf, 0x38, 0x7, 0xfe, 0x70,
+ 0x3, 0xfc, 0xe0, 0x1, 0xf8,
+
+ /* U+0030 "0" */
+ 0x3, 0xf8, 0x1, 0xff, 0xc0, 0xff, 0xfe, 0x1f,
+ 0x7, 0xc7, 0xc0, 0x7c, 0xf0, 0x7, 0xbc, 0x0,
+ 0x7f, 0x80, 0xf, 0xf0, 0x1, 0xfe, 0x0, 0x3f,
+ 0xc0, 0x7, 0xf8, 0x0, 0xff, 0xe, 0x1f, 0xe3,
+ 0xe3, 0xfc, 0x7c, 0x7f, 0x8f, 0x8f, 0xf0, 0xe1,
+ 0xfe, 0x0, 0x3f, 0xc0, 0x7, 0xf8, 0x0, 0xff,
+ 0x0, 0x1f, 0xe0, 0x3, 0xfc, 0x0, 0x7f, 0x80,
+ 0xf, 0xf0, 0x1, 0xef, 0x0, 0x79, 0xf0, 0x1f,
+ 0x1f, 0x7, 0xc3, 0xff, 0xf8, 0x1f, 0xfc, 0x0,
+ 0xfe, 0x0,
+
+ /* U+0031 "1" */
+ 0x3, 0xf0, 0x0, 0xfe, 0x0, 0x3f, 0xc0, 0x1f,
+ 0xf8, 0x7, 0xcf, 0x1, 0xf1, 0xe0, 0x3c, 0x3c,
+ 0x7, 0x7, 0x80, 0x80, 0xf0, 0x0, 0x1e, 0x0,
+ 0x3, 0xc0, 0x0, 0x78, 0x0, 0xf, 0x0, 0x1,
+ 0xe0, 0x0, 0x3c, 0x0, 0x7, 0x80, 0x0, 0xf0,
+ 0x0, 0x1e, 0x0, 0x3, 0xc0, 0x0, 0x78, 0x0,
+ 0xf, 0x0, 0x1, 0xe0, 0x0, 0x3c, 0x0, 0x7,
+ 0x80, 0x0, 0xf0, 0x0, 0x1e, 0x0, 0x3, 0xc0,
+ 0x0, 0x78, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xf8,
+
+ /* U+0032 "2" */
+ 0x3, 0xf8, 0x1, 0xff, 0xc0, 0x7f, 0xfe, 0x1f,
+ 0x7, 0xc7, 0xc0, 0x3c, 0xf0, 0x7, 0xbc, 0x0,
+ 0x7f, 0x80, 0xf, 0xf0, 0x1, 0xe0, 0x0, 0x3c,
+ 0x0, 0x7, 0x80, 0x1, 0xf0, 0x0, 0x3c, 0x0,
+ 0xf, 0x80, 0x1, 0xe0, 0x0, 0x7c, 0x0, 0x1f,
+ 0x0, 0x7, 0xc0, 0x1, 0xf0, 0x0, 0x7e, 0x0,
+ 0xf, 0x80, 0x3, 0xe0, 0x0, 0xf8, 0x0, 0x3e,
+ 0x0, 0xf, 0x80, 0x3, 0xe0, 0x0, 0xf8, 0x0,
+ 0x3e, 0x0, 0x7, 0xff, 0xfe, 0xff, 0xff, 0xdf,
+ 0xff, 0xf8,
+
+ /* U+0033 "3" */
+ 0x7f, 0xff, 0x8f, 0xff, 0xf1, 0xff, 0xfe, 0x0,
+ 0x3, 0xc0, 0x0, 0xf0, 0x0, 0x3c, 0x0, 0xf,
+ 0x0, 0x3, 0xc0, 0x0, 0xf0, 0x0, 0x3e, 0x0,
+ 0x7, 0x80, 0x1, 0xfe, 0x0, 0x3f, 0xf0, 0x7,
+ 0xff, 0x0, 0x3, 0xf0, 0x0, 0x1e, 0x0, 0x3,
+ 0xc0, 0x0, 0x3c, 0x0, 0x7, 0x80, 0x0, 0xf0,
+ 0x0, 0x1e, 0x0, 0x3, 0xfc, 0x0, 0x7f, 0x80,
+ 0xf, 0xf0, 0x1, 0xef, 0x0, 0x79, 0xf0, 0x1f,
+ 0x1f, 0x7, 0xc3, 0xff, 0xf0, 0x1f, 0xfc, 0x0,
+ 0xfe, 0x0,
+
+ /* U+0034 "4" */
+ 0x0, 0x1e, 0x0, 0xf, 0x80, 0x3, 0xc0, 0x1,
+ 0xe0, 0x0, 0x78, 0x0, 0x3c, 0x0, 0x1f, 0x0,
+ 0x7, 0x80, 0x3, 0xc0, 0x1, 0xf0, 0x0, 0x78,
+ 0x0, 0x3e, 0x0, 0xf, 0x0, 0x7, 0x80, 0xf3,
+ 0xe0, 0x3c, 0xf0, 0xf, 0x7c, 0x3, 0xde, 0x0,
+ 0xff, 0x0, 0x3f, 0xc0, 0xf, 0xf0, 0x3, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x3,
+ 0xc0, 0x0, 0xf0, 0x0, 0x3c, 0x0, 0xf, 0x0,
+ 0x3, 0xc0, 0x0, 0xf0, 0x0, 0x3c,
+
+ /* U+0035 "5" */
+ 0x7f, 0xff, 0x9f, 0xff, 0xe7, 0xff, 0xf9, 0xe0,
+ 0x0, 0x78, 0x0, 0x1e, 0x0, 0x7, 0x80, 0x1,
+ 0xe0, 0x0, 0x78, 0x0, 0x1e, 0x0, 0x7, 0x8f,
+ 0x81, 0xef, 0xf8, 0x7f, 0xff, 0x1f, 0x87, 0xe7,
+ 0xc0, 0x79, 0xe0, 0x1f, 0x0, 0x3, 0xc0, 0x0,
+ 0xf0, 0x0, 0x3c, 0x0, 0xf, 0x0, 0x3, 0xc0,
+ 0x0, 0xf0, 0x0, 0x3c, 0x0, 0xf, 0xf0, 0x3,
+ 0xde, 0x1, 0xe7, 0x80, 0x78, 0xf8, 0x7e, 0x3f,
+ 0xff, 0x3, 0xff, 0x80, 0x3f, 0x0,
+
+ /* U+0036 "6" */
+ 0x0, 0x3c, 0x0, 0x7, 0x80, 0x0, 0x78, 0x0,
+ 0xf, 0x0, 0x1, 0xe0, 0x0, 0x1e, 0x0, 0x3,
+ 0xc0, 0x0, 0x3c, 0x0, 0x7, 0x80, 0x0, 0x70,
+ 0x0, 0xf, 0x0, 0x1, 0xe7, 0xc0, 0x1f, 0xff,
+ 0x3, 0xff, 0xfc, 0x3f, 0xf, 0xc7, 0xc0, 0x3e,
+ 0x78, 0x1, 0xe7, 0x80, 0x1f, 0xf0, 0x0, 0xff,
+ 0x0, 0xf, 0xf0, 0x0, 0xff, 0x0, 0xf, 0xf0,
+ 0x0, 0xff, 0x0, 0xf, 0xf8, 0x1, 0xe7, 0x80,
+ 0x1e, 0x7c, 0x3, 0xe3, 0xf0, 0xfc, 0x1f, 0xff,
+ 0x80, 0xff, 0xf0, 0x1, 0xf8, 0x0,
+
+ /* U+0037 "7" */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0, 0x1e, 0xf0, 0x1, 0xef, 0x0, 0x1e, 0xf0,
+ 0x3, 0xcf, 0x0, 0x3c, 0x0, 0x3, 0x80, 0x0,
+ 0x78, 0x0, 0x7, 0x80, 0x0, 0xf0, 0x0, 0xf,
+ 0x0, 0x0, 0xf0, 0x0, 0x1e, 0x0, 0x1, 0xe0,
+ 0x0, 0x3c, 0x0, 0x3, 0xc0, 0x0, 0x3c, 0x0,
+ 0x7, 0x80, 0x0, 0x78, 0x0, 0x7, 0x80, 0x0,
+ 0xf0, 0x0, 0xf, 0x0, 0x1, 0xe0, 0x0, 0x1e,
+ 0x0, 0x1, 0xe0, 0x0, 0x3c, 0x0, 0x3, 0xc0,
+ 0x0, 0x7c, 0x0, 0x7, 0x80, 0x0,
+
+ /* U+0038 "8" */
+ 0x1, 0xf8, 0x0, 0xff, 0xf0, 0x1f, 0xff, 0x83,
+ 0xf0, 0xfc, 0x3c, 0x3, 0xc7, 0xc0, 0x3e, 0x78,
+ 0x1, 0xe7, 0x80, 0x1e, 0x78, 0x1, 0xe7, 0x80,
+ 0x1e, 0x3c, 0x3, 0xc3, 0xe0, 0x7c, 0x1f, 0xf,
+ 0x80, 0xff, 0xf0, 0x3, 0xfc, 0x0, 0x7f, 0xe0,
+ 0xf, 0xff, 0x3, 0xe0, 0x7c, 0x3c, 0x3, 0xc7,
+ 0x80, 0x1e, 0xf0, 0x0, 0xff, 0x0, 0xf, 0xf0,
+ 0x0, 0xff, 0x0, 0xf, 0xf0, 0x0, 0xff, 0x80,
+ 0x1f, 0x7c, 0x3, 0xe7, 0xe0, 0x7e, 0x3f, 0xff,
+ 0xc0, 0xff, 0xf0, 0x3, 0xfc, 0x0,
+
+ /* U+0039 "9" */
+ 0x3, 0xf8, 0x0, 0xff, 0xf0, 0x1f, 0xff, 0x83,
+ 0xe0, 0xfc, 0x7c, 0x3, 0xe7, 0x80, 0x1e, 0xf8,
+ 0x1, 0xff, 0x0, 0xf, 0xf0, 0x0, 0xff, 0x0,
+ 0xf, 0xf0, 0x0, 0xff, 0x0, 0xf, 0xf8, 0x1,
+ 0xf7, 0x80, 0x1e, 0x7c, 0x3, 0xe3, 0xe0, 0x7e,
+ 0x3f, 0xff, 0xc1, 0xff, 0xfc, 0x7, 0xe7, 0x80,
+ 0x0, 0xf8, 0x0, 0xf, 0x0, 0x1, 0xe0, 0x0,
+ 0x1e, 0x0, 0x3, 0xc0, 0x0, 0x3c, 0x0, 0x7,
+ 0x80, 0x0, 0xf8, 0x0, 0xf, 0x0, 0x1, 0xe0,
+ 0x0, 0x1e, 0x0, 0x3, 0xc0, 0x0,
+
+ /* U+003A ":" */
+ 0x7d, 0xff, 0xff, 0xff, 0xef, 0x80, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
+ 0xf7, 0xff, 0xff, 0xff, 0xbe
+};
+
+
+/*---------------------
+ * GLYPH DESCRIPTION
+ *--------------------*/
+
+static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
+ {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
+ {.bitmap_index = 0, .adv_w = 403, .box_w = 24, .box_h = 31, .ofs_x = 1, .ofs_y = 0},
+ {.bitmap_index = 93, .adv_w = 403, .box_w = 19, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 167, .adv_w = 403, .box_w = 19, .box_h = 31, .ofs_x = 4, .ofs_y = 0},
+ {.bitmap_index = 241, .adv_w = 403, .box_w = 19, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 315, .adv_w = 403, .box_w = 19, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 389, .adv_w = 403, .box_w = 18, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 459, .adv_w = 403, .box_w = 18, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 529, .adv_w = 403, .box_w = 20, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 607, .adv_w = 403, .box_w = 20, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 685, .adv_w = 403, .box_w = 20, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 763, .adv_w = 403, .box_w = 20, .box_h = 31, .ofs_x = 3, .ofs_y = 0},
+ {.bitmap_index = 841, .adv_w = 403, .box_w = 7, .box_h = 24, .ofs_x = 9, .ofs_y = 0}
+};
+
+/*---------------------
+ * CHARACTER MAPPING
+ *--------------------*/
+
+
+
+/*Collect the unicode lists and glyph_id offsets*/
+static const lv_font_fmt_txt_cmap_t cmaps[] =
+{
+ {
+ .range_start = 37, .range_length = 1, .glyph_id_start = 1,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY
+ },
+ {
+ .range_start = 48, .range_length = 11, .glyph_id_start = 2,
+ .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY
+ }
+};
+
+
+
+/*--------------------
+ * ALL CUSTOM DATA
+ *--------------------*/
+
+#if LV_VERSION_CHECK(8, 0, 0)
+/*Store all the custom data of the font*/
+static lv_font_fmt_txt_glyph_cache_t cache;
+static const lv_font_fmt_txt_dsc_t font_dsc = {
+#else
+static lv_font_fmt_txt_dsc_t font_dsc = {
+#endif
+ .glyph_bitmap = glyph_bitmap,
+ .glyph_dsc = glyph_dsc,
+ .cmaps = cmaps,
+ .kern_dsc = NULL,
+ .kern_scale = 0,
+ .cmap_num = 2,
+ .bpp = 1,
+ .kern_classes = 0,
+ .bitmap_format = 0,
+#if LV_VERSION_CHECK(8, 0, 0)
+ .cache = &cache
+#endif
+};
+
+
+/*-----------------
+ * PUBLIC FONT
+ *----------------*/
+
+/*Initialize a public general font descriptor*/
+#if LV_VERSION_CHECK(8, 0, 0)
+const lv_font_t jetbrains_mono_42 = {
+#else
+lv_font_t jetbrains_mono_42 = {
+#endif
+ .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/
+ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/
+ .line_height = 31, /*The maximum line height required by the font*/
+ .base_line = 0, /*Baseline measured from the bottom of the line*/
+#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
+ .subpx = LV_FONT_SUBPX_NONE,
+#endif
+#if LV_VERSION_CHECK(7, 4, 0)
+ .underline_position = -7,
+ .underline_thickness = 2,
+#endif
+ .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
+};
+
+
+
+#endif /*#if JETBRAINS_MONO_42*/
+
diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp
index 7e38b3f4..1eb36999 100644
--- a/src/displayapp/screens/ApplicationList.cpp
+++ b/src/displayapp/screens/ApplicationList.cpp
@@ -49,7 +49,7 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen1() {
{Symbols::stopWatch, Apps::StopWatch},
{Symbols::music, Apps::Music},
{Symbols::map, Apps::Navigation},
- {Symbols::shoe, Apps::Motion},
+ {Symbols::shoe, Apps::Steps},
{Symbols::heartBeat, Apps::HeartRate},
{"", Apps::None},
}};
@@ -62,7 +62,7 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
{Symbols::paintbrush, Apps::Paint},
{Symbols::paddle, Apps::Paddle},
{"2", Apps::Twos},
- {"", Apps::None},
+ {"M", Apps::Motion},
{"", Apps::None},
{"", Apps::None},
}};
diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp
index e7196267..a8bb3c18 100644
--- a/src/displayapp/screens/Motion.cpp
+++ b/src/displayapp/screens/Motion.cpp
@@ -3,8 +3,6 @@
#include "../DisplayApp.h"
using namespace Pinetime::Applications::Screens;
-extern lv_font_t jetbrains_mono_extrabold_compressed;
-extern lv_font_t jetbrains_mono_bold_20;
Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionController& motionController)
: Screen(app), motionController {motionController} {
@@ -29,13 +27,16 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr
lv_chart_init_points(chart, ser3, 0);
lv_chart_refresh(chart); /*Required after direct set*/
+ label = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_text_fmt(label, "X #FF0000 %d# Y #008000 %d# Z #FFFF00 %d#", 0, 0, 0);
+ lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);
+ lv_label_set_recolor(label, true);
+
labelStep = lv_label_create(lv_scr_act(), NULL);
lv_obj_align(labelStep, chart, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
- lv_label_set_text(labelStep, "Steps: ");
+ lv_label_set_text(labelStep, "Steps ---");
- labelStepValue = lv_label_create(lv_scr_act(), NULL);
- lv_obj_align(labelStepValue, labelStep, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
- lv_label_set_text(labelStepValue, "-");
}
Motion::~Motion() {
@@ -47,8 +48,10 @@ bool Motion::Refresh() {
lv_chart_set_next(chart, ser2, motionController.Y());
lv_chart_set_next(chart, ser3, motionController.Z());
- snprintf(nbStepsBuffer, nbStepsBufferSize, "%lu", motionController.NbSteps());
- lv_label_set_text(labelStepValue, nbStepsBuffer);
+ lv_label_set_text_fmt(labelStep, "Steps %lu", motionController.NbSteps());
+
+ lv_label_set_text_fmt(label, "X #FF0000 %d# Y #008000 %d# Z #FFFF00 %d#", motionController.X() / 0x10, motionController.Y() / 0x10, motionController.Z() / 0x10);
+ lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);
return running;
}
diff --git a/src/displayapp/screens/Motion.h b/src/displayapp/screens/Motion.h
index 11007866..132b20ec 100644
--- a/src/displayapp/screens/Motion.h
+++ b/src/displayapp/screens/Motion.h
@@ -26,9 +26,9 @@ namespace Pinetime {
lv_chart_series_t* ser1;
lv_chart_series_t* ser2;
lv_chart_series_t* ser3;
+ lv_obj_t* label;
lv_obj_t* labelStep;
- lv_obj_t* labelStepValue;
static constexpr uint8_t nbStepsBufferSize = 9;
char nbStepsBuffer[nbStepsBufferSize + 1];
bool running = true;
diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp
index f0fd2f66..1f113750 100644
--- a/src/displayapp/screens/Notifications.cpp
+++ b/src/displayapp/screens/Notifications.cpp
@@ -176,7 +176,17 @@ Notifications::NotificationItem::NotificationItem(const char* title,
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x888888));
if (title == nullptr)
title = "Notification";
+ char* pchar;
+ pchar = strchr(title, '\n');
+ while (pchar != nullptr) {
+ *pchar = ' ';
+ pchar =
+ pchar = strchr(pchar + 1, '\n');
+ }
lv_label_set_text(alert_type, title);
+ lv_label_set_long_mode(alert_type, LV_LABEL_LONG_SROLL_CIRC);
+ lv_label_set_anim_speed(alert_type, 3);
+ lv_obj_set_width(alert_type, 180);
lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16);
/////////
diff --git a/src/displayapp/screens/Steps.cpp b/src/displayapp/screens/Steps.cpp
new file mode 100644
index 00000000..b485c975
--- /dev/null
+++ b/src/displayapp/screens/Steps.cpp
@@ -0,0 +1,72 @@
+#include "Steps.h"
+#include <lvgl/lvgl.h>
+#include "../DisplayApp.h"
+#include "Symbols.h"
+
+using namespace Pinetime::Applications::Screens;
+
+Steps::Steps(
+ Pinetime::Applications::DisplayApp *app,
+ Controllers::MotionController& motionController,
+ Controllers::Settings &settingsController)
+ : Screen(app),
+ motionController{motionController},
+ settingsController{settingsController} {
+
+ stepsArc = lv_arc_create(lv_scr_act(), nullptr);
+
+ lv_obj_set_style_local_bg_opa(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
+ lv_obj_set_style_local_border_width(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 2);
+ lv_obj_set_style_local_radius(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
+ lv_obj_set_style_local_line_color(stepsArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0x0000FF));
+ lv_arc_set_end_angle(stepsArc, 200);
+ lv_obj_set_size(stepsArc, 220, 220);
+ lv_arc_set_range(stepsArc, 0, 500);
+ lv_obj_align(stepsArc, nullptr, LV_ALIGN_CENTER, 0, 0);
+
+ stepsCount = motionController.NbSteps();
+
+ lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal()));
+
+ lSteps = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
+ lv_obj_set_style_local_text_font(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
+ lv_label_set_text_fmt(lSteps, "%li", stepsCount);
+ lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20);
+
+ lv_obj_t * lstepsL = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(lstepsL, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
+ lv_label_set_text_static(lstepsL, "Steps");
+ lv_obj_align(lstepsL, lSteps, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+
+ lv_obj_t * lstepsGoal = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_color(lstepsGoal, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN);
+ lv_label_set_text_fmt(lstepsGoal,"Goal\n%i", settingsController.GetStepsGoal());
+ lv_label_set_align(lstepsGoal, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(lstepsGoal, lSteps, LV_ALIGN_OUT_BOTTOM_MID, 0, 60);
+
+ lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
+ 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_static(backgroundLabel, "");
+
+}
+
+Steps::~Steps() {
+ lv_obj_clean(lv_scr_act());
+}
+
+bool Steps::Refresh() {
+
+ stepsCount = motionController.NbSteps();
+
+ lv_label_set_text_fmt(lSteps,"%li", stepsCount);
+ lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20);
+
+ lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal()));
+
+ return running;
+}
+
+
diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h
new file mode 100644
index 00000000..9c135e26
--- /dev/null
+++ b/src/displayapp/screens/Steps.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <cstdint>
+#include <lvgl/lvgl.h>
+#include "Screen.h"
+#include <components/motion/MotionController.h>
+
+namespace Pinetime {
+
+ namespace Controllers {
+ class Settings;
+ }
+
+ namespace Applications {
+ namespace Screens {
+
+ class Steps : public Screen {
+ public:
+ Steps(DisplayApp* app, Controllers::MotionController& motionController, Controllers::Settings &settingsController);
+ ~Steps() override;
+
+ bool Refresh() override;
+
+
+ private:
+
+ Controllers::MotionController& motionController;
+ Controllers::Settings& settingsController;
+
+ lv_obj_t * lSteps;
+ lv_obj_t * lStepsIcon;
+ lv_obj_t * stepsArc;
+
+ uint32_t stepsCount;
+
+ };
+ }
+ }
+}
diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp
new file mode 100644
index 00000000..b7c024f1
--- /dev/null
+++ b/src/displayapp/screens/settings/SettingSteps.cpp
@@ -0,0 +1,98 @@
+#include "SettingSteps.h"
+#include <lvgl/lvgl.h>
+#include "displayapp/DisplayApp.h"
+#include "displayapp/screens/Symbols.h"
+
+using namespace Pinetime::Applications::Screens;
+
+namespace {
+ static void event_handler(lv_obj_t * obj, lv_event_t event) {
+ SettingSteps* screen = static_cast<SettingSteps *>(obj->user_data);
+ screen->UpdateSelected(obj, event);
+ }
+}
+
+SettingSteps::SettingSteps(
+ 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_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
+ 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, 30, 60);
+ lv_obj_set_width(container1, LV_HOR_RES - 50);
+ lv_obj_set_height(container1, LV_VER_RES - 60);
+ lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
+
+ lv_obj_t * title = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_text_static(title,"Daily steps goal");
+ lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15);
+
+ lv_obj_t * icon = lv_label_create(lv_scr_act(), NULL);
+ 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::shoe);
+ lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
+
+
+ stepValue = lv_label_create(lv_scr_act(), NULL);
+ lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
+ lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
+ lv_label_set_align(stepValue, LV_LABEL_ALIGN_CENTER);
+ lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
+
+ btnPlus = lv_btn_create(lv_scr_act(), NULL);
+ btnPlus->user_data = this;
+ lv_obj_set_size(btnPlus, 80, 50);
+ lv_obj_align(btnPlus, lv_scr_act(), LV_ALIGN_CENTER, 55, 80);
+ lv_obj_set_style_local_value_str(btnPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
+ lv_obj_set_event_cb(btnPlus, event_handler);
+
+ btnMinus = lv_btn_create(lv_scr_act(), NULL);
+ btnMinus->user_data = this;
+ lv_obj_set_size(btnMinus, 80, 50);
+ lv_obj_set_event_cb(btnMinus, event_handler);
+ lv_obj_align(btnMinus, lv_scr_act(), LV_ALIGN_CENTER, -55, 80);
+ lv_obj_set_style_local_value_str(btnMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
+
+}
+
+SettingSteps::~SettingSteps() {
+ lv_obj_clean(lv_scr_act());
+ settingsController.SaveSettings();
+}
+
+bool SettingSteps::Refresh() {
+ return running;
+}
+
+
+void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) {
+ uint32_t value = settingsController.GetStepsGoal();
+ if(object == btnPlus && (event == LV_EVENT_PRESSED)) {
+ value += 1000;
+ if ( value <= 500000 ) {
+ settingsController.SetStepsGoal(value);
+ lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
+ lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
+ }
+ }
+
+ if(object == btnMinus && (event == LV_EVENT_PRESSED)) {
+ value -= 1000;
+ if ( value >= 1000 ) {
+ settingsController.SetStepsGoal(value);
+ lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
+ lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/displayapp/screens/settings/SettingSteps.h b/src/displayapp/screens/settings/SettingSteps.h
new file mode 100644
index 00000000..0a4c2056
--- /dev/null
+++ b/src/displayapp/screens/settings/SettingSteps.h
@@ -0,0 +1,32 @@
+#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 SettingSteps : public Screen{
+ public:
+ SettingSteps(DisplayApp* app, Pinetime::Controllers::Settings &settingsController);
+ ~SettingSteps() override;
+
+ bool Refresh() override;
+ void UpdateSelected(lv_obj_t *object, lv_event_t event);
+
+ private:
+
+ Controllers::Settings& settingsController;
+
+ lv_obj_t * stepValue;
+ lv_obj_t * btnPlus;
+ lv_obj_t * btnMinus;
+
+ };
+ }
+ }
+}
diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp
index e24be3d7..2c72c832 100644
--- a/src/displayapp/screens/settings/Settings.cpp
+++ b/src/displayapp/screens/settings/Settings.cpp
@@ -44,9 +44,7 @@ std::unique_ptr<Screen> Settings::CreateScreen1() {
{Symbols::clock, "Wake Up", Apps::SettingWakeUp},
{Symbols::clock, "Time format", Apps::SettingTimeFormat},
{Symbols::clock, "Watch face", Apps::SettingWatchFace},
- }
-
- };
+ }};
return std::unique_ptr<Screen>(new Screens::List(0, 2, app, settingsController, applications));
}
@@ -54,13 +52,11 @@ 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::batteryHalf, "Battery", Apps::BatteryInfo},
{Symbols::check, "Firmware", Apps::FirmwareValidation},
{Symbols::list, "About", Apps::SysInfo},
- {"", "", Apps::None},
- }
-
- };
+ }};
return std::unique_ptr<Screen>(new Screens::List(1, 2, app, settingsController, applications));
}
diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h
index 2a5b6057..761baba2 100644
--- a/src/libs/lv_conf.h
+++ b/src/libs/lv_conf.h
@@ -415,6 +415,7 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(jetbrains_mono_bold_20) \
LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed) \
+ LV_FONT_DECLARE(jetbrains_mono_42) \
LV_FONT_DECLARE(jetbrains_mono_76) \
LV_FONT_DECLARE(lv_font_sys_48)
diff --git a/src/logging/NrfLogger.cpp b/src/logging/NrfLogger.cpp
index 70a00e61..1c048f2c 100644
--- a/src/logging/NrfLogger.cpp
+++ b/src/logging/NrfLogger.cpp
@@ -12,8 +12,9 @@ void NrfLogger::Init() {
NRF_LOG_DEFAULT_BACKENDS_INIT();
- if (pdPASS != xTaskCreate(NrfLogger::Process, "LOGGER", 200, this, 0, &m_logger_thread))
+ if (pdPASS != xTaskCreate(NrfLogger::Process, "LOGGER", 200, this, 0, &m_logger_thread)) {
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
+ }
}
void NrfLogger::Process(void*) {
@@ -21,7 +22,7 @@ void NrfLogger::Process(void*) {
// Suppress endless loop diagnostic
#pragma clang diagnostic push
#pragma ide diagnostic ignored "EndlessLoop"
- while (1) {
+ while (true) {
NRF_LOG_FLUSH();
vTaskDelay(100); // Not good for power consumption, it will wake up every 100ms...
}