From 39bc166e549e8ccae75468aa2dd3613d51f54e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Sun, 10 Dec 2023 18:35:19 +0100 Subject: [PATCH] Watch face selection at build time Watch faces can now be selected at buid time. It's implemented in a similar way than the selection of user apps, using a list of watch face description that is generated at build time (consteval, constexpr) --- src/CMakeLists.txt | 3 - src/components/settings/Settings.h | 2 +- src/displayapp/Apps.h | 29 +++- src/displayapp/DisplayApp.cpp | 48 +++---- src/displayapp/UserApps.h | 25 +++- src/displayapp/WatchFaces.h | 14 -- src/displayapp/screens/Clock.cpp | 133 ------------------ src/displayapp/screens/Clock.h | 63 --------- src/displayapp/screens/WatchFaceAnalog.h | 18 +++ .../screens/WatchFaceCasioStyleG7710.h | 23 +++ src/displayapp/screens/WatchFaceDigital.h | 21 +++ src/displayapp/screens/WatchFaceInfineat.h | 22 +++ .../screens/WatchFacePineTimeStyle.h | 21 +++ src/displayapp/screens/WatchFaceTerminal.h | 21 +++ .../screens/settings/SettingWatchFace.cpp | 9 +- .../screens/settings/SettingWatchFace.h | 23 ++- 16 files changed, 216 insertions(+), 259 deletions(-) delete mode 100644 src/displayapp/WatchFaces.h delete mode 100644 src/displayapp/screens/Clock.cpp delete mode 100644 src/displayapp/screens/Clock.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4207161e..9a993e02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -373,7 +373,6 @@ list(APPEND SOURCE_FILES logging/NrfLogger.cpp displayapp/DisplayApp.cpp displayapp/screens/Screen.cpp - displayapp/screens/Clock.cpp displayapp/screens/Tile.cpp displayapp/screens/InfiniPaint.cpp displayapp/screens/Paddle.cpp @@ -597,7 +596,6 @@ set(INCLUDE_FILES displayapp/Messages.h displayapp/TouchEvents.h displayapp/screens/Screen.h - displayapp/screens/Clock.h displayapp/screens/Tile.h displayapp/screens/InfiniPaint.h displayapp/screens/StopWatch.h @@ -613,7 +611,6 @@ set(INCLUDE_FILES displayapp/screens/ApplicationList.h displayapp/screens/CheckboxList.h displayapp/Apps.h - displayapp/WatchFaces.h displayapp/screens/Notifications.h displayapp/screens/HeartRate.h displayapp/screens/Metronome.h diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 81cf4923..c9a0b799 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -3,7 +3,7 @@ #include #include "components/brightness/BrightnessController.h" #include "components/fs/FS.h" -#include "displayapp/WatchFaces.h" +#include "displayapp/Apps.h" namespace Pinetime { namespace Controllers { diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index f65fd2cf..097b530e 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -1,9 +1,10 @@ #pragma once #include +#include namespace Pinetime { namespace Applications { - enum class Apps { + enum class Apps : uint8_t { None, Launcher, Clock, @@ -42,14 +43,31 @@ namespace Pinetime { Weather }; + enum class WatchFace : uint8_t { + Digital = 0, + Analog = 1, + PineTimeStyle = 2, + Terminal = 3, + Infineat = 4, + CasioStyleG7710 = 5, + }; + template struct AppTraits {}; + template + struct WatchFaceTraits {}; + template struct TypeList { static constexpr size_t Count = sizeof...(As); }; + template + struct WatchFaceTypeList { + static constexpr size_t Count = sizeof...(Ws); + }; + using UserAppTypes = TypeList; + + using UserWatchFaceTypes = WatchFaceTypeList; + + static_assert(UserWatchFaceTypes::Count >= 1); } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 98be6324..3b34d7b8 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -11,7 +11,6 @@ #include "components/motion/MotionController.h" #include "components/motor/MotorController.h" #include "displayapp/screens/ApplicationList.h" -#include "displayapp/screens/Clock.h" #include "displayapp/screens/FirmwareUpdate.h" #include "displayapp/screens/FirmwareValidation.h" #include "displayapp/screens/InfiniPaint.h" @@ -435,17 +434,17 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio filesystem, std::move(apps)); } break; - case Apps::Clock: - currentScreen = std::make_unique(dateTimeController, - batteryController, - bleController, - notificationManager, - settingsController, - heartRateController, - motionController, - systemTask->nimble().weather(), - filesystem); - break; + case Apps::Clock: { + const auto* watchFace = + std::find_if(userWatchFaces.begin(), userWatchFaces.end(), [this](const WatchFaceDescription& watchfaceDescription) { + return watchfaceDescription.watchFace == settingsController.GetWatchFace(); + }); + if (watchFace != userWatchFaces.end()) + currentScreen.reset(watchFace->create(controllers)); + else { + currentScreen.reset(userWatchFaces[0].create(controllers)); + } + } break; case Apps::Error: currentScreen = std::make_unique(bootError); break; @@ -489,9 +488,14 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::Settings: currentScreen = std::make_unique(this, settingsController); break; - case Apps::SettingWatchFace: - currentScreen = std::make_unique(this, settingsController, filesystem); - break; + case Apps::SettingWatchFace: { + std::array items; + int i = 0; + for (const auto& userWatchFace : userWatchFaces) { + items[i++] = Screens::CheckboxList::Item {userWatchFace.name, userWatchFace.isAvailable(controllers.filesystem)}; + } + currentScreen = std::make_unique(this, std::move(items), settingsController, filesystem); + } break; case Apps::SettingTimeFormat: currentScreen = std::make_unique(settingsController); break; @@ -536,18 +540,10 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio const auto* d = std::find_if(userApps.begin(), userApps.end(), [app](const AppDescription& appDescription) { return appDescription.app == app; }); - if (d != userApps.end()) + if (d != userApps.end()) { currentScreen.reset(d->create(controllers)); - else { - currentScreen = std::make_unique(dateTimeController, - batteryController, - bleController, - notificationManager, - settingsController, - heartRateController, - motionController, - systemTask->nimble().weather(), - filesystem); + } else { + currentScreen.reset(userWatchFaces[0].create(controllers)); } break; } diff --git a/src/displayapp/UserApps.h b/src/displayapp/UserApps.h index 0ed9d602..cb6d5779 100644 --- a/src/displayapp/UserApps.h +++ b/src/displayapp/UserApps.h @@ -7,7 +7,12 @@ #include "displayapp/screens/Twos.h" #include "displayapp/screens/Tile.h" #include "displayapp/screens/ApplicationList.h" -#include "displayapp/screens/Clock.h" +#include "displayapp/screens/WatchFaceDigital.h" +#include "displayapp/screens/WatchFaceAnalog.h" +#include "displayapp/screens/WatchFaceCasioStyleG7710.h" +#include "displayapp/screens/WatchFaceInfineat.h" +#include "displayapp/screens/WatchFacePineTimeStyle.h" +#include "displayapp/screens/WatchFaceTerminal.h" namespace Pinetime { namespace Applications { @@ -21,16 +26,34 @@ namespace Pinetime { Screens::Screen* (*create)(AppControllers& controllers); }; + struct WatchFaceDescription { + WatchFace watchFace; + const char* name; + Screens::Screen* (*create)(AppControllers& controllers); + bool (*isAvailable)(Controllers::FS& fileSystem); + }; + template consteval AppDescription CreateAppDescription() { return {AppTraits::app, AppTraits::icon, &AppTraits::Create}; } + template + consteval WatchFaceDescription CreateWatchFaceDescription() { + return {WatchFaceTraits::watchFace, WatchFaceTraits::name, &WatchFaceTraits::Create, &WatchFaceTraits::IsAvailable}; + } + template