Author: Avamander <avamander@gmail.com>
Renamed displayapp/Screens to displayapp/screens
src/CMakeLists.txt | 70 ++++++++++++++++---------------- | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 src/libs/lvgl/src/lv_core/lv_obj.c | 2
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 546ce813ed0805c8c705d55eeec91b128e4947bc..9d03e9043a6c6f767ab709d431e974bac998d0a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -324,23 +324,23 @@ list(APPEND SOURCE_FILES logging/NrfLogger.cpp displayapp/DisplayApp.cpp - displayapp/Screens/Screen.cpp - displayapp/Screens/Clock.cpp - displayapp/Screens/Tile.cpp - displayapp/Screens/Meter.cpp - displayapp/Screens/Gauge.cpp - displayapp/Screens/InfiniPaint.cpp - displayapp/Screens/DropDownDemo.cpp - displayapp/Screens/Modal.cpp - displayapp/Screens/BatteryIcon.cpp - displayapp/Screens/BleIcon.cpp - displayapp/Screens/Brightness.cpp - displayapp/Screens/SystemInfo.cpp - displayapp/Screens/Label.cpp - displayapp/Screens/FirmwareUpdate.cpp - displayapp/Screens/Music.cpp - displayapp/Screens/FirmwareValidation.cpp - displayapp/Screens/ApplicationList.cpp + displayapp/screens/Screen.cpp + displayapp/screens/Clock.cpp + displayapp/screens/Tile.cpp + displayapp/screens/Meter.cpp + displayapp/screens/Gauge.cpp + displayapp/screens/InfiniPaint.cpp + displayapp/screens/DropDownDemo.cpp + displayapp/screens/Modal.cpp + displayapp/screens/BatteryIcon.cpp + displayapp/screens/BleIcon.cpp + displayapp/screens/Brightness.cpp + displayapp/screens/SystemInfo.cpp + displayapp/screens/Label.cpp + displayapp/screens/FirmwareUpdate.cpp + displayapp/screens/Music.cpp + displayapp/screens/FirmwareValidation.cpp + displayapp/screens/ApplicationList.cpp main.cpp drivers/St7789.cpp drivers/SpiNorFlash.cpp @@ -401,23 +401,23 @@ logging/Logger.h logging/NrfLogger.h displayapp/DisplayApp.h displayapp/TouchEvents.h - displayapp/Screens/Screen.h - displayapp/Screens/Clock.h - displayapp/Screens/Tile.h - displayapp/Screens/Meter.h - displayapp/Screens/Gauge.h - displayapp/Screens/InfiniPaint.h - displayapp/Screens/DropDownDemo.h - displayapp/Screens/Modal.h - displayapp/Screens/BatteryIcon.h - displayapp/Screens/BleIcon.cpp - displayapp/Screens/Brightness.h - displayapp/Screens/SystemInfo.h - displayapp/Screens/ScreenList.h - displayapp/Screens/Label.h - displayapp/Screens/FirmwareUpdate.h - displayapp/Screens/FirmwareValidation.h - displayapp/Screens/ApplicationList.h + displayapp/screens/Screen.h + displayapp/screens/Clock.h + displayapp/screens/Tile.h + displayapp/screens/Meter.h + displayapp/screens/Gauge.h + displayapp/screens/InfiniPaint.h + displayapp/screens/DropDownDemo.h + displayapp/screens/Modal.h + displayapp/screens/BatteryIcon.h + displayapp/screens/BleIcon.cpp + displayapp/screens/Brightness.h + displayapp/screens/SystemInfo.h + displayapp/screens/ScreenList.h + displayapp/screens/Label.h + displayapp/screens/FirmwareUpdate.h + displayapp/screens/FirmwareValidation.h + displayapp/screens/ApplicationList.h displayapp/Apps.h drivers/St7789.h drivers/SpiNorFlash.h @@ -453,7 +453,7 @@ libs/date/includes/date/tz_private.h displayapp/LittleVgl.h systemtask/SystemTask.h systemtask/SystemMonitor.h - displayapp/Screens/Symbols.h + displayapp/screens/Symbols.h drivers/TwiMaster.h ) diff --git a/src/displayapp/Screens/ApplicationList.cpp b/src/displayapp/Screens/ApplicationList.cpp deleted file mode 100644 index eb85be4fab9351f6cbaba635acd8b247ef3b624d..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/ApplicationList.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include <DisplayApp/DisplayApp.h> -#include <functional> -#include "ApplicationList.h" -#include "Tile.h" -#include "Symbols.h" - -using namespace Pinetime::Applications::Screens; - -ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp *app) : - Screen(app), - screens{app, { - [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, - [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, - //[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } - } - } {} - - -ApplicationList::~ApplicationList() { - lv_obj_clean(lv_scr_act()); -} - -bool ApplicationList::Refresh() { - if(running) - running = screens.Refresh(); - return running; -} - -bool ApplicationList::OnButtonPushed() { - running = false; - app->StartApp(Apps::Clock); - return true; -} - -bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return screens.OnTouchEvent(event); -} - -std::unique_ptr<Screen> ApplicationList::CreateScreen1() { - std::array<Screens::Tile::Applications, 6> applications { - {{Symbols::clock, Apps::Clock}, - {Symbols::music, Apps::Music}, - {Symbols::sun, Apps::Brightness}, - {Symbols::list, Apps::SysInfo}, - {Symbols::check, Apps::FirmwareValidation}, - {Symbols::none, Apps::None} - } - - - }; - - return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); -} - -std::unique_ptr<Screen> ApplicationList::CreateScreen2() { - std::array<Screens::Tile::Applications, 6> applications { - {{Symbols::tachometer, Apps::Gauge}, - {Symbols::asterisk, Apps::Meter}, - {Symbols::paintbrush, Apps::Paint}, - {Symbols::none, Apps::None}, - {Symbols::none, Apps::None}, - {Symbols::none, Apps::None} - } - }; - - return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); -} - -std::unique_ptr<Screen> ApplicationList::CreateScreen3() { - std::array<Screens::Tile::Applications, 6> applications { - {{"A", Apps::Meter}, - {"B", Apps::Gauge}, - {"C", Apps::Clock}, - {"D", Apps::Music}, - {"E", Apps::SysInfo}, - {"F", Apps::Brightness} - } - }; - - return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); -} diff --git a/src/displayapp/Screens/ApplicationList.h b/src/displayapp/Screens/ApplicationList.h deleted file mode 100644 index a1e6811b3c3fcaaff970e6f3a69d7f1cf75f3d67..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/ApplicationList.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <vector> -#include <Components/Ble/NimbleController.h> -#include "Screen.h" -#include "Label.h" -#include "ScreenList.h" -#include "Gauge.h" -#include "Meter.h" -#include <functional> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class ApplicationList : public Screen { - public: - explicit ApplicationList(DisplayApp* app); - ~ApplicationList() override; - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - private: - bool running = true; - - ScreenList<2> screens; - std::unique_ptr<Screen> CreateScreen1(); - std::unique_ptr<Screen> CreateScreen2(); - std::unique_ptr<Screen> CreateScreen3(); - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/BatteryIcon.cpp b/src/displayapp/Screens/BatteryIcon.cpp deleted file mode 100644 index 26939d1824ffff8209c97db5252a17c1f3fdb50e..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/BatteryIcon.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "BatteryIcon.h" -#include "Symbols.h" -using namespace Pinetime::Applications::Screens; - -const char* BatteryIcon::GetBatteryIcon(float batteryPercent) { - if(batteryPercent > 90.0f) return Symbols::batteryFull; - if(batteryPercent > 75.0f) return Symbols::batteryThreeQuarter; - if(batteryPercent > 50.0f) return Symbols::batteryHalf; - if(batteryPercent > 25.0f) return Symbols::batteryOneQuarter; - return Symbols::batteryEmpty; -} - -const char* BatteryIcon::GetUnknownIcon() { - return Symbols::batteryEmpty; -} - -const char *BatteryIcon::GetPlugIcon(bool isCharging) { - if(isCharging) - return Symbols::plug; - else return ""; -} diff --git a/src/displayapp/Screens/BatteryIcon.h b/src/displayapp/Screens/BatteryIcon.h deleted file mode 100644 index 58f04a875493f8cd3eaf1f6c9612362cde90aa31..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/BatteryIcon.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <libs/lvgl/src/lv_draw/lv_img_decoder.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class BatteryIcon { - public: - static const char* GetUnknownIcon(); - static const char* GetBatteryIcon(float batteryPercent); - static const char* GetPlugIcon(bool isCharging); - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/BleIcon.cpp b/src/displayapp/Screens/BleIcon.cpp deleted file mode 100644 index 1bbbd0531a4932f9449a654330bda910b870f69a..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/BleIcon.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "BleIcon.h" -#include "Symbols.h" -using namespace Pinetime::Applications::Screens; - -const char* BleIcon::GetIcon(bool isConnected) { - if(isConnected) return Symbols::bluetooth; - else return ""; -} \ No newline at end of file diff --git a/src/displayapp/Screens/BleIcon.h b/src/displayapp/Screens/BleIcon.h deleted file mode 100644 index c1398d2a68b5c9fffbd321e8d0dd7220d54106b4..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/BleIcon.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace Pinetime { - namespace Applications { - namespace Screens { - class BleIcon { - public: - static const char* GetIcon(bool isConnected); - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/Brightness.cpp b/src/displayapp/Screens/Brightness.cpp deleted file mode 100644 index 9e3416c0d958fe8c4983305fcae49b7552baf92d..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Brightness.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "Brightness.h" - -using namespace Pinetime::Applications::Screens; - -void slider_event_cb(lv_obj_t * slider, lv_event_t event) { - if(event == LV_EVENT_VALUE_CHANGED) { - auto* brightnessSlider = static_cast<Brightness*>(slider->user_data); - brightnessSlider->OnValueChanged(); - } -} - -Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { - slider = lv_slider_create(lv_scr_act(), NULL); - lv_obj_set_user_data(slider, this); - lv_obj_set_width(slider, LV_DPI * 2); - lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_event_cb(slider, slider_event_cb); - lv_slider_set_range(slider, 0, 2); - lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); - - slider_label = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(slider_label, LevelToString(brightness.Level())); - lv_obj_set_auto_realign(slider_label, true); - lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); -} - -Brightness::~Brightness() { - lv_obj_clean(lv_scr_act()); -} - -bool Brightness::Refresh() { - return running; -} - -bool Brightness::OnButtonPushed() { - running = false; - return true; -} - -const char *Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { - switch(level) { - case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off"; - case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low"; - case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium"; - case Pinetime::Controllers::BrightnessController::Levels::High: return "High"; - default : return "???"; - } -} - -void Brightness::OnValueChanged() { - SetValue(lv_slider_get_value(slider)); -} - -void Brightness::SetValue(uint8_t value) { - switch(value) { - case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break; - case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break; - case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break; - } - lv_label_set_text(slider_label, LevelToString(brightness.Level())); -} - -uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) { - switch(level) { - case Pinetime::Controllers::BrightnessController::Levels::Off: return 0; - case Pinetime::Controllers::BrightnessController::Levels::Low: return 0; - case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1; - case Pinetime::Controllers::BrightnessController::Levels::High: return 2; - default : return 0; - } -} - -bool Brightness::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - switch(event) { - case TouchEvents::SwipeLeft: - brightness.Lower(); - SetValue(); - return true; - case TouchEvents::SwipeRight: - brightness.Higher(); - SetValue(); - return true; - default: - return false; - } -} - -void Brightness::SetValue() { - lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); - lv_label_set_text(slider_label, LevelToString(brightness.Level())); -} diff --git a/src/displayapp/Screens/Brightness.h b/src/displayapp/Screens/Brightness.h deleted file mode 100644 index 37cbcd7eb693cc3af6e55c11a2cde034e781e51f..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Brightness.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include <libs/lvgl/src/lv_core/lv_obj.h> -#include <Components/Brightness/BrightnessController.h> -#include "Screen.h" - -namespace Pinetime { - namespace Applications { - namespace Screens { - class Brightness : public Screen { - public: - Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); - ~Brightness() override; - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - - void OnValueChanged(); - private: - bool running = true; - Controllers::BrightnessController& brightness; - - lv_obj_t * slider_label; - lv_obj_t * slider; - - const char* LevelToString(Controllers::BrightnessController::Levels level); - uint8_t LevelToInt(Controllers::BrightnessController::Levels level); - void SetValue(uint8_t value); - void SetValue(); - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/Clock.cpp b/src/displayapp/Screens/Clock.cpp deleted file mode 100644 index 06fab9aa6825350fe401c1427e67afd0ab7bafd1..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Clock.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include <cstdio> -#include <libs/date/includes/date/date.h> -#include <Components/DateTime/DateTimeController.h> -#include <libs/lvgl/lvgl.h> -#include "Clock.h" -#include "../DisplayApp.h" -#include "BatteryIcon.h" -#include "BleIcon.h" -#include "Symbols.h" -using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressed; -extern lv_font_t jetbrains_mono_bold_20; -extern lv_style_t* LabelBigStyle; - -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{{}}, - dateTimeController{dateTimeController}, batteryController{batteryController}, bleController{bleController} { - displayedChar[0] = 0; - displayedChar[1] = 0; - displayedChar[2] = 0; - displayedChar[3] = 0; - displayedChar[4] = 0; - - batteryIcon = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(batteryIcon, Symbols::batteryFull); - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); - - batteryPlug = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(batteryPlug, Symbols::plug); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - bleIcon = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(bleIcon, Symbols::bluetooth); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - - label_date = lv_label_create(lv_scr_act(), NULL); - - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); - - 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); - - backgroundLabel = lv_label_create(lv_scr_act(), NULL); - backgroundLabel->user_data = this; - 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, ""); - - - heartbeatIcon = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(heartbeatIcon, Symbols::heartBeat); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - - heartbeatValue = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(heartbeatValue, "0"); - lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - - heartbeatBpm = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(heartbeatBpm, "BPM"); - lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - - stepValue = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(stepValue, "0"); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); - - stepIcon = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(stepIcon, Symbols::shoe); - lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); -} - -Clock::~Clock() { - lv_obj_clean(lv_scr_act()); -} - -bool Clock::Refresh() { - batteryPercentRemaining = batteryController.PercentRemaining(); - if (batteryPercentRemaining.IsUpdated()) { - auto batteryPercent = batteryPercentRemaining.Get(); - lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); - auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent(); - lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); - } - - bleState = bleController.IsConnected(); - if (bleState.IsUpdated()) { - if(bleState.Get() == true) { - lv_label_set_text(bleIcon, BleIcon::GetIcon(true)); - } else { - lv_label_set_text(bleIcon, BleIcon::GetIcon(false)); - } - } - lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); - - currentDateTime = dateTimeController.CurrentDateTime(); - - if(currentDateTime.IsUpdated()) { - auto newDateTime = currentDateTime.Get(); - - auto dp = date::floor<date::days>(newDateTime); - auto time = date::make_time(newDateTime-dp); - auto yearMonthDay = date::year_month_day(dp); - - auto year = (int)yearMonthDay.year(); - auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned)yearMonthDay.month()); - auto day = (unsigned)yearMonthDay.day(); - auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding()); - - auto hour = time.hours().count(); - auto minute = time.minutes().count(); - - char minutesChar[3]; - sprintf(minutesChar, "%02d", static_cast<int>(minute)); - - char hoursChar[3]; - sprintf(hoursChar, "%02d", static_cast<int>(hour)); - - char timeStr[6]; - sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); - - 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]; - - lv_label_set_text(label_time, timeStr); - } - - if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - char dateStr[22]; - sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); - lv_label_set_text(label_date, dateStr); - - - currentYear = year; - currentMonth = month; - currentDayOfWeek = dayOfWeek; - currentDay = day; - } - } - - // TODO heartbeat = heartBeatController.GetValue(); - if(heartbeat.IsUpdated()) { - char heartbeatBuffer[4]; - sprintf(heartbeatBuffer, "%d", heartbeat.Get()); - lv_label_set_text(heartbeatValue, heartbeatBuffer); - lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - } - - // TODO stepCount = stepController.GetValue(); - if(stepCount.IsUpdated()) { - char stepBuffer[5]; - sprintf(stepBuffer, "%lu", stepCount.Get()); - lv_label_set_text(stepValue, stepBuffer); - lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); - lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); - } - - return running; -} - -const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { - return Clock::MonthsString[static_cast<uint8_t>(month)]; -} - -const char *Clock::DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek) { - return Clock::DaysString[static_cast<uint8_t>(dayOfWeek)]; -} - -char const *Clock::DaysString[] = { - "", - "MONDAY", - "TUESDAY", - "WEDNESDAY", - "THURSDAY", - "FRIDAY", - "SATURDAY", - "SUNDAY" -}; - -char const *Clock::MonthsString[] = { - "", - "JAN", - "FEB", - "MAR", - "APR", - "MAY", - "JUN", - "JUL", - "AUG", - "SEP", - "OCT", - "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() { - running = false; - return false; -} - - diff --git a/src/displayapp/Screens/Clock.h b/src/displayapp/Screens/Clock.h deleted file mode 100644 index 7363fdaf46ec9998d17322edef4e37b374f77388..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Clock.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include <cstdint> -#include <chrono> -#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> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - template <class T> - class DirtyValue { - public: - explicit DirtyValue(T v) { value = v; } - explicit DirtyValue(T& v) { value = v; } - bool IsUpdated() const { return isUpdated; } - T& Get() { this->isUpdated = false; return value; } - - DirtyValue& operator=(const T& other) { - if (this->value != other) { - this->value = other; - this->isUpdated = true; - } - return *this; - } - private: - T value; - bool isUpdated = true; - }; - class Clock : public Screen{ - public: - Clock(DisplayApp* app, - Controllers::DateTime& dateTimeController, - Controllers::Battery& batteryController, - Controllers::Ble& bleController); - ~Clock() override; - - 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[]; - - char displayedChar[5]; - - 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<float> batteryPercentRemaining {0}; - DirtyValue<bool> bleState {false}; - DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime; - DirtyValue<uint32_t> stepCount {0}; - DirtyValue<uint8_t> heartbeat {0}; - - - lv_obj_t* label_time; - lv_obj_t* label_date; - lv_obj_t* backgroundLabel; - lv_obj_t * batteryIcon; - lv_obj_t * bleIcon; - lv_obj_t* batteryPlug; - lv_obj_t* heartbeatIcon; - lv_obj_t* heartbeatValue; - lv_obj_t* heartbeatBpm; - lv_obj_t* stepIcon; - lv_obj_t* stepValue; - - Controllers::DateTime& dateTimeController; - Controllers::Battery& batteryController; - Controllers::Ble& bleController; - - bool running = true; - - }; - } - } -} diff --git a/src/displayapp/Screens/DropDownDemo.cpp b/src/displayapp/Screens/DropDownDemo.cpp deleted file mode 100644 index 735a0ccedecbcc71b51825830b919677eb7f28ea..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/DropDownDemo.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include <libraries/log/nrf_log.h> -#include "DropDownDemo.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; - -DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) { - // Create the dropdown object, with many item, and fix its height - ddlist = lv_ddlist_create(lv_scr_act(), NULL); - lv_ddlist_set_options(ddlist, "Apple\n" - "Banana\n" - "Orange\n" - "Melon\n" - "Grape\n" - "Raspberry\n" - "A\n" - "B\n" - "C\n" - "D\n" - "E"); - lv_ddlist_set_fix_width(ddlist, 150); - lv_ddlist_set_draw_arrow(ddlist, true); - lv_ddlist_set_fix_height(ddlist, 150); - lv_obj_align(ddlist, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); -} - -DropDownDemo::~DropDownDemo() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); - lv_obj_clean(lv_scr_act()); -} - -bool DropDownDemo::Refresh() { - auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); - - // Switch touchmode to Polling if the dropdown is opened. This will allow to scroll inside the - // dropdown while it is opened. - // Disable the polling mode when the dropdown is closed to be able to handle the gestures. - if(list->opened) - app->SetTouchMode(DisplayApp::TouchModes::Polling); - else - app->SetTouchMode(DisplayApp::TouchModes::Gestures); - return running; -} - -bool DropDownDemo::OnButtonPushed() { - running = false; - return true; -} - -bool DropDownDemo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - // If the dropdown is opened, notify Display app that it doesn't need to handle the event - // (this will prevent displayApp from going back to the menu or clock scree). - auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); - if(list->opened) { - return true; - } else { - return false; - } -} - diff --git a/src/displayapp/Screens/DropDownDemo.h b/src/displayapp/Screens/DropDownDemo.h deleted file mode 100644 index 7c75efc029f327787a85b275770f5795217dcf3e..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/DropDownDemo.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <cstdint> -#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> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class DropDownDemo : public Screen{ - public: - DropDownDemo(DisplayApp* app); - ~DropDownDemo() override; - - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - - private: - lv_obj_t * ddlist; - bool running = true; - bool isDropDownOpened = false; - }; - } - } -} diff --git a/src/displayapp/Screens/FirmwareUpdate.cpp b/src/displayapp/Screens/FirmwareUpdate.cpp deleted file mode 100644 index e831114d4ff5878be506deb68811ed895a5c791e..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/FirmwareUpdate.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "FirmwareUpdate.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; - - -FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) : - Screen(app), bleController{bleController} { - - titleLabel = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(titleLabel, "Firmware update"); - lv_obj_set_auto_realign(titleLabel, true); - lv_obj_align(titleLabel, NULL, LV_ALIGN_IN_TOP_MID, 0, 50); - - bar1 = lv_bar_create(lv_scr_act(), NULL); - lv_obj_set_size(bar1, 200, 30); - lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0); - lv_bar_set_anim_time(bar1, 10); - lv_bar_set_range(bar1, 0, 100); - lv_bar_set_value(bar1, 0, LV_ANIM_OFF); - - percentLabel = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(percentLabel, ""); - lv_obj_set_auto_realign(percentLabel, true); - lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); -} - -FirmwareUpdate::~FirmwareUpdate() { - lv_obj_clean(lv_scr_act()); -} - -bool FirmwareUpdate::Refresh() { - switch(bleController.State()) { - default: - case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: - case Pinetime::Controllers::Ble::FirmwareUpdateStates::Running: - if(state != States::Running) - state = States::Running; - return DisplayProgression(); - case Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated: - if(state != States::Validated) { - UpdateValidated(); - state = States::Validated; - } - return running; - case Pinetime::Controllers::Ble::FirmwareUpdateStates::Error: - if(state != States::Error) { - UpdateError(); - state = States::Error; - } - return running; - } -} - -bool FirmwareUpdate::DisplayProgression() const { - float current = bleController.FirmwareUpdateCurrentBytes() / 1024.0f; - float total = bleController.FirmwareUpdateTotalBytes() / 1024.0f; - int16_t pc = (current / total) * 100.0f; - sprintf(percentStr, "%d %%", pc); - lv_label_set_text(percentLabel, percentStr); - - lv_bar_set_value(bar1, pc, LV_ANIM_OFF); - return running; -} - -bool FirmwareUpdate::OnButtonPushed() { - running = false; - return true; -} - -void FirmwareUpdate::UpdateValidated() { - lv_label_set_recolor(percentLabel, true); - lv_label_set_text(percentLabel, "#00ff00 Image Ok!#"); -} - -void FirmwareUpdate::UpdateError() { - lv_label_set_recolor(percentLabel, true); - lv_label_set_text(percentLabel, "#ff0000 Error!#"); -} diff --git a/src/displayapp/Screens/FirmwareUpdate.h b/src/displayapp/Screens/FirmwareUpdate.h deleted file mode 100644 index faaf39533d6e26dcc8303ec70ec2314292ff01fc..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/FirmwareUpdate.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include <cstdint> -#include <chrono> -#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/Ble/BleController.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class FirmwareUpdate : public Screen{ - public: - FirmwareUpdate(DisplayApp* app, Pinetime::Controllers::Ble& bleController); - ~FirmwareUpdate() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - private: - enum class States { Idle, Running, Validated, Error }; - Pinetime::Controllers::Ble& bleController; - lv_obj_t* bar1; - lv_obj_t* percentLabel; - lv_obj_t* titleLabel; - mutable char percentStr[10]; - bool running = true; - States state; - - bool DisplayProgression() const; - - void UpdateValidated(); - - void UpdateError(); - }; - } - } -} diff --git a/src/displayapp/Screens/FirmwareValidation.cpp b/src/displayapp/Screens/FirmwareValidation.cpp deleted file mode 100644 index fb2dd956a27096e2b706a0683dfc45173757489a..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/FirmwareValidation.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "FirmwareValidation.h" -#include "../DisplayApp.h" -#include "../../Version.h" -#include "../../Components/FirmwareValidator/FirmwareValidator.h" - -using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressed; -extern lv_font_t jetbrains_mono_bold_20; - -namespace { - static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) - { - FirmwareValidation* screen = static_cast<FirmwareValidation *>(obj->user_data); - screen->OnButtonEvent(obj, event); - } - -} - -FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, - Pinetime::Controllers::FirmwareValidator &validator) - : Screen{app}, validator{validator} { - labelVersionInfo = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelVersionInfo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); - lv_label_set_text(labelVersionInfo, "Version : "); - lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT); - - - labelVersionValue = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0); - lv_label_set_recolor(labelVersionValue, true); - sprintf(version, "%ld.%ld.%ld", Version::Major(), Version::Minor(), Version::Patch()); - lv_label_set_text(labelVersionValue, version); - - labelIsValidated = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelIsValidated, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50); - lv_label_set_recolor(labelIsValidated, true); - lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK); - lv_obj_set_width(labelIsValidated, 240); - - if(validator.IsValidated()) - lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#"); - else { - lv_label_set_text(labelIsValidated, - "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); - - buttonValidate = lv_btn_create(lv_scr_act(), NULL); - lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); - buttonValidate->user_data = this; - lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); - - labelButtonValidate = lv_label_create(buttonValidate, NULL); - lv_label_set_recolor(labelButtonValidate, true); - lv_label_set_text(labelButtonValidate, "#00ff00 Validate#"); - - buttonReset = lv_btn_create(lv_scr_act(), NULL); - buttonReset->user_data = this; - lv_obj_align(buttonReset, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); - lv_obj_set_event_cb(buttonReset, ButtonEventHandler); - - labelButtonReset = lv_label_create(buttonReset, NULL); - lv_label_set_recolor(labelButtonReset, true); - lv_label_set_text(labelButtonReset, "#ff0000 Reset#"); - } -} - - -FirmwareValidation::~FirmwareValidation() { - lv_obj_clean(lv_scr_act()); -} - -bool FirmwareValidation::Refresh() { - return running; -} - -bool FirmwareValidation::OnButtonPushed() { - running = false; - return true; -} - -void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) { - if(object == buttonValidate && event == LV_EVENT_PRESSED) { - validator.Validate(); - running = false; - } else if(object == buttonReset && event == LV_EVENT_PRESSED) { - validator.Reset(); - } - -} - - diff --git a/src/displayapp/Screens/FirmwareValidation.h b/src/displayapp/Screens/FirmwareValidation.h deleted file mode 100644 index 947f5575ba0fa5a4eed356e7c26781b1d9049dda..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/FirmwareValidation.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include <cstdint> -#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> - -namespace Pinetime { - namespace Controllers { - class FirmwareValidator; - } - - namespace Applications { - namespace Screens { - - class FirmwareValidation : public Screen{ - public: - FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator); - ~FirmwareValidation() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnButtonEvent(lv_obj_t *object, lv_event_t event); - - private: - Pinetime::Controllers::FirmwareValidator& validator; - - lv_obj_t* labelVersionInfo; - lv_obj_t* labelVersionValue; - char version[9]; - lv_obj_t* labelIsValidated; - lv_obj_t* buttonValidate; - lv_obj_t* labelButtonValidate; - lv_obj_t* buttonReset; - lv_obj_t* labelButtonReset; - bool running = true; - }; - } - } -} diff --git a/src/displayapp/Screens/Gauge.cpp b/src/displayapp/Screens/Gauge.cpp deleted file mode 100644 index fd905231fd835b5b66d92cd2b3541c68061e53f4..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Gauge.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#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 deleted file mode 100644 index 03c06bed9b4cdd5e9d8601b59b68619fae35601f..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Gauge.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <cstdint> -#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> - -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/InfiniPaint.cpp b/src/displayapp/Screens/InfiniPaint.cpp deleted file mode 100644 index b340f5d86e8ee6b5cbcd8e74d72e0d34001b66b1..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/InfiniPaint.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include <libraries/log/nrf_log.h> -#include "InfiniPaint.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; - -InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp *app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} { - app->SetTouchMode(DisplayApp::TouchModes::Polling); - std::fill(b, b+bufferSize, LV_COLOR_WHITE); -} - -InfiniPaint::~InfiniPaint() { - // Reset the touchmode - app->SetTouchMode(DisplayApp::TouchModes::Gestures); - lv_obj_clean(lv_scr_act()); -} - -bool InfiniPaint::Refresh() { - return running; -} - -bool InfiniPaint::OnButtonPushed() { - running = false; - return true; -} - -bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return true; -} - -bool InfiniPaint::OnTouchEvent(uint16_t x, uint16_t y) { - lv_area_t area; - area.x1 = x-(width/2); - area.y1 = y-(height/2); - area.x2 = x+(width/2)-1; - area.y2 = y+(height/2)-1; - lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); - lvgl.FlushDisplay(&area, b); - return true; -} - diff --git a/src/displayapp/Screens/InfiniPaint.h b/src/displayapp/Screens/InfiniPaint.h deleted file mode 100644 index a1592f97b4af0899e64343cff4f76c66ead9c9e5..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/InfiniPaint.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <cstdint> -#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 <drivers/St7789.h> -#include <DisplayApp/LittleVgl.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class InfiniPaint : public Screen{ - public: - InfiniPaint(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); - ~InfiniPaint() override; - - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - bool OnTouchEvent(uint16_t x, uint16_t y) override; - - private: - Pinetime::Components::LittleVgl& lvgl; - static constexpr uint16_t width = 10; - static constexpr uint16_t height = 10; - static constexpr uint16_t bufferSize = width*height; - lv_color_t b[bufferSize]; - bool running = true; - }; - } - } -} diff --git a/src/displayapp/Screens/Label.cpp b/src/displayapp/Screens/Label.cpp deleted file mode 100644 index 780ee88eb25b832d61ad0368e2b1cb5dec5e2e59..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Label.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "Label.h" - -using namespace Pinetime::Applications::Screens; - -Label::Label(Pinetime::Applications::DisplayApp *app, const char *text) : Screen(app), text{text} { - label = lv_label_create(lv_scr_act(), NULL); - lv_label_set_align(label, LV_LABEL_ALIGN_LEFT); - lv_obj_set_size(label, 240, 240); - lv_label_set_text(label, text); -} - -Label::~Label() { - lv_obj_clean(lv_scr_act()); -} diff --git a/src/displayapp/Screens/Label.h b/src/displayapp/Screens/Label.h deleted file mode 100644 index 3e7b37972846ce336c2c081120afcdde6d7ef688..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Label.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include <vector> -#include "Screen.h" -#include <lvgl/lvgl.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class Label : public Screen { - public: - Label(DisplayApp* app, const char* text); - ~Label() override; - bool Refresh() override {return false;} - - private: - lv_obj_t * label = nullptr; - const char* text = nullptr; - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/Meter.cpp b/src/displayapp/Screens/Meter.cpp deleted file mode 100644 index c74b8bdfa1f0297a3f4d56205034be4a0ce0f32f..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Meter.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#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 deleted file mode 100644 index ddf8be8d9c0ecf7de71d21f2332b4b2ef8268540..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Meter.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <cstdint> -#include <chrono> -#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> - -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 deleted file mode 100644 index 63ae70c033d7514800107d6b56e5d6ce0f4f3915..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Modal.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#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::Hide() { - /* Delete the parent modal background */ - lv_obj_del_async(lv_obj_get_parent(mbox)); - mbox = NULL; /* happens before object is actually deleted! */ - isVisible = false; -} - -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(); - } -} - -void Modal::Show(const char* msg) { - if(isVisible) return; - isVisible = true; - 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); - lv_mbox_set_text(mbox, msg); - 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); -} diff --git a/src/displayapp/Screens/Modal.h b/src/displayapp/Screens/Modal.h deleted file mode 100644 index c616c29483cd644b08655e32b2f703e5459b061f..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Modal.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <cstdint> -#include <chrono> -#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> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class Modal : public Screen{ - public: - Modal(DisplayApp* app); - ~Modal() override; - - void Show(const char* msg); - 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; - bool isVisible = false; - - }; - } - } -} diff --git a/src/displayapp/Screens/Music.cpp b/src/displayapp/Screens/Music.cpp deleted file mode 100644 index 9b7d198bcde58788e36f92454b28b30daee61e92..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Music.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include "Music.h" - -using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressed; -extern lv_font_t jetbrains_mono_bold_20; - -static void event_handler(lv_obj_t * obj, lv_event_t event) -{ - Music* screen = static_cast<Music *>(obj->user_data); - screen->OnObjectEvent(obj, event); -} - -Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { - lv_obj_t * label; - - btnVolDown = lv_btn_create(lv_scr_act(), NULL); - btnVolDown->user_data = this; - lv_obj_set_event_cb(btnVolDown, event_handler); - lv_obj_align(btnVolDown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10); - label = lv_label_create(btnVolDown, NULL); - lv_label_set_text(label, "v-"); - - btnVolUp = lv_btn_create(lv_scr_act(), NULL); - btnVolUp->user_data = this; - lv_obj_set_event_cb(btnVolUp, event_handler); - lv_obj_align(btnVolUp, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10); - label = lv_label_create(btnVolUp, NULL); - lv_label_set_text(label, "v+"); - - btnPrev = lv_btn_create(lv_scr_act(), NULL); - btnPrev->user_data = this; - lv_obj_set_event_cb(btnPrev, event_handler); - lv_obj_set_size(btnPrev, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPrev, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10,-10); - label = lv_label_create(btnPrev, NULL); - lv_label_set_text(label, "<<"); - - btnPlayPause = lv_btn_create(lv_scr_act(), NULL); - btnPlayPause->user_data = this; - lv_obj_set_event_cb(btnPlayPause, event_handler); - lv_obj_set_size(btnPlayPause, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPlayPause, NULL, LV_ALIGN_IN_BOTTOM_MID, 0,-10); - txtPlayPause = lv_label_create(btnPlayPause, NULL); - lv_label_set_text(txtPlayPause, ">"); - - btnNext = lv_btn_create(lv_scr_act(), NULL); - btnNext->user_data = this; - lv_obj_set_event_cb(btnNext, event_handler); - lv_obj_set_size(btnNext, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnNext, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10,-10); - label = lv_label_create(btnNext, NULL); - lv_label_set_text(label, ">>"); - - txtArtist = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); - lv_obj_align(txtArtist, NULL, LV_ALIGN_IN_LEFT_MID, 0,-20); - lv_label_set_text(txtArtist, "Artist Name"); - lv_label_set_align(txtArtist, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtArtist, LV_HOR_RES); - - txtTrack = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_DOT); - lv_obj_align(txtTrack, NULL, LV_ALIGN_IN_LEFT_MID, 0,20); - lv_label_set_text(txtTrack, "This is a very long track name"); - lv_label_set_align(txtTrack, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtTrack, LV_HOR_RES); - - musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); -} - -Music::~Music() { - lv_obj_clean(lv_scr_act()); -} - -bool Music::OnButtonPushed() { - running = false; - return true; -} - -bool Music::Refresh() { - - if (m_artist != musicService.artist()) { - m_artist = musicService.artist(); - lv_label_set_text(txtArtist, m_artist.data()); - } - if (m_track != musicService.track()) { - m_track = musicService.track(); - lv_label_set_text(txtTrack, m_track.data()); - } - if (m_album != musicService.album()) { - m_album = musicService.album(); - } - if (m_status != musicService.status()) { - m_status = musicService.status(); - } - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - lv_label_set_text(txtPlayPause, "||"); - } else { - lv_label_set_text(txtPlayPause, ">"); - } - - return running; -} - -void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) -{ - if (event == LV_EVENT_CLICKED) { - if (obj == btnVolDown) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); - } else if (obj == btnVolUp) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); - } else if (obj == btnPrev) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); - } else if (obj == btnPlayPause) { - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); - } else { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); - } - } else if (obj == btnNext) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); - } - } -} diff --git a/src/displayapp/Screens/Music.h b/src/displayapp/Screens/Music.h deleted file mode 100644 index 95cac0f0a434d7d206bb9721ccb348afd21532df..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Music.h +++ /dev/null @@ -1,49 +0,0 @@ -#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 "../../Version.h" -#include <Components/Ble/MusicService.h> -#include <string> - -namespace Pinetime { - namespace Applications { - namespace Screens { - - class Music : public Screen{ - public: - Music(DisplayApp* app, Pinetime::Controllers::MusicService &music); - ~Music() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - - private: - lv_obj_t * btnPrev; - lv_obj_t * btnPlayPause; - lv_obj_t * btnNext; - lv_obj_t * btnVolDown; - lv_obj_t * btnVolUp; - lv_obj_t * txtArtist; - lv_obj_t * txtTrack; - lv_obj_t * txtPlayPause; - - bool running = true; - Pinetime::Controllers::MusicService &musicService; - std::string m_artist; - std::string m_album; - std::string m_track; - unsigned char m_status; - }; - } - } -} diff --git a/src/displayapp/Screens/Screen.cpp b/src/displayapp/Screens/Screen.cpp deleted file mode 100644 index 1467df3309fdbd104e41d49878202c5f9535d4f5..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Screen.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "Screen.h" -using namespace Pinetime::Applications::Screens; \ No newline at end of file diff --git a/src/displayapp/Screens/Screen.h b/src/displayapp/Screens/Screen.h deleted file mode 100644 index dbf81a440b5ad761d17215b843adde2b4cedde8b..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Screen.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include <cstdint> -#include "../TouchEvents.h" - -namespace Pinetime { - namespace Applications { - class DisplayApp; - namespace Screens { - class Screen { - public: - 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; } - - // Return false if the event hasn't been handled by the app, true if it has been handled - virtual bool OnTouchEvent(TouchEvents event) { return false; } - virtual bool OnTouchEvent(uint16_t x, uint16_t y) { return false; } - - protected: - DisplayApp* app; - }; - } - } -} diff --git a/src/displayapp/Screens/ScreenList.h b/src/displayapp/Screens/ScreenList.h deleted file mode 100644 index d873336d2d5ad362a70fcc9cf9592c2ca0169cf9..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/ScreenList.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <vector> -#include <Components/Ble/NimbleController.h> -#include <functional> -#include "Screen.h" -#include "Label.h" - -namespace Pinetime { - namespace Applications { - namespace Screens { - template <size_t N> - class ScreenList : public Screen { - public: - ScreenList(DisplayApp* app, std::array<std::function<std::unique_ptr<Screen>()>, N>&& screens) - : Screen(app), screens{std::move(screens)}, current{this->screens[0]()} { - - } - - ~ScreenList() override { - - } - - bool Refresh() override { - running = current->Refresh(); - return running; - } - - bool OnButtonPushed() override { - running = false; - return true; - } - - bool OnTouchEvent(TouchEvents event) override { - switch (event) { - case TouchEvents::SwipeDown: - if (screenIndex > 0) { - current.reset(nullptr); - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); - screenIndex--; - current = screens[screenIndex](); - } - return true; - case TouchEvents::SwipeUp: - if (screenIndex < screens.size() - 1) { - current.reset(nullptr); - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); - screenIndex++; - current = screens[screenIndex](); - } - return true; - default: - return false; - } - return false; - } - - private: - bool running = true; - uint8_t screenIndex = 0; - std::array<std::function<std::unique_ptr<Screen>()>, N> screens; - std::unique_ptr<Screen> current; - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/Symbols.h b/src/displayapp/Screens/Symbols.h deleted file mode 100644 index aeea3243031f38dd617aab77eb586e51b482098e..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Symbols.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -namespace Pinetime { - namespace Applications { - namespace Screens { - namespace Symbols { - static constexpr const char* none = ""; - static constexpr const char* batteryFull = "\xEF\x89\x80"; - static constexpr const char* batteryEmpty = "\xEF\x89\x84"; - static constexpr const char* batteryThreeQuarter = "\xEF\x89\x81"; - static constexpr const char* batteryHalf = "\xEF\x89\x82"; - static constexpr const char* batteryOneQuarter = "\xEF\x89\x83"; - static constexpr const char* heartBeat = "\xEF\x88\x9E"; - static constexpr const char* bluetoothFull = "\xEF\x8A\x93"; - static constexpr const char* bluetooth = "\xEF\x8A\x94"; - static constexpr const char* plug = "\xEF\x87\xA6"; - static constexpr const char* shoe = "\xEF\x95\x8B"; - static constexpr const char* clock = "\xEF\x80\x97"; - static constexpr const char* info = "\xEF\x84\xA9"; - static constexpr const char* list = "\xEF\x80\xBA"; - static constexpr const char* sun = "\xEF\x86\x85"; - static constexpr const char* check = "\xEF\x95\xA0"; - static constexpr const char* music = "\xEF\x80\x81"; - static constexpr const char* tachometer = "\xEF\x8F\xBD"; - static constexpr const char* asterisk = "\xEF\x81\xA9"; - static constexpr const char* paintbrush = "\xEF\x87\xBC"; - } - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/SystemInfo.cpp b/src/displayapp/Screens/SystemInfo.cpp deleted file mode 100644 index fcafcf7d26a075a56d67006354c3b090c75c54d7..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/SystemInfo.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include <libs/lvgl/lvgl.h> -#include <DisplayApp/DisplayApp.h> -#include <functional> -#include "SystemInfo.h" -#include "../../Version.h" -#include "Tile.h" - -using namespace Pinetime::Applications::Screens; - -SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp *app, - Pinetime::Controllers::DateTime &dateTimeController, - Pinetime::Controllers::Battery& batteryController, - Pinetime::Controllers::BrightnessController& brightnessController, - Pinetime::Controllers::Ble& bleController, - Pinetime::Drivers::WatchdogView& watchdog) : - Screen(app), - dateTimeController{dateTimeController}, batteryController{batteryController}, - brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog}, - screens{app, { - [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, - [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, - [this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } - } - } {} - - -SystemInfo::~SystemInfo() { - lv_obj_clean(lv_scr_act()); -} - -bool SystemInfo::Refresh() { - screens.Refresh(); - return running; -} - -bool SystemInfo::OnButtonPushed() { - running = false; - return true; -} - -bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return screens.OnTouchEvent(event); -} - -std::unique_ptr<Screen> SystemInfo::CreateScreen1() { - auto batteryPercentF = batteryController.PercentRemaining(); - uint16_t batteryPercent = 0; - if(batteryPercentF > 100.0f) batteryPercent = 100; - else if(batteryPercentF < 0.0f) batteryPercent = 0; - - uint8_t brightness = 0; - switch(brightnessController.Level()) { - case Controllers::BrightnessController::Levels::Off: brightness = 0; break; - case Controllers::BrightnessController::Levels::Low: brightness = 1; break; - case Controllers::BrightnessController::Levels::Medium: brightness = 2; break; - case Controllers::BrightnessController::Levels::High: brightness = 3; break; - } - auto resetReason = [this]() { - switch (watchdog.ResetReason()) { - case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg"; - case Drivers::Watchdog::ResetReasons::HardReset: return "hardr"; - case Drivers::Watchdog::ResetReasons::NFC: return "nfc"; - case Drivers::Watchdog::ResetReasons::SoftReset: return "softr"; - case Drivers::Watchdog::ResetReasons::CpuLockup: return "cpulock"; - case Drivers::Watchdog::ResetReasons::SystemOff: return "off"; - case Drivers::Watchdog::ResetReasons::LpComp: return "lpcomp"; - case Drivers::Watchdog::ResetReasons::DebugInterface: return "dbg"; - case Drivers::Watchdog::ResetReasons::ResetPin: return "rst"; - default: return "?"; - } - }(); - - // uptime - static constexpr uint32_t secondsInADay = 60*60*24; - static constexpr uint32_t secondsInAnHour = 60*60; - static constexpr uint32_t secondsInAMinute = 60; - uint32_t uptimeSeconds = dateTimeController.Uptime().count(); - uint32_t uptimeDays = (uptimeSeconds / secondsInADay); - uptimeSeconds = uptimeSeconds % secondsInADay; - uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; - uptimeSeconds = uptimeSeconds % secondsInAnHour; - uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; - uptimeSeconds = uptimeSeconds % secondsInAMinute; - // TODO handle more than 100 days of uptime - - sprintf(t1, "Pinetime\n" - "Version:%ld.%ld.%ld\n" - "Build: %s\n" - " %s\n" - "Date: %02d/%02d/%04d\n" - "Time: %02d:%02d:%02d\n" - "Uptime: %02lud %02lu:%02lu:%02lu\n" - "Battery: %d%%\n" - "Backlight: %d/3\n" - "Last reset: %s\n", - Version::Major(), Version::Minor(), Version::Patch(), - __DATE__, __TIME__, - dateTimeController.Day(), static_cast<uint8_t>(dateTimeController.Month()), dateTimeController.Year(), - dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), - uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, - batteryPercent, brightness, resetReason); - - return std::unique_ptr<Screen>(new Screens::Label(app, t1)); -} - -std::unique_ptr<Screen> SystemInfo::CreateScreen2() { - auto& bleAddr = bleController.Address(); - sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x", - bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); - return std::unique_ptr<Screen>(new Screens::Label(app, t2)); -} - -std::unique_ptr<Screen> SystemInfo::CreateScreen3() { - strncpy(t3, "Hello from\nthe developper!", 27); - return std::unique_ptr<Screen>(new Screens::Label(app, t3)); -} diff --git a/src/displayapp/Screens/SystemInfo.h b/src/displayapp/Screens/SystemInfo.h deleted file mode 100644 index ac8abae5182d82a896caa90fb68c096b1621496c..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/SystemInfo.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include <vector> -#include <Components/Ble/NimbleController.h> -#include "Screen.h" -#include "Label.h" -#include "ScreenList.h" -#include "Gauge.h" -#include "Meter.h" -#include <functional> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class SystemInfo : public Screen { - public: - explicit SystemInfo(DisplayApp* app, - Pinetime::Controllers::DateTime& dateTimeController, - Pinetime::Controllers::Battery& batteryController, - Pinetime::Controllers::BrightnessController& brightnessController, - Pinetime::Controllers::Ble& bleController, - Pinetime::Drivers::WatchdogView& watchdog); - ~SystemInfo() override; - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - private: - bool running = true; - - Pinetime::Controllers::DateTime& dateTimeController; - Pinetime::Controllers::Battery& batteryController; - Pinetime::Controllers::BrightnessController& brightnessController; - Pinetime::Controllers::Ble& bleController; - Pinetime::Drivers::WatchdogView& watchdog; - - char t1[200]; - char t2[200]; - char t3[30]; - - ScreenList<3> screens; - std::unique_ptr<Screen> CreateScreen1(); - std::unique_ptr<Screen> CreateScreen2(); - std::unique_ptr<Screen> CreateScreen3(); - }; - } - } -} \ No newline at end of file diff --git a/src/displayapp/Screens/Tab.cpp b/src/displayapp/Screens/Tab.cpp deleted file mode 100644 index adc32578a76f112230e420e37a6bc89e7d8635e8..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Tab.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#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 deleted file mode 100644 index e16dbb962d8f777c125f3f2b24ef79d7853127d3..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Tab.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include <cstdint> -#include "Screen.h" -#include <bits/unique_ptr.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 deleted file mode 100644 index 1447d789be2b499c1397427363afd3c2e9124068..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Tile.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#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> -#include "Symbols.h" -#include "../../Version.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); -} - -Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen(app) { - for(int i = 0, appIndex = 0; i < 8; i++) { - if(i == 3) btnm_map1[i] = "\n"; - else if(i == 7) btnm_map1[i] = ""; - else { - btnm_map1[i] = applications[appIndex].icon; - apps[appIndex] = applications[appIndex].application; - appIndex++; - } - } - modal.reset(new Modal(app)); - - 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); - - btnm1->user_data = this; - lv_obj_set_event_cb(btnm1, event_handler); -} - -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) { - if(event == LV_EVENT_VALUE_CHANGED) { - app->StartApp(apps[buttonId]); - running = false; - } -} - -bool Tile::OnButtonPushed() { - app->StartApp(Apps::Clock); - running = false; - return true; -} - - diff --git a/src/displayapp/Screens/Tile.h b/src/displayapp/Screens/Tile.h deleted file mode 100644 index 3136d892526c8c837fd6f9e375736f7b72bcbf19..0000000000000000000000000000000000000000 --- a/src/displayapp/Screens/Tile.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <cstdint> -#include "Screen.h" -#include <bits/unique_ptr.h> -#include "Modal.h" -#include <lvgl/src/lv_core/lv_style.h> -#include <DisplayApp/Apps.h> - -namespace Pinetime { - namespace Applications { - namespace Screens { - class Tile : public Screen { - public: - struct Applications { - const char* icon; - Pinetime::Applications::Apps application; - }; - - explicit Tile(DisplayApp* app, std::array<Applications, 6>& applications); - ~Tile() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); - - private: - lv_obj_t * btnm1; - bool running = true; - - std::unique_ptr<Modal> modal; - - const char* btnm_map1[8]; - Pinetime::Applications::Apps apps[6]; - }; - } - } -} diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb85be4fab9351f6cbaba635acd8b247ef3b624d --- /dev/null +++ b/src/displayapp/screens/ApplicationList.cpp @@ -0,0 +1,82 @@ +#include <libs/lvgl/lvgl.h> +#include <DisplayApp/DisplayApp.h> +#include <functional> +#include "ApplicationList.h" +#include "Tile.h" +#include "Symbols.h" + +using namespace Pinetime::Applications::Screens; + +ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp *app) : + Screen(app), + screens{app, { + [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, + //[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } + } + } {} + + +ApplicationList::~ApplicationList() { + lv_obj_clean(lv_scr_act()); +} + +bool ApplicationList::Refresh() { + if(running) + running = screens.Refresh(); + return running; +} + +bool ApplicationList::OnButtonPushed() { + running = false; + app->StartApp(Apps::Clock); + return true; +} + +bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen1() { + std::array<Screens::Tile::Applications, 6> applications { + {{Symbols::clock, Apps::Clock}, + {Symbols::music, Apps::Music}, + {Symbols::sun, Apps::Brightness}, + {Symbols::list, Apps::SysInfo}, + {Symbols::check, Apps::FirmwareValidation}, + {Symbols::none, Apps::None} + } + + + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen2() { + std::array<Screens::Tile::Applications, 6> applications { + {{Symbols::tachometer, Apps::Gauge}, + {Symbols::asterisk, Apps::Meter}, + {Symbols::paintbrush, Apps::Paint}, + {Symbols::none, Apps::None}, + {Symbols::none, Apps::None}, + {Symbols::none, Apps::None} + } + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} + +std::unique_ptr<Screen> ApplicationList::CreateScreen3() { + std::array<Screens::Tile::Applications, 6> applications { + {{"A", Apps::Meter}, + {"B", Apps::Gauge}, + {"C", Apps::Clock}, + {"D", Apps::Music}, + {"E", Apps::SysInfo}, + {"F", Apps::Brightness} + } + }; + + return std::unique_ptr<Screen>(new Screens::Tile(app, applications)); +} diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h new file mode 100644 index 0000000000000000000000000000000000000000..a1e6811b3c3fcaaff970e6f3a69d7f1cf75f3d67 --- /dev/null +++ b/src/displayapp/screens/ApplicationList.h @@ -0,0 +1,32 @@ +#pragma once + +#include <vector> +#include <Components/Ble/NimbleController.h> +#include "Screen.h" +#include "Label.h" +#include "ScreenList.h" +#include "Gauge.h" +#include "Meter.h" +#include <functional> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class ApplicationList : public Screen { + public: + explicit ApplicationList(DisplayApp* app); + ~ApplicationList() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + private: + bool running = true; + + ScreenList<2> screens; + std::unique_ptr<Screen> CreateScreen1(); + std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26939d1824ffff8209c97db5252a17c1f3fdb50e --- /dev/null +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -0,0 +1,21 @@ +#include "BatteryIcon.h" +#include "Symbols.h" +using namespace Pinetime::Applications::Screens; + +const char* BatteryIcon::GetBatteryIcon(float batteryPercent) { + if(batteryPercent > 90.0f) return Symbols::batteryFull; + if(batteryPercent > 75.0f) return Symbols::batteryThreeQuarter; + if(batteryPercent > 50.0f) return Symbols::batteryHalf; + if(batteryPercent > 25.0f) return Symbols::batteryOneQuarter; + return Symbols::batteryEmpty; +} + +const char* BatteryIcon::GetUnknownIcon() { + return Symbols::batteryEmpty; +} + +const char *BatteryIcon::GetPlugIcon(bool isCharging) { + if(isCharging) + return Symbols::plug; + else return ""; +} diff --git a/src/displayapp/screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h new file mode 100644 index 0000000000000000000000000000000000000000..58f04a875493f8cd3eaf1f6c9612362cde90aa31 --- /dev/null +++ b/src/displayapp/screens/BatteryIcon.h @@ -0,0 +1,16 @@ +#pragma once + +#include <libs/lvgl/src/lv_draw/lv_img_decoder.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class BatteryIcon { + public: + static const char* GetUnknownIcon(); + static const char* GetBatteryIcon(float batteryPercent); + static const char* GetPlugIcon(bool isCharging); + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/BleIcon.cpp b/src/displayapp/screens/BleIcon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1bbbd0531a4932f9449a654330bda910b870f69a --- /dev/null +++ b/src/displayapp/screens/BleIcon.cpp @@ -0,0 +1,8 @@ +#include "BleIcon.h" +#include "Symbols.h" +using namespace Pinetime::Applications::Screens; + +const char* BleIcon::GetIcon(bool isConnected) { + if(isConnected) return Symbols::bluetooth; + else return ""; +} \ No newline at end of file diff --git a/src/displayapp/screens/BleIcon.h b/src/displayapp/screens/BleIcon.h new file mode 100644 index 0000000000000000000000000000000000000000..c1398d2a68b5c9fffbd321e8d0dd7220d54106b4 --- /dev/null +++ b/src/displayapp/screens/BleIcon.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + namespace Screens { + class BleIcon { + public: + static const char* GetIcon(bool isConnected); + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e3416c0d958fe8c4983305fcae49b7552baf92d --- /dev/null +++ b/src/displayapp/screens/Brightness.cpp @@ -0,0 +1,92 @@ +#include <libs/lvgl/lvgl.h> +#include "Brightness.h" + +using namespace Pinetime::Applications::Screens; + +void slider_event_cb(lv_obj_t * slider, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + auto* brightnessSlider = static_cast<Brightness*>(slider->user_data); + brightnessSlider->OnValueChanged(); + } +} + +Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { + slider = lv_slider_create(lv_scr_act(), NULL); + lv_obj_set_user_data(slider, this); + lv_obj_set_width(slider, LV_DPI * 2); + lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(slider, slider_event_cb); + lv_slider_set_range(slider, 0, 2); + lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); + + slider_label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(slider_label, LevelToString(brightness.Level())); + lv_obj_set_auto_realign(slider_label, true); + lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); +} + +Brightness::~Brightness() { + lv_obj_clean(lv_scr_act()); +} + +bool Brightness::Refresh() { + return running; +} + +bool Brightness::OnButtonPushed() { + running = false; + return true; +} + +const char *Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off"; + case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low"; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium"; + case Pinetime::Controllers::BrightnessController::Levels::High: return "High"; + default : return "???"; + } +} + +void Brightness::OnValueChanged() { + SetValue(lv_slider_get_value(slider)); +} + +void Brightness::SetValue(uint8_t value) { + switch(value) { + case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break; + case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break; + case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break; + } + lv_label_set_text(slider_label, LevelToString(brightness.Level())); +} + +uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Low: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1; + case Pinetime::Controllers::BrightnessController::Levels::High: return 2; + default : return 0; + } +} + +bool Brightness::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch(event) { + case TouchEvents::SwipeLeft: + brightness.Lower(); + SetValue(); + return true; + case TouchEvents::SwipeRight: + brightness.Higher(); + SetValue(); + return true; + default: + return false; + } +} + +void Brightness::SetValue() { + lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); + lv_label_set_text(slider_label, LevelToString(brightness.Level())); +} diff --git a/src/displayapp/screens/Brightness.h b/src/displayapp/screens/Brightness.h new file mode 100644 index 0000000000000000000000000000000000000000..37cbcd7eb693cc3af6e55c11a2cde034e781e51f --- /dev/null +++ b/src/displayapp/screens/Brightness.h @@ -0,0 +1,33 @@ +#pragma once + +#include <libs/lvgl/src/lv_core/lv_obj.h> +#include <Components/Brightness/BrightnessController.h> +#include "Screen.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Brightness : public Screen { + public: + Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); + ~Brightness() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + void OnValueChanged(); + private: + bool running = true; + Controllers::BrightnessController& brightness; + + lv_obj_t * slider_label; + lv_obj_t * slider; + + const char* LevelToString(Controllers::BrightnessController::Levels level); + uint8_t LevelToInt(Controllers::BrightnessController::Levels level); + void SetValue(uint8_t value); + void SetValue(); + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06fab9aa6825350fe401c1427e67afd0ab7bafd1 --- /dev/null +++ b/src/displayapp/screens/Clock.cpp @@ -0,0 +1,227 @@ +#include <cstdio> +#include <libs/date/includes/date/date.h> +#include <Components/DateTime/DateTimeController.h> +#include <libs/lvgl/lvgl.h> +#include "Clock.h" +#include "../DisplayApp.h" +#include "BatteryIcon.h" +#include "BleIcon.h" +#include "Symbols.h" +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; +extern lv_style_t* LabelBigStyle; + +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{{}}, + dateTimeController{dateTimeController}, batteryController{batteryController}, bleController{bleController} { + displayedChar[0] = 0; + displayedChar[1] = 0; + displayedChar[2] = 0; + displayedChar[3] = 0; + displayedChar[4] = 0; + + batteryIcon = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(batteryIcon, Symbols::batteryFull); + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); + + batteryPlug = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(batteryPlug, Symbols::plug); + lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + bleIcon = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(bleIcon, Symbols::bluetooth); + lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + + label_date = lv_label_create(lv_scr_act(), NULL); + + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); + + 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); + + backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel->user_data = this; + 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, ""); + + + heartbeatIcon = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(heartbeatIcon, Symbols::heartBeat); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + + heartbeatValue = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(heartbeatValue, "0"); + lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + + heartbeatBpm = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(heartbeatBpm, "BPM"); + lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + + stepValue = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(stepValue, "0"); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + + stepIcon = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(stepIcon, Symbols::shoe); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); +} + +Clock::~Clock() { + lv_obj_clean(lv_scr_act()); +} + +bool Clock::Refresh() { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { + auto batteryPercent = batteryPercentRemaining.Get(); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent(); + lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); + } + + bleState = bleController.IsConnected(); + if (bleState.IsUpdated()) { + if(bleState.Get() == true) { + lv_label_set_text(bleIcon, BleIcon::GetIcon(true)); + } else { + lv_label_set_text(bleIcon, BleIcon::GetIcon(false)); + } + } + lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5); + lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); + + currentDateTime = dateTimeController.CurrentDateTime(); + + if(currentDateTime.IsUpdated()) { + auto newDateTime = currentDateTime.Get(); + + auto dp = date::floor<date::days>(newDateTime); + auto time = date::make_time(newDateTime-dp); + auto yearMonthDay = date::year_month_day(dp); + + auto year = (int)yearMonthDay.year(); + auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned)yearMonthDay.month()); + auto day = (unsigned)yearMonthDay.day(); + auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding()); + + auto hour = time.hours().count(); + auto minute = time.minutes().count(); + + char minutesChar[3]; + sprintf(minutesChar, "%02d", static_cast<int>(minute)); + + char hoursChar[3]; + sprintf(hoursChar, "%02d", static_cast<int>(hour)); + + char timeStr[6]; + sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); + + 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]; + + lv_label_set_text(label_time, timeStr); + } + + if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { + char dateStr[22]; + sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); + lv_label_set_text(label_date, dateStr); + + + currentYear = year; + currentMonth = month; + currentDayOfWeek = dayOfWeek; + currentDay = day; + } + } + + // TODO heartbeat = heartBeatController.GetValue(); + if(heartbeat.IsUpdated()) { + char heartbeatBuffer[4]; + sprintf(heartbeatBuffer, "%d", heartbeat.Get()); + lv_label_set_text(heartbeatValue, heartbeatBuffer); + lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); + lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); + } + + // TODO stepCount = stepController.GetValue(); + if(stepCount.IsUpdated()) { + char stepBuffer[5]; + sprintf(stepBuffer, "%lu", stepCount.Get()); + lv_label_set_text(stepValue, stepBuffer); + lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); + lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); + } + + return running; +} + +const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { + return Clock::MonthsString[static_cast<uint8_t>(month)]; +} + +const char *Clock::DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek) { + return Clock::DaysString[static_cast<uint8_t>(dayOfWeek)]; +} + +char const *Clock::DaysString[] = { + "", + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" +}; + +char const *Clock::MonthsString[] = { + "", + "JAN", + "FEB", + "MAR", + "APR", + "MAY", + "JUN", + "JUL", + "AUG", + "SEP", + "OCT", + "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() { + running = false; + return false; +} + + diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h new file mode 100644 index 0000000000000000000000000000000000000000..7363fdaf46ec9998d17322edef4e37b374f77388 --- /dev/null +++ b/src/displayapp/screens/Clock.h @@ -0,0 +1,88 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#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> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + template <class T> + class DirtyValue { + public: + explicit DirtyValue(T v) { value = v; } + explicit DirtyValue(T& v) { value = v; } + bool IsUpdated() const { return isUpdated; } + T& Get() { this->isUpdated = false; return value; } + + DirtyValue& operator=(const T& other) { + if (this->value != other) { + this->value = other; + this->isUpdated = true; + } + return *this; + } + private: + T value; + bool isUpdated = true; + }; + class Clock : public Screen{ + public: + Clock(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController); + ~Clock() override; + + 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[]; + + char displayedChar[5]; + + 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<float> batteryPercentRemaining {0}; + DirtyValue<bool> bleState {false}; + DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime; + DirtyValue<uint32_t> stepCount {0}; + DirtyValue<uint8_t> heartbeat {0}; + + + lv_obj_t* label_time; + lv_obj_t* label_date; + lv_obj_t* backgroundLabel; + lv_obj_t * batteryIcon; + lv_obj_t * bleIcon; + lv_obj_t* batteryPlug; + lv_obj_t* heartbeatIcon; + lv_obj_t* heartbeatValue; + lv_obj_t* heartbeatBpm; + lv_obj_t* stepIcon; + lv_obj_t* stepValue; + + Controllers::DateTime& dateTimeController; + Controllers::Battery& batteryController; + Controllers::Ble& bleController; + + bool running = true; + + }; + } + } +} diff --git a/src/displayapp/screens/DropDownDemo.cpp b/src/displayapp/screens/DropDownDemo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..735a0ccedecbcc71b51825830b919677eb7f28ea --- /dev/null +++ b/src/displayapp/screens/DropDownDemo.cpp @@ -0,0 +1,64 @@ +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> +#include "DropDownDemo.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; + +DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) { + // Create the dropdown object, with many item, and fix its height + ddlist = lv_ddlist_create(lv_scr_act(), NULL); + lv_ddlist_set_options(ddlist, "Apple\n" + "Banana\n" + "Orange\n" + "Melon\n" + "Grape\n" + "Raspberry\n" + "A\n" + "B\n" + "C\n" + "D\n" + "E"); + lv_ddlist_set_fix_width(ddlist, 150); + lv_ddlist_set_draw_arrow(ddlist, true); + lv_ddlist_set_fix_height(ddlist, 150); + lv_obj_align(ddlist, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); +} + +DropDownDemo::~DropDownDemo() { + // Reset the touchmode + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_obj_clean(lv_scr_act()); +} + +bool DropDownDemo::Refresh() { + auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); + + // Switch touchmode to Polling if the dropdown is opened. This will allow to scroll inside the + // dropdown while it is opened. + // Disable the polling mode when the dropdown is closed to be able to handle the gestures. + if(list->opened) + app->SetTouchMode(DisplayApp::TouchModes::Polling); + else + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + return running; +} + +bool DropDownDemo::OnButtonPushed() { + running = false; + return true; +} + +bool DropDownDemo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + // If the dropdown is opened, notify Display app that it doesn't need to handle the event + // (this will prevent displayApp from going back to the menu or clock scree). + auto* list = static_cast<lv_ddlist_ext_t *>(ddlist->ext_attr); + if(list->opened) { + return true; + } else { + return false; + } +} + diff --git a/src/displayapp/screens/DropDownDemo.h b/src/displayapp/screens/DropDownDemo.h new file mode 100644 index 0000000000000000000000000000000000000000..7c75efc029f327787a85b275770f5795217dcf3e --- /dev/null +++ b/src/displayapp/screens/DropDownDemo.h @@ -0,0 +1,29 @@ +#pragma once + +#include <cstdint> +#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> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class DropDownDemo : public Screen{ + public: + DropDownDemo(DisplayApp* app); + ~DropDownDemo() override; + + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + private: + lv_obj_t * ddlist; + bool running = true; + bool isDropDownOpened = false; + }; + } + } +} diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e831114d4ff5878be506deb68811ed895a5c791e --- /dev/null +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -0,0 +1,82 @@ +#include <libs/lvgl/lvgl.h> +#include "FirmwareUpdate.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; + + +FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) : + Screen(app), bleController{bleController} { + + titleLabel = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(titleLabel, "Firmware update"); + lv_obj_set_auto_realign(titleLabel, true); + lv_obj_align(titleLabel, NULL, LV_ALIGN_IN_TOP_MID, 0, 50); + + bar1 = lv_bar_create(lv_scr_act(), NULL); + lv_obj_set_size(bar1, 200, 30); + lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_bar_set_anim_time(bar1, 10); + lv_bar_set_range(bar1, 0, 100); + lv_bar_set_value(bar1, 0, LV_ANIM_OFF); + + percentLabel = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(percentLabel, ""); + lv_obj_set_auto_realign(percentLabel, true); + lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); +} + +FirmwareUpdate::~FirmwareUpdate() { + lv_obj_clean(lv_scr_act()); +} + +bool FirmwareUpdate::Refresh() { + switch(bleController.State()) { + default: + case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: + case Pinetime::Controllers::Ble::FirmwareUpdateStates::Running: + if(state != States::Running) + state = States::Running; + return DisplayProgression(); + case Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated: + if(state != States::Validated) { + UpdateValidated(); + state = States::Validated; + } + return running; + case Pinetime::Controllers::Ble::FirmwareUpdateStates::Error: + if(state != States::Error) { + UpdateError(); + state = States::Error; + } + return running; + } +} + +bool FirmwareUpdate::DisplayProgression() const { + float current = bleController.FirmwareUpdateCurrentBytes() / 1024.0f; + float total = bleController.FirmwareUpdateTotalBytes() / 1024.0f; + int16_t pc = (current / total) * 100.0f; + sprintf(percentStr, "%d %%", pc); + lv_label_set_text(percentLabel, percentStr); + + lv_bar_set_value(bar1, pc, LV_ANIM_OFF); + return running; +} + +bool FirmwareUpdate::OnButtonPushed() { + running = false; + return true; +} + +void FirmwareUpdate::UpdateValidated() { + lv_label_set_recolor(percentLabel, true); + lv_label_set_text(percentLabel, "#00ff00 Image Ok!#"); +} + +void FirmwareUpdate::UpdateError() { + lv_label_set_recolor(percentLabel, true); + lv_label_set_text(percentLabel, "#ff0000 Error!#"); +} diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h new file mode 100644 index 0000000000000000000000000000000000000000..faaf39533d6e26dcc8303ec70ec2314292ff01fc --- /dev/null +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -0,0 +1,41 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#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/Ble/BleController.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class FirmwareUpdate : public Screen{ + public: + FirmwareUpdate(DisplayApp* app, Pinetime::Controllers::Ble& bleController); + ~FirmwareUpdate() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + private: + enum class States { Idle, Running, Validated, Error }; + Pinetime::Controllers::Ble& bleController; + lv_obj_t* bar1; + lv_obj_t* percentLabel; + lv_obj_t* titleLabel; + mutable char percentStr[10]; + bool running = true; + States state; + + bool DisplayProgression() const; + + void UpdateValidated(); + + void UpdateError(); + }; + } + } +} diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb2dd956a27096e2b706a0683dfc45173757489a --- /dev/null +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -0,0 +1,91 @@ +#include <libs/lvgl/lvgl.h> +#include "FirmwareValidation.h" +#include "../DisplayApp.h" +#include "../../Version.h" +#include "../../Components/FirmwareValidator/FirmwareValidator.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +namespace { + static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) + { + FirmwareValidation* screen = static_cast<FirmwareValidation *>(obj->user_data); + screen->OnButtonEvent(obj, event); + } + +} + +FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::FirmwareValidator &validator) + : Screen{app}, validator{validator} { + labelVersionInfo = lv_label_create(lv_scr_act(), NULL); + lv_obj_align(labelVersionInfo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + lv_label_set_text(labelVersionInfo, "Version : "); + lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT); + + + labelVersionValue = lv_label_create(lv_scr_act(), NULL); + lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0); + lv_label_set_recolor(labelVersionValue, true); + sprintf(version, "%ld.%ld.%ld", Version::Major(), Version::Minor(), Version::Patch()); + lv_label_set_text(labelVersionValue, version); + + labelIsValidated = lv_label_create(lv_scr_act(), NULL); + lv_obj_align(labelIsValidated, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50); + lv_label_set_recolor(labelIsValidated, true); + lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK); + lv_obj_set_width(labelIsValidated, 240); + + if(validator.IsValidated()) + lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#"); + else { + lv_label_set_text(labelIsValidated, + "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); + + buttonValidate = lv_btn_create(lv_scr_act(), NULL); + lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + buttonValidate->user_data = this; + lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); + + labelButtonValidate = lv_label_create(buttonValidate, NULL); + lv_label_set_recolor(labelButtonValidate, true); + lv_label_set_text(labelButtonValidate, "#00ff00 Validate#"); + + buttonReset = lv_btn_create(lv_scr_act(), NULL); + buttonReset->user_data = this; + lv_obj_align(buttonReset, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_event_cb(buttonReset, ButtonEventHandler); + + labelButtonReset = lv_label_create(buttonReset, NULL); + lv_label_set_recolor(labelButtonReset, true); + lv_label_set_text(labelButtonReset, "#ff0000 Reset#"); + } +} + + +FirmwareValidation::~FirmwareValidation() { + lv_obj_clean(lv_scr_act()); +} + +bool FirmwareValidation::Refresh() { + return running; +} + +bool FirmwareValidation::OnButtonPushed() { + running = false; + return true; +} + +void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) { + if(object == buttonValidate && event == LV_EVENT_PRESSED) { + validator.Validate(); + running = false; + } else if(object == buttonReset && event == LV_EVENT_PRESSED) { + validator.Reset(); + } + +} + + diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h new file mode 100644 index 0000000000000000000000000000000000000000..947f5575ba0fa5a4eed356e7c26781b1d9049dda --- /dev/null +++ b/src/displayapp/screens/FirmwareValidation.h @@ -0,0 +1,42 @@ +#pragma once + +#include <cstdint> +#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> + +namespace Pinetime { + namespace Controllers { + class FirmwareValidator; + } + + namespace Applications { + namespace Screens { + + class FirmwareValidation : public Screen{ + public: + FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator); + ~FirmwareValidation() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnButtonEvent(lv_obj_t *object, lv_event_t event); + + private: + Pinetime::Controllers::FirmwareValidator& validator; + + lv_obj_t* labelVersionInfo; + lv_obj_t* labelVersionValue; + char version[9]; + lv_obj_t* labelIsValidated; + lv_obj_t* buttonValidate; + lv_obj_t* labelButtonValidate; + lv_obj_t* buttonReset; + lv_obj_t* labelButtonReset; + bool running = true; + }; + } + } +} diff --git a/src/displayapp/screens/Gauge.cpp b/src/displayapp/screens/Gauge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd905231fd835b5b66d92cd2b3541c68061e53f4 --- /dev/null +++ b/src/displayapp/screens/Gauge.cpp @@ -0,0 +1,58 @@ +#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 0000000000000000000000000000000000000000..03c06bed9b4cdd5e9d8601b59b68619fae35601f --- /dev/null +++ b/src/displayapp/screens/Gauge.h @@ -0,0 +1,32 @@ +#pragma once + +#include <cstdint> +#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> + +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/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b340f5d86e8ee6b5cbcd8e74d72e0d34001b66b1 --- /dev/null +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -0,0 +1,44 @@ +#include <libs/lvgl/lvgl.h> +#include <libraries/log/nrf_log.h> +#include "InfiniPaint.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; + +InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp *app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} { + app->SetTouchMode(DisplayApp::TouchModes::Polling); + std::fill(b, b+bufferSize, LV_COLOR_WHITE); +} + +InfiniPaint::~InfiniPaint() { + // Reset the touchmode + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + lv_obj_clean(lv_scr_act()); +} + +bool InfiniPaint::Refresh() { + return running; +} + +bool InfiniPaint::OnButtonPushed() { + running = false; + return true; +} + +bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return true; +} + +bool InfiniPaint::OnTouchEvent(uint16_t x, uint16_t y) { + lv_area_t area; + area.x1 = x-(width/2); + area.y1 = y-(height/2); + area.x2 = x+(width/2)-1; + area.y2 = y+(height/2)-1; + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); + lvgl.FlushDisplay(&area, b); + return true; +} + diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h new file mode 100644 index 0000000000000000000000000000000000000000..a1592f97b4af0899e64343cff4f76c66ead9c9e5 --- /dev/null +++ b/src/displayapp/screens/InfiniPaint.h @@ -0,0 +1,35 @@ +#pragma once + +#include <cstdint> +#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 <drivers/St7789.h> +#include <DisplayApp/LittleVgl.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class InfiniPaint : public Screen{ + public: + InfiniPaint(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); + ~InfiniPaint() override; + + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + bool OnTouchEvent(uint16_t x, uint16_t y) override; + + private: + Pinetime::Components::LittleVgl& lvgl; + static constexpr uint16_t width = 10; + static constexpr uint16_t height = 10; + static constexpr uint16_t bufferSize = width*height; + lv_color_t b[bufferSize]; + bool running = true; + }; + } + } +} diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp new file mode 100644 index 0000000000000000000000000000000000000000..780ee88eb25b832d61ad0368e2b1cb5dec5e2e59 --- /dev/null +++ b/src/displayapp/screens/Label.cpp @@ -0,0 +1,15 @@ +#include <libs/lvgl/lvgl.h> +#include "Label.h" + +using namespace Pinetime::Applications::Screens; + +Label::Label(Pinetime::Applications::DisplayApp *app, const char *text) : Screen(app), text{text} { + label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_align(label, LV_LABEL_ALIGN_LEFT); + lv_obj_set_size(label, 240, 240); + lv_label_set_text(label, text); +} + +Label::~Label() { + lv_obj_clean(lv_scr_act()); +} diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h new file mode 100644 index 0000000000000000000000000000000000000000..3e7b37972846ce336c2c081120afcdde6d7ef688 --- /dev/null +++ b/src/displayapp/screens/Label.h @@ -0,0 +1,23 @@ +#pragma once + +#include <vector> +#include "Screen.h" +#include <lvgl/lvgl.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Label : public Screen { + public: + Label(DisplayApp* app, const char* text); + ~Label() override; + bool Refresh() override {return false;} + + private: + lv_obj_t * label = nullptr; + const char* text = nullptr; + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c74b8bdfa1f0297a3f4d56205034be4a0ce0f32f --- /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 0000000000000000000000000000000000000000..ddf8be8d9c0ecf7de71d21f2332b4b2ef8268540 --- /dev/null +++ b/src/displayapp/screens/Meter.h @@ -0,0 +1,32 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#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> + +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 0000000000000000000000000000000000000000..63ae70c033d7514800107d6b56e5d6ce0f4f3915 --- /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::Hide() { + /* Delete the parent modal background */ + lv_obj_del_async(lv_obj_get_parent(mbox)); + mbox = NULL; /* happens before object is actually deleted! */ + isVisible = false; +} + +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(); + } +} + +void Modal::Show(const char* msg) { + if(isVisible) return; + isVisible = true; + 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); + lv_mbox_set_text(mbox, msg); + 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); +} diff --git a/src/displayapp/screens/Modal.h b/src/displayapp/screens/Modal.h new file mode 100644 index 0000000000000000000000000000000000000000..c616c29483cd644b08655e32b2f703e5459b061f --- /dev/null +++ b/src/displayapp/screens/Modal.h @@ -0,0 +1,39 @@ +#pragma once + +#include <cstdint> +#include <chrono> +#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> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Modal : public Screen{ + public: + Modal(DisplayApp* app); + ~Modal() override; + + void Show(const char* msg); + 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; + bool isVisible = false; + + }; + } + } +} diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b7d198bcde58788e36f92454b28b30daee61e92 --- /dev/null +++ b/src/displayapp/screens/Music.cpp @@ -0,0 +1,125 @@ +#include <libs/lvgl/lvgl.h> +#include "Music.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +static void event_handler(lv_obj_t * obj, lv_event_t event) +{ + Music* screen = static_cast<Music *>(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { + lv_obj_t * label; + + btnVolDown = lv_btn_create(lv_scr_act(), NULL); + btnVolDown->user_data = this; + lv_obj_set_event_cb(btnVolDown, event_handler); + lv_obj_align(btnVolDown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10); + label = lv_label_create(btnVolDown, NULL); + lv_label_set_text(label, "v-"); + + btnVolUp = lv_btn_create(lv_scr_act(), NULL); + btnVolUp->user_data = this; + lv_obj_set_event_cb(btnVolUp, event_handler); + lv_obj_align(btnVolUp, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10); + label = lv_label_create(btnVolUp, NULL); + lv_label_set_text(label, "v+"); + + btnPrev = lv_btn_create(lv_scr_act(), NULL); + btnPrev->user_data = this; + lv_obj_set_event_cb(btnPrev, event_handler); + lv_obj_set_size(btnPrev, LV_HOR_RES / 4, LV_VER_RES / 4); + lv_obj_align(btnPrev, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10,-10); + label = lv_label_create(btnPrev, NULL); + lv_label_set_text(label, "<<"); + + btnPlayPause = lv_btn_create(lv_scr_act(), NULL); + btnPlayPause->user_data = this; + lv_obj_set_event_cb(btnPlayPause, event_handler); + lv_obj_set_size(btnPlayPause, LV_HOR_RES / 4, LV_VER_RES / 4); + lv_obj_align(btnPlayPause, NULL, LV_ALIGN_IN_BOTTOM_MID, 0,-10); + txtPlayPause = lv_label_create(btnPlayPause, NULL); + lv_label_set_text(txtPlayPause, ">"); + + btnNext = lv_btn_create(lv_scr_act(), NULL); + btnNext->user_data = this; + lv_obj_set_event_cb(btnNext, event_handler); + lv_obj_set_size(btnNext, LV_HOR_RES / 4, LV_VER_RES / 4); + lv_obj_align(btnNext, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10,-10); + label = lv_label_create(btnNext, NULL); + lv_label_set_text(label, ">>"); + + txtArtist = lv_label_create(lv_scr_act(), NULL); + lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); + lv_obj_align(txtArtist, NULL, LV_ALIGN_IN_LEFT_MID, 0,-20); + lv_label_set_text(txtArtist, "Artist Name"); + lv_label_set_align(txtArtist, LV_LABEL_ALIGN_CENTER); + lv_obj_set_width(txtArtist, LV_HOR_RES); + + txtTrack = lv_label_create(lv_scr_act(), NULL); + lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_DOT); + lv_obj_align(txtTrack, NULL, LV_ALIGN_IN_LEFT_MID, 0,20); + lv_label_set_text(txtTrack, "This is a very long track name"); + lv_label_set_align(txtTrack, LV_LABEL_ALIGN_CENTER); + lv_obj_set_width(txtTrack, LV_HOR_RES); + + musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); +} + +Music::~Music() { + lv_obj_clean(lv_scr_act()); +} + +bool Music::OnButtonPushed() { + running = false; + return true; +} + +bool Music::Refresh() { + + if (m_artist != musicService.artist()) { + m_artist = musicService.artist(); + lv_label_set_text(txtArtist, m_artist.data()); + } + if (m_track != musicService.track()) { + m_track = musicService.track(); + lv_label_set_text(txtTrack, m_track.data()); + } + if (m_album != musicService.album()) { + m_album = musicService.album(); + } + if (m_status != musicService.status()) { + m_status = musicService.status(); + } + if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { + lv_label_set_text(txtPlayPause, "||"); + } else { + lv_label_set_text(txtPlayPause, ">"); + } + + return running; +} + +void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) +{ + if (event == LV_EVENT_CLICKED) { + if (obj == btnVolDown) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); + } else if (obj == btnVolUp) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); + } else if (obj == btnPrev) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); + } else if (obj == btnPlayPause) { + if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); + } else { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); + } + } else if (obj == btnNext) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); + } + } +} diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h new file mode 100644 index 0000000000000000000000000000000000000000..95cac0f0a434d7d206bb9721ccb348afd21532df --- /dev/null +++ b/src/displayapp/screens/Music.h @@ -0,0 +1,49 @@ +#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 "../../Version.h" +#include <Components/Ble/MusicService.h> +#include <string> + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Music : public Screen{ + public: + Music(DisplayApp* app, Pinetime::Controllers::MusicService &music); + ~Music() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); + + private: + lv_obj_t * btnPrev; + lv_obj_t * btnPlayPause; + lv_obj_t * btnNext; + lv_obj_t * btnVolDown; + lv_obj_t * btnVolUp; + lv_obj_t * txtArtist; + lv_obj_t * txtTrack; + lv_obj_t * txtPlayPause; + + bool running = true; + Pinetime::Controllers::MusicService &musicService; + std::string m_artist; + std::string m_album; + std::string m_track; + unsigned char m_status; + }; + } + } +} diff --git a/src/displayapp/screens/Screen.cpp b/src/displayapp/screens/Screen.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1467df3309fdbd104e41d49878202c5f9535d4f5 --- /dev/null +++ b/src/displayapp/screens/Screen.cpp @@ -0,0 +1,2 @@ +#include "Screen.h" +using namespace Pinetime::Applications::Screens; \ No newline at end of file diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h new file mode 100644 index 0000000000000000000000000000000000000000..dbf81a440b5ad761d17215b843adde2b4cedde8b --- /dev/null +++ b/src/displayapp/screens/Screen.h @@ -0,0 +1,30 @@ +#pragma once + +#include <cstdint> +#include "../TouchEvents.h" + +namespace Pinetime { + namespace Applications { + class DisplayApp; + namespace Screens { + class Screen { + public: + 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; } + + // Return false if the event hasn't been handled by the app, true if it has been handled + virtual bool OnTouchEvent(TouchEvents event) { return false; } + virtual bool OnTouchEvent(uint16_t x, uint16_t y) { return false; } + + protected: + DisplayApp* app; + }; + } + } +} diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h new file mode 100644 index 0000000000000000000000000000000000000000..d873336d2d5ad362a70fcc9cf9592c2ca0169cf9 --- /dev/null +++ b/src/displayapp/screens/ScreenList.h @@ -0,0 +1,66 @@ +#pragma once + +#include <vector> +#include <Components/Ble/NimbleController.h> +#include <functional> +#include "Screen.h" +#include "Label.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + template <size_t N> + class ScreenList : public Screen { + public: + ScreenList(DisplayApp* app, std::array<std::function<std::unique_ptr<Screen>()>, N>&& screens) + : Screen(app), screens{std::move(screens)}, current{this->screens[0]()} { + + } + + ~ScreenList() override { + + } + + bool Refresh() override { + running = current->Refresh(); + return running; + } + + bool OnButtonPushed() override { + running = false; + return true; + } + + bool OnTouchEvent(TouchEvents event) override { + switch (event) { + case TouchEvents::SwipeDown: + if (screenIndex > 0) { + current.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); + screenIndex--; + current = screens[screenIndex](); + } + return true; + case TouchEvents::SwipeUp: + if (screenIndex < screens.size() - 1) { + current.reset(nullptr); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); + screenIndex++; + current = screens[screenIndex](); + } + return true; + default: + return false; + } + return false; + } + + private: + bool running = true; + uint8_t screenIndex = 0; + std::array<std::function<std::unique_ptr<Screen>()>, N> screens; + std::unique_ptr<Screen> current; + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h new file mode 100644 index 0000000000000000000000000000000000000000..aeea3243031f38dd617aab77eb586e51b482098e --- /dev/null +++ b/src/displayapp/screens/Symbols.h @@ -0,0 +1,30 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + namespace Screens { + namespace Symbols { + static constexpr const char* none = ""; + static constexpr const char* batteryFull = "\xEF\x89\x80"; + static constexpr const char* batteryEmpty = "\xEF\x89\x84"; + static constexpr const char* batteryThreeQuarter = "\xEF\x89\x81"; + static constexpr const char* batteryHalf = "\xEF\x89\x82"; + static constexpr const char* batteryOneQuarter = "\xEF\x89\x83"; + static constexpr const char* heartBeat = "\xEF\x88\x9E"; + static constexpr const char* bluetoothFull = "\xEF\x8A\x93"; + static constexpr const char* bluetooth = "\xEF\x8A\x94"; + static constexpr const char* plug = "\xEF\x87\xA6"; + static constexpr const char* shoe = "\xEF\x95\x8B"; + static constexpr const char* clock = "\xEF\x80\x97"; + static constexpr const char* info = "\xEF\x84\xA9"; + static constexpr const char* list = "\xEF\x80\xBA"; + static constexpr const char* sun = "\xEF\x86\x85"; + static constexpr const char* check = "\xEF\x95\xA0"; + static constexpr const char* music = "\xEF\x80\x81"; + static constexpr const char* tachometer = "\xEF\x8F\xBD"; + static constexpr const char* asterisk = "\xEF\x81\xA9"; + static constexpr const char* paintbrush = "\xEF\x87\xBC"; + } + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fcafcf7d26a075a56d67006354c3b090c75c54d7 --- /dev/null +++ b/src/displayapp/screens/SystemInfo.cpp @@ -0,0 +1,116 @@ +#include <libs/lvgl/lvgl.h> +#include <DisplayApp/DisplayApp.h> +#include <functional> +#include "SystemInfo.h" +#include "../../Version.h" +#include "Tile.h" + +using namespace Pinetime::Applications::Screens; + +SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::DateTime &dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog) : + Screen(app), + dateTimeController{dateTimeController}, batteryController{batteryController}, + brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog}, + screens{app, { + [this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, + [this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } + } + } {} + + +SystemInfo::~SystemInfo() { + lv_obj_clean(lv_scr_act()); +} + +bool SystemInfo::Refresh() { + screens.Refresh(); + return running; +} + +bool SystemInfo::OnButtonPushed() { + running = false; + return true; +} + +bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen1() { + auto batteryPercentF = batteryController.PercentRemaining(); + uint16_t batteryPercent = 0; + if(batteryPercentF > 100.0f) batteryPercent = 100; + else if(batteryPercentF < 0.0f) batteryPercent = 0; + + uint8_t brightness = 0; + switch(brightnessController.Level()) { + case Controllers::BrightnessController::Levels::Off: brightness = 0; break; + case Controllers::BrightnessController::Levels::Low: brightness = 1; break; + case Controllers::BrightnessController::Levels::Medium: brightness = 2; break; + case Controllers::BrightnessController::Levels::High: brightness = 3; break; + } + auto resetReason = [this]() { + switch (watchdog.ResetReason()) { + case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg"; + case Drivers::Watchdog::ResetReasons::HardReset: return "hardr"; + case Drivers::Watchdog::ResetReasons::NFC: return "nfc"; + case Drivers::Watchdog::ResetReasons::SoftReset: return "softr"; + case Drivers::Watchdog::ResetReasons::CpuLockup: return "cpulock"; + case Drivers::Watchdog::ResetReasons::SystemOff: return "off"; + case Drivers::Watchdog::ResetReasons::LpComp: return "lpcomp"; + case Drivers::Watchdog::ResetReasons::DebugInterface: return "dbg"; + case Drivers::Watchdog::ResetReasons::ResetPin: return "rst"; + default: return "?"; + } + }(); + + // uptime + static constexpr uint32_t secondsInADay = 60*60*24; + static constexpr uint32_t secondsInAnHour = 60*60; + static constexpr uint32_t secondsInAMinute = 60; + uint32_t uptimeSeconds = dateTimeController.Uptime().count(); + uint32_t uptimeDays = (uptimeSeconds / secondsInADay); + uptimeSeconds = uptimeSeconds % secondsInADay; + uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; + uptimeSeconds = uptimeSeconds % secondsInAnHour; + uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; + uptimeSeconds = uptimeSeconds % secondsInAMinute; + // TODO handle more than 100 days of uptime + + sprintf(t1, "Pinetime\n" + "Version:%ld.%ld.%ld\n" + "Build: %s\n" + " %s\n" + "Date: %02d/%02d/%04d\n" + "Time: %02d:%02d:%02d\n" + "Uptime: %02lud %02lu:%02lu:%02lu\n" + "Battery: %d%%\n" + "Backlight: %d/3\n" + "Last reset: %s\n", + Version::Major(), Version::Minor(), Version::Patch(), + __DATE__, __TIME__, + dateTimeController.Day(), static_cast<uint8_t>(dateTimeController.Month()), dateTimeController.Year(), + dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), + uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, + batteryPercent, brightness, resetReason); + + return std::unique_ptr<Screen>(new Screens::Label(app, t1)); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen2() { + auto& bleAddr = bleController.Address(); + sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x", + bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); + return std::unique_ptr<Screen>(new Screens::Label(app, t2)); +} + +std::unique_ptr<Screen> SystemInfo::CreateScreen3() { + strncpy(t3, "Hello from\nthe developper!", 27); + return std::unique_ptr<Screen>(new Screens::Label(app, t3)); +} diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..ac8abae5182d82a896caa90fb68c096b1621496c --- /dev/null +++ b/src/displayapp/screens/SystemInfo.h @@ -0,0 +1,47 @@ +#pragma once + +#include <vector> +#include <Components/Ble/NimbleController.h> +#include "Screen.h" +#include "Label.h" +#include "ScreenList.h" +#include "Gauge.h" +#include "Meter.h" +#include <functional> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class SystemInfo : public Screen { + public: + explicit SystemInfo(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog); + ~SystemInfo() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + private: + bool running = true; + + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::BrightnessController& brightnessController; + Pinetime::Controllers::Ble& bleController; + Pinetime::Drivers::WatchdogView& watchdog; + + char t1[200]; + char t2[200]; + char t3[30]; + + ScreenList<3> screens; + std::unique_ptr<Screen> CreateScreen1(); + std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); + }; + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Tab.cpp b/src/displayapp/screens/Tab.cpp new file mode 100644 index 0000000000000000000000000000000000000000..adc32578a76f112230e420e37a6bc89e7d8635e8 --- /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 0000000000000000000000000000000000000000..e16dbb962d8f777c125f3f2b24ef79d7853127d3 --- /dev/null +++ b/src/displayapp/screens/Tab.h @@ -0,0 +1,23 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.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 0000000000000000000000000000000000000000..1447d789be2b499c1397427363afd3c2e9124068 --- /dev/null +++ b/src/displayapp/screens/Tile.cpp @@ -0,0 +1,61 @@ +#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> +#include "Symbols.h" +#include "../../Version.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); +} + +Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen(app) { + for(int i = 0, appIndex = 0; i < 8; i++) { + if(i == 3) btnm_map1[i] = "\n"; + else if(i == 7) btnm_map1[i] = ""; + else { + btnm_map1[i] = applications[appIndex].icon; + apps[appIndex] = applications[appIndex].application; + appIndex++; + } + } + modal.reset(new Modal(app)); + + 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); + + btnm1->user_data = this; + lv_obj_set_event_cb(btnm1, event_handler); +} + +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) { + if(event == LV_EVENT_VALUE_CHANGED) { + app->StartApp(apps[buttonId]); + running = false; + } +} + +bool Tile::OnButtonPushed() { + app->StartApp(Apps::Clock); + running = false; + return true; +} + + diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h new file mode 100644 index 0000000000000000000000000000000000000000..3136d892526c8c837fd6f9e375736f7b72bcbf19 --- /dev/null +++ b/src/displayapp/screens/Tile.h @@ -0,0 +1,39 @@ +#pragma once + +#include <cstdint> +#include "Screen.h" +#include <bits/unique_ptr.h> +#include "Modal.h" +#include <lvgl/src/lv_core/lv_style.h> +#include <DisplayApp/Apps.h> + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tile : public Screen { + public: + struct Applications { + const char* icon; + Pinetime::Applications::Apps application; + }; + + explicit Tile(DisplayApp* app, std::array<Applications, 6>& applications); + ~Tile() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); + + private: + lv_obj_t * btnm1; + bool running = true; + + std::unique_ptr<Modal> modal; + + const char* btnm_map1[8]; + Pinetime::Applications::Apps apps[6]; + }; + } + } +} diff --git a/src/libs/lvgl/src/lv_core/lv_obj.c b/src/libs/lvgl/src/lv_core/lv_obj.c index 510a87062cc39693d97a7ae1252c6c7e394ce8f4..511e72dbcc1b487164cc4dc8bf27d79f25eea0b7 100644 --- a/src/libs/lvgl/src/lv_core/lv_obj.c +++ b/src/libs/lvgl/src/lv_core/lv_obj.c @@ -163,7 +163,7 @@ new_obj = lv_ll_ins_head(&disp->scr_ll); LV_ASSERT_MEM(new_obj); if(new_obj == NULL) return NULL; - new_obj->par = NULL; /*Screens has no a parent*/ + new_obj->par = NULL; /*screens has no a parent*/ lv_ll_init(&(new_obj->child_ll), sizeof(lv_obj_t)); /*Set the callbacks*/