From 548c9021458d72f0ea8931281201d2dc40888f6e Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 28 Sep 2022 21:14:48 +0100 Subject: [PATCH 01/19] Add flag to make page indicator horizontal --- src/displayapp/widgets/PageIndicator.cpp | 21 +++++++++++---------- src/displayapp/widgets/PageIndicator.h | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/displayapp/widgets/PageIndicator.cpp b/src/displayapp/widgets/PageIndicator.cpp index 84d03e7ed0..2f4996876a 100644 --- a/src/displayapp/widgets/PageIndicator.cpp +++ b/src/displayapp/widgets/PageIndicator.cpp @@ -3,27 +3,28 @@ using namespace Pinetime::Applications::Widgets; -PageIndicator::PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens) : nCurrentScreen {nCurrentScreen}, nScreens {nScreens} { +PageIndicator::PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens, bool horizontal) + : nCurrentScreen {nCurrentScreen}, nScreens {nScreens}, horizontal {horizontal} { } void PageIndicator::Create() { - pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[0].y = 0; - pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[1].y = LV_VER_RES; + pageIndicatorBasePoints[0].x = horizontal ? 0 : LV_HOR_RES - 1; + pageIndicatorBasePoints[0].y = horizontal ? LV_VER_RES - 1 : 0; + pageIndicatorBasePoints[1].x = horizontal ? LV_HOR_RES : LV_HOR_RES - 1; + pageIndicatorBasePoints[1].y = horizontal ? LV_VER_RES - 1 : LV_VER_RES; pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, Colors::bgDark); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); - const int16_t indicatorSize = LV_VER_RES / nScreens; + const int16_t indicatorSize = (horizontal ? LV_HOR_RES : LV_VER_RES) / nScreens; const int16_t indicatorPos = indicatorSize * nCurrentScreen; - pageIndicatorPoints[0].x = LV_HOR_RES - 1; - pageIndicatorPoints[0].y = indicatorPos; - pageIndicatorPoints[1].x = LV_HOR_RES - 1; - pageIndicatorPoints[1].y = indicatorPos + indicatorSize; + pageIndicatorPoints[0].x = horizontal ? indicatorPos : LV_HOR_RES - 1; + pageIndicatorPoints[0].y = horizontal ? LV_VER_RES - 1 : indicatorPos; + pageIndicatorPoints[1].x = horizontal ? indicatorPos + indicatorSize : LV_HOR_RES - 1; + pageIndicatorPoints[1].y = horizontal ? LV_VER_RES - 1 : indicatorPos + indicatorSize; pageIndicator = lv_line_create(lv_scr_act(), nullptr); lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); diff --git a/src/displayapp/widgets/PageIndicator.h b/src/displayapp/widgets/PageIndicator.h index 8484735e58..ecafda0b57 100644 --- a/src/displayapp/widgets/PageIndicator.h +++ b/src/displayapp/widgets/PageIndicator.h @@ -6,12 +6,13 @@ namespace Pinetime { namespace Widgets { class PageIndicator { public: - PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens); + PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens, bool horizontal = false); void Create(); private: uint8_t nCurrentScreen; uint8_t nScreens; + bool horizontal; lv_point_t pageIndicatorBasePoints[2]; lv_point_t pageIndicatorPoints[2]; From 3183212c2207f046e9d33489308620326fb72ebe Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 29 Sep 2022 10:49:23 +0100 Subject: [PATCH 02/19] Turn watchface settings into a multipage checkbox list Generalizes code introduced with Infineat watchface --- src/CMakeLists.txt | 2 +- src/displayapp/screens/CheckboxList.cpp | 117 ----------------- src/displayapp/screens/CheckboxList.h | 48 ------- src/displayapp/screens/Container.cpp | 17 +++ src/displayapp/screens/Container.h | 22 ++++ src/displayapp/screens/ScreenList.h | 4 + .../screens/settings/SettingWatchFace.cpp | 120 ++++++++++++------ .../screens/settings/SettingWatchFace.h | 33 +++-- 8 files changed, 149 insertions(+), 214 deletions(-) delete mode 100644 src/displayapp/screens/CheckboxList.cpp delete mode 100644 src/displayapp/screens/CheckboxList.h create mode 100644 src/displayapp/screens/Container.cpp create mode 100644 src/displayapp/screens/Container.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0bcb788fae..d1ba3898af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -396,7 +396,7 @@ list(APPEND SOURCE_FILES displayapp/screens/Motion.cpp displayapp/screens/FlashLight.cpp displayapp/screens/List.cpp - displayapp/screens/CheckboxList.cpp + displayapp/screens/Container.cpp displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp diff --git a/src/displayapp/screens/CheckboxList.cpp b/src/displayapp/screens/CheckboxList.cpp deleted file mode 100644 index b89add4333..0000000000 --- a/src/displayapp/screens/CheckboxList.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "displayapp/screens/CheckboxList.h" -#include "displayapp/DisplayApp.h" -#include "displayapp/screens/Styles.h" - -using namespace Pinetime::Applications::Screens; - -namespace { - static void event_handler(lv_obj_t* obj, lv_event_t event) { - CheckboxList* screen = static_cast(obj->user_data); - screen->UpdateSelected(obj, event); - } - -} - -CheckboxList::CheckboxList(const uint8_t screenID, - const uint8_t numScreens, - DisplayApp* app, - Controllers::Settings& settingsController, - const char* optionsTitle, - const char* optionsSymbol, - void (Controllers::Settings::*SetOptionIndex)(uint8_t), - uint8_t (Controllers::Settings::*GetOptionIndex)() const, - std::array options) - : Screen(app), - screenID {screenID}, - settingsController {settingsController}, - SetOptionIndex {SetOptionIndex}, - GetOptionIndex {GetOptionIndex}, - options {options} { - - settingsController.SetWatchfacesMenu(screenID); - - // Set the background to Black - lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); - - if (numScreens > 1) { - pageIndicatorBasePoints[0].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[0].y = 0; - pageIndicatorBasePoints[1].x = LV_HOR_RES - 1; - pageIndicatorBasePoints[1].y = LV_VER_RES; - - pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); - lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints.data(), 2); - - const uint16_t indicatorSize = LV_VER_RES / numScreens; - const uint16_t indicatorPos = indicatorSize * screenID; - - pageIndicatorPoints[0].x = LV_HOR_RES - 1; - pageIndicatorPoints[0].y = indicatorPos; - pageIndicatorPoints[1].x = LV_HOR_RES - 1; - pageIndicatorPoints[1].y = indicatorPos + indicatorSize; - - pageIndicator = lv_line_create(lv_scr_act(), NULL); - lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); - lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_line_set_points(pageIndicator, pageIndicatorPoints.data(), 2); - } - - lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); - - 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, 10, 60); - lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); - lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); - - lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title, optionsTitle); - lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); - lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); - - lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - lv_label_set_text_static(icon, optionsSymbol); - lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); - lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); - - for (unsigned int i = 0; i < options.size(); i++) { - if (strcmp(options[i], "")) { - cbOption[i] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text(cbOption[i], options[i]); - cbOption[i]->user_data = this; - lv_obj_set_event_cb(cbOption[i], event_handler); - SetRadioButtonStyle(cbOption[i]); - - if (static_cast((settingsController.*GetOptionIndex)() - MaxItems * screenID) == i) { - lv_checkbox_set_checked(cbOption[i], true); - } - } - } -} - -CheckboxList::~CheckboxList() { - lv_obj_clean(lv_scr_act()); - settingsController.SaveSettings(); -} - -void CheckboxList::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (unsigned int i = 0; i < options.size(); i++) { - if (strcmp(options[i], "")) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); - (settingsController.*SetOptionIndex)(MaxItems * screenID + i); - } else { - lv_checkbox_set_checked(cbOption[i], false); - } - } - } - } -} diff --git a/src/displayapp/screens/CheckboxList.h b/src/displayapp/screens/CheckboxList.h deleted file mode 100644 index 5bdd143e3d..0000000000 --- a/src/displayapp/screens/CheckboxList.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "displayapp/screens/Screen.h" -#include "displayapp/Apps.h" -#include "components/settings/Settings.h" - -namespace Pinetime { - namespace Applications { - namespace Screens { - class CheckboxList : public Screen { - public: - static constexpr size_t MaxItems = 4; - - CheckboxList(const uint8_t screenID, - const uint8_t numScreens, - DisplayApp* app, - Controllers::Settings& settingsController, - const char* optionsTitle, - const char* optionsSymbol, - void (Controllers::Settings::*SetOptionIndex)(uint8_t), - uint8_t (Controllers::Settings::*GetOptionIndex)() const, - std::array options); - - ~CheckboxList() override; - - void UpdateSelected(lv_obj_t* object, lv_event_t event); - - private: - const uint8_t screenID; - Controllers::Settings& settingsController; - const char* optionsTitle; - const char* optionsSymbol; - void (Controllers::Settings::*SetOptionIndex)(uint8_t); - uint8_t (Controllers::Settings::*GetOptionIndex)() const; - std::array options; - std::array cbOption; - std::array pageIndicatorBasePoints; - std::array pageIndicatorPoints; - lv_obj_t* pageIndicatorBase; - lv_obj_t* pageIndicator; - }; - } - } -} diff --git a/src/displayapp/screens/Container.cpp b/src/displayapp/screens/Container.cpp new file mode 100644 index 0000000000..a04312fb9f --- /dev/null +++ b/src/displayapp/screens/Container.cpp @@ -0,0 +1,17 @@ +#include "displayapp/screens/Container.h" + +using namespace Pinetime::Applications::Screens; + +Container::Container( + DisplayApp* app, + lv_obj_t* container, + uint8_t screenIdx, + uint8_t nScreens, + bool horizontal) + : Screen(app), container {container}, pageIndicator {screenIdx, nScreens, horizontal} { + pageIndicator.Create(); +} + +Container::~Container() { + lv_obj_clean(lv_scr_act()); +} diff --git a/src/displayapp/screens/Container.h b/src/displayapp/screens/Container.h new file mode 100644 index 0000000000..7d3787812c --- /dev/null +++ b/src/displayapp/screens/Container.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include "displayapp/screens/Screen.h" +#include "displayapp/widgets/PageIndicator.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Container : public Screen { + public: + Container(DisplayApp* app, lv_obj_t* container, uint8_t screenIdx, uint8_t nScreens, bool horizontal = false); + ~Container() override; + + private: + lv_obj_t* container; + Widgets::PageIndicator pageIndicator; + }; + } + } +} diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index ad882948de..38a7612f2f 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -99,6 +99,10 @@ namespace Pinetime { return false; } + uint8_t getScreenIndex() { + return screenIndex; + } + private: uint8_t initScreen = 0; const std::array()>, N> screens; diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index bd2f349c3e..fb4168d582 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -9,54 +9,98 @@ using namespace Pinetime::Applications::Screens; -constexpr const char* SettingWatchFace::title; -constexpr const char* SettingWatchFace::symbol; +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* settings = static_cast(obj->user_data); + settings->UpdateSelected(obj, event); + } +} + +auto SettingWatchFace::CreateScreenList() { + std::array()>, nScreens> screens; + for (uint8_t i = 0; i < screens.size(); i++) { + screens[i] = [this, i]() -> std::unique_ptr { return CreateScreen(i); }; + } + return screens; +} + +std::unique_ptr SettingWatchFace::CreateScreen(uint8_t screenIdx) { + /* Container */ + lv_obj_t* container = lv_obj_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_size(container, LV_HOR_RES, LV_VER_RES); + lv_obj_set_pos(container, 0, 0); + + /* Title... */ + lv_obj_t* title = lv_label_create(container, nullptr); + lv_label_set_text_static(title, this.title); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, container, LV_ALIGN_IN_TOP_MID, 10, 15); + + /* ...with icon */ + lv_obj_t* icon = lv_label_create(container, nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, this.icon); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + /* Watchface option list */ + lv_obj_t* list = lv_cont_create(container, nullptr); + + lv_obj_set_style_local_bg_opa(list, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(list, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(list, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(list, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); -SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + lv_obj_set_pos(list, 10, 60); + lv_obj_set_width(list, LV_HOR_RES - 20); + lv_obj_set_height(list, LV_VER_RES - 50); + lv_cont_set_layout(list, LV_LAYOUT_COLUMN_LEFT); + + for (uint8_t i = 0; i < optionsPerScreen ; i++) { + uint8_t optionIdx = screenIdx * optionsPerScreen + i; + if (optionIdx < nOptions) { + lv_obj_t* checkbox = lv_checkbox_create(list, nullptr); + lv_checkbox_set_text(checkbox, options[optionIdx]); + checkbox->user_data = this; + lv_obj_set_event_cb(checkbox, event_handler); + SetRadioButtonStyle(checkbox); + if (optionIdx == settingsController.GetClockFace()) { + lv_checkbox_set_checked(checkbox, true); + } + checkboxes[i] = checkbox; + } else { + checkboxes[i] = nullptr; + } + } + + return std::make_unique(app, container, screenIdx, nScreens, true); +} + +SettingWatchFace::SettingWatchFace(DisplayApp* app, Controllers::Settings& settingsController) : Screen(app), settingsController {settingsController}, - screens {app, - settingsController.GetWatchfacesMenu(), - {[this]() -> std::unique_ptr { - return CreateScreen1(); - }, - [this]() -> std::unique_ptr { - return CreateScreen2(); - }}, - Screens::ScreenListModes::UpDown} { -} + screens {app, 0, CreateScreenList(), Screens::ScreenListModes::RightLeft} { } SettingWatchFace::~SettingWatchFace() { lv_obj_clean(lv_scr_act()); settingsController.SaveSettings(); } -bool SettingWatchFace::OnTouchEvent(Pinetime::Applications::TouchEvents event) { +bool SettingWatchFace::OnTouchEvent(Applications::TouchEvents event) { return screens.OnTouchEvent(event); } -std::unique_ptr SettingWatchFace::CreateScreen1() { - std::array watchfaces {"Digital face", "Analog face", "PineTimeStyle", "Terminal"}; - return std::make_unique(0, - 2, - app, - settingsController, - title, - symbol, - &Controllers::Settings::SetClockFace, - &Controllers::Settings::GetClockFace, - watchfaces); -} - -std::unique_ptr SettingWatchFace::CreateScreen2() { - std::array watchfaces {"Infineat face", "", "", ""}; - return std::make_unique(1, - 2, - app, - settingsController, - title, - symbol, - &Controllers::Settings::SetClockFace, - &Controllers::Settings::GetClockFace, - watchfaces); +void SettingWatchFace::UpdateSelected(lv_obj_t* obj, lv_event_t event) { + if (event == LV_EVENT_VALUE_CHANGED) { + uint8_t screenIdx = screens.getScreenIndex(); + for (uint8_t i = 0; i < optionsPerScreen && checkboxes[i]; i++) { + if (obj == checkboxes[i]) { + lv_checkbox_set_checked(checkboxes[i], true); + settingsController.SetClockFace(screenIdx * optionsPerScreen + i); + } else { + lv_checkbox_set_checked(checkboxes[i], false); + } + } + } } diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 7d14554eb2..85ba243499 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -3,32 +3,45 @@ #include #include #include - +#include "displayapp/screens/Screen.h" #include "displayapp/screens/ScreenList.h" +#include "displayapp/screens/Container.h" #include "components/settings/Settings.h" -#include "displayapp/screens/Screen.h" -#include "displayapp/screens/Symbols.h" namespace Pinetime { - namespace Applications { namespace Screens { class SettingWatchFace : public Screen { public: - SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + SettingWatchFace(DisplayApp* app, Controllers::Settings& settingsController); ~SettingWatchFace() override; - bool OnTouchEvent(TouchEvents event) override; + bool OnTouchEvent(Applications::TouchEvents event) override; + + void UpdateSelected(lv_obj_t* object, lv_event_t event); private: + static constexpr const char* icon = Symbols::home; + static constexpr const char* title = "Watch face"; + + static constexpr uint8_t optionsPerScreen = 4; + static constexpr uint8_t nOptions = 6; + static constexpr uint8_t nScreens = (nOptions + optionsPerScreen - 1) / optionsPerScreen; + static constexpr std::array options = { + "Digital face", "Analog face", "PineTimeStyle", "Terminal", + "Infineat", "Fuzzy face", + }; + + auto CreateScreenList(); + std::unique_ptr CreateScreen(uint8_t screenIdx); + Controllers::Settings& settingsController; ScreenList<2> screens; - static constexpr const char* title = "Watch face"; - static constexpr const char* symbol = Symbols::home; - std::unique_ptr CreateScreen1(); - std::unique_ptr CreateScreen2(); + ScreenList screens; + + lv_obj_t* checkboxes[optionsPerScreen]; }; } } From 9ba1420abe028765a0ae6d998b85d004f15f645d Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 10 Sep 2021 23:39:32 +0100 Subject: [PATCH 03/19] Add first implementation of a fuzzy watchface --- src/CMakeLists.txt | 2 + .../fonts/jetbrains_mono_regular_36.c | 361 ++++++++++++++++++ src/displayapp/screens/Clock.cpp | 8 + src/displayapp/screens/Clock.h | 1 + src/displayapp/screens/WatchFaceFuzzy.cpp | 120 ++++++ src/displayapp/screens/WatchFaceFuzzy.h | 28 ++ src/libs/lv_conf.h | 1 + 7 files changed, 521 insertions(+) create mode 100644 src/displayapp/fonts/jetbrains_mono_regular_36.c create mode 100644 src/displayapp/screens/WatchFaceFuzzy.cpp create mode 100644 src/displayapp/screens/WatchFaceFuzzy.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d1ba3898af..29348c8329 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -429,7 +429,9 @@ list(APPEND SOURCE_FILES displayapp/screens/WatchFaceDigital.cpp displayapp/screens/WatchFaceInfineat.cpp displayapp/screens/WatchFaceTerminal.cpp + displayapp/screens/WatchFaceFuzzy.cpp displayapp/screens/WatchFacePineTimeStyle.cpp + displayapp/screens/PineTimeStyle.cpp ## diff --git a/src/displayapp/fonts/jetbrains_mono_regular_36.c b/src/displayapp/fonts/jetbrains_mono_regular_36.c new file mode 100644 index 0000000000..74d4794667 --- /dev/null +++ b/src/displayapp/fonts/jetbrains_mono_regular_36.c @@ -0,0 +1,361 @@ +/******************************************************************************* + * Size: 36 px + * Bpp: 1 + * Opts: + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef JETBRAINS_MONO_REGULAR_36 +#define JETBRAINS_MONO_REGULAR_36 1 +#endif + +#if JETBRAINS_MONO_REGULAR_36 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0027 "'" */ + 0xff, 0xff, 0xff, 0xfc, + + /* U+0061 "a" */ + 0x7, 0xf0, 0x1f, 0xfc, 0x3f, 0xfe, 0x7c, 0x1e, + 0x78, 0xf, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, + 0xf, 0xff, 0x3f, 0xff, 0x7f, 0xff, 0xf0, 0x7, + 0xe0, 0x7, 0xe0, 0x7, 0xe0, 0x7, 0xf0, 0xf, + 0xf8, 0x3f, 0x7f, 0xf7, 0x3f, 0xe7, 0xf, 0xc7, + + /* U+0062 "b" */ + 0xe0, 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, + 0x0, 0x1c, 0x0, 0x38, 0xf8, 0x77, 0xfc, 0xef, + 0xfd, 0xf0, 0x7b, 0xc0, 0x7f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, + 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfe, + 0x3, 0xfe, 0xf, 0x77, 0xfe, 0xef, 0xf9, 0xc7, + 0xc0, + + /* U+0063 "c" */ + 0xf, 0xe0, 0x3f, 0xf0, 0xff, 0xf3, 0xc1, 0xef, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x0, 0xe0, + 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, + 0x1c, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, + 0x7f, 0xf8, 0x7f, 0xe0, 0x7f, 0x0, + + /* U+0064 "d" */ + 0x0, 0xe, 0x0, 0x1c, 0x0, 0x38, 0x0, 0x70, + 0x0, 0xe0, 0x1, 0xc3, 0xe3, 0x9f, 0xf7, 0x7f, + 0xee, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, + 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfe, + 0x3, 0xde, 0xf, 0xbf, 0xf7, 0x3f, 0xee, 0x1f, + 0x1c, + + /* U+0065 "e" */ + 0xf, 0xe0, 0x3f, 0xe0, 0xff, 0xe3, 0xc1, 0xef, + 0x1, 0xdc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xe, 0x0, + 0x1c, 0x0, 0x38, 0x0, 0x78, 0xf, 0x78, 0x3c, + 0x7f, 0xf8, 0x7f, 0xe0, 0x7f, 0x0, + + /* U+0066 "f" */ + 0x0, 0x7f, 0x80, 0xff, 0xc0, 0xff, 0xe0, 0x78, + 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, + 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, + 0x0, 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, + 0x0, 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, + + /* U+0067 "g" */ + 0xf, 0x8e, 0x7f, 0xdd, 0xff, 0xfb, 0xc1, 0xff, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfe, 0x3, 0xde, 0xf, 0xbf, 0xf7, 0x3f, 0xee, + 0x1f, 0x1c, 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, + 0x1, 0xc0, 0x7, 0x9f, 0xfe, 0x3f, 0xf8, 0x7f, + 0xe0, + + /* U+0068 "h" */ + 0xe0, 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, + 0x0, 0x1c, 0x0, 0x38, 0xf8, 0x77, 0xfc, 0xef, + 0xfd, 0xf0, 0x7b, 0xc0, 0x7f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, + 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfc, + 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, 0xc0, + 0x1c, + + /* U+0069 "i" */ + 0x1, 0xc0, 0x1, 0xf0, 0x0, 0xf8, 0x0, 0x38, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x80, 0x7f, 0xc0, 0x3f, 0xe0, 0x0, 0x70, 0x0, + 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, 0x0, + 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, 0x70, + 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, + 0x0, 0x3, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, + + /* U+006A "j" */ + 0x0, 0x38, 0x1, 0xf0, 0x7, 0xc0, 0xe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf9, + 0xff, 0xe7, 0xff, 0x80, 0xe, 0x0, 0x38, 0x0, + 0xe0, 0x3, 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, + 0x3, 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, 0x3, + 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, 0x3, 0x80, + 0xe, 0x0, 0x38, 0x1, 0xc0, 0xf, 0x3f, 0xf8, + 0xff, 0xc3, 0xfc, 0x0, + + /* U+006B "k" */ + 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0x0, + 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0xf, 0xe0, 0x1e, + 0xe0, 0x1e, 0xe0, 0x3c, 0xe0, 0x78, 0xe0, 0x70, + 0xe0, 0xf0, 0xe1, 0xe0, 0xff, 0xc0, 0xff, 0xc0, + 0xff, 0xc0, 0xe1, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, + 0xe0, 0x78, 0xe0, 0x3c, 0xe0, 0x3c, 0xe0, 0x1e, + 0xe0, 0xe, 0xe0, 0xf, + + /* U+006C "l" */ + 0xff, 0xc0, 0x1f, 0xf8, 0x3, 0xff, 0x0, 0x0, + 0xe0, 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, 0x70, + 0x0, 0xe, 0x0, 0x1, 0xc0, 0x0, 0x38, 0x0, + 0x7, 0x0, 0x0, 0xe0, 0x0, 0x1c, 0x0, 0x3, + 0x80, 0x0, 0x70, 0x0, 0xe, 0x0, 0x1, 0xc0, + 0x0, 0x38, 0x0, 0x7, 0x0, 0x0, 0xe0, 0x0, + 0x1c, 0x0, 0x3, 0x80, 0x0, 0x78, 0x0, 0x7, + 0xff, 0x0, 0x7f, 0xe0, 0x7, 0xfc, + + /* U+006D "m" */ + 0xe7, 0x1e, 0x77, 0xdf, 0xbf, 0xef, 0xfe, 0x7c, + 0xfe, 0x1c, 0x3f, 0xe, 0x1f, 0x87, 0xf, 0xc3, + 0x87, 0xe1, 0xc3, 0xf0, 0xe1, 0xf8, 0x70, 0xfc, + 0x38, 0x7e, 0x1c, 0x3f, 0xe, 0x1f, 0x87, 0xf, + 0xc3, 0x87, 0xe1, 0xc3, 0xf0, 0xe1, 0xf8, 0x70, + 0xfc, 0x38, 0x70, + + /* U+006E "n" */ + 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, + 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x70, + + /* U+006F "o" */ + 0xf, 0xe0, 0x3f, 0xe0, 0xff, 0xe3, 0xc1, 0xef, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, + 0x7f, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, + + /* U+0070 "p" */ + 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0xf8, 0x3d, + 0xdf, 0xfb, 0xbf, 0xe7, 0x1f, 0xe, 0x0, 0x1c, + 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, 0x1, 0xc0, + 0x0, + + /* U+0071 "q" */ + 0xf, 0x8e, 0x7f, 0xdd, 0xff, 0xbb, 0xc1, 0xff, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3e, + 0xff, 0xdc, 0xff, 0xb8, 0x7c, 0x70, 0x0, 0xe0, + 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, + 0x1c, + + /* U+0072 "r" */ + 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, + 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, + 0x1c, 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, 0x1, + 0xc0, 0x3, 0x80, 0x7, 0x0, 0x0, + + /* U+0073 "s" */ + 0xf, 0xf0, 0x3f, 0xf0, 0xff, 0xf3, 0xc0, 0xf7, + 0x0, 0xee, 0x0, 0x1c, 0x0, 0x3c, 0x0, 0x3f, + 0x80, 0x3f, 0xe0, 0x1f, 0xf0, 0x3, 0xe0, 0x1, + 0xe0, 0x1, 0xc0, 0x3, 0xf0, 0x7, 0xf0, 0x1e, + 0xff, 0xf8, 0xff, 0xe0, 0x7f, 0x0, + + /* U+0074 "t" */ + 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, 0x70, + 0x0, 0x38, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, + 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, + 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, + 0x0, 0x70, 0x0, 0x38, 0x0, 0x1e, 0x0, 0x7, + 0xfe, 0x3, 0xff, 0x0, 0x7f, 0x80, + + /* U+0075 "u" */ + 0xe0, 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, + 0x0, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, + 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, + 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, + 0x7f, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, + + /* U+0076 "v" */ + 0xe0, 0x3, 0xfc, 0x0, 0xe7, 0x0, 0x39, 0xc0, + 0x1e, 0x78, 0x7, 0xe, 0x1, 0xc3, 0x80, 0xf0, + 0xf0, 0x38, 0x1c, 0xe, 0x7, 0x7, 0x81, 0xe1, + 0xc0, 0x38, 0x70, 0xe, 0x3c, 0x3, 0xce, 0x0, + 0x73, 0x80, 0x1d, 0xc0, 0x7, 0xf0, 0x0, 0xfc, + 0x0, 0x3e, 0x0, 0xf, 0x80, + + /* U+0077 "w" */ + 0xe0, 0xe0, 0xfc, 0x1c, 0x1f, 0x87, 0x83, 0x70, + 0xf0, 0x66, 0x1b, 0x1c, 0xc3, 0x63, 0x9c, 0x6c, + 0x73, 0x8d, 0x8e, 0x73, 0x31, 0x8e, 0x66, 0x30, + 0xcc, 0x66, 0x19, 0x8d, 0xc3, 0x31, 0xb8, 0x76, + 0x37, 0xe, 0x86, 0xc1, 0xf0, 0xd8, 0x3e, 0x1b, + 0x3, 0xc1, 0xe0, 0x78, 0x3c, 0xf, 0x7, 0x80, + + /* U+0078 "x" */ + 0x70, 0x7, 0x9e, 0x1, 0xc3, 0xc0, 0xf0, 0x70, + 0x78, 0x1e, 0x1c, 0x3, 0xcf, 0x0, 0x77, 0x80, + 0x1f, 0xc0, 0x3, 0xf0, 0x0, 0x78, 0x0, 0x3e, + 0x0, 0xf, 0xc0, 0x7, 0x78, 0x3, 0xce, 0x0, + 0xe3, 0xc0, 0x78, 0x78, 0x3c, 0xe, 0x1e, 0x3, + 0xc7, 0x80, 0x7b, 0xc0, 0xe, + + /* U+0079 "y" */ + 0xf0, 0x3, 0xfc, 0x0, 0xe7, 0x0, 0x79, 0xe0, + 0x1c, 0x38, 0x7, 0xf, 0x3, 0xc3, 0xc0, 0xe0, + 0x70, 0x38, 0x1e, 0x1e, 0x3, 0x87, 0x0, 0xf3, + 0xc0, 0x1c, 0xe0, 0x7, 0x38, 0x1, 0xfe, 0x0, + 0x3f, 0x0, 0xf, 0xc0, 0x1, 0xe0, 0x0, 0x78, + 0x0, 0x1e, 0x0, 0x7, 0x0, 0x1, 0xc0, 0x0, + 0xf0, 0x0, 0x38, 0x0, 0x1e, 0x0, 0x7, 0x0, + 0x1, 0xc0, 0x0, + + /* U+007A "z" */ + 0x7f, 0xfe, 0xff, 0xfd, 0xff, 0xf8, 0x0, 0xf0, + 0x3, 0xc0, 0xf, 0x0, 0x1c, 0x0, 0x78, 0x1, + 0xe0, 0x7, 0x80, 0x1e, 0x0, 0x78, 0x0, 0xf0, + 0x3, 0xc0, 0xf, 0x0, 0x3c, 0x0, 0xf0, 0x1, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 +}; + + +/*--------------------- + * 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 = 346, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 346, .box_w = 3, .box_h = 10, .ofs_x = 9, .ofs_y = 16}, + {.bitmap_index = 5, .adv_w = 346, .box_w = 16, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 45, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 94, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 132, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 181, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 219, .adv_w = 346, .box_w = 17, .box_h = 26, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 275, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, + {.bitmap_index = 324, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 373, .adv_w = 346, .box_w = 17, .box_h = 27, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 431, .adv_w = 346, .box_w = 14, .box_h = 34, .ofs_x = 3, .ofs_y = -6}, + {.bitmap_index = 491, .adv_w = 346, .box_w = 16, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 543, .adv_w = 346, .box_w = 19, .box_h = 26, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 605, .adv_w = 346, .box_w = 17, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 648, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 686, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 724, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, + {.bitmap_index = 773, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, + {.bitmap_index = 822, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 860, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 898, .adv_w = 346, .box_w = 17, .box_h = 25, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 952, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 990, .adv_w = 346, .box_w = 18, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1035, .adv_w = 346, .box_w = 19, .box_h = 20, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1083, .adv_w = 346, .box_w = 18, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1128, .adv_w = 346, .box_w = 18, .box_h = 26, .ofs_x = 2, .ofs_y = -6}, + {.bitmap_index = 1187, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_0[] = { + 0x0, 0x7 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 8, .glyph_id_start = 1, + .unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 2, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + }, + { + .range_start = 97, .range_length = 26, .glyph_id_start = 3, + .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_regular_36 = { +#else +lv_font_t jetbrains_mono_regular_36 = { +#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 = 34, /*The maximum line height required by the font*/ + .base_line = 6, /*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 = -6, + .underline_thickness = 2, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + + + +#endif /*#if JETBRAINS_MONO_REGULAR_36*/ + diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index d1e0f5659f..6961f52ea0 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -13,6 +13,7 @@ #include "displayapp/screens/WatchFaceInfineat.h" #include "displayapp/screens/WatchFaceAnalog.h" #include "displayapp/screens/WatchFacePineTimeStyle.h" +#include "displayapp/screens/WatchFaceFuzzy.h" using namespace Pinetime::Applications::Screens; @@ -51,6 +52,9 @@ Clock::Clock(DisplayApp* app, case 4: return WatchFaceInfineatScreen(); break; + case 5: + return WatchFaceFuzzyScreen(); + break; } return WatchFaceDigitalScreen(); }()} { @@ -120,3 +124,7 @@ std::unique_ptr Clock::WatchFaceInfineatScreen() { motionController, filesystem); } + +std::unique_ptr Clock::WatchFaceFuzzyScreen() { + return std::make_unique(app, dateTimeController); +} diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index e5605c5f54..118a350935 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -51,6 +51,7 @@ namespace Pinetime { std::unique_ptr WatchFacePineTimeStyleScreen(); std::unique_ptr WatchFaceTerminalScreen(); std::unique_ptr WatchFaceInfineatScreen(); + std::unique_ptr WatchFaceFuzzyScreen(); }; } } diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp new file mode 100644 index 0000000000..e4e5cc8cd0 --- /dev/null +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -0,0 +1,120 @@ +#include "WatchFaceFuzzy.h" + +//#include +#include +//#include + +using namespace Pinetime::Applications::Screens; + +WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController) + : Screen(app), dateTimeController {dateTimeController} { + + /* Why would we need this? */ + //settingsController.SetClockFace(0); + + /* + * `lv_scr_act()` get the active screen on the default display + * (note that we only have one display in this setup, but LVGL has + * multidisplay support as well). + * + * `nullptr` is used simply because we don't want to *copy* the label + * from any other object. + */ + label_time = lv_label_create(lv_scr_act(), nullptr); + + /* Set size of the label to screen size */ + lv_obj_set_size(label_time, LV_HOR_RES, LV_VER_RES); + + /* Set the behavior of the label when the text is longer than the + * object size. In this case we want to break the text to keep the + * width and extend the height of the obj. + * + * Note: this doesn't work properly or it is someone dependent on when + * it is called. Avoiding it for now and specifying linebreaks + * directly in the string. + */ + //lv_label_set_long_mode(label_time, LV_LABEL_LONG_BREAK); + + /* Set text alignment (left) in the label */ + lv_label_set_align(label_time, LV_LABEL_ALIGN_LEFT); + + /* Set main color and font for the label + * Note: color can be changed when setting the text as well allowing + * for multicolor strings. Can we do this with fonts as well? + * + * "local" style take precedence over global styles + * + * `LV_LABEL_PART_MAIN` is the only "part" of a label. + * + * `LV_STATE_DEFAULT` is the label state (which cannot be checked or + * toggled or whatever...). + */ + lv_label_set_recolor(label_time, true); + lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x777777)); + lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_regular_36); + + /* Creates a new LVGL task called periodically. + * lv_task_create(callback, period, priority, userdata) + * callback: in this case is a generic wrapper of Refresh() + * period: how often the callback is triggered (every 60s == 60000ms) + * priority: see LVGL for more info + * userdata: accessible from the callback (see Screen.cpp) + */ + taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); + + /* Refresh to avoid waiting for 60s */ + Refresh(); +} + +WatchFaceFuzzy::~WatchFaceFuzzy() { + /* Remove refresh task for this watchface */ + lv_task_del(taskRefresh); + /* Delete all children of the active screen (this watchface) */ + lv_obj_clean(lv_scr_act()); +} + +void WatchFaceFuzzy::Refresh() { + /* Possible wordings: + * - " o'clock" + * - "half past " + * - "quarter past/to " + * - " past/to " + * - " past/to " + * - " past/to " + */ + uint8_t hours, minutes, minutesUnits; + char const* pastTo = "past"; + char const* hoursAccent = "ffffff"; + char const* strings[20] = { "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", "eleven", "twelve", + "thirteen", "fourteen", "quarter", "seventeen", "eighteen", "nineteen", + "twenty" }; + hours = dateTimeController.Hours() % 12; + minutes = dateTimeController.Minutes(); + if (minutes > 30) { + pastTo = "to"; + hours = (hours + 1) % 12; + minutes = 60 - minutes; + } + minutesUnits = minutes % 10; + auto hoursStr = strings[(hours + 11) % 12]; + if (minutes == 0) { + lv_label_set_text_fmt(label_time, "#%s %s#\no'clock", hoursAccent, hoursStr); + } else if (minutes == 30) { + lv_label_set_text_fmt(label_time, "half\npast\n#%s %s#", hoursAccent, hoursStr); + } else if (minutes <= 20) { + lv_label_set_text_fmt(label_time, "%s\n%s\n#%s %s#", strings[minutes - 1], pastTo, hoursAccent, hoursStr); + } else { + lv_label_set_text_fmt(label_time, "twenty\n%s %s\n#%s %s#", strings[minutesUnits - 1], pastTo, hoursAccent, hoursStr); + } + /* Align the label w.r.t. another object (active screen in this case) + * You can use the last two parameters to move the obj around + * *after the alignment*. + * See https://docs.lvgl.io/latest/en/html/_images/align.png for all + * possible alignments. + * + * NOTE: you should set the alignment after determining the size + * (and content) of the label to get a reliable result! + */ + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 10, -10); +} diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h new file mode 100644 index 0000000000..7a1380cefd --- /dev/null +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -0,0 +1,28 @@ +#pragma once + +#include +/* #include */ +/* #include */ +/* #include */ +#include "Screen.h" +//#include "ScreenList.h" +#include "components/datetime/DateTimeController.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class WatchFaceFuzzy : public Screen { + public: + WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController); + ~WatchFaceFuzzy() override; + void Refresh() override; + + private: + lv_obj_t* label_time; + Controllers::DateTime& dateTimeController; + lv_task_t* taskRefresh; + }; + } + } +} + diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 063f1d340d..2157b48878 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -417,6 +417,7 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed) \ LV_FONT_DECLARE(jetbrains_mono_42) \ LV_FONT_DECLARE(jetbrains_mono_76) \ + LV_FONT_DECLARE(jetbrains_mono_regular_36) \ LV_FONT_DECLARE(open_sans_light) \ LV_FONT_DECLARE(lv_font_sys_48) From 27c47c560526a826235f37906a8997e26abe29aa Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Sun, 12 Sep 2021 18:49:27 +0100 Subject: [PATCH 04/19] Make time actually fuzzy --- src/displayapp/screens/WatchFaceFuzzy.cpp | 25 ++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index e4e5cc8cd0..5f9ff67756 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -82,13 +82,14 @@ void WatchFaceFuzzy::Refresh() { * - " past/to " * - " past/to " */ - uint8_t hours, minutes, minutesUnits; + + uint8_t hours, minutes; char const* pastTo = "past"; char const* hoursAccent = "ffffff"; - char const* strings[20] = { "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "ten", "eleven", "twelve", - "thirteen", "fourteen", "quarter", "seventeen", "eighteen", "nineteen", - "twenty" }; + char const* hourStr[12] = { "twelve", "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", "eleven" }; + char const* minuteStr[6] = {"five", "ten", "quarter", "twenty", + "twenty five", "half" }; hours = dateTimeController.Hours() % 12; minutes = dateTimeController.Minutes(); if (minutes > 30) { @@ -96,17 +97,13 @@ void WatchFaceFuzzy::Refresh() { hours = (hours + 1) % 12; minutes = 60 - minutes; } - minutesUnits = minutes % 10; - auto hoursStr = strings[(hours + 11) % 12]; + // Make it fuzzy + minutes = minutes / 5 + (minutes % 5 > 2); if (minutes == 0) { - lv_label_set_text_fmt(label_time, "#%s %s#\no'clock", hoursAccent, hoursStr); - } else if (minutes == 30) { - lv_label_set_text_fmt(label_time, "half\npast\n#%s %s#", hoursAccent, hoursStr); - } else if (minutes <= 20) { - lv_label_set_text_fmt(label_time, "%s\n%s\n#%s %s#", strings[minutes - 1], pastTo, hoursAccent, hoursStr); + lv_label_set_text_fmt(label_time, "#%s %s#\no'clock", hoursAccent, hourStr[hours]); } else { - lv_label_set_text_fmt(label_time, "twenty\n%s %s\n#%s %s#", strings[minutesUnits - 1], pastTo, hoursAccent, hoursStr); - } + lv_label_set_text_fmt(label_time, "%s %s #%s %s#", minuteStr[minutes - 1], pastTo, hoursAccent, hourStr[hours]); + } /* Align the label w.r.t. another object (active screen in this case) * You can use the last two parameters to move the obj around * *after the alignment*. From 38d4ac05b987819012fc6384d718a1627090dcef Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 20:11:58 +0100 Subject: [PATCH 05/19] Rework string building Taking a page from XFCE4-panel book [1], the string building process for the fuzzy clock has been adapted to a possible future introduction of internationalisation (e.g., with lv_i18n). --- src/displayapp/screens/WatchFaceFuzzy.cpp | 102 +++++++++++++--------- src/displayapp/screens/WatchFaceFuzzy.h | 5 +- 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 5f9ff67756..1ecb87ab3a 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -1,8 +1,7 @@ #include "WatchFaceFuzzy.h" -//#include #include -//#include +#include using namespace Pinetime::Applications::Screens; @@ -22,21 +21,23 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeC */ label_time = lv_label_create(lv_scr_act(), nullptr); - /* Set size of the label to screen size */ - lv_obj_set_size(label_time, LV_HOR_RES, LV_VER_RES); - /* Set the behavior of the label when the text is longer than the * object size. In this case we want to break the text to keep the * width and extend the height of the obj. * - * Note: this doesn't work properly or it is someone dependent on when - * it is called. Avoiding it for now and specifying linebreaks - * directly in the string. + * Note: let's try to use linebreaks explicitly to avoid problems with + * the hour accent (which tends to break with this long break mode) */ - //lv_label_set_long_mode(label_time, LV_LABEL_LONG_BREAK); + lv_label_set_long_mode(label_time, LV_LABEL_LONG_BREAK); + /* Set size of the label to screen size */ + //lv_obj_set_size(label_time, LV_HOR_RES, LV_VER_RES); + lv_obj_set_width(label_time, LV_HOR_RES); - /* Set text alignment (left) in the label */ - lv_label_set_align(label_time, LV_LABEL_ALIGN_LEFT); + /* Set text alignment in the label. + * NOTE: alignment is character-wise and not pixel-wise (the result is + * probably not what you would expect is un are centering text) + */ + lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); /* Set main color and font for the label * Note: color can be changed when setting the text as well allowing @@ -59,6 +60,10 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeC * period: how often the callback is triggered (every 60s == 60000ms) * priority: see LVGL for more info * userdata: accessible from the callback (see Screen.cpp) + * + * NOTE: Updating every minute is efficient but it means that you need + * to wait for up to one minute for the clock to update after + * bluetooth connection (e.g., when you hard reset the PineTime). */ taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); @@ -74,36 +79,21 @@ WatchFaceFuzzy::~WatchFaceFuzzy() { } void WatchFaceFuzzy::Refresh() { - /* Possible wordings: - * - " o'clock" - * - "half past " - * - "quarter past/to " - * - " past/to " - * - " past/to " - * - " past/to " - */ - uint8_t hours, minutes; - char const* pastTo = "past"; - char const* hoursAccent = "ffffff"; - char const* hourStr[12] = { "twelve", "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "ten", "eleven" }; - char const* minuteStr[6] = {"five", "ten", "quarter", "twenty", - "twenty five", "half" }; - hours = dateTimeController.Hours() % 12; + std::string hoursStr, timeStr; + + hours = dateTimeController.Hours() % 12; // TODO: maybe that's not needed? minutes = dateTimeController.Minutes(); - if (minutes > 30) { - pastTo = "to"; + auto sector = (minutes / 5 + (minutes % 5 > 2)) % 12; + + timeStr = timeSectors[sector]; + if (timeStr.find("%1") != std::string::npos) hours = (hours + 1) % 12; - minutes = 60 - minutes; - } - // Make it fuzzy - minutes = minutes / 5 + (minutes % 5 > 2); - if (minutes == 0) { - lv_label_set_text_fmt(label_time, "#%s %s#\no'clock", hoursAccent, hourStr[hours]); - } else { - lv_label_set_text_fmt(label_time, "%s %s #%s %s#", minuteStr[minutes - 1], pastTo, hoursAccent, hourStr[hours]); - } + hoursStr = std::string("#") + timeAccent + " " + hourNames[hours] + "#"; + timeStr.replace(timeStr.find("%"), 2, hoursStr); + + lv_label_set_text_fmt(label_time, timeStr.c_str()); + /* Align the label w.r.t. another object (active screen in this case) * You can use the last two parameters to move the obj around * *after the alignment*. @@ -113,5 +103,39 @@ void WatchFaceFuzzy::Refresh() { * NOTE: you should set the alignment after determining the size * (and content) of the label to get a reliable result! */ - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 10, -10); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); } + +/* Consider something like this + * https://salsa.debian.org/xfce-team/desktop/xfce4-panel/-/blob/debian/master/plugins/clock/clock-fuzzy.c + * to gradually implement internationalisation + */ +const char* WatchFaceFuzzy::timeSectors[] = { + "%0\no'clock", + "five past\n%0", + "ten past\n%0", + "quarter\npast\n%0", + "twenty\npast\n%0", + "twenty\nfive past\n%0", + "half past\n%0", + "twenty\nfive to\n%1", + "twenty\nto %1", + "quarter\nto %1", + "ten to\n%1", + "five to\n%1", +}; +const char* WatchFaceFuzzy::hourNames[] = { + "twelve", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "ten", + "eleven", +}; + diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index 7a1380cefd..c33d51d783 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -18,9 +18,12 @@ namespace Pinetime { void Refresh() override; private: - lv_obj_t* label_time; Controllers::DateTime& dateTimeController; lv_task_t* taskRefresh; + lv_obj_t* label_time; + const char* timeAccent = "ffffff"; + static const char* timeSectors[12]; + static const char* hourNames[12]; }; } } From 4b4264bb02642572aa4096273e031793a72f458a Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 20:20:17 +0100 Subject: [PATCH 06/19] Add example of italian localisation --- src/displayapp/screens/WatchFaceFuzzy.cpp | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 1ecb87ab3a..534fef2b64 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -139,3 +139,34 @@ const char* WatchFaceFuzzy::hourNames[] = { "eleven", }; +/* Once i18n is implemented, new languages can be introduced like this: + * + * char* it-IT_sectors[] = { + * "%0\nin punto", + * "%0 e cinque", + * "%0 e dieci", + * "%0 e un quarto", + * "%0 e venti", + * "%0 e venti cinque", + * "%0 e mezza", + * "%0 e trenta cinque", + * "%1 meno venti", + * "%1 meno un quarto", + * "%1 meno dieci", + * "%1 meno cinque", + * }; + * const char* it-IT_hourNames[] = { + * "dodici", + * "una", + * "due", + * "tre", + * "quattro", + * "cinque", + * "sei", + * "sette", + * "otto", + * "nove", + * "dieci", + * "undici", + * }; + */ From f7445f387f3c08e4457d46f1ed110c668356ad34 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 20:28:38 +0100 Subject: [PATCH 07/19] Remove personal notes and comments --- src/displayapp/screens/WatchFaceFuzzy.cpp | 73 +++-------------------- src/displayapp/screens/WatchFaceFuzzy.h | 4 -- 2 files changed, 7 insertions(+), 70 deletions(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 534fef2b64..dd1b0ed31f 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -8,73 +8,21 @@ using namespace Pinetime::Applications::Screens; WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController) : Screen(app), dateTimeController {dateTimeController} { - /* Why would we need this? */ - //settingsController.SetClockFace(0); - - /* - * `lv_scr_act()` get the active screen on the default display - * (note that we only have one display in this setup, but LVGL has - * multidisplay support as well). - * - * `nullptr` is used simply because we don't want to *copy* the label - * from any other object. - */ label_time = lv_label_create(lv_scr_act(), nullptr); - - /* Set the behavior of the label when the text is longer than the - * object size. In this case we want to break the text to keep the - * width and extend the height of the obj. - * - * Note: let's try to use linebreaks explicitly to avoid problems with - * the hour accent (which tends to break with this long break mode) - */ lv_label_set_long_mode(label_time, LV_LABEL_LONG_BREAK); - /* Set size of the label to screen size */ - //lv_obj_set_size(label_time, LV_HOR_RES, LV_VER_RES); lv_obj_set_width(label_time, LV_HOR_RES); - - /* Set text alignment in the label. - * NOTE: alignment is character-wise and not pixel-wise (the result is - * probably not what you would expect is un are centering text) - */ lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - - /* Set main color and font for the label - * Note: color can be changed when setting the text as well allowing - * for multicolor strings. Can we do this with fonts as well? - * - * "local" style take precedence over global styles - * - * `LV_LABEL_PART_MAIN` is the only "part" of a label. - * - * `LV_STATE_DEFAULT` is the label state (which cannot be checked or - * toggled or whatever...). - */ lv_label_set_recolor(label_time, true); lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x777777)); lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_regular_36); - /* Creates a new LVGL task called periodically. - * lv_task_create(callback, period, priority, userdata) - * callback: in this case is a generic wrapper of Refresh() - * period: how often the callback is triggered (every 60s == 60000ms) - * priority: see LVGL for more info - * userdata: accessible from the callback (see Screen.cpp) - * - * NOTE: Updating every minute is efficient but it means that you need - * to wait for up to one minute for the clock to update after - * bluetooth connection (e.g., when you hard reset the PineTime). - */ taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); - /* Refresh to avoid waiting for 60s */ Refresh(); } WatchFaceFuzzy::~WatchFaceFuzzy() { - /* Remove refresh task for this watchface */ lv_task_del(taskRefresh); - /* Delete all children of the active screen (this watchface) */ lv_obj_clean(lv_scr_act()); } @@ -92,23 +40,16 @@ void WatchFaceFuzzy::Refresh() { hoursStr = std::string("#") + timeAccent + " " + hourNames[hours] + "#"; timeStr.replace(timeStr.find("%"), 2, hoursStr); - lv_label_set_text_fmt(label_time, timeStr.c_str()); - - /* Align the label w.r.t. another object (active screen in this case) - * You can use the last two parameters to move the obj around - * *after the alignment*. - * See https://docs.lvgl.io/latest/en/html/_images/align.png for all - * possible alignments. - * - * NOTE: you should set the alignment after determining the size - * (and content) of the label to get a reliable result! - */ + lv_label_set_text(label_time, timeStr.c_str()); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); } -/* Consider something like this - * https://salsa.debian.org/xfce-team/desktop/xfce4-panel/-/blob/debian/master/plugins/clock/clock-fuzzy.c - * to gradually implement internationalisation +/* Inspired by XFCE4-panel's fuzzy clock. + * + * https://salsa.debian.org/xfce-team/desktop/xfce4-panel/-/blob/debian/master/plugins/clock/clock-fuzzy.c + * + * Strings contain either a `%0` or a `%1`, indicating the position of + * the `hour` or `hour+1`, respectively. */ const char* WatchFaceFuzzy::timeSectors[] = { "%0\no'clock", diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index c33d51d783..ed17ee631a 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -1,11 +1,7 @@ #pragma once #include -/* #include */ -/* #include */ -/* #include */ #include "Screen.h" -//#include "ScreenList.h" #include "components/datetime/DateTimeController.h" namespace Pinetime { From 6a0330f8ca4aae94fc409532acd3a1e287b3f07a Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 20:37:38 +0100 Subject: [PATCH 08/19] Revert back to Jetbrains Mono 42 Font now includes: 0x20,0x27,0x30-0x3A,0x61-0x7A --- .../fonts/jetbrains_mono_regular_36.c | 361 ------------------ src/displayapp/screens/WatchFaceFuzzy.cpp | 2 +- src/libs/lv_conf.h | 1 - 3 files changed, 1 insertion(+), 363 deletions(-) delete mode 100644 src/displayapp/fonts/jetbrains_mono_regular_36.c diff --git a/src/displayapp/fonts/jetbrains_mono_regular_36.c b/src/displayapp/fonts/jetbrains_mono_regular_36.c deleted file mode 100644 index 74d4794667..0000000000 --- a/src/displayapp/fonts/jetbrains_mono_regular_36.c +++ /dev/null @@ -1,361 +0,0 @@ -/******************************************************************************* - * Size: 36 px - * Bpp: 1 - * Opts: - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -#ifndef JETBRAINS_MONO_REGULAR_36 -#define JETBRAINS_MONO_REGULAR_36 1 -#endif - -#if JETBRAINS_MONO_REGULAR_36 - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - 0x0, - - /* U+0027 "'" */ - 0xff, 0xff, 0xff, 0xfc, - - /* U+0061 "a" */ - 0x7, 0xf0, 0x1f, 0xfc, 0x3f, 0xfe, 0x7c, 0x1e, - 0x78, 0xf, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, - 0xf, 0xff, 0x3f, 0xff, 0x7f, 0xff, 0xf0, 0x7, - 0xe0, 0x7, 0xe0, 0x7, 0xe0, 0x7, 0xf0, 0xf, - 0xf8, 0x3f, 0x7f, 0xf7, 0x3f, 0xe7, 0xf, 0xc7, - - /* U+0062 "b" */ - 0xe0, 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, - 0x0, 0x1c, 0x0, 0x38, 0xf8, 0x77, 0xfc, 0xef, - 0xfd, 0xf0, 0x7b, 0xc0, 0x7f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, - 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfe, - 0x3, 0xfe, 0xf, 0x77, 0xfe, 0xef, 0xf9, 0xc7, - 0xc0, - - /* U+0063 "c" */ - 0xf, 0xe0, 0x3f, 0xf0, 0xff, 0xf3, 0xc1, 0xef, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x0, 0xe0, - 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, - 0x1c, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, - 0x7f, 0xf8, 0x7f, 0xe0, 0x7f, 0x0, - - /* U+0064 "d" */ - 0x0, 0xe, 0x0, 0x1c, 0x0, 0x38, 0x0, 0x70, - 0x0, 0xe0, 0x1, 0xc3, 0xe3, 0x9f, 0xf7, 0x7f, - 0xee, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, - 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfe, - 0x3, 0xde, 0xf, 0xbf, 0xf7, 0x3f, 0xee, 0x1f, - 0x1c, - - /* U+0065 "e" */ - 0xf, 0xe0, 0x3f, 0xe0, 0xff, 0xe3, 0xc1, 0xef, - 0x1, 0xdc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xe, 0x0, - 0x1c, 0x0, 0x38, 0x0, 0x78, 0xf, 0x78, 0x3c, - 0x7f, 0xf8, 0x7f, 0xe0, 0x7f, 0x0, - - /* U+0066 "f" */ - 0x0, 0x7f, 0x80, 0xff, 0xc0, 0xff, 0xe0, 0x78, - 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, - 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, - 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, - 0x0, 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, - 0x0, 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, - - /* U+0067 "g" */ - 0xf, 0x8e, 0x7f, 0xdd, 0xff, 0xfb, 0xc1, 0xff, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfe, 0x3, 0xde, 0xf, 0xbf, 0xf7, 0x3f, 0xee, - 0x1f, 0x1c, 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, - 0x1, 0xc0, 0x7, 0x9f, 0xfe, 0x3f, 0xf8, 0x7f, - 0xe0, - - /* U+0068 "h" */ - 0xe0, 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, - 0x0, 0x1c, 0x0, 0x38, 0xf8, 0x77, 0xfc, 0xef, - 0xfd, 0xf0, 0x7b, 0xc0, 0x7f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, - 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, 0xfc, - 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, 0xc0, - 0x1c, - - /* U+0069 "i" */ - 0x1, 0xc0, 0x1, 0xf0, 0x0, 0xf8, 0x0, 0x38, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, - 0x80, 0x7f, 0xc0, 0x3f, 0xe0, 0x0, 0x70, 0x0, - 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, 0x0, - 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, 0x70, - 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x7, - 0x0, 0x3, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe0, - - /* U+006A "j" */ - 0x0, 0x38, 0x1, 0xf0, 0x7, 0xc0, 0xe, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf9, - 0xff, 0xe7, 0xff, 0x80, 0xe, 0x0, 0x38, 0x0, - 0xe0, 0x3, 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, - 0x3, 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, 0x3, - 0x80, 0xe, 0x0, 0x38, 0x0, 0xe0, 0x3, 0x80, - 0xe, 0x0, 0x38, 0x1, 0xc0, 0xf, 0x3f, 0xf8, - 0xff, 0xc3, 0xfc, 0x0, - - /* U+006B "k" */ - 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0x0, - 0xe0, 0x0, 0xe0, 0x0, 0xe0, 0xf, 0xe0, 0x1e, - 0xe0, 0x1e, 0xe0, 0x3c, 0xe0, 0x78, 0xe0, 0x70, - 0xe0, 0xf0, 0xe1, 0xe0, 0xff, 0xc0, 0xff, 0xc0, - 0xff, 0xc0, 0xe1, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, - 0xe0, 0x78, 0xe0, 0x3c, 0xe0, 0x3c, 0xe0, 0x1e, - 0xe0, 0xe, 0xe0, 0xf, - - /* U+006C "l" */ - 0xff, 0xc0, 0x1f, 0xf8, 0x3, 0xff, 0x0, 0x0, - 0xe0, 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, 0x70, - 0x0, 0xe, 0x0, 0x1, 0xc0, 0x0, 0x38, 0x0, - 0x7, 0x0, 0x0, 0xe0, 0x0, 0x1c, 0x0, 0x3, - 0x80, 0x0, 0x70, 0x0, 0xe, 0x0, 0x1, 0xc0, - 0x0, 0x38, 0x0, 0x7, 0x0, 0x0, 0xe0, 0x0, - 0x1c, 0x0, 0x3, 0x80, 0x0, 0x78, 0x0, 0x7, - 0xff, 0x0, 0x7f, 0xe0, 0x7, 0xfc, - - /* U+006D "m" */ - 0xe7, 0x1e, 0x77, 0xdf, 0xbf, 0xef, 0xfe, 0x7c, - 0xfe, 0x1c, 0x3f, 0xe, 0x1f, 0x87, 0xf, 0xc3, - 0x87, 0xe1, 0xc3, 0xf0, 0xe1, 0xf8, 0x70, 0xfc, - 0x38, 0x7e, 0x1c, 0x3f, 0xe, 0x1f, 0x87, 0xf, - 0xc3, 0x87, 0xe1, 0xc3, 0xf0, 0xe1, 0xf8, 0x70, - 0xfc, 0x38, 0x70, - - /* U+006E "n" */ - 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, 0xf, - 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x70, - - /* U+006F "o" */ - 0xf, 0xe0, 0x3f, 0xe0, 0xff, 0xe3, 0xc1, 0xef, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, - 0x7f, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, - - /* U+0070 "p" */ - 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0xf8, 0x3d, - 0xdf, 0xfb, 0xbf, 0xe7, 0x1f, 0xe, 0x0, 0x1c, - 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, 0x1, 0xc0, - 0x0, - - /* U+0071 "q" */ - 0xf, 0x8e, 0x7f, 0xdd, 0xff, 0xbb, 0xc1, 0xff, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3e, - 0xff, 0xdc, 0xff, 0xb8, 0x7c, 0x70, 0x0, 0xe0, - 0x1, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, - 0x1c, - - /* U+0072 "r" */ - 0xe3, 0xe1, 0xdf, 0xf3, 0xbf, 0xf7, 0xc1, 0xef, - 0x1, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x3, 0x80, 0x7, 0x0, 0xe, 0x0, - 0x1c, 0x0, 0x38, 0x0, 0x70, 0x0, 0xe0, 0x1, - 0xc0, 0x3, 0x80, 0x7, 0x0, 0x0, - - /* U+0073 "s" */ - 0xf, 0xf0, 0x3f, 0xf0, 0xff, 0xf3, 0xc0, 0xf7, - 0x0, 0xee, 0x0, 0x1c, 0x0, 0x3c, 0x0, 0x3f, - 0x80, 0x3f, 0xe0, 0x1f, 0xf0, 0x3, 0xe0, 0x1, - 0xe0, 0x1, 0xc0, 0x3, 0xf0, 0x7, 0xf0, 0x1e, - 0xff, 0xf8, 0xff, 0xe0, 0x7f, 0x0, - - /* U+0074 "t" */ - 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, 0x70, - 0x0, 0x38, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, 0x0, - 0x70, 0x0, 0x38, 0x0, 0x1c, 0x0, 0xe, 0x0, - 0x7, 0x0, 0x3, 0x80, 0x1, 0xc0, 0x0, 0xe0, - 0x0, 0x70, 0x0, 0x38, 0x0, 0x1e, 0x0, 0x7, - 0xfe, 0x3, 0xff, 0x0, 0x7f, 0x80, - - /* U+0075 "u" */ - 0xe0, 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, - 0x0, 0xfc, 0x1, 0xf8, 0x3, 0xf0, 0x7, 0xe0, - 0xf, 0xc0, 0x1f, 0x80, 0x3f, 0x0, 0x7e, 0x0, - 0xfc, 0x1, 0xf8, 0x3, 0xf8, 0xf, 0x78, 0x3c, - 0x7f, 0xf0, 0x7f, 0xc0, 0x7f, 0x0, - - /* U+0076 "v" */ - 0xe0, 0x3, 0xfc, 0x0, 0xe7, 0x0, 0x39, 0xc0, - 0x1e, 0x78, 0x7, 0xe, 0x1, 0xc3, 0x80, 0xf0, - 0xf0, 0x38, 0x1c, 0xe, 0x7, 0x7, 0x81, 0xe1, - 0xc0, 0x38, 0x70, 0xe, 0x3c, 0x3, 0xce, 0x0, - 0x73, 0x80, 0x1d, 0xc0, 0x7, 0xf0, 0x0, 0xfc, - 0x0, 0x3e, 0x0, 0xf, 0x80, - - /* U+0077 "w" */ - 0xe0, 0xe0, 0xfc, 0x1c, 0x1f, 0x87, 0x83, 0x70, - 0xf0, 0x66, 0x1b, 0x1c, 0xc3, 0x63, 0x9c, 0x6c, - 0x73, 0x8d, 0x8e, 0x73, 0x31, 0x8e, 0x66, 0x30, - 0xcc, 0x66, 0x19, 0x8d, 0xc3, 0x31, 0xb8, 0x76, - 0x37, 0xe, 0x86, 0xc1, 0xf0, 0xd8, 0x3e, 0x1b, - 0x3, 0xc1, 0xe0, 0x78, 0x3c, 0xf, 0x7, 0x80, - - /* U+0078 "x" */ - 0x70, 0x7, 0x9e, 0x1, 0xc3, 0xc0, 0xf0, 0x70, - 0x78, 0x1e, 0x1c, 0x3, 0xcf, 0x0, 0x77, 0x80, - 0x1f, 0xc0, 0x3, 0xf0, 0x0, 0x78, 0x0, 0x3e, - 0x0, 0xf, 0xc0, 0x7, 0x78, 0x3, 0xce, 0x0, - 0xe3, 0xc0, 0x78, 0x78, 0x3c, 0xe, 0x1e, 0x3, - 0xc7, 0x80, 0x7b, 0xc0, 0xe, - - /* U+0079 "y" */ - 0xf0, 0x3, 0xfc, 0x0, 0xe7, 0x0, 0x79, 0xe0, - 0x1c, 0x38, 0x7, 0xf, 0x3, 0xc3, 0xc0, 0xe0, - 0x70, 0x38, 0x1e, 0x1e, 0x3, 0x87, 0x0, 0xf3, - 0xc0, 0x1c, 0xe0, 0x7, 0x38, 0x1, 0xfe, 0x0, - 0x3f, 0x0, 0xf, 0xc0, 0x1, 0xe0, 0x0, 0x78, - 0x0, 0x1e, 0x0, 0x7, 0x0, 0x1, 0xc0, 0x0, - 0xf0, 0x0, 0x38, 0x0, 0x1e, 0x0, 0x7, 0x0, - 0x1, 0xc0, 0x0, - - /* U+007A "z" */ - 0x7f, 0xfe, 0xff, 0xfd, 0xff, 0xf8, 0x0, 0xf0, - 0x3, 0xc0, 0xf, 0x0, 0x1c, 0x0, 0x78, 0x1, - 0xe0, 0x7, 0x80, 0x1e, 0x0, 0x78, 0x0, 0xf0, - 0x3, 0xc0, 0xf, 0x0, 0x3c, 0x0, 0xf0, 0x1, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0 -}; - - -/*--------------------- - * 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 = 346, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1, .adv_w = 346, .box_w = 3, .box_h = 10, .ofs_x = 9, .ofs_y = 16}, - {.bitmap_index = 5, .adv_w = 346, .box_w = 16, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 45, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 94, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 132, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 181, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 219, .adv_w = 346, .box_w = 17, .box_h = 26, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 275, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, - {.bitmap_index = 324, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 373, .adv_w = 346, .box_w = 17, .box_h = 27, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 431, .adv_w = 346, .box_w = 14, .box_h = 34, .ofs_x = 3, .ofs_y = -6}, - {.bitmap_index = 491, .adv_w = 346, .box_w = 16, .box_h = 26, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 543, .adv_w = 346, .box_w = 19, .box_h = 26, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 605, .adv_w = 346, .box_w = 17, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 648, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 686, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 724, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, - {.bitmap_index = 773, .adv_w = 346, .box_w = 15, .box_h = 26, .ofs_x = 3, .ofs_y = -6}, - {.bitmap_index = 822, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 4, .ofs_y = 0}, - {.bitmap_index = 860, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 898, .adv_w = 346, .box_w = 17, .box_h = 25, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 952, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0}, - {.bitmap_index = 990, .adv_w = 346, .box_w = 18, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 1035, .adv_w = 346, .box_w = 19, .box_h = 20, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1083, .adv_w = 346, .box_w = 18, .box_h = 20, .ofs_x = 2, .ofs_y = 0}, - {.bitmap_index = 1128, .adv_w = 346, .box_w = 18, .box_h = 26, .ofs_x = 2, .ofs_y = -6}, - {.bitmap_index = 1187, .adv_w = 346, .box_w = 15, .box_h = 20, .ofs_x = 3, .ofs_y = 0} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_0[] = { - 0x0, 0x7 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = -{ - { - .range_start = 32, .range_length = 8, .glyph_id_start = 1, - .unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 2, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - }, - { - .range_start = 97, .range_length = 26, .glyph_id_start = 3, - .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_regular_36 = { -#else -lv_font_t jetbrains_mono_regular_36 = { -#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 = 34, /*The maximum line height required by the font*/ - .base_line = 6, /*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 = -6, - .underline_thickness = 2, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - - - -#endif /*#if JETBRAINS_MONO_REGULAR_36*/ - diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index dd1b0ed31f..d05a516885 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -14,7 +14,7 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeC lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); lv_label_set_recolor(label_time, true); lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x777777)); - lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_regular_36); + lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 2157b48878..063f1d340d 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -417,7 +417,6 @@ typedef void* lv_indev_drv_user_data_t; /*Type of user data in the in LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed) \ LV_FONT_DECLARE(jetbrains_mono_42) \ LV_FONT_DECLARE(jetbrains_mono_76) \ - LV_FONT_DECLARE(jetbrains_mono_regular_36) \ LV_FONT_DECLARE(open_sans_light) \ LV_FONT_DECLARE(lv_font_sys_48) From 5fa3756d10a10f78e61dad488d1444ea734db308 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 21:25:01 +0100 Subject: [PATCH 09/19] Add spanish and catalan examples thanks to @adocampo Using the clock system for catalan since it uses the same logic as the other languages. Could be fun to dive into the traditional and formal bell systems, but these would conflict with localisation since the difference is in the logic. --- src/displayapp/screens/WatchFaceFuzzy.cpp | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index d05a516885..8779a46338 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -81,6 +81,64 @@ const char* WatchFaceFuzzy::hourNames[] = { }; /* Once i18n is implemented, new languages can be introduced like this: + * + * const char* ca-ES_sectors[] = { + * "%0\nen punt", + * "%0\ni cinc", + * "%0\ni deu", + * "%0\ni quart", + * "%0\ni vint", + * "%0\ni vint\ni cinc", + * "%0\ni mitja", + * "%1\nmenys\nvint\ni-cinc", + * "%1\nmenys\nvint", + * "%1\nmenys\nquart", + * "%1\nmenys deu", + * "%1\nmenys\ncinc", + * }; + * const char* ca-ES_hourNames[] = { + * "les dotze", + * "la una", + * "les dues", + * "les tres", + * "les\nquatre", + * "les cinc", + * "les sis", + * "les set", + * "les vuit", + * "les nou", + * "les deu", + * "les onze", + * }; + * + * const char* es-ES_sectors[] = { + * "%0\nen punto", + * "%0\ny cinco", + * "%0\ny diez", + * "%0\ny cuarto", + * "%0\ny veinte", + * "%0\ny veinti\ncinco", + * "%0\ny media", + * "%1\nmenos\nveinti\ncinco", + * "%1\nmenos\nveinte", + * "%1\nmenos\ncuarto", + * "%1\nmenos\ndiez", + * "%1\nmenos\ncinco", + * }; + * const char* es-ES_hourNames[] = { + * "las doce", + * "la una", + * "las dos", + * "las tres", + * "las\ncuatro", + * "las cinco", + * "las seis", + * "las siete", + * "las ocho", + * "las nueve", + * "las diez", + * "las once", + * }; * * char* it-IT_sectors[] = { * "%0\nin punto", From 992a856d75890643ca01d2a9696a0056c151e4ec Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 23 Sep 2021 12:29:17 +0100 Subject: [PATCH 10/19] Add german example thanks to @schneidr As noted by @schneidr, the german example is not completely correct and in particular there is a singular/plural issue with "Ein[s]". I don't think this is worth addressing until we have a better idea of what the localisation API will be. --- src/displayapp/screens/WatchFaceFuzzy.cpp | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 8779a46338..a1ec4ee5ba 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -168,4 +168,33 @@ const char* WatchFaceFuzzy::hourNames[] = { * "dieci", * "undici", * }; + * + * const char* de_DE_sectors[] = { + * "%0 Uhr", + * "Fünf nach %0", + * "Zehn nach %0", + * "Viertel nach %0", + * "Zwanzig nach %0", + * "Fünf vor halb %1", + * "Halb %1", + * "Fünf nach halb %1", + * "Zwanzig vor %1", + * "Viertel vor %1", + * "Zehn vor %1", + * "Fünf vor %1", + * }; + * const char* de_DE_hourNames[] = { + * "Zwölf", + * "Eins", // TODO: "Ein" in "Ein Uhr" + * "Zwei", + * "Drei", + * "Vier", + * "Fünf", + * "Sechs", + * "Sieben", + * "Acht", + * "Neun", + * "Zehn", + * "Elf", + * }; */ From b0c6d7b1bfac45a40722728e545e156e3f4f9760 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Wed, 22 Sep 2021 21:52:55 +0100 Subject: [PATCH 11/19] Format with clang-format --- src/displayapp/screens/WatchFaceFuzzy.cpp | 2 +- src/displayapp/screens/WatchFaceFuzzy.h | 33 +++++++++++------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index a1ec4ee5ba..75fd14a401 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -30,7 +30,7 @@ void WatchFaceFuzzy::Refresh() { uint8_t hours, minutes; std::string hoursStr, timeStr; - hours = dateTimeController.Hours() % 12; // TODO: maybe that's not needed? + hours = dateTimeController.Hours() % 12; // TODO: maybe that's not needed? minutes = dateTimeController.Minutes(); auto sector = (minutes / 5 + (minutes % 5 > 2)) % 12; diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index ed17ee631a..e6c7bfab07 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -5,23 +5,22 @@ #include "components/datetime/DateTimeController.h" namespace Pinetime { - namespace Applications { - namespace Screens { - class WatchFaceFuzzy : public Screen { - public: - WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController); - ~WatchFaceFuzzy() override; - void Refresh() override; + namespace Applications { + namespace Screens { + class WatchFaceFuzzy : public Screen { + public: + WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController); + ~WatchFaceFuzzy() override; + void Refresh() override; - private: - Controllers::DateTime& dateTimeController; - lv_task_t* taskRefresh; - lv_obj_t* label_time; - const char* timeAccent = "ffffff"; - static const char* timeSectors[12]; - static const char* hourNames[12]; - }; - } + private: + Controllers::DateTime& dateTimeController; + lv_task_t* taskRefresh; + lv_obj_t* label_time; + const char* timeAccent = "ffffff"; + static const char* timeSectors[12]; + static const char* hourNames[12]; + }; } + } } - From 16f78ed8c2872ea00208e3322d5fe3a76c3882a5 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 23 Sep 2021 13:32:31 +0100 Subject: [PATCH 12/19] Use colors from standard palette --- src/displayapp/screens/WatchFaceFuzzy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 75fd14a401..782f2fe40b 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -13,7 +13,7 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeC lv_obj_set_width(label_time, LV_HOR_RES); lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); lv_label_set_recolor(label_time, true); - lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x777777)); + lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); From dd75b610f87e755d73ae3d705732cb14fbf32918 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 23 Sep 2021 16:25:17 +0100 Subject: [PATCH 13/19] Update docs with instructions to generate JetBrains Mono 42 Also rework the docs a bit. --- src/displayapp/fonts/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/displayapp/fonts/README.md b/src/displayapp/fonts/README.md index b2669a788c..03b872c404 100644 --- a/src/displayapp/fonts/README.md +++ b/src/displayapp/fonts/README.md @@ -15,9 +15,7 @@ using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex) - Define the new symbols in `src/displayapp/screens/Symbols.h`: -``` -static constexpr const char* newSymbol = "\xEF\x86\x85"; -``` +Fill the font converter fields as follows: ### the config file format: From 445634a7177db394de1259520d2731a385088a31 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 24 Sep 2021 12:04:53 +0100 Subject: [PATCH 14/19] Minor fixes --- src/displayapp/screens/WatchFaceFuzzy.cpp | 28 +++++++++++++---------- src/displayapp/screens/WatchFaceFuzzy.h | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 782f2fe40b..7d296d5d88 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -8,13 +8,13 @@ using namespace Pinetime::Applications::Screens; WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController) : Screen(app), dateTimeController {dateTimeController} { - label_time = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(label_time, LV_LABEL_LONG_BREAK); - lv_obj_set_width(label_time, LV_HOR_RES); - lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER); - lv_label_set_recolor(label_time, true); - lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); + timeLabel = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(timeLabel, LV_LABEL_LONG_BREAK); + lv_obj_set_width(timeLabel, LV_HOR_RES); + lv_label_set_align(timeLabel, LV_LABEL_ALIGN_CENTER); + lv_label_set_recolor(timeLabel, true); + lv_obj_set_style_local_text_color(timeLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_obj_set_style_local_text_font(timeLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); @@ -32,7 +32,11 @@ void WatchFaceFuzzy::Refresh() { hours = dateTimeController.Hours() % 12; // TODO: maybe that's not needed? minutes = dateTimeController.Minutes(); - auto sector = (minutes / 5 + (minutes % 5 > 2)) % 12; + auto sector = minutes / 5 + (minutes % 5 > 2); + if (sector == 12) { + hours = (hours + 1) % 12; + sector = 0; + } timeStr = timeSectors[sector]; if (timeStr.find("%1") != std::string::npos) @@ -40,8 +44,8 @@ void WatchFaceFuzzy::Refresh() { hoursStr = std::string("#") + timeAccent + " " + hourNames[hours] + "#"; timeStr.replace(timeStr.find("%"), 2, hoursStr); - lv_label_set_text(label_time, timeStr.c_str()); - lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + lv_label_set_text(timeLabel, timeStr.c_str()); + lv_obj_align(timeLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); } /* Inspired by XFCE4-panel's fuzzy clock. @@ -88,9 +92,9 @@ const char* WatchFaceFuzzy::hourNames[] = { * "%0\ni deu", * "%0\ni quart", * "%0\ni vint", - * "%0\ni vint\ni cinc", + * "%0\ni vint-\ni-cinc", * "%0\ni mitja", - * "%1\nmenys\nvint\ni-cinc", + * "%1\nmenys\nvint-\ni-cinc", * "%1\nmenys\nvint", * "%1\nmenys\nquart", * "%1\nmenys deu", diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index e6c7bfab07..871946b96a 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -16,7 +16,7 @@ namespace Pinetime { private: Controllers::DateTime& dateTimeController; lv_task_t* taskRefresh; - lv_obj_t* label_time; + lv_obj_t* timeLabel; const char* timeAccent = "ffffff"; static const char* timeSectors[12]; static const char* hourNames[12]; From 7c96ebe2fda38eda9d61e82da81a12f8a0de87c6 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Fri, 7 Jan 2022 15:43:29 +0000 Subject: [PATCH 15/19] Fix inconsistent braces --- src/displayapp/screens/WatchFaceFuzzy.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 7d296d5d88..8005110c0d 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -39,8 +39,9 @@ void WatchFaceFuzzy::Refresh() { } timeStr = timeSectors[sector]; - if (timeStr.find("%1") != std::string::npos) + if (timeStr.find("%1") != std::string::npos) { hours = (hours + 1) % 12; + } hoursStr = std::string("#") + timeAccent + " " + hourNames[hours] + "#"; timeStr.replace(timeStr.find("%"), 2, hoursStr); From cc6c89c1be7576b3639cca5e9aeed4f31c2cf344 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 10 Jan 2022 15:04:59 +0000 Subject: [PATCH 16/19] Force display refresh on instance creation This is done by setting a screen wide black background as the parent object. --- src/displayapp/screens/WatchFaceFuzzy.cpp | 9 ++++++++- src/displayapp/screens/WatchFaceFuzzy.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 8005110c0d..0ee1b4eb13 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -8,7 +8,14 @@ using namespace Pinetime::Applications::Screens; WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController) : Screen(app), dateTimeController {dateTimeController} { - timeLabel = lv_label_create(lv_scr_act(), nullptr); + backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_click(backgroundLabel, true); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); + + timeLabel = lv_label_create(backgroundLabel, nullptr); lv_label_set_long_mode(timeLabel, LV_LABEL_LONG_BREAK); lv_obj_set_width(timeLabel, LV_HOR_RES); lv_label_set_align(timeLabel, LV_LABEL_ALIGN_CENTER); diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index 871946b96a..7764bb5a48 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -16,6 +16,7 @@ namespace Pinetime { private: Controllers::DateTime& dateTimeController; lv_task_t* taskRefresh; + lv_obj_t* backgroundLabel; lv_obj_t* timeLabel; const char* timeAccent = "ffffff"; static const char* timeSectors[12]; From c100dad0918446fbe0042e45b6e7cdff53386feb Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 13 Jan 2022 14:28:34 +0000 Subject: [PATCH 17/19] Add digital watchface preview on shake --- src/displayapp/Apps.h | 1 + src/displayapp/DisplayApp.cpp | 15 ++++++++++- src/displayapp/screens/Clock.cpp | 9 ++++++- src/displayapp/screens/Clock.h | 3 +++ src/displayapp/screens/Notifications.h | 1 - src/displayapp/screens/Screen.h | 5 +++- src/displayapp/screens/WatchFaceDigital.cpp | 13 ++++++++-- src/displayapp/screens/WatchFaceDigital.h | 5 +++- src/displayapp/screens/WatchFaceFuzzy.cpp | 28 +++++++++++++++++---- src/displayapp/screens/WatchFaceFuzzy.h | 15 ++++++++++- 10 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index 8aad953517..6e3830c2c9 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -6,6 +6,7 @@ namespace Pinetime { None, Launcher, Clock, + WatchFaceDigitalPreview, SysInfo, FirmwareUpdate, FirmwareValidation, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index aa2c037e3f..aca77c4dab 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -12,6 +12,7 @@ #include "components/motor/MotorController.h" #include "displayapp/screens/ApplicationList.h" #include "displayapp/screens/Clock.h" +#include "displayapp/screens/WatchFaceDigital.h" #include "displayapp/screens/FirmwareUpdate.h" #include "displayapp/screens/FirmwareValidation.h" #include "displayapp/screens/InfiniPaint.h" @@ -327,9 +328,21 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) settingsController, heartRateController, motionController, + motorController, filesystem); break; - + case Apps::WatchFaceDigitalPreview: + currentScreen = std::make_unique(this, + dateTimeController, + batteryController, + bleController, + notificationManager, + settingsController, + heartRateController, + motionController, + Screens::Screen::Modes::Preview); + ReturnApp(Apps::Clock, FullRefreshDirections::Left, TouchEvents::None); + break; case Apps::Error: currentScreen = std::make_unique(this, bootError); ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 6961f52ea0..4867b7c439 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -4,6 +4,7 @@ #include #include "components/battery/BatteryController.h" #include "components/motion/MotionController.h" +#include "components/motor/MotorController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" #include "components/settings/Settings.h" @@ -25,6 +26,7 @@ Clock::Clock(DisplayApp* app, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, + Controllers::MotorController& motorController, Controllers::FS& filesystem) : Screen(app), dateTimeController {dateTimeController}, @@ -34,6 +36,7 @@ Clock::Clock(DisplayApp* app, settingsController {settingsController}, heartRateController {heartRateController}, motionController {motionController}, + motorController {motorController}, filesystem {filesystem}, screen {[this, &settingsController]() { switch (settingsController.GetClockFace()) { @@ -126,5 +129,9 @@ std::unique_ptr Clock::WatchFaceInfineatScreen() { } std::unique_ptr Clock::WatchFaceFuzzyScreen() { - return std::make_unique(app, dateTimeController); + return std::make_unique(app, + dateTimeController, + settingsController, + motorController, + motionController); } diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 118a350935..f210d1ebb7 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -15,6 +15,7 @@ namespace Pinetime { class Ble; class NotificationManager; class MotionController; + class MotorController; } namespace Applications { @@ -29,6 +30,7 @@ namespace Pinetime { Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, Controllers::MotionController& motionController, + Controllers::MotorController& motorController, Controllers::FS& filesystem); ~Clock() override; @@ -43,6 +45,7 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + Controllers::MotorController& motorController; Controllers::FS& filesystem; std::unique_ptr screen; diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 9d843a9b13..adcb26617b 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -18,7 +18,6 @@ namespace Pinetime { class Notifications : public Screen { public: - enum class Modes { Normal, Preview }; explicit Notifications(DisplayApp* app, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::AlertNotificationService& alertNotificationService, diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index e72a2368fb..167b698ef8 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -44,7 +44,9 @@ namespace Pinetime { } public: - explicit Screen(DisplayApp* app) : app {app} { + enum class Modes { Normal, Preview }; + explicit Screen(DisplayApp* app, Modes mode = Modes::Normal) + : app {app}, mode {mode} { } virtual ~Screen() = default; @@ -71,6 +73,7 @@ namespace Pinetime { protected: DisplayApp* app; bool running = true; + Modes mode = Modes::Normal; }; } } diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 47f40dabbe..44e71dfd12 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -21,8 +21,9 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, Controllers::NotificationManager& notificationManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController) - : Screen(app), + Controllers::MotionController& motionController, + Screen::Modes mode) + : Screen(app, mode), currentDateTime {{}}, dateTimeController {dateTimeController}, notificationManager {notificationManager}, @@ -71,6 +72,10 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, lv_label_set_text_static(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + if (mode == Screen::Modes::Preview) { + timeoutTickCount = xTaskGetTickCount() + (5 * 1024); + } + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); Refresh(); } @@ -175,4 +180,8 @@ void WatchFaceDigital::Refresh() { lv_obj_realign(stepValue); lv_obj_realign(stepIcon); } + + if (mode == Screen::Modes::Preview && xTaskGetTickCount() > timeoutTickCount) { + running = false; + } } diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 60446afaa7..731b014472 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -31,7 +31,8 @@ namespace Pinetime { Controllers::NotificationManager& notificationManager, Controllers::Settings& settingsController, Controllers::HeartRateController& heartRateController, - Controllers::MotionController& motionController); + Controllers::MotionController& motionController, + Screen::Modes mode = Screen::Modes::Normal); ~WatchFaceDigital() override; void Refresh() override; @@ -71,6 +72,8 @@ namespace Pinetime { Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; + uint32_t timeoutTickCount; + lv_task_t* taskRefresh; Widgets::StatusIcons statusIcons; }; diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 0ee1b4eb13..491f4fafd5 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -1,12 +1,20 @@ #include "WatchFaceFuzzy.h" -#include #include +#include using namespace Pinetime::Applications::Screens; -WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController) - : Screen(app), dateTimeController {dateTimeController} { +WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Settings& settingsController, + Controllers::MotorController& motorController, + Controllers::MotionController& motionController) + : Screen(app), + dateTimeController {dateTimeController}, + settingsController {settingsController}, + motorController {motorController}, + motionController {motionController} { backgroundLabel = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_click(backgroundLabel, true); @@ -23,7 +31,7 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeC lv_obj_set_style_local_text_color(timeLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_obj_set_style_local_text_font(timeLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); - taskRefresh = lv_task_create(RefreshTaskCallback, 60000, LV_TASK_PRIO_MID, this); + taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); Refresh(); } @@ -34,10 +42,20 @@ WatchFaceFuzzy::~WatchFaceFuzzy() { } void WatchFaceFuzzy::Refresh() { + // Triggered once, on shaking state change (off -> on) + should_digital = motionController.Should_ShakeWake(settingsController.GetShakeThreshold()); + if (!shaking && should_digital) { + motorController.RunForDuration(35); + app->StartApp(Apps::WatchFaceDigitalPreview, DisplayApp::FullRefreshDirections::Right); + } + shaking = should_digital; + + // TODO: while the refresh rate is high enough to detect interaction, + // we only need to run the rest of the code every 60 seconds. uint8_t hours, minutes; std::string hoursStr, timeStr; - hours = dateTimeController.Hours() % 12; // TODO: maybe that's not needed? + hours = dateTimeController.Hours() % 12; minutes = dateTimeController.Minutes(); auto sector = minutes / 5 + (minutes % 5 > 2); if (sector == 12) { diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index 7764bb5a48..23c1d3617a 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -2,25 +2,38 @@ #include #include "Screen.h" +#include "displayapp/DisplayApp.h" #include "components/datetime/DateTimeController.h" +#include "components/settings/Settings.h" +#include "components/motion/MotionController.h" +#include "components/motion/MotionController.h" namespace Pinetime { namespace Applications { namespace Screens { class WatchFaceFuzzy : public Screen { public: - WatchFaceFuzzy(DisplayApp* app, Controllers::DateTime& dateTimeController); + WatchFaceFuzzy(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Settings& settingsController, + Controllers::MotorController& motorController, + Controllers::MotionController& motionController); ~WatchFaceFuzzy() override; void Refresh() override; private: Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + Controllers::MotorController& motorController; + Controllers::MotionController& motionController; lv_task_t* taskRefresh; lv_obj_t* backgroundLabel; lv_obj_t* timeLabel; const char* timeAccent = "ffffff"; static const char* timeSectors[12]; static const char* hourNames[12]; + bool shaking = true; + bool should_digital; }; } } From a1386e7b1c228882549831c52c951312579c9a88 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 29 Sep 2022 10:48:36 +0100 Subject: [PATCH 18/19] Minor fixes due to changes in how fonts are handled --- src/CMakeLists.txt | 1 - src/displayapp/fonts/fonts.json | 2 +- src/displayapp/screens/WatchFaceFuzzy.cpp | 2 +- src/displayapp/screens/WatchFaceFuzzy.h | 22 +++++++++++++--------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29348c8329..2450b00ff3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -431,7 +431,6 @@ list(APPEND SOURCE_FILES displayapp/screens/WatchFaceTerminal.cpp displayapp/screens/WatchFaceFuzzy.cpp displayapp/screens/WatchFacePineTimeStyle.cpp - displayapp/screens/PineTimeStyle.cpp ## diff --git a/src/displayapp/fonts/fonts.json b/src/displayapp/fonts/fonts.json index 006b884947..6d409bb9f3 100644 --- a/src/displayapp/fonts/fonts.json +++ b/src/displayapp/fonts/fonts.json @@ -18,7 +18,7 @@ "sources": [ { "file": "JetBrainsMono-Regular.ttf", - "range": "0x25, 0x2b, 0x2d, 0x30-0x3a" + "range": "0x20, 0x25, 0x27, 0x2b, 0x2d, 0x30-0x3a, 0x61-0x7a" } ], "bpp": 1, diff --git a/src/displayapp/screens/WatchFaceFuzzy.cpp b/src/displayapp/screens/WatchFaceFuzzy.cpp index 491f4fafd5..3b3bec55de 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.cpp +++ b/src/displayapp/screens/WatchFaceFuzzy.cpp @@ -21,7 +21,7 @@ WatchFaceFuzzy::WatchFaceFuzzy(DisplayApp* app, lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES); lv_obj_set_pos(backgroundLabel, 0, 0); - lv_label_set_text(backgroundLabel, ""); + lv_label_set_text_static(backgroundLabel, ""); timeLabel = lv_label_create(backgroundLabel, nullptr); lv_label_set_long_mode(timeLabel, LV_LABEL_LONG_BREAK); diff --git a/src/displayapp/screens/WatchFaceFuzzy.h b/src/displayapp/screens/WatchFaceFuzzy.h index 23c1d3617a..0474de020f 100644 --- a/src/displayapp/screens/WatchFaceFuzzy.h +++ b/src/displayapp/screens/WatchFaceFuzzy.h @@ -1,11 +1,11 @@ #pragma once #include -#include "Screen.h" +#include "displayapp/screens/Screen.h" #include "displayapp/DisplayApp.h" #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" -#include "components/motion/MotionController.h" +#include "components/motor/MotorController.h" #include "components/motion/MotionController.h" namespace Pinetime { @@ -19,21 +19,25 @@ namespace Pinetime { Controllers::MotorController& motorController, Controllers::MotionController& motionController); ~WatchFaceFuzzy() override; + void Refresh() override; private: - Controllers::DateTime& dateTimeController; - Controllers::Settings& settingsController; - Controllers::MotorController& motorController; - Controllers::MotionController& motionController; - lv_task_t* taskRefresh; - lv_obj_t* backgroundLabel; - lv_obj_t* timeLabel; const char* timeAccent = "ffffff"; static const char* timeSectors[12]; static const char* hourNames[12]; bool shaking = true; bool should_digital; + + lv_obj_t* backgroundLabel; + lv_obj_t* timeLabel; + + Controllers::DateTime& dateTimeController; + Controllers::Settings& settingsController; + Controllers::MotorController& motorController; + Controllers::MotionController& motionController; + + lv_task_t* taskRefresh; }; } } From 8e7e014094686459d419c3ca081f3a24bc6ccf03 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 29 Sep 2022 11:33:08 +0100 Subject: [PATCH 19/19] Minor fixes --- src/displayapp/screens/Clock.cpp | 2 +- src/displayapp/screens/settings/SettingWatchFace.cpp | 8 ++++---- src/displayapp/screens/settings/SettingWatchFace.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 4867b7c439..a92d9344e9 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -122,7 +122,7 @@ std::unique_ptr Clock::WatchFaceInfineatScreen() { dateTimeController, batteryController, bleController, - notificatioManager, + notificationManager, settingsController, motionController, filesystem); diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index fb4168d582..e87491c78c 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -1,10 +1,8 @@ #include "displayapp/screens/settings/SettingWatchFace.h" #include #include "displayapp/DisplayApp.h" -#include "displayapp/screens/CheckboxList.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/Styles.h" -#include "displayapp/screens/Symbols.h" #include "components/settings/Settings.h" using namespace Pinetime::Applications::Screens; @@ -16,6 +14,8 @@ namespace { } } +constexpr std::array SettingWatchFace::options; + auto SettingWatchFace::CreateScreenList() { std::array()>, nScreens> screens; for (uint8_t i = 0; i < screens.size(); i++) { @@ -33,14 +33,14 @@ std::unique_ptr SettingWatchFace::CreateScreen(uint8_t screenIdx) { /* Title... */ lv_obj_t* title = lv_label_create(container, nullptr); - lv_label_set_text_static(title, this.title); + lv_label_set_text_static(title, this->title); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); lv_obj_align(title, container, LV_ALIGN_IN_TOP_MID, 10, 15); /* ...with icon */ lv_obj_t* icon = lv_label_create(container, nullptr); lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - lv_label_set_text_static(icon, this.icon); + lv_label_set_text_static(icon, this->icon); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 85ba243499..32412885d0 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -3,10 +3,11 @@ #include #include #include +#include "components/settings/Settings.h" +#include "displayapp/screens/Container.h" #include "displayapp/screens/Screen.h" #include "displayapp/screens/ScreenList.h" -#include "displayapp/screens/Container.h" -#include "components/settings/Settings.h" +#include "displayapp/screens/Symbols.h" namespace Pinetime { namespace Applications { @@ -37,7 +38,6 @@ namespace Pinetime { std::unique_ptr CreateScreen(uint8_t screenIdx); Controllers::Settings& settingsController; - ScreenList<2> screens; ScreenList screens;