InfiniTime.git

commit 72c992c84e44ac9a6dd8c53055a00ca801bf9ffe

Author: Jean-François Milants <jf@codingfield.com>

Watch face selection using CMake

Update Apps.md to mention the selection of watchfaces using Cmake.

 doc/code/Apps.md | 46 ++++++++++++++++++++++++++++++++++++++++++----


diff --git a/doc/code/Apps.md b/doc/code/Apps.md
index 6ca844815b83ad0b8a3dff2eead59d1827afde64..ca7d8bc22912bc62c5a0865bcff0c71b8fae997d 100644
--- a/doc/code/Apps.md
+++ b/doc/code/Apps.md
@@ -35,18 +35,20 @@ that will call the method `Refresh()` periodically.
 
 ## App types
 
-There are basically 2 types of applications : **system** apps and **user** apps.
+There are basically 3 types of applications : **system** apps and **user** apps and **watchfaces**.
 
 **System** applications are always built into InfiniTime, and InfiniTime cannot work properly without those apps.
 The watchfaces, settings, notifications and the application launcher are examples of such system applications.
 
 **User** applications are optionally built into the firmware. They extend the functionalities of the system.
 
-The distinction between **system** and **user** applications allows for more flexibility and customization.
-This allows to easily select which user applications must be built into the firmware
+**Watchfaces** are very similar to the **user** apps, they are optional, but at least one must be built into the firmware.
+
+The distinction between **system** apps,  **user** apps and watchfaces allows for more flexibility and customization.
+This allows to easily select which user applications and watchfaces must be built into the firmware
 without overflowing the system memory.
 
-## Apps initialization
+## Apps and watchfaces initialization
 
 Apps are created by `DisplayApp` in `DisplayApp::LoadScreen()`.
 This method simply call the creates an instance of the class that corresponds to the app specified in parameters.
@@ -54,6 +56,8 @@
 The constructor of **system** apps is called directly. If the application is a **user** app,
 the corresponding `AppDescription` is first retrieved from `userApps`
 and then the function `create` is called to create an instance of the app.
+
+Watchfaces are handled in a very similar way than the **user** apps : they are created by `DisplayApp` in the method `DisplayApp::LoadScreen()` when the application type is `Apps::Clock`.
 
 ## User application selection at build time
 
@@ -85,6 +89,32 @@
 This array `userApps` is used by `DisplayApp` to create the applications and the `AppLauncher`
 to list all available applications.
 
+## Watchface selection at build time
+
+The list of available watchface is also generated at build time by the `consteval`
+function `CreateWatchFaceDescriptions()` in `UserApps.h` in the same way as the **user** apps.
+Watchfaces must declare a `WatchFaceTraits` so that the corresponding `WatchFaceDescription` can be generated.
+Here is an example of `WatchFaceTraits`:
+```c++
+    template <>
+    struct WatchFaceTraits<WatchFace::Analog> {
+      static constexpr WatchFace watchFace = WatchFace::Analog;
+      static constexpr const char* name = "Analog face";
+
+      static Screens::Screen* Create(AppControllers& controllers) {
+        return new Screens::WatchFaceAnalog(controllers.dateTimeController,
+                                            controllers.batteryController,
+                                            controllers.bleController,
+                                            controllers.notificationManager,
+                                            controllers.settingsController);
+      };
+
+      static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
+        return true;
+      }
+    };
+```
+
 ## Creating your own app
 
 A minimal user app could look like this:
@@ -166,6 +196,14 @@ Ex : build the firmware with 3 user application : Alarm, Timer and MyApp (the application will be listed in this specific order in the application menu).
 
 ```cmake
 $ cmake ... -DENABLE_USERAPPS="Apps::Alarm, Apps::Timer, Apps::MyApp" ... 
+```
+
+Similarly, the list of watchfaces is also generated by CMake, so you need to add the variable `ENABLE_WATCHFACES` to the command line of CMake. It must be set with the list of watchfaces that will be built into the firmware.
+
+Ex: build the firmware with 3 watchfaces : Analog, PineTimeStyle and Infineat:
+
+```cmake
+$ cmake ... -DENABLE_WATCHFACES="WatchFace::Analog,WatchFace::PineTimeStyle,WatchFace::Infineat" ...
 ```
 
 You should now be able to [build](../buildAndProgram.md) the firmware