~aleteoryx/muditaos

89962fa4396f51e9dd0fdcf4df1b82c424429db4 — Adam Wulkiewicz 3 years ago 1a2ea53
[BH-1598] Add clock faces with dates

Add classic and vertical face with dates for both 12h and 24h format.

Fix centering of battery indicator when level is smaller than 100%.

Fix incorrect time format of the alarm in clock face settings.

Change placement of battery and time format indicators on
ClassicWithAmPm screen while charging.
34 files changed, 563 insertions(+), 177 deletions(-)

M harmony_changelog.md
M module-apps/apps-common/widgets/BellBaseLayout.cpp
M module-apps/apps-common/widgets/BellBaseLayout.hpp
M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp
M module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp
M module-apps/apps-common/widgets/TimeSetSpinner.hpp
M module-gui/gui/widgets/Style.hpp
M module-gui/gui/widgets/text/Text.hpp
M products/BellHybrid/CMakeLists.txt
M products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp
M products/BellHybrid/apps/common/CMakeLists.txt
M products/BellHybrid/apps/common/include/common/data/BellMainStyle.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithDate.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithDate.hpp
M products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp
M products/BellHybrid/apps/common/include/common/widgets/BellStatusClock.hpp
M products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithAmPm.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithTemp.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithDate.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp
M products/BellHybrid/apps/common/src/widgets/BellBattery.cpp
M products/BellHybrid/apps/common/src/widgets/BellStatusClock.cpp
M products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp
M products/BellHybrid/apps/common/src/widgets/ListItems.cpp
M products/BellHybrid/assets/assets_proprietary.json
M harmony_changelog.md => harmony_changelog.md +15 -3
@@ 5,19 5,31 @@
### Added

#### Home Screen:
* Font size increased
* Font size increased.
* Clock faces with dates.

#### General:
* Bedside lamp mode
* Bedside lamp mode.

#### UI/UX:
* Improve refreshing of the display.

#### Onboarding
* Shortcuts instruction
* Shortcuts instruction.

### Changed

#### Home Screen:
* Placement of battery and time format indicators.

### Fixed

#### Home Screen:
* Centering of battery indicator.

#### Settings:
* Incorrect time format of the alarm in clock face settings.

## [1.7.0 2022-11-14]

### Added

M module-apps/apps-common/widgets/BellBaseLayout.cpp => module-apps/apps-common/widgets/BellBaseLayout.cpp +33 -42
@@ 6,13 6,7 @@

namespace gui
{
    BellBaseLayout::BellBaseLayout(Item *parent,
                                   Position x,
                                   Position y,
                                   Length w,
                                   Length h,
                                   bool withSideArrows,
                                   style::bell_base_layout::ParentType type)
    BellBaseLayout::BellBaseLayout(Item *parent, Position x, Position y, Length w, Length h, bool withSideArrows)
        : VThreeBox(parent, x, y, w, h)
    {
        setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::h);


@@ 37,10 31,6 @@ namespace gui
        lastBox->setEdges(RectangleEdge::None);
        lastBox->activeItem = false;

        if (type == style::bell_base_layout::ParentType::SideListView) {
            lastBox->setMargins(Margins(0, 0, 0, style::bell_base_layout::outer_layout_margin));
        }

        resizeItems();

        if (withSideArrows) {


@@ 50,8 40,8 @@ namespace gui

    Item *BellBaseLayout::getCenterBox() const noexcept
    {
        if (centerThreeBox != nullptr) {
            return centerThreeBox->centerBox;
        if (arrowsThreeBox != nullptr) {
            return arrowsThreeBox->centerBox;
        }
        return centerBox;
    }


@@ 59,8 49,8 @@ namespace gui
    void BellBaseLayout::resizeCenter()
    {
        centerBox->resizeItems();
        if (centerThreeBox != nullptr) {
            centerThreeBox->resizeItems();
        if (arrowsThreeBox != nullptr) {
            arrowsThreeBox->resizeItems();
        }
    }



@@ 74,40 64,41 @@ namespace gui

    void BellBaseLayout::addSideArrows()
    {
        centerThreeBox = new HThreeBox<HBox, HBox, HBox>(centerBox);
        centerThreeBox->setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::center_layout_h);
        centerThreeBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        centerThreeBox->setEdges(RectangleEdge::None);

        centerThreeBox->firstBox = new HBox(centerThreeBox);
        centerThreeBox->firstBox->setAlignment(Alignment(Alignment::Vertical::Center));
        centerThreeBox->firstBox->setEdges(RectangleEdge::None);
        centerThreeBox->firstBox->activeItem = false;

        leftArrow = new ImageBox(centerThreeBox->firstBox, new Image("bell_arrow_left_W_M"));
        arrowsThreeBox = new HThreeBox<HBox, HBox, HBox>(centerBox);
        arrowsThreeBox->setMinimumSize(style::bell_base_layout::arrows_layout_w,
                                       style::bell_base_layout::center_layout_h);
        arrowsThreeBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        arrowsThreeBox->setEdges(RectangleEdge::None);

        arrowsThreeBox->firstBox = new HBox(arrowsThreeBox);
        arrowsThreeBox->firstBox->setAlignment(Alignment(Alignment::Vertical::Center));
        arrowsThreeBox->firstBox->setEdges(RectangleEdge::None);
        arrowsThreeBox->firstBox->activeItem = false;

        leftArrow = new ImageBox(arrowsThreeBox->firstBox, new Image("bell_arrow_left_W_M"));
        leftArrow->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
        leftArrow->setMinimumSizeToFitImage();
        leftArrow->setVisible(true);
        leftArrow->setEdges(RectangleEdge::None);
        centerThreeBox->firstBox->setMinimumSize(leftArrow->widgetMinimumArea.w, leftArrow->widgetMinimumArea.h);
        arrowsThreeBox->firstBox->setMinimumSize(leftArrow->widgetMinimumArea.w, leftArrow->widgetMinimumArea.h);

        centerThreeBox->centerBox = new HBox(centerThreeBox);
        centerThreeBox->centerBox->setEdges(RectangleEdge::None);
        centerThreeBox->centerBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        centerThreeBox->centerBox->setMaximumSize(style::bell_base_layout::center_layout_w,
        arrowsThreeBox->centerBox = new HBox(arrowsThreeBox);
        arrowsThreeBox->centerBox->setEdges(RectangleEdge::None);
        arrowsThreeBox->centerBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        arrowsThreeBox->centerBox->setMaximumSize(style::bell_base_layout::center_layout_w,
                                                  style::bell_base_layout::center_layout_h);

        centerThreeBox->lastBox = new HBox(centerThreeBox);
        centerThreeBox->lastBox->setAlignment(Alignment(Alignment::Vertical::Center));
        centerThreeBox->lastBox->setEdges(RectangleEdge::None);
        centerThreeBox->lastBox->activeItem = false;
        arrowsThreeBox->lastBox = new HBox(arrowsThreeBox);
        arrowsThreeBox->lastBox->setAlignment(Alignment(Alignment::Vertical::Center));
        arrowsThreeBox->lastBox->setEdges(RectangleEdge::None);
        arrowsThreeBox->lastBox->activeItem = false;

        rightArrow = new ImageBox(centerThreeBox->lastBox, new Image("bell_arrow_right_W_M"));
        rightArrow = new ImageBox(arrowsThreeBox->lastBox, new Image("bell_arrow_right_W_M"));
        rightArrow->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        rightArrow->setMinimumSizeToFitImage();
        rightArrow->setVisible(true);
        rightArrow->setEdges(RectangleEdge::None);
        centerThreeBox->lastBox->setMinimumSize(rightArrow->widgetMinimumArea.w, rightArrow->widgetMinimumArea.h);
        arrowsThreeBox->lastBox->setMinimumSize(rightArrow->widgetMinimumArea.w, rightArrow->widgetMinimumArea.h);
    }

    void BellBaseLayout::setArrowVisible(Arrow arrow, bool isVisible)


@@ 122,12 113,12 @@ namespace gui
    {
        setArrowVisible(BellBaseLayout::Arrow::Left, !minCondition);
        setArrowVisible(BellBaseLayout::Arrow::Right, !maxCondition);
        if (centerThreeBox != nullptr) {
            if (centerThreeBox->firstBox != nullptr) {
                centerThreeBox->firstBox->resizeItems();
        if (arrowsThreeBox != nullptr) {
            if (arrowsThreeBox->firstBox != nullptr) {
                arrowsThreeBox->firstBox->resizeItems();
            }
            if (centerThreeBox->lastBox != nullptr) {
                centerThreeBox->lastBox->resizeItems();
            if (arrowsThreeBox->lastBox != nullptr) {
                arrowsThreeBox->lastBox->resizeItems();
            }
        }
    }

M module-apps/apps-common/widgets/BellBaseLayout.hpp => module-apps/apps-common/widgets/BellBaseLayout.hpp +8 -19
@@ 13,15 13,9 @@ namespace style::bell_base_layout
    constexpr inline auto first_layout_min_h  = 30U;
    constexpr inline auto outer_layouts_w     = 448U;
    constexpr inline auto outer_layouts_h     = 102U;
    constexpr inline auto outer_layout_margin = 38U;
    constexpr inline auto center_layout_w     = 504U;
    constexpr inline auto center_layout_h     = h - 2 * outer_layout_margin - 2 * outer_layouts_h;

    enum class ParentType
    {
        SideListView,
        Window
    };
    constexpr inline auto center_layout_w     = w;
    constexpr inline auto center_layout_h     = 200U;
    constexpr inline auto arrows_layout_w     = 504U;
} // namespace style::bell_base_layout

namespace gui


@@ 35,13 29,8 @@ namespace gui
            Right
        };

        explicit BellBaseLayout(Item *parent,
                                Position x                               = 0,
                                Position y                               = 0,
                                Length w                                 = 0,
                                Length h                                 = 0,
                                bool withSideArrows                      = true,
                                style::bell_base_layout::ParentType type = style::bell_base_layout::ParentType::Window);
        explicit BellBaseLayout(
            Item *parent, Position x = 0, Position y = 0, Length w = 0, Length h = 0, bool withSideArrows = true);

        [[nodiscard]] Item *getCenterBox() const noexcept;
        void resizeCenter();


@@ 51,9 40,9 @@ namespace gui
        void setMinMaxArrowsVisibility(bool minCondition, bool maxCondition);

      private:
        HThreeBox<HBox, HBox, HBox> *centerThreeBox{nullptr};
        ImageBox *leftArrow{nullptr};
        ImageBox *rightArrow{nullptr};
        HThreeBox<HBox, HBox, HBox> *arrowsThreeBox = nullptr;
        ImageBox *leftArrow                         = nullptr;
        ImageBox *rightArrow                        = nullptr;

        void addSideArrows();
    };

M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp +17 -10
@@ 11,9 11,7 @@
namespace gui
{

    TimeSetFmtSpinner::TimeSetFmtSpinner(
        Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h, utils::time::Locale::TimeFormat timeFormat)
        : HBox{parent, x, y, w, h}
    TimeSetFmtSpinner::TimeSetFmtSpinner(Item *parent, utils::time::Locale::TimeFormat timeFormat) : HBox{parent}
    {
        using namespace utils;



@@ 218,6 216,14 @@ namespace gui
        return timeFormat;
    }

    void TimeSetFmtSpinner::setVisible(bool value)
    {
        HBox::setVisible(value);
        // This is a workaround for fmt visibility not changed properly
        // It's probably caused by a bug in BoxLayout
        fmt->setVisible(value);
    }

    auto TimeSetFmtSpinner::setTime(std::time_t time) noexcept -> void
    {
        using namespace utils::time;


@@ 258,16 264,17 @@ namespace gui

    void TimeSetFmtSpinner::handleContentChanged()
    {
        fmt->setMinimumWidthToFitText();
        fmt->setMargins(getFmtMargins(noFocusFontName));
        auto widthToSet = timeSetSpinner->widgetMinimumArea.w;

        auto widthToSet =
            timeFormat == utils::time::Locale::TimeFormat::FormatTime12H
                ? timeSetSpinner->widgetMinimumArea.w + fmt->widgetMinimumArea.w + fmt->margins.getSumInAxis(Axis::X)
                : timeSetSpinner->widgetMinimumArea.w;
        if (timeFormat == utils::time::Locale::TimeFormat::FormatTime12H && fmt->visible) {
            fmt->setMinimumWidthToFitText();
            fmt->setMargins(getFmtMargins(noFocusFontName));
            widthToSet =
                timeSetSpinner->widgetMinimumArea.w + fmt->widgetMinimumArea.w + fmt->margins.getSumInAxis(Axis::X);
        }

        setMinimumWidth(widthToSet);
        setMaximumWidth(widgetMinimumArea.w);
        setMaximumWidth(widthToSet);

        HBox::handleContentChanged();
    }

M module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.hpp +3 -4
@@ 37,10 37,6 @@ namespace gui
        };
        explicit TimeSetFmtSpinner(
            Item *parent                               = nullptr,
            uint32_t x                                 = 0U,
            uint32_t y                                 = 0U,
            uint32_t w                                 = 0U,
            uint32_t h                                 = 0U,
            utils::time::Locale::TimeFormat timeFormat = utils::time::Locale::TimeFormat::FormatTime12H);

        /// Switches currently displayed time format


@@ 64,6 60,8 @@ namespace gui

        auto getTimeFormat() const noexcept -> utils::time::Locale::TimeFormat;

        void setVisible(bool value) override;

      private:
        enum class TraverseDir : bool
        {


@@ 73,6 71,7 @@ namespace gui

        std::map<std::string, Margins> fmtMarginsMap = {
            {style::window::font::verybiglight, {style::time_set_fmt_spinner::small_margin, 0, 0, 0}},
            {style::window::font::veryverybiglight, {style::time_set_fmt_spinner::small_margin, 0, 0, 0}},
            {style::window::font::largelight, {style::time_set_fmt_spinner::small_margin, 0, 0, 0}},
            {style::window::font::supersizemelight, {style::time_set_fmt_spinner::big_margin, 0, 0, 0}},
            {style::window::font::huge, {style::time_set_fmt_spinner::big_margin, 0, 0, 0}},

M module-apps/apps-common/widgets/TimeSetSpinner.hpp => module-apps/apps-common/widgets/TimeSetSpinner.hpp +3 -0
@@ 47,6 47,7 @@ namespace gui
      private:
        std::map<std::string, std::string> colonFontMap = {
            {style::window::font::verybiglight, "alarm_colon_W_M"},
            {style::window::font::veryverybiglight, "alarm_colon_W_M"},
            {style::window::font::largelight, "alarm_colon_W_M"},
            {style::window::font::supersizeme, "alarm_colon_select_W_M"},
            {style::window::font::supersizemelight, "alarm_colon_select_W_M"},


@@ 56,6 57,8 @@ namespace gui
        std::map<std::string, Margins> colonMarginsMap = {
            {style::window::font::verybiglight,
             {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, 0}},
            {style::window::font::veryverybiglight,
             {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, 0}},
            {style::window::font::largelight,
             {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, 0}},
            {style::window::font::supersizeme,

M module-gui/gui/widgets/Style.hpp => module-gui/gui/widgets/Style.hpp +1 -0
@@ 65,6 65,7 @@ namespace style
            inline constexpr auto supersizemelight = "supersizemelight";
            inline constexpr auto largelight       = "largelight";
            inline constexpr auto large            = "large";
            inline constexpr auto veryverybiglight = "veryverybiglight";
            inline constexpr auto verybiglight     = "verybiglight";
            inline constexpr auto verybig          = "verybig";
            inline constexpr auto mediumbigbold    = "mediumbigbold";

M module-gui/gui/widgets/text/Text.hpp => module-gui/gui/widgets/text/Text.hpp +4 -4
@@ 119,10 119,10 @@ namespace gui
      public:
        Text();
        Text(Item *parent,
             const uint32_t &x,
             const uint32_t &y,
             const uint32_t &w,
             const uint32_t &h,
             const uint32_t &x     = 0,
             const uint32_t &y     = 0,
             const uint32_t &w     = 0,
             const uint32_t &h     = 0,
             ExpandMode expandMode = ExpandMode::None,
             TextType textType     = TextType::MultiLine);
        ~Text() override;

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +2 -2
@@ 115,14 115,14 @@ download_asset_release_json(json-common-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_common.json
                            ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                            MuditaOSPublicAssets
                            0.0.13
                            0.0.14
                            ${MUDITA_CACHE_DIR}
    )
download_asset_release_json(json-community-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_community.json
                            ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                            MuditaOSPublicAssets
                            0.0.13
                            0.0.14
                            ${MUDITA_CACHE_DIR}
    )
download_asset_json(json-rt1051-target

M products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/LayoutWindowPresenter.cpp +8 -7
@@ 11,8 11,8 @@
#include <Temperature.hpp>
#include <service-appmgr/Constants.hpp>

constexpr auto alarmTime              = 1000 * 60 * 60 * 12;
constexpr auto clockTime              = 1000 * 60 * 60 * 12;
constexpr auto alarmTime              = 0;
constexpr auto clockTime              = 0;
constexpr Store::Battery batteryState = {
    .levelState = Store::Battery::LevelState::Normal,
    .state      = Store::Battery::State::Discharging,


@@ 71,16 71,17 @@ namespace app::bell_settings

    void LayoutWindowPresenter::initLayoutOptions()
    {

        auto layoutsList = timeModel->getTimeFormat() == utils::time::Locale::TimeFormat::FormatTime24H
                               ? gui::factory::getLayoutsFormat24h()
                               : gui::factory::getLayoutsFormat12h();
        const auto timeFormat = timeModel->getTimeFormat();
        auto layoutsList      = timeFormat == utils::time::Locale::TimeFormat::FormatTime24H
                                    ? gui::factory::getLayoutsFormat24h()
                                    : gui::factory::getLayoutsFormat12h();

        for (auto &layoutEntry : layoutsList) {
            auto layout = layoutEntry.second();
            layout->setViewState(app::home_screen::ViewState::Activated);
            layout->setTimeFormat(timeModel->getTimeFormat());
            layout->setTimeFormat(timeFormat);
            layout->setTime(clockTime);
            layout->setAlarmTimeFormat(timeFormat);
            layout->setAlarmTime(alarmTime);
            layout->setBatteryLevelState(batteryState);
            layout->setTemperature(temperature);

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +4 -0
@@ 55,10 55,12 @@ target_sources(application-bell-common
        src/layouts/HomeScreenLayoutClassic.cpp
        src/layouts/HomeScreenLayoutClassicWithAmPm.cpp
        src/layouts/HomeScreenLayoutClassicWithBattery.cpp
        src/layouts/HomeScreenLayoutClassicWithDate.cpp
        src/layouts/HomeScreenLayoutClassicWithTemp.cpp
        src/layouts/HomeScreenLayoutVertical.cpp
        src/layouts/HomeScreenLayoutVerticalSimple.cpp
        src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp
        src/layouts/HomeScreenLayoutVerticalWithDate.cpp

    PUBLIC
        include/common/BellListItemProvider.hpp


@@ 109,10 111,12 @@ target_sources(application-bell-common
        include/common/layouts/HomeScreenLayoutClassic.hpp
        include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp
        include/common/layouts/HomeScreenLayoutClassicWithBattery.hpp
        include/common/layouts/HomeScreenLayoutClassicWithDate.hpp
        include/common/layouts/HomeScreenLayoutClassicWithTemp.hpp
        include/common/layouts/HomeScreenLayoutVertical.hpp
        include/common/layouts/HomeScreenLayoutVerticalSimple.hpp
        include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp
        include/common/layouts/HomeScreenLayoutVerticalWithDate.hpp
)

target_link_libraries(application-bell-common

M products/BellHybrid/apps/common/include/common/data/BellMainStyle.hpp => products/BellHybrid/apps/common/include/common/data/BellMainStyle.hpp +2 -0
@@ 12,6 12,7 @@ namespace bellMainStyle
        namespace time
        {
            inline constexpr auto font = style::window::font::gargantuan;
            inline constexpr auto font_small = style::window::font::veryverybiglight;
        } // namespace time

        namespace alarmSetSpinner


@@ 22,6 23,7 @@ namespace bellMainStyle
        namespace bottomDescription
        {
            inline constexpr auto font_normal = style::window::font::largelight;
            inline constexpr auto font_smallnormal = style::window::font::veryverybiglight;
            inline constexpr auto font_small  = style::window::font::verybiglight;

        } // namespace bottomDescription

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp +12 -12
@@ 9,8 9,7 @@

namespace style::homescreen_classic
{
    constexpr inline auto bottom_box_w = 390U;
    constexpr inline auto bottom_box_h = 102U;
    constexpr inline auto status_box_layout_w = 350U;
} // namespace style::homescreen_classic
namespace gui
{


@@ 39,7 38,7 @@ namespace gui
        SnoozeIconAndTime,
    };

    class HomeScreenLayoutClassic : public BaseHomeScreenLayoutProvider, BellBaseLayout
    class HomeScreenLayoutClassic : public BaseHomeScreenLayoutProvider, protected BellBaseLayout
    {
      public:
        HomeScreenLayoutClassic(std::string name);


@@ 59,16 58,17 @@ namespace gui
        auto getLayout() -> Item * override;

      protected:
        auto setHeaderViewMode(HeaderViewMode mode) -> void;
        virtual auto buildInterface() -> void;
        void setHeaderViewMode(HeaderViewMode mode);
        virtual void buildInterface();
        virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);
        auto removeTextDescription() -> void;
        void removeTextDescription();

        TimeSetFmtSpinner *time{};
        DuoHBox *statusBox{};
        BellBattery *battery{};
        TextFixedSize *bottomText{};
        AlarmSetSpinner *alarm{};
        SnoozeTimer *snoozeTimer{};
        HBox *timeHBox            = nullptr;
        TimeSetFmtSpinner *time   = nullptr;
        HBox *statusBox           = nullptr;
        BellBattery *battery      = nullptr;
        TextFixedSize *bottomText = nullptr;
        AlarmSetSpinner *alarm    = nullptr;
        SnoozeTimer *snoozeTimer  = nullptr;
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp +2 -0
@@ 16,6 16,8 @@ namespace gui

      protected:
        auto buildInterface() -> void override;
        bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext) override;
        void handleContentChanged() override;

        TextFixedSize *fmt{};
    };

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithDate.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithDate.hpp +32 -0
@@ 0,0 1,32 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "HomeScreenLayoutClassic.hpp"

namespace style::homescreen_classic
{
    constexpr inline auto ampm_layout_w      = 51U;
    constexpr inline auto ampm_margin_w      = 5U;
    constexpr inline auto ampm_time_margin_w = ampm_layout_w + ampm_margin_w;
} // namespace style::homescreen_classic
namespace gui
{
    class HomeScreenLayoutClassicWithDate : public HomeScreenLayoutClassic
    {
      public:
        HomeScreenLayoutClassicWithDate(std::string name);

        void setTime(std::time_t newTime) override;
        void setTimeFormat(utils::time::Locale::TimeFormat fmt) override;

      protected:
        void buildInterface() override;
        bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext) override;

        Text *date          = nullptr;
        TextFixedSize *ampm = nullptr;
        bool showAMPM       = false;
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVertical.hpp +2 -0
@@ 51,5 51,7 @@ namespace gui
      protected:
        auto setScreenMode(ScreenMode mode) -> void;
        virtual bool isBatteryVisibilityAllowed(const Store::Battery &batteryContext);
        virtual bool isAlarmTimeVisibilityAllowed();
        bool isBatteryCharging(const Store::Battery::State state);
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp +2 -2
@@ 9,7 9,7 @@ namespace style::homescreen_vertical_ampm
{
    constexpr inline auto alarm_margin_top   = 83U;
    constexpr inline auto battery_margin_bot = 68U;
    constexpr inline auto fmt_margin_bot     = 77U;
    constexpr inline auto ampm_margin_bot    = 77U;
} // namespace style::homescreen_vertical_ampm

namespace gui


@@ 22,6 22,6 @@ namespace gui

        auto setTime(std::time_t newTime) -> void override;

        TextFixedSize *fmt{};
        TextFixedSize *ampm{};
    };
}; // namespace gui

A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithDate.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutVerticalWithDate.hpp +32 -0
@@ 0,0 1,32 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "HomeScreenLayoutVertical.hpp"

namespace style::homescreen_vertical_date
{
    constexpr inline auto margin_top = 64U;
    constexpr inline auto margin_bot = 70U;
} // namespace style::homescreen_vertical_date

namespace gui
{

    class HomeScreenLayoutVerticalWithDate : public HomeScreenLayoutVertical
    {
      public:
        HomeScreenLayoutVerticalWithDate(std::string name);

        void setTime(std::time_t newTime) override;
        void setTimeFormat(utils::time::Locale::TimeFormat fmt) override;

      private:
        void setBatteryLevelState(const Store::Battery &batteryContext) override;
        bool isAlarmTimeVisibilityAllowed() override;

        TextFixedSize *ampm = nullptr;
        TextFixedSize *date = nullptr;
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp => products/BellHybrid/apps/common/include/common/widgets/BellBattery.hpp +7 -4
@@ 18,7 18,7 @@ namespace gui
        constexpr auto percent_h          = 102U;
        constexpr auto percent_w          = 106U;
        constexpr auto battery_widget_h   = 64U;
        constexpr auto battery_widget_w   = 240U;
        constexpr auto battery_widget_w   = 184U;

    } // namespace battery



@@ 31,13 31,16 @@ namespace gui
    class BellBattery : public gui::HBox
    {
      public:
        BellBattery(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        BellBattery(Item *parent);
        void setFont(const UTF8 &fontName);
        void update(units::SOC soc, bool isCharging);
        void setBatteryPercentMode(BatteryPercentMode mode);

      private:
        void setWidthsToFitContent();

        BatteryPercentMode batteryPercentMode = BatteryPercentMode::Show;
        TextFixedSize *percentText;
        Image *img;
        Text *percentText                     = nullptr;
        Image *img                            = nullptr;
    };
} // namespace gui

M products/BellHybrid/apps/common/include/common/widgets/BellStatusClock.hpp => products/BellHybrid/apps/common/include/common/widgets/BellStatusClock.hpp +1 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 12,10 12,6 @@ namespace gui
      public:
        explicit BellStatusClock(
            Item *parent                               = nullptr,
            uint32_t x                                 = 0U,
            uint32_t y                                 = 0U,
            uint32_t w                                 = 0U,
            uint32_t h                                 = 0U,
            utils::time::Locale::TimeFormat timeFormat = utils::time::Locale::TimeFormat::FormatTime12H);
    };


M products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp => products/BellHybrid/apps/common/include/common/widgets/LayoutVertical.hpp +12 -10
@@ 16,6 16,7 @@ namespace style::homescreen_vertical
    constexpr inline auto leftMargin        = 60U;
    constexpr inline auto rightMargin       = 60U;
    constexpr inline auto topNegativeMargin = -35;
    constexpr inline auto info_line_h       = 44U;
} // namespace style::homescreen_vertical

namespace gui


@@ 37,19 38,20 @@ namespace gui
        LayoutVertical(
            Item *parent, const uint32_t &x = 0, const uint32_t &y = 0, const uint32_t &w = 0, const uint32_t &h = 0);

        HBox *mainScreen{};
        BellBaseLayout *setAlarmScreen{};
        Icon *alarmActivatedDeactivatedScreen{};
        AlarmIcon *alarmMainIcon{};
        BellBattery *battery{};
        HBox *mainScreen                      = nullptr;
        BellBaseLayout *setAlarmScreen        = nullptr;
        Icon *alarmActivatedDeactivatedScreen = nullptr;
        AlarmIcon *alarmMainIcon              = nullptr;
        TimeSetFmtSpinner *alarmMainTime      = nullptr;
        BellBattery *battery                  = nullptr;

        // Main Screen
        ClockVertical *time{};
        VBox *leftBox{};
        VBox *rightBox{};
        ClockVertical *time = nullptr;
        VBox *leftBox       = nullptr;
        VBox *rightBox      = nullptr;

        // Set Alarm Screen
        AlarmIcon *alarmTopIcon{};
        TimeSetFmtSpinner *setAlarmFmtSpinner{};
        AlarmIcon *alarmTopIcon               = nullptr;
        TimeSetFmtSpinner *setAlarmFmtSpinner = nullptr;
    };
}; // namespace gui

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp +15 -9
@@ 21,7 21,7 @@ namespace
    bool isBatteryCharging(const Store::Battery::State state)
    {
        using State = Store::Battery::State;
        return state == State::Charging or state == State::ChargingDone;
        return (state == State::Charging) || (state == State::ChargingDone);
    }
} // namespace



@@ 50,28 50,32 @@ namespace gui
        snoozeTimer->setVisible(false);
        snoozeTimer->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        time = new TimeSetFmtSpinner(this->centerBox);
        time->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        timeHBox = new HBox(this->centerBox);
        timeHBox->setMaximumSize(style::bell_base_layout::center_layout_w, style::bell_base_layout::center_layout_h);
        timeHBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        timeHBox->setEdges(RectangleEdge::None);

        time = new TimeSetFmtSpinner(timeHBox);
        time->setMaximumSize(style::bell_base_layout::center_layout_w, style::bell_base_layout::center_layout_h);
        time->setFont(mainWindow::time::font);
        time->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        time->setEditMode(EditMode::Browse);
        time->activeItem = false;

        statusBox = new DuoHBox(this->lastBox, 0, 0, 0, 0);
        statusBox->setMinimumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        statusBox = new HBox(this->lastBox);
        statusBox->setMinimumSize(style::homescreen_classic::status_box_layout_w,
                                  style::bell_base_layout::outer_layouts_h);
        statusBox->setEdges(RectangleEdge::None);
        statusBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        statusBox->setVisible(true);

        battery = new BellBattery(nullptr, 0, 0, 0, 0);
        battery->setMinimumSize(battery::battery_widget_w, battery::battery_widget_h);
        battery = new BellBattery(statusBox);
        battery->setMaximumSize(battery::battery_widget_w, battery::battery_widget_h);
        battery->setEdges(RectangleEdge::None);
        battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        battery->setVisible(true);
        battery->setBatteryPercentMode(BatteryPercentMode::Show);

        statusBox->setItems(battery, nullptr);

        bottomText = new TextFixedSize(this->lastBox, 0, 0, 0, 0);
        bottomText->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        bottomText->setFont(mainWindow::bottomDescription::font_small);


@@ 226,6 230,8 @@ namespace gui
    void HomeScreenLayoutClassic::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        time->setTimeFormat(fmt);
        // setTimeFormat makes AM/PM "visible" so disable it
        time->setTimeFormatSpinnerVisibility(false);
    }

    void HomeScreenLayoutClassic::setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt)

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithAmPm.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithAmPm.cpp +23 -4
@@ 21,15 21,16 @@ namespace gui
    {
        using namespace bellMainStyle;

        fmt = new TextFixedSize(nullptr, 0, 0, 0, 0);
        fmt->setMaximumSize(style::homescreen_classic::bottom_box_w, style::homescreen_classic::bottom_box_h);
        battery->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        fmt = new TextFixedSize(statusBox);
        fmt->setMaximumSize(style::homescreen_classic::status_box_layout_w, style::bell_base_layout::outer_layouts_h);
        fmt->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        fmt->setFont(mainWindow::bottomDescription::font_normal);
        fmt->setEdges(RectangleEdge::None);
        fmt->activeItem = false;
        fmt->drawUnderline(false);
        fmt->setText("");

        statusBox->setItems(battery, fmt);
    }

    auto HomeScreenLayoutClassicWithAmPm::setTime(std::time_t newTime) -> void


@@ 40,5 41,23 @@ namespace gui
        const auto hours = std::chrono::hours{t->tm_hour};
        const auto isPM  = date::is_pm(hours);
        fmt->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
        fmt->setMinimumWidthToFitText();
        fmt->setMaximumWidth(fmt->widgetMinimumArea.w);
    }

    bool HomeScreenLayoutClassicWithAmPm::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        return HomeScreenLayoutClassic::isBatteryVisibilityAllowed(batteryContext);
    }

    void HomeScreenLayoutClassicWithAmPm::handleContentChanged()
    {
        if (battery->visible) {
            fmt->setMargins({20, 0, 0, 0});
        }
        else {
            fmt->setMargins({0, 0, 0, 0});
        }
        HomeScreenLayoutClassic::handleContentChanged();
    }
}; // namespace gui

A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp +92 -0
@@ 0,0 1,92 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutClassicWithDate.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/DuoHBox.hpp"

#include <date/date.h>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>

namespace gui
{
    HomeScreenLayoutClassicWithDate::HomeScreenLayoutClassicWithDate(std::string name)
        : HomeScreenLayoutClassic(std::move(name))
    {
        buildInterface();
    }

    void HomeScreenLayoutClassicWithDate::buildInterface()
    {
        using namespace bellMainStyle;

        date = new Text(nullptr);
        date->setMaximumSize(style::homescreen_classic::status_box_layout_w, style::bell_base_layout::outer_layouts_h);
        date->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        date->setFont(mainWindow::bottomDescription::font_normal);
        date->setEdges(RectangleEdge::None);
        date->activeItem = false;
        date->drawUnderline(false);
        date->setText("00/00");
        date->setMargins({0, 0, 20, 0});

        statusBox->removeWidget(battery);
        statusBox->addWidget(date);
        statusBox->addWidget(battery);

        // Assume format is 12h
        time->setMargins({style::homescreen_classic::ampm_time_margin_w, 0, 0, 0});

        ampm = new TextFixedSize(timeHBox);
        ampm->setMinimumSize(style::homescreen_classic::ampm_layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMaximumSize(style::homescreen_classic::ampm_layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMargins({style::homescreen_classic::ampm_margin_w, 0, 0, 0});
        ampm->setFont(mainWindow::time::font_small);
        ampm->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Top));
        ampm->setEdges(RectangleEdge::None);
        ampm->activeItem = false;
        ampm->drawUnderline(false);

        resizeItems();
    }

    void HomeScreenLayoutClassicWithDate::setTime(std::time_t newTime)
    {
        HomeScreenLayoutClassic::setTime(newTime);

        const auto t = std::localtime(&newTime);
        std::stringstream ss;
        ss << std::setfill('0') << std::setw(2) << t->tm_mday;
        ss << '/';
        ss << std::setfill('0') << std::setw(2) << (t->tm_mon + 1);

        date->setText(ss.str());

        if (ampm->visible) {
            const auto hours = std::chrono::hours{t->tm_hour};
            const auto isPM  = date::is_pm(hours);
            ampm->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
        }
    }

    void HomeScreenLayoutClassicWithDate::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        HomeScreenLayoutClassic::setTimeFormat(fmt);
        if (fmt == utils::time::Locale::TimeFormat::FormatTime12H) {
            time->setMargins({style::homescreen_classic::ampm_time_margin_w, 0, 0, 0});
            ampm->setVisible(true);
        }
        else {
            time->setMargins({0, 0, 0, 0});
            ampm->setVisible(false);
        }
    }

    bool HomeScreenLayoutClassicWithDate::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        return true;
    }

}; // namespace gui

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithTemp.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithTemp.cpp +1 -3
@@ 20,14 20,12 @@ namespace gui
    {
        using namespace bellMainStyle;

        tempText = new TextFixedSize(nullptr, 0, 0, 0, 0);
        tempText = new TextFixedSize(statusBox);
        tempText->setMaximumSize(style::homescreen_classic::temperature_w, style::homescreen_classic::temperature_h);
        tempText->setFont(mainWindow::bottomDescription::font_normal);
        tempText->setEdges(RectangleEdge::None);
        tempText->activeItem = false;
        tempText->drawUnderline(false);

        statusBox->setItems(battery, tempText);
    }

    auto HomeScreenLayoutClassicWithTemp::setTemperature(utils::temperature::Temperature newTemp) -> void

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVertical.cpp +26 -7
@@ 18,12 18,6 @@
namespace
{
    constexpr auto dischargingLevelShowTop = 20;

    bool isBatteryCharging(const Store::Battery::State state)
    {
        using State = Store::Battery::State;
        return state == State::Charging or state == State::ChargingDone;
    }
} // namespace

namespace gui


@@ 44,6 38,7 @@ namespace gui
        case app::home_screen::ViewState::Deactivated:
            alarmActivatedDeactivatedScreen->image->set("big_no-alarm_W_G", {});
            alarmMainIcon->setVisible(false);
            alarmMainTime->setVisible(false);
            alarmTopIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
            setScreenMode(ScreenMode::Main);
            break;


@@ 67,12 62,21 @@ namespace gui
            alarmActivatedDeactivatedScreen->image->set("big_alarm_W_G", {});
            alarmMainIcon->setVisible(true);
            alarmMainIcon->setStatus(AlarmIcon::Status::ACTIVATED);
            if (isAlarmTimeVisibilityAllowed()) {
                alarmMainTime->setVisible(true);
                // For unknown reason the mode is modified by showing/hiding windows
                alarmMainTime->setEditMode(EditMode::Browse);
            }
            else {
                alarmMainTime->setVisible(false);
            }
            alarmTopIcon->setStatus(AlarmIcon::Status::ACTIVATED);
            setScreenMode(ScreenMode::Main);
            break;
        case app::home_screen::ViewState::AlarmRinging:
            setScreenMode(ScreenMode::Main);
            alarmMainIcon->setStatus(AlarmIcon::Status::RINGING);
            alarmMainTime->setVisible(false);
            break;
        case app::home_screen::ViewState::AlarmRingingDeactivatedWait:
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);


@@ 80,11 84,13 @@ namespace gui
            break;
        case app::home_screen::ViewState::AlarmSnoozedWait:
            alarmMainIcon->setStatus(AlarmIcon::Status::SNOOZE);
            alarmMainTime->setVisible(false);
            alarmActivatedDeactivatedScreen->image->set("big_alarm_snoozed_W_M", {});
            setScreenMode(ScreenMode::AlarmActivatedDeactivated);
            break;
        case app::home_screen::ViewState::AlarmSnoozed:
            alarmMainIcon->setStatus(AlarmIcon::Status::SNOOZE);
            alarmMainTime->setVisible(false);
            setScreenMode(ScreenMode::Main);
            break;
        }


@@ 126,7 132,18 @@ namespace gui

    bool HomeScreenLayoutVertical::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)
    {
        return (batteryContext.level < dischargingLevelShowTop) or isBatteryCharging(batteryContext.state);
        return (batteryContext.level < dischargingLevelShowTop) || isBatteryCharging(batteryContext.state);
    }

    bool HomeScreenLayoutVertical::isAlarmTimeVisibilityAllowed()
    {
        return false;
    }

    bool HomeScreenLayoutVertical::isBatteryCharging(const Store::Battery::State state)
    {
        using State = Store::Battery::State;
        return (state == State::Charging) || (state == State::ChargingDone);
    }

    void HomeScreenLayoutVertical::setBatteryLevelState(const Store::Battery &batteryContext)


@@ 149,6 166,7 @@ namespace gui
    void HomeScreenLayoutVertical::setAlarmTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        setAlarmFmtSpinner->setTimeFormat(fmt);
        alarmMainTime->setTimeFormat(fmt);
    }

    void HomeScreenLayoutVertical::setTimeFormat(utils::time::Locale::TimeFormat fmt)


@@ 169,6 187,7 @@ namespace gui
    void HomeScreenLayoutVertical::setAlarmTime(std::time_t newTime)
    {
        setAlarmFmtSpinner->setTime(newTime);
        alarmMainTime->setTime(newTime);
    }

    auto HomeScreenLayoutVertical::getLayout() -> Item *

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithAmPm.cpp +10 -10
@@ 44,18 44,18 @@ namespace gui
        battery->setMargins(Margins{0, 0, 0, style::homescreen_vertical_ampm::battery_margin_bot});

        rightBox->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Bottom));
        fmt = new TextFixedSize(rightBox, 0, 0, 0, 0);
        fmt->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        fmt->setFont(mainWindow::bottomDescription::font_normal);
        fmt->setEdges(RectangleEdge::None);
        fmt->activeItem = false;
        fmt->drawUnderline(false);
        fmt->setMargins(Margins{0, 0, 0, style::homescreen_vertical_ampm::fmt_margin_bot});
        fmt->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Bottom));
        ampm = new TextFixedSize(rightBox, 0, 0, 0, 0);
        ampm->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::bell_base_layout::outer_layouts_h);
        ampm->setFont(mainWindow::bottomDescription::font_normal);
        ampm->setEdges(RectangleEdge::None);
        ampm->activeItem = false;
        ampm->drawUnderline(false);
        ampm->setMargins(Margins{0, 0, 0, style::homescreen_vertical_ampm::ampm_margin_bot});
        ampm->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Bottom));

        alarmMainIcon->informContentChanged();
        battery->informContentChanged();
        fmt->informContentChanged();
        ampm->informContentChanged();
    }

    auto HomeScreenLayoutVerticalWithAmPm::setTime(std::time_t newTime) -> void


@@ 65,6 65,6 @@ namespace gui
        const auto t     = std::localtime(&newTime);
        const auto hours = std::chrono::hours{t->tm_hour};
        const auto isPM  = date::is_pm(hours);
        fmt->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
        ampm->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
    }
}; // namespace gui

A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithDate.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalWithDate.cpp +129 -0
@@ 0,0 1,129 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutVerticalWithDate.hpp"
#include "data/BellMainStyle.hpp"
#include "widgets/BellBattery.hpp"
#include "widgets/SnoozeTimer.hpp"

#include <apps-common/actions/AlarmRingingData.hpp>
#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>
#include <gui/widgets/text/TextFixedSize.hpp>
#include <gui/widgets/Style.hpp>
#include <time/time_constants.hpp>
#include <widgets/AlarmIcon.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/ClockVertical.hpp>

namespace gui
{
    HomeScreenLayoutVerticalWithDate::HomeScreenLayoutVerticalWithDate(std::string name)
        : HomeScreenLayoutVertical(std::move(name))
    {
        using namespace bellMainStyle;

        const auto sideBoxWidth = (style::window_width - style::homescreen_vertical::center_box_w) / 2;

        leftBox->setMinimumSize(sideBoxWidth, style::window_height);
        leftBox->setMargins(Margins({0, 0, 0, 0}));
        leftBox->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Top));

        leftBox->addWidget(alarmMainIcon);
        alarmMainIcon->setMargins(Margins{0, style::homescreen_vertical_date::margin_top, 0, 0});
        alarmMainIcon->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Top));

        leftBox->addWidget(alarmMainTime);

        rightBox->setMinimumSize(sideBoxWidth, style::window_height);
        rightBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Bottom));
        rightBox->setMargins(Margins({0, 0, 0, 0}));

        rightBox->addWidget(battery);
        battery->setFont(mainWindow::bottomDescription::font_smallnormal);
        battery->setBatteryPercentMode(BatteryPercentMode::Show);
        battery->setEdges(RectangleEdge::None);
        battery->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        battery->setMinimumSize(battery::battery_widget_w, style::homescreen_vertical::info_line_h);
        battery->setMaximumSize(battery::battery_widget_w, style::homescreen_vertical::info_line_h);

        date = new TextFixedSize(rightBox);
        date->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::homescreen_vertical::info_line_h);
        date->setFont(mainWindow::bottomDescription::font_smallnormal);
        date->setEdges(RectangleEdge::None);
        date->activeItem = false;
        date->drawUnderline(false);
        date->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        date->setText("00/00");

        // Assume 12h format
        ampm = new TextFixedSize(rightBox);
        ampm->setMaximumSize(style::bell_base_layout::outer_layouts_w, style::homescreen_vertical::info_line_h);
        ampm->setFont(mainWindow::bottomDescription::font_smallnormal);
        ampm->setEdges(RectangleEdge::None);
        ampm->activeItem = false;
        ampm->drawUnderline(false);
        ampm->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        ampm->setText("XX");
        ampm->setMargins(Margins{0, 0, 0, style::homescreen_vertical_date::margin_bot});

        alarmMainIcon->informContentChanged();
        battery->informContentChanged();
        date->informContentChanged();
        ampm->informContentChanged();
    }

    auto HomeScreenLayoutVerticalWithDate::setTime(std::time_t newTime) -> void
    {
        HomeScreenLayoutVertical::setTime(newTime);

        const auto t = std::localtime(&newTime);

        std::stringstream ss;
        ss << std::setfill('0') << std::setw(2) << t->tm_mday;
        ss << '/';
        ss << std::setfill('0') << std::setw(2) << (t->tm_mon + 1);

        date->setText(ss.str());

        if (ampm->visible) {
            const auto hours = std::chrono::hours{t->tm_hour};
            const auto isPM  = date::is_pm(hours);
            ampm->setText(isPM ? utils::time::Locale::getPM() : utils::time::Locale::getAM());
        }
    }

    void HomeScreenLayoutVerticalWithDate::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        HomeScreenLayoutVertical::setTimeFormat(fmt);
        if (fmt == utils::time::Locale::TimeFormat::FormatTime12H) {
            ampm->setMargins(Margins{0, 0, 0, style::homescreen_vertical_date::margin_bot});
            date->setMargins({0, 0, 0, 0});
            ampm->setVisible(true);
        }
        else {
            ampm->setMargins({0, 0, 0, 0});
            date->setMargins(Margins{0, 0, 0, style::homescreen_vertical_date::margin_bot});
            ampm->setVisible(false);
        }
    }

    void HomeScreenLayoutVerticalWithDate::setBatteryLevelState(const Store::Battery &batteryContext)
    {
        // In 24h mode battery indicator is lower so 100% is too long to be displayed
        if (!ampm->visible) {
            const auto percentMode = batteryContext.level < 100 ? BatteryPercentMode::Show : BatteryPercentMode::Hide;
            battery->setBatteryPercentMode(percentMode);
        }
        else
            battery->setBatteryPercentMode(BatteryPercentMode::Show);
        battery->update(batteryContext.level, isBatteryCharging(batteryContext.state));
        battery->setVisible(true);
        battery->informContentChanged();
    }

    bool HomeScreenLayoutVerticalWithDate::isAlarmTimeVisibilityAllowed()
    {
        return true;
    }
}; // namespace gui

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp +8 -3
@@ 6,11 6,13 @@
#include <common/layouts/HomeScreenLayoutClassic.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithAmPm.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithBattery.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithDate.hpp>
#if CONFIG_ENABLE_TEMP == 1
#include <common/layouts/HomeScreenLayoutClassicWithTemp.hpp>
#endif
#include <common/layouts/HomeScreenLayoutVerticalSimple.hpp>
#include <common/layouts/HomeScreenLayoutVerticalWithAmPm.hpp>
#include <common/layouts/HomeScreenLayoutVerticalWithDate.hpp>
#include <ProductConfig.hpp>

namespace gui::factory


@@ 21,8 23,10 @@ namespace gui::factory
        {
            {"Classic", []() { return new HomeScreenLayoutClassic("Classic"); }},
                {"ClassicWithBattery", []() { return new HomeScreenLayoutClassicWithBattery("ClassicWithBattery"); }},
                {"ClassicWithDate", []() { return new HomeScreenLayoutClassicWithDate("ClassicWithDate"); }},
                {"VerticalSimple", []() { return new HomeScreenLayoutVerticalSimple("VerticalSimple"); }},
            {
                "VerticalSimple", []() { return new HomeScreenLayoutVerticalSimple("VerticalSimple"); }
                "VerticalWithDate", []() { return new HomeScreenLayoutVerticalWithDate("VerticalWithDate"); }
            }
#if CONFIG_ENABLE_TEMP == 1
            ,


@@ 38,12 42,13 @@ namespace gui::factory
        return
        {
            {"Classic", []() { return new HomeScreenLayoutClassic("Classic"); }},

                {"ClassicWithAmPm", []() { return new HomeScreenLayoutClassicWithAmPm("ClassicWithAmPm"); }},
                {"ClassicWithBattery", []() { return new HomeScreenLayoutClassicWithBattery("ClassicWithBattery"); }},
                {"ClassicWithDate", []() { return new HomeScreenLayoutClassicWithDate("ClassicWithDateAmPm"); }},
                {"VerticalSimple", []() { return new HomeScreenLayoutVerticalSimple("VerticalSimple"); }},
                {"VerticalWithAmPm", []() { return new HomeScreenLayoutVerticalWithAmPm("VerticalWithAmPm"); }},
            {
                "VerticalWithAmPm", []() { return new HomeScreenLayoutVerticalWithAmPm("VerticalWithAmPm"); }
                "VerticalWithDate", []() { return new HomeScreenLayoutVerticalWithDate("VerticalWithDateAmPm"); }
            }
#if CONFIG_ENABLE_TEMP == 1
            ,

M products/BellHybrid/apps/common/src/widgets/BellBattery.cpp => products/BellHybrid/apps/common/src/widgets/BellBattery.cpp +32 -10
@@ 20,30 20,39 @@ namespace

namespace gui
{
    BellBattery::BellBattery(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) : HBox(parent, x, y, w, h)
    BellBattery::BellBattery(Item *parent) : HBox(parent)
    {
        img = new Image(this, battery_low, gui::ImageTypeSpecifier::W_M);
        img->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        img->setMargins(gui::Margins(0, 0, battery::image_right_margin, 0));

        percentText = new TextFixedSize(this, 0, 0, 0, 0);
        percentText->setMinimumSize(battery::percent_w, battery::percent_h);
        percentText = new Text(this);
        percentText->setMaximumSize(battery::percent_w, battery::percent_h);
        percentText->setFont(battery::font_small);
        percentText->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        percentText->setEdges(RectangleEdge::None);
        percentText->setEditMode(EditMode::Browse);
        percentText->activeItem = false;
        percentText->drawUnderline(false);
        percentText->setVisible(false);
        percentText->setText("000%");
    }

    void BellBattery::setFont(const UTF8 &fontName)
    {
        percentText->setFont(fontName);
    }

    void BellBattery::update(const units::SOC soc, const bool isCharging)
    {
        const auto image = battery_utils::getBatteryLevelImage(entries, soc);
        if (not image) {
        if (!image) {
            return;
        }

        percentText->setText(std::to_string(soc) + "%");
        const auto text = UTF8(std::to_string(soc) + "%");
        // Without this the text is not set properly if percentText was hidden
        percentText->setMinimumWidthToFitText(text);
        percentText->setText(text);

        if (isCharging) {
            img->set(battery_charging, gui::ImageTypeSpecifier::W_M);


@@ 52,20 61,33 @@ namespace gui
            img->set(image->data(), gui::ImageTypeSpecifier::W_M);
        }

        setBatteryPercentMode(batteryPercentMode);
    }

    void BellBattery::setBatteryPercentMode(BatteryPercentMode mode)
    {
        batteryPercentMode = mode;
        if (batteryPercentMode == BatteryPercentMode::Show) {
            img->setMargins(gui::Margins(0, 0, battery::image_right_margin, 0));
            percentText->setVisible(true);
        }
        else {
            img->setMargins(gui::Margins(0, 0, 0, 0));
            percentText->setVisible(false);
        }

        setWidthsToFitContent();
        img->informContentChanged();
    }

    void BellBattery::setBatteryPercentMode(BatteryPercentMode mode)
    void BellBattery::setWidthsToFitContent()
    {
        batteryPercentMode = mode;
        if (batteryPercentMode == BatteryPercentMode::Hide) {
            percentText->setVisible(false);
        auto width = img->widgetMinimumArea.w + img->getMargins().right;
        if (percentText->visible) {
            percentText->setMinimumWidthToFitText();
            width += percentText->widgetMinimumArea.w;
        }
        setMinimumWidth(width);
        setMaximumWidth(width);
    }
} // namespace gui

M products/BellHybrid/apps/common/src/widgets/BellStatusClock.cpp => products/BellHybrid/apps/common/src/widgets/BellStatusClock.cpp +3 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <common/widgets/BellStatusClock.hpp>


@@ 8,9 8,8 @@
namespace gui
{

    BellStatusClock::BellStatusClock(
        Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h, utils::time::Locale::TimeFormat timeFormat)
        : TimeSetFmtSpinner{parent, x, y, w, h, timeFormat}
    BellStatusClock::BellStatusClock(Item *parent, utils::time::Locale::TimeFormat timeFormat)
        : TimeSetFmtSpinner{parent, timeFormat}
    {
        setFont(bell_style::statusClockFont);
        setEditMode(EditMode::Browse);

M products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp => products/BellHybrid/apps/common/src/widgets/LayoutVertical.cpp +15 -1
@@ 26,9 26,14 @@ namespace gui
    {
        using namespace bellMainStyle;

        setMinimumSize(style::window_width, style::window_height);
        setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        setEdges(RectangleEdge::None);

        // Main Screen
        mainScreen = new HBox(this);
        mainScreen->setMinimumSize(style::window_width, style::window_height);
        mainScreen->setEdges(RectangleEdge::None);

        leftBox = new VBox(mainScreen, 0, 0, 0, 0);
        leftBox->setMinimumSize(style::homescreen_vertical::side_box_w, style::window_height);


@@ 38,6 43,7 @@ namespace gui
        auto centerBox = new VBox(mainScreen, 0, 0, 0, 0);
        centerBox->setMinimumSize(style::homescreen_vertical::center_box_w, style::window_height);
        centerBox->setEdges(RectangleEdge::None);
        centerBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        time = new ClockVertical(centerBox);
        time->setFont(style::window::font::colossal);


@@ 56,7 62,15 @@ namespace gui
        alarmMainIcon->setStatus(AlarmIcon::Status::DEACTIVATED);
        alarmMainIcon->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        battery = new BellBattery(nullptr, 0, 0, 0, 0);
        alarmMainTime = new TimeSetFmtSpinner(leftBox);
        alarmMainTime->setMaximumSize(style::bell_base_layout::outer_layouts_w,
                                      style::homescreen_vertical::info_line_h);
        alarmMainTime->setFont(mainWindow::bottomDescription::font_smallnormal);
        alarmMainTime->setEditMode(EditMode::Browse);
        alarmMainTime->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center));
        alarmMainTime->setVisible(false);

        battery = new BellBattery(nullptr);
        battery->setMinimumSize(battery::battery_widget_w, battery::battery_widget_h);
        battery->setEdges(RectangleEdge::None);
        battery->setVisible(true);

M products/BellHybrid/apps/common/src/widgets/ListItems.cpp => products/BellHybrid/apps/common/src/widgets/ListItems.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <common/data/StyleCommon.hpp>


@@ 48,7 48,7 @@ namespace gui
                               const std::string &topDescription)
        : BellSideListItemWithCallbacks(topDescription)
    {
        spinner = new TimeSetFmtSpinner(body->getCenterBox(), 0, 0, 0, 0, timeFormat);
        spinner = new TimeSetFmtSpinner(body->getCenterBox(), timeFormat);
        spinner->setMaximumSize(::style::bell_base_layout::w, ::style::bell_base_layout::h);
        spinner->setFont(focusFont, noFocusFont);
        spinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

M products/BellHybrid/assets/assets_proprietary.json => products/BellHybrid/assets/assets_proprietary.json +5 -0
@@ 20,6 20,11 @@
            "ref": "10c74fcb09c2022325767cad735c0183b6f5393a"
        },
        {
            "name": "./fonts/bell/gt_pressura_light_40.mpf",
            "output": "assets/fonts/gt_pressura/gt_pressura_light_40.mpf",
            "ref": "594167d42d7881e3d7c6fa28db945cd5409db69c"
        },
        {
            "name": "./fonts/bell/gt_pressura_regular_90.mpf",
            "ref": "10c74fcb09c2022325767cad735c0183b6f5393a",
            "output": "assets/fonts/gt_pressura/gt_pressura_regular_90.mpf"