summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt12
-rw-r--r--README.md4
-rwxr-xr-xcmake-nRF5x/CMake_nRF5x.cmake7
-rw-r--r--doc/buildAndProgram.md15
-rw-r--r--src/CMakeLists.txt26
-rw-r--r--src/displayapp/Apps.h2
-rw-r--r--src/displayapp/DisplayApp.cpp40
-rw-r--r--src/displayapp/DisplayAppRecovery.cpp6
-rw-r--r--src/displayapp/fonts/Readme.md2
-rw-r--r--src/displayapp/fonts/jetbrains_mono_bold_20.c105
-rw-r--r--src/displayapp/screens/ApplicationList.cpp14
-rw-r--r--src/displayapp/screens/Clock.cpp8
-rw-r--r--src/displayapp/screens/Notifications.cpp16
-rw-r--r--src/displayapp/screens/StopWatch.cpp210
-rw-r--r--src/displayapp/screens/StopWatch.h86
-rw-r--r--src/displayapp/screens/Symbols.h3
-rw-r--r--src/displayapp/screens/SystemInfo.cpp6
-rw-r--r--src/displayapp/screens/WatchFaceAnalog.cpp2
m---------src/libs/lvgl0
-rw-r--r--src/main.cpp6
-rw-r--r--src/recoveryLoader.cpp6
-rw-r--r--src/systemtask/SystemTask.cpp8
22 files changed, 456 insertions, 128 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 54ef9fa..f2edbc4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,15 @@
cmake_minimum_required(VERSION 3.10)
-project(pinetime VERSION 0.14.1 LANGUAGES C CXX ASM)
+project(pinetime VERSION 0.15.0 LANGUAGES C CXX ASM)
+
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_CXX_STANDARD 14)
+
+# set(CMAKE_GENERATOR "Unix Makefiles")
+set(CMAKE_C_EXTENSIONS OFF)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(NRF_TARGET "nrf52")
diff --git a/README.md b/README.md
index c0fb5cb..86db9eb 100644
--- a/README.md
+++ b/README.md
@@ -44,9 +44,11 @@ As of now, here is the list of achievements of this project:
* Notification (displays the last notification received)
* Paddle (single player pong-like game)
* Two (2048 clone game)
- - Supported by 2 companion apps (development is in progress):
+ * Stopwatch (with all the necessary functions such as play, pause, lap, stop)
+ - Supported by 3 companion apps (development is in progress):
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/) (on Android)
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux)
+ * [Siglo](https://github.com/alexr4535/siglo) (on Linux)
* **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY)
- **[Experimental]** OTA (Over-the-air) update via BLE
- **[Experimental]** Bootloader based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
diff --git a/cmake-nRF5x/CMake_nRF5x.cmake b/cmake-nRF5x/CMake_nRF5x.cmake
index c1785d3..ead7b9f 100755
--- a/cmake-nRF5x/CMake_nRF5x.cmake
+++ b/cmake-nRF5x/CMake_nRF5x.cmake
@@ -36,9 +36,6 @@ macro(nRF5x_setup)
set(CMAKE_OSX_SYSROOT "/")
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
- # language standard/version settings
- set(CMAKE_C_STANDARD 99)
- set(CMAKE_CXX_STANDARD 11)
# CPU specyfic settings
if (NRF_TARGET MATCHES "nrf51")
@@ -86,8 +83,8 @@ macro(nRF5x_setup)
set(CMAKE_CXX_FLAGS "${COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g3")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
- set(CMAKE_ASM_FLAGS "-MP -MD -std=c99 -x assembler-with-cpp")
- set(CMAKE_EXE_LINKER_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} ${CPU_FLAGS} -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm")
+ set(CMAKE_ASM_FLAGS "-MP -MD -x assembler-with-cpp")
+ set(CMAKE_EXE_LINKER_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} ${CPU_FLAGS} -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm")
# note: we must override the default cmake linker flags so that CMAKE_C_FLAGS are not added implicitly
set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_COMPILER} <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_C_COMPILER} <LINK_FLAGS> <OBJECTS> -lstdc++ -o <TARGET> <LINK_LIBRARIES>")
diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md
index 484916a..cf34909 100644
--- a/doc/buildAndProgram.md
+++ b/doc/buildAndProgram.md
@@ -22,18 +22,23 @@ CMake configures the project according to variables you specify the command line
**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`-DARM_NONE_EABI_TOOLCHAIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2020-q2-update/`|
**NRF5_SDK_PATH**|path to the NRF52 SDK|`-DNRF5_SDK_PATH=/home/jf/nrf52/Pinetime/sdk`|
**USE_JLINK, USE_GDB_CLIENT and USE_OPENOCD**|Enable *JLink* mode, *GDB Client* (Black Magic Probe) mode or *OpenOCD* mode (set the one you want to use to `1`)|`-DUSE_JLINK=1`
-**CMAKE_BUILD_TYPE**| Build type (Release or Debug). Release is applied by default if this variable is not specified.|`-DCMAKE_BUILD_TYPE=Debug`
+**CMAKE_BUILD_TYPE (\*)**| Build type (Release or Debug). Release is applied by default if this variable is not specified.|`-DCMAKE_BUILD_TYPE=Debug`
**NRFJPROG**|Path to the NRFJProg executable. Used only if `USE_JLINK` is 1.|`-DNRFJPROG=/opt/nrfjprog/nrfjprog`
**GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb`
**GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0`
-**BUILD_DFU (\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-BUILD_DFU=1`
+**BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-BUILD_DFU=1`
-####(*) Note about **BUILD_DFU**:
+####(**) Note about **CMAKE_BUILD_TYPE**:
+By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime.
+
+The *Debug* mode disables all optimizations, which makes the code easier to debug. However, the binary size will likely be too big to fit in the internal flash memory. If you want to build and debug a *Debug* binary, you'll need to disable some parts of the code. For example, the icons for the **Navigation** app use a lot of memory space. You can comment the content of `m_iconMap` in the [Navigation](https://github.com/JF002/InfiniTime/blob/develop/src/displayapp/screens/Navigation.h#L148) application to free some memory.
+
+####(**) Note about **BUILD_DFU**:
DFU files are the files you'll need to install your build of InfiniTime using OTA (over-the-air) mecanism. To generate the DFU file, the Python tool [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) is needed on your system. Check that this tool is properly installed before enabling this option.
#### CMake command line for JLink
```
-cmake -DCMAKE_BUILD_TYPE=Debug -DARM_NONE_EABI_TOOLCHAIN_PATH=... -DNRF5_SDK_PATH=... -DUSE_JLINK=1 -DNRFJPROG=... ../
+cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=... -DNRF5_SDK_PATH=... -DUSE_JLINK=1 -DNRFJPROG=... ../
```
#### CMake command line for GDB Client (Black Magic Probe)
@@ -57,7 +62,7 @@ During the project generation, CMake created the following targets:
- **pinetime-mcuboot-recovery** : build pinetime-recovery with bootloader support
- **pinetime-mcuboot-recovery-loader** : build pinetime-recovery-loader with bootloader support
-If you just want to build the project and run it on the Pinetime, using *pinetime-app* is recommanded. See [this page](../bootloader/README.md) for more info about bootloader support.
+If you just want to build the project and run it on the Pinetime, using *pinetime-app* is recommended. See [this page](../bootloader/README.md) for more info about bootloader support.
Build:
```
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ac53354..1183bb3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,16 +3,6 @@ cmake_minimum_required(VERSION 3.10)
project(pinetime-app C CXX ASM)
-set(CMAKE_C_STANDARD 99)
-set(CMAKE_CXX_STANDARD 14)
-
-# set(CMAKE_GENERATOR "Unix Makefiles")
-set(CMAKE_C_EXTENSIONS OFF)
-set(CMAKE_C_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-
# define some variables just for this example to determine file locations
set(NRF_PROJECT_NAME pinetime-app)
set(NRF_BOARD pca10040)
@@ -485,6 +475,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/Meter.cpp
displayapp/screens/InfiniPaint.cpp
displayapp/screens/Paddle.cpp
+ displayapp/screens/StopWatch.cpp
displayapp/screens/BatteryIcon.cpp
displayapp/screens/BleIcon.cpp
displayapp/screens/NotificationIcon.cpp
@@ -644,6 +635,7 @@ set(INCLUDE_FILES
displayapp/screens/Tile.h
displayapp/screens/Meter.h
displayapp/screens/InfiniPaint.h
+ displayapp/screens/StopWatch.h
displayapp/screens/Paddle.h
displayapp/screens/DropDownDemo.h
displayapp/screens/BatteryIcon.h
@@ -873,8 +865,6 @@ target_compile_options(${EXECUTABLE_NAME} PUBLIC
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_NAME}
@@ -905,8 +895,6 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
@@ -944,8 +932,6 @@ target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
@@ -975,9 +961,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES
SUFFIX ".out"
- LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
+ LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map"
)
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
@@ -1019,8 +1003,6 @@ add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
@@ -1054,8 +1036,6 @@ add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES
SUFFIX ".out"
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map"
- CXX_STANDARD 11
- C_STANDARD 99
)
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h
index 028fc80..74b121d 100644
--- a/src/displayapp/Apps.h
+++ b/src/displayapp/Apps.h
@@ -2,6 +2,6 @@
namespace Pinetime {
namespace Applications {
- enum class Apps {None, Launcher, Clock, SysInfo, Meter, Brightness, Music, FirmwareValidation, Paint, Paddle, Notifications, Twos, HeartRate, Navigation};
+ enum class Apps {None, Launcher, Clock, SysInfo, Meter, Brightness, Music, FirmwareValidation, Paint, Paddle, Notifications, Twos, HeartRate, Navigation, StopWatch};
}
}
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index fee973a..3de2699 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -12,6 +12,7 @@
#include "displayapp/screens/FirmwareValidation.h"
#include "displayapp/screens/InfiniPaint.h"
#include "displayapp/screens/Paddle.h"
+#include "displayapp/screens/StopWatch.h"
#include "displayapp/screens/Meter.h"
#include "displayapp/screens/Music.h"
#include "displayapp/screens/Navigation.h"
@@ -122,7 +123,7 @@ void DisplayApp::Refresh() {
currentScreen.reset(nullptr);
lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up);
onClockApp = false;
- currentScreen.reset(new Screens::Notifications(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview));
+ currentScreen = std::make_unique<Screens::Notifications>(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview);
}
}
break;
@@ -160,10 +161,10 @@ void DisplayApp::Refresh() {
// lvgl.SetFullRefresh(components::LittleVgl::FullRefreshDirections::Down);
// currentScreen.reset(nullptr);
// if(toggle) {
-// currentScreen.reset(new Screens::Tile(this));
+// currentScreen = std::make_unique<Screens::Tile>(this);
// toggle = false;
// } else {
-// currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController));
+// currentScreen = std::make_unique<Screens::Clock>(this, dateTimeController, batteryController, bleController);
// toggle = true;
// }
@@ -171,10 +172,14 @@ void DisplayApp::Refresh() {
case Messages::BleFirmwareUpdateStarted:
lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down);
currentScreen.reset(nullptr);
- currentScreen.reset(new Screens::FirmwareUpdate(this, bleController));
+ currentScreen = std::make_unique<Screens::FirmwareUpdate>(this, bleController);
onClockApp = false;
break;
+ case Messages::UpdateDateTime:
+ // Added to remove warning
+ // What should happen here?
+ break;
}
}
@@ -197,22 +202,23 @@ void DisplayApp::RunningState() {
onClockApp = false;
switch(nextApp) {
case Apps::None:
- case Apps::Launcher: currentScreen.reset(new Screens::ApplicationList(this, settingsController)); break;
+ case Apps::Launcher: currentScreen = std::make_unique<Screens::ApplicationList>(this, settingsController); break;
case Apps::Clock:
- currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController, notificationManager, settingsController, heartRateController));
+ currentScreen = std::make_unique<Screens::Clock>(this, dateTimeController, batteryController, bleController, notificationManager, settingsController, heartRateController);
onClockApp = true;
break;
- case Apps::SysInfo: currentScreen.reset(new Screens::SystemInfo(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break;
- case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
- case Apps::Twos: currentScreen.reset(new Screens::Twos(this)); break;
- case Apps::Paint: currentScreen.reset(new Screens::InfiniPaint(this, lvgl)); break;
- case Apps::Paddle: currentScreen.reset(new Screens::Paddle(this, lvgl)); break;
- case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break;
- case Apps::Music : currentScreen.reset(new Screens::Music(this, systemTask.nimble().music())); break;
- case Apps::Navigation : currentScreen.reset(new Screens::Navigation(this, systemTask.nimble().navigation())); break;
- case Apps::FirmwareValidation: currentScreen.reset(new Screens::FirmwareValidation(this, validator)); break;
- case Apps::Notifications: currentScreen.reset(new Screens::Notifications(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal)); break;
- case Apps::HeartRate: currentScreen.reset(new Screens::HeartRate(this, heartRateController)); break;
+ case Apps::SysInfo: currentScreen = std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog); break;
+ case Apps::Meter: currentScreen = std::make_unique<Screens::Meter>(this);break;
+ case Apps::StopWatch: currentScreen = std::make_unique<Screens::StopWatch>(this); break;
+ case Apps::Twos: currentScreen = std::make_unique<Screens::Twos>(this); break;
+ case Apps::Paint: currentScreen = std::make_unique<Screens::InfiniPaint>(this, lvgl); break;
+ case Apps::Paddle: currentScreen = std::make_unique<Screens::Paddle>(this, lvgl); break;
+ case Apps::Brightness : currentScreen = std::make_unique<Screens::Brightness>(this, brightnessController); break;
+ case Apps::Music : currentScreen = std::make_unique<Screens::Music>(this, systemTask.nimble().music()); break;
+ case Apps::Navigation : currentScreen = std::make_unique<Screens::Navigation>(this, systemTask.nimble().navigation()); break;
+ case Apps::FirmwareValidation: currentScreen = std::make_unique<Screens::FirmwareValidation>(this, validator); break;
+ case Apps::Notifications: currentScreen = std::make_unique<Screens::Notifications>(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal); break;
+ case Apps::HeartRate: currentScreen = std::make_unique<Screens::HeartRate>(this, heartRateController); break;
}
nextApp = Apps::None;
}
diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp
index 9cf7695..57b8aed 100644
--- a/src/displayapp/DisplayAppRecovery.cpp
+++ b/src/displayapp/DisplayAppRecovery.cpp
@@ -83,8 +83,7 @@ void DisplayApp::DisplayLogo(uint16_t color) {
for(int i = 0; i < displayWidth; i++) {
rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel);
ulTaskNotifyTake(pdTRUE, 500);
- lcd.BeginDrawBuffer(0, i, displayWidth, 1);
- lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
+ lcd.DrawBuffer(0, i, displayWidth, 1, reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
}
}
@@ -94,8 +93,7 @@ void DisplayApp::DisplayOtaProgress(uint8_t percent, uint16_t color) {
for(int i = 0; i < barHeight; i++) {
ulTaskNotifyTake(pdTRUE, 500);
uint16_t barWidth = std::min(static_cast<float>(percent) * 2.4f, static_cast<float>(displayWidth));
- lcd.BeginDrawBuffer(0, displayWidth - barHeight + i, barWidth, 1);
- lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
+ lcd.DrawBuffer(0, displayWidth - barHeight + i, barWidth, 1, reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
}
}
diff --git a/src/displayapp/fonts/Readme.md b/src/displayapp/fonts/Readme.md
index 8e50c29..79b36bc 100644
--- a/src/displayapp/fonts/Readme.md
+++ b/src/displayapp/fonts/Readme.md
@@ -10,7 +10,7 @@
* Bpp : 1 bit-per-pixel
* Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.tff` and specify the following range : `0x20-0x7f, 0x410-0x44f`
- * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd`
+ * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
Add new symbols:
diff --git a/src/displayapp/fonts/jetbrains_mono_bold_20.c b/src/displayapp/fonts/jetbrains_mono_bold_20.c
index dc30104..f4050db 100644
--- a/src/displayapp/fonts/jetbrains_mono_bold_20.c
+++ b/src/displayapp/fonts/jetbrains_mono_bold_20.c
@@ -466,8 +466,8 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0x66, 0x66, 0x66, 0x6c, 0x63,
/* U+417 "З" */
- 0x1f, 0x8f, 0xfd, 0xc7, 0x80, 0x70, 0x1c, 0x3e,
- 0x7, 0xf0, 0xf, 0x0, 0xe0, 0x1d, 0x83, 0xb8,
+ 0x1f, 0xf, 0xf3, 0xc7, 0x0, 0x60, 0x1c, 0x1e,
+ 0x3, 0xf0, 0xe, 0x0, 0xe0, 0x1f, 0x83, 0xf8,
0xf7, 0xfc, 0x3e, 0x0,
/* U+418 "И" */
@@ -615,7 +615,7 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0x70,
/* U+437 "з" */
- 0x3f, 0x1f, 0xfe, 0x1c, 0x7, 0x1f, 0x7, 0xe0,
+ 0x3f, 0x1f, 0xfe, 0x1c, 0x7, 0x1f, 0x87, 0xe0,
0x1c, 0x7, 0xe1, 0xdf, 0xe3, 0xf0,
/* U+438 "и" */
@@ -738,6 +738,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0xcf, 0x9f, 0xff, 0xf1, 0xff, 0xfc, 0x1f, 0xff,
0x1, 0xff, 0xc0, 0x1f, 0xf0, 0x0, 0x70, 0x0,
+ /* U+F024 "" */
+ 0x70, 0x0, 0xf, 0x80, 0x0, 0xf8, 0x0, 0xf,
+ 0xff, 0xf, 0x7f, 0xff, 0xf7, 0xff, 0xff, 0x7f,
+ 0xff, 0xf7, 0xff, 0xff, 0x7f, 0xff, 0xf7, 0xff,
+ 0xff, 0x7f, 0xff, 0xf7, 0xff, 0xff, 0x7f, 0xff,
+ 0xf7, 0xff, 0xff, 0x7f, 0x7f, 0xe7, 0x0, 0x78,
+ 0x70, 0x0, 0x7, 0x0, 0x0, 0x70, 0x0, 0x7,
+ 0x0, 0x0,
+
/* U+F027 "" */
0x0, 0xc0, 0x3, 0x80, 0xf, 0x0, 0x3e, 0xf,
0xfc, 0x9f, 0xf9, 0xbf, 0xf1, 0xff, 0xe3, 0xff,
@@ -789,6 +798,13 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0xff, 0xfc, 0xff, 0xff, 0x3f, 0xff, 0xcf, 0xff,
0xf3, 0xff, 0xfc, 0xff, 0x7e, 0x1f, 0x80,
+ /* U+F04D "" */
+ 0x7f, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x80,
+
/* U+F051 "" */
0xe0, 0x3f, 0x81, 0xfe, 0xf, 0xf8, 0x7f, 0xe3,
0xff, 0x9f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -897,6 +913,13 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0x81, 0xf8, 0x6d, 0x99, 0x9a, 0x36, 0x7, 0x80,
0xe0, 0x18, 0x2, 0x0, 0x0,
+ /* U+F2F2 "" */
+ 0x7, 0xe0, 0x7, 0xe0, 0x1, 0x80, 0x3, 0xc0,
+ 0xf, 0xf2, 0x1f, 0xff, 0x3e, 0x7e, 0x7e, 0x7e,
+ 0xfe, 0x7e, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f,
+ 0xfe, 0x7f, 0xff, 0xff, 0x7f, 0xfe, 0x7f, 0xfe,
+ 0x3f, 0xfc, 0x1f, 0xf8, 0x7, 0xe0,
+
/* U+F3DD "" */
0x40, 0x0, 0x40, 0x70, 0x0, 0x7e, 0x3c, 0x0,
0x3f, 0x8f, 0x80, 0x1f, 0x81, 0xe0, 0x1f, 0xc0,
@@ -1080,7 +1103,7 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 1514, .adv_w = 192, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = -3},
{.bitmap_index = 1538, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
{.bitmap_index = 1554, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
- {.bitmap_index = 1575, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 1575, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 1595, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 1611, .adv_w = 192, .box_w = 9, .box_h = 19, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 1633, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0},
@@ -1139,36 +1162,39 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 2498, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 2511, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 2561, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 2609, .adv_w = 240, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
- {.bitmap_index = 2638, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 2693, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
- {.bitmap_index = 2732, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
- {.bitmap_index = 2775, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1},
- {.bitmap_index = 2803, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 2851, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
- {.bitmap_index = 2890, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1},
- {.bitmap_index = 2918, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 2966, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 3019, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3038, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 3088, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3124, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3172, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
- {.bitmap_index = 3215, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
- {.bitmap_index = 3253, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
- {.bitmap_index = 3291, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
- {.bitmap_index = 3329, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
- {.bitmap_index = 3367, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
- {.bitmap_index = 3405, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3},
- {.bitmap_index = 3443, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 3472, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 3538, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
- {.bitmap_index = 3587, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3637, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3697, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
- {.bitmap_index = 3750, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3805, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
- {.bitmap_index = 3858, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
+ {.bitmap_index = 2609, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 2659, .adv_w = 240, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
+ {.bitmap_index = 2688, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 2743, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 2782, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 2825, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 2853, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 2901, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 2940, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 2979, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1},
+ {.bitmap_index = 3007, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3055, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3108, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3127, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3177, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3213, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3261, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 3304, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
+ {.bitmap_index = 3342, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
+ {.bitmap_index = 3380, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
+ {.bitmap_index = 3418, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
+ {.bitmap_index = 3456, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
+ {.bitmap_index = 3494, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3},
+ {.bitmap_index = 3532, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3561, .adv_w = 280, .box_w = 16, .box_h = 19, .ofs_x = 1, .ofs_y = -2},
+ {.bitmap_index = 3599, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3665, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
+ {.bitmap_index = 3714, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3764, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3824, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
+ {.bitmap_index = 3877, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3932, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
+ {.bitmap_index = 3985, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
};
/*---------------------
@@ -1176,10 +1202,11 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
*--------------------*/
static const uint16_t unicode_list_2[] = {
- 0x0, 0x16, 0x26, 0x27, 0x28, 0x39, 0x47, 0x4a,
- 0x4b, 0x50, 0x68, 0x94, 0x128, 0x184, 0x1e5, 0x1fb,
- 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243, 0x292, 0x293,
- 0x3dc, 0x3fc, 0x45c, 0x54a, 0x55f, 0x59e, 0x59f, 0x6a8
+ 0x0, 0x16, 0x23, 0x26, 0x27, 0x28, 0x39, 0x47,
+ 0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x94, 0x128, 0x184,
+ 0x1e5, 0x1fb, 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243,
+ 0x292, 0x293, 0x2f1, 0x3dc, 0x3fc, 0x45c, 0x54a, 0x55f,
+ 0x59e, 0x59f, 0x6a8
};
/*Collect the unicode lists and glyph_id offsets*/
@@ -1195,7 +1222,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
},
{
.range_start = 61441, .range_length = 1705, .glyph_id_start = 160,
- .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 32, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
+ .unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 35, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
}
};
diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp
index 0f3286d..6003904 100644
--- a/src/displayapp/screens/ApplicationList.cpp
+++ b/src/displayapp/screens/ApplicationList.cpp
@@ -56,21 +56,21 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen1() {
};
- return std::unique_ptr<Screen>(new Screens::Tile(0, app, settingsController, applications));
+ return std::make_unique<Screens::Tile>(0, app, settingsController, applications);
}
std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
std::array<Screens::Tile::Applications, 6> applications {
{{Symbols::map, Apps::Navigation},
- {Symbols::asterisk, Apps::Meter},
+ {Symbols::stopWatch, Apps::StopWatch},
{Symbols::paintbrush, Apps::Paint},
- {Symbols::info, Apps::Notifications},
- {Symbols::paddle, Apps::Paddle},
- {"2", Apps::Twos}
+ {Symbols::info, Apps::Notifications},
+ {Symbols::paddle, Apps::Paddle},
+ {"2", Apps::Twos}
}
};
- return std::unique_ptr<Screen>(new Screens::Tile(1, app, settingsController, applications));
+ return std::make_unique<Screens::Tile>(1, app, settingsController, applications);
}
std::unique_ptr<Screen> ApplicationList::CreateScreen3() {
@@ -84,6 +84,6 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen3() {
}
};
- return std::unique_ptr<Screen>(new Screens::Tile(2, app, settingsController, applications));
+ return std::make_unique<Screens::Tile>(2, app, settingsController, applications);
}
diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp
index 342dd22..6918037 100644
--- a/src/displayapp/screens/Clock.cpp
+++ b/src/displayapp/screens/Clock.cpp
@@ -64,20 +64,20 @@ bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
}
std::unique_ptr<Screen> Clock::WatchFaceDigitalScreen() {
- return std::unique_ptr<Screen>(new Screens::WatchFaceDigital(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, heartRateController));
+ return std::make_unique<Screens::WatchFaceDigital>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, heartRateController);
}
std::unique_ptr<Screen> Clock::WatchFaceAnalogScreen() {
- return std::unique_ptr<Screen>(new Screens::WatchFaceAnalog(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController));
+ return std::make_unique<Screens::WatchFaceAnalog>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController);
}
/*
// Examples for more watch faces
std::unique_ptr<Screen> Clock::WatchFaceMinimalScreen() {
- return std::unique_ptr<Screen>(new Screens::WatchFaceMinimal(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController));
+ return std::make_unique<Screens::WatchFaceMinimal>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController);
}
std::unique_ptr<Screen> Clock::WatchFaceCustomScreen() {
- return std::unique_ptr<Screen>(new Screens::WatchFaceCustom(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController));
+ return std::make_unique<Screens::WatchFaceCustom>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController);
}
*/ \ No newline at end of file
diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp
index 4219bac..c903ed0 100644
--- a/src/displayapp/screens/Notifications.cpp
+++ b/src/displayapp/screens/Notifications.cpp
@@ -17,22 +17,22 @@ Notifications::Notifications(DisplayApp *app,
auto notification = notificationManager.GetLastNotification();
if(notification.valid) {
currentId = notification.id;
- currentItem.reset(new NotificationItem("\nNotification",
+ currentItem = std::make_unique<NotificationItem>("\nNotification",
notification.message.data(),
notification.index,
notification.category,
notificationManager.NbNotifications(),
mode,
- alertNotificationService));
+ alertNotificationService);
validDisplay = true;
} else {
- currentItem.reset(new NotificationItem("\nNotification",
+ currentItem = std::make_unique<NotificationItem>("\nNotification",
"No notification to display",
0,
notification.category,
notificationManager.NbNotifications(),
Modes::Preview,
- alertNotificationService));
+ alertNotificationService);
}
if(mode == Modes::Preview) {
@@ -87,13 +87,13 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
currentId = previousNotification.id;
currentItem.reset(nullptr);
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
- currentItem.reset(new NotificationItem("\nNotification",
+ currentItem = std::make_unique<NotificationItem>("\nNotification",
previousNotification.message.data(),
previousNotification.index,
previousNotification.category,
notificationManager.NbNotifications(),
mode,
- alertNotificationService));
+ alertNotificationService);
}
return true;
case Pinetime::Applications::TouchEvents::SwipeDown: {
@@ -109,13 +109,13 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
currentId = nextNotification.id;
currentItem.reset(nullptr);
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
- currentItem.reset(new NotificationItem("\nNotification",
+ currentItem = std::make_unique<NotificationItem>("\nNotification",
nextNotification.message.data(),
nextNotification.index,
nextNotification.category,
notificationManager.NbNotifications(),
mode,
- alertNotificationService));
+ alertNotificationService);
}
return true;
case Pinetime::Applications::TouchEvents::LongTap: {
diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp
new file mode 100644
index 0000000..63f18d4
--- /dev/null
+++ b/src/displayapp/screens/StopWatch.cpp
@@ -0,0 +1,210 @@
+#include "StopWatch.h"
+
+#include "Screen.h"
+#include "Symbols.h"
+#include "lvgl/lvgl.h"
+#include "projdefs.h"
+#include "FreeRTOSConfig.h"
+#include "task.h"
+
+#include <tuple>
+
+using namespace Pinetime::Applications::Screens;
+
+// Anonymous namespace for local functions
+namespace {
+ TimeSeparated_t convertTicksToTimeSegments(const TickType_t timeElapsed) {
+ const int timeElapsedMillis = (static_cast<float>(timeElapsed) / static_cast<float>(configTICK_RATE_HZ)) * 1000;
+
+ const int milliSecs = (timeElapsedMillis % 1000) / 10; // Get only the first two digits and ignore the last
+ const int secs = (timeElapsedMillis / 1000) % 60;
+ const int mins = (timeElapsedMillis / 1000) / 60;
+ return TimeSeparated_t {mins, secs, milliSecs};
+ }
+
+ TickType_t calculateDelta(const TickType_t startTime, const TickType_t currentTime) {
+ TickType_t delta = 0;
+ // Take care of overflow
+ if (startTime > currentTime) {
+ delta = 0xffffffff - startTime;
+ delta += (currentTime + 1);
+ } else {
+ delta = currentTime - startTime;
+ }
+ return delta;
+ }
+}
+
+static void play_pause_event_handler(lv_obj_t* obj, lv_event_t event) {
+ auto stopWatch = static_cast<StopWatch*>(obj->user_data);
+ stopWatch->playPauseBtnEventHandler(event);
+}
+
+static void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
+ auto stopWatch = static_cast<StopWatch*>(obj->user_data);
+ stopWatch->stopLapBtnEventHandler(event);
+}
+
+StopWatch::StopWatch(DisplayApp* app)
+ : Screen(app), running {true}, currentState {States::Init}, currentEvent {Events::Stop}, startTime {}, oldTimeElapsed {},
+ currentTimeSeparated {}, lapBuffer {}, lapNr {}, lapPressed {false} {
+
+ time = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed);
+ lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -45);
+ lv_label_set_text(time, "00:00");
+
+ msecTime = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
+ lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 108, 3);
+ lv_label_set_text(msecTime, "00");
+
+ btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
+ btnPlayPause->user_data = this;
+ lv_obj_set_event_cb(btnPlayPause, play_pause_event_handler);
+ lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, -10);
+ lv_obj_set_height(btnPlayPause, 40);
+ txtPlayPause = lv_label_create(btnPlayPause, nullptr);
+ lv_label_set_text(txtPlayPause, Symbols::play);
+
+ lapOneText = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
+ lv_obj_align(lapOneText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30);
+ lv_label_set_text(lapOneText, "");
+
+ lapTwoText = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_font(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
+ lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55);
+ lv_label_set_text(lapTwoText, "");
+
+ // We don't want this button in the init state
+ btnStopLap = nullptr;
+}
+
+StopWatch::~StopWatch() {
+ lv_obj_clean(lv_scr_act());
+}
+
+bool StopWatch::Refresh() {
+ // @startuml CHIP8_state
+ // State "Init" as init
+ // State "Running" as run
+ // State "Halted" as halt
+
+ // [*] --> init
+ // init -> run : press play
+ // run -> run : press lap
+ // run --> halt : press pause
+ // halt --> run : press play
+ // halt --> init : press stop
+ // @enduml
+ // Copy paste the above plantuml text to visualize the state diagram
+ switch (currentState) {
+ // Init state when an user first opens the app
+ // and when a stop/reset button is pressed
+ case States::Init: {
+ if (btnStopLap) {
+ lv_obj_del(btnStopLap);
+ }
+ // The initial default value
+ lv_label_set_text(time, "00:00");
+ lv_label_set_text(msecTime, "00");
+
+ lv_label_set_text(lapOneText, "");
+ lv_label_set_text(lapTwoText, "");
+ lapBuffer.clearBuffer();
+ lapNr = 0;
+
+ if (currentEvent == Events::Play) {
+ btnStopLap = lv_btn_create(lv_scr_act(), nullptr);
+ btnStopLap->user_data = this;
+ lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler);
+ lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0);
+ lv_obj_set_height(btnStopLap, 40);
+ txtStopLap = lv_label_create(btnStopLap, nullptr);
+ lv_label_set_text(txtStopLap, Symbols::lapsFlag);
+
+ startTime = xTaskGetTickCount();
+ currentState = States::Running;
+ }
+ break;
+ }
+ case States::Running: {
+ lv_label_set_text(txtPlayPause, Symbols::pause);
+ lv_label_set_text(txtStopLap, Symbols::lapsFlag);
+
+ const auto timeElapsed = calculateDelta(startTime, xTaskGetTickCount());
+ currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
+
+ lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
+ lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.msecs);
+
+ if (lapPressed == true) {
+ if (lapBuffer[1]) {
+ lv_label_set_text_fmt(lapOneText, "#%d %d:%d:%d", (lapNr - 1), lapBuffer[1]->mins, lapBuffer[1]->secs, lapBuffer[1]->msecs);
+ }
+ if (lapBuffer[0]) {
+ lv_label_set_text_fmt(lapTwoText, "#%d %d:%d:%d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->msecs);
+ }
+ // Reset the bool to avoid setting the text in each cycle until there is a change
+ lapPressed = false;
+ }
+
+ if (currentEvent == Events::Pause) {
+ // Reset the start time
+ startTime = 0;
+ // Store the current time elapsed in cache
+ oldTimeElapsed += timeElapsed;
+ currentState = States::Halted;
+ }
+ break;
+ }
+ case States::Halted: {
+ lv_label_set_text(txtPlayPause, Symbols::play);
+ lv_label_set_text(txtStopLap, Symbols::stop);
+
+ if (currentEvent == Events::Play) {
+ startTime = xTaskGetTickCount();
+ currentState = States::Running;
+ }
+ if (currentEvent == Events::Stop) {
+ currentState = States::Init;
+ oldTimeElapsed = 0;
+ }
+ break;
+ }
+ }
+ return running;
+}
+
+bool StopWatch::OnButtonPushed() {
+ running = false;
+ return true;
+}
+
+void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
+ if (event == LV_EVENT_CLICKED) {
+ if (currentState == States::Init) {
+ currentEvent = Events::Play;
+ } else {
+ // Simple Toggle for play/pause
+ currentEvent = (currentEvent == Events::Play ? Events::Pause : Events::Play);
+ }
+ }
+}
+
+void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
+ if (event == LV_EVENT_CLICKED) {
+ // If running, then this button is used to save laps
+ if (currentState == States::Running) {
+ lapBuffer.addLaps(currentTimeSeparated);
+ lapNr++;
+ lapPressed = true;
+
+ } else if (currentState == States::Halted) {
+ currentEvent = Events::Stop;
+ } else {
+ // Not possible to reach here. Do nothing.
+ }
+ }
+}
diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h
new file mode 100644
index 0000000..f9dd5c7
--- /dev/null
+++ b/src/displayapp/screens/StopWatch.h
@@ -0,0 +1,86 @@
+#pragma once
+
+#include "Screen.h"
+#include "components/datetime/DateTimeController.h"
+#include "../LittleVgl.h"
+
+#include "FreeRTOS.h"
+#include "portmacro_cmsis.h"
+
+#include <array>
+
+namespace Pinetime::Applications::Screens {
+
+ enum class States { Init, Running, Halted };
+
+ enum class Events { Play, Pause, Stop };
+
+ struct TimeSeparated_t {
+ int mins;
+ int secs;
+ int msecs;
+ };
+
+ // A simple buffer to hold the latest two laps
+ template <int N> struct LapTextBuffer_t {
+ LapTextBuffer_t() : buffer {}, currentSize {}, capacity {N}, head {-1} {
+ }
+
+ void addLaps(const TimeSeparated_t& timeVal) {
+ head++;
+ head %= capacity;
+ buffer[head] = timeVal;
+
+ if (currentSize < capacity) {
+ currentSize++;
+ }
+ }
+
+ void clearBuffer() {
+ buffer = {};
+ currentSize = 0;
+ head = -1;
+ }
+
+ TimeSeparated_t* operator[](std::size_t idx) {
+ // Sanity check for out-of-bounds
+ if (idx >= 0 && idx < capacity) {
+ if (idx < currentSize) {
+ // This transformation is to ensure that head is always pointing to index 0.
+ const auto transformed_idx = (head - idx) % capacity;
+ return (&buffer[transformed_idx]);
+ }
+ }
+ return nullptr;
+ }
+
+ private:
+ std::array<TimeSeparated_t, N> buffer;
+ uint8_t currentSize;
+ uint8_t capacity;
+ int8_t head;
+ };
+
+ class StopWatch : public Screen {
+ public:
+ StopWatch(DisplayApp* app);
+ ~StopWatch() override;
+ bool Refresh() override;
+ bool OnButtonPushed() override;
+ void playPauseBtnEventHandler(lv_event_t event);
+ void stopLapBtnEventHandler(lv_event_t event);
+
+ private:
+ bool running;
+ States currentState;
+ Events currentEvent;
+ TickType_t startTime;
+ TickType_t oldTimeElapsed;
+ TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs
+ LapTextBuffer_t<2> lapBuffer;
+ int lapNr;
+ bool lapPressed;
+ lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
+ lv_obj_t *lapOneText, *lapTwoText;
+ };
+}
diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h
index 1a6bbd7..9a13a75 100644
--- a/src/displayapp/screens/Symbols.h
+++ b/src/displayapp/screens/Symbols.h
@@ -36,6 +36,9 @@ namespace Pinetime {
static constexpr const char* stepBackward = "\xEF\x81\x88";
static constexpr const char* play = "\xEF\x81\x8B";
static constexpr const char* pause = "\xEF\x81\x8C";
+ static constexpr const char* stop = "\xEF\x81\x8D";
+ static constexpr const char* stopWatch = "\xEF\x8B\xB2";
+ static constexpr const char* lapsFlag = "\xEF\x80\xA4";
}
}
}
diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp
index 0d6f8e5..949fd34 100644
--- a/src/displayapp/screens/SystemInfo.cpp
+++ b/src/displayapp/screens/SystemInfo.cpp
@@ -104,14 +104,14 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen1() {
uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds,
batteryPercent, brightness, resetReason);
- return std::unique_ptr<Screen>(new Screens::Label(app, t1));
+ return std::make_unique<Screens::Label>(app, t1);
}
std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
auto& bleAddr = bleController.Address();
sprintf(t2, "BLE MAC: \n %02x:%02x:%02x:%02x:%02x:%02x",
bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]);
- return std::unique_ptr<Screen>(new Screens::Label(app, t2));
+ return std::make_unique<Screens::Label>(app, t2);
}
std::unique_ptr<Screen> SystemInfo::CreateScreen3() {
@@ -123,5 +123,5 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen3() {
"Source code:\n"
"https://github.com/\n"
" JF002/InfiniTime");
- return std::unique_ptr<Screen>(new Screens::Label(app, t3));
+ return std::make_unique<Screens::Label>(app, t3);
}
diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp
index b51d48c..66af584 100644
--- a/src/displayapp/screens/WatchFaceAnalog.cpp
+++ b/src/displayapp/screens/WatchFaceAnalog.cpp
@@ -5,6 +5,8 @@
#include "Symbols.h"
#include "NotificationIcon.h"
+#include <cmath>
+
LV_IMG_DECLARE(bg_clock);
using namespace Pinetime::Applications::Screens;
diff --git a/src/libs/lvgl b/src/libs/lvgl
-Subproject 69a50b97dafffddd212e4b006776b473951be7a
+Subproject 1b6501dc3babf39538f4a02aa9fb14c2aaebca2
diff --git a/src/main.cpp b/src/main.cpp
index b29aac7..bd4bbe7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -49,6 +49,8 @@ Pinetime::Logging::NrfLogger logger;
Pinetime::Logging::DummyLogger logger;
#endif
+#include <memory>
+
static constexpr uint8_t pinSpiSck = 2;
static constexpr uint8_t pinSpiMosi = 3;
static constexpr uint8_t pinSpiMiso = 4;
@@ -254,8 +256,8 @@ int main(void) {
debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback);
- systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, spiNorFlash, twiMaster, touchPanel, lvgl, batteryController, bleController,
- dateTimeController, motorController, heartRateSensor, settingsController));
+ systemTask = std::make_unique<Pinetime::System::SystemTask>(spi, lcd, spiNorFlash, twiMaster, touchPanel, lvgl, batteryController, bleController,
+ dateTimeController, motorController, heartRateSensor, settingsController);
systemTask->Start();
nimble_port_init();
diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp
index 40cd66d..9ed062e 100644
--- a/src/recoveryLoader.cpp
+++ b/src/recoveryLoader.cpp
@@ -134,8 +134,7 @@ void DisplayLogo() {
for(int i = 0; i < displayWidth; i++) {
rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel);
ulTaskNotifyTake(pdTRUE, 500);
- lcd.BeginDrawBuffer(0, i, displayWidth, 1);
- lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
+ lcd.DrawBuffer(0, i, displayWidth, 1, reinterpret_cast<const uint8_t *>(displayBuffer), displayWidth * bytesPerPixel);
}
}
@@ -145,8 +144,7 @@ void DisplayProgressBar(uint8_t percent, uint16_t color) {
for(int i = 0; i < barHeight; i++) {
ulTaskNotifyTake(pdTRUE, 500);
uint16_t barWidth = std::min(static_cast<float>(percent) * 2.4f, static_cast<float>(displayWidth));
- lcd.BeginDrawBuffer(0, displayWidth - barHeight + i, barWidth, 1);
- lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
+ lcd.DrawBuffer(0, displayWidth - barHeight + i, barWidth, 1, reinterpret_cast<const uint8_t *>(displayBuffer), barWidth * bytesPerPixel);
}
}
diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp
index 19a416b..7b137f5 100644
--- a/src/systemtask/SystemTask.cpp
+++ b/src/systemtask/SystemTask.cpp
@@ -23,6 +23,8 @@
#include "drivers/Hrs3300.h"
#include "main.h"
+#include <memory>
+
using namespace Pinetime::System;
void IdleTimerCallback(TimerHandle_t xTimer) {
@@ -86,9 +88,9 @@ void SystemTask::Work() {
settingsController.Init();
- displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController,
+ displayApp = std::make_unique<Pinetime::Applications::DisplayApp>(lcd, lvgl, touchPanel, batteryController, bleController,
dateTimeController, watchdogView, *this, notificationManager,
- heartRateController, settingsController));
+ heartRateController, settingsController);
displayApp->Start();
batteryController.Update();
@@ -96,7 +98,7 @@ void SystemTask::Work() {
heartRateSensor.Init();
heartRateSensor.Disable();
- heartRateApp.reset(new Pinetime::Applications::HeartRateTask(heartRateSensor, heartRateController));
+ heartRateApp = std::make_unique<Pinetime::Applications::HeartRateTask>(heartRateSensor, heartRateController);
heartRateApp->Start();