From 1d3742e14f09316a1d795527713eb8f9742f0ffb Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Apr 2021 03:08:51 +0100 Subject: Big UI and navigation Rewrite new navigation add some color to the apps redesign menus new settings menu new quick settings code clean up size reduction by converting navigation images to font and more... --- src/displayapp/screens/ApplicationList.cpp | 50 ++-- src/displayapp/screens/ApplicationList.h | 14 +- src/displayapp/screens/BatteryInfo.cpp | 144 +++++++++++ src/displayapp/screens/BatteryInfo.h | 49 ++++ src/displayapp/screens/Brightness.cpp | 5 - src/displayapp/screens/Brightness.h | 4 +- src/displayapp/screens/Clock.cpp | 5 - src/displayapp/screens/Clock.h | 4 +- src/displayapp/screens/DropDownDemo.cpp | 5 - src/displayapp/screens/DropDownDemo.h | 4 +- src/displayapp/screens/FirmwareUpdate.cpp | 5 - src/displayapp/screens/FirmwareUpdate.h | 4 +- src/displayapp/screens/FirmwareValidation.cpp | 17 +- src/displayapp/screens/FirmwareValidation.h | 4 +- src/displayapp/screens/FlashLight.cpp | 79 ++++++ src/displayapp/screens/FlashLight.h | 36 +++ src/displayapp/screens/HeartRate.cpp | 36 +-- src/displayapp/screens/HeartRate.h | 10 +- src/displayapp/screens/InfiniPaint.cpp | 44 +++- src/displayapp/screens/InfiniPaint.h | 6 +- src/displayapp/screens/Label.cpp | 42 +++- src/displayapp/screens/Label.h | 17 +- src/displayapp/screens/List.cpp | 126 ++++++++++ src/displayapp/screens/List.h | 49 ++++ src/displayapp/screens/Meter.cpp | 5 - src/displayapp/screens/Meter.h | 3 +- src/displayapp/screens/Music.cpp | 5 - src/displayapp/screens/Music.h | 4 +- src/displayapp/screens/Navigation.cpp | 77 +++--- src/displayapp/screens/Navigation.h | 272 +++++++-------------- src/displayapp/screens/Notifications.cpp | 48 ++-- src/displayapp/screens/Notifications.h | 3 +- src/displayapp/screens/Paddle.cpp | 13 +- src/displayapp/screens/Paddle.h | 6 +- src/displayapp/screens/Screen.h | 2 + src/displayapp/screens/ScreenList.h | 7 +- src/displayapp/screens/StopWatch.cpp | 28 ++- src/displayapp/screens/StopWatch.h | 2 +- src/displayapp/screens/Symbols.h | 13 + src/displayapp/screens/SystemInfo.cpp | 129 +++++++--- src/displayapp/screens/SystemInfo.h | 11 +- src/displayapp/screens/Tile.cpp | 124 ++++++++-- src/displayapp/screens/Tile.h | 31 ++- src/displayapp/screens/Twos.cpp | 5 - src/displayapp/screens/Twos.h | 4 +- src/displayapp/screens/WatchFaceDigital.cpp | 6 - src/displayapp/screens/WatchFaceDigital.h | 4 +- src/displayapp/screens/settings/QuickSettings.cpp | 177 ++++++++++++++ src/displayapp/screens/settings/QuickSettings.h | 57 +++++ src/displayapp/screens/settings/SettingDisplay.cpp | 109 +++++++++ src/displayapp/screens/settings/SettingDisplay.h | 30 +++ .../screens/settings/SettingTimeFormat.cpp | 89 +++++++ .../screens/settings/SettingTimeFormat.h | 30 +++ src/displayapp/screens/settings/SettingWakeUp.cpp | 107 ++++++++ src/displayapp/screens/settings/SettingWakeUp.h | 30 +++ .../screens/settings/SettingWatchFace.cpp | 88 +++++++ src/displayapp/screens/settings/SettingWatchFace.h | 30 +++ src/displayapp/screens/settings/Settings.cpp | 69 ++++++ src/displayapp/screens/settings/Settings.h | 37 +++ 59 files changed, 1922 insertions(+), 492 deletions(-) create mode 100644 src/displayapp/screens/BatteryInfo.cpp create mode 100644 src/displayapp/screens/BatteryInfo.h create mode 100644 src/displayapp/screens/FlashLight.cpp create mode 100644 src/displayapp/screens/FlashLight.h create mode 100644 src/displayapp/screens/List.cpp create mode 100644 src/displayapp/screens/List.h create mode 100644 src/displayapp/screens/settings/QuickSettings.cpp create mode 100644 src/displayapp/screens/settings/QuickSettings.h create mode 100644 src/displayapp/screens/settings/SettingDisplay.cpp create mode 100644 src/displayapp/screens/settings/SettingDisplay.h create mode 100644 src/displayapp/screens/settings/SettingTimeFormat.cpp create mode 100644 src/displayapp/screens/settings/SettingTimeFormat.h create mode 100644 src/displayapp/screens/settings/SettingWakeUp.cpp create mode 100644 src/displayapp/screens/settings/SettingWakeUp.h create mode 100644 src/displayapp/screens/settings/SettingWatchFace.cpp create mode 100644 src/displayapp/screens/settings/SettingWatchFace.h create mode 100644 src/displayapp/screens/settings/Settings.cpp create mode 100644 src/displayapp/screens/settings/Settings.h (limited to 'src/displayapp/screens') diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 60039045..db244822 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -9,9 +9,13 @@ using namespace Pinetime::Applications::Screens; ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp *app, - Pinetime::Controllers::Settings &settingsController) : + Pinetime::Controllers::Settings &settingsController, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController) : Screen(app), settingsController{settingsController}, + batteryController{batteryController}, + dateTimeController{dateTimeController}, screens{app, settingsController.GetAppMenu(), { @@ -33,47 +37,41 @@ bool ApplicationList::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 ApplicationList::CreateScreen1() { std::array applications { - {{Symbols::clock, Apps::Clock}, - {Symbols::music, Apps::Music}, - {Symbols::sun, Apps::Brightness}, - {Symbols::list, Apps::SysInfo}, - {Symbols::check, Apps::FirmwareValidation}, - {Symbols::heartBeat, Apps::HeartRate} + { + {Symbols::stopWatch, Apps::StopWatch}, + {Symbols::music, Apps::Music}, + {Symbols::map, Apps::Navigation}, + {Symbols::shoe, Apps::Clock}, + {Symbols::heartBeat, Apps::HeartRate}, + {"", Apps::None}, } - - }; - return std::make_unique(0, app, settingsController, applications); + return std::make_unique(0, 2, app, settingsController, batteryController, dateTimeController, applications); } std::unique_ptr ApplicationList::CreateScreen2() { std::array applications { - {{Symbols::map, Apps::Navigation}, - {Symbols::stopWatch, Apps::StopWatch}, - {Symbols::paintbrush, Apps::Paint}, - {Symbols::info, Apps::Notifications}, - {Symbols::paddle, Apps::Paddle}, - {"2", Apps::Twos} + { + {Symbols::paintbrush, Apps::Paint}, + {Symbols::paddle, Apps::Paddle}, + {"2", Apps::Twos}, + {"", Apps::None}, + {"", Apps::None}, + {"", Apps::None}, } }; - return std::make_unique(1, app, settingsController, applications); + return std::make_unique(1, 2, app, settingsController, batteryController, dateTimeController, applications); } -std::unique_ptr ApplicationList::CreateScreen3() { +/*std::unique_ptr ApplicationList::CreateScreen3() { std::array applications { {{"A", Apps::Meter}, {"B", Apps::Navigation}, @@ -84,6 +82,6 @@ std::unique_ptr ApplicationList::CreateScreen3() { } }; - return std::make_unique(2, app, settingsController, applications); -} + return std::make_unique(2, 3, app, settingsController, batteryController, dateTimeController, applications); +}*/ diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 0a0c6388..e334ccde 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -4,6 +4,9 @@ #include "Screen.h" #include "ScreenList.h" +#include "components/datetime/DateTimeController.h" +#include "components/settings/Settings.h" +#include "components/battery/BatteryController.h" namespace Pinetime { namespace Applications { @@ -11,21 +14,22 @@ namespace Pinetime { class ApplicationList : public Screen { public: explicit ApplicationList(DisplayApp* app, - Pinetime::Controllers::Settings &settingsController); + Pinetime::Controllers::Settings &settingsController, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController); ~ApplicationList() override; bool Refresh() override; - bool OnButtonPushed() override; bool OnTouchEvent(TouchEvents event) override; private: Controllers::Settings& settingsController; - - bool running = true; + Pinetime::Controllers::Battery& batteryController; + Controllers::DateTime& dateTimeController; ScreenList<2> screens; std::unique_ptr CreateScreen1(); std::unique_ptr CreateScreen2(); - std::unique_ptr CreateScreen3(); + //std::unique_ptr CreateScreen3(); }; } } diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp new file mode 100644 index 00000000..ae39138f --- /dev/null +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -0,0 +1,144 @@ +#include "BatteryInfo.h" +#include "../DisplayApp.h" +#include "components/battery/BatteryController.h" + +using namespace Pinetime::Applications::Screens; + +static void lv_update_task(struct _lv_task_t *task) { + auto user_data = static_cast(task->user_data); + user_data->UpdateScreen(); +} + +static void lv_anim_task(struct _lv_task_t *task) { + auto user_data = static_cast(task->user_data); + user_data->UpdateAnim(); +} + +BatteryInfo::BatteryInfo( + Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::Battery& batteryController) : + Screen(app), + batteryController{batteryController} +{ + + batteryPercent = batteryController.PercentRemaining(); + batteryVoltage = batteryController.Voltage(); + + charging_bar = lv_bar_create(lv_scr_act(), nullptr); + lv_obj_set_size(charging_bar, 200, 15); + lv_bar_set_range(charging_bar, 0, 100); + lv_obj_align(charging_bar, nullptr, LV_ALIGN_CENTER, 0, 10); + lv_bar_set_anim_time(charging_bar, 2000); + lv_obj_set_style_local_radius(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, lv_color_hex(0x222222)); + lv_obj_set_style_local_bg_opa(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_OPA_100); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); + lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_OFF); + + status = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(status,"Reading Battery status"); + lv_label_set_align(status, LV_LABEL_ALIGN_CENTER); + lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20); + + percent = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(percent, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); + if ( batteryPercent >= 0) { + lv_label_set_text_fmt(percent,"%02i%%", batteryPercent); + } else { + lv_label_set_text(percent,"--%"); + } + lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT); + lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60); + + // hack to not use the flot functions from printf + uint8_t batteryVoltageBytes[2]; + batteryVoltageBytes[1] = static_cast(batteryVoltage); //truncate whole numbers + batteryVoltageBytes[0] = static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); //remove whole part of flt and shift 2 places over + // + + voltage = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xC6A600)); + lv_label_set_text_fmt(voltage,"%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]); + lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER); + lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95); + + lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + 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_static(backgroundLabel, ""); + + taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_LOW, this); + taskAnim = lv_task_create(lv_anim_task, 1000, LV_TASK_PRIO_LOW, this); + UpdateScreen(); +} + + +BatteryInfo::~BatteryInfo() { + lv_task_del(taskUpdate); + lv_task_del(taskAnim); + lv_obj_clean(lv_scr_act()); +} + +void BatteryInfo::UpdateAnim() { + batteryPercent = batteryController.PercentRemaining(); + + if ( batteryPercent >= 0 ) { + if ( batteryController.IsCharging() ) { + animation +=1; + if (animation >= 100) { + animation = 0; + } + + } else { + if (animation > batteryPercent) { + animation--; + } + if (animation < batteryPercent) { + animation++; + } + } + + lv_bar_set_value(charging_bar, animation, LV_ANIM_OFF); + } +} + +void BatteryInfo::UpdateScreen() { + + batteryController.Update(); + + batteryPercent = batteryController.PercentRemaining(); + batteryVoltage = batteryController.Voltage(); + + if ( batteryPercent >= 0 ) { + if ( batteryController.IsCharging() ) { + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); + lv_label_set_text_static(status,"Battery charging"); + + } else { + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); + lv_label_set_text_static(status,"Battery discharging"); + } + + lv_label_set_text_fmt(percent,"%02i%%", batteryPercent); + + } else { + lv_label_set_text_static(status,"Reading Battery status"); + lv_label_set_text(percent,"--%"); + } + + lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20); + // hack to not use the flot functions from printf + uint8_t batteryVoltageBytes[2]; + batteryVoltageBytes[1] = static_cast(batteryVoltage); //truncate whole numbers + batteryVoltageBytes[0] = static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); //remove whole part of flt and shift 2 places over + // + lv_label_set_text_fmt(voltage,"%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]); + +} + +bool BatteryInfo::Refresh() { + + return running; +} + diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h new file mode 100644 index 00000000..206f1ab0 --- /dev/null +++ b/src/displayapp/screens/BatteryInfo.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include + + +namespace Pinetime { + namespace Controllers { + class Battery; + } + + namespace Applications { + namespace Screens { + + class BatteryInfo : public Screen{ + public: + BatteryInfo(DisplayApp* app, + Pinetime::Controllers::Battery& batteryController); + ~BatteryInfo() override; + + bool Refresh() override; + + + void UpdateScreen(); + void UpdateAnim(); + + private: + + Pinetime::Controllers::Battery& batteryController; + + lv_obj_t* voltage; + lv_obj_t* percent; + lv_obj_t* charging_bar; + lv_obj_t* status; + + lv_task_t* taskUpdate; + lv_task_t* taskAnim; + + int8_t animation = 0; + int8_t batteryPercent = -1; + float batteryVoltage = 0.0f; + + }; + } + } +} diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 36820417..38469cf5 100644 --- a/src/displayapp/screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -33,11 +33,6 @@ 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"; diff --git a/src/displayapp/screens/Brightness.h b/src/displayapp/screens/Brightness.h index 7aee968e..60b33cfd 100644 --- a/src/displayapp/screens/Brightness.h +++ b/src/displayapp/screens/Brightness.h @@ -13,12 +13,12 @@ namespace Pinetime { 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; diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 69180370..d8cc573a 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -54,11 +54,6 @@ bool Clock::Refresh() { return running; } -bool Clock::OnButtonPushed() { - running = false; - return false; -} - bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 964ccbf6..a5163655 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -33,7 +33,7 @@ namespace Pinetime { ~Clock() override; bool Refresh() override; - bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; private: @@ -54,7 +54,7 @@ namespace Pinetime { //std::unique_ptr WatchFaceMinimalScreen(); //std::unique_ptr WatchFaceCustomScreen(); - bool running = true; + }; } diff --git a/src/displayapp/screens/DropDownDemo.cpp b/src/displayapp/screens/DropDownDemo.cpp index 944c63bb..c3ec5d7d 100644 --- a/src/displayapp/screens/DropDownDemo.cpp +++ b/src/displayapp/screens/DropDownDemo.cpp @@ -44,11 +44,6 @@ bool DropDownDemo::Refresh() { 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). diff --git a/src/displayapp/screens/DropDownDemo.h b/src/displayapp/screens/DropDownDemo.h index d66aeed0..821ae528 100644 --- a/src/displayapp/screens/DropDownDemo.h +++ b/src/displayapp/screens/DropDownDemo.h @@ -14,12 +14,12 @@ namespace Pinetime { ~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 index 2f0bb5ad..e894850e 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -65,11 +65,6 @@ bool FirmwareUpdate::DisplayProgression() const { 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!#"); diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index 262e7afb..27be3631 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -16,7 +16,7 @@ namespace Pinetime { ~FirmwareUpdate() override; bool Refresh() override; - bool OnButtonPushed() override; + private: enum class States { Idle, Running, Validated, Error }; @@ -25,7 +25,7 @@ namespace Pinetime { lv_obj_t* percentLabel; lv_obj_t* titleLabel; mutable char percentStr[10]; - bool running = true; + States state; bool DisplayProgression() const; diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index adacd8cd..f78b1a67 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -46,20 +46,20 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); buttonValidate->user_data = this; lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); + lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x009900)); labelButtonValidate = lv_label_create(buttonValidate, nullptr); - lv_label_set_recolor(labelButtonValidate, true); - lv_label_set_text(labelButtonValidate, "#00ff00 Validate#"); + lv_label_set_text_static(labelButtonValidate, "Validate"); buttonReset = lv_btn_create(lv_scr_act(), nullptr); buttonReset->user_data = this; lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x990000)); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); - + labelButtonReset = lv_label_create(buttonReset, nullptr); - lv_label_set_recolor(labelButtonReset, true); - lv_label_set_text(labelButtonReset, "#ff0000 Reset#"); - } + lv_label_set_text_static(labelButtonReset, "Reset"); + } } @@ -71,11 +71,6 @@ 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(); diff --git a/src/displayapp/screens/FirmwareValidation.h b/src/displayapp/screens/FirmwareValidation.h index 9eea86bd..b83f8238 100644 --- a/src/displayapp/screens/FirmwareValidation.h +++ b/src/displayapp/screens/FirmwareValidation.h @@ -17,7 +17,7 @@ namespace Pinetime { ~FirmwareValidation() override; bool Refresh() override; - bool OnButtonPushed() override; + void OnButtonEvent(lv_obj_t *object, lv_event_t event); @@ -32,7 +32,7 @@ namespace Pinetime { lv_obj_t* labelButtonValidate; lv_obj_t* buttonReset; lv_obj_t* labelButtonReset; - bool running = true; + }; } } diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp new file mode 100644 index 00000000..0ef1b333 --- /dev/null +++ b/src/displayapp/screens/FlashLight.cpp @@ -0,0 +1,79 @@ +#include "FlashLight.h" +#include "../DisplayApp.h" +#include "Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t * obj, lv_event_t event) { + FlashLight* screen = static_cast(obj->user_data); + screen->OnClickEvent(obj, event); + } +} + +FlashLight::FlashLight( + Pinetime::Applications::DisplayApp *app, + System::SystemTask &systemTask, + Controllers::BrightnessController& brightness) : + Screen(app), + systemTask{systemTask}, + brightness{brightness} + +{ + brightness.Backup(); + brightness.Set(Controllers::BrightnessController::Levels::High); + // Set the background + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFFFF)); + + flashLight = lv_label_create(lv_scr_act(), NULL); + lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_text_font(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + lv_label_set_text_static(flashLight, Symbols::highlight); + lv_obj_align(flashLight, NULL, LV_ALIGN_CENTER, 0, 0); + + backgroundAction = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(backgroundAction, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundAction, 240, 240); + lv_obj_set_pos(backgroundAction, 0, 0); + lv_label_set_text(backgroundAction, ""); + lv_obj_set_click(backgroundAction, true); + backgroundAction->user_data = this; + lv_obj_set_event_cb(backgroundAction, event_handler); + + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + +} + + +FlashLight::~FlashLight() { + lv_obj_clean(lv_scr_act()); + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + brightness.Restore(); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); +} + +void FlashLight::OnClickEvent(lv_obj_t *obj, lv_event_t event) { + if(obj == backgroundAction) { + if (event == LV_EVENT_CLICKED) { + isOn = !isOn; + + if ( isOn ) { + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFFFF)); + lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + } else { + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); + lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFFFF)); + } + + } + } +} + +bool FlashLight::Refresh() { + return running; +} + +bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return true; +} + diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h new file mode 100644 index 00000000..c62472ab --- /dev/null +++ b/src/displayapp/screens/FlashLight.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include "Screen.h" +#include +#include "systemtask/SystemTask.h" +#include "components/brightness/BrightnessController.h" + + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class FlashLight : public Screen{ + public: + FlashLight(DisplayApp* app, System::SystemTask &systemTask, Controllers::BrightnessController& brightness); + ~FlashLight() override; + + bool Refresh() override; + + bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; + void OnClickEvent(lv_obj_t *obj, lv_event_t event); + + private: + Pinetime::System::SystemTask& systemTask; + Controllers::BrightnessController& brightness; + + lv_obj_t* flashLight; + lv_obj_t* backgroundAction; + bool isOn = true; + + }; + } + } +} diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 401d57d9..0bc3c352 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -27,26 +27,28 @@ namespace { } } -HeartRate::HeartRate(Pinetime::Applications::DisplayApp *app, Controllers::HeartRateController& heartRateController) : Screen(app), heartRateController{heartRateController} { +HeartRate::HeartRate(Pinetime::Applications::DisplayApp *app, Controllers::HeartRateController& heartRateController, System::SystemTask &systemTask) : + Screen(app), heartRateController{heartRateController}, systemTask{systemTask} { - label_hr = lv_label_create(lv_scr_act(), NULL); + label_hr = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); - - lv_obj_align(label_hr, lv_scr_act(), LV_ALIGN_CENTER, -70, -40); + lv_obj_set_style_local_text_font(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_label_set_text(label_hr, "000"); + lv_obj_align(label_hr, nullptr, LV_ALIGN_CENTER, 0, -40); - label_bpm = lv_label_create(lv_scr_act(), NULL); - lv_label_set_text(label_bpm, "Heart rate BPM"); + label_bpm = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(label_bpm, "Heart rate BPM"); lv_obj_align(label_bpm, label_hr, LV_ALIGN_OUT_TOP_MID, 0, -20); - label_status = lv_label_create(lv_scr_act(), NULL); + label_status = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(label_status, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); lv_label_set_text(label_status, ToString(Pinetime::Controllers::HeartRateController::States::NotEnoughData)); lv_obj_align(label_status, label_hr, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); - btn_startStop = lv_btn_create(lv_scr_act(), NULL); + btn_startStop = lv_btn_create(lv_scr_act(), nullptr); btn_startStop->user_data = this; lv_obj_set_height(btn_startStop, 50); lv_obj_set_event_cb(btn_startStop, btnStartStopEventHandler); @@ -58,21 +60,20 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp *app, Controllers::Heart HeartRate::~HeartRate() { lv_obj_clean(lv_scr_act()); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); } bool HeartRate::Refresh() { - char hr[4]; auto state = heartRateController.State(); switch(state) { case Controllers::HeartRateController::States::NoTouch: case Controllers::HeartRateController::States::NotEnoughData: - case Controllers::HeartRateController::States::Stopped: + //case Controllers::HeartRateController::States::Stopped: lv_label_set_text(label_hr, "000"); break; default: - sprintf(hr, "%03d", heartRateController.HeartRate()); - lv_label_set_text(label_hr, hr); + lv_label_set_text_fmt(label_hr, "%03d", heartRateController.HeartRate()); } lv_label_set_text(label_status, ToString(state)); @@ -81,20 +82,19 @@ bool HeartRate::Refresh() { return running; } -bool HeartRate::OnButtonPushed() { - running = false; - return true; -} - void HeartRate::OnStartStopEvent(lv_event_t event) { if (event == LV_EVENT_CLICKED) { if(heartRateController.State() == Controllers::HeartRateController::States::Stopped) { heartRateController.Start(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); } else { heartRateController.Stop(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); } } } diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index b9424998..c8f36999 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -4,6 +4,7 @@ #include #include "Screen.h" #include +#include "systemtask/SystemTask.h" #include #include @@ -16,25 +17,24 @@ namespace Pinetime { class HeartRate : public Screen{ public: - HeartRate(DisplayApp* app, Controllers::HeartRateController& HeartRateController); + HeartRate(DisplayApp* app, Controllers::HeartRateController& HeartRateController, System::SystemTask &systemTask); ~HeartRate() override; bool Refresh() override; - bool OnButtonPushed() override; + void OnStartStopEvent(lv_event_t event); private: Controllers::HeartRateController& heartRateController; + Pinetime::System::SystemTask& systemTask; void UpdateStartStopButton(bool isRunning); lv_obj_t* label_hr; lv_obj_t* label_bpm; lv_obj_t* label_status; - lv_style_t labelBigStyle; - lv_style_t* labelStyle; lv_obj_t* btn_startStop; lv_obj_t* label_startStop; - bool running = true; + }; } diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index 6d1f75b8..b2f0fdfe 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -6,7 +6,7 @@ using namespace Pinetime::Applications::Screens; 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); + std::fill(b, b + bufferSize, selectColor); } InfiniPaint::~InfiniPaint() { @@ -19,12 +19,44 @@ bool InfiniPaint::Refresh() { return running; } -bool InfiniPaint::OnButtonPushed() { - running = false; - return true; -} - bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch(event) { + case Pinetime::Applications::TouchEvents::LongTap: + switch (color) { + case 0: + selectColor = LV_COLOR_MAGENTA; + break; + case 1: + selectColor = LV_COLOR_GREEN; + break; + case 2: + selectColor = LV_COLOR_WHITE; + break; + case 3: + selectColor = LV_COLOR_RED; + break; + case 4: + selectColor = LV_COLOR_CYAN; + break; + case 5: + selectColor = LV_COLOR_YELLOW; + break; + case 6: + selectColor = LV_COLOR_BLUE; + break; + case 7: + selectColor = LV_COLOR_BLACK; + break; + + default: + color = 0; + break; + } + + std::fill(b, b + bufferSize, selectColor); + color++; + return true; + } return true; } diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index 9a7ac076..da9c39ba 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -19,8 +19,6 @@ namespace Pinetime { bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; @@ -31,7 +29,9 @@ namespace Pinetime { static constexpr uint16_t height = 10; static constexpr uint16_t bufferSize = width * height; lv_color_t b[bufferSize]; - bool running = true; + lv_color_t selectColor = LV_COLOR_WHITE; + uint8_t color = 2; + }; } } diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 4be7742a..cc268775 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -2,13 +2,45 @@ 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(), nullptr); - lv_label_set_align(label, LV_LABEL_ALIGN_LEFT); - lv_obj_set_size(label, 240, 240); - lv_label_set_text(label, text); +Label::Label(uint8_t screenID, uint8_t numScreens, + Pinetime::Applications::DisplayApp *app, lv_obj_t* labelText) : + Screen(app), + labelText{labelText} { + + if ( numScreens > 1 ) { + pageIndicatorBasePoints[0].x = 240 - 1; + pageIndicatorBasePoints[0].y = 6; + pageIndicatorBasePoints[1].x = 240 - 1; + pageIndicatorBasePoints[1].y = 240 - 6; + + pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); + lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); + + + uint16_t indicatorSize = 228 / numScreens; + uint16_t indicatorPos = indicatorSize * screenID; + + pageIndicatorPoints[0].x = 240 - 1; + pageIndicatorPoints[0].y = (6 + indicatorPos); + pageIndicatorPoints[1].x = 240 - 1; + pageIndicatorPoints[1].y = (6 + indicatorPos) + indicatorSize; + + pageIndicator = lv_line_create(lv_scr_act(), NULL); + lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); + } + } Label::~Label() { lv_obj_clean(lv_scr_act()); } + +bool Label::Refresh() { + return running; +} diff --git a/src/displayapp/screens/Label.h b/src/displayapp/screens/Label.h index dba89bbf..a1bcba95 100644 --- a/src/displayapp/screens/Label.h +++ b/src/displayapp/screens/Label.h @@ -9,13 +9,22 @@ namespace Pinetime { class Label : public Screen { public: - Label(DisplayApp* app, const char* text); + Label( uint8_t screenID, uint8_t numScreens, + DisplayApp* app, lv_obj_t* labelText ); ~Label() override; - bool Refresh() override {return false;} + + bool Refresh() override; + private: - lv_obj_t * label = nullptr; - const char* text = nullptr; + + bool running = true; + + lv_obj_t * labelText = nullptr; + lv_point_t pageIndicatorBasePoints[2]; + lv_point_t pageIndicatorPoints[2]; + lv_obj_t* pageIndicatorBase; + lv_obj_t* pageIndicator; }; } } diff --git a/src/displayapp/screens/List.cpp b/src/displayapp/screens/List.cpp new file mode 100644 index 00000000..87cfa6db --- /dev/null +++ b/src/displayapp/screens/List.cpp @@ -0,0 +1,126 @@ +#include "List.h" +#include "../DisplayApp.h" +#include "Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) { + List* screen = static_cast(obj->user_data); + screen->OnButtonEvent(obj, event); + } + +} + +List::List(uint8_t screenID, uint8_t numScreens, + DisplayApp* app, + Controllers::Settings &settingsController, + std::array& applications) : + Screen(app), + settingsController{settingsController} +{ + + // Set the background to Black + lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0)); + + settingsController.SetSettingsMenu(screenID); + + if ( numScreens > 1 ) { + pageIndicatorBasePoints[0].x = 240 - 1; + pageIndicatorBasePoints[0].y = 6; + pageIndicatorBasePoints[1].x = 240 - 1; + pageIndicatorBasePoints[1].y = 240 - 6; + + pageIndicatorBase = lv_line_create(lv_scr_act(), NULL); + lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); + + + uint16_t indicatorSize = 228 / numScreens; + uint16_t indicatorPos = indicatorSize * screenID; + + pageIndicatorPoints[0].x = 240 - 1; + pageIndicatorPoints[0].y = 6 + indicatorPos; + pageIndicatorPoints[1].x = 240 - 1; + pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + + pageIndicator = lv_line_create(lv_scr_act(), NULL); + lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); + } + + + lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + + //lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 0, 0); + lv_obj_set_width(container1, LV_HOR_RES - 15); + lv_obj_set_height(container1, LV_VER_RES); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t * labelBt; + lv_obj_t * labelBtIco; + + for(int i = 0; i < MAXLISTITEMS; i++) { + apps[i] = applications[i].application; + if ( applications[i].application != Apps::None) { + + itemApps[i] = lv_btn_create(container1, nullptr); + lv_obj_set_style_local_bg_opa(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); + + lv_obj_set_width(itemApps[i], LV_HOR_RES - 25); + lv_obj_set_height(itemApps[i], 52); + lv_obj_set_event_cb(itemApps[i], ButtonEventHandler); + lv_btn_set_layout(itemApps[i], LV_LAYOUT_ROW_MID); + itemApps[i]->user_data = this; + + labelBtIco = lv_label_create(itemApps[i], nullptr); + lv_obj_set_style_local_text_color(labelBtIco, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + lv_label_set_text_static(labelBtIco, applications[i].icon); + + labelBt = lv_label_create(itemApps[i], nullptr); + lv_label_set_text_fmt(labelBt, " %s", applications[i].name); + + } + } + + lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text_static(backgroundLabel, ""); + +} + +List::~List() { + lv_obj_clean(lv_scr_act()); +} + +bool List::Refresh() { + + return running; +} + +void List::OnButtonEvent(lv_obj_t * object, lv_event_t event) { + if ( event == LV_EVENT_RELEASED ) { + for(int i = 0; i < MAXLISTITEMS; i++) { + if ( apps[i] != Apps::None && object == itemApps[i] ) { + app->StartApp(apps[i], DisplayApp::FullRefreshDirections::Down); + running = false; + return; + } + } + } +} + diff --git a/src/displayapp/screens/List.h b/src/displayapp/screens/List.h new file mode 100644 index 00000000..739a91c3 --- /dev/null +++ b/src/displayapp/screens/List.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include "../Apps.h" +#include "components/settings/Settings.h" + +#define MAXLISTITEMS 4 + +namespace Pinetime { + namespace Applications { + namespace Screens { + class List : public Screen { + public: + struct Applications { + const char* icon; + const char* name; + Pinetime::Applications::Apps application; + }; + + explicit List(uint8_t screenID, uint8_t numScreens, + DisplayApp* app, + Controllers::Settings& settingsController, + std::array& applications); + ~List() override; + + bool Refresh() override; + + + void OnButtonEvent(lv_obj_t *object, lv_event_t event); + + private: + + Controllers::Settings& settingsController; + Pinetime::Applications::Apps apps[MAXLISTITEMS]; + + lv_obj_t * itemApps[MAXLISTITEMS]; + + lv_point_t pageIndicatorBasePoints[2]; + lv_point_t pageIndicatorPoints[2]; + lv_obj_t* pageIndicatorBase; + lv_obj_t* pageIndicator; + + }; + } + } +} diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index 58a0636f..2c042cac 100644 --- a/src/displayapp/screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -36,8 +36,3 @@ bool Meter::Refresh() { return running; } - -bool Meter::OnButtonPushed() { - running = false; - return true; -} diff --git a/src/displayapp/screens/Meter.h b/src/displayapp/screens/Meter.h index 86888dda..6a1fc3bf 100644 --- a/src/displayapp/screens/Meter.h +++ b/src/displayapp/screens/Meter.h @@ -15,14 +15,13 @@ namespace Pinetime { ~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/Music.cpp b/src/displayapp/screens/Music.cpp index b68f3781..85d35c96 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -134,11 +134,6 @@ Music::~Music() { lv_obj_clean(lv_scr_act()); } -bool Music::OnButtonPushed() { - running = false; - return true; -} - bool Music::Refresh() { if (artist != musicService.getArtist()) { artist = musicService.getArtist(); diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index 66bde21b..096ab74d 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -37,7 +37,7 @@ namespace Pinetime { bool Refresh() override; - bool OnButtonPushed() override; + void OnObjectEvent(lv_obj_t *obj, lv_event_t event); @@ -81,7 +81,7 @@ namespace Pinetime { bool playing; /** Watchapp */ - bool running = true; + }; } } diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index 9fbcbe57..cfe60e23 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -22,16 +22,7 @@ using namespace Pinetime::Applications::Screens; -/** - * Set the pixel array to display by the image - * This just calls lv_img_set_src but adds type safety - * - * @param img pointer to an image object - * @param data the image array - */ -inline void lv_img_set_src_arr(lv_obj_t *img, const lv_img_dsc_t *src_img) { - lv_img_set_src(img, src_img); -} +LV_FONT_DECLARE(lv_font_navi_80) /** * Navigation watchapp @@ -39,36 +30,37 @@ inline void lv_img_set_src_arr(lv_obj_t *img, const lv_img_dsc_t *src_img) { */ Navigation::Navigation(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::NavigationService &nav) : Screen(app), navService(nav) { - constexpr uint8_t FONT_HEIGHT = 12; - constexpr uint8_t LINE_PAD = 15; - constexpr int8_t MIDDLE_OFFSET = -25; + imgFlag = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_navi_80); + lv_obj_set_style_local_text_color(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN); + lv_label_set_text(imgFlag, iconForName("flag")); + lv_obj_align(imgFlag, nullptr, LV_ALIGN_CENTER, 0, -60); - imgFlag = lv_img_create(lv_scr_act(), nullptr); - lv_img_set_src_arr(imgFlag, &flag); - lv_obj_align(imgFlag, nullptr, LV_ALIGN_IN_TOP_MID, 0, 15); txtNarrative = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(txtNarrative, LV_LABEL_LONG_SROLL); - lv_obj_align(txtNarrative, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 1 * FONT_HEIGHT); - lv_label_set_text(txtNarrative, "Narrative"); - lv_label_set_align(txtNarrative, LV_LABEL_ALIGN_CENTER); - lv_label_set_anim_speed(txtNarrative, 15); + lv_label_set_long_mode(txtNarrative, LV_LABEL_LONG_BREAK); lv_obj_set_width(txtNarrative, LV_HOR_RES); + lv_label_set_text(txtNarrative, "Welcome to navigation!"); + lv_label_set_align(txtNarrative, LV_LABEL_ALIGN_CENTER); + lv_obj_align(txtNarrative, nullptr, LV_ALIGN_CENTER, 0, 10); txtManDist = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(txtManDist, LV_LABEL_LONG_SROLL); - lv_obj_align(txtManDist, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 2 * FONT_HEIGHT + LINE_PAD); - lv_label_set_text(txtManDist, "0M"); - lv_label_set_align(txtManDist, LV_LABEL_ALIGN_CENTER); + lv_label_set_long_mode(txtManDist, LV_LABEL_LONG_BREAK); + lv_obj_set_style_local_text_color(txtManDist, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); lv_obj_set_width(txtManDist, LV_HOR_RES); + lv_label_set_text(txtManDist, "--M"); + lv_label_set_align(txtManDist, LV_LABEL_ALIGN_CENTER); + lv_obj_align(txtManDist, nullptr, LV_ALIGN_CENTER, 0, 60); //Route Progress - barProgress = lv_bar_create(lv_scr_act(), NULL); + barProgress = lv_bar_create(lv_scr_act(), nullptr); lv_obj_set_size(barProgress, 200, 20); - lv_obj_align(barProgress, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + lv_obj_align(barProgress, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, -10); + lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_BG, LV_STATE_DEFAULT, lv_color_hex(0x222222)); + lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, LV_COLOR_ORANGE); lv_bar_set_anim_time(barProgress, 500); lv_bar_set_range(barProgress, 0, 100); - lv_bar_set_value(barProgress, 0, LV_ANIM_ON); + lv_bar_set_value(barProgress, 0, LV_ANIM_OFF); } Navigation::~Navigation() { @@ -79,8 +71,8 @@ bool Navigation::Refresh() { if (m_flag != navService.getFlag()) { m_flag = navService.getFlag(); - - lv_img_set_src_arr(imgFlag, iconForName(m_flag)); + lv_label_set_text(imgFlag, iconForName(m_flag)); + //lv_img_set_src_arr(imgFlag, iconForName(m_flag)); } if (m_narrative != navService.getNarrative()) { @@ -95,23 +87,22 @@ bool Navigation::Refresh() { if (m_progress != navService.getProgress()) { m_progress = navService.getProgress(); - lv_bar_set_value(barProgress, m_progress, LV_ANIM_ON); + lv_bar_set_value(barProgress, m_progress, LV_ANIM_OFF); + if ( m_progress > 90 ) { + lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, LV_COLOR_RED); + } else { + lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC , LV_STATE_DEFAULT, LV_COLOR_ORANGE); + } } return running; } -bool Navigation::OnButtonPushed() { - running = false; - return true; -} - -const lv_img_dsc_t* Navigation::iconForName(std::string icon) -{ - for (auto iter : m_iconMap) { - if (iter.first == icon) { - return iter.second; - } +const char* Navigation::iconForName(std::string icon) { + for (auto iter : m_iconMap) { + if (iter.first == icon) { + return iter.second; } - return &invalid; + } + return "\xEE\xA4\x90"; } diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index 9fdd37d9..53108f98 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -22,94 +22,7 @@ #include #include "Screen.h" #include -#include -#include "displayapp/icons/navigation/arrive-left.c" -#include "displayapp/icons/navigation/arrive-right.c" -#include "displayapp/icons/navigation/arrive-straight.c" -#include "displayapp/icons/navigation/arrive.c" -#include "displayapp/icons/navigation/close.c" -#include "displayapp/icons/navigation/continue-left.c" -#include "displayapp/icons/navigation/continue-right.c" -#include "displayapp/icons/navigation/continue-slight-left.c" -#include "displayapp/icons/navigation/continue-slight-right.c" -#include "displayapp/icons/navigation/continue-straight.c" -#include "displayapp/icons/navigation/continue-uturn.c" -#include "displayapp/icons/navigation/continue.c" -#include "displayapp/icons/navigation/depart-left.c" -#include "displayapp/icons/navigation/depart-right.c" -#include "displayapp/icons/navigation/depart-straight.c" -#include "displayapp/icons/navigation/end-of-road-left.c" -#include "displayapp/icons/navigation/end-of-road-right.c" -#include "displayapp/icons/navigation/ferry.c" -#include "displayapp/icons/navigation/flag.c" -#include "displayapp/icons/navigation/fork-left.c" -#include "displayapp/icons/navigation/fork-right.c" -#include "displayapp/icons/navigation/fork-slight-left.c" -#include "displayapp/icons/navigation/fork-slight-right.c" -#include "displayapp/icons/navigation/fork-straight.c" -#include "displayapp/icons/navigation/invalid.c" -#include "displayapp/icons/navigation/invalid-left.c" -#include "displayapp/icons/navigation/invalid-right.c" -#include "displayapp/icons/navigation/invalid-slight-left.c" -#include "displayapp/icons/navigation/invalid-slight-right.c" -#include "displayapp/icons/navigation/invalid-straight.c" -#include "displayapp/icons/navigation/invalid-uturn.c" -#include "displayapp/icons/navigation/merge-left.c" -#include "displayapp/icons/navigation/merge-right.c" -#include "displayapp/icons/navigation/merge-slight-left.c" -#include "displayapp/icons/navigation/merge-slight-right.c" -#include "displayapp/icons/navigation/merge-straight.c" -#include "displayapp/icons/navigation/new-name-left.c" -#include "displayapp/icons/navigation/new-name-right.c" -#include "displayapp/icons/navigation/new-name-sharp-left.c" -#include "displayapp/icons/navigation/new-name-sharp-right.c" -#include "displayapp/icons/navigation/new-name-slight-left.c" -#include "displayapp/icons/navigation/new-name-slight-right.c" -#include "displayapp/icons/navigation/new-name-straight.c" -#include "displayapp/icons/navigation/notification-left.c" -#include "displayapp/icons/navigation/notification-right.c" -#include "displayapp/icons/navigation/notification-sharp-left.c" -#include "displayapp/icons/navigation/notification-sharp-right.c" -#include "displayapp/icons/navigation/notification-slight-left.c" -#include "displayapp/icons/navigation/notification-slight-right.c" -#include "displayapp/icons/navigation/notification-straight.c" -#include "displayapp/icons/navigation/off-ramp-left.c" -#include "displayapp/icons/navigation/off-ramp-right.c" -#include "displayapp/icons/navigation/off-ramp-slight-left.c" -#include "displayapp/icons/navigation/off-ramp-slight-right.c" -#include "displayapp/icons/navigation/on-ramp-left.c" -#include "displayapp/icons/navigation/on-ramp-right.c" -#include "displayapp/icons/navigation/on-ramp-sharp-left.c" -#include "displayapp/icons/navigation/on-ramp-sharp-right.c" -#include "displayapp/icons/navigation/on-ramp-slight-left.c" -#include "displayapp/icons/navigation/on-ramp-slight-right.c" -#include "displayapp/icons/navigation/on-ramp-straight.c" -#include "displayapp/icons/navigation/rotary.c" -#include "displayapp/icons/navigation/rotary-left.c" -#include "displayapp/icons/navigation/rotary-right.c" -#include "displayapp/icons/navigation/rotary-sharp-left.c" -#include "displayapp/icons/navigation/rotary-sharp-right.c" -#include "displayapp/icons/navigation/rotary-slight-left.c" -#include "displayapp/icons/navigation/rotary-slight-right.c" -#include "displayapp/icons/navigation/rotary-straight.c" -#include "displayapp/icons/navigation/roundabout.c" -#include "displayapp/icons/navigation/roundabout-left.c" -#include "displayapp/icons/navigation/roundabout-right.c" -#include "displayapp/icons/navigation/roundabout-sharp-left.c" -#include "displayapp/icons/navigation/roundabout-sharp-right.c" -#include "displayapp/icons/navigation/roundabout-slight-left.c" -#include "displayapp/icons/navigation/roundabout-slight-right.c" -#include "displayapp/icons/navigation/roundabout-straight.c" -#include "displayapp/icons/navigation/turn-left.c" -#include "displayapp/icons/navigation/turn-right.c" -#include "displayapp/icons/navigation/turn-sharp-left.c" -#include "displayapp/icons/navigation/turn-sharp-right.c" -#include "displayapp/icons/navigation/turn-slight-left.c" -#include "displayapp/icons/navigation/turn-slight-right.c" -#include "displayapp/icons/navigation/turn-straight.c" -#include "displayapp/icons/navigation/updown.c" -#include "displayapp/icons/navigation/uturn.c" namespace Pinetime { namespace Controllers { @@ -124,8 +37,7 @@ namespace Pinetime { ~Navigation() override; bool Refresh() override; - bool OnButtonPushed() override; - + private: lv_obj_t *imgFlag; @@ -141,97 +53,97 @@ namespace Pinetime { int m_progress; /** Watchapp */ - bool running = true; - - const lv_img_dsc_t* iconForName(std::string icon); - - std::array, 89 > m_iconMap = { { - {"arrive-left", &arrive_left}, - {"arrive-right", &arrive_right}, - {"arrive-straight", &arrive_straight}, - {"arrive", &arrive}, - {"close", &close}, - {"continue-left", &continue_left}, - {"continue-right", &continue_right}, - {"continue-slight-left", &continue_slight_left}, - {"continue-slight-right", &continue_slight_right}, - {"continue-straight", &continue_straight}, - {"continue-uturn", &continue_uturn}, - {"continue", &continue_icon}, - {"depart-left", &depart_left}, - {"depart-right", &depart_right}, - {"depart-straight", &depart_straight}, - {"end-of-road-left", &end_of_road_left}, - {"end-of-road-right", &end_of_road_right}, - {"ferry", &ferry}, - {"flag", &flag}, - {"fork-left", &fork_left}, - {"fork-right", &fork_right}, - {"fork-slight-left", &fork_slight_left}, - {"fork-slight-right", &fork_slight_right}, - {"fork-straight", &fork_straight}, - {"invalid", &invalid}, - {"invalid-left", &invalid_left}, - {"invalid-right", &invalid_right}, - {"invalid-slight-left", &invalid_slight_left}, - {"invalid-slight-right", &invalid_slight_right}, - {"invalid-straight", &invalid_straight}, - {"invalid-uturn", &invalid_uturn}, - {"merge-left", &merge_left}, - {"merge-right", &merge_right}, - {"merge-slight-left", &merge_slight_left}, - {"merge-slight-right", &merge_slight_right}, - {"merge-straight", &merge_straight}, - {"new-name-left", &new_name_left}, - {"new-name-right", &new_name_right}, - {"new-name-sharp-left", &new_name_sharp_left}, - {"new-name-sharp-right", &new_name_sharp_right}, - {"new-name-slight-left", &new_name_slight_left}, - {"new-name-slight-right", &new_name_slight_right}, - {"new-name-straight", &new_name_straight}, - {"notification-left", ¬ification_left}, - {"notification-right", ¬ification_right}, - {"notification-sharp-left", ¬ification_sharp_left}, - {"notification-sharp-right", ¬ification_sharp_right}, - {"notification-slight-left", ¬ification_slight_left}, - {"notification-slight-right", ¬ification_slight_right}, - {"notification-straight", ¬ification_straight}, - {"off-ramp-left", &off_ramp_left}, - {"off-ramp-right", &off_ramp_right}, - {"off-ramp-slight-left", &off_ramp_slight_left}, - {"off-ramp-slight-right", &off_ramp_slight_right}, - {"on-ramp-left", &on_ramp_left}, - {"on-ramp-right", &on_ramp_right}, - {"on-ramp-sharp-left", &on_ramp_sharp_left}, - {"on-ramp-sharp-right", &on_ramp_sharp_right}, - {"on-ramp-slight-left", &on_ramp_slight_left}, - {"on-ramp-slight-right", &on_ramp_slight_right}, - {"on-ramp-straight", &on_ramp_straight}, - {"rotary", &rotary}, - {"rotary-left", &rotary_left}, - {"rotary-right", &rotary_right}, - {"rotary-sharp-left", &rotary_sharp_left}, - {"rotary-sharp-right", &rotary_sharp_right}, - {"rotary-slight-left", &rotary_slight_left}, - {"rotary-slight-right", &rotary_slight_right}, - {"rotary-straight", &rotary_straight}, - {"roundabout", &roundabout}, - {"roundabout-left", &roundabout_left}, - {"roundabout-right", &roundabout_right}, - {"roundabout-sharp-left", &roundabout_sharp_left}, - {"roundabout-sharp-right", &roundabout_sharp_right}, - {"roundabout-slight-left", &roundabout_slight_left}, - {"roundabout-slight-right", &roundabout_slight_right}, - {"roundabout-straight", &roundabout_straight}, - {"turn-left", &turn_left}, - {"turn-right", &turn_right}, - {"turn-sharp-left", &turn_sharp_left}, - {"turn-sharp-right", &turn_sharp_right}, - {"turn-slight-left", &turn_slight_left}, - {"turn-slight-right", &turn_slight_right}, - {"turn-straight", &turn_straight}, - {"updown", &updown}, - {"uturn", &uturn} } }; + + const char* iconForName(std::string icon); + + std::array, 89 > m_iconMap = { { + {"arrive-left" ,"\xEE\xA4\x81" }, + {"arrive-right" ,"\xEE\xA4\x82" }, + {"arrive-straight" ,"\xEE\xA4\x80" }, + {"arrive" ,"\xEE\xA4\x80" }, + {"close" ,"\xEE\xA4\x83" }, + {"continue-left" ,"\xEE\xA4\x85" }, + {"continue-right" ,"\xEE\xA4\x86" }, + {"continue-slight-left" ,"\xEE\xA4\x87" }, + {"continue-slight-right" ,"\xEE\xA4\x88" }, + {"continue-straight" ,"\xEE\xA4\x84" }, + {"continue-uturn" ,"\xEE\xA4\x89" }, + {"continue" ,"\xEE\xA4\x84" }, + {"depart-left" ,"\xEE\xA4\x8B" }, + {"depart-right" ,"\xEE\xA4\x8C" }, + {"depart-straight" ,"\xEE\xA4\x8A" }, + {"end-of-road-left" ,"\xEE\xA4\x8D" }, + {"end-of-road-right" ,"\xEE\xA4\x8E" }, + {"ferry" ,"\xEE\xA4\x8F" }, + {"flag" ,"\xEE\xA4\x90" }, + {"fork-left" ,"\xEE\xA4\x92" }, + {"fork-right" ,"\xEE\xA4\x93" }, + {"fork-slight-left" ,"\xEE\xA4\x94" }, + {"fork-slight-right" ,"\xEE\xA4\x95" }, + {"fork-straight" ,"\xEE\xA4\x96" }, + {"invalid" ,"\xEE\xA4\x84" }, + {"invalid-left" ,"\xEE\xA4\x85" }, + {"invalid-right" ,"\xEE\xA4\x86" }, + {"invalid-slight-left" ,"\xEE\xA4\x87" }, + {"invalid-slight-right" ,"\xEE\xA4\x88" }, + {"invalid-straight" ,"\xEE\xA4\x84" }, + {"invalid-uturn" ,"\xEE\xA4\x89" }, + {"merge-left" ,"\xEE\xA4\x97" }, + {"merge-right" ,"\xEE\xA4\x98" }, + {"merge-slight-left" ,"\xEE\xA4\x99" }, + {"merge-slight-right" ,"\xEE\xA4\x9A" }, + {"merge-straight" ,"\xEE\xA4\x84" }, + {"new-name-left" ,"\xEE\xA4\x85" }, + {"new-name-right" ,"\xEE\xA4\x86" }, + {"new-name-sharp-left" ,"\xEE\xA4\x9B" }, + {"new-name-sharp-right" ,"\xEE\xA4\x9C" }, + {"new-name-slight-left" ,"\xEE\xA4\x87" }, + {"new-name-slight-right" ,"\xEE\xA4\x88" }, + {"new-name-straight" ,"\xEE\xA4\x84" }, + {"notification-left" ,"\xEE\xA4\x85" }, + {"notification-right" ,"\xEE\xA4\x86" }, + {"notification-sharp-left" ,"\xEE\xA4\x9B" }, + {"notification-sharp-right" ,"\xEE\xA4\xA5" }, + {"notification-slight-left" ,"\xEE\xA4\x87" }, + {"notification-slight-right" ,"\xEE\xA4\x88" }, + {"notification-straight" ,"\xEE\xA4\x84" }, + {"off-ramp-left" ,"\xEE\xA4\x9D" }, + {"off-ramp-right" ,"\xEE\xA4\x9E" }, + {"off-ramp-slight-left" ,"\xEE\xA4\x9F" }, + {"off-ramp-slight-right" ,"\xEE\xA4\xA0" }, + {"on-ramp-left" ,"\xEE\xA4\x85" }, + {"on-ramp-right" ,"\xEE\xA4\x86" }, + {"on-ramp-sharp-left" ,"\xEE\xA4\x9B" }, + {"on-ramp-sharp-right" ,"\xEE\xA4\xA5" }, + {"on-ramp-slight-left" ,"\xEE\xA4\x87" }, + {"on-ramp-slight-right" ,"\xEE\xA4\x88" }, + {"on-ramp-straight" ,"\xEE\xA4\x84" }, + {"rotary" ,"\xEE\xA4\xA1" }, + {"rotary-left" ,"\xEE\xA4\xA2" }, + {"rotary-right" ,"\xEE\xA4\xA3" }, + {"rotary-sharp-left" ,"\xEE\xA4\xA4" }, + {"rotary-sharp-right" ,"\xEE\xA4\xA5" }, + {"rotary-slight-left" ,"\xEE\xA4\xA6" }, + {"rotary-slight-right" ,"\xEE\xA4\xA7" }, + {"rotary-straight" ,"\xEE\xA4\xA8" }, + {"roundabout" ,"\xEE\xA4\xA1" }, + {"roundabout-left" ,"\xEE\xA4\xA2" }, + {"roundabout-right" ,"\xEE\xA4\xA3" }, + {"roundabout-sharp-left" ,"\xEE\xA4\xA4" }, + {"roundabout-sharp-right" ,"\xEE\xA4\xA5" }, + {"roundabout-slight-left" ,"\xEE\xA4\xA6" }, + {"roundabout-slight-right" ,"\xEE\xA4\xA7" }, + {"roundabout-straight" ,"\xEE\xA4\xA8" }, + {"turn-left" ,"\xEE\xA4\x85" }, + {"turn-right" ,"\xEE\xA4\x86" }, + {"turn-sharp-left" ,"\xEE\xA4\x9B" }, + {"turn-sharp-right" ,"\xEE\xA4\xA5" }, + {"turn-slight-left" ,"\xEE\xA4\x87" }, + {"turn-slight-right" ,"\xEE\xA4\x88" }, + {"turn-straight" ,"\xEE\xA4\x84" }, + {"updown" ,"\xEE\xA4\xA9" }, + {"uturn" ,"\xEE\xA4\x89" }, + } }; }; } } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index c903ed0f..ea6adc64 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -18,21 +18,21 @@ Notifications::Notifications(DisplayApp *app, if(notification.valid) { currentId = notification.id; currentItem = std::make_unique("\nNotification", - notification.message.data(), - notification.index, - notification.category, - notificationManager.NbNotifications(), - mode, - alertNotificationService); + notification.message.data(), + notification.index, + notification.category, + notificationManager.NbNotifications(), + mode, + alertNotificationService); validDisplay = true; } else { currentItem = std::make_unique("\nNotification", - "No notification to display", - 0, - notification.category, - notificationManager.NbNotifications(), - Modes::Preview, - alertNotificationService); + "No notification to display", + 0, + notification.category, + notificationManager.NbNotifications(), + Modes::Preview, + alertNotificationService); } if(mode == Modes::Preview) { @@ -62,11 +62,6 @@ bool Notifications::Refresh() { timeoutLinePoints[1].x = pos; lv_line_set_points(timeoutLine, timeoutLinePoints, 2); - - if (!running) { - // Start clock app when exiting this one - app->StartApp(Apps::Clock); - } } return running; @@ -74,7 +69,7 @@ bool Notifications::Refresh() { bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { switch (event) { - case Pinetime::Applications::TouchEvents::SwipeUp: { + case Pinetime::Applications::TouchEvents::SwipeDown: { Controllers::NotificationManager::Notification previousNotification; if(validDisplay) previousNotification = notificationManager.GetPrevious(currentId); @@ -86,7 +81,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { validDisplay = true; currentId = previousNotification.id; currentItem.reset(nullptr); - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); currentItem = std::make_unique("\nNotification", previousNotification.message.data(), previousNotification.index, @@ -96,19 +91,22 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { alertNotificationService); } return true; - case Pinetime::Applications::TouchEvents::SwipeDown: { + case Pinetime::Applications::TouchEvents::SwipeUp: { Controllers::NotificationManager::Notification nextNotification; if(validDisplay) nextNotification = notificationManager.GetNext(currentId); else nextNotification = notificationManager.GetLastNotification(); - if (!nextNotification.valid) return true; + if (!nextNotification.valid) { + running = false; + return false; + } validDisplay = true; currentId = nextNotification.id; currentItem.reset(nullptr); - app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); currentItem = std::make_unique("\nNotification", nextNotification.message.data(), nextNotification.index, @@ -127,12 +125,6 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } } - -bool Notifications::OnButtonPushed() { - running = false; - return true; -} - namespace { static void AcceptIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) { auto* item = static_cast(obj->user_data); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 028a3780..0d54ddbe 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -20,7 +20,6 @@ namespace Pinetime { ~Notifications() override; bool Refresh() override; - bool OnButtonPushed() override; bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; class NotificationItem { @@ -55,7 +54,7 @@ namespace Pinetime { }; private: - bool running = true; + struct NotificationData { const char* title; diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index eda06547..e86cf01b 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -103,7 +103,8 @@ Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::Li app->SetTouchMode(DisplayApp::TouchModes::Polling); points = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(points, "0"); + lv_label_set_text(points, "0000"); + lv_obj_set_style_local_text_color(points, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x444444)); lv_obj_align(points, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); paddle.header.always_zero = 0; @@ -164,18 +165,12 @@ bool Paddle::Refresh() { ballX = 107; ballY = 107; score = 0; - } - sprintf(scoreStr, "%d", score); - lv_label_set_text(points, scoreStr); + } + lv_label_set_text_fmt(points, "%04d", score); } return running; } -bool Paddle::OnButtonPushed() { - running = false; - return true; -} - bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return true; } diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index 358bd2f5..453d99ae 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -17,7 +17,7 @@ namespace Pinetime { ~Paddle() override; bool Refresh() override; - bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(uint16_t x, uint16_t y) override; @@ -36,8 +36,6 @@ namespace Pinetime { int counter = 0; // init Frame refresh limit counter int score = 0; - char scoreStr[10]; - lv_img_dsc_t paddle; lv_img_dsc_t ball; @@ -45,7 +43,7 @@ namespace Pinetime { lv_obj_t* paddle_image; // pointer to paddle image lv_obj_t* ball_image; // pointer to ball image - bool running = true; + }; } } diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index 638dac99..cf4f6994 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -56,6 +56,8 @@ namespace Pinetime { protected: DisplayApp* app; + bool running = true; + }; } } diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index 43b33f40..23bcd98b 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -29,11 +29,6 @@ namespace Pinetime { return running; } - bool OnButtonPushed() override { - running = false; - return true; - } - bool OnTouchEvent(TouchEvents event) override { if ( mode == ScreenListModes::UpDown) { @@ -108,7 +103,7 @@ namespace Pinetime { uint8_t screenIndex = 0; std::unique_ptr current; - bool running = true; + }; } } diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index 63f18d4b..e07a960f 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -50,14 +50,16 @@ StopWatch::StopWatch(DisplayApp* app) currentTimeSeparated {}, lapBuffer {}, lapNr {}, lapPressed {false} { time = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed); - lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -45); + lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); + lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_label_set_text(time, "00:00"); + lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -45); msecTime = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); - lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 108, 3); + //lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_label_set_text(msecTime, "00"); + lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 108, 3); btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; @@ -68,12 +70,14 @@ StopWatch::StopWatch(DisplayApp* app) lv_label_set_text(txtPlayPause, Symbols::play); lapOneText = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + //lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_obj_set_style_local_text_color(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_align(lapOneText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30); lv_label_set_text(lapOneText, ""); lapTwoText = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + //lv_obj_set_style_local_text_font(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); + lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55); lv_label_set_text(lapTwoText, ""); @@ -156,6 +160,11 @@ bool StopWatch::Refresh() { // Store the current time elapsed in cache oldTimeElapsed += timeElapsed; currentState = States::Halted; + lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + } else { + lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); } break; } @@ -170,6 +179,8 @@ bool StopWatch::Refresh() { if (currentEvent == Events::Stop) { currentState = States::Init; oldTimeElapsed = 0; + lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); } break; } @@ -177,11 +188,6 @@ bool StopWatch::Refresh() { return running; } -bool StopWatch::OnButtonPushed() { - running = false; - return true; -} - void StopWatch::playPauseBtnEventHandler(lv_event_t event) { if (event == LV_EVENT_CLICKED) { if (currentState == States::Init) { diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index f9dd5c76..b882cab5 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -66,7 +66,7 @@ namespace Pinetime::Applications::Screens { StopWatch(DisplayApp* app); ~StopWatch() override; bool Refresh() override; - bool OnButtonPushed() override; + void playPauseBtnEventHandler(lv_event_t event); void stopLapBtnEventHandler(lv_event_t event); diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h index 9a13a755..0750f2c1 100644 --- a/src/displayapp/screens/Symbols.h +++ b/src/displayapp/screens/Symbols.h @@ -39,6 +39,19 @@ namespace Pinetime { static constexpr const char* stop = "\xEF\x81\x8D"; static constexpr const char* stopWatch = "\xEF\x8B\xB2"; static constexpr const char* lapsFlag = "\xEF\x80\xA4"; + + // lv_font_sys_48.c + static constexpr const char* settings = "\xEE\xA4\x82";//e902 + + static constexpr const char* brightnessHigh = "\xEE\xA4\x84";//e904 + static constexpr const char* brightnessLow = "\xEE\xA4\x85";//e905 + static constexpr const char* brightnessMedium = "\xEE\xA4\x86";//e906 + + static constexpr const char* notificationsOff = "\xEE\xA4\x8B";//e90b + static constexpr const char* notificationsOn = "\xEE\xA4\x8C";//e90c + + static constexpr const char* highlight = "\xEE\xA4\x87";//e907 + } } } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 949fd345..f3ac7490 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -25,7 +25,8 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp *app, { [this]() -> std::unique_ptr { return CreateScreen1(); }, [this]() -> std::unique_ptr { return CreateScreen2(); }, - [this]() -> std::unique_ptr { return CreateScreen3(); } + [this]() -> std::unique_ptr { return CreateScreen3(); }, + [this]() -> std::unique_ptr { return CreateScreen4(); } }, Screens::ScreenListModes::UpDown } {} @@ -49,16 +50,46 @@ bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) { return screens.OnTouchEvent(event); } +void SystemInfo::CreateContainer() { + + if ( container1 ) { + container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 0, 0); + lv_obj_set_width(container1, LV_HOR_RES - 10); + lv_obj_set_height(container1, LV_VER_RES); + lv_cont_set_layout(container1, LV_LAYOUT_CENTER); + } +} + std::unique_ptr SystemInfo::CreateScreen1() { + CreateContainer(); + + lv_obj_t * label = lv_label_create(container1, nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#FFFF00 InfiniTime#\n\n" + "#444444 Version# %ld.%ld.%ld\n\n" + "#444444 Build date#\n" + "\t%s\n" + "\t%s\n", + Version::Major(), Version::Minor(), Version::Patch(), + __DATE__, __TIME__); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + return std::unique_ptr(new Screens::Label(0, 4, app, label)); +} + +std::unique_ptr SystemInfo::CreateScreen2() { + CreateContainer(); + auto batteryPercent = static_cast(batteryController.PercentRemaining()); + float batteryVoltage = batteryController.Voltage(); - 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"; @@ -87,41 +118,73 @@ std::unique_ptr SystemInfo::CreateScreen1() { uptimeSeconds = uptimeSeconds % secondsInAMinute; // TODO handle more than 100 days of uptime - sprintf(t1, "InfiniTime\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__, + if (batteryPercent == -1) batteryPercent = 0; + + // hack to not use the flot functions from printf + uint8_t batteryVoltageBytes[2]; + batteryVoltageBytes[1] = static_cast(batteryVoltage); //truncate whole numbers + batteryVoltageBytes[0] = static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); //remove whole part of flt and shift 2 places over + // + + lv_obj_t * label = lv_label_create(container1, nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#444444 Date# %02d/%02d/%04d\n" + "#444444 Time# %02d:%02d:%02d\n" + "#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n" + "#444444 Battery# %d%%/%1i.%02iv\n" + "#444444 Backlight# %s\n" + "#444444 Last reset# %s\n", dateTimeController.Day(), static_cast(dateTimeController.Month()), dateTimeController.Year(), dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, - batteryPercent, brightness, resetReason); + batteryPercent, batteryVoltageBytes[1], batteryVoltageBytes[0], brightnessController.ToString(), resetReason + ); + return std::unique_ptr(new Screens::Label(1, 4, app, label)); - return std::make_unique(app, t1); } -std::unique_ptr SystemInfo::CreateScreen2() { +std::unique_ptr SystemInfo::CreateScreen3() { + lv_mem_monitor_t mon; + lv_mem_monitor(&mon); + CreateContainer(); + + lv_obj_t * label = lv_label_create(container1, nullptr); + lv_label_set_recolor(label, true); auto& bleAddr = bleController.Address(); - sprintf(t2, "BLE MAC: \n %02x:%02x:%02x:%02x:%02x:%02x", - bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); - return std::make_unique(app, t2); + lv_label_set_text_fmt(label, + "#444444 BLE MAC#\n" + " %02x:%02x:%02x:%02x:%02x:%02x" + "\n" + "#444444 Memory#\n" + " #444444 used# %d (%d%%)\n" + " #444444 frag# %d%%\n" + " #444444 free# %d" + "\n" + "#444444 Steps# %li", + bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0], + (int)mon.total_size - mon.free_size, + mon.used_pct, + mon.frag_pct, + (int)mon.free_biggest_size, + 0 + ); + + return std::unique_ptr(new Screens::Label(2, 4, app, label)); } -std::unique_ptr SystemInfo::CreateScreen3() { - sprintf(t3, "Hello from\nthe developer!\n" +std::unique_ptr SystemInfo::CreateScreen4() { + CreateContainer(); + lv_obj_t * label = lv_label_create(container1, nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_static(label, "Software Licensed\n" "under the terms of\n" "the GNU General\n" "Public License v3\n" - "Source code:\n" - "https://github.com/\n" - " JF002/InfiniTime"); - return std::make_unique(app, t3); -} + "#444444 Source code#\n" + "#FFFF00 https://github.com/#\n" + "#FFFF00 JF002/InfiniTime#"); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + return std::unique_ptr(new Screens::Label(3, 4, app, label)); +} \ No newline at end of file diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index 75268c71..574ded74 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -35,20 +35,21 @@ namespace Pinetime { private: bool running = true; + lv_obj_t* container1; + 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[200]; - - ScreenList<3> screens; + ScreenList<4> screens; std::unique_ptr CreateScreen1(); std::unique_ptr CreateScreen2(); std::unique_ptr CreateScreen3(); + std::unique_ptr CreateScreen4(); + + void CreateContainer(); }; } } diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index ca753db9..8fa7fd07 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -1,56 +1,136 @@ #include "Tile.h" #include "../DisplayApp.h" +#include "BatteryIcon.h" using namespace Pinetime::Applications::Screens; -static void event_handler(lv_obj_t * obj, lv_event_t event) { - Tile* screen = static_cast(obj->user_data); - uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); - uint32_t eventData = *eventDataPtr; - screen->OnObjectEvent(obj, event, eventData); + +namespace { + static void lv_update_task(struct _lv_task_t *task) { + auto user_data = static_cast(task->user_data); + user_data->UpdateScreen(); + } + + static void event_handler(lv_obj_t * obj, lv_event_t event) { + Tile* screen = static_cast(obj->user_data); + uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); + uint32_t eventData = *eventDataPtr; + screen->OnObjectEvent(obj, event, eventData); + } } -Tile::Tile(uint8_t screenID, DisplayApp* app, Controllers::Settings& settingsController, std::array& applications) : Screen(app) { +Tile::Tile(uint8_t screenID, uint8_t numScreens, + DisplayApp* app, + Controllers::Settings& settingsController, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController, + std::array& applications) : + Screen(app), + batteryController{batteryController}, + dateTimeController{dateTimeController} { settingsController.SetAppMenu(screenID); + + // Time + label_time = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); + lv_label_set_align( label_time, LV_LABEL_ALIGN_CENTER ); + lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 15, 6); + + // Battery + batteryIcon = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 6); + + if ( numScreens > 1 ) { + pageIndicatorBasePoints[0].x = 240 - 1; + pageIndicatorBasePoints[0].y = 6; + pageIndicatorBasePoints[1].x = 240 - 1; + pageIndicatorBasePoints[1].y = 240 - 6; + + pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); + + + uint16_t indicatorSize = 228 / numScreens; + uint16_t indicatorPos = indicatorSize * screenID; + + pageIndicatorPoints[0].x = 240 - 1; + pageIndicatorPoints[0].y = 6 + indicatorPos; + pageIndicatorPoints[1].x = 240 - 1; + pageIndicatorPoints[1].y = 6 + indicatorPos + indicatorSize; + + pageIndicator = lv_line_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3); + lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); + lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); + } - 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++; + uint8_t btIndex = 0; + for(uint8_t i = 0; i < 6; i++) { + if(i == 3) btnmMap[btIndex++] = "\n"; + if ( applications[i].application == Apps::None ) { + btnmMap[btIndex] = " "; + } else { + btnmMap[btIndex] = applications[i].icon; } + btIndex++; + apps[i] = applications[i].application; } + btnmMap[btIndex] = ""; btnm1 = lv_btnmatrix_create(lv_scr_act(), nullptr); - lv_btnmatrix_set_map(btnm1, btnm_map1); - lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); + lv_btnmatrix_set_map(btnm1, btnmMap); + lv_obj_set_size(btnm1, LV_HOR_RES - 10, LV_VER_RES - 60); + lv_obj_align(btnm1, NULL, LV_ALIGN_CENTER, 0, 10); + + lv_obj_set_style_local_radius(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_COLOR_AQUA); + lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_20); + lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111)); + + for(uint8_t i = 0; i < 6; i++) { + if ( applications[i].application == Apps::None ) { + lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_DISABLED ); + } + } btnm1->user_data = this; lv_obj_set_event_cb(btnm1, event_handler); + + lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + 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_static(backgroundLabel, ""); + + taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_MID, this); } Tile::~Tile() { + lv_task_del(taskUpdate); lv_obj_clean(lv_scr_act()); } +void Tile::UpdateScreen() { + lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); +} + 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]); + app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Down); 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 index f717a220..54ffcdae 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -5,7 +5,10 @@ #include #include "Screen.h" #include "../Apps.h" +#include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" +#include "components/datetime/DateTimeController.h" +#include "components/battery/BatteryController.h" namespace Pinetime { namespace Applications { @@ -17,19 +20,35 @@ namespace Pinetime { Pinetime::Applications::Apps application; }; - explicit Tile(uint8_t screenID, DisplayApp* app, Controllers::Settings& settingsController, std::array& applications); + explicit Tile(uint8_t screenID, uint8_t numScreens, + DisplayApp* app, + Controllers::Settings& settingsController, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController, + std::array& applications); + ~Tile() override; bool Refresh() override; - bool OnButtonPushed() override; - + void UpdateScreen(); void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); private: - lv_obj_t * btnm1; - bool running = true; - const char* btnm_map1[8]; + Pinetime::Controllers::Battery& batteryController; + Controllers::DateTime& dateTimeController; + + lv_task_t* taskUpdate; + + lv_obj_t* label_time; + lv_obj_t* batteryIcon; + lv_point_t pageIndicatorBasePoints[2]; + lv_point_t pageIndicatorPoints[2]; + lv_obj_t* pageIndicatorBase; + lv_obj_t* pageIndicator; + lv_obj_t* btnm1; + + const char* btnmMap[8]; Pinetime::Applications::Apps apps[6]; }; } diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index b51a9ec6..5210a4d6 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -101,11 +101,6 @@ bool Twos::Refresh() { return running; } -bool Twos::OnButtonPushed() { - running = false; - return true; -} - bool Twos::placeNewTile() { std::vector< std::pair > availableCells; for(int row = 0; row < 4; row++) { diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index ec021971..7223c7a8 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -15,7 +15,7 @@ namespace Pinetime { Twos(DisplayApp* app); ~Twos() override; bool Refresh() override; - bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; private: @@ -26,7 +26,7 @@ namespace Pinetime { lv_style_t style_cell4; lv_style_t style_cell5; - bool running = true; + lv_obj_t *scoreText; lv_obj_t *gridDisplay; Tile grid[4][4]; diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index c39fe496..6fe076c5 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -249,9 +249,3 @@ bool WatchFaceDigital::Refresh() { } -bool WatchFaceDigital::OnButtonPushed() { - running = false; - return false; -} - - diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 70a9ce5d..8f23985c 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -32,7 +32,7 @@ namespace Pinetime { ~WatchFaceDigital() override; bool Refresh() override; - bool OnButtonPushed() override; + void OnObjectEvent(lv_obj_t *pObj, lv_event_t i); private: @@ -74,7 +74,7 @@ namespace Pinetime { Controllers::Settings& settingsController; Controllers::HeartRateController& heartRateController; - bool running = true; + }; } diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp new file mode 100644 index 00000000..9fd051b8 --- /dev/null +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -0,0 +1,177 @@ +#include "QuickSettings.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" +#include "displayapp/screens/BatteryIcon.h" + + +using namespace Pinetime::Applications::Screens; + +namespace { + static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) { + QuickSettings* screen = static_cast(obj->user_data); + screen->OnButtonEvent(obj, event); + } + + static void lv_update_task(struct _lv_task_t *task) { + auto user_data = static_cast(task->user_data); + user_data->UpdateScreen(); + } +} + +QuickSettings::QuickSettings( + Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController, + Controllers::BrightnessController& brightness, + Pinetime::Controllers::Settings &settingsController) : + Screen(app), + batteryController{batteryController}, + dateTimeController{dateTimeController}, + brightness{brightness}, + settingsController{settingsController} +{ + + // Time + label_time = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); + lv_label_set_align( label_time, LV_LABEL_ALIGN_CENTER ); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 15, 4); + + batteryIcon = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); + lv_obj_align(batteryIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 4); + + + lv_obj_t * lbl_btn; + + btn1 = lv_btn_create(lv_scr_act(), nullptr); + btn1->user_data = this; + lv_obj_set_event_cb(btn1, ButtonEventHandler); + lv_obj_align(btn1, nullptr, LV_ALIGN_CENTER, -50, -30); + lv_obj_set_style_local_radius(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + + lv_btn_set_fit2(btn1, LV_FIT_TIGHT, LV_FIT_TIGHT); + + btn1_lvl = lv_label_create(btn1, nullptr); + lv_obj_set_style_local_text_font(btn1_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + lv_label_set_text_static(btn1_lvl, brightness.GetIcon()); + + + btn2 = lv_btn_create(lv_scr_act(), nullptr); + btn2->user_data = this; + lv_obj_set_event_cb(btn2, ButtonEventHandler); + lv_obj_align(btn2, nullptr, LV_ALIGN_CENTER, 50, -30); + lv_obj_set_style_local_radius(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_grad_dir(btn2, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + lv_btn_set_fit2(btn2, LV_FIT_TIGHT, LV_FIT_TIGHT); + + lbl_btn = lv_label_create(btn2, nullptr); + lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + lv_label_set_text_static(lbl_btn, Symbols::highlight); + + + btn3 = lv_btn_create(lv_scr_act(), nullptr); + btn3->user_data = this; + lv_obj_set_event_cb(btn3, ButtonEventHandler); + lv_obj_align(btn3, nullptr, LV_ALIGN_CENTER, -50, 60); + lv_btn_set_checkable(btn3, true); + lv_obj_set_style_local_radius(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_grad_dir(btn3, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GREEN); + lv_obj_set_style_local_bg_grad_dir(btn1, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_GRAD_DIR_NONE); + lv_btn_set_fit2(btn3, LV_FIT_TIGHT, LV_FIT_TIGHT); + + btn3_lvl = lv_label_create(btn3, nullptr); + lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + + if ( settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::ON ) { + lv_obj_add_state(btn3, LV_STATE_CHECKED); + lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); + } else { + lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); + } + + btn4 = lv_btn_create(lv_scr_act(), nullptr); + btn4->user_data = this; + lv_obj_set_event_cb(btn4, ButtonEventHandler); + lv_obj_align(btn4, nullptr, LV_ALIGN_CENTER, 50, 60); + lv_obj_set_style_local_radius(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_grad_dir(btn4, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_GRAD_DIR_NONE); + lv_btn_set_fit2(btn4, LV_FIT_TIGHT, LV_FIT_TIGHT); + + lbl_btn = lv_label_create(btn4, nullptr); + lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); + lv_label_set_text_static(lbl_btn, Symbols::settings); + + lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + 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_static(backgroundLabel, ""); + + taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_MID, this); + +} + + +QuickSettings::~QuickSettings() { + lv_task_del(taskUpdate); + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void QuickSettings::UpdateScreen() { + lv_label_set_text_fmt(label_time, "%02i:%02i", dateTimeController.Hours(), dateTimeController.Minutes()); + lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryController.PercentRemaining())); +} + +void QuickSettings::OnButtonEvent(lv_obj_t *object, lv_event_t event) { + if(object == btn2 && event == LV_EVENT_PRESSED) { + + running = false; + app->StartApp(Apps::FlashLight, DisplayApp::FullRefreshDirections::None); + + } else if(object == btn1 && event == LV_EVENT_PRESSED) { + + brightness.Step(); + lv_label_set_text_static(btn1_lvl, brightness.GetIcon()); + settingsController.SetBrightness( brightness.Level() ); + + } else if(object == btn3 && event == LV_EVENT_VALUE_CHANGED) { + + if(lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { + settingsController.SetVibrationStatus( Controllers::Settings::Vibration::ON ); + lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); + } else { + settingsController.SetVibrationStatus(Controllers::Settings::Vibration::OFF); + lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); + } + + } else if(object == btn4 && event == LV_EVENT_PRESSED) { + running = false; + settingsController.SetSettingsMenu(0); + app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up); + + } + +} + +bool QuickSettings::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch (event) { + case Pinetime::Applications::TouchEvents::SwipeLeft: + running = false; + return false; + + default: + return true; + } +} + +bool QuickSettings::Refresh() { + return running; +} diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h new file mode 100644 index 00000000..329be55b --- /dev/null +++ b/src/displayapp/screens/settings/QuickSettings.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include "displayapp/screens/Screen.h" +#include +#include "components/datetime/DateTimeController.h" +#include "components/brightness/BrightnessController.h" +#include "components/settings/Settings.h" +#include "components/battery/BatteryController.h" + + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class QuickSettings : public Screen{ + public: + QuickSettings(DisplayApp* app, + Pinetime::Controllers::Battery& batteryController, + Controllers::DateTime& dateTimeController, + Controllers::BrightnessController& brightness, + Pinetime::Controllers::Settings &settingsController); + + ~QuickSettings() override; + + bool Refresh() override; + + bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; + void OnButtonEvent(lv_obj_t *object, lv_event_t event); + + void UpdateScreen(); + + private: + + Pinetime::Controllers::Battery& batteryController; + Controllers::DateTime& dateTimeController; + Controllers::BrightnessController& brightness; + Controllers::Settings& settingsController; + + lv_task_t* taskUpdate; + lv_obj_t * batteryIcon; + lv_obj_t * label_time; + + lv_obj_t * btn1; + lv_obj_t * btn1_lvl; + lv_obj_t * btn2; + lv_obj_t * btn3; + lv_obj_t * btn3_lvl; + lv_obj_t * btn4; + + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp new file mode 100644 index 00000000..6c1bc9b5 --- /dev/null +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -0,0 +1,109 @@ +#include "SettingDisplay.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/Messages.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t * obj, lv_event_t event) { + SettingDisplay* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingDisplay::SettingDisplay( + Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Settings &settingsController) : + Screen(app), + settingsController{settingsController} +{ + + lv_obj_t * container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 60); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 50); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title,"Display timeout"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); + + lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::sun); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + optionsTotal = 0; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 5 seconds"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetScreenTimeOut() == 5000 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 15 seconds"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetScreenTimeOut() == 15000 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 20 seconds"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetScreenTimeOut() == 20000 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 30 seconds"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetScreenTimeOut() == 30000 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; +} + +SettingDisplay::~SettingDisplay() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +bool SettingDisplay::Refresh() { + return running; +} + + +void SettingDisplay::UpdateSelected(lv_obj_t *object, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + for(int i = 0; i < optionsTotal; i++) { + if ( object == cbOption[i] ) { + lv_checkbox_set_checked(cbOption[i], true); + + if ( i == 0 ) { settingsController.SetScreenTimeOut(5000); }; + if ( i == 1 ) { settingsController.SetScreenTimeOut(15000); }; + if ( i == 2 ) { settingsController.SetScreenTimeOut(20000); }; + if ( i == 3 ) { settingsController.SetScreenTimeOut(30000); }; + + app->PushMessage(Applications::Display::Messages::UpdateTimeOut); + + } else { + lv_checkbox_set_checked(cbOption[i], false); + } + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h new file mode 100644 index 00000000..9565d3c7 --- /dev/null +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingDisplay : public Screen{ + public: + SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingDisplay() override; + + bool Refresh() override; + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t * cbOption[4]; + + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingTimeFormat.cpp b/src/displayapp/screens/settings/SettingTimeFormat.cpp new file mode 100644 index 00000000..ff217bda --- /dev/null +++ b/src/displayapp/screens/settings/SettingTimeFormat.cpp @@ -0,0 +1,89 @@ +#include "SettingTimeFormat.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t * obj, lv_event_t event) { + SettingTimeFormat* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingTimeFormat::SettingTimeFormat( + Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Settings &settingsController) : + Screen(app), + settingsController{settingsController} +{ + + lv_obj_t * container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 60); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 50); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title,"Time format"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + + lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::clock); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + optionsTotal = 0; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 12-hour"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " 24-hour"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; +} + +SettingTimeFormat::~SettingTimeFormat() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +bool SettingTimeFormat::Refresh() { + return running; +} + + +void SettingTimeFormat::UpdateSelected(lv_obj_t *object, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + for(int i = 0; i < optionsTotal; i++) { + if ( object == cbOption[i] ) { + lv_checkbox_set_checked(cbOption[i], true); + + if ( i == 0 ) { settingsController.SetClockType(Controllers::Settings::ClockType::H12); }; + if ( i == 1 ) { settingsController.SetClockType(Controllers::Settings::ClockType::H24); }; + + } else { + lv_checkbox_set_checked(cbOption[i], false); + } + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingTimeFormat.h b/src/displayapp/screens/settings/SettingTimeFormat.h new file mode 100644 index 00000000..a6380493 --- /dev/null +++ b/src/displayapp/screens/settings/SettingTimeFormat.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingTimeFormat : public Screen{ + public: + SettingTimeFormat(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingTimeFormat() override; + + bool Refresh() override; + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t * cbOption[2]; + + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp new file mode 100644 index 00000000..927a9e3a --- /dev/null +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -0,0 +1,107 @@ +#include "SettingWakeUp.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include "components/settings/Settings.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t * obj, lv_event_t event) { + SettingWakeUp* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingWakeUp::SettingWakeUp( + Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Settings &settingsController) : + Screen(app), + settingsController{settingsController} +{ + + lv_obj_t * container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 60); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 50); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title,"Wake Up"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); + + lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::clock); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + optionsTotal = 0; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " None"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; +} + +SettingWakeUp::~SettingWakeUp() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +bool SettingWakeUp::Refresh() { + return running; +} + + +void SettingWakeUp::UpdateSelected(lv_obj_t *object, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + for(int i = 0; i < optionsTotal; i++) { + if ( object == cbOption[i] ) { + lv_checkbox_set_checked(cbOption[i], true); + + if ( i == 0 ) { settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::None); }; + if ( i == 1 ) { settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::SingleTap); }; + if ( i == 2 ) { settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap); }; + if ( i == 3 ) { settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist); }; + + } else { + lv_checkbox_set_checked(cbOption[i], false); + } + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h new file mode 100644 index 00000000..99ddd363 --- /dev/null +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingWakeUp : public Screen{ + public: + SettingWakeUp(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingWakeUp() override; + + bool Refresh() override; + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t * cbOption[3]; + + }; + } + } +} diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp new file mode 100644 index 00000000..f763acd4 --- /dev/null +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -0,0 +1,88 @@ +#include "SettingWatchFace.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +namespace { + static void event_handler(lv_obj_t * obj, lv_event_t event) { + SettingWatchFace* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingWatchFace::SettingWatchFace( + Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Settings &settingsController) : + Screen(app), + settingsController{settingsController} +{ + + lv_obj_t * container1 = lv_cont_create(lv_scr_act(), nullptr); + + //lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 60); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 50); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title,"Watch face"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15); + + lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); + lv_label_set_text_static(icon, Symbols::clock); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + optionsTotal = 0; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Digital face"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetClockFace() == 0 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Analog face"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetClockFace() == 1 ) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; +} + +SettingWatchFace::~SettingWatchFace() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +bool SettingWatchFace::Refresh() { + return running; +} + + +void SettingWatchFace::UpdateSelected(lv_obj_t *object, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + for(uint8_t i = 0; i < optionsTotal; i++) { + if ( object == cbOption[i] ) { + lv_checkbox_set_checked(cbOption[i], true); + settingsController.SetClockFace(i); + } else { + lv_checkbox_set_checked(cbOption[i], false); + } + } + } +} \ No newline at end of file diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h new file mode 100644 index 00000000..8c30ed28 --- /dev/null +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingWatchFace : public Screen{ + public: + SettingWatchFace(DisplayApp* app, Pinetime::Controllers::Settings &settingsController); + ~SettingWatchFace() override; + + bool Refresh() override; + void UpdateSelected(lv_obj_t *object, lv_event_t event); + + private: + + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t * cbOption[2]; + + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp new file mode 100644 index 00000000..b2825915 --- /dev/null +++ b/src/displayapp/screens/settings/Settings.cpp @@ -0,0 +1,69 @@ +#include "Settings.h" +#include +#include +#include "displayapp/screens/List.h" +#include "displayapp/Apps.h" +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Symbols.h" + +using namespace Pinetime::Applications::Screens; + +Settings::Settings( + Pinetime::Applications::DisplayApp *app, + Pinetime::Controllers::Settings &settingsController) : + Screen(app), + settingsController{settingsController}, + screens{app, + settingsController.GetSettingsMenu(), + { + [this]() -> std::unique_ptr { return CreateScreen1(); }, + [this]() -> std::unique_ptr { return CreateScreen2(); } + }, + Screens::ScreenListModes::UpDown + } {} + +Settings::~Settings() { + lv_obj_clean(lv_scr_act()); +} + +bool Settings::Refresh() { + + if(running) + running = screens.Refresh(); + return running; +} + +bool Settings::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr Settings::CreateScreen1() { + + std::array applications { + { + {Symbols::sun, "Display", Apps::SettingDisplay}, + {Symbols::clock, "Wake Up", Apps::SettingWakeUp}, + {Symbols::clock, "Time format", Apps::SettingTimeFormat}, + {Symbols::clock, "Watch face", Apps::SettingWatchFace}, + } + + }; + + return std::unique_ptr(new Screens::List(0, 2, app, settingsController, applications)); +} + + +std::unique_ptr Settings::CreateScreen2() { + + std::array applications { + { + {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, + {Symbols::check, "Firmware", Apps::FirmwareValidation}, + {Symbols::list, "About", Apps::SysInfo}, + {"", "", Apps::None}, + } + + }; + + return std::unique_ptr(new Screens::List(1, 2, app, settingsController, applications)); +} diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h new file mode 100644 index 00000000..9955e1d4 --- /dev/null +++ b/src/displayapp/screens/settings/Settings.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/ScreenList.h" + +namespace Pinetime { + + + namespace Applications { + namespace Screens { + + class Settings : public Screen{ + public: + Settings(DisplayApp* app, + Pinetime::Controllers::Settings &settingsController); + ~Settings() override; + + bool Refresh() override; + + void OnButtonEvent(lv_obj_t *object, lv_event_t event); + bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; + + private: + + Controllers::Settings& settingsController; + + ScreenList<2> screens; + + std::unique_ptr CreateScreen1(); + std::unique_ptr CreateScreen2(); + + + }; + } + } +} -- cgit v1.2.3-70-g09d2 From bb7531e2085cee056161c528d84884d5a75c5e6e Mon Sep 17 00:00:00 2001 From: Joaquim Date: Sun, 4 Apr 2021 13:51:22 +0100 Subject: double tap wakeup error fix battery nonblocking read --- src/components/battery/BatteryController.cpp | 74 +++++++++++++++++++++------- src/components/battery/BatteryController.h | 47 ++++-------------- src/displayapp/screens/InfiniPaint.cpp | 2 + src/displayapp/screens/Notifications.cpp | 5 +- src/drivers/TwiMaster.cpp | 7 ++- src/libs/lv_conf.h | 2 +- src/systemtask/SystemTask.cpp | 20 ++++---- 7 files changed, 89 insertions(+), 68 deletions(-) (limited to 'src/displayapp/screens') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index aaa245e4..50f95c99 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,16 +1,38 @@ #include "BatteryController.h" #include +#include #include #include +#include using namespace Pinetime::Controllers; +#define SAMPLES_IN_BUFFER 1 +static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER]; + +static float voltage = 0.0f; +static int percentRemaining = -1; + void Battery::Init() { nrf_gpio_cfg_input(chargingPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup); nrf_gpio_cfg_input(powerPresentPin, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup); +} + +void Battery::Update() { + isCharging = !nrf_gpio_pin_read(chargingPin); + isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); + + // Non blocking read + SaadcInit(); + nrfx_saadc_sample(); + +} + +void Battery::SaadcInit() { nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; - nrfx_saadc_init(&adcConfig, SaadcEventHandler); + APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, SaadcEventHandler)); + nrf_saadc_channel_config_t adcChannelConfig = { .resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, @@ -18,32 +40,50 @@ void Battery::Init() { .reference = NRF_SAADC_REFERENCE_INTERNAL, .acq_time = NRF_SAADC_ACQTIME_3US, .mode = NRF_SAADC_MODE_SINGLE_ENDED, - .burst = NRF_SAADC_BURST_DISABLED, + .burst = NRF_SAADC_BURST_ENABLED, .pin_p = batteryVoltageAdcInput, .pin_n = NRF_SAADC_INPUT_DISABLED }; - nrfx_saadc_channel_init(0, &adcChannelConfig); + APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig)); + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER)); + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER)); + } -void Battery::Update() { - isCharging = !nrf_gpio_pin_read(chargingPin); - isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); +void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { + int avg_sample = 0; + int i = 0; + + const float battery_max = 4.18; //maximum voltage of battery ( max charging voltage is 4.21 ) + const float battery_min = 3.20; //minimum voltage of battery before shutdown ( depends on the battery ) - nrf_saadc_value_t value = 0; - nrfx_saadc_sample_convert(0, &value); + if (p_event->type == NRFX_SAADC_EVT_DONE) { + + APP_ERROR_CHECK(nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER)); - // see https://forum.pine64.org/showthread.php?tid=8147 - voltage = (value * 2.0f) / (1024/3.0f); - int percentRemaining = ((voltage - 3.55f)*100.0f)*3.9f; - percentRemaining = std::max(percentRemaining, 0); - percentRemaining = std::min(percentRemaining, 100); + for (i = 0; i < SAMPLES_IN_BUFFER; i++) { + avg_sample += p_event->data.done.p_buffer[i]; // take N samples in a row + } + avg_sample /= i; // average all the samples out - percentRemainingBuffer.insert(percentRemaining); + voltage = (static_cast(avg_sample) * 2.04f) / (1024 / 3.0f); + voltage = roundf(voltage * 100) / 100; -// NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage)); -// NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent); + percentRemaining = static_cast(((voltage - battery_min) / (battery_max - battery_min)) * 100); + + percentRemaining = std::max(percentRemaining, 0); + percentRemaining = std::min(percentRemaining, 100); + + nrfx_saadc_uninit(); + + } } -void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * event) { +int Battery::PercentRemaining() { + return percentRemaining; +} + +float Battery::Voltage() { + return voltage; } \ No newline at end of file diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 86250a57..9bc942c9 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -6,44 +6,16 @@ namespace Pinetime { namespace Controllers { - /** A simple circular buffer that can be used to average - out the sensor values. The total capacity of the CircBuffer - is given as the template parameter N. - */ - template - class CircBuffer { - public: - CircBuffer() : arr{}, sz{}, cap{N}, head{} {} - /** - insert member function overwrites the next data to the current - HEAD and moves the HEAD to the newly inserted value. - */ - void insert(const int num) { - head %= cap; - arr[head++] = num; - if (sz != cap) { - sz++; - } - } - - int GetAverage() const { - int sum = std::accumulate(arr.begin(), arr.end(), 0); - return (sum / sz); - } - - private: - std::array arr; /**< internal array used to store the values*/ - uint8_t sz; /**< The current size of the array.*/ - uint8_t cap; /**< Total capacity of the CircBuffer.*/ - uint8_t head; /**< The current head of the CircBuffer*/ - }; class Battery { public: + void Init(); void Update(); - int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); } - float Voltage() const { return voltage; } + + int PercentRemaining(); + float Voltage(); + bool IsCharging() const { return isCharging; } bool IsPowerPresent() const { return isPowerPresent; } @@ -51,12 +23,13 @@ namespace Pinetime { static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; - static constexpr uint8_t percentRemainingSamples = 10; - static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); - CircBuffer percentRemainingBuffer {}; - float voltage = 0.0f; + bool isCharging = false; bool isPowerPresent = false; + + static void SaadcEventHandler(nrfx_saadc_evt_t const * p_event); + void SaadcInit(); + }; } } \ No newline at end of file diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index b2f0fdfe..b6a7e3e4 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -56,6 +56,8 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { std::fill(b, b + bufferSize, selectColor); color++; return true; + default: + return true; } return true; } diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index ea6adc64..1a8fca9c 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -117,7 +117,7 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } return true; case Pinetime::Applications::TouchEvents::LongTap: { - notificationManager.ToggleVibrations(); + //notificationManager.ToggleVibrations(); return true; } default: @@ -214,6 +214,7 @@ namespace { lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80); label_accept = lv_label_create(bt_accept, nullptr); lv_label_set_text(label_accept, Symbols::phone); + lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); bt_reject = lv_btn_create(callBtnContainer, nullptr); bt_reject->user_data = this; @@ -221,6 +222,7 @@ namespace { lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80); label_reject = lv_label_create(bt_reject, nullptr); lv_label_set_text(label_reject, Symbols::phoneSlash); + lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); bt_mute = lv_btn_create(callBtnContainer, nullptr); bt_mute->user_data = this; @@ -228,6 +230,7 @@ namespace { lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80); label_mute = lv_label_create(bt_mute, nullptr); lv_label_set_text(label_mute, Symbols::volumMute); + lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); } break; } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 6a063ecf..d5898b5e 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -10,6 +10,7 @@ using namespace Pinetime::Drivers; TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params} { mutex = xSemaphoreCreateBinary(); + ASSERT(mutex != NULL); } void TwiMaster::Init() { @@ -61,9 +62,11 @@ void TwiMaster::Init() { } TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { - xSemaphoreTake(mutex, portMAX_DELAY); + // this is causing an error when came from sleep + //xSemaphoreTake(mutex, portMAX_DELAY); + auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size); - xSemaphoreGive(mutex); + //xSemaphoreGive(mutex); return ret; } diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 0d1304a5..b2c45ab1 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -74,7 +74,7 @@ typedef int16_t lv_coord_t; #define LV_MEM_CUSTOM 0 #if LV_MEM_CUSTOM == 0 /* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ -#define LV_MEM_SIZE (12U * 1024U) +#define LV_MEM_SIZE (14U * 1024U) /* Complier prefix for a big array declaration */ #define LV_MEM_ATTR diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 236c313a..2aa071dc 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -148,8 +148,12 @@ void SystemTask::Work() { break; case Messages::GoToRunning: spi.Wakeup(); - //twiMaster.Wakeup(); - //touchPanel.Wakeup(); + + // Double Tap needs the touch screen to be in normal mode + if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { + twiMaster.Wakeup(); + touchPanel.Wakeup(); + } nimbleController.StartAdvertising(); xTimerStart(idleTimer, 0); @@ -212,14 +216,10 @@ void SystemTask::Work() { // Double Tap needs the touch screen to be in normal mode if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { - //touchPanel.Sleep(); + touchPanel.Sleep(); + twiMaster.Sleep(); } - // No Wake uo mode, we can put the twi to sleep - if ( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None ) { - //twiMaster.Sleep(); - } - isSleeping = true; isGoingToSleep = false; break; @@ -281,10 +281,10 @@ void SystemTask::OnTouchEvent() { GoToRunning(); } else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { // error - /*auto info = touchPanel.GetTouchInfo(); + auto info = touchPanel.GetTouchInfo(); if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) { GoToRunning(); - }*/ + } } } } -- cgit v1.2.3-70-g09d2 From f8b9a7c06081df68b34defd8df4a5ae39b390237 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sun, 4 Apr 2021 17:19:41 +0200 Subject: Fix music app : - Enable LVGL animation (and disable groups, which were not used), and set the speed. - Fix disc animation and progress display by initializing lastIncrement at 0 (a random value will be used otherwise, in release build) --- src/components/ble/MusicService.cpp | 2 +- src/displayapp/screens/Music.cpp | 22 +++++++++++++--------- src/displayapp/screens/Music.h | 2 +- src/libs/lv_conf.h | 4 ++-- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/displayapp/screens') diff --git a/src/components/ble/MusicService.cpp b/src/components/ble/MusicService.cpp index bd6e27fb..b02e743a 100644 --- a/src/components/ble/MusicService.cpp +++ b/src/components/ble/MusicService.cpp @@ -164,7 +164,7 @@ Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask & artistName = "Waiting for"; albumName = ""; - trackName = "track information..."; + trackName = "track information.."; playing = false; repeat = false; shuffle = false; diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index b68f3781..2a0aa052 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -98,24 +98,28 @@ Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Mus lv_label_set_text(txtTrackDuration, "--:--/--:--"); lv_label_set_align(txtTrackDuration, LV_ALIGN_IN_LEFT_MID); lv_obj_set_width(txtTrackDuration, LV_HOR_RES); - + constexpr uint8_t FONT_HEIGHT = 12; constexpr uint8_t LINE_PAD = 15; constexpr int8_t MIDDLE_OFFSET = -25; txtArtist = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); + lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL_CIRC); + lv_label_set_anim_speed(txtArtist, 1); lv_obj_align(txtArtist, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 1 * FONT_HEIGHT); - lv_label_set_text(txtArtist, "Artist Name"); lv_label_set_align(txtArtist, LV_ALIGN_IN_LEFT_MID); - lv_obj_set_width(txtArtist, LV_HOR_RES); - + lv_obj_set_width(txtArtist, LV_HOR_RES-12); + lv_label_set_text(txtArtist, "Artist Name"); + + txtTrack = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL); + lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL_CIRC); + lv_label_set_anim_speed(txtTrack, 1); lv_obj_align(txtTrack, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 2 * FONT_HEIGHT + LINE_PAD); - lv_label_set_text(txtTrack, "This is a very long getTrack name"); + lv_label_set_align(txtTrack, LV_ALIGN_IN_LEFT_MID); - lv_obj_set_width(txtTrack, LV_HOR_RES); - + lv_obj_set_width(txtTrack, LV_HOR_RES-12); + lv_label_set_text(txtTrack, "This is a very long getTrack name"); + /** Init animation */ imgDisc = lv_img_create(lv_scr_act(), nullptr); lv_img_set_src_arr(imgDisc, &disc); diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index 66bde21b..c4f4cbef 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -76,7 +76,7 @@ namespace Pinetime { /** Last length */ int lastLength; /** Last time an animation update or timer was incremented */ - TickType_t lastIncrement; + TickType_t lastIncrement = 0; bool playing; diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 7a800b31..e16769cd 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -140,7 +140,7 @@ typedef int16_t lv_coord_t; *==================*/ /*1: Enable the Animations */ -#define LV_USE_ANIMATION 0 +#define LV_USE_ANIMATION 1 #if LV_USE_ANIMATION /*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ @@ -177,7 +177,7 @@ typedef void* lv_anim_user_data_t; #define LV_USE_IMG_TRANSFORM 0 /* 1: Enable object groups (for keyboard/encoder navigation) */ -#define LV_USE_GROUP 1 +#define LV_USE_GROUP 0 #if LV_USE_GROUP typedef void* lv_group_user_data_t; #endif /*LV_USE_GROUP*/ -- cgit v1.2.3-70-g09d2 From 96961709f3a659fd89ccbb8a13813ed9f3c586eb Mon Sep 17 00:00:00 2001 From: Joaquim José Almeida Pereira Date: Mon, 5 Apr 2021 11:01:44 +0100 Subject: array in SettingWakeUp wrong size --- src/displayapp/screens/settings/SettingWakeUp.h | 2 +- src/drivers/TwiMaster.cpp | 2 +- src/systemtask/SystemTask.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/displayapp/screens') diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 99ddd363..86b52837 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -22,7 +22,7 @@ namespace Pinetime { Controllers::Settings& settingsController; uint8_t optionsTotal; - lv_obj_t * cbOption[3]; + lv_obj_t * cbOption[4]; }; } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index d5898b5e..072dd5fc 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -63,8 +63,8 @@ void TwiMaster::Init() { TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) { // this is causing an error when came from sleep + // //xSemaphoreTake(mutex, portMAX_DELAY); - auto ret = ReadWithRetry(deviceAddress, registerAddress, data, size); //xSemaphoreGive(mutex); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 2aa071dc..43e6f082 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -280,7 +280,7 @@ void SystemTask::OnTouchEvent() { if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap ) { GoToRunning(); } else if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { - // error + auto info = touchPanel.GetTouchInfo(); if( info.isTouch and info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap ) { GoToRunning(); -- cgit v1.2.3-70-g09d2 From 3cf4df905a20a51939141430e155c9d8e6623e30 Mon Sep 17 00:00:00 2001 From: Joaquim Date: Thu, 8 Apr 2021 16:15:57 +0100 Subject: restore battery buffer --- src/components/battery/BatteryController.cpp | 10 ++----- src/components/battery/BatteryController.h | 40 ++++++++++++++++++++++++++-- src/displayapp/screens/Twos.cpp | 3 +-- 3 files changed, 41 insertions(+), 12 deletions(-) (limited to 'src/displayapp/screens') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index beca95c4..4a7a2345 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -66,6 +66,8 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { percentRemaining = std::max(percentRemaining, 0); percentRemaining = std::min(percentRemaining, 100); + percentRemainingBuffer.insert(percentRemaining); + nrfx_saadc_uninit(); } } @@ -73,11 +75,3 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) { void Battery::adcCallbackStatic(nrfx_saadc_evt_t const *event) { instance->SaadcEventHandler(event); } - -int Battery::PercentRemaining() { - return percentRemaining; -} - -float Battery::Voltage() { - return voltage; -} \ No newline at end of file diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 6a0c7dff..2776687b 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -7,6 +7,38 @@ namespace Pinetime { namespace Controllers { + /** A simple circular buffer that can be used to average + out the sensor values. The total capacity of the CircBuffer + is given as the template parameter N. + */ + template + class CircBuffer { + public: + CircBuffer() : arr{}, sz{}, cap{N}, head{} {} + /** + insert member function overwrites the next data to the current + HEAD and moves the HEAD to the newly inserted value. + */ + void insert(const int num) { + head %= cap; + arr[head++] = num; + if (sz != cap) { + sz++; + } + } + + int GetAverage() const { + int sum = std::accumulate(arr.begin(), arr.end(), 0); + return (sum / sz); + } + + private: + std::array arr; /**< internal array used to store the values*/ + uint8_t sz; /**< The current size of the array.*/ + uint8_t cap; /**< Total capacity of the CircBuffer.*/ + uint8_t head; /**< The current head of the CircBuffer*/ + }; + class Battery { public: @@ -15,8 +47,9 @@ namespace Pinetime { void Init(); void Update(); - int PercentRemaining(); - float Voltage(); + int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); } + + float Voltage() const { return voltage; } bool IsCharging() const { return isCharging; } bool IsPowerPresent() const { return isPowerPresent; } @@ -24,6 +57,9 @@ namespace Pinetime { private: static Battery *instance; nrf_saadc_value_t saadc_value; + + static constexpr uint8_t percentRemainingSamples = 10; + CircBuffer percentRemainingBuffer {}; static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; diff --git a/src/displayapp/screens/Twos.cpp b/src/displayapp/screens/Twos.cpp index 5210a4d6..7a3ed1e4 100644 --- a/src/displayapp/screens/Twos.cpp +++ b/src/displayapp/screens/Twos.cpp @@ -153,8 +153,7 @@ bool Twos::tryMove(Tile grid[][4], int newRow, int newCol, int oldRow, int oldCo } bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - bool validMove; - validMove = false; + bool validMove = false; for(int row = 0; row < 4; row++) { for(int col = 0; col < 4; col++) { grid[row][col].merged = false; // reinitialize merge state -- cgit v1.2.3-70-g09d2