diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37ee0848bd..455efb20e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -433,6 +433,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingDisplay.cpp displayapp/screens/settings/SettingSteps.cpp displayapp/screens/settings/SettingPineTimeStyle.cpp + displayapp/screens/settings/SettingBatteryFormat.cpp ## Watch faces displayapp/icons/bg_clock.c diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index a54ba9760e..054d010b75 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -12,6 +12,8 @@ namespace Pinetime { public: enum class ClockType : uint8_t { H24, H12 }; enum class Vibration : uint8_t { ON, OFF }; + enum class BatteryPercentage : u_int8_t { ON, OFF }; + enum class BatteryColor : u_int8_t { ON, OFF }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, @@ -103,6 +105,26 @@ namespace Pinetime { return settings.vibrationStatus; }; + void SetBatteryPercentageStatus(BatteryPercentage status) { + if (status != settings.batteryPercentageStatus) { + settingsChanged = true; + } + settings.batteryPercentageStatus = status; + }; + BatteryPercentage GetBatteryPercentageStatus() const { + return settings.batteryPercentageStatus; + }; + + void SetBatteryColorStatus(BatteryColor status) { + if (status != settings.batteryColorStatus) { + settingsChanged = true; + } + settings.batteryColorStatus = status; + }; + BatteryColor GetBatteryColorStatus() const { + return settings.batteryColorStatus; + }; + void SetScreenTimeOut(uint32_t timeout) { if (timeout != settings.screenTimeOut) { settingsChanged = true; @@ -171,6 +193,8 @@ namespace Pinetime { ClockType clockType = ClockType::H24; Vibration vibrationStatus = Vibration::ON; + BatteryPercentage batteryPercentageStatus = BatteryPercentage::OFF; + BatteryColor batteryColorStatus = BatteryColor::OFF; uint8_t clockFace = 0; diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index e3aca8cf00..ba65fbeaa8 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -32,7 +32,8 @@ namespace Pinetime { SettingDisplay, SettingWakeUp, SettingSteps, - SettingPineTimeStyle + SettingPineTimeStyle, + SettingBatteryFormat }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 9d47310197..a780f881e0 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -44,6 +44,7 @@ #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" #include "displayapp/screens/settings/SettingPineTimeStyle.h" +#include "displayapp/screens/settings/SettingBatteryFormat.h" #include "libs/lv_conf.h" @@ -382,6 +383,10 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; + case Apps::SettingBatteryFormat: + currentScreen = std::make_unique(this, settingsController); + ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); + break; case Apps::BatteryInfo: currentScreen = std::make_unique(this, batteryController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index c67bcb2317..411328df4e 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -1,4 +1,5 @@ #include +#include #include "BatteryIcon.h" #include "Symbols.h" @@ -20,6 +21,20 @@ const char* BatteryIcon::GetUnknownIcon() { return Symbols::batteryEmpty; } +const lv_color_t BatteryIcon::GetBatteryColor(uint8_t batteryPercent) { + if (batteryPercent > 75) + return LV_COLOR_GREEN; + if (batteryPercent > 50) + return LV_COLOR_YELLOW; + if (batteryPercent > 25) + return LV_COLOR_ORANGE; + return LV_COLOR_RED; +} + +const lv_color_t BatteryIcon::GetDefaultBatteryColor() { + return LV_COLOR_WHITE; +} + const char* BatteryIcon::GetPlugIcon(bool isCharging) { if (isCharging) return Symbols::plug; diff --git a/src/displayapp/screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h index b370b331d2..c5bb5a3074 100644 --- a/src/displayapp/screens/BatteryIcon.h +++ b/src/displayapp/screens/BatteryIcon.h @@ -7,6 +7,8 @@ namespace Pinetime { public: static const char* GetUnknownIcon(); static const char* GetBatteryIcon(uint8_t batteryPercent); + static const lv_color_t GetBatteryColor(uint8_t batteryPercent); + static const lv_color_t GetDefaultBatteryColor(); static const char* GetPlugIcon(bool isCharging); }; } diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 75e35c1bdc..f12ef54b90 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -69,6 +69,10 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app, lv_label_set_text(batteryIcon, Symbols::batteryHalf); lv_obj_align(batteryIcon, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 0); + batteryValue = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(batteryValue, ""); + lv_obj_align(batteryValue, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + notificationIcon = lv_label_create(lv_scr_act(), NULL); lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00)); lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); @@ -181,6 +185,18 @@ void WatchFaceAnalog::Refresh() { if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + + if (settingsController.GetBatteryColorStatus() == Controllers::Settings::BatteryColor::ON) { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, BatteryIcon::GetBatteryColor(batteryPercent)); + } else { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, BatteryIcon::GetDefaultBatteryColor()); + } + + if (settingsController.GetBatteryPercentageStatus() == Controllers::Settings::BatteryPercentage::ON) { + lv_label_set_text_fmt(batteryValue, "%lu", batteryPercent); + } else { + lv_label_set_text(batteryValue, ""); + } } notificationState = notificationManager.AreNewNotificationsAvailable(); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 406f4d50a7..409008e86c 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -72,6 +72,7 @@ namespace Pinetime { lv_obj_t* label_date_day; lv_obj_t* batteryIcon; + lv_obj_t* batteryValue; lv_obj_t* notificationIcon; Controllers::DateTime& dateTimeController; diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 58ab619035..e9d8743900 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -37,10 +37,14 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app, lv_label_set_text(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); + batteryValue = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text(batteryValue, ""); + lv_obj_align(batteryValue, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + batteryPlug = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); lv_label_set_text(batteryPlug, Symbols::plug); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_align(batteryPlug, batteryValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0000FF)); @@ -106,6 +110,19 @@ void WatchFaceDigital::Refresh() { if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent)); + + if (settingsController.GetBatteryColorStatus() == Controllers::Settings::BatteryColor::ON) { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, BatteryIcon::GetBatteryColor(batteryPercent)); + } else { + lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, BatteryIcon::GetDefaultBatteryColor()); + } + + if (settingsController.GetBatteryPercentageStatus() == Controllers::Settings::BatteryPercentage::ON) { + lv_label_set_text_fmt(batteryValue, "%lu%%", batteryPercent); + } else { + lv_label_set_text(batteryValue, ""); + } + auto isCharging = batteryController.IsCharging() or batteryController.IsPowerPresent(); lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging)); } @@ -115,7 +132,8 @@ void WatchFaceDigital::Refresh() { lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get())); } lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0); - lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_align(batteryValue, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); + lv_obj_align(batteryPlug, batteryValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); notificationState = notificatioManager.AreNewNotificationsAvailable(); diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 48dc13731a..9a7eca58dd 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -57,6 +57,7 @@ namespace Pinetime { lv_obj_t* label_date; lv_obj_t* backgroundLabel; lv_obj_t* batteryIcon; + lv_obj_t* batteryValue; lv_obj_t* bleIcon; lv_obj_t* batteryPlug; lv_obj_t* heartbeatIcon; diff --git a/src/displayapp/screens/settings/SettingBatteryFormat.cpp b/src/displayapp/screens/settings/SettingBatteryFormat.cpp new file mode 100644 index 0000000000..42075f16c6 --- /dev/null +++ b/src/displayapp/screens/settings/SettingBatteryFormat.cpp @@ -0,0 +1,95 @@ +#include "SettingBatteryFormat.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) { + SettingBatteryFormat* screen = static_cast(obj->user_data); + screen->UpdateSelected(obj, event); + } +} + +SettingBatteryFormat::SettingBatteryFormat(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, "Battery style"); + 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::batteryThreeQuarter); + 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], " Show percent"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetBatteryPercentageStatus() == Controllers::Settings::BatteryPercentage::ON) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + + optionsTotal++; + cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text_static(cbOption[optionsTotal], " Colorful icon"); + cbOption[optionsTotal]->user_data = this; + lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); + if (settingsController.GetBatteryColorStatus() == Controllers::Settings::BatteryColor::ON) { + lv_checkbox_set_checked(cbOption[optionsTotal], true); + } + optionsTotal++; +} + +SettingBatteryFormat::~SettingBatteryFormat() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingBatteryFormat::UpdateSelected(lv_obj_t* object, lv_event_t event) { + if (event == LV_EVENT_VALUE_CHANGED) { + int index = 0; + for (; index < optionsTotal; ++index) { + if (cbOption[index] == object) { + break; + } + } + + if (index == 0) { + if (settingsController.GetBatteryPercentageStatus() == Controllers::Settings::BatteryPercentage::ON) { + settingsController.SetBatteryPercentageStatus(Controllers::Settings::BatteryPercentage::OFF); + lv_checkbox_set_checked(cbOption[index], false); + } else { + settingsController.SetBatteryPercentageStatus(Controllers::Settings::BatteryPercentage::ON); + lv_checkbox_set_checked(cbOption[index], true); + } + }; + if (index == 1) { + if (settingsController.GetBatteryColorStatus() == Controllers::Settings::BatteryColor::ON) { + settingsController.SetBatteryColorStatus(Controllers::Settings::BatteryColor::OFF); + lv_checkbox_set_checked(cbOption[index], false); + } else { + settingsController.SetBatteryColorStatus(Controllers::Settings::BatteryColor::ON); + lv_checkbox_set_checked(cbOption[index], true); + } + }; + } +} diff --git a/src/displayapp/screens/settings/SettingBatteryFormat.h b/src/displayapp/screens/settings/SettingBatteryFormat.h new file mode 100644 index 0000000000..82c67a7528 --- /dev/null +++ b/src/displayapp/screens/settings/SettingBatteryFormat.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingBatteryFormat : public Screen { + public: + SettingBatteryFormat(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + ~SettingBatteryFormat() override; + + void UpdateSelected(lv_obj_t* object, lv_event_t event); + + private: + Controllers::Settings& settingsController; + uint8_t optionsTotal; + lv_obj_t* cbOption[1]; + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index e3319f030a..aac3da1cfc 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -50,8 +50,8 @@ std::unique_ptr Settings::CreateScreen2() { std::array applications {{ {Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, + {Symbols::batteryThreeQuarter, "Battery style", Apps::SettingBatteryFormat}, {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, - {Symbols::check, "Firmware", Apps::FirmwareValidation}, }}; return std::make_unique(1, 3, app, settingsController, applications); @@ -60,10 +60,10 @@ std::unique_ptr Settings::CreateScreen2() { std::unique_ptr Settings::CreateScreen3() { std::array applications {{ + {Symbols::check, "Firmware", Apps::FirmwareValidation}, {Symbols::list, "About", Apps::SysInfo}, {Symbols::none, "None", Apps::None}, - {Symbols::none, "None", Apps::None}, - {Symbols::none, "None", Apps::None}, + {Symbols::none, "None", Apps::None} }}; return std::make_unique(2, 3, app, settingsController, applications);