diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 3b113eada9..8f65147f7f 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -209,10 +209,18 @@ namespace Pinetime { return bleRadioEnabled; }; + void SetShowBatteryPercentage(bool enabled) { + settings.showBatteryPercentage = enabled; + } + + bool GetShowBatteryPercentage() { + return settings.showBatteryPercentage; + } + private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0003; + static constexpr uint32_t settingsVersion = 0x0004; struct SettingsData { uint32_t version = settingsVersion; uint32_t stepsGoal = 10000; @@ -229,6 +237,7 @@ namespace Pinetime { std::bitset<4> wakeUpMode {0}; uint16_t shakeWakeThreshold = 150; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; + bool showBatteryPercentage = false; }; SettingsData settings; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 3174a65832..b873db2acb 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -424,7 +424,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::BatteryInfo: - currentScreen = std::make_unique(this, batteryController); + currentScreen = std::make_unique(this, batteryController, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SysInfo: diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index 2fe7c25195..4e572b644f 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -6,7 +6,15 @@ using namespace Pinetime::Applications::Screens; void BatteryIcon::Create(lv_obj_t* parent) { - batteryImg = lv_img_create(parent, nullptr); + + batteryContainer = lv_cont_create(parent, nullptr); + lv_cont_set_layout(batteryContainer, LV_LAYOUT_ROW_MID); + lv_cont_set_fit(batteryContainer, LV_FIT_TIGHT); + lv_obj_set_style_local_bg_color(batteryContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); + lv_obj_set_style_local_pad_inner(batteryContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_pad_hor(batteryContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + batteryImg = lv_img_create(batteryContainer, nullptr); lv_img_set_src(batteryImg, &batteryicon); lv_obj_set_style_local_image_recolor(batteryImg, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); @@ -14,15 +22,26 @@ void BatteryIcon::Create(lv_obj_t* parent) { lv_obj_set_width(batteryJuice, 8); lv_obj_align(batteryJuice, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -2, -2); lv_obj_set_style_local_radius(batteryJuice, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0); + + batteryPercentageText = lv_label_create(batteryContainer, nullptr); + lv_label_set_text(batteryPercentageText, ""); + lv_obj_align(batteryPercentageText, batteryContainer, LV_ALIGN_IN_RIGHT_MID, 0, 0); } lv_obj_t* BatteryIcon::GetObject() { - return batteryImg; + return batteryContainer; } -void BatteryIcon::SetBatteryPercentage(uint8_t percentage) { +void BatteryIcon::SetBatteryPercentage(uint8_t percentage, bool show_percentage) { lv_obj_set_height(batteryJuice, percentage * 14 / 100); lv_obj_realign(batteryJuice); + if (show_percentage) { + lv_label_set_text_fmt(batteryPercentageText, "%02i%%", percentage); + } else { + lv_label_set_text(batteryPercentageText, ""); + } + lv_obj_realign(batteryPercentageText); + lv_obj_realign(batteryContainer); } void BatteryIcon::SetColor(lv_color_t color) { @@ -32,8 +51,8 @@ void BatteryIcon::SetColor(lv_color_t color) { } const char* BatteryIcon::GetPlugIcon(bool isCharging) { - if (isCharging) + if (isCharging) { return Symbols::plug; - else - return ""; + } + return ""; } diff --git a/src/displayapp/screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h index 45d8f0efe7..99bd839020 100644 --- a/src/displayapp/screens/BatteryIcon.h +++ b/src/displayapp/screens/BatteryIcon.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include "components/settings/Settings.h" namespace Pinetime { namespace Applications { @@ -10,15 +11,17 @@ namespace Pinetime { void Create(lv_obj_t* parent); void SetColor(lv_color_t); - void SetBatteryPercentage(uint8_t percentage); + void SetBatteryPercentage(uint8_t percentage, bool show_percentage); lv_obj_t* GetObject(); static const char* GetUnknownIcon(); static const char* GetPlugIcon(bool isCharging); private: + lv_obj_t* batteryContainer; lv_obj_t* batteryImg; lv_obj_t* batteryJuice; + lv_obj_t* batteryPercentageText; }; } } diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index d9d479f8b1..4621887d93 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -4,8 +4,19 @@ using namespace Pinetime::Applications::Screens; -BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Battery& batteryController) - : Screen(app), batteryController {batteryController} { +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + if (event == LV_EVENT_VALUE_CHANGED) { + auto* battery = static_cast(obj->user_data); + battery->ToggleBatteryPercentState(); + } + } +} + +BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::Settings& settingsController) + : Screen(app), batteryController {batteryController}, settingsController {settingsController} { batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); @@ -13,7 +24,7 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont 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_obj_align(charging_bar, nullptr, LV_ALIGN_CENTER, 0, -30); lv_bar_set_anim_time(charging_bar, 1000); 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)); @@ -27,22 +38,31 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont 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); + lv_obj_set_style_local_text_font(percent, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_fmt(percent, "%02i%%", batteryPercent); lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT); - lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60); + lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -70); 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_MAKE(0xff, 0xb0, 0x0)); lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER); - lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95); + lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 55); + + show_percentage_checkbox = lv_checkbox_create(lv_scr_act(), nullptr); + lv_checkbox_set_text(show_percentage_checkbox, "Show %"); + lv_obj_align(show_percentage_checkbox, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, -5); + lv_obj_add_state(show_percentage_checkbox, LV_STATE_DEFAULT); + lv_checkbox_set_checked(show_percentage_checkbox, settingsController.GetShowBatteryPercentage()); + show_percentage_checkbox->user_data = this; + lv_obj_set_event_cb(show_percentage_checkbox, event_handler); taskRefresh = lv_task_create(RefreshTaskCallback, 5000, LV_TASK_PRIO_MID, this); Refresh(); } BatteryInfo::~BatteryInfo() { + settingsController.SaveSettings(); lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); } @@ -72,3 +92,8 @@ void BatteryInfo::Refresh() { lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); } + +void BatteryInfo::ToggleBatteryPercentState() { + settingsController.SetShowBatteryPercentage(!settingsController.GetShowBatteryPercentage()); + lv_checkbox_set_checked(show_percentage_checkbox, settingsController.GetShowBatteryPercentage()); +} diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index de34cdffac..cfa9b9db0f 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -2,6 +2,7 @@ #include #include "displayapp/screens/Screen.h" +#include "components/settings/Settings.h" #include namespace Pinetime { @@ -14,14 +15,19 @@ namespace Pinetime { class BatteryInfo : public Screen { public: - BatteryInfo(DisplayApp* app, Pinetime::Controllers::Battery& batteryController); + BatteryInfo(DisplayApp* app, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::Settings& settingsController); ~BatteryInfo() override; void Refresh() override; + void ToggleBatteryPercentState(); private: Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::Settings& settingsController; + lv_obj_t* show_percentage_checkbox; lv_obj_t* voltage; lv_obj_t* percent; lv_obj_t* charging_bar; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index c633e17bb9..cc7cc367ab 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -29,7 +29,11 @@ Tile::Tile(uint8_t screenID, Pinetime::Controllers::Battery& batteryController, Controllers::DateTime& dateTimeController, std::array& applications) - : Screen(app), batteryController {batteryController}, dateTimeController {dateTimeController}, pageIndicator(screenID, numScreens) { + : Screen(app), + batteryController {batteryController}, + settingsController(settingsController), + dateTimeController {dateTimeController}, + pageIndicator(screenID, numScreens) { settingsController.SetAppMenu(screenID); @@ -93,7 +97,7 @@ Tile::~Tile() { void Tile::UpdateScreen() { lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str()); - batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining()); + batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining(), settingsController.GetShowBatteryPercentage()); } void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index ff121376c5..5e6083cb6c 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -37,6 +37,7 @@ namespace Pinetime { private: Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::Settings& settingsController; Controllers::DateTime& dateTimeController; lv_task_t* taskUpdate; diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 251a560f6e..e81839a407 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -182,7 +182,7 @@ void WatchFaceAnalog::UpdateClock() { void WatchFaceAnalog::SetBatteryIcon() { auto batteryPercent = batteryPercentRemaining.Get(); - batteryIcon.SetBatteryPercentage(batteryPercent); + batteryIcon.SetBatteryPercentage(batteryPercent, settingsController.GetShowBatteryPercentage()); } void WatchFaceAnalog::Refresh() { diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index d10f8532af..33809c7e83 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -102,7 +102,7 @@ void WatchFaceDigital::Refresh() { batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); - batteryIcon.SetBatteryPercentage(batteryPercent); + batteryIcon.SetBatteryPercentage(batteryPercent, settingsController.GetShowBatteryPercentage()); } bleState = bleController.IsConnected(); diff --git a/src/displayapp/screens/WatchFacePineTimeStyle.cpp b/src/displayapp/screens/WatchFacePineTimeStyle.cpp index 63b421da10..9fc4b1e097 100644 --- a/src/displayapp/screens/WatchFacePineTimeStyle.cpp +++ b/src/displayapp/screens/WatchFacePineTimeStyle.cpp @@ -329,7 +329,7 @@ bool WatchFacePineTimeStyle::OnButtonPushed() { void WatchFacePineTimeStyle::SetBatteryIcon() { auto batteryPercent = batteryPercentRemaining.Get(); - batteryIcon.SetBatteryPercentage(batteryPercent); + batteryIcon.SetBatteryPercentage(batteryPercent, settingsController.GetShowBatteryPercentage()); } void WatchFacePineTimeStyle::AlignIcons() { diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 708d5109a5..eca3022dbf 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -118,7 +118,7 @@ QuickSettings::~QuickSettings() { void QuickSettings::UpdateScreen() { lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str()); - batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining()); + batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining(), settingsController.GetShowBatteryPercentage()); } void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) {