diff options
Diffstat (limited to 'src/DisplayApp')
-rw-r--r-- | src/DisplayApp/DisplayApp.cpp | 84 | ||||
-rw-r--r-- | src/DisplayApp/DisplayApp.h | 28 | ||||
-rw-r--r-- | src/DisplayApp/Fonts/jetbrains_mono_bold_20.c | 594 | ||||
-rw-r--r-- | src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c | 507 | ||||
-rw-r--r-- | src/DisplayApp/LittleVgl.cpp | 717 | ||||
-rw-r--r-- | src/DisplayApp/LittleVgl.h | 100 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Clock.cpp | 142 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Clock.h | 51 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Gauge.cpp | 57 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Gauge.h | 39 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Message.cpp | 82 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Message.h | 20 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Meter.cpp | 47 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Meter.h | 38 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Modal.cpp | 81 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Modal.h | 44 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Screen.h | 15 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Tab.cpp | 67 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Tab.h | 28 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Tile.cpp | 163 | ||||
-rw-r--r-- | src/DisplayApp/Screens/Tile.h | 64 |
21 files changed, 2865 insertions, 103 deletions
diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index ca139423..d7d62dde 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -4,35 +4,39 @@ #include <libraries/log/nrf_log.h> #include <boards.h> #include <nrf_font.h> -#include <hal/nrf_rtc.h> -#include "Components/Gfx/Gfx.h" #include <queue.h> #include <Components/DateTime/DateTimeController.h> #include <drivers/Cst816s.h> -#include <chrono> #include <string> +#include <lvgl/lvgl.h> +#include <DisplayApp/Screens/Tile.h> +#include <DisplayApp/Screens/Message.h> +#include <DisplayApp/Screens/Meter.h> +#include <DisplayApp/Screens/Gauge.h> +#include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::Gfx& gfx, + Pinetime::Components::LittleVgl& lvgl, Pinetime::Drivers::Cst816S& touchPanel, Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController) : + Controllers::DateTime &dateTimeController, + Pinetime::System::SystemTask& systemTask) : lcd{lcd}, - gfx{gfx}, + lvgl{lvgl}, touchPanel{touchPanel}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - clockScreen{gfx} { + currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) }, + systemTask{systemTask} { msgQueue = xQueueCreate(queueSize, itemSize); - currentScreen = &clockScreen; } void DisplayApp::Start() { - if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 256, this, 0, &taskHandle)) + if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 512, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } @@ -40,8 +44,14 @@ void DisplayApp::Process(void *instance) { auto *app = static_cast<DisplayApp *>(instance); NRF_LOG_INFO("DisplayApp task started!"); app->InitHw(); + + // Send a dummy notification to unlock the lvgl display driver for the first iteration + xTaskNotifyGive(xTaskGetCurrentTaskHandle()); + while (1) { + app->Refresh(); + } } @@ -52,8 +62,6 @@ void DisplayApp::InitHw() { nrf_gpio_pin_clear(pinLcdBacklight1); nrf_gpio_pin_clear(pinLcdBacklight2); nrf_gpio_pin_clear(pinLcdBacklight3); - - currentScreen->Refresh(true); } uint32_t acc = 0; @@ -68,7 +76,7 @@ void DisplayApp::Refresh() { break; case States::Running: RunningState(); - queueTimeout = 1000; + queueTimeout = 20; break; } @@ -99,25 +107,51 @@ void DisplayApp::Refresh() { case Messages::UpdateDateTime: break; case Messages::UpdateBleConnection: - clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected); +// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected); break; case Messages::UpdateBatteryLevel: - clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); +// clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); break; case Messages::TouchEvent: if(state != States::Running) break; OnTouchEvent(); break; + case Messages::ButtonPushed: + if(!currentScreen->OnButtonPushed()) { + systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); + } +// currentScreen.reset(nullptr); +// if(toggle) { +// modal.Show(); +//// currentScreen.reset(new Screens::Tile(this)); +// toggle = false; +// } else { +// modal.Hide(); +//// currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); +// toggle = true; +// } + + break; } } } void DisplayApp::RunningState() { - clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); - - if(currentScreen != nullptr) { - currentScreen->Refresh(false); +// clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); + + if(!currentScreen->Refresh()) { + currentScreen.reset(nullptr); + switch(nextApp) { + case Apps::None: + case Apps::Launcher: currentScreen.reset(new Screens::Tile(this)); break; + case Apps::Clock: currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); break; + case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; + case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; + case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; + } + nextApp = Apps::None; } + lv_task_handler(); } void DisplayApp::IdleState() { @@ -136,10 +170,14 @@ void DisplayApp::PushMessage(DisplayApp::Messages msg) { static uint16_t pointColor = 0x07e0; void DisplayApp::OnTouchEvent() { - auto info = touchPanel.GetTouchInfo(); +// auto info = touchPanel.GetTouchInfo(); +// +// if(info.isTouch) { +// lcd.DrawPixel(info.x, info.y, pointColor); +// pointColor+=10; +// } +} - if(info.isTouch) { - gfx.FillRectangle(info.x-10, info.y-10, 20,20, pointColor); - pointColor+=10; - } +void DisplayApp::StartApp(DisplayApp::Apps app) { + nextApp = app; } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 5a5d3ee6..348fd5bf 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -11,35 +11,39 @@ #include <Components/DateTime/DateTimeController.h> #include "Fonts/lcdfont14.h" #include "../drivers/Cst816s.h" +#include "LittleVgl.h" #include <date/date.h> #include <DisplayApp/Screens/Clock.h> -#include <DisplayApp/Screens/Message.h> -extern const FONT_INFO lCD_70ptFontInfo; namespace Pinetime { + namespace System { + class SystemTask; + }; namespace Applications { class DisplayApp { public: enum class States {Idle, Running}; - enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent} ; + enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ; DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::Gfx& gfx, + Pinetime::Components::LittleVgl& lvgl, Pinetime::Drivers::Cst816S&, Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime& dateTimeController); + Controllers::DateTime& dateTimeController, + Pinetime::System::SystemTask& systemTask); void Start(); void PushMessage(Messages msg); + enum class Apps {None, Launcher, Clock, Test, Meter, Gauge}; + void StartApp(Apps app); + private: TaskHandle_t taskHandle; static void Process(void* instance); void InitHw(); Pinetime::Drivers::St7789& lcd; - Pinetime::Components::Gfx& gfx; - const FONT_INFO largeFont {lCD_70ptFontInfo.height, lCD_70ptFontInfo.startChar, lCD_70ptFontInfo.endChar, lCD_70ptFontInfo.spacePixels, lCD_70ptFontInfo.charInfo, lCD_70ptFontInfo.data}; - const FONT_INFO smallFont {lCD_14ptFontInfo.height, lCD_14ptFontInfo.startChar, lCD_14ptFontInfo.endChar, lCD_14ptFontInfo.spacePixels, lCD_14ptFontInfo.charInfo, lCD_14ptFontInfo.data}; + Pinetime::Components::LittleVgl lvgl; void Refresh(); States state = States::Running; @@ -57,11 +61,15 @@ namespace Pinetime { Pinetime::Drivers::Cst816S& touchPanel; void OnTouchEvent(); - Screens::Clock clockScreen; - Screens::Screen* currentScreen = nullptr; + std::unique_ptr<Screens::Screen> currentScreen; static constexpr uint8_t pinLcdBacklight1 = 14; static constexpr uint8_t pinLcdBacklight2 = 22; static constexpr uint8_t pinLcdBacklight3 = 23; + + bool isClock = true; + + Pinetime::System::SystemTask& systemTask; + Apps nextApp = Apps::None; }; } } diff --git a/src/DisplayApp/Fonts/jetbrains_mono_bold_20.c b/src/DisplayApp/Fonts/jetbrains_mono_bold_20.c new file mode 100644 index 00000000..e7d053b8 --- /dev/null +++ b/src/DisplayApp/Fonts/jetbrains_mono_bold_20.c @@ -0,0 +1,594 @@ +#include "lvgl/lvgl.h" + +/******************************************************************************* + * Size: 20 px + * Bpp: 1 + * Opts: + ******************************************************************************/ + +#ifndef JETBRAINS_MONO_BOLD_20 +#define JETBRAINS_MONO_BOLD_20 1 +#endif + +#if JETBRAINS_MONO_BOLD_20 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+20 " " */ + 0x0, + + /* U+21 "!" */ + 0xff, 0xff, 0xff, 0xe0, 0xf, 0xc0, + + /* U+22 "\"" */ + 0xef, 0xdf, 0xbf, 0x7e, 0xfd, 0xc0, + + /* U+23 "#" */ + 0x8, 0xc3, 0x10, 0x62, 0x3f, 0xf7, 0xfe, 0x23, + 0x4, 0x61, 0x88, 0x31, 0x1f, 0xfb, 0xff, 0x19, + 0x82, 0x30, 0xc4, 0x0, + + /* U+24 "$" */ + 0x1c, 0x7, 0x3, 0xf1, 0xfe, 0xe3, 0xf8, 0x7e, + 0x3, 0xe0, 0x7f, 0x7, 0xe0, 0x3c, 0x7, 0xe1, + 0xfc, 0xf7, 0xf8, 0xfc, 0x1c, 0x7, 0x0, + + /* U+25 "%" */ + 0x78, 0x1f, 0x83, 0x30, 0x66, 0x1f, 0xcc, 0xf2, + 0x1, 0x80, 0xde, 0x67, 0xf8, 0xcc, 0x19, 0x83, + 0x30, 0x7e, 0x7, 0x80, + + /* U+26 "&" */ + 0x1e, 0x7, 0xe1, 0xce, 0x38, 0x7, 0x0, 0x70, + 0x1e, 0x7, 0x66, 0xed, 0xdc, 0xf3, 0x9c, 0x73, + 0xcf, 0xfc, 0xf9, 0x80, + + /* U+27 "'" */ + 0xff, 0xff, 0xc0, + + /* U+28 "(" */ + 0x2, 0x1c, 0xfb, 0xc7, 0x1e, 0x38, 0x70, 0xe1, + 0xc3, 0x87, 0xe, 0x1c, 0x3c, 0x38, 0x38, 0x7c, + 0x38, + + /* U+29 ")" */ + 0x1, 0xc3, 0xc1, 0xc1, 0xc3, 0xc3, 0x87, 0xe, + 0x1c, 0x38, 0x70, 0xe1, 0xc7, 0x8e, 0x79, 0xe3, + 0x80, + + /* U+2A "*" */ + 0xc, 0x3, 0x8, 0xc7, 0xb7, 0x7f, 0x83, 0x1, + 0xe0, 0xcc, 0x73, 0x80, 0x0, + + /* U+2B "+" */ + 0x1c, 0x7, 0x1, 0xc3, 0xff, 0xff, 0xc7, 0x1, + 0xc0, 0x70, 0x1c, 0x0, + + /* U+2C "," */ + 0x7b, 0x9c, 0xce, 0x60, + + /* U+2D "-" */ + 0xff, 0xff, + + /* U+2E "." */ + 0x6f, 0xf6, + + /* U+2F "/" */ + 0x1, 0xc0, 0x60, 0x38, 0xe, 0x3, 0x1, 0xc0, + 0x70, 0x18, 0xe, 0x3, 0x1, 0xc0, 0x70, 0x18, + 0xe, 0x3, 0x80, 0xc0, 0x70, 0x18, 0xe, 0x0, + + /* U+30 "0" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xfb, 0x7e, + 0xdf, 0xb7, 0xed, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0x8f, 0x80, + + /* U+31 "1" */ + 0x3c, 0x3e, 0x3f, 0x13, 0x81, 0xc0, 0xe0, 0x70, + 0x38, 0x1c, 0xe, 0x7, 0x3, 0x8f, 0xff, 0xfc, + + /* U+32 "2" */ + 0x1f, 0x1f, 0xef, 0x3f, 0x87, 0x1, 0xc0, 0x70, + 0x38, 0x1e, 0xf, 0x7, 0x87, 0x83, 0xc0, 0xff, + 0xff, 0xf0, + + /* U+33 "3" */ + 0x7f, 0xdf, 0xf0, 0x3c, 0x1c, 0x1c, 0x7, 0xc1, + 0xf8, 0xf, 0x1, 0xc0, 0x7e, 0x1d, 0x8f, 0x7f, + 0x87, 0xc0, + + /* U+34 "4" */ + 0x7, 0x7, 0x3, 0x83, 0x83, 0x81, 0xc1, 0xcf, + 0xe7, 0xe3, 0xff, 0xff, 0xe0, 0x70, 0x38, 0x1c, + + /* U+35 "5" */ + 0xff, 0x7f, 0xb8, 0x1c, 0xe, 0x7, 0x73, 0xfd, + 0xcf, 0x3, 0x81, 0xc0, 0xfc, 0xff, 0xf1, 0xf0, + + /* U+36 "6" */ + 0x6, 0x3, 0x1, 0xc0, 0x60, 0x30, 0x1b, 0xc7, + 0xfb, 0xcf, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0x87, 0x80, + + /* U+37 "7" */ + 0xff, 0xff, 0xfe, 0xb, 0x86, 0x1, 0x80, 0xc0, + 0x30, 0x18, 0x6, 0x3, 0x80, 0xc0, 0x70, 0x18, + 0xe, 0x0, + + /* U+38 "8" */ + 0x3e, 0x1f, 0xce, 0x3b, 0x6, 0xe3, 0x9f, 0xc7, + 0xf1, 0x8e, 0xc1, 0xf0, 0x7c, 0x1f, 0x8f, 0x7f, + 0x8f, 0x80, + + /* U+39 "9" */ + 0x1e, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7f, + 0x3d, 0xfe, 0x3d, 0x80, 0xc0, 0x60, 0x38, 0xc, + 0x6, 0x0, + + /* U+3A ":" */ + 0xff, 0x80, 0x0, 0xff, 0x80, + + /* U+3B ";" */ + 0x7b, 0xde, 0x0, 0x0, 0x0, 0x7b, 0x9c, 0xce, + 0x60, + + /* U+3C "<" */ + 0x0, 0x81, 0xc3, 0xe7, 0xcf, 0x6, 0x3, 0xc0, + 0x7c, 0xf, 0x81, 0xc0, 0x20, + + /* U+3D "=" */ + 0xff, 0xff, 0xc0, 0x0, 0x0, 0x7, 0xff, 0xfe, + + /* U+3E ">" */ + 0x0, 0x70, 0x3e, 0x7, 0xc0, 0xf8, 0xc, 0x1e, + 0x7c, 0xf8, 0x70, 0x20, 0x0, + + /* U+3F "?" */ + 0xfc, 0xfe, 0xf, 0x7, 0x7, 0xf, 0x3e, 0x3c, + 0x30, 0x30, 0x0, 0x0, 0x70, 0x70, + + /* U+40 "@" */ + 0x1f, 0x87, 0xf9, 0xc3, 0xf0, 0x3c, 0x77, 0x9f, + 0xf3, 0x1e, 0x63, 0xcc, 0x79, 0x8f, 0x31, 0xe7, + 0xfc, 0x77, 0xc0, 0x1c, 0x1, 0xf0, 0x1e, 0x0, + + /* U+41 "A" */ + 0xf, 0x0, 0xf0, 0xf, 0x1, 0xf8, 0x19, 0x81, + 0x98, 0x19, 0x83, 0x9c, 0x3f, 0xc3, 0xfc, 0x70, + 0xe7, 0xe, 0x60, 0x66, 0x6, + + /* U+42 "B" */ + 0xfe, 0x3f, 0xce, 0x3b, 0x8e, 0xe3, 0xb8, 0xcf, + 0xe3, 0xfc, 0xe3, 0xb8, 0x7e, 0x1f, 0x8f, 0xff, + 0xbf, 0xc0, + + /* U+43 "C" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe0, 0x38, 0xe, + 0x3, 0x80, 0xe0, 0x38, 0xe, 0x1f, 0xcf, 0x7f, + 0x8f, 0xc0, + + /* U+44 "D" */ + 0xfe, 0x3f, 0xee, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xe1, 0xf8, 0x7e, 0x1f, 0x8f, 0xff, + 0xbf, 0x80, + + /* U+45 "E" */ + 0xff, 0xff, 0xf8, 0x1c, 0xe, 0x7, 0x3, 0xfd, + 0xfe, 0xe0, 0x70, 0x38, 0x1c, 0xf, 0xff, 0xfc, + + /* U+46 "F" */ + 0xff, 0xff, 0xf8, 0x1c, 0xe, 0x7, 0x3, 0xff, + 0xff, 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x0, + + /* U+47 "G" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe0, 0x38, 0xe, + 0x7f, 0x9f, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0x87, 0x80, + + /* U+48 "H" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0xff, + 0xff, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1c, + + /* U+49 "I" */ + 0xff, 0xff, 0xc7, 0x3, 0x81, 0xc0, 0xe0, 0x70, + 0x38, 0x1c, 0xe, 0x7, 0x3, 0x8f, 0xff, 0xfc, + + /* U+4A "J" */ + 0x3f, 0xcf, 0xf0, 0x1c, 0x7, 0x1, 0xc0, 0x70, + 0x1c, 0x7, 0x1, 0xc0, 0x7e, 0x1f, 0x8f, 0x7f, + 0x8f, 0xc0, + + /* U+4B "K" */ + 0xe1, 0xdc, 0x3b, 0x8e, 0x71, 0xce, 0x31, 0xce, + 0x3f, 0x87, 0xf0, 0xe7, 0x1c, 0x63, 0x8e, 0x70, + 0xce, 0x1d, 0xc3, 0x80, + + /* U+4C "L" */ + 0xe0, 0x70, 0x38, 0x1c, 0xe, 0x7, 0x3, 0x81, + 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xf, 0xff, 0xfc, + + /* U+4D "M" */ + 0xe1, 0xf8, 0x7f, 0x3f, 0xcf, 0xda, 0xf7, 0xbd, + 0xef, 0x33, 0xc0, 0xf0, 0x3c, 0xf, 0x3, 0xc0, + 0xf0, 0x30, + + /* U+4E "N" */ + 0xe1, 0xf0, 0xfc, 0x7e, 0x3d, 0x9e, 0xcf, 0x67, + 0x9b, 0xcd, 0xe6, 0xf1, 0xf8, 0xfc, 0x3e, 0x1c, + + /* U+4F "O" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0x8f, 0x80, + + /* U+50 "P" */ + 0xff, 0x3f, 0xee, 0x3f, 0x87, 0xe1, 0xf8, 0xff, + 0xfb, 0xfc, 0xe0, 0x38, 0xe, 0x3, 0x80, 0xe0, + 0x38, 0x0, + + /* U+51 "Q" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0x8f, 0x80, 0x70, 0xe, 0x1, 0xc0, + + /* U+52 "R" */ + 0xff, 0x3f, 0xee, 0x3f, 0x87, 0xe1, 0xf8, 0xff, + 0xfb, 0xf8, 0xe6, 0x39, 0xce, 0x33, 0x8e, 0xe3, + 0xb8, 0x70, + + /* U+53 "S" */ + 0x3f, 0x1f, 0xee, 0x3f, 0x87, 0xe0, 0x3e, 0x7, + 0xf0, 0x7e, 0x3, 0xc0, 0x7e, 0x1f, 0xcf, 0x7f, + 0x8f, 0xc0, + + /* U+54 "T" */ + 0xff, 0xff, 0xf0, 0xe0, 0x38, 0xe, 0x3, 0x80, + 0xe0, 0x38, 0xe, 0x3, 0x80, 0xe0, 0x38, 0xe, + 0x3, 0x80, + + /* U+55 "U" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x77, 0xf1, 0xf0, + + /* U+56 "V" */ + 0x60, 0x66, 0x6, 0x70, 0xe7, 0xe, 0x30, 0xc3, + 0xc, 0x39, 0xc1, 0x98, 0x19, 0x81, 0x98, 0x1f, + 0x80, 0xf0, 0xf, 0x0, 0xf0, + + /* U+57 "W" */ + 0xc6, 0x3c, 0x73, 0x47, 0x36, 0xf3, 0x6f, 0x26, + 0xf6, 0x6d, 0x66, 0xd6, 0x69, 0x66, 0x9e, 0x69, + 0xe6, 0x9e, 0x39, 0xe3, 0x9e, + + /* U+58 "X" */ + 0xe1, 0xd8, 0x67, 0x38, 0xcc, 0x3f, 0x7, 0x81, + 0xe0, 0x78, 0x1e, 0xf, 0xc3, 0x31, 0xce, 0xe1, + 0xf8, 0x70, + + /* U+59 "Y" */ + 0xe0, 0xfc, 0x1d, 0xc7, 0x38, 0xe3, 0x98, 0x77, + 0x6, 0xc0, 0xf8, 0xe, 0x1, 0xc0, 0x38, 0x7, + 0x0, 0xe0, 0x1c, 0x0, + + /* U+5A "Z" */ + 0xff, 0xff, 0xc0, 0xe0, 0xe0, 0x60, 0x70, 0x70, + 0x38, 0x38, 0x38, 0x1c, 0x1c, 0xf, 0xff, 0xfc, + + /* U+5B "[" */ + 0xff, 0xfe, 0x38, 0xe3, 0x8e, 0x38, 0xe3, 0x8e, + 0x38, 0xe3, 0x8e, 0x38, 0xff, 0xf0, + + /* U+5C "\\" */ + 0xe0, 0x18, 0x7, 0x1, 0xc0, 0x30, 0xe, 0x3, + 0x80, 0x60, 0x1c, 0x3, 0x0, 0xe0, 0x38, 0x6, + 0x1, 0xc0, 0x70, 0xc, 0x3, 0x80, 0x60, 0x1c, + + /* U+5D "]" */ + 0xff, 0xf1, 0xc7, 0x1c, 0x71, 0xc7, 0x1c, 0x71, + 0xc7, 0x1c, 0x71, 0xc7, 0xff, 0xf0, + + /* U+5E "^" */ + 0xc, 0x7, 0x81, 0xe0, 0xfc, 0x33, 0x1c, 0xe6, + 0x19, 0x86, + + /* U+5F "_" */ + 0xff, 0xff, 0xf0, + + /* U+60 "`" */ + 0x63, 0x8e, + + /* U+61 "a" */ + 0x1f, 0x1f, 0xef, 0x1c, 0x7, 0x3f, 0xdf, 0xfe, + 0x1f, 0x87, 0xe3, 0xff, 0xf7, 0x9c, + + /* U+62 "b" */ + 0xe0, 0x38, 0xe, 0x3, 0xbc, 0xff, 0xbc, 0xfe, + 0x1f, 0x87, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0xff, + 0xbb, 0xc0, + + /* U+63 "c" */ + 0x3f, 0x1f, 0xef, 0x1f, 0x83, 0xe0, 0x38, 0xe, + 0x3, 0x87, 0xf1, 0xdf, 0xe3, 0xe0, + + /* U+64 "d" */ + 0x1, 0xc0, 0x70, 0x1c, 0xf7, 0x7f, 0xfc, 0xfe, + 0x1f, 0x87, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f, + 0xcf, 0x70, + + /* U+65 "e" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xff, 0xff, 0xfe, + 0x3, 0x80, 0xf1, 0xdf, 0xe3, 0xf0, + + /* U+66 "f" */ + 0xf, 0xc7, 0xf1, 0xc0, 0x70, 0xff, 0xff, 0xf1, + 0xc0, 0x70, 0x1c, 0x7, 0x1, 0xc0, 0x70, 0x1c, + 0x7, 0x0, + + /* U+67 "g" */ + 0x3d, 0xdf, 0xff, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0xcf, 0x7f, 0xcf, 0x70, 0x1c, 0xf, 0x3f, + 0x8f, 0xc0, + + /* U+68 "h" */ + 0xe0, 0x70, 0x38, 0x1d, 0xcf, 0xf7, 0x9f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1c, + + /* U+69 "i" */ + 0x8, 0x7, 0x0, 0x80, 0x0, 0xfc, 0x3f, 0x1, + 0xc0, 0x70, 0x1c, 0x7, 0x1, 0xc0, 0x70, 0x1c, + 0x3f, 0xff, 0xfc, + + /* U+6A "j" */ + 0x2, 0x7, 0x2, 0x0, 0x7f, 0x7f, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xf, + 0xfe, 0xfc, + + /* U+6B "k" */ + 0xe0, 0x38, 0xe, 0x3, 0x87, 0xe1, 0xb8, 0xee, + 0x33, 0x9c, 0xfe, 0x3f, 0x8e, 0x73, 0x8e, 0xe3, + 0xb8, 0x70, + + /* U+6C "l" */ + 0xfe, 0x1f, 0xc0, 0x38, 0x7, 0x0, 0xe0, 0x1c, + 0x3, 0x80, 0x70, 0xe, 0x1, 0xc0, 0x38, 0x7, + 0x0, 0xfe, 0xf, 0xc0, + + /* U+6D "m" */ + 0xd9, 0xbf, 0xfc, 0xcf, 0x33, 0xcc, 0xf3, 0x3c, + 0xcf, 0x33, 0xcc, 0xf3, 0x3c, 0xcc, + + /* U+6E "n" */ + 0xee, 0x7f, 0xbc, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xf8, 0xe0, + + /* U+6F "o" */ + 0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xf3, 0xdf, 0xe1, 0xf0, + + /* U+70 "p" */ + 0xef, 0x3f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xf3, 0xff, 0xee, 0xf3, 0x80, 0xe0, + 0x38, 0x0, + + /* U+71 "q" */ + 0x3d, 0xdf, 0xff, 0x3f, 0x87, 0xe1, 0xf8, 0x7e, + 0x1f, 0x87, 0xf3, 0xdf, 0xf3, 0xdc, 0x7, 0x1, + 0xc0, 0x70, + + /* U+72 "r" */ + 0xef, 0x3f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0xe, + 0x3, 0x80, 0xe0, 0x38, 0xe, 0x0, + + /* U+73 "s" */ + 0x3f, 0x3f, 0xee, 0x1f, 0x80, 0xfc, 0x1f, 0xe0, + 0x3c, 0x7, 0xe1, 0xff, 0xe3, 0xf0, + + /* U+74 "t" */ + 0x1c, 0x7, 0x1, 0xc3, 0xff, 0xff, 0xc7, 0x1, + 0xc0, 0x70, 0x1c, 0x7, 0x1, 0xc0, 0x70, 0xf, + 0xc1, 0xf0, + + /* U+75 "u" */ + 0xe3, 0xf1, 0xf8, 0xfc, 0x7e, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe3, 0xbf, 0x8f, 0x80, + + /* U+76 "v" */ + 0xc0, 0xf8, 0x76, 0x19, 0x86, 0x73, 0x8c, 0xc3, + 0x30, 0xfc, 0x1e, 0x7, 0x81, 0xe0, + + /* U+77 "w" */ + 0xc6, 0x24, 0x62, 0x4e, 0x66, 0xf6, 0x6f, 0x66, + 0xf6, 0x6b, 0x66, 0x94, 0x79, 0x43, 0x9c, 0x39, + 0xc0, + + /* U+78 "x" */ + 0xe1, 0xdc, 0xe3, 0x30, 0xfc, 0x1e, 0x7, 0x81, + 0xe0, 0xfc, 0x73, 0x9c, 0x6e, 0x1c, + + /* U+79 "y" */ + 0xe1, 0xf8, 0x76, 0x19, 0xce, 0x33, 0x8e, 0xc3, + 0xf0, 0x7c, 0x1e, 0x3, 0x80, 0xc0, 0x70, 0x1c, + 0x6, 0x0, + + /* U+7A "z" */ + 0xff, 0xff, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0x7f, 0xff, 0xe0, + + /* U+7B "{" */ + 0x3, 0x87, 0xc3, 0x81, 0xc0, 0xe0, 0x70, 0x38, + 0x1c, 0xfc, 0x7e, 0x3, 0x81, 0xc0, 0xe0, 0x70, + 0x38, 0x1c, 0xf, 0x83, 0xc0, + + /* U+7C "|" */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + + /* U+7D "}" */ + 0xf0, 0x3f, 0x1, 0xc0, 0x70, 0x1c, 0x7, 0x1, + 0xc0, 0x70, 0xf, 0xc3, 0xf1, 0xc0, 0x70, 0x1c, + 0x7, 0x1, 0xc0, 0x70, 0xf8, 0x3c, 0x0, + + /* U+7E "~" */ + 0x78, 0xff, 0x3c, 0xff, 0x1e +}; + + +/*--------------------- + * 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 = 192, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 192, .box_w = 3, .box_h = 14, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 7, .adv_w = 192, .box_w = 7, .box_h = 6, .ofs_x = 3, .ofs_y = 8}, + {.bitmap_index = 13, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 33, .adv_w = 192, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 56, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 76, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 96, .adv_w = 192, .box_w = 3, .box_h = 6, .ofs_x = 5, .ofs_y = 8}, + {.bitmap_index = 99, .adv_w = 192, .box_w = 7, .box_h = 19, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 116, .adv_w = 192, .box_w = 7, .box_h = 19, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 133, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 146, .adv_w = 192, .box_w = 10, .box_h = 9, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 158, .adv_w = 192, .box_w = 5, .box_h = 6, .ofs_x = 3, .ofs_y = -3}, + {.bitmap_index = 162, .adv_w = 192, .box_w = 8, .box_h = 2, .ofs_x = 2, .ofs_y = 5}, + {.bitmap_index = 164, .adv_w = 192, .box_w = 4, .box_h = 4, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 166, .adv_w = 192, .box_w = 10, .box_h = 19, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 190, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 208, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 224, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 242, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 260, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 276, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 292, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 310, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 328, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 346, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 364, .adv_w = 192, .box_w = 3, .box_h = 11, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 369, .adv_w = 192, .box_w = 5, .box_h = 14, .ofs_x = 3, .ofs_y = -3}, + {.bitmap_index = 378, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 391, .adv_w = 192, .box_w = 9, .box_h = 7, .ofs_x = 2, .ofs_y = 3}, + {.bitmap_index = 399, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 412, .adv_w = 192, .box_w = 8, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 426, .adv_w = 192, .box_w = 11, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 450, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 471, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 489, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 507, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 525, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 541, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 557, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 575, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 591, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 607, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 625, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 645, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 661, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 679, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 695, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 713, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 731, .adv_w = 192, .box_w = 10, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 753, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 771, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 789, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 807, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 823, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 844, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 865, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 883, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 903, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 919, .adv_w = 192, .box_w = 6, .box_h = 18, .ofs_x = 4, .ofs_y = -2}, + {.bitmap_index = 933, .adv_w = 192, .box_w = 10, .box_h = 19, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 957, .adv_w = 192, .box_w = 6, .box_h = 18, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 971, .adv_w = 192, .box_w = 10, .box_h = 8, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 981, .adv_w = 192, .box_w = 10, .box_h = 2, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 984, .adv_w = 192, .box_w = 5, .box_h = 3, .ofs_x = 3, .ofs_y = 13}, + {.bitmap_index = 986, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1000, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1018, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1032, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1050, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1064, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1082, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1100, .adv_w = 192, .box_w = 9, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1116, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1135, .adv_w = 192, .box_w = 8, .box_h = 18, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1153, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1171, .adv_w = 192, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1191, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1205, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1218, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1232, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1250, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1268, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1282, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1296, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1314, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1327, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1341, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1358, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1372, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1390, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1403, .adv_w = 192, .box_w = 9, .box_h = 18, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 1424, .adv_w = 192, .box_w = 3, .box_h = 18, .ofs_x = 5, .ofs_y = -2}, + {.bitmap_index = 1431, .adv_w = 192, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1454, .adv_w = 192, .box_w = 10, .box_h = 4, .ofs_x = 1, .ofs_y = 5} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t jetbrains_mono_bold_20 = { + .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 = 20, /*The maximum line height required by the font*/ + .base_line = 3, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if JETBRAINS_MONO_BOLD_20*/ + diff --git a/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c b/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c new file mode 100644 index 00000000..c9917e40 --- /dev/null +++ b/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c @@ -0,0 +1,507 @@ +#include "lvgl/lvgl.h" + +/******************************************************************************* + * Size: 80 px + * Bpp: 1 + * Opts: + ******************************************************************************/ + +#ifndef JETBRAINS_MONO_EXTRABOLD_COMPRESSED +#define JETBRAINS_MONO_EXTRABOLD_COMPRESSED 1 +#endif + +#if JETBRAINS_MONO_EXTRABOLD_COMPRESSED + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+30 "0" */ + 0x0, 0x1, 0xff, 0xc0, 0x0, 0x0, 0xf, 0xff, + 0xfe, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xc0, 0x0, + 0x3f, 0xff, 0xff, 0xf8, 0x0, 0x3f, 0xff, 0xff, + 0xfe, 0x0, 0x3f, 0xff, 0xff, 0xff, 0x80, 0x3f, + 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, + 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0x1f, 0xff, 0xe0, 0x3f, 0xff, + 0xcf, 0xff, 0xc0, 0x7, 0xff, 0xe7, 0xff, 0xc0, + 0x1, 0xff, 0xf7, 0xff, 0xc0, 0x0, 0x7f, 0xff, + 0xff, 0xe0, 0x0, 0x3f, 0xff, 0xff, 0xe0, 0x0, + 0xf, 0xff, 0xff, 0xf0, 0x0, 0x7, 0xff, 0xff, + 0xf8, 0x0, 0x3, 0xff, 0xff, 0xfc, 0x0, 0x1, + 0xff, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x7f, 0xff, 0xff, 0x80, 0x0, 0x3f, + 0xff, 0xff, 0xc0, 0x70, 0x1f, 0xff, 0xff, 0xe0, + 0x7c, 0xf, 0xff, 0xff, 0xf0, 0x7f, 0x7, 0xff, + 0xff, 0xf8, 0x3f, 0x83, 0xff, 0xff, 0xfc, 0x1f, + 0xc1, 0xff, 0xff, 0xfe, 0xf, 0xe0, 0xff, 0xff, + 0xff, 0x7, 0xf0, 0x7f, 0xff, 0xff, 0x83, 0xf8, + 0x3f, 0xff, 0xff, 0xc1, 0xfc, 0x1f, 0xff, 0xff, + 0xe0, 0xfe, 0xf, 0xff, 0xff, 0xf0, 0x7f, 0x7, + 0xff, 0xff, 0xf8, 0x3f, 0x83, 0xff, 0xff, 0xfc, + 0x1f, 0xc1, 0xff, 0xff, 0xfe, 0xf, 0xe0, 0xff, + 0xff, 0xff, 0x3, 0xe0, 0x7f, 0xff, 0xff, 0x80, + 0xe0, 0x3f, 0xff, 0xff, 0xc0, 0x0, 0x1f, 0xff, + 0xff, 0xe0, 0x0, 0xf, 0xff, 0xff, 0xf0, 0x0, + 0x7, 0xff, 0xff, 0xf8, 0x0, 0x3, 0xff, 0xff, + 0xfc, 0x0, 0x1, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0x0, 0xff, 0xff, 0xff, + 0xc0, 0x0, 0x7f, 0xf9, 0xff, 0xf0, 0x0, 0x7f, + 0xfc, 0xff, 0xfc, 0x0, 0x7f, 0xfe, 0x7f, 0xff, + 0x80, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0x7, 0xff, 0xff, 0xff, 0xff, 0x3, 0xff, 0xff, + 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x3f, 0xff, 0xff, 0xff, 0x80, 0xf, 0xff, 0xff, + 0xff, 0x80, 0x3, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xfc, + 0x0, 0x0, 0x0, 0x7f, 0xf0, 0x0, 0x0, + + /* U+31 "1" */ + 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, 0xf, 0xff, + 0xe0, 0x0, 0x0, 0x3f, 0xff, 0xe0, 0x0, 0x0, + 0x7f, 0xff, 0xe0, 0x0, 0x1, 0xff, 0xff, 0xe0, + 0x0, 0x3, 0xff, 0xff, 0xe0, 0x0, 0x7, 0xff, + 0xff, 0xe0, 0x0, 0x1f, 0xff, 0xff, 0xe0, 0x0, + 0x3f, 0xff, 0xff, 0xe0, 0x0, 0x7f, 0xff, 0xff, + 0xe0, 0x0, 0x7f, 0xff, 0xff, 0xe0, 0x0, 0x7f, + 0xfd, 0xff, 0xe0, 0x0, 0x7f, 0xf9, 0xff, 0xe0, + 0x0, 0x7f, 0xf1, 0xff, 0xe0, 0x0, 0x7f, 0xe1, + 0xff, 0xe0, 0x0, 0x7f, 0x81, 0xff, 0xe0, 0x0, + 0x7f, 0x1, 0xff, 0xe0, 0x0, 0x7c, 0x1, 0xff, + 0xe0, 0x0, 0x78, 0x1, 0xff, 0xe0, 0x0, 0x60, + 0x1, 0xff, 0xe0, 0x0, 0x40, 0x1, 0xff, 0xe0, + 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, + 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, + 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, + 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, + 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, + 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, + 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, + 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, + 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, + 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, + 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, + 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, + 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x1, + 0xff, 0xe0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, + + /* U+32 "2" */ + 0x0, 0x1, 0xff, 0xc0, 0x0, 0x0, 0xf, 0xff, + 0xfc, 0x0, 0x0, 0x1f, 0xff, 0xff, 0x80, 0x0, + 0x3f, 0xff, 0xff, 0xf0, 0x0, 0x3f, 0xff, 0xff, + 0xfc, 0x0, 0x3f, 0xff, 0xff, 0xff, 0x0, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, + 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xe0, 0x7f, 0xff, + 0x8f, 0xff, 0xc0, 0xf, 0xff, 0xc7, 0xff, 0xc0, + 0x3, 0xff, 0xe7, 0xff, 0xc0, 0x0, 0xff, 0xfb, + 0xff, 0xc0, 0x0, 0x7f, 0xfd, 0xff, 0xe0, 0x0, + 0x1f, 0xfe, 0xff, 0xf0, 0x0, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x7, 0xff, 0x80, 0x0, 0x0, 0x3, + 0xff, 0xc0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, 0xff, + 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x0, + 0x0, 0x7f, 0xfc, 0x0, 0x0, 0x0, 0x3f, 0xfe, + 0x0, 0x0, 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0x0, 0x0, 0x0, 0x3f, 0xff, 0x0, + 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0x80, 0x0, 0x0, 0x7f, 0xff, 0x80, 0x0, + 0x0, 0x7f, 0xff, 0x80, 0x0, 0x0, 0x7f, 0xff, + 0x80, 0x0, 0x0, 0x7f, 0xff, 0x80, 0x0, 0x0, + 0xff, 0xff, 0x80, 0x0, 0x0, 0xff, 0xff, 0x80, + 0x0, 0x0, 0xff, 0xff, 0x80, 0x0, 0x0, 0xff, + 0xff, 0x80, 0x0, 0x1, 0xff, 0xff, 0x0, 0x0, + 0x1, 0xff, 0xff, 0x0, 0x0, 0x1, 0xff, 0xff, + 0x0, 0x0, 0x1, 0xff, 0xfe, 0x0, 0x0, 0x3, + 0xff, 0xfe, 0x0, 0x0, 0x3, 0xff, 0xfe, 0x0, + 0x0, 0x3, 0xff, 0xfc, 0x0, 0x0, 0x3, 0xff, + 0xfc, 0x0, 0x0, 0x1, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0xc0, + + /* U+33 "3" */ + 0x1f, 0xff, 0xff, 0xff, 0xfe, 0xf, 0xff, 0xff, + 0xff, 0xff, 0x7, 0xff, 0xff, 0xff, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, + 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, + 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0xf, 0xff, + 0xff, 0x8f, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, + 0x80, 0x0, 0x0, 0x1f, 0xff, 0x80, 0x0, 0x0, + 0x1f, 0xff, 0x80, 0x0, 0x0, 0x3f, 0xff, 0x80, + 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0x0, 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, + 0x0, 0x3f, 0xff, 0x0, 0x0, 0x0, 0x3f, 0xfe, + 0x0, 0x0, 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, + 0x3f, 0xfe, 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0, + 0x0, 0x0, 0x1f, 0xff, 0x80, 0x0, 0x0, 0xf, + 0xff, 0xf8, 0x0, 0x0, 0x7, 0xff, 0xff, 0x0, + 0x0, 0x3, 0xff, 0xff, 0xe0, 0x0, 0x1, 0xff, + 0xff, 0xf8, 0x0, 0x0, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0x80, 0x0, 0x3f, 0xff, + 0xff, 0xe0, 0x0, 0x1f, 0xff, 0xff, 0xf0, 0x0, + 0xf, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0xff, + 0xfe, 0x0, 0x0, 0x0, 0x1f, 0xff, 0x80, 0x0, + 0x0, 0x7, 0xff, 0xc0, 0x0, 0x0, 0x1, 0xff, + 0xe0, 0x0, 0x0, 0x0, 0xff, 0xf8, 0x0, 0x0, + 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x1f, 0xfe, + 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x7, 0xff, 0x80, 0x0, 0x0, 0x3, 0xff, 0xc0, + 0x0, 0x0, 0x1, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0x0, 0xff, 0xff, 0xff, + 0xc0, 0x0, 0x7f, 0xf9, 0xff, 0xf0, 0x0, 0x7f, + 0xfc, 0xff, 0xfc, 0x0, 0x7f, 0xfe, 0x7f, 0xff, + 0x80, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0xf, 0xff, 0xff, 0xff, 0xff, 0x3, 0xff, 0xff, + 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x3f, 0xff, 0xff, 0xff, 0x80, 0xf, 0xff, 0xff, + 0xff, 0x80, 0x3, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xfc, + 0x0, 0x0, 0x0, 0x7f, 0xf0, 0x0, 0x0, + + /* U+34 "4" */ + 0x0, 0x0, 0x3, 0xff, 0xf0, 0x0, 0x0, 0x1f, + 0xff, 0x80, 0x0, 0x0, 0x7f, 0xfc, 0x0, 0x0, + 0x3, 0xff, 0xe0, 0x0, 0x0, 0x1f, 0xff, 0x80, + 0x0, 0x0, 0xff, 0xfc, 0x0, 0x0, 0x3, 0xff, + 0xe0, 0x0, 0x0, 0x1f, 0xff, 0x0, 0x0, 0x0, + 0xff, 0xfc, 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, + 0x0, 0x1f, 0xff, 0x0, 0x0, 0x0, 0xff, 0xfc, + 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, 0x3f, + 0xff, 0x0, 0x0, 0x0, 0xff, 0xf8, 0x0, 0x0, + 0x7, 0xff, 0xe0, 0x0, 0x0, 0x3f, 0xff, 0x0, + 0x0, 0x0, 0xff, 0xf8, 0x0, 0x0, 0x7, 0xff, + 0xc0, 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, 0x1, + 0xff, 0xf8, 0x0, 0x0, 0x7, 0xff, 0xc0, 0x0, + 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x1, 0xff, 0xf8, + 0x0, 0x0, 0xf, 0xff, 0xc0, 0x0, 0x0, 0x3f, + 0xfe, 0x0, 0xff, 0xf1, 0xff, 0xf0, 0x3, 0xff, + 0xcf, 0xff, 0xc0, 0xf, 0xff, 0x7f, 0xfe, 0x0, + 0x3f, 0xfd, 0xff, 0xf0, 0x0, 0xff, 0xff, 0xff, + 0xc0, 0x3, 0xff, 0xff, 0xfe, 0x0, 0xf, 0xff, + 0xff, 0xf0, 0x0, 0x3f, 0xff, 0xff, 0x80, 0x0, + 0xff, 0xff, 0xfe, 0x0, 0x3, 0xff, 0xff, 0xf8, + 0x0, 0xf, 0xff, 0xff, 0xe0, 0x0, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x3f, + 0xfc, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, + 0x3, 0xff, 0xc0, 0x0, 0x0, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x3, 0xff, 0xc0, 0x0, 0x0, + 0xf, 0xff, 0x0, 0x0, 0x0, 0x3f, 0xfc, 0x0, + 0x0, 0x0, 0xff, 0xf0, + + /* U+35 "5" */ + 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, + 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, + 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x7, 0xff, 0x80, 0x0, 0x0, 0x3, 0xff, 0xc0, + 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x0, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, + 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x1f, + 0xfe, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x7, 0xff, 0x80, 0x0, 0x0, 0x3, 0xff, + 0xc0, 0x7f, 0x80, 0x1, 0xff, 0xe1, 0xff, 0xf8, + 0x0, 0xff, 0xf1, 0xff, 0xff, 0x0, 0x7f, 0xf9, + 0xff, 0xff, 0xc0, 0x3f, 0xfd, 0xff, 0xff, 0xf0, + 0x1f, 0xff, 0xff, 0xff, 0xfc, 0xf, 0xff, 0xff, + 0xff, 0xff, 0x7, 0xff, 0xff, 0xff, 0xff, 0xc3, + 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xfc, 0x7, + 0xff, 0xf8, 0xff, 0xf8, 0x0, 0xff, 0xfc, 0x0, + 0x0, 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, 0xf, + 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0xc0, 0x0, + 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x0, + 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x1f, 0xfe, + 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x7, 0xff, 0x80, 0x0, 0x0, 0x3, 0xff, 0xc0, + 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0x0, 0x1, + 0xff, 0xff, 0xff, 0x80, 0x0, 0xff, 0xfb, 0xff, + 0xe0, 0x0, 0xff, 0xf9, 0xff, 0xf8, 0x0, 0xff, + 0xfc, 0xff, 0xff, 0x81, 0xff, 0xfe, 0x3f, 0xff, + 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0x7, 0xff, 0xff, 0xff, 0xff, 0x1, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x7f, 0xff, 0xff, 0xff, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0x0, 0x7, 0xff, 0xff, + 0xff, 0x0, 0x0, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0x1f, 0xff, 0xfc, 0x0, 0x0, 0x0, 0xff, 0xe0, + 0x0, 0x0, + + /* U+36 "6" */ + 0x0, 0x0, 0xf, 0xff, 0x80, 0x0, 0x0, 0x7, + 0xff, 0xe0, 0x0, 0x0, 0x3, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0xff, 0xf8, 0x0, 0x0, 0x0, 0x7f, + 0xfe, 0x0, 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, + 0x0, 0xf, 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, + 0xc0, 0x0, 0x0, 0x3, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0xff, 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfc, + 0x0, 0x0, 0x0, 0x3f, 0xff, 0x0, 0x0, 0x0, + 0xf, 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0xc0, + 0x0, 0x0, 0x3, 0xff, 0xf0, 0x0, 0x0, 0x1, + 0xff, 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x0, + 0x0, 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, 0xf, + 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0xc0, 0x0, + 0x0, 0x3, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xff, + 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x3f, 0xc0, + 0x0, 0x1f, 0xfe, 0x3f, 0xfe, 0x0, 0xf, 0xff, + 0xbf, 0xff, 0xe0, 0x3, 0xff, 0xdf, 0xff, 0xfc, + 0x1, 0xff, 0xef, 0xff, 0xff, 0x80, 0x7f, 0xff, + 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xfe, + 0xf, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, + 0xff, 0xff, 0xf1, 0xff, 0xff, 0x3, 0xff, 0xfc, + 0x7f, 0xff, 0x0, 0x3f, 0xff, 0x9f, 0xff, 0x0, + 0x3, 0xff, 0xef, 0xff, 0xc0, 0x0, 0xff, 0xfb, + 0xff, 0xe0, 0x0, 0x1f, 0xff, 0xff, 0xf8, 0x0, + 0x7, 0xff, 0xff, 0xfc, 0x0, 0x0, 0xff, 0xff, + 0xff, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xc0, 0x0, + 0xf, 0xff, 0xff, 0xf0, 0x0, 0x3, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x3f, 0xff, 0xff, 0xe0, 0x0, 0x1f, 0xff, 0x7f, + 0xf8, 0x0, 0x7, 0xff, 0xdf, 0xfe, 0x0, 0x3, + 0xff, 0xe7, 0xff, 0xc0, 0x0, 0xff, 0xf9, 0xff, + 0xfc, 0x0, 0xff, 0xfe, 0x3f, 0xff, 0xc0, 0xff, + 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, + 0xf0, 0x7, 0xff, 0xff, 0xff, 0xf8, 0x0, 0xff, + 0xff, 0xff, 0xfe, 0x0, 0x1f, 0xff, 0xff, 0xfe, + 0x0, 0x3, 0xff, 0xff, 0xff, 0x0, 0x0, 0x3f, + 0xff, 0xff, 0x0, 0x0, 0x3, 0xff, 0xff, 0x0, + 0x0, 0x0, 0xf, 0xfc, 0x0, 0x0, + + /* U+37 "7" */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x0, 0xf, 0xff, 0xff, 0xe0, 0x0, 0x1f, + 0xfe, 0xff, 0xe0, 0x0, 0x1f, 0xfe, 0xff, 0xe0, + 0x0, 0x3f, 0xfc, 0xff, 0xe0, 0x0, 0x3f, 0xfc, + 0xff, 0xe0, 0x0, 0x7f, 0xf8, 0xff, 0xe0, 0x0, + 0x7f, 0xf8, 0xff, 0xe0, 0x0, 0xff, 0xf8, 0xff, + 0xe0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x1, 0xff, + 0xf0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, + 0x3, 0xff, 0xe0, 0x0, 0x0, 0x3, 0xff, 0xc0, + 0x0, 0x0, 0x7, 0xff, 0xc0, 0x0, 0x0, 0x7, + 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0x80, 0x0, + 0x0, 0xf, 0xff, 0x80, 0x0, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0x1f, 0xff, 0x0, 0x0, 0x0, + 0x1f, 0xfe, 0x0, 0x0, 0x0, 0x3f, 0xfe, 0x0, + 0x0, 0x0, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x7f, + 0xfc, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, 0x0, + 0x0, 0xff, 0xf8, 0x0, 0x0, 0x0, 0xff, 0xf8, + 0x0, 0x0, 0x1, 0xff, 0xf0, 0x0, 0x0, 0x1, + 0xff, 0xf0, 0x0, 0x0, 0x1, 0xff, 0xe0, 0x0, + 0x0, 0x3, 0xff, 0xe0, 0x0, 0x0, 0x3, 0xff, + 0xc0, 0x0, 0x0, 0x7, 0xff, 0xc0, 0x0, 0x0, + 0x7, 0xff, 0x80, 0x0, 0x0, 0xf, 0xff, 0x80, + 0x0, 0x0, 0xf, 0xff, 0x80, 0x0, 0x0, 0x1f, + 0xff, 0x0, 0x0, 0x0, 0x1f, 0xff, 0x0, 0x0, + 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, 0x3f, 0xfe, + 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x0, 0x0, 0x0, + 0x7f, 0xfc, 0x0, 0x0, 0x0, 0x7f, 0xf8, 0x0, + 0x0, 0x0, 0xff, 0xf8, 0x0, 0x0, 0x0, 0xff, + 0xf8, 0x0, 0x0, 0x1, 0xff, 0xf0, 0x0, 0x0, + 0x1, 0xff, 0xf0, 0x0, 0x0, 0x3, 0xff, 0xe0, + 0x0, 0x0, + + /* U+38 "8" */ + 0x0, 0x1, 0xff, 0xe0, 0x0, 0x0, 0x7, 0xff, + 0xff, 0x80, 0x0, 0x7, 0xff, 0xff, 0xf8, 0x0, + 0x7, 0xff, 0xff, 0xff, 0x80, 0x3, 0xff, 0xff, + 0xff, 0xf0, 0x1, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xff, + 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0xf, + 0xff, 0xe0, 0x3f, 0xff, 0xc3, 0xff, 0xe0, 0x3, + 0xff, 0xf0, 0xff, 0xf0, 0x0, 0x7f, 0xfc, 0x7f, + 0xf8, 0x0, 0xf, 0xff, 0x9f, 0xfe, 0x0, 0x3, + 0xff, 0xe7, 0xff, 0x0, 0x0, 0x7f, 0xf9, 0xff, + 0xc0, 0x0, 0x1f, 0xfe, 0x7f, 0xf0, 0x0, 0x7, + 0xff, 0x9f, 0xfc, 0x0, 0x1, 0xff, 0xe7, 0xff, + 0x0, 0x0, 0x7f, 0xf9, 0xff, 0xc0, 0x0, 0x1f, + 0xfe, 0x3f, 0xf8, 0x0, 0xf, 0xff, 0xf, 0xfe, + 0x0, 0x3, 0xff, 0xc3, 0xff, 0xc0, 0x1, 0xff, + 0xe0, 0x7f, 0xf8, 0x0, 0xff, 0xf8, 0xf, 0xff, + 0x80, 0xff, 0xfc, 0x1, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0x0, 0x7, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x7f, 0xff, 0xff, 0x0, + 0x0, 0x3, 0xff, 0xfe, 0x0, 0x0, 0x7, 0xff, + 0xff, 0xf0, 0x0, 0x7, 0xff, 0xff, 0xff, 0x80, + 0x7, 0xff, 0xff, 0xff, 0xf0, 0x3, 0xff, 0xff, + 0xff, 0xff, 0x1, 0xff, 0xf8, 0xf, 0xff, 0xe0, + 0xff, 0xf8, 0x0, 0x7f, 0xf8, 0x3f, 0xfc, 0x0, + 0xf, 0xff, 0x1f, 0xfe, 0x0, 0x1, 0xff, 0xe7, + 0xff, 0x80, 0x0, 0x7f, 0xfb, 0xff, 0xc0, 0x0, + 0xf, 0xfe, 0xff, 0xf0, 0x0, 0x3, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x3f, 0xff, 0xff, 0xc0, 0x0, 0xf, 0xff, 0xff, + 0xf0, 0x0, 0x3, 0xff, 0xff, 0xfe, 0x0, 0x1, + 0xff, 0xff, 0xff, 0x80, 0x0, 0x7f, 0xff, 0xff, + 0xf0, 0x0, 0x3f, 0xff, 0x7f, 0xfe, 0x0, 0x1f, + 0xff, 0x9f, 0xff, 0xe0, 0x3f, 0xff, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x3, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x7f, 0xff, 0xff, 0xff, + 0x80, 0xf, 0xff, 0xff, 0xff, 0xc0, 0x1, 0xff, + 0xff, 0xff, 0xe0, 0x0, 0x1f, 0xff, 0xff, 0xe0, + 0x0, 0x1, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x7, + 0xff, 0x80, 0x0, + + /* U+39 "9" */ + 0x0, 0x0, 0xff, 0xc0, 0x0, 0x0, 0x3, 0xff, + 0xff, 0x0, 0x0, 0x3, 0xff, 0xff, 0xf0, 0x0, + 0x3, 0xff, 0xff, 0xff, 0x0, 0x1, 0xff, 0xff, + 0xff, 0xe0, 0x1, 0xff, 0xff, 0xff, 0xfc, 0x0, + 0x7f, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, + 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0xf, + 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xfc, 0xf, + 0xff, 0xf1, 0xff, 0xf8, 0x0, 0xff, 0xfc, 0x7f, + 0xfc, 0x0, 0xf, 0xff, 0x9f, 0xff, 0x0, 0x3, + 0xff, 0xef, 0xff, 0x80, 0x0, 0x7f, 0xfb, 0xff, + 0xe0, 0x0, 0x1f, 0xff, 0xff, 0xf0, 0x0, 0x3, + 0xff, 0xff, 0xfc, 0x0, 0x0, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x3f, 0xff, 0xff, 0xc0, 0x0, 0xf, + 0xff, 0xff, 0xf0, 0x0, 0x3, 0xff, 0xff, 0xfc, + 0x0, 0x0, 0xff, 0xff, 0xff, 0x80, 0x0, 0x7f, + 0xff, 0xff, 0xe0, 0x0, 0x1f, 0xff, 0x7f, 0xf8, + 0x0, 0xf, 0xff, 0xdf, 0xff, 0x0, 0x3, 0xff, + 0xe7, 0xff, 0xf0, 0x3, 0xff, 0xf8, 0xff, 0xff, + 0x3, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xf8, + 0x7, 0xff, 0xff, 0xdf, 0xfe, 0x0, 0xff, 0xff, + 0xef, 0xff, 0x80, 0x1f, 0xff, 0xf7, 0xff, 0xc0, + 0x1, 0xff, 0xf1, 0xff, 0xf0, 0x0, 0xf, 0xf0, + 0xff, 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfc, 0x0, + 0x0, 0x0, 0x1f, 0xff, 0x0, 0x0, 0x0, 0xf, + 0xff, 0x80, 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, + 0x0, 0x1, 0xff, 0xf0, 0x0, 0x0, 0x0, 0xff, + 0xf8, 0x0, 0x0, 0x0, 0x7f, 0xfe, 0x0, 0x0, + 0x0, 0x1f, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, + 0x80, 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, + 0x1, 0xff, 0xf0, 0x0, 0x0, 0x0, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x7f, 0xfe, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0x80, + 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, 0x3, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0xff, 0xf8, 0x0, + 0x0, 0x0, 0x7f, 0xfe, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0x80, 0x0, + 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, + + /* U+3A ":" */ + 0x7, 0xe0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, + 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, + 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x7, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xe0, 0x1f, 0xf8, + 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xfe, 0x7f, 0xfe, 0x3f, 0xfc, + 0x1f, 0xf8, 0x7, 0xe0 +}; + + +/*--------------------- + * 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 = 768, .box_w = 41, .box_h = 59, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 303, .adv_w = 768, .box_w = 40, .box_h = 58, .ofs_x = 6, .ofs_y = 0}, + {.bitmap_index = 593, .adv_w = 768, .box_w = 41, .box_h = 58, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 891, .adv_w = 768, .box_w = 41, .box_h = 59, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 1194, .adv_w = 768, .box_w = 38, .box_h = 58, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 1470, .adv_w = 768, .box_w = 41, .box_h = 58, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 1768, .adv_w = 768, .box_w = 42, .box_h = 59, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 2078, .adv_w = 768, .box_w = 40, .box_h = 58, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 2368, .adv_w = 768, .box_w = 42, .box_h = 60, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 2683, .adv_w = 768, .box_w = 42, .box_h = 59, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 2993, .adv_w = 768, .box_w = 16, .box_h = 46, .ofs_x = 16, .ofs_y = -1} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 48, .range_length = 11, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t jetbrains_mono_extrabold_compressed = { + .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 = 60, /*The maximum line height required by the font*/ + .base_line = 1, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if JETBRAINS_MONO_EXTRABOLD_COMPRESSED*/ + diff --git a/src/DisplayApp/LittleVgl.cpp b/src/DisplayApp/LittleVgl.cpp new file mode 100644 index 00000000..905c00ba --- /dev/null +++ b/src/DisplayApp/LittleVgl.cpp @@ -0,0 +1,717 @@ +#include <FreeRTOS.h> +#include <projdefs.h> +#include <task.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <hal/nrf_rtc.h> +#include <libraries/log/nrf_log.h> + +#include <libs/lvgl/src/lv_themes/lv_theme.h> +#include <libs/lvgl/src/lv_themes/lv_theme_night.h> + +#include "LittleVgl.h" + +using namespace Pinetime::Components; + +extern "C" { +LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed) +LV_FONT_DECLARE(jetbrains_mono_bold_20) +} + +static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { + auto* lvgl = static_cast<LittleVgl*>(disp_drv->user_data); + lvgl->FlushDisplay(area, color_p); +} + +bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { + auto* lvgl = static_cast<LittleVgl*>(indev_drv->user_data); + return lvgl->GetTouchPadInfo(data); +} + +LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd{lcd}, touchPanel{touchPanel}, previousClick{0,0} { + lv_init(); + InitTheme(); + InitDisplay(); + InitTouchpad(); +} + +void LittleVgl::InitDisplay() { + lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 4); /*Initialize the display buffer*/ + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + + /*Set up the functions to access to your display*/ + + /*Set the resolution of the display*/ + disp_drv.hor_res = 240; + disp_drv.ver_res = 240; + + /*Used to copy the buffer's content to the display*/ + disp_drv.flush_cb = disp_flush; + /*Set a display buffer*/ + disp_drv.buffer = &disp_buf_2; + disp_drv.user_data = this; + + /*Finally register the driver*/ + lv_disp_drv_register(&disp_drv); +} + +void LittleVgl::InitTouchpad() { + lv_indev_drv_t indev_drv; + + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = touchpad_read; + indev_drv.user_data = this; + lv_indev_drv_register(&indev_drv); +} + +void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) { + ulTaskNotifyTake(pdTRUE, 500); + + auto x = area->x1; + auto y = area->y1; + auto width = (area->x2-area->x1)+1; + auto height = (area->y2-area->y1)+1; + lcd.BeginDrawBuffer(x, y, width, height); + lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2) ; + + /* IMPORTANT!!! + * Inform the graphics library that you are ready with the flushing*/ + lv_disp_flush_ready(&disp_drv); +} + +bool LittleVgl::GetTouchPadInfo(lv_indev_data_t *ptr) { + auto info = touchPanel.GetTouchInfo(); + + if((previousClick.x != info.x || previousClick.y != info.y) && + (info.gesture == Drivers::Cst816S::Gestures::SingleTap)) { + // TODO For an unknown reason, the first touch is taken twice into account. + // 'firstTouch' is a quite'n'dirty workaound until I find a better solution + if(firstTouch) ptr->state = LV_INDEV_STATE_REL; + else ptr->state = LV_INDEV_STATE_PR; + firstTouch = false; + previousClick.x = info.x; + previousClick.y = info.y; + } + else { + ptr->state = LV_INDEV_STATE_REL; + } + + ptr->point.x = info.x; + ptr->point.y = info.y; + return false; +} + +void LittleVgl::InitTheme() { + uint16_t i; + lv_style_t ** style_p = (lv_style_t **)&theme.style; + for(i = 0; i < LV_THEME_STYLE_COUNT; i++) { + *style_p = &def; + style_p++; + } + + InitBaseTheme(); + InitThemeContainer(); + InitThemeButton(); + InitThemeLabel(); + InitThemeLine(); + InitThemeLed(); + InitThemeImage(); + InitThemeBar(); + InitThemeSlider(); + InitThemeSwitch(); + InitThemeMeter(); + InitThemeGauge(); + InitThemeArc(); + InitThemePreload(); + InitThemeChart(); + InitThemeCalendar(); + InitThemeCheckBox(); + InitThemeButtonMatrix(); + InitThemeKnob(); + InitThemeMessageBox(); + InitThemePage(); + InitThemeTextArea(); + InitThemeSpinBox(); + InitThemeList(); + InitThemeDropDownList(); + InitThemeRoller(); + InitThemeTabView(); + InitThemeTileView(); + InitThemeTable(); + InitThemeWindow(); + + lv_theme_set_current(&theme); +} + +void LittleVgl::InitBaseTheme() { + if(font == nullptr) font = &jetbrains_mono_bold_20; + lv_style_copy(&def, &lv_style_plain); /*Initialize the default style*/ + def.text.font = font; + + lv_style_copy(&bg, &lv_style_plain); + bg.body.main_color = LV_COLOR_BLACK; + bg.body.grad_color = LV_COLOR_BLACK; + bg.text.color = LV_COLOR_WHITE; + bg.text.font = font; + bg.image.color = LV_COLOR_WHITE; + + lv_style_copy(&scr, &bg); + scr.body.padding.bottom = 0; + scr.body.padding.top = 0; + scr.body.padding.left = 0; + scr.body.padding.right = 0; + + lv_style_copy(&sb, &def); + sb.body.main_color = lv_color_hsv_to_rgb(hue, 30, 60); + sb.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 60); + sb.body.border.width = 0; + sb.body.padding.inner = LV_DPI / 20; + sb.body.padding.left = 0; + sb.body.padding.right = 0; + sb.body.padding.top = 0; + sb.body.padding.bottom = 0; + sb.body.radius = LV_DPI / 30; + sb.body.opa = LV_OPA_COVER; + + lv_style_copy(&panel, &bg); + panel.body.main_color = lv_color_hsv_to_rgb(hue, 11, 18); + panel.body.grad_color = lv_color_hsv_to_rgb(hue, 11, 18); + panel.body.radius = LV_DPI / 20; + panel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 25); + panel.body.border.width = 1; + panel.body.border.opa = LV_OPA_COVER; + panel.body.padding.left = LV_DPI / 10; + panel.body.padding.right = LV_DPI / 10; + panel.body.padding.top = LV_DPI / 10; + panel.body.padding.bottom = LV_DPI / 10; + panel.line.color = lv_color_hsv_to_rgb(hue, 20, 40); + panel.line.width = 1; + + theme.style.scr = &scr; + theme.style.bg = &bg; + theme.style.panel = &def; +} + +void LittleVgl::InitThemeContainer() { + theme.style.cont = &panel; +} + +void LittleVgl::InitThemeButton() { + + + lv_style_copy(&btn_rel, &def); + btn_rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40); + btn_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20); + btn_rel.body.border.color = lv_color_hex3(0x111); + btn_rel.body.border.width = 1; + btn_rel.body.border.opa = LV_OPA_70; + btn_rel.body.padding.left = LV_DPI / 4; + btn_rel.body.padding.right = LV_DPI / 4; + btn_rel.body.padding.top = LV_DPI / 8; + btn_rel.body.padding.bottom = LV_DPI / 8; + btn_rel.body.shadow.type = LV_SHADOW_BOTTOM; + btn_rel.body.shadow.color = lv_color_hex3(0x111); + btn_rel.body.shadow.width = LV_DPI / 30; + btn_rel.text.color = lv_color_hex3(0xeee); + btn_rel.image.color = lv_color_hex3(0xeee); + + lv_style_copy(&btn_pr, &btn_rel); + btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 30); + btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 10); + + lv_style_copy(&btn_tgl_rel, &btn_rel); + btn_tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20); + btn_tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40); + btn_tgl_rel.body.shadow.width = LV_DPI / 40; + btn_tgl_rel.text.color = lv_color_hex3(0xddd); + btn_tgl_rel.image.color = lv_color_hex3(0xddd); + + lv_style_copy(&btn_tgl_pr, &btn_rel); + btn_tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 10); + btn_tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 30); + btn_tgl_pr.body.shadow.width = LV_DPI / 30; + btn_tgl_pr.text.color = lv_color_hex3(0xddd); + btn_tgl_pr.image.color = lv_color_hex3(0xddd); + + lv_style_copy(&btn_ina, &btn_rel); + btn_ina.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20); + btn_ina.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20); + btn_ina.body.shadow.width = 0; + btn_ina.text.color = lv_color_hex3(0xaaa); + btn_ina.image.color = lv_color_hex3(0xaaa); + + theme.style.btn.rel = &btn_rel; + theme.style.btn.pr = &btn_pr; + theme.style.btn.tgl_rel = &btn_tgl_rel; + theme.style.btn.tgl_pr = &btn_tgl_pr; + theme.style.btn.ina = &btn_ina; +} + +void LittleVgl::InitThemeLabel() { + lv_style_copy(&prim, &bg); + prim.text.color = lv_color_hsv_to_rgb(hue, 5, 95); + + lv_style_copy(&sec, &bg); + sec.text.color = lv_color_hsv_to_rgb(hue, 15, 65); + + lv_style_copy(&hint, &bg); + hint.text.color = lv_color_hsv_to_rgb(hue, 20, 55); + + theme.style.label.prim = &prim; + theme.style.label.sec = &sec; + theme.style.label.hint = &hint; +} + +void LittleVgl::InitThemeLine() { + theme.style.line.decor = &def; +} + +void LittleVgl::InitThemeLed() { + lv_style_copy(&led, &def); + led.body.shadow.width = LV_DPI / 10; + led.body.radius = LV_RADIUS_CIRCLE; + led.body.border.width = LV_DPI / 30; + led.body.border.opa = LV_OPA_30; + led.body.main_color = lv_color_hsv_to_rgb(hue, 100, 100); + led.body.grad_color = lv_color_hsv_to_rgb(hue, 100, 40); + led.body.border.color = lv_color_hsv_to_rgb(hue, 60, 60); + led.body.shadow.color = lv_color_hsv_to_rgb(hue, 100, 100); + + theme.style.led = &led; +} + +void LittleVgl::InitThemeImage() { + theme.style.img.light = &def; + theme.style.img.dark = &def; +} + +void LittleVgl::InitThemeBar() { + lv_style_copy(&bar_bg, &panel); + bar_bg.body.padding.left = LV_DPI / 16; + bar_bg.body.padding.right = LV_DPI / 16; + bar_bg.body.padding.top = LV_DPI / 16; + bar_bg.body.padding.bottom = LV_DPI / 16; + bar_bg.body.radius = LV_RADIUS_CIRCLE; + + lv_style_copy(&bar_indic, &def); + bar_indic.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70); + bar_indic.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70); + bar_indic.body.border.color = lv_color_hsv_to_rgb(hue, 20, 15); + bar_indic.body.border.width = 1; + bar_indic.body.border.opa = LV_OPA_COVER; + bar_indic.body.radius = LV_RADIUS_CIRCLE; + bar_indic.body.padding.left = 0; + bar_indic.body.padding.right = 0; + bar_indic.body.padding.top = 0; + bar_indic.body.padding.bottom = 0; + + theme.style.bar.bg = &bar_bg; + theme.style.bar.indic = &bar_indic; +} + +void LittleVgl::InitThemeSlider() { + lv_style_copy(&slider_knob, theme.style.btn.rel); + slider_knob.body.radius = LV_RADIUS_CIRCLE; + + theme.style.slider.bg = theme.style.bar.bg; + theme.style.slider.indic = theme.style.bar.indic; + theme.style.slider.knob = &slider_knob; +} + +void LittleVgl::InitThemeSwitch() { + theme.style.sw.bg = theme.style.bar.bg; + theme.style.sw.indic = theme.style.bar.indic; + theme.style.sw.knob_off = theme.style.slider.knob; + theme.style.sw.knob_on = theme.style.slider.knob; +} + +void LittleVgl::InitThemeMeter() { + static lv_style_t lmeter_bg; + lv_style_copy(&lmeter_bg, &def); + lmeter_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 70); + lmeter_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 95, 90); + lmeter_bg.body.padding.left = LV_DPI / 10; /*Scale line length*/ + lmeter_bg.body.padding.inner = LV_DPI / 10; /*Text padding*/ + lmeter_bg.body.border.color = lv_color_hex3(0x333); + lmeter_bg.line.color = lv_color_hex3(0x555); + lmeter_bg.line.width = 1; + lmeter_bg.text.color = lv_color_hex3(0xddd); + + theme.style.lmeter = &lmeter_bg; +} + +void LittleVgl::InitThemeGauge() { + static lv_style_t gauge_bg; + lv_style_copy(&gauge_bg, &def); + gauge_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 70); + gauge_bg.body.grad_color = gauge_bg.body.main_color; + gauge_bg.line.color = lv_color_hsv_to_rgb(hue, 80, 75); + gauge_bg.line.width = 1; + gauge_bg.text.color = lv_color_hex3(0xddd); + + theme.style.gauge = &gauge_bg; +} + +void LittleVgl::InitThemeArc() { + lv_style_copy(&arc, &def); + arc.line.width = 8; + arc.line.color = lv_color_hsv_to_rgb(hue, 80, 70); + arc.line.rounded = 1; + + /*For preloader*/ + arc.body.border.width = 7; + arc.body.border.color = lv_color_hsv_to_rgb(hue, 11, 48); + arc.body.padding.left = 1; + arc.body.padding.right = 1; + arc.body.padding.top = 1; + arc.body.padding.bottom = 1; + + theme.style.arc = &arc; +} + +void LittleVgl::InitThemePreload() { +// theme.style.preload = theme.style.arc; +} + +void LittleVgl::InitThemeChart() { + theme.style.chart = &panel; +} + +void LittleVgl::InitThemeCalendar() { + + lv_style_copy(&cal_bg, &bg); + cal_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40); + cal_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40); + cal_bg.body.border.color = lv_color_hex3(0x333); + cal_bg.body.border.width = 1; + cal_bg.body.radius = LV_DPI / 20; + cal_bg.body.padding.left = LV_DPI / 10; + cal_bg.body.padding.right = LV_DPI / 10; + cal_bg.body.padding.top = LV_DPI / 10; + cal_bg.body.padding.bottom = LV_DPI / 10; + + + lv_style_copy(&cal_header, &bg); + cal_header.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20); + cal_header.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20); + cal_header.body.radius = 0; + cal_header.body.border.width = 1; + cal_header.body.border.color = lv_color_hex3(0x333); + cal_header.body.padding.left = LV_DPI / 10; + cal_header.body.padding.right = LV_DPI / 10; + cal_header.body.padding.top = LV_DPI / 10; + cal_header.body.padding.bottom = LV_DPI / 10; + + + lv_style_copy(&week_box, &panel); + week_box.body.main_color = lv_color_hsv_to_rgb(hue, 30, 45); + week_box.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 45); + week_box.body.radius = LV_DPI / 20; + week_box.body.border.width = 1; + week_box.body.padding.left = LV_DPI / 20; + week_box.body.padding.right = LV_DPI / 20; + week_box.body.padding.top = LV_DPI / 25; + week_box.body.padding.bottom = LV_DPI / 25; + + lv_style_copy(&today_box, &week_box); + today_box.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70); + today_box.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70); + today_box.body.radius = LV_DPI / 20; + today_box.body.padding.left = LV_DPI / 14; + today_box.body.padding.right = LV_DPI / 14; + today_box.body.padding.top = LV_DPI / 14; + today_box.body.padding.bottom = LV_DPI / 14; + + lv_style_copy(&highlighted_days, &bg); + highlighted_days.text.color = lv_color_hsv_to_rgb(hue, 40, 80); + + lv_style_copy(&ina_days, &bg); + ina_days.text.color = lv_color_hsv_to_rgb(hue, 0, 60); + + theme.style.calendar.bg = &cal_bg; + theme.style.calendar.header = &cal_header; + theme.style.calendar.week_box = &week_box; + theme.style.calendar.today_box = &today_box; + theme.style.calendar.highlighted_days = &highlighted_days; + theme.style.calendar.day_names = &cal_bg; + theme.style.calendar.inactive_days = &ina_days; +} + +void LittleVgl::InitThemeCheckBox() { + + lv_style_copy(&rel, &def); + rel.body.radius = LV_DPI / 20; + rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 95); + rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 95); + rel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 50); + rel.body.border.width = 2; + ; + + lv_style_copy(&pr, &rel); + pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 80); + pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 80); + pr.body.border.color = lv_color_hsv_to_rgb(hue, 10, 20); + pr.body.border.width = 1; + ; + + lv_style_copy(&tgl_rel, &rel); + tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 80, 90); + tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 90); + tgl_rel.body.border.color = lv_color_hsv_to_rgb(hue, 80, 50); + + lv_style_copy(&tgl_pr, &tgl_rel); + tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70); + tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70); + tgl_pr.body.border.color = lv_color_hsv_to_rgb(hue, 80, 30); + tgl_pr.body.border.width = 1; + ; + + lv_style_copy(&ina, &rel); + ina.body.main_color = lv_color_hex3(0x777); + ina.body.grad_color = lv_color_hex3(0x777); + ina.body.border.width = 0; + + theme.style.cb.bg = &lv_style_transp; + theme.style.cb.box.rel = &rel; + theme.style.cb.box.pr = ≺ + theme.style.cb.box.tgl_rel = &tgl_rel; + theme.style.cb.box.tgl_pr = &tgl_pr; + theme.style.cb.box.ina = &def; +} + +void LittleVgl::InitThemeButtonMatrix() { + + lv_style_copy(&btnm_bg, theme.style.btn.rel); + btnm_bg.body.padding.left = 2; + btnm_bg.body.padding.right = 2; + btnm_bg.body.padding.top = 2; + btnm_bg.body.padding.bottom = 2; + btnm_bg.body.padding.inner = 0; + btnm_bg.body.border.width = 1; + + lv_style_copy(&btnm_rel, theme.style.btn.rel); + btnm_rel.body.border.part = LV_BORDER_FULL | LV_BORDER_INTERNAL; + btnm_rel.body.border.width = 1; + btnm_rel.body.radius = 2; + + lv_style_copy(&btnm_pr, theme.style.btn.pr); + btnm_pr.body.border.part = btnm_rel.body.border.part; + btnm_pr.body.border.width = btnm_rel.body.border.width; + btnm_pr.body.radius = btnm_rel.body.radius; + + lv_style_copy(&btnm_tgl_rel, theme.style.btn.tgl_rel); + btnm_tgl_rel.body.border.part = btnm_rel.body.border.part; + btnm_tgl_rel.body.border.width = btnm_rel.body.border.width; + btnm_tgl_rel.body.radius = btnm_rel.body.radius; + + lv_style_copy(&btnm_tgl_pr, theme.style.btn.pr); + btnm_tgl_pr.body.border.part = btnm_rel.body.border.part; + btnm_tgl_pr.body.border.width = btnm_rel.body.border.width; + btnm_tgl_pr.body.radius = btnm_rel.body.radius; + + lv_style_copy(&btnm_ina, theme.style.btn.ina); + btnm_ina.body.border.part = btnm_rel.body.border.part; + btnm_ina.body.border.width = btnm_rel.body.border.width; + btnm_ina.body.radius = btnm_rel.body.radius; + + theme.style.btnm.bg = &btnm_bg; + theme.style.btnm.btn.rel = &btnm_rel; + theme.style.btnm.btn.pr = &btnm_pr; + theme.style.btnm.btn.tgl_rel = &btnm_tgl_rel; + theme.style.btnm.btn.tgl_pr = &btnm_tgl_pr; + theme.style.btnm.btn.ina = &btnm_ina; +} + +void LittleVgl::InitThemeKnob() { + theme.style.kb.bg = &bg; + theme.style.kb.btn.rel = theme.style.btn.rel; + theme.style.kb.btn.pr = theme.style.btn.pr; + theme.style.kb.btn.tgl_rel = theme.style.btn.tgl_rel; + theme.style.kb.btn.tgl_pr = theme.style.btn.tgl_pr; + theme.style.kb.btn.ina = theme.style.btn.ina; +} + +void LittleVgl::InitThemeMessageBox() { + lv_style_copy(&mbox_bg, &bg); + mbox_bg.body.main_color = lv_color_hsv_to_rgb(hue, 30, 30); + mbox_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 30); + mbox_bg.body.border.color = lv_color_hsv_to_rgb(hue, 11, 20); + mbox_bg.body.border.width = 1; + mbox_bg.body.shadow.width = LV_DPI / 10; + mbox_bg.body.shadow.color = lv_color_hex3(0x222); + mbox_bg.body.radius = LV_DPI / 20; + theme.style.mbox.bg = &mbox_bg; + theme.style.mbox.btn.bg = &lv_style_transp; + theme.style.mbox.btn.rel = theme.style.btn.rel; + theme.style.mbox.btn.pr = theme.style.btn.pr; +} + +void LittleVgl::InitThemePage() { + lv_style_copy(&page_scrl, &bg); + page_scrl.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40); + page_scrl.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40); + page_scrl.body.border.color = lv_color_hex3(0x333); + page_scrl.body.border.width = 1; + page_scrl.body.radius = LV_DPI / 20; + + theme.style.page.bg = &panel; + theme.style.page.scrl = &page_scrl; + theme.style.page.sb = &sb; +} + +void LittleVgl::InitThemeTextArea() { + theme.style.ta.area = &panel; + theme.style.ta.oneline = &panel; + theme.style.ta.cursor = NULL; + theme.style.ta.sb = &def; +} + +void LittleVgl::InitThemeSpinBox() { + theme.style.spinbox.bg = &panel; + theme.style.spinbox.cursor = theme.style.ta.cursor; + theme.style.spinbox.sb = theme.style.ta.sb; +} + +void LittleVgl::InitThemeList() { + + lv_style_copy(&list_bg, &panel); + list_bg.body.padding.top = 0; + list_bg.body.padding.bottom = 0; + list_bg.body.padding.left = 0; + list_bg.body.padding.right = 0; + list_bg.body.padding.inner = 0; + + lv_style_copy(&list_btn_rel, &bg); + list_btn_rel.body.opa = LV_OPA_TRANSP; + list_btn_rel.body.border.part = LV_BORDER_BOTTOM; + list_btn_rel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 5); + list_btn_rel.body.border.width = 1; + list_btn_rel.body.radius = LV_DPI / 10; + list_btn_rel.text.color = lv_color_hsv_to_rgb(hue, 5, 80); + list_btn_rel.image.color = lv_color_hsv_to_rgb(hue, 5, 80); + list_btn_rel.body.padding.top = LV_DPI / 6; + list_btn_rel.body.padding.bottom = LV_DPI / 6; + list_btn_rel.body.padding.left = LV_DPI / 8; + list_btn_rel.body.padding.right = LV_DPI / 8; + + lv_style_copy(&list_btn_pr, theme.style.btn.pr); + list_btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 5); + list_btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 5); + list_btn_pr.body.border.color = lv_color_hsv_to_rgb(hue, 10, 5); + list_btn_pr.body.border.width = 0; + list_btn_pr.body.padding.top = LV_DPI / 6; + list_btn_pr.body.padding.bottom = LV_DPI / 6; + list_btn_pr.body.padding.left = LV_DPI / 8; + list_btn_pr.body.padding.right = LV_DPI / 8; + list_btn_pr.text.color = lv_color_hsv_to_rgb(hue, 5, 80); + list_btn_pr.image.color = lv_color_hsv_to_rgb(hue, 5, 80); + + lv_style_copy(&list_btn_tgl_rel, &list_btn_rel); + list_btn_tgl_rel.body.opa = LV_OPA_COVER; + list_btn_tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70); + list_btn_tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70); + list_btn_tgl_rel.body.border.color = lv_color_hsv_to_rgb(hue, 60, 40); + list_btn_tgl_rel.body.radius = list_bg.body.radius; + + lv_style_copy(&list_btn_tgl_pr, &list_btn_tgl_rel); + list_btn_tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 80, 60); + list_btn_tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 60); + + theme.style.list.sb = &sb; + theme.style.list.bg = &list_bg; + theme.style.list.scrl = &lv_style_transp_tight; + theme.style.list.btn.rel = &list_btn_rel; + theme.style.list.btn.pr = &list_btn_pr; + theme.style.list.btn.tgl_rel = &list_btn_tgl_rel; + theme.style.list.btn.tgl_pr = &list_btn_tgl_pr; + theme.style.list.btn.ina = &def; +} + +void LittleVgl::InitThemeDropDownList() { + lv_style_copy(&ddlist_bg, theme.style.btn.rel); + ddlist_bg.text.line_space = LV_DPI / 8; + ddlist_bg.body.padding.top = LV_DPI / 8; + ddlist_bg.body.padding.bottom = LV_DPI / 8; + ddlist_bg.body.padding.left = LV_DPI / 8; + ddlist_bg.body.padding.right = LV_DPI / 8; + ddlist_bg.body.radius = LV_DPI / 30; + + lv_style_copy(&ddlist_sel, theme.style.btn.rel); + ddlist_sel.body.main_color = lv_color_hsv_to_rgb(hue, 20, 50); + ddlist_sel.body.grad_color = lv_color_hsv_to_rgb(hue, 20, 50); + ddlist_sel.body.radius = 0; + + theme.style.ddlist.bg = &ddlist_bg; + theme.style.ddlist.sel = &ddlist_sel; + theme.style.ddlist.sb = &def; +} + +void LittleVgl::InitThemeRoller() { + lv_style_t roller_bg; + + lv_style_copy(&roller_bg, theme.style.ddlist.bg); + roller_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20); + roller_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40); + roller_bg.text.color = lv_color_hsv_to_rgb(hue, 5, 70); + roller_bg.text.opa = LV_OPA_60; + + theme.style.roller.bg = &roller_bg; + theme.style.roller.sel = theme.style.ddlist.sel; +} + +void LittleVgl::InitThemeTabView() { + theme.style.tabview.bg = &bg; + theme.style.tabview.indic = &lv_style_transp; + theme.style.tabview.btn.bg = &lv_style_transp; + theme.style.tabview.btn.rel = theme.style.btn.rel; + theme.style.tabview.btn.pr = theme.style.btn.pr; + theme.style.tabview.btn.tgl_rel = theme.style.btn.tgl_rel; + theme.style.tabview.btn.tgl_pr = theme.style.btn.tgl_pr; +} + +void LittleVgl::InitThemeTileView() { + theme.style.tileview.bg = &lv_style_transp_tight; + theme.style.tileview.scrl = &lv_style_transp_tight; + theme.style.tileview.sb = theme.style.page.sb; +} + +void LittleVgl::InitThemeTable() { + lv_style_copy(&cell, &panel); + cell.body.radius = 0; + cell.body.border.width = 1; + cell.body.padding.left = LV_DPI / 12; + cell.body.padding.right = LV_DPI / 12; + cell.body.padding.top = LV_DPI / 12; + cell.body.padding.bottom = LV_DPI / 12; + + theme.style.table.bg = &lv_style_transp_tight; + theme.style.table.cell = &cell; +} + +void LittleVgl::InitThemeWindow() { +// lv_style_copy(&win_bg, &bg); +// win_bg.body.border.color = lv_color_hex3(0x333); +// win_bg.body.border.width = 1; +// +// lv_style_copy(&win_header, &win_bg); +// win_header.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20); +// win_header.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20); +// win_header.body.radius = 0; +// win_header.body.padding.left = 0; +// win_header.body.padding.right = 0; +// win_header.body.padding.top = 0; +// win_header.body.padding.bottom = 0; +// +// lv_style_copy(&win_btn_pr, &def); +// win_btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 10); +// win_btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 10); +// win_btn_pr.text.color = lv_color_hex3(0xaaa); +// win_btn_pr.image.color = lv_color_hex3(0xaaa); +// +// theme.style.win.bg = &win_bg; +// theme.style.win.sb = &sb; +// theme.style.win.header = &win_header; +// theme.style.win.content = &lv_style_transp; +// theme.style.win.btn.rel = &lv_style_transp; +// theme.style.win.btn.pr = &win_btn_pr; +} diff --git a/src/DisplayApp/LittleVgl.h b/src/DisplayApp/LittleVgl.h new file mode 100644 index 00000000..40fb1809 --- /dev/null +++ b/src/DisplayApp/LittleVgl.h @@ -0,0 +1,100 @@ +#pragma once + +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_themes/lv_theme.h> +#include <libs/lvgl/src/lv_hal/lv_hal.h> +#include <drivers/St7789.h> +#include <drivers/Cst816s.h> + + +static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); +static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); + +namespace Pinetime { + namespace Components { + class LittleVgl { + public: + LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel); + void FlushDisplay(const lv_area_t * area, lv_color_t * color_p); + + + bool GetTouchPadInfo(lv_indev_data_t *ptr); + private: + void InitDisplay(); + void InitTouchpad(); + void InitTheme(); + void InitBaseTheme(); + void InitThemeContainer(); + void InitThemeButton(); + void InitThemeLabel(); + void InitThemeLine(); + void InitThemeLed(); + void InitThemeImage(); + void InitThemeBar(); + void InitThemeSlider(); + void InitThemeSwitch(); + void InitThemeMeter(); + void InitThemeGauge(); + void InitThemeArc(); + void InitThemePreload(); + void InitThemeChart(); + void InitThemeCalendar(); + void InitThemeCheckBox(); + void InitThemeButtonMatrix(); + void InitThemeKnob(); + void InitThemeMessageBox(); + void InitThemePage(); + void InitThemeTextArea(); + void InitThemeSpinBox(); + void InitThemeList(); + void InitThemeDropDownList(); + void InitThemeRoller(); + void InitThemeTabView(); + void InitThemeTileView(); + void InitThemeTable(); + void InitThemeWindow(); + + Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Cst816S& touchPanel; + + + lv_disp_buf_t disp_buf_2; + lv_color_t buf2_1[LV_HOR_RES_MAX * 4]; + lv_color_t buf2_2[LV_HOR_RES_MAX * 4]; + + lv_disp_drv_t disp_drv; + lv_point_t previousClick; + + lv_style_t def; + lv_style_t scr, bg, sb, panel; + lv_font_t * font = nullptr; + uint16_t hue = 10; + lv_theme_t theme; + lv_style_t btn_rel, btn_pr, btn_tgl_rel, btn_tgl_pr, btn_ina; + lv_style_t prim, sec, hint; + lv_style_t led; + lv_style_t bar_bg, bar_indic; + lv_style_t slider_knob; + lv_style_t arc; + lv_style_t cal_bg; + lv_style_t cal_header; + lv_style_t week_box; + lv_style_t today_box; + lv_style_t highlighted_days; + lv_style_t ina_days; + lv_style_t rel, pr, tgl_rel, tgl_pr, ina; + lv_style_t btnm_bg, btnm_rel, btnm_pr, btnm_tgl_rel, btnm_tgl_pr, btnm_ina; + lv_style_t mbox_bg; + lv_style_t page_scrl; + lv_style_t list_bg, list_btn_rel, list_btn_pr, list_btn_tgl_rel, list_btn_tgl_pr; + lv_style_t ddlist_bg, ddlist_sel; + lv_style_t cell; + lv_style_t win_bg; + lv_style_t win_header; + lv_style_t win_btn_pr; + + bool firstTouch = true; + }; + } +} + diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 16f4cfeb..7051c433 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -2,36 +2,94 @@ #include <libs/date/includes/date/date.h> #include <Components/DateTime/DateTimeController.h> #include <Version.h> +#include <libs/lvgl/lvgl.h> #include "Clock.h" +#include "../DisplayApp.h" using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; -void Clock::Refresh(bool fullRefresh) { - if(fullRefresh) { - gfx.FillRectangle(0,0,240,240,0x0000); - currentChar[0] = 1; - currentChar[1] = 2; - currentChar[2] = 3; - currentChar[3] = 4; - auto dummy = currentDateTime.Get(); - } +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Clock* screen = static_cast<Clock *>(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +Clock::Clock(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController) : Screen(app), currentDateTime{{}}, version {{}}, + dateTimeController{dateTimeController}, batteryController{batteryController}, bleController{bleController} { + displayedChar[0] = 0; + displayedChar[1] = 0; + displayedChar[2] = 0; + displayedChar[3] = 0; + displayedChar[4] = 0; + + label_battery = lv_label_create(lv_scr_act(), NULL); + lv_obj_align(label_battery, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -80, 0); + + labelStyle = const_cast<lv_style_t *>(lv_label_get_style(label_battery, LV_LABEL_STYLE_MAIN)); + labelStyle->text.font = &jetbrains_mono_bold_20; + + lv_style_copy(&labelBigStyle, labelStyle); + labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed; + + lv_label_set_style(label_battery, LV_LABEL_STYLE_MAIN, labelStyle); + + label_ble = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_ble, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(label_ble, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 0); + + label_time = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_time, LV_LABEL_STYLE_MAIN, &labelBigStyle); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0); + + + label_date = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_date, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); + + backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel->user_data = this; + lv_label_set_style(backgroundLabel, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_set_click(backgroundLabel, true); + lv_obj_set_event_cb(backgroundLabel, event_handler); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); +} + +Clock::~Clock() { + lv_obj_clean(lv_scr_act()); +} - if (fullRefresh || batteryPercentRemaining.IsUpdated()) { +bool Clock::Refresh() { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { char batteryChar[11]; auto newBatteryValue = batteryPercentRemaining.Get(); newBatteryValue = (newBatteryValue > 100) ? 100 : newBatteryValue; newBatteryValue = (newBatteryValue < 0) ? 0 : newBatteryValue; sprintf(batteryChar, "BAT: %d%%", newBatteryValue); - gfx.DrawString((240 - 108), 0, 0xffff, batteryChar, &smallFont, false); + lv_label_set_text(label_battery, batteryChar); } - if (fullRefresh || bleState.IsUpdated()) { - uint16_t color = (bleState.Get() == BleConnectionStates::Connected) ? 0xffff : 0x0000; - gfx.DrawString(10, 0, color, "BLE", &smallFont, false); + bleState = bleController.IsConnected(); + if (bleState.IsUpdated()) { + if(bleState.Get() == true) { + lv_obj_set_hidden(label_ble, false); + lv_label_set_text(label_ble, "BLE"); + } else { + lv_obj_set_hidden(label_ble, true); + } } - if(fullRefresh || currentDateTime.IsUpdated()) { + currentDateTime = dateTimeController.CurrentDateTime(); + + if(currentDateTime.IsUpdated()) { auto newDateTime = currentDateTime.Get(); auto dp = date::floor<date::days>(newDateTime); @@ -53,35 +111,23 @@ void Clock::Refresh(bool fullRefresh) { char hoursChar[3]; sprintf(hoursChar, "%02d", hour); - uint8_t x = 7; - if (hoursChar[0] != currentChar[0]) { - gfx.DrawChar(&largeFont, hoursChar[0], &x, 78, 0xffff); - currentChar[0] = hoursChar[0]; - } - - x = 61; - if (hoursChar[1] != currentChar[1]) { - gfx.DrawChar(&largeFont, hoursChar[1], &x, 78, 0xffff); - currentChar[1] = hoursChar[1]; - } + char timeStr[6]; + sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); - x = 127; - if (minutesChar[0] != currentChar[2]) { - gfx.DrawChar(&largeFont, minutesChar[0], &x, 78, 0xffff); - currentChar[2] = minutesChar[0]; - } + if(hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || minutesChar[1] != displayedChar[3]) { + displayedChar[0] = hoursChar[0]; + displayedChar[1] = hoursChar[1]; + displayedChar[2] = minutesChar[0]; + displayedChar[3] = minutesChar[1]; - x = 181; - if (minutesChar[1] != currentChar[3]) { - gfx.DrawChar(&largeFont, minutesChar[1], &x, 78, 0xffff); - currentChar[3] = minutesChar[1]; + lv_label_set_text(label_time, timeStr); } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - gfx.FillRectangle(0,180, 240, 15, 0x0000); char dateStr[22]; sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); - gfx.DrawString(10, 180, 0xffff, dateStr, &smallFont, false); + lv_label_set_text(label_date, dateStr); + currentYear = year; currentMonth = month; @@ -90,12 +136,7 @@ void Clock::Refresh(bool fullRefresh) { } } - if(fullRefresh || version.IsUpdated()) { - auto dummy = version.Get(); - char versionStr[20]; - sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); - gfx.DrawString(20, 220, 0xffff, versionStr, &smallFont, false); - } + return running; } const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { @@ -132,3 +173,18 @@ char const *Clock::MonthsString[] = { "NOV", "DEC" }; + +void Clock::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(obj == backgroundLabel) { + if (event == LV_EVENT_CLICKED) { + + running = false; + } + } +} + +bool Clock::OnButtonPushed() { + return Screen::OnButtonPushed(); +} + + diff --git a/src/DisplayApp/Screens/Clock.h b/src/DisplayApp/Screens/Clock.h index 75ea34dd..d14595b0 100644 --- a/src/DisplayApp/Screens/Clock.h +++ b/src/DisplayApp/Screens/Clock.h @@ -5,6 +5,10 @@ #include <Components/Gfx/Gfx.h> #include "Screen.h" #include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <Components/Battery/BatteryController.h> +#include <Components/Ble/BleController.h> #include "../Fonts/lcdfont14.h" #include "../Fonts/lcdfont70.h" #include "../../Version.h" @@ -19,11 +23,13 @@ namespace Pinetime { explicit DirtyValue(T v) { value = v; } explicit DirtyValue(T& v) { value = v; } bool IsUpdated() const { return isUpdated; } - T& Get() { this->isUpdated = false; return value;} + T& Get() { this->isUpdated = false; return value; } DirtyValue& operator=(const T& other) { - this->value = other; - this->isUpdated = true; + if (this->value != other) { + this->value = other; + this->isUpdated = true; + } return *this; } private: @@ -32,33 +38,50 @@ namespace Pinetime { }; class Clock : public Screen{ public: - enum class BleConnectionStates{ NotConnected, Connected}; - Clock(Components::Gfx& gfx) : Screen(gfx), currentDateTime{{}}, version {{}} {} - void Refresh(bool fullRefresh) override; + Clock(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController); + ~Clock() override; - void SetBatteryPercentRemaining(uint8_t percent) { batteryPercentRemaining = percent; } - void SetBleConnectionState(BleConnectionStates state) { bleState = state; } - void SetCurrentDateTime(const std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>& tp) { currentDateTime = tp;} + bool Refresh() override; + bool OnButtonPushed() override; + void OnObjectEvent(lv_obj_t *pObj, lv_event_t i); private: static const char* MonthToString(Pinetime::Controllers::DateTime::Months month); static const char* DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek); static char const *DaysString[]; static char const *MonthsString[]; - const FONT_INFO largeFont {lCD_70ptFontInfo.height, lCD_70ptFontInfo.startChar, lCD_70ptFontInfo.endChar, lCD_70ptFontInfo.spacePixels, lCD_70ptFontInfo.charInfo, lCD_70ptFontInfo.data}; - const FONT_INFO smallFont {lCD_14ptFontInfo.height, lCD_14ptFontInfo.startChar, lCD_14ptFontInfo.endChar, lCD_14ptFontInfo.spacePixels, lCD_14ptFontInfo.charInfo, lCD_14ptFontInfo.data}; + char displayedChar[5]; - char currentChar[4]; uint16_t currentYear = 1970; Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; uint8_t currentDay = 0; DirtyValue<uint8_t> batteryPercentRemaining {0}; - DirtyValue<BleConnectionStates> bleState {BleConnectionStates::NotConnected}; - DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>> currentDateTime; + DirtyValue<bool> bleState {false}; + DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime; DirtyValue<Pinetime::Version> version; + + lv_style_t* labelStyle; + lv_style_t labelBigStyle; + lv_obj_t * label_battery; + + lv_obj_t * label_ble; + lv_obj_t* label_time; + lv_obj_t* label_date; + lv_obj_t* label_version; + lv_obj_t* backgroundLabel; + + Controllers::DateTime& dateTimeController; + Controllers::Battery& batteryController; + Controllers::Ble& bleController; + + bool running = true; + }; } } diff --git a/src/DisplayApp/Screens/Gauge.cpp b/src/DisplayApp/Screens/Gauge.cpp new file mode 100644 index 00000000..4c4cccd9 --- /dev/null +++ b/src/DisplayApp/Screens/Gauge.cpp @@ -0,0 +1,57 @@ +#include <libs/lvgl/lvgl.h> +#include "Gauge.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + + +Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) { + /*Create a style*/ + lv_style_copy(&style, &lv_style_pretty_color); + style.body.main_color = LV_COLOR_CYAN; /*Line color at the beginning*/ + style.body.grad_color = LV_COLOR_RED; /*Line color at the end*/ + style.body.padding.left = 10; /*Scale line length*/ + style.body.padding.inner = 8 ; /*Scale label padding*/ + style.body.border.color = lv_color_hex3(0x333); /*Needle middle circle color*/ + style.line.width = 3; + style.text.color = LV_COLOR_WHITE; + style.line.color = LV_COLOR_RED; /*Line color after the critical value*/ + + /*Describe the color for the needles*/ + + needle_colors[0] = LV_COLOR_ORANGE; + + /*Create a gauge*/ + gauge1 = lv_gauge_create(lv_scr_act(), NULL); + lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style); + lv_gauge_set_needle_count(gauge1, 1, needle_colors); + lv_obj_set_size(gauge1, 180, 180); + lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_gauge_set_scale(gauge1, 360, 60, 0); + lv_gauge_set_range(gauge1, 0, 59); + + /*Set the values*/ + lv_gauge_set_value(gauge1, 0, value); +} + +Gauge::~Gauge() { + + + lv_obj_clean(lv_scr_act()); +} + +bool Gauge::Refresh() { +// lv_lmeter_set_value(lmeter, value++); /*Set the current value*/ +// if(value>=60) value = 0; + + lv_gauge_set_value(gauge1, 0, value++); + if(value == 59) value = 0; + return running; +} + +bool Gauge::OnButtonPushed() { + running = false; + return true; +} diff --git a/src/DisplayApp/Screens/Gauge.h b/src/DisplayApp/Screens/Gauge.h new file mode 100644 index 00000000..463654ee --- /dev/null +++ b/src/DisplayApp/Screens/Gauge.h @@ -0,0 +1,39 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#include <Components/Gfx/Gfx.h> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <Components/Battery/BatteryController.h> +#include <Components/Ble/BleController.h> +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Gauge : public Screen{ + public: + Gauge(DisplayApp* app); + ~Gauge() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + private: + lv_style_t style; + lv_color_t needle_colors[3]; + lv_obj_t * gauge1; + + uint32_t value=30; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Message.cpp b/src/DisplayApp/Screens/Message.cpp index 121e34b9..c8a4ea1f 100644 --- a/src/DisplayApp/Screens/Message.cpp +++ b/src/DisplayApp/Screens/Message.cpp @@ -2,13 +2,87 @@ #include <libs/date/includes/date/date.h> #include <Components/DateTime/DateTimeController.h> #include <Version.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <libs/lvgl/src/lv_font/lv_font.h> +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> #include "Message.h" +#include <DisplayApp/DisplayApp.h> + using namespace Pinetime::Applications::Screens; -void Message::Refresh(bool fullRefresh) { - if(fullRefresh) { - gfx.FillRectangle(0,0,240,240,0xffff); - gfx.DrawString(120, 10, 0x5555, "COUCOU", &smallFont, false); +extern lv_font_t jetbrains_mono_bold_20; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Message* screen = static_cast<Message *>(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +Message::Message(DisplayApp* app) : Screen(app) { + + backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel->user_data = this; + + labelStyle = const_cast<lv_style_t *>(lv_label_get_style(backgroundLabel, LV_LABEL_STYLE_MAIN)); + labelStyle->text.font = &jetbrains_mono_bold_20; + + lv_label_set_style(backgroundLabel, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_set_click(backgroundLabel, true); + lv_obj_set_event_cb(backgroundLabel, event_handler); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); +// lv_obj_align(backgroundLabel, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + + button = lv_btn_create(lv_scr_act(), NULL); + lv_obj_set_event_cb(button, event_handler); + lv_obj_align(button, NULL, LV_ALIGN_CENTER, 0, -40); + button->user_data = this; + + label = lv_label_create(button, NULL); + lv_label_set_style(label, LV_LABEL_STYLE_MAIN, labelStyle); + lv_label_set_text(label, "Hello!"); + + labelClick = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(labelClick, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(labelClick, button, LV_ALIGN_OUT_BOTTOM_MID, 0, 30); + lv_label_set_text(labelClick, "0"); +} + +Message::~Message() { + lv_obj_clean(lv_scr_act()); +} + +bool Message::Refresh() { + if(previousClickCount != clickCount) { + lv_label_set_text_fmt(labelClick, "%d", clickCount); + previousClickCount = clickCount; + } + + return running; +} + +void Message::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(obj == backgroundLabel) { + if(event == LV_EVENT_CLICKED) { + app->PushMessage(DisplayApp::Messages::SwitchScreen); + NRF_LOG_INFO("SCREEN"); + } + return ; } + + if(event == LV_EVENT_CLICKED) { + NRF_LOG_INFO("Clicked"); + clickCount++; + } + else if(event == LV_EVENT_VALUE_CHANGED) { + NRF_LOG_INFO("Toggled"); + } +} + +bool Message::OnButtonPushed() { + running = false; + return true; } diff --git a/src/DisplayApp/Screens/Message.h b/src/DisplayApp/Screens/Message.h index ac300faf..4e87bba4 100644 --- a/src/DisplayApp/Screens/Message.h +++ b/src/DisplayApp/Screens/Message.h @@ -8,18 +8,30 @@ #include "../Fonts/lcdfont14.h" #include "../Fonts/lcdfont70.h" #include "../../Version.h" +#include <lvgl/src/lv_core/lv_style.h> namespace Pinetime { namespace Applications { namespace Screens { class Message : public Screen{ public: - Message(Components::Gfx& gfx) : Screen(gfx) {} - void Refresh(bool fullRefresh) override; + explicit Message(DisplayApp* app); + ~Message() override; + bool Refresh() override; + bool OnButtonPushed(); + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); private: - const FONT_INFO largeFont {lCD_70ptFontInfo.height, lCD_70ptFontInfo.startChar, lCD_70ptFontInfo.endChar, lCD_70ptFontInfo.spacePixels, lCD_70ptFontInfo.charInfo, lCD_70ptFontInfo.data}; - const FONT_INFO smallFont {lCD_14ptFontInfo.height, lCD_14ptFontInfo.startChar, lCD_14ptFontInfo.endChar, lCD_14ptFontInfo.spacePixels, lCD_14ptFontInfo.charInfo, lCD_14ptFontInfo.data}; + + lv_style_t* labelStyle; + lv_obj_t * label; + lv_obj_t* backgroundLabel; + lv_obj_t * button; + lv_obj_t * labelClick; + + uint32_t clickCount = 0 ; + uint32_t previousClickCount = 0; + bool running = true; }; } } diff --git a/src/DisplayApp/Screens/Meter.cpp b/src/DisplayApp/Screens/Meter.cpp new file mode 100644 index 00000000..c74b8bdf --- /dev/null +++ b/src/DisplayApp/Screens/Meter.cpp @@ -0,0 +1,47 @@ +#include <libs/lvgl/lvgl.h> +#include "Meter.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + + +Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) { + + lv_style_copy(&style_lmeter, &lv_style_pretty_color); + style_lmeter.line.width = 2; + style_lmeter.line.color = LV_COLOR_SILVER; + style_lmeter.body.main_color = lv_color_make(255,0,0); + style_lmeter.body.grad_color = lv_color_make(160,0,0); + style_lmeter.body.padding.left = 16; /*Line length*/ + + /*Create a line meter */ + lmeter = lv_lmeter_create(lv_scr_act(), NULL); + lv_lmeter_set_range(lmeter, 0, 60); /*Set the range*/ + lv_lmeter_set_value(lmeter, value); /*Set the current value*/ + lv_lmeter_set_angle_offset(lmeter, 180); + lv_lmeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/ + lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter); /*Apply the new style*/ + lv_obj_set_size(lmeter, 150, 150); + lv_obj_align(lmeter, NULL, LV_ALIGN_CENTER, 0, 0); + +} + +Meter::~Meter() { + + + lv_obj_clean(lv_scr_act()); +} + +bool Meter::Refresh() { + lv_lmeter_set_value(lmeter, value++); /*Set the current value*/ + if(value>=60) value = 0; + + return running; +} + +bool Meter::OnButtonPushed() { + running = false; + return true; +} diff --git a/src/DisplayApp/Screens/Meter.h b/src/DisplayApp/Screens/Meter.h new file mode 100644 index 00000000..1a08b46c --- /dev/null +++ b/src/DisplayApp/Screens/Meter.h @@ -0,0 +1,38 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#include <Components/Gfx/Gfx.h> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <Components/Battery/BatteryController.h> +#include <Components/Ble/BleController.h> +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Meter : public Screen{ + public: + Meter(DisplayApp* app); + ~Meter() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + private: + lv_style_t style_lmeter; + lv_obj_t * lmeter; + + uint32_t value=0; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp new file mode 100644 index 00000000..fc353c49 --- /dev/null +++ b/src/DisplayApp/Screens/Modal.cpp @@ -0,0 +1,81 @@ +#include <libs/lvgl/lvgl.h> +#include "Modal.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +Modal::Modal(Pinetime::Applications::DisplayApp *app) : Screen(app) { + + +} + +Modal::~Modal() { + lv_obj_clean(lv_scr_act()); +} + +bool Modal::Refresh() { + + return running; +} + +bool Modal::OnButtonPushed() { + running = false; + return true; +} + +void Modal::Show() { + lv_style_copy(&modal_style, &lv_style_plain_color); + modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK; + modal_style.body.opa = LV_OPA_50; + + obj = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(obj, &modal_style); + lv_obj_set_pos(obj, 0, 0); + lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES); + lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */ + + static const char * btns2[] = {"Ok", ""}; + + /* Create the message box as a child of the modal background */ + mbox = lv_mbox_create(obj, NULL); + lv_mbox_add_btns(mbox, btns2); + char versionStr[20]; + sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); + lv_mbox_set_text(mbox, versionStr); +// lv_mbox_set_text(mbox, "Hello world!"); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); + + mbox->user_data = this; + + /* Fade the message box in with an animation */ + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_time(&a, 500, 0); + lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER); + lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale); + lv_anim_create(&a); +} + +void Modal::Hide() { + /* Delete the parent modal background */ + lv_obj_del_async(lv_obj_get_parent(mbox)); + mbox = NULL; /* happens before object is actually deleted! */ +} + +void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) { + auto* m = static_cast<Modal *>(obj->user_data); + m->OnEvent(obj, evt); +} + +void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) { + if(evt == LV_EVENT_DELETE && event_obj == mbox) { + Hide(); + } else if(evt == LV_EVENT_VALUE_CHANGED) { + /* A button was clicked */ + lv_mbox_start_auto_close(mbox, 0); +// Hide(); + } +} diff --git a/src/DisplayApp/Screens/Modal.h b/src/DisplayApp/Screens/Modal.h new file mode 100644 index 00000000..de287293 --- /dev/null +++ b/src/DisplayApp/Screens/Modal.h @@ -0,0 +1,44 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#include <Components/Gfx/Gfx.h> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include <libs/lvgl/src/lv_core/lv_style.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <Components/Battery/BatteryController.h> +#include <Components/Ble/BleController.h> +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Modal : public Screen{ + public: + Modal(DisplayApp* app); + ~Modal() override; + + void Show(); + void Hide(); + + bool Refresh() override; + bool OnButtonPushed() override; + + static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt); + private: + void OnEvent(lv_obj_t *event_obj, lv_event_t evt); + + lv_style_t modal_style; + lv_obj_t *obj; + lv_obj_t *mbox; + lv_obj_t *info; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h index 5e2fa43e..6cbd41ad 100644 --- a/src/DisplayApp/Screens/Screen.h +++ b/src/DisplayApp/Screens/Screen.h @@ -1,17 +1,22 @@ #pragma once -#include <Components/Gfx/Gfx.h> - namespace Pinetime { namespace Applications { + class DisplayApp; namespace Screens { class Screen { public: - Screen(Components::Gfx& gfx) : gfx{gfx} {} - virtual void Refresh(bool fullRefresh) = 0; + Screen(DisplayApp* app) : app{app} {} + virtual ~Screen() = default; + + // Return false if the app can be closed, true if it must continue to run + virtual bool Refresh() = 0; + + // Return false if the button hasn't been handled by the app, true if it has been handled + virtual bool OnButtonPushed() { return false; } protected: - Components::Gfx& gfx; + DisplayApp* app; }; } } diff --git a/src/DisplayApp/Screens/Tab.cpp b/src/DisplayApp/Screens/Tab.cpp new file mode 100644 index 00000000..adc32578 --- /dev/null +++ b/src/DisplayApp/Screens/Tab.cpp @@ -0,0 +1,67 @@ +#include <cstdio> +#include <libs/date/includes/date/date.h> +#include <Components/DateTime/DateTimeController.h> +#include <Version.h> +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <libs/lvgl/src/lv_font/lv_font.h> +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> +#include "Tab.h" +#include <DisplayApp/DisplayApp.h> + + +using namespace Pinetime::Applications::Screens; + +extern lv_font_t jetbrains_mono_bold_20; + +//static void event_handler(lv_obj_t * obj, lv_event_t event) { +// Tile* screen = static_cast<Tile *>(obj->user_data); +// screen->OnObjectEvent(obj, event); +//} + +Tab::Tab(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { +/*Create a Tab view object*/ + lv_obj_t *tabview; + tabview = lv_tabview_create(lv_scr_act(), NULL); + + /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/ + lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1"); + lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2"); + lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3"); + + + /*Add content to the tabs*/ + lv_obj_t * label = lv_label_create(tab1, NULL); + lv_label_set_text(label, "This the first tab\n\n" + "If the content\n" + "of a tab\n" + "become too long\n" + "the it \n" + "automatically\n" + "become\n" + "scrollable."); + + label = lv_label_create(tab2, NULL); + lv_label_set_text(label, "Second tab"); + + label = lv_label_create(tab3, NULL); + lv_label_set_text(label, "Third tab"); + +} + +Tab::~Tab() { + lv_obj_clean(lv_scr_act()); +} + +void Tab::Refresh(bool fullRefresh) { + +} + +void Tab::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(event == LV_EVENT_CLICKED) { + NRF_LOG_INFO("Clicked"); + } + else if(event == LV_EVENT_VALUE_CHANGED) { + NRF_LOG_INFO("Toggled"); + } +} diff --git a/src/DisplayApp/Screens/Tab.h b/src/DisplayApp/Screens/Tab.h new file mode 100644 index 00000000..1af956f4 --- /dev/null +++ b/src/DisplayApp/Screens/Tab.h @@ -0,0 +1,28 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#include <Components/Gfx/Gfx.h> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" +#include <lvgl/src/lv_core/lv_style.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tab : public Screen { + public: + explicit Tab(DisplayApp* app, Components::Gfx& gfx); + ~Tab() override; + void Refresh(bool fullRefresh) override; + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); + + private: + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp new file mode 100644 index 00000000..004c8d31 --- /dev/null +++ b/src/DisplayApp/Screens/Tile.cpp @@ -0,0 +1,163 @@ +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <libs/lvgl/src/lv_font/lv_font.h> +#include <libs/lvgl/lvgl.h> +#include "Tile.h" +#include <DisplayApp/DisplayApp.h> + + +using namespace Pinetime::Applications::Screens; + +extern lv_font_t jetbrains_mono_bold_20; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Tile* screen = static_cast<Tile *>(obj->user_data); + uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); + uint32_t eventData = *eventDataPtr; + screen->OnObjectEvent(obj, event, eventData); +} + +static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "App3", ""}; + +Tile::Tile(DisplayApp* app) : Screen(app) { + modal.reset(new Modal(app)); +/* + static lv_point_t valid_pos[] = {{0,0}, {LV_COORD_MIN, LV_COORD_MIN}}; + tileview = lv_tileview_create(lv_scr_act(), NULL); + lv_tileview_set_valid_positions(tileview, valid_pos, 1); + lv_tileview_set_edge_flash(tileview, false); + + tile1 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile1, 0, 0); + lv_obj_set_size(tile1, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile1); +*/ + btnm1 = lv_btnm_create(lv_scr_act(), NULL); + lv_btnm_set_map(btnm1, btnm_map1); + lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); + +// labelRelStyle = const_cast<lv_style_t *>(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_REL)); +// labelRelStyle->text.font = &jetbrains_mono_bold_20; +// labelRelStyle->body.grad_color = labelRelStyle->body.main_color; +// lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_REL, labelRelStyle); +// +// labelPrStyle = const_cast<lv_style_t *>(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_PR)); +// labelPrStyle->text.font = &jetbrains_mono_bold_20; +// labelPrStyle->body.grad_color = labelPrStyle->body.shadow.color; + + + +// lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_PR, labelPrStyle); +//TODO better style handling +// lv_obj_align(btnm1, tile1, LV_ALIGN_CENTER, 0, 0); + btnm1->user_data = this; + lv_obj_set_event_cb(btnm1, event_handler); + +/* + tile2 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile2, 0, LV_VER_RES); + lv_obj_set_size(tile2, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile2); + + btnm2 = lv_btnm_create(tileview, NULL); + lv_btnm_set_map(btnm2, btnm_map2); + lv_obj_align(btnm2, tile2, LV_ALIGN_CENTER, 0, 0); +*/ +/* + tile1 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile1, 0, 0); + lv_obj_set_size(tile1, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile1); + + btn1 = lv_btn_create(tile1, NULL); + lv_obj_align(btn1, tile1, LV_ALIGN_CENTER, 0, 0); + + label1 = lv_label_create(btn1, NULL); + lv_label_set_text(label1, "Button1"); +*/ +/* + tile2 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile2, 0, LV_VER_RES); + lv_obj_set_size(tile2, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile2); + + btn2 = lv_btn_create(tile2, NULL); + lv_obj_align(btn2, tile2, LV_ALIGN_CENTER, 0, 0); + + + label2 = lv_label_create(btn2, NULL); + lv_label_set_text(label2, "Button2"); + + tile3 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile3, 0, LV_VER_RES*2); + lv_obj_set_size(tile3, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile3); + + btn3 = lv_btn_create(tile3, NULL); + lv_obj_align(btn3, tile3, LV_ALIGN_CENTER, 0, 0); + + + label3 = lv_label_create(btn3, NULL); + lv_label_set_text(label3, "Button3"); +*/ +} + +Tile::~Tile() { + lv_obj_clean(lv_scr_act()); +} + +bool Tile::Refresh() { + return running; +} + +void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { + auto* tile = static_cast<Tile*>(obj->user_data); + if(event == LV_EVENT_VALUE_CHANGED) { + switch(buttonId) { + case 0: + tile->StartMeterApp(); + break; + case 1: + tile->StartGaugeApp(); + break; + case 2: + tile->StartClockApp(); + break; + case 3: + modal->Show(); + break; + case 4: + case 5: + tile->StartTestApp(); + + break; + } + clickCount++; + } +} + +bool Tile::OnButtonPushed() { + app->StartApp(DisplayApp::Apps::Clock); + running = false; + return true; +} + +void Tile::StartClockApp() { + app->StartApp(DisplayApp::Apps::Clock); + running = false; +} + +void Tile::StartTestApp() { + app->StartApp(DisplayApp::Apps::Test); + running = false; +} + +void Tile::StartMeterApp() { + app->StartApp(DisplayApp::Apps::Meter); + running = false; +} + +void Tile::StartGaugeApp() { + app->StartApp(DisplayApp::Apps::Gauge); + running = false; +} + diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h new file mode 100644 index 00000000..eb253435 --- /dev/null +++ b/src/DisplayApp/Screens/Tile.h @@ -0,0 +1,64 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#include <Components/Gfx/Gfx.h> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" +#include "Modal.h" +#include <lvgl/src/lv_core/lv_style.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tile : public Screen { + public: + explicit Tile(DisplayApp* app); + ~Tile() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); + + private: + + lv_style_t* labelRelStyle; + lv_style_t* labelPrStyle; + lv_obj_t * label1; + lv_obj_t * label2; + lv_obj_t * label3; + + lv_obj_t* backgroundLabel; + lv_obj_t * button; + lv_obj_t * labelClick; + + lv_obj_t *tileview; + lv_obj_t * tile1; + lv_obj_t * tile2; + lv_obj_t * list; + lv_obj_t * list_btn; + lv_obj_t * tile3; + lv_obj_t * btn1; + lv_obj_t * btn2; + lv_obj_t * btn3; + + lv_obj_t * btnm1; + lv_obj_t * btnm2; + + uint32_t clickCount = 0 ; + uint32_t previousClickCount = 0; + void StartClockApp(); + void StartTestApp(); + void StartMeterApp(); + void StartGaugeApp(); + bool running = true; + + std::unique_ptr<Modal> modal; + }; + } + } +} |