InfiniTime.git

commit edba1d9ccfb2b16c26b12428acb71425f4f41cd5

Author: Riku Isokoski <riksu9000@gmail.com>

Add status icons widget

 src/CMakeLists.txt | 2 
 src/displayapp/DisplayApp.cpp | 6 +
 src/displayapp/screens/ApplicationList.cpp | 11 +++
 src/displayapp/screens/ApplicationList.h | 2 
 src/displayapp/screens/Tile.cpp | 19 +++--
 src/displayapp/screens/Tile.h | 10 +-
 src/displayapp/screens/WatchFaceDigital.cpp | 40 +----------
 src/displayapp/screens/WatchFaceDigital.h | 9 --
 src/displayapp/screens/settings/QuickSettings.cpp | 15 ++--
 src/displayapp/screens/settings/QuickSettings.h | 13 ++-
 src/displayapp/widgets/StatusIcons.cpp | 55 +++++++++++++++++
 src/displayapp/widgets/StatusIcons.h | 38 +++++++++++


diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6069aca61ae5d0dbd89fb13e275b5081644e60df..e6971a56246e8dc7151b5cda1450517ed5a90e1e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -406,6 +406,7 @@         displayapp/screens/Styles.cpp
         displayapp/Colors.cpp
         displayapp/widgets/Counter.cpp
         displayapp/widgets/PageIndicator.cpp
+        displayapp/widgets/StatusIcons.cpp
 
         ## Settings
         displayapp/screens/settings/QuickSettings.cpp
@@ -611,6 +612,7 @@         displayapp/screens/Alarm.h
         displayapp/Colors.h
         displayapp/widgets/Counter.h
         displayapp/widgets/PageIndicator.h
+        displayapp/widgets/StatusIcons.h
         drivers/St7789.h
         drivers/SpiNorFlash.h
         drivers/SpiMaster.h




diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index 93d7277d813cccc0eab921f148877c4abeb428a4..d5cc98108c6a3245bd8638130018e5d5a6539d44 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -311,7 +311,8 @@   ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::SwipeDown);
 
   switch (app) {
     case Apps::Launcher:
-      currentScreen = std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, dateTimeController);
+      currentScreen =
+        std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, bleController, dateTimeController);
       ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown);
       break;
     case Apps::None:
@@ -377,7 +378,8 @@                                                                batteryController,
                                                                dateTimeController,
                                                                brightnessController,
                                                                motorController,
-                                                               settingsController);
+                                                               settingsController,
+                                                               bleController);
       ReturnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft);
       break;
     case Apps::Settings:




diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp
index 9fd408e11a8d66990325ac1282e07c0375edd7e9..9f3e9568e578ec6ad3c3234ade8fc29d27474fda 100644
--- a/src/displayapp/screens/ApplicationList.cpp
+++ b/src/displayapp/screens/ApplicationList.cpp
@@ -21,10 +21,12 @@
 ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app,
                                  Pinetime::Controllers::Settings& settingsController,
                                  Pinetime::Controllers::Battery& batteryController,
+                                 Pinetime::Controllers::Ble& bleController,
                                  Controllers::DateTime& dateTimeController)
   : Screen(app),
     settingsController {settingsController},
     batteryController {batteryController},
+    bleController {bleController},
     dateTimeController {dateTimeController},
     screens {app, settingsController.GetAppMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} {
 }
@@ -43,5 +45,12 @@   for (int i = 0; i < appsPerScreen; i++) {
     apps[i] = applications[screenNum * appsPerScreen + i];
   }
 
-  return std::make_unique<Screens::Tile>(screenNum, nScreens, app, settingsController, batteryController, dateTimeController, apps);
+  return std::make_unique<Screens::Tile>(screenNum,
+                                         nScreens,
+                                         app,
+                                         settingsController,
+                                         batteryController,
+                                         bleController,
+                                         dateTimeController,
+                                         apps);
 }




diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h
index 14d7623cd948ef58aa8bcbc579d505718153c0f9..e7c094bffe8b9068b71f8367c9a05f7dcbf7b778 100644
--- a/src/displayapp/screens/ApplicationList.h
+++ b/src/displayapp/screens/ApplicationList.h
@@ -19,6 +19,7 @@       public:
         explicit ApplicationList(DisplayApp* app,
                                  Pinetime::Controllers::Settings& settingsController,
                                  Pinetime::Controllers::Battery& batteryController,
+                                 Pinetime::Controllers::Ble& bleController,
                                  Controllers::DateTime& dateTimeController);
         ~ApplicationList() override;
         bool OnTouchEvent(TouchEvents event) override;
@@ -29,6 +30,7 @@         std::unique_ptr CreateScreen(unsigned int screenNum) const;
 
         Controllers::Settings& settingsController;
         Pinetime::Controllers::Battery& batteryController;
+        Pinetime::Controllers::Ble& bleController;
         Controllers::DateTime& dateTimeController;
 
         static constexpr int appsPerScreen = 6;




diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp
index c633e17bb92467bc206bf1885a54b4bb94e347e8..2af04ab06fc077730b22c07a322ae977d2514659 100644
--- a/src/displayapp/screens/Tile.cpp
+++ b/src/displayapp/screens/Tile.cpp
@@ -1,6 +1,7 @@
 #include "displayapp/screens/Tile.h"
 #include "displayapp/DisplayApp.h"
 #include "displayapp/screens/BatteryIcon.h"
+#include "components/ble/BleController.h"
 
 using namespace Pinetime::Applications::Screens;
 
@@ -26,21 +27,25 @@ Tile::Tile(uint8_t screenID,
            uint8_t numScreens,
            DisplayApp* app,
            Controllers::Settings& settingsController,
-           Pinetime::Controllers::Battery& batteryController,
+           Controllers::Battery& batteryController,
+           Controllers::Ble& bleController,
            Controllers::DateTime& dateTimeController,
            std::array<Applications, 6>& applications)
-  : Screen(app), batteryController {batteryController}, dateTimeController {dateTimeController}, pageIndicator(screenID, numScreens) {
+  : Screen(app),
+    dateTimeController {dateTimeController},
+    pageIndicator(screenID, numScreens),
+    statusIcons(batteryController, bleController) {
 
   settingsController.SetAppMenu(screenID);
 
+  statusIcons.Create();
+  lv_obj_align(statusIcons.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -8, 0);
+  statusIcons.Align();
+
   // Time
   label_time = lv_label_create(lv_scr_act(), nullptr);
   lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
   lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
-
-  // Battery
-  batteryIcon.Create(lv_scr_act());
-  lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, -8, 0);
 
   pageIndicator.Create();
 
@@ -93,7 +98,7 @@ }
 
 void Tile::UpdateScreen() {
   lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str());
-  batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining());
+  statusIcons.Update();
 }
 
 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 ff121376c51b641341ca360ab87869c46afc1089..d8a6812819b12a658f741987d56c1de51673df1c 100644
--- a/src/displayapp/screens/Tile.h
+++ b/src/displayapp/screens/Tile.h
@@ -7,10 +7,9 @@ #include "displayapp/screens/Screen.h"
 #include "displayapp/Apps.h"
 #include "components/datetime/DateTimeController.h"
 #include "components/settings/Settings.h"
-#include "components/datetime/DateTimeController.h"
 #include "components/battery/BatteryController.h"
-#include "displayapp/screens/BatteryIcon.h"
 #include "displayapp/widgets/PageIndicator.h"
+#include "displayapp/widgets/StatusIcons.h"
 
 namespace Pinetime {
   namespace Applications {
@@ -26,7 +25,8 @@         explicit Tile(uint8_t screenID,
                       uint8_t numScreens,
                       DisplayApp* app,
                       Controllers::Settings& settingsController,
-                      Pinetime::Controllers::Battery& batteryController,
+                      Controllers::Battery& batteryController,
+                      Controllers::Ble& bleController,
                       Controllers::DateTime& dateTimeController,
                       std::array<Applications, 6>& applications);
 
@@ -36,7 +36,6 @@         void UpdateScreen();
         void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId);
 
       private:
-        Pinetime::Controllers::Battery& batteryController;
         Controllers::DateTime& dateTimeController;
 
         lv_task_t* taskUpdate;
@@ -45,8 +44,7 @@         lv_obj_t* label_time;
         lv_obj_t* btnm1;
 
         Widgets::PageIndicator pageIndicator;
-
-        BatteryIcon batteryIcon;
+        Widgets::StatusIcons statusIcons;
 
         const char* btnmMap[8];
         Pinetime::Applications::Apps apps[6];




diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp
index d10f8532af9cba115e2b3f56fee6896904bca501..7e876d8f6e973351722fe164d59711cfe302504e 100644
--- a/src/displayapp/screens/WatchFaceDigital.cpp
+++ b/src/displayapp/screens/WatchFaceDigital.cpp
@@ -3,8 +3,6 @@
 #include <date/date.h>
 #include <lvgl/lvgl.h>
 #include <cstdio>
-#include "displayapp/screens/BatteryIcon.h"
-#include "displayapp/screens/BleIcon.h"
 #include "displayapp/screens/NotificationIcon.h"
 #include "displayapp/screens/Symbols.h"
 #include "components/battery/BatteryController.h"
@@ -13,6 +11,7 @@ #include "components/ble/NotificationManager.h"
 #include "components/heartrate/HeartRateController.h"
 #include "components/motion/MotionController.h"
 #include "components/settings/Settings.h"
+
 using namespace Pinetime::Applications::Screens;
 
 WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
@@ -26,25 +25,13 @@                                    Controllers::MotionController& motionController)
   : Screen(app),
     currentDateTime {{}},
     dateTimeController {dateTimeController},
-    batteryController {batteryController},
-    bleController {bleController},
     notificatioManager {notificatioManager},
     settingsController {settingsController},
     heartRateController {heartRateController},
-    motionController {motionController} {
-
-  batteryIcon.Create(lv_scr_act());
-  lv_obj_align(batteryIcon.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 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_static(batteryPlug, Symbols::plug);
-  lv_obj_align(batteryPlug, batteryIcon.GetObject(), LV_ALIGN_OUT_LEFT_MID, -5, 0);
+    motionController {motionController},
+    statusIcons(batteryController, bleController) {
 
-  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(0x0082FC));
-  lv_label_set_text_static(bleIcon, Symbols::bluetooth);
-  lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+  statusIcons.Create();
 
   notificationIcon = lv_label_create(lv_scr_act(), nullptr);
   lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
@@ -94,24 +81,7 @@   lv_obj_clean(lv_scr_act());
 }
 
 void WatchFaceDigital::Refresh() {
-  powerPresent = batteryController.IsPowerPresent();
-  if (powerPresent.IsUpdated()) {
-    lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
-  }
-
-  batteryPercentRemaining = batteryController.PercentRemaining();
-  if (batteryPercentRemaining.IsUpdated()) {
-    auto batteryPercent = batteryPercentRemaining.Get();
-    batteryIcon.SetBatteryPercentage(batteryPercent);
-  }
-
-  bleState = bleController.IsConnected();
-  bleRadioEnabled = bleController.IsRadioEnabled();
-  if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
-    lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get()));
-  }
-  lv_obj_realign(batteryPlug);
-  lv_obj_realign(bleIcon);
+  statusIcons.Update();
 
   notificationState = notificatioManager.AreNewNotificationsAvailable();
   if (notificationState.IsUpdated()) {




diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h
index bd27806f46676ae3d99f8f95bb27ff664dad9ae0..499357922bba7ceed305eba1cacf1e19cb516d7e 100644
--- a/src/displayapp/screens/WatchFaceDigital.h
+++ b/src/displayapp/screens/WatchFaceDigital.h
@@ -1,6 +1,5 @@
 #pragma once
 
-#include <displayapp/screens/BatteryIcon.h>
 #include <lvgl/src/lv_core/lv_obj.h>
 #include <chrono>
 #include <cstdint>
@@ -8,6 +7,7 @@ #include 
 #include "displayapp/screens/Screen.h"
 #include "components/datetime/DateTimeController.h"
 #include "components/ble/BleController.h"
+#include "displayapp/widgets/StatusIcons.h"
 
 namespace Pinetime {
   namespace Controllers {
@@ -59,25 +59,20 @@
         lv_obj_t* label_time;
         lv_obj_t* label_time_ampm;
         lv_obj_t* label_date;
-        lv_obj_t* bleIcon;
-        lv_obj_t* batteryPlug;
         lv_obj_t* heartbeatIcon;
         lv_obj_t* heartbeatValue;
         lv_obj_t* stepIcon;
         lv_obj_t* stepValue;
         lv_obj_t* notificationIcon;
-
-        BatteryIcon batteryIcon;
 
         Controllers::DateTime& dateTimeController;
-        Controllers::Battery& batteryController;
-        Controllers::Ble& bleController;
         Controllers::NotificationManager& notificatioManager;
         Controllers::Settings& settingsController;
         Controllers::HeartRateController& heartRateController;
         Controllers::MotionController& motionController;
 
         lv_task_t* taskRefresh;
+        Widgets::StatusIcons statusIcons;
       };
     }
   }




diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp
index ab5a437b4aa95e9fe306a3b42c4de9b531c928a7..f756006617582656f502fdcec964e7be11bbc5ac 100644
--- a/src/displayapp/screens/settings/QuickSettings.cpp
+++ b/src/displayapp/screens/settings/QuickSettings.cpp
@@ -2,6 +2,7 @@ #include "displayapp/screens/settings/QuickSettings.h"
 #include "displayapp/DisplayApp.h"
 #include "displayapp/screens/Symbols.h"
 #include "displayapp/screens/BatteryIcon.h"
+#include <components/ble/BleController.h>
 
 using namespace Pinetime::Applications::Screens;
 
@@ -22,13 +23,16 @@                              Pinetime::Controllers::Battery& batteryController,
                              Controllers::DateTime& dateTimeController,
                              Controllers::BrightnessController& brightness,
                              Controllers::MotorController& motorController,
-                             Pinetime::Controllers::Settings& settingsController)
+                             Pinetime::Controllers::Settings& settingsController,
+                             Controllers::Ble& bleController)
   : Screen(app),
-    batteryController {batteryController},
     dateTimeController {dateTimeController},
     brightness {brightness},
     motorController {motorController},
-    settingsController {settingsController} {
+    settingsController {settingsController},
+    statusIcons(batteryController, bleController) {
+
+  statusIcons.Create();
 
   // This is the distance (padding) between all objects on this screen.
   static constexpr uint8_t innerDistance = 10;
@@ -37,9 +41,6 @@   // Time
   label_time = lv_label_create(lv_scr_act(), nullptr);
   lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
   lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0);
-
-  batteryIcon.Create(lv_scr_act());
-  lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
 
   static constexpr uint8_t barHeight = 20 + innerDistance;
   static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2;
@@ -117,7 +118,7 @@ }
 
 void QuickSettings::UpdateScreen() {
   lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str());
-  batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining());
+  statusIcons.Update();
 }
 
 void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) {




diff --git a/src/displayapp/screens/settings/QuickSettings.h b/src/displayapp/screens/settings/QuickSettings.h
index 40a2a2ef57f4b9acf5bd02fe5f080e69c07786ae..fd1b5ea488d48e4c4444a9c1c5e522869bd29aa2 100644
--- a/src/displayapp/screens/settings/QuickSettings.h
+++ b/src/displayapp/screens/settings/QuickSettings.h
@@ -8,7 +8,7 @@ #include "components/brightness/BrightnessController.h"
 #include "components/motor/MotorController.h"
 #include "components/settings/Settings.h"
 #include "components/battery/BatteryController.h"
-#include <displayapp/screens/BatteryIcon.h>
+#include "displayapp/widgets/StatusIcons.h"
 
 namespace Pinetime {
 
@@ -22,7 +22,8 @@                       Pinetime::Controllers::Battery& batteryController,
                       Controllers::DateTime& dateTimeController,
                       Controllers::BrightnessController& brightness,
                       Controllers::MotorController& motorController,
-                      Pinetime::Controllers::Settings& settingsController);
+                      Pinetime::Controllers::Settings& settingsController,
+                      Controllers::Ble& bleController);
 
         ~QuickSettings() override;
 
@@ -31,7 +32,6 @@
         void UpdateScreen();
 
       private:
-        Pinetime::Controllers::Battery& batteryController;
         Controllers::DateTime& dateTimeController;
         Controllers::BrightnessController& brightness;
         Controllers::MotorController& motorController;
@@ -40,6 +40,11 @@
         lv_task_t* taskUpdate;
         lv_obj_t* label_time;
 
+        DirtyValue<uint8_t> batteryPercentRemaining {};
+        DirtyValue<bool> powerPresent {};
+        DirtyValue<bool> bleState {};
+        DirtyValue<bool> bleRadioEnabled {};
+
         lv_style_t btn_style;
 
         lv_obj_t* btn1;
@@ -49,7 +54,7 @@         lv_obj_t* btn3;
         lv_obj_t* btn3_lvl;
         lv_obj_t* btn4;
 
-        BatteryIcon batteryIcon;
+        Widgets::StatusIcons statusIcons;
       };
     }
   }




diff --git a/src/displayapp/widgets/StatusIcons.cpp b/src/displayapp/widgets/StatusIcons.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d8f294b51d2d1deca85db6aa31825b7724b9b4a7
--- /dev/null
+++ b/src/displayapp/widgets/StatusIcons.cpp
@@ -0,0 +1,55 @@
+#include "displayapp/widgets/StatusIcons.h"
+#include "displayapp/screens/Symbols.h"
+
+using namespace Pinetime::Applications::Widgets;
+
+StatusIcons::StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController)
+  : batteryController {batteryController}, bleController {bleController} {
+}
+
+void StatusIcons::Align() {
+  lv_obj_t* lastIcon = batteryIcon.GetObject();
+
+  for (auto& icon : icons) {
+    if (!lv_obj_get_hidden(icon)) {
+      lv_obj_align(icon, lastIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0);
+      lastIcon = icon;
+    }
+  }
+}
+
+void StatusIcons::Create() {
+  batteryIcon.Create(lv_scr_act());
+  lv_obj_align(batteryIcon.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0);
+
+  icons[Icons::BatteryPlug] = lv_label_create(lv_scr_act(), nullptr);
+  lv_obj_set_style_local_text_color(icons[Icons::BatteryPlug], LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000));
+  lv_label_set_text_static(icons[Icons::BatteryPlug], Screens::Symbols::plug);
+
+  icons[Icons::BleIcon] = lv_label_create(lv_scr_act(), nullptr);
+  lv_obj_set_style_local_text_color(icons[Icons::BleIcon], LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0082FC));
+  lv_label_set_text_static(icons[Icons::BleIcon], Screens::Symbols::bluetooth);
+
+  Align();
+}
+
+void StatusIcons::Update() {
+  powerPresent = batteryController.IsPowerPresent();
+  if (powerPresent.IsUpdated()) {
+    lv_obj_set_hidden(icons[Icons::BatteryPlug], !powerPresent.Get());
+  }
+
+  batteryPercentRemaining = batteryController.PercentRemaining();
+  if (batteryPercentRemaining.IsUpdated()) {
+    auto batteryPercent = batteryPercentRemaining.Get();
+    batteryIcon.SetBatteryPercentage(batteryPercent);
+  }
+
+  bleState = bleController.IsConnected();
+  bleRadioEnabled = bleController.IsRadioEnabled();
+  if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
+    lv_obj_set_hidden(icons[Icons::BleIcon], !bleState.Get());
+  }
+
+  Align();
+}




diff --git a/src/displayapp/widgets/StatusIcons.h b/src/displayapp/widgets/StatusIcons.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6e713e2f7295e3bff289b646ce0ae46f3a30c00
--- /dev/null
+++ b/src/displayapp/widgets/StatusIcons.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <lvgl/lvgl.h>
+
+#include "displayapp/screens/Screen.h"
+#include "components/battery/BatteryController.h"
+#include "components/ble/BleController.h"
+#include "displayapp/screens/BatteryIcon.h"
+
+namespace Pinetime {
+  namespace Applications {
+    namespace Widgets {
+      class StatusIcons {
+      public:
+        StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController);
+        void Align();
+        void Create();
+        lv_obj_t* GetObject() {
+          return batteryIcon.GetObject();
+        }
+        void Update();
+
+      private:
+        Screens::BatteryIcon batteryIcon;
+        Pinetime::Controllers::Battery& batteryController;
+        Controllers::Ble& bleController;
+
+        Screens::DirtyValue<uint8_t> batteryPercentRemaining {};
+        Screens::DirtyValue<bool> powerPresent {};
+        Screens::DirtyValue<bool> bleState {};
+        Screens::DirtyValue<bool> bleRadioEnabled {};
+
+        enum Icons { BatteryPlug, BleIcon };
+        lv_obj_t* icons[2];
+      };
+    }
+  }
+}