A art/bell/bell_lightning_W_G.png => art/bell/bell_lightning_W_G.png +0 -0
A art/bell/bell_lightning_W_M.png => art/bell/bell_lightning_W_M.png +0 -0
A art/bell/bell_status_battery_lvl0_W_G.png => art/bell/bell_status_battery_lvl0_W_G.png +0 -0
A art/bell/bell_status_battery_lvl1_W_G.png => art/bell/bell_status_battery_lvl1_W_G.png +0 -0
A art/bell/bell_status_battery_lvl2_W_G.png => art/bell/bell_status_battery_lvl2_W_G.png +0 -0
A art/bell/bell_status_battery_lvl3_W_G.png => art/bell/bell_status_battery_lvl3_W_G.png +0 -0
A art/bell/bell_status_battery_lvl4_W_G.png => art/bell/bell_status_battery_lvl4_W_G.png +0 -0
A art/bell/bell_status_battery_lvl5_W_G.png => art/bell/bell_status_battery_lvl5_W_G.png +0 -0
A image/assets/images/bell/bell_lightning_W_G.vpi => image/assets/images/bell/bell_lightning_W_G.vpi +0 -0
A image/assets/images/bell/bell_lightning_W_M.vpi => image/assets/images/bell/bell_lightning_W_M.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl0_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl0_W_G.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl1_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl1_W_G.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl2_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl2_W_G.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl3_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl3_W_G.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl4_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl4_W_G.vpi +0 -0
A image/assets/images/bell/bell_status_battery_lvl5_W_G.vpi => image/assets/images/bell/bell_status_battery_lvl5_W_G.vpi +0 -0
M products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp => products/BellHybrid/apps/application-bell-main/ApplicationBellMain.cpp +5 -1
@@ 9,6 9,7 @@
#include "windows/BellBatteryShutdownWindow.hpp"
#include "windows/BellHomeScreenWindow.hpp"
#include "windows/BellMainMenuWindow.hpp"
+#include "windows/BellBatteryStatusWindow.hpp"
#include <apps-common/messages/AppMessage.hpp>
#include <common/BellPowerOffPresenter.hpp>
@@ 78,7 79,10 @@ namespace app
return std::make_unique<gui::BellFactoryReset>(app, std::make_unique<gui::BellPowerOffPresenter>(app));
});
- // for demo only - to be removed
+ windowsFactory.attach(gui::BellBatteryStatusWindow::name, [](ApplicationCommon *app, const std::string &name) {
+ return std::make_unique<gui::BellBatteryStatusWindow>(app);
+ });
+
windowsFactory.attach(
gui::window::name::bell_main_menu_dialog,
[](ApplicationCommon *app, const std::string &name) { return std::make_unique<gui::Dialog>(app, name); });
M products/BellHybrid/apps/application-bell-main/CMakeLists.txt => products/BellHybrid/apps/application-bell-main/CMakeLists.txt +3 -0
@@ 10,6 10,7 @@ target_sources(application-bell-main
windows/BellBatteryShutdownWindow.cpp
windows/BellHomeScreenWindow.cpp
windows/BellMainMenuWindow.cpp
+ windows/BellBatteryStatusWindow.cpp
models/BatteryModel.cpp
models/TemperatureModel.cpp
@@ 24,6 25,8 @@ target_sources(application-bell-main
windows/BellBatteryShutdownWindow.hpp
windows/BellHomeScreenWindow.hpp
windows/BellMainMenuWindow.hpp
+ windows/BellBatteryStatusWindow.hpp
+ data/BatteryUtils.hpp
models/BatteryModel.cpp
models/TemperatureModel.hpp
A products/BellHybrid/apps/application-bell-main/data/BatteryUtils.hpp => products/BellHybrid/apps/application-bell-main/data/BatteryUtils.hpp +48 -0
@@ 0,0 1,48 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <cstdint>
+#include <algorithm>
+#include <optional>
+
+namespace battery_utils
+{
+ struct BatteryLevelEntry
+ {
+ using Range = std::pair<std::uint32_t, std::uint32_t>;
+ Range realLvl;
+ Range displayedLvl;
+ std::string_view image;
+ };
+
+ struct ScaledBatteryLevel
+ {
+ std::uint32_t level;
+ std::string image;
+ };
+
+ template <std::size_t N>
+ [[nodiscard]] std::optional<ScaledBatteryLevel> getScaledBatteryLevel(
+ const std::array<BatteryLevelEntry, N> &entries, const std::uint32_t val)
+ {
+ auto result = std::find_if(entries.begin(), entries.end(), [val](const auto &e) {
+ return val >= e.realLvl.first && val <= e.realLvl.second;
+ });
+
+ if (result != entries.end()) {
+ const auto outputStart = result->displayedLvl.first;
+ const auto outputEnd = result->displayedLvl.second;
+ const auto inputStart = result->realLvl.first;
+ const auto inputEnd = result->realLvl.second;
+ float slope = 1.0 * (outputEnd - outputStart) / (inputEnd - inputStart);
+ auto output = outputStart + slope * (val - inputStart);
+
+ return ScaledBatteryLevel{static_cast<std::uint32_t>(std::floor(output)), result->image.data()};
+ }
+
+ return {};
+ }
+
+} // namespace battery_utils
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.cpp +8 -0
@@ 114,4 114,12 @@ namespace app::home_screen
snoozeTimer->reset(snoozeDuration, snoozeTick);
}
+ std::uint32_t HomeScreenPresenter::getBatteryLvl() const
+ {
+ return batteryModel->getLevelState().level;
+ }
+ bool HomeScreenPresenter::isBatteryCharging() const
+ {
+ return batteryModel->getLevelState().state == Store::Battery::State::Charging;
+ }
} // namespace app::home_screen
M products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp => products/BellHybrid/apps/application-bell-main/presenters/HomeScreenPresenter.hpp +6 -2
@@ 74,7 74,8 @@ namespace app::home_screen
virtual void setBatteryLevelState(const Store::Battery &batteryContext) = 0;
/// Various
- virtual void switchToMenu() = 0;
+ virtual void switchToMenu() = 0;
+ virtual void switchToBatteryStatus() = 0;
};
class AbstractPresenter : public BasePresenter<AbstractView>
@@ 95,6 96,8 @@ namespace app::home_screen
virtual void startSnoozeTimer(std::chrono::seconds snoozeDuration) = 0;
virtual void stopSnoozeTimer() = 0;
virtual void restartSnoozeTimer(std::chrono::seconds snoozeDuration) = 0;
+ virtual std::uint32_t getBatteryLvl() const = 0;
+ virtual bool isBatteryCharging() const = 0;
static constexpr auto defaultTimeout = std::chrono::milliseconds{5000};
};
@@ 127,10 130,11 @@ namespace app::home_screen
void handleAlarmModelReady() override;
void setSnoozeTimer(std::unique_ptr<app::ProgressTimerWithSnoozeTimer> &&_timer) override;
-
void startSnoozeTimer(std::chrono::seconds snoozeDuration);
void stopSnoozeTimer();
void restartSnoozeTimer(std::chrono::seconds snoozeDuration);
+ std::uint32_t getBatteryLvl() const override;
+ bool isBatteryCharging() const override;
private:
ApplicationCommon *app;
M products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp => products/BellHybrid/apps/application-bell-main/presenters/StateController.cpp +6 -3
@@ 32,9 32,10 @@ namespace app::home_screen
{
namespace Helpers
{
- auto switchToMenu = [](AbstractView &view) { view.switchToMenu(); };
- auto makeAlarmEditable = [](AbstractView &view) { view.setAlarmEdit(true); };
- auto makeAlarmNonEditable = [](AbstractView &view) { view.setAlarmEdit(false); };
+ auto switchToMenu = [](AbstractView &view) { view.switchToMenu(); };
+ auto switchToBatteryStatus = [](AbstractView &view) { view.switchToBatteryStatus(); };
+ auto makeAlarmEditable = [](AbstractView &view) { view.setAlarmEdit(true); };
+ auto makeAlarmNonEditable = [](AbstractView &view) { view.setAlarmEdit(false); };
auto updateBottomStats =
[](AbstractView &view, AbstractBatteryModel &batteryModel, AbstractTemperatureModel &temperatureModel) {
view.setTemperature(temperatureModel.getTemperature());
@@ 274,6 275,7 @@ namespace app::home_screen
"Deactivated"_s + event<Events::RotateRightPress> / Helpers::makeAlarmEditable = "DeactivatedEdit"_s,
"Deactivated"_s + event<Events::DeepUpPress> = "ActivatedWait"_s,
"Deactivated"_s + event<Events::TimeUpdate> / Helpers::updateBottomStats,
+ "Deactivated"_s + event<Events::BackPress> / Helpers::switchToBatteryStatus,
"DeactivatedWait"_s + sml::on_entry<_> / DeactivatedWait::entry,
"DeactivatedWait"_s + sml::on_exit<_> / DeactivatedWait::exit,
@@ 320,6 322,7 @@ namespace app::home_screen
"Activated"_s + event<Events::TimeUpdate> / Helpers::updateBottomStats,
"Activated"_s + event<Events::DeepDownPress> = "DeactivatedWait"_s,
"Activated"_s + event<Events::AlarmRinging> = "AlarmRinging"_s,
+ "Activated"_s + event<Events::BackPress> / Helpers::switchToBatteryStatus,
"ActivatedEdit"_s + sml::on_entry<_> / AlarmEdit::entry,
"ActivatedEdit"_s + sml::on_exit<_> / AlarmEdit::exit,
M products/BellHybrid/apps/application-bell-main/widgets/BellBattery.cpp => products/BellHybrid/apps/application-bell-main/widgets/BellBattery.cpp +13 -24
@@ 2,21 2,19 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "BellBattery.hpp"
+#include "data/BatteryUtils.hpp"
#include <Image.hpp>
namespace
{
- constexpr unsigned int minVal = 80;
- constexpr unsigned int oldMax = 95;
- constexpr unsigned int newMax = 100;
- constexpr unsigned int oldRange = oldMax - minVal;
- constexpr unsigned int newRange = newMax - minVal;
-
- unsigned int translateBatteryLevel(unsigned int percentage)
- {
- return (((percentage - minVal) * newRange) / oldRange) + minVal;
- }
-} // namespace
+ constexpr auto entries =
+ std::array<battery_utils::BatteryLevelEntry, 6>{{{{5, 10}, {1, 5}, "bell_battery_empty"},
+ {{11, 30}, {6, 29}, "bell_battery_lvl1"},
+ {{31, 50}, {30, 53}, "bell_battery_lvl2"},
+ {{51, 70}, {54, 77}, "bell_battery_lvl3"},
+ {{71, 95}, {78, 99}, "bell_battery_lvl4"},
+ {{96, 100}, {100, 100}, "bell_battery_lvl5"}}};
+}
namespace gui
{
@@ 37,21 35,12 @@ namespace gui
void BellBattery::update(const Store::Battery &batteryContext)
{
- (void)batteryContext;
-
- // Fuel gauge and charger are different hw elements
- // Charger sometimes stops charging before FG shows 100%
- auto level = batteryContext.level;
-
- if (level > 95) {
- level = 100;
- }
-
- // Translate 80-95% range to 80-100% range for display
- if ((level > 80) && (level <= 95)) {
- level = translateBatteryLevel(level);
+ const auto result = battery_utils::getScaledBatteryLevel(entries, batteryContext.level);
+ if (not result) {
+ return;
}
+ const auto level = result->level;
if (batteryContext.state == Store::Battery::State::Charging) {
img->set(battery::battery_charging, gui::ImageTypeSpecifier::W_M);
A products/BellHybrid/apps/application-bell-main/windows/BellBatteryStatusWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellBatteryStatusWindow.cpp +111 -0
@@ 0,0 1,111 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "BellBatteryStatusWindow.hpp"
+#include "data/BatteryUtils.hpp"
+
+#include <gui/widgets/TextFixedSize.hpp>
+#include <gui/widgets/ImageBox.hpp>
+#include <gui/input/InputEvent.hpp>
+#include <Application.hpp>
+
+#include <chrono>
+
+namespace
+{
+ constexpr auto imageType = gui::ImageTypeSpecifier::W_G;
+ constexpr auto batteryEntries =
+ std::array<battery_utils::BatteryLevelEntry, 6>{{{{5, 10}, {1, 5}, "bell_status_battery_lvl0"},
+ {{11, 30}, {6, 29}, "bell_status_battery_lvl1"},
+ {{31, 50}, {30, 53}, "bell_status_battery_lvl2"},
+ {{51, 70}, {54, 77}, "bell_status_battery_lvl3"},
+ {{71, 95}, {78, 99}, "bell_status_battery_lvl4"},
+ {{96, 100}, {100, 100}, "bell_status_battery_lvl5"}}};
+} // namespace
+
+namespace gui
+{
+ using namespace std::chrono_literals;
+
+ BellBatteryStatusWindow::BellBatteryStatusWindow(app::ApplicationCommon *app) : WindowWithTimer{app, name, 5s}
+ {
+ buildInterface();
+ }
+ void BellBatteryStatusWindow::buildInterface()
+ {
+ WindowWithTimer::buildInterface();
+ statusBar->setVisible(false);
+ header->setTitleVisibility(false);
+ navBar->setVisible(false);
+
+ body = new BellBaseLayout(this, 0, 0, style::window_width, style::window_height, false);
+
+ topDescription = new TextFixedSize(body->firstBox);
+ topDescription->setMinimumSize(style::bell_base_layout::outer_layouts_w,
+ style::bell_base_layout::outer_layouts_h);
+ topDescription->setFont(top_description_font);
+ topDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ topDescription->setEdges(RectangleEdge::None);
+ topDescription->activeItem = false;
+ topDescription->drawUnderline(false);
+ topDescription->setText(utils::translate("app_settings_tech_info_battery"));
+
+ hbox = new HBox(body->lastBox);
+ hbox->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
+ hbox->setEdges(RectangleEdge::None);
+ hbox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+
+ chargingIcon = new ImageBox(hbox, 0, 0, 0, 0, new Image("bell_lightning", imageType));
+ chargingIcon->setMargins(gui::Margins(0, 0, 8, 0));
+ chargingIcon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ chargingIcon->setMinimumSizeToFitImage();
+ chargingIcon->activeItem = false;
+
+ bottomDescription = new TextFixedSize(hbox);
+ bottomDescription->setMaximumSize(bottom_description_max_size_w, bottom_description_max_size_h);
+ bottomDescription->setFont(bottom_description_font);
+ bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ bottomDescription->setEdges(RectangleEdge::None);
+ bottomDescription->activeItem = false;
+ bottomDescription->drawUnderline(false);
+
+ center = new ImageBox(body->centerBox,
+ 0,
+ 0,
+ style::bell_base_layout::w,
+ style::bell_base_layout::h,
+ new Image("bell_status_battery_lvl0", imageType));
+ center->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
+ center->setEdges(RectangleEdge::None);
+ center->setMinimumSizeToFitImage();
+ center->activeItem = false;
+
+ body->resize();
+ }
+ bool BellBatteryStatusWindow::onInput(const InputEvent &inputEvent)
+ {
+ if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
+ application->returnToPreviousWindow();
+ return true;
+ }
+ return false;
+ }
+ void BellBatteryStatusWindow::onBeforeShow(ShowMode mode, SwitchData *data)
+ {
+ if (data != nullptr) {
+ WindowWithTimer::onBeforeShow(mode, data);
+ const auto &switchData = static_cast<Data &>(*data);
+ const auto entry = battery_utils::getScaledBatteryLevel(batteryEntries, switchData.chargeLevel);
+ if (entry) {
+ center->setImage(entry->image, imageType);
+ bottomDescription->setText(std::to_string(entry->level) + "%");
+ chargingIcon->setVisible(switchData.isCharging);
+ hbox->resizeItems();
+ body->resize();
+ }
+ }
+ else {
+ LOG_ERROR("BellBatteryStatusWindow must be invoked with a valid SwitchData");
+ }
+ }
+} // namespace gui
A products/BellHybrid/apps/application-bell-main/windows/BellBatteryStatusWindow.hpp => products/BellHybrid/apps/application-bell-main/windows/BellBatteryStatusWindow.hpp +48 -0
@@ 0,0 1,48 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <apps-common/widgets/BellBaseLayout.hpp>
+#include <apps-common/popups/WindowWithTimer.hpp>
+
+namespace gui
+{
+ class TextFixedSize;
+ class ImageBox;
+ class Image;
+
+ class BellBatteryStatusWindow : public WindowWithTimer
+ {
+ public:
+ struct Data : public gui::SwitchData
+ {
+ Data(std::uint32_t lvl, bool chargeState) : chargeLevel{lvl}, isCharging{chargeState}
+ {}
+ const std::uint32_t chargeLevel;
+ const bool isCharging;
+ };
+ static constexpr auto name = "BellBatteryStatusWindow";
+ explicit BellBatteryStatusWindow(app::ApplicationCommon *app);
+
+ private:
+ static constexpr auto top_description_font = style::window::font::largelight;
+ static constexpr auto bottom_description_font = style::window::font::verybiglight;
+ static constexpr auto bottom_description_max_size_w = 85U;
+ static constexpr auto bottom_description_max_size_h = 85U;
+
+ void buildInterface() override;
+ bool onInput(const InputEvent &inputEvent) override;
+ void onBeforeShow(ShowMode mode, SwitchData *data) override;
+
+ BellBaseLayout *body{};
+ TextFixedSize *topDescription{};
+
+ TextFixedSize *bottomDescription{};
+ ImageBox *chargingIcon{};
+
+ HBox *hbox{};
+ ImageBox *center{};
+ };
+
+} // namespace gui
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +8 -0
@@ 4,6 4,7 @@
#include "BellHomeScreenWindow.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/SnoozeTimer.hpp"
+#include "BellBatteryStatusWindow.hpp"
#include <application-bell-main/ApplicationBellMain.hpp>
#include <apps-common/widgets/BellBaseLayout.hpp>
@@ 308,4 309,11 @@ namespace gui
}
return false;
}
+ void BellHomeScreenWindow::switchToBatteryStatus()
+ {
+ application->switchWindow(gui::BellBatteryStatusWindow::name,
+ std::make_unique<gui::BellBatteryStatusWindow::Data>(presenter->getBatteryLvl(),
+ presenter->isBatteryCharging()));
+ }
+
} // namespace gui
M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.hpp +1 -0
@@ 62,6 62,7 @@ namespace gui
void setTimeFormat(utils::time::Locale::TimeFormat fmt) override;
void setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt) override;
void switchToMenu() override;
+ void switchToBatteryStatus() override;
BellBaseLayout *body{};