Compare commits

...

10 Commits

Author SHA1 Message Date
Ryan Rix
e3967e8a90 this modulo math seems stinky even if it worked. probably because 24h time but it would behave differently in 12h time? 2023-10-12 13:20:15 -07:00
Ryan Rix
49ba4c29ae fix watchface bug when the time is almost top of the hour 2023-10-12 13:19:48 -07:00
Ryan Rix
d31c8c99c8 tweak fuzzy time rules 2023-09-26 12:15:21 -07:00
Ryan Rix
92f8c37291 Now that i have room, larger vulf mono font 2023-09-26 12:15:04 -07:00
Ryan Rix
1eb624c452 change index of watch faces since i removed some 2023-09-26 12:14:39 -07:00
Ryan Rix
deb8f9368f fuzzy clock 2023-09-26 01:04:20 -07:00
Ryan Rix
3ade3153e5 remove PTS, Terminal and Infineat faces 2023-09-25 23:45:08 -07:00
Ryan Rix
f5e7dba873 remove paint and paddle apps 2023-09-25 23:42:04 -07:00
Ryan Rix
fb213c323b add build deps in shell.nix 2023-09-25 23:41:14 -07:00
Ryan Rix
9241d4783c copy digital clock in to new screen and wire it up 2023-09-25 19:03:02 -07:00
13 changed files with 373 additions and 146 deletions

31
shell.nix Normal file
View File

@ -0,0 +1,31 @@
{ pkgs ? import <nixpkgs> {} }:
with pkgs; let
py4McuBoot = python3.withPackages (ps: with ps; [
cbor
intelhex
click
cryptography
]);
in mkShell {
packages = [
gcc-arm-embedded-10
nrf5-sdk
cmake
nodePackages.lv_font_conv
lv_img_conv
py4McuBoot
clang-tools
SDL2
libpng
python3Packages.adafruit-nrfutil
];
ARM_NONE_EABI_TOOLCHAIN_PATH="${gcc-arm-embedded-10}";
NRF5_SDK_PATH="${nrf5-sdk}/share/nRF5_SDK";
CMAKE_BUILD_TYPE="Release";
BUILD_DFU=1;
BUILD_RESOURCES=1;
TARGET_DEVICE="PINETIME";
}

View File

@ -375,8 +375,6 @@ list(APPEND SOURCE_FILES
displayapp/screens/Screen.cpp displayapp/screens/Screen.cpp
displayapp/screens/Clock.cpp displayapp/screens/Clock.cpp
displayapp/screens/Tile.cpp displayapp/screens/Tile.cpp
displayapp/screens/InfiniPaint.cpp
displayapp/screens/Paddle.cpp
displayapp/screens/StopWatch.cpp displayapp/screens/StopWatch.cpp
displayapp/screens/BatteryIcon.cpp displayapp/screens/BatteryIcon.cpp
displayapp/screens/BleIcon.cpp displayapp/screens/BleIcon.cpp
@ -429,10 +427,8 @@ list(APPEND SOURCE_FILES
## Watch faces ## Watch faces
displayapp/screens/WatchFaceAnalog.cpp displayapp/screens/WatchFaceAnalog.cpp
displayapp/screens/WatchFaceDigital.cpp displayapp/screens/WatchFaceDigital.cpp
displayapp/screens/WatchFaceInfineat.cpp
displayapp/screens/WatchFaceTerminal.cpp
displayapp/screens/WatchFacePineTimeStyle.cpp
displayapp/screens/WatchFaceCasioStyleG7710.cpp displayapp/screens/WatchFaceCasioStyleG7710.cpp
displayapp/screens/WatchFaceFuzzy.cpp
## ##
@ -600,9 +596,7 @@ set(INCLUDE_FILES
displayapp/screens/Screen.h displayapp/screens/Screen.h
displayapp/screens/Clock.h displayapp/screens/Clock.h
displayapp/screens/Tile.h displayapp/screens/Tile.h
displayapp/screens/InfiniPaint.h
displayapp/screens/StopWatch.h displayapp/screens/StopWatch.h
displayapp/screens/Paddle.h
displayapp/screens/BatteryIcon.h displayapp/screens/BatteryIcon.h
displayapp/screens/BleIcon.h displayapp/screens/BleIcon.h
displayapp/screens/NotificationIcon.h displayapp/screens/NotificationIcon.h

View File

@ -16,8 +16,6 @@ namespace Pinetime {
FlashLight, FlashLight,
BatteryInfo, BatteryInfo,
Music, Music,
Paint,
Paddle,
Twos, Twos,
HeartRate, HeartRate,
Navigation, Navigation,

View File

@ -14,8 +14,6 @@
#include "displayapp/screens/Clock.h" #include "displayapp/screens/Clock.h"
#include "displayapp/screens/FirmwareUpdate.h" #include "displayapp/screens/FirmwareUpdate.h"
#include "displayapp/screens/FirmwareValidation.h" #include "displayapp/screens/FirmwareValidation.h"
#include "displayapp/screens/InfiniPaint.h"
#include "displayapp/screens/Paddle.h"
#include "displayapp/screens/StopWatch.h" #include "displayapp/screens/StopWatch.h"
#include "displayapp/screens/Metronome.h" #include "displayapp/screens/Metronome.h"
#include "displayapp/screens/Music.h" #include "displayapp/screens/Music.h"
@ -522,12 +520,6 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
case Apps::Twos: case Apps::Twos:
currentScreen = std::make_unique<Screens::Twos>(); currentScreen = std::make_unique<Screens::Twos>();
break; break;
case Apps::Paint:
currentScreen = std::make_unique<Screens::InfiniPaint>(lvgl, motorController);
break;
case Apps::Paddle:
currentScreen = std::make_unique<Screens::Paddle>(lvgl);
break;
case Apps::Music: case Apps::Music:
currentScreen = std::make_unique<Screens::Music>(systemTask->nimble().music()); currentScreen = std::make_unique<Screens::Music>(systemTask->nimble().music());
break; break;

View File

@ -5,10 +5,8 @@ namespace Pinetime {
enum class WatchFace : uint8_t { enum class WatchFace : uint8_t {
Digital = 0, Digital = 0,
Analog = 1, Analog = 1,
PineTimeStyle = 2, CasioStyleG7710 = 2,
Terminal = 3, Fuzzy = 3,
Infineat = 4,
CasioStyleG7710 = 5,
}; };
} }
} }

View File

@ -1,6 +1,6 @@
set(FONTS jetbrains_mono_42 jetbrains_mono_76 jetbrains_mono_bold_20 set(FONTS jetbrains_mono_42 jetbrains_mono_76 jetbrains_mono_bold_20
jetbrains_mono_extrabold_compressed lv_font_sys_48 jetbrains_mono_extrabold_compressed lv_font_sys_48
open_sans_light fontawesome_weathericons) open_sans_light fontawesome_weathericons vulf_mono_italic)
find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED
HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin") HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin")
message(STATUS "Using ${LV_FONT_CONV} to generate font files") message(STATUS "Using ${LV_FONT_CONV} to generate font files")

View File

@ -3,7 +3,7 @@
"sources": [ "sources": [
{ {
"file": "JetBrainsMono-Bold.ttf", "file": "JetBrainsMono-Bold.ttf",
"range": "0x20-0x7e, 0x410-0x44f, 0xB0" "range": "0x20-0x7e, 0xB0, 0x410-0x44f"
}, },
{ {
"file": "FontAwesome5-Solid+Brands+Regular.woff", "file": "FontAwesome5-Solid+Brands+Regular.woff",
@ -11,8 +11,17 @@
} }
], ],
"bpp": 1, "bpp": 1,
"size": 20, "size": 20
"patches": ["jetbrains_mono_bold_20.c_zero.patch", "jetbrains_mono_bold_20.c_M.patch"] },
"vulf_mono_italic": {
"sources": [
{
"file": "Vulf_Mono-Italic.woff",
"range": "0x20-0x7e, 0xB0"
}
],
"bpp": 1,
"size": 30
}, },
"jetbrains_mono_42": { "jetbrains_mono_42": {
"sources": [ "sources": [
@ -38,7 +47,7 @@
"sources": [ "sources": [
{ {
"file": "JetBrainsMono-ExtraBold.ttf", "file": "JetBrainsMono-ExtraBold.ttf",
"range": "0x30-0x3a" "range": "0x20, 0x30-0x3a"
} }
], ],
"bpp": 1, "bpp": 1,

View File

@ -50,8 +50,6 @@ namespace Pinetime {
{Symbols::heartBeat, Apps::HeartRate, true}, {Symbols::heartBeat, Apps::HeartRate, true},
{Symbols::music, Apps::Music, true}, {Symbols::music, Apps::Music, true},
{Symbols::paintbrush, Apps::Paint, true},
{Symbols::paddle, Apps::Paddle, true},
{"2", Apps::Twos, true}, {"2", Apps::Twos, true},
{Symbols::drum, Apps::Metronome, true}, {Symbols::drum, Apps::Metronome, true},
{Symbols::map, Apps::Navigation, Applications::Screens::Navigation::IsAvailable(filesystem)}, {Symbols::map, Apps::Navigation, Applications::Screens::Navigation::IsAvailable(filesystem)},

View File

@ -8,10 +8,8 @@
#include "components/settings/Settings.h" #include "components/settings/Settings.h"
#include "displayapp/DisplayApp.h" #include "displayapp/DisplayApp.h"
#include "displayapp/screens/WatchFaceDigital.h" #include "displayapp/screens/WatchFaceDigital.h"
#include "displayapp/screens/WatchFaceTerminal.h"
#include "displayapp/screens/WatchFaceInfineat.h"
#include "displayapp/screens/WatchFaceAnalog.h" #include "displayapp/screens/WatchFaceAnalog.h"
#include "displayapp/screens/WatchFacePineTimeStyle.h" #include "displayapp/screens/WatchFaceFuzzy.h"
#include "displayapp/screens/WatchFaceCasioStyleG7710.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h"
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
@ -43,18 +41,12 @@ Clock::Clock(Controllers::DateTime& dateTimeController,
case WatchFace::Analog: case WatchFace::Analog:
return WatchFaceAnalogScreen(); return WatchFaceAnalogScreen();
break; break;
case WatchFace::PineTimeStyle:
return WatchFacePineTimeStyleScreen();
break;
case WatchFace::Terminal:
return WatchFaceTerminalScreen();
break;
case WatchFace::Infineat:
return WatchFaceInfineatScreen();
break;
case WatchFace::CasioStyleG7710: case WatchFace::CasioStyleG7710:
return WatchFaceCasioStyleG7710(); return WatchFaceCasioStyleG7710();
break; break;
case WatchFace::Fuzzy:
return WatchFaceFuzzy();
break;
} }
return WatchFaceDigitalScreen(); return WatchFaceDigitalScreen();
}()} { }()} {
@ -91,36 +83,6 @@ std::unique_ptr<Screen> Clock::WatchFaceAnalogScreen() {
settingsController); settingsController);
} }
std::unique_ptr<Screen> Clock::WatchFacePineTimeStyleScreen() {
return std::make_unique<Screens::WatchFacePineTimeStyle>(dateTimeController,
batteryController,
bleController,
notificationManager,
settingsController,
motionController,
weatherService);
}
std::unique_ptr<Screen> Clock::WatchFaceTerminalScreen() {
return std::make_unique<Screens::WatchFaceTerminal>(dateTimeController,
batteryController,
bleController,
notificationManager,
settingsController,
heartRateController,
motionController);
}
std::unique_ptr<Screen> Clock::WatchFaceInfineatScreen() {
return std::make_unique<Screens::WatchFaceInfineat>(dateTimeController,
batteryController,
bleController,
notificationManager,
settingsController,
motionController,
filesystem);
}
std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() { std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() {
return std::make_unique<Screens::WatchFaceCasioStyleG7710>(dateTimeController, return std::make_unique<Screens::WatchFaceCasioStyleG7710>(dateTimeController,
batteryController, batteryController,
@ -131,3 +93,12 @@ std::unique_ptr<Screen> Clock::WatchFaceCasioStyleG7710() {
motionController, motionController,
filesystem); filesystem);
} }
std::unique_ptr<Screen> Clock::WatchFaceFuzzy() {
return std::make_unique<Screens::WatchFaceFuzzy>(dateTimeController,
batteryController,
bleController,
notificationManager,
heartRateController,
motionController);
}

View File

@ -54,6 +54,7 @@ namespace Pinetime {
std::unique_ptr<Screen> WatchFaceTerminalScreen(); std::unique_ptr<Screen> WatchFaceTerminalScreen();
std::unique_ptr<Screen> WatchFaceInfineatScreen(); std::unique_ptr<Screen> WatchFaceInfineatScreen();
std::unique_ptr<Screen> WatchFaceCasioStyleG7710(); std::unique_ptr<Screen> WatchFaceCasioStyleG7710();
std::unique_ptr<Screen> WatchFaceFuzzy();
}; };
} }
} }

View File

@ -0,0 +1,158 @@
#include "displayapp/screens/WatchFaceFuzzy.h"
#include <lvgl/lvgl.h>
#include <cstdio>
#include <lvgl/src/lv_core/lv_obj_style_dec.h>
#include <lvgl/src/lv_font/lv_font.h>
#include <lvgl/src/lv_misc/lv_area.h>
#include "displayapp/screens/NotificationIcon.h"
#include "displayapp/screens/Symbols.h"
#include "components/battery/BatteryController.h"
#include "components/ble/BleController.h"
#include "components/ble/NotificationManager.h"
#include "components/heartrate/HeartRateController.h"
#include "components/motion/MotionController.h"
using namespace Pinetime::Applications::Screens;
WatchFaceFuzzy::WatchFaceFuzzy(Controllers::DateTime& dateTimeController,
const Controllers::Battery& batteryController,
const Controllers::Ble& bleController,
Controllers::NotificationManager& notificationManager,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController)
: currentDateTime {{}},
dateTimeController {dateTimeController},
notificationManager {notificationManager},
heartRateController {heartRateController},
motionController {motionController},
statusIcons(batteryController, bleController) {
statusIcons.Create();
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME);
lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false));
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
label_time = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &vulf_mono_italic);
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
lv_label_set_recolor(label_time, true);
label_date = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999));
lv_obj_align(label_date, label_time, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);
heartbeatIcon = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text_static(heartbeatIcon, Symbols::heartBeat);
lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B));
lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B));
lv_label_set_text_static(heartbeatValue, "");
lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
stepValue = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7));
lv_label_set_text_static(stepValue, "0");
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
stepIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(stepIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FFE7));
lv_label_set_text_static(stepIcon, Symbols::shoe);
lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0);
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
Refresh();
}
WatchFaceFuzzy::~WatchFaceFuzzy() {
lv_task_del(taskRefresh);
lv_obj_clean(lv_scr_act());
}
void WatchFaceFuzzy::Refresh() {
statusIcons.Update();
notificationState = notificationManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(notificationState.Get()));
}
currentDateTime = std::chrono::time_point_cast<std::chrono::minutes>(dateTimeController.CurrentDateTime());
if (currentDateTime.IsUpdated()) {
uint8_t hour = dateTimeController.Hours();
uint8_t minute = dateTimeController.Minutes();
printTimeWords(static_cast<int>(hour), static_cast<int>(minute));
currentDate = std::chrono::time_point_cast<days>(currentDateTime.Get());
if (currentDate.IsUpdated()) {
uint16_t year = dateTimeController.Year();
uint8_t day = dateTimeController.Day();
lv_label_set_text_fmt(label_date,
"%s %d %s %d",
dateTimeController.DayOfWeekShortToString(),
day,
dateTimeController.MonthShortToString(),
year);
lv_obj_realign(label_date);
}
}
heartbeat = heartRateController.HeartRate();
heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
if (heartbeatRunning.Get()) {
lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xCE1B1B));
lv_label_set_text_fmt(heartbeatValue, "%d", heartbeat.Get());
} else {
lv_obj_set_style_local_text_color(heartbeatIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x1B1B1B));
lv_label_set_text_static(heartbeatValue, "");
}
lv_obj_realign(heartbeatIcon);
lv_obj_realign(heartbeatValue);
}
stepCount = motionController.NbSteps();
if (stepCount.IsUpdated()) {
lv_label_set_text_fmt(stepValue, "%lu", stepCount.Get());
lv_obj_realign(stepValue);
lv_obj_realign(stepIcon);
}
}
char const* WatchFaceFuzzy::mods[] = {"", "five", "ten", "quarter", "twenty", "twenty five", "half"};
char const* WatchFaceFuzzy::nums[] = {"twelve", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"};
void WatchFaceFuzzy::printTimeWords(int h, int m) {
const char* mod;
if (m <= 30) {
mod = mods[m / 5];
} else {
mod = mods[(60-m) / 5];
}
h = (h % 12);
if (m >= 56) {
sprintf(timeStr, "#ffffff nearly %s#\n#808080 o' clock#", nums[(h+1) % 12]);
}
else if (m == 0 || m <= 4) {
sprintf(timeStr, "#ffffff %s#\n#808080 o' clock#", nums[h]);
}
else if (m <= 32) {
sprintf(timeStr, "#ffffff %s#\n#808080 past# #FFFFFF %s#", mod, nums[h]);
}
else if (m > 32) {
sprintf(timeStr, "#ffffff %s#\n#808080 to# #FFFFFF %s#", mod, nums[(h+1) % 12]);
}
lv_label_set_text(label_time, timeStr);
}

View File

@ -0,0 +1,80 @@
#pragma once
#include <lvgl/src/lv_core/lv_obj.h>
#include <chrono>
#include <cstdint>
#include <memory>
#include "displayapp/screens/Screen.h"
#include "components/datetime/DateTimeController.h"
#include "components/ble/BleController.h"
#include "displayapp/widgets/StatusIcons.h"
#include "utility/DirtyValue.h"
extern lv_font_t vulf_mono_italic;
namespace Pinetime {
namespace Controllers {
class Battery;
class Ble;
class NotificationManager;
class HeartRateController;
class MotionController;
}
namespace Applications {
namespace Screens {
class WatchFaceFuzzy : public Screen {
public:
WatchFaceFuzzy(Controllers::DateTime& dateTimeController,
const Controllers::Battery& batteryController,
const Controllers::Ble& bleController,
Controllers::NotificationManager& notificationManager,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController);
~WatchFaceFuzzy() override;
void Refresh() override;
private:
uint8_t displayedHour = -1;
uint8_t displayedMinute = -1;
static char const *nums[];
static char const *mods[];
char timeStr[64];
Utility::DirtyValue<uint8_t> batteryPercentRemaining {};
Utility::DirtyValue<bool> powerPresent {};
Utility::DirtyValue<bool> bleState {};
Utility::DirtyValue<bool> bleRadioEnabled {};
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>> currentDateTime {};
Utility::DirtyValue<uint32_t> stepCount {};
Utility::DirtyValue<uint8_t> heartbeat {};
Utility::DirtyValue<bool> heartbeatRunning {};
Utility::DirtyValue<bool> notificationState {};
using days = std::chrono::duration<int32_t, std::ratio<86400>>; // TODO: days is standard in c++20
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, days>> currentDate;
lv_obj_t* label_time;
lv_obj_t* label_date;
lv_obj_t* heartbeatIcon;
lv_obj_t* heartbeatValue;
lv_obj_t* stepIcon;
lv_obj_t* stepValue;
lv_obj_t* notificationIcon;
Controllers::DateTime& dateTimeController;
Controllers::NotificationManager& notificationManager;
Controllers::HeartRateController& heartRateController;
Controllers::MotionController& motionController;
lv_task_t* taskRefresh;
Widgets::StatusIcons statusIcons;
void printTimeWords(int h, int m);
};
}
}
}

View File

@ -9,8 +9,8 @@
#include "displayapp/screens/Screen.h" #include "displayapp/screens/Screen.h"
#include "displayapp/screens/Symbols.h" #include "displayapp/screens/Symbols.h"
#include "displayapp/screens/CheckboxList.h" #include "displayapp/screens/CheckboxList.h"
#include "displayapp/screens/WatchFaceInfineat.h"
#include "displayapp/screens/WatchFaceCasioStyleG7710.h" #include "displayapp/screens/WatchFaceCasioStyleG7710.h"
#include "displayapp/screens/WatchFaceFuzzy.h"
namespace Pinetime { namespace Pinetime {
@ -43,11 +43,8 @@ namespace Pinetime {
std::array<Screens::CheckboxList::Item, settingsPerScreen * nScreens> watchfaces { std::array<Screens::CheckboxList::Item, settingsPerScreen * nScreens> watchfaces {
{{"Digital face", true}, {{"Digital face", true},
{"Analog face", true}, {"Analog face", true},
{"PineTimeStyle", true},
{"Terminal", true},
{"Infineat face", Applications::Screens::WatchFaceInfineat::IsAvailable(filesystem)},
{"Casio G7710", Applications::Screens::WatchFaceCasioStyleG7710::IsAvailable(filesystem)}, {"Casio G7710", Applications::Screens::WatchFaceCasioStyleG7710::IsAvailable(filesystem)},
{"", false}, {"Fuzzy Clock", true},
{"", false}}}; {"", false}}};
ScreenList<nScreens> screens; ScreenList<nScreens> screens;
}; };