~aleteoryx/muditaos

7088002df312b4eeead556d89160c47d4bc93f4d — Maciej Gibowicz 1 year, 10 months ago 9726445
[BH-1860] Add new clock face with quotes

In the settings, the user can choose a clock face with quotes. A
dedicated clock face includes information about the time, alarm
settings, quote and author of the quote.
22 files changed, 321 insertions(+), 31 deletions(-)

M harmony_changelog.md
M module-apps/apps-common/widgets/TimeSetSpinner.cpp
M module-apps/apps-common/widgets/TimeSetSpinner.hpp
M module-gui/gui/widgets/ImageBox.cpp
M module-gui/gui/widgets/ImageBox.hpp
M products/BellHybrid/CMakeLists.txt
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/HomeScreenLayoutClassicWithDate.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithQuotes.hpp
A products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithQuotesAmPm.hpp
M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutNames.hpp
M products/BellHybrid/apps/common/include/common/widgets/BellConnectionStatus.hpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithQuotes.cpp
A products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithQuotesAmPm.cpp
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp
M products/BellHybrid/apps/common/src/widgets/BellConnectionStatus.cpp
M products/BellHybrid/assets/assets_common.json
M products/BellHybrid/assets/assets_proprietary.json
M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 6,6 6,7 @@

### Added
* Added new 32px and 170px fonts
* Added new clock face with quotes

### Changed / Improved
* Updated FSL drivers from NXP

M module-apps/apps-common/widgets/TimeSetSpinner.cpp => module-apps/apps-common/widgets/TimeSetSpinner.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimeSetSpinner.hpp"


@@ 158,7 158,7 @@ namespace gui

        colon->setImage(getColonImage(noFocusFontName));
        colon->setMargins(getColonMargins(noFocusFontName));
        colon->setMinimumSizeToFitImage();
        colon->fitBoxToImage();

        setMinimumSize(hour->widgetMinimumArea.w + colon->widgetMinimumArea.w +
                           colon->getMargins().getSumInAxis(Axis::X) + minute->widgetMinimumArea.w,

M module-apps/apps-common/widgets/TimeSetSpinner.hpp => module-apps/apps-common/widgets/TimeSetSpinner.hpp +2 -1
@@ 19,6 19,7 @@ namespace style::time_set_spinner
    inline constexpr auto very_small_margin       = 3U;
    inline constexpr auto small_margin = 6U;
    inline constexpr auto big_margin   = 6U;
    inline constexpr auto huge_margin             = 6U;
    inline constexpr auto gargantuan_margin_left  = 14U;
    inline constexpr auto gargantuan_margin_right = 7U;
    inline constexpr auto bottom_align_margin     = -12;


@@ 65,7 66,7 @@ namespace gui
            {style::window::font::large, {style::time_set_spinner::small_margin, 0, style::time_set_spinner::small_margin, style::time_set_spinner::bottom_align_margin}},
            {style::window::font::supersizeme, {style::time_set_spinner::big_margin, 0, style::time_set_spinner::big_margin, 0}},
            {style::window::font::supersizemelight, {style::time_set_spinner::big_margin, 0, style::time_set_spinner::big_margin, 0}},
            {style::window::font::huge, {style::time_set_spinner::big_margin, 0, style::time_set_spinner::big_margin, 0}},
            {style::window::font::huge, {style::time_set_spinner::huge_margin, 0, style::time_set_spinner::huge_margin, 0}},
            {style::window::font::gargantuan, {style::time_set_spinner::gargantuan_margin_left, 0, style::time_set_spinner::gargantuan_margin_right, 0}}};
        // clang-format on


M module-gui/gui/widgets/ImageBox.cpp => module-gui/gui/widgets/ImageBox.cpp +7 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ImageBox.hpp"


@@ 26,6 26,12 @@ void ImageBox::setImage(const UTF8 &name, ImageTypeSpecifier specifier)
    image->set(name, specifier);
}

void ImageBox::fitBoxToImage()
{
    setMinimumSize(image->getWidth(), image->getHeight());
    setMaximumSize(image->getWidth(), image->getHeight());
}

void ImageBox::setMinimumSizeToFitImage()
{
    setMinimumSize(image->getWidth(), image->getHeight());

M module-gui/gui/widgets/ImageBox.hpp => module-gui/gui/widgets/ImageBox.hpp +4 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 18,6 18,9 @@ namespace gui

        void showImage(bool show);
        void setImage(const UTF8 &name, ImageTypeSpecifier specifier = ImageTypeSpecifier::None);
        /// adjusts the box size perfectly to the image
        void fitBoxToImage();
        /// adjusts the box size to at least the same size as the image
        virtual void setMinimumSizeToFitImage();

      protected:

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +2 -2
@@ 143,14 143,14 @@ download_asset_release_json(json-common-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_common.json
                           ${SYSROOT_PATH}/system_a/
                            MuditaOSPublicAssets
                            0.0.21
                            0.0.22
                            ${MUDITA_CACHE_DIR}
    )
download_asset_release_json(json-community-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_community.json
                           ${SYSROOT_PATH}/system_a/
                            MuditaOSPublicAssets
                            0.0.21
                            0.0.22
                            ${MUDITA_CACHE_DIR}
    )
download_asset_json(json-rt1051-target

M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +4 -0
@@ 68,6 68,8 @@ target_sources(application-bell-common
        src/layouts/HomeScreenLayoutClassicWithAmPm.cpp
        src/layouts/HomeScreenLayoutClassicWithBattery.cpp
        src/layouts/HomeScreenLayoutClassicWithDate.cpp
        src/layouts/HomeScreenLayoutClassicWithQuotes.cpp
        src/layouts/HomeScreenLayoutClassicWithQuotesAmPm.cpp
        src/layouts/HomeScreenLayoutClassicWithTemp.cpp
        src/layouts/HomeScreenLayoutVertical.cpp
        src/layouts/HomeScreenLayoutVerticalSimple.cpp


@@ 139,6 141,8 @@ target_sources(application-bell-common
        include/common/layouts/HomeScreenLayoutClassicWithAmPm.hpp
        include/common/layouts/HomeScreenLayoutClassicWithBattery.hpp
        include/common/layouts/HomeScreenLayoutClassicWithDate.hpp
        include/common/layouts/HomeScreenLayoutClassicWithQuotes.hpp
        include/common/layouts/HomeScreenLayoutClassicWithQuotesAmPm.hpp
        include/common/layouts/HomeScreenLayoutClassicWithTemp.hpp
        include/common/layouts/HomeScreenLayoutVertical.hpp
        include/common/layouts/HomeScreenLayoutVerticalSimple.hpp

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

#pragma once


@@ 27,5 27,13 @@ namespace bellMainStyle
            inline constexpr auto font_small  = style::window::font::verybiglight;

        } // namespace bottomDescription
    }     // namespace mainWindow

        namespace ampm
        {
            inline constexpr auto layout_w      = 51U;
            inline constexpr auto margin_w      = 5U;
            inline constexpr auto time_margin_w = layout_w + margin_w;
        } // namespace ampm

    } // namespace mainWindow
} // namespace bellMainStyle

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassic.hpp +3 -0
@@ 94,5 94,8 @@ namespace gui
        AlarmSetSpinner *alarm    = nullptr;
        SnoozeTimer *snoozeTimer  = nullptr;
        Icon *lowBatteryWarning                = nullptr;

        std::function<void()> onShowMessage;
        std::function<void()> onHideMessage;
    };
}; // namespace gui

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithDate.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutClassicWithDate.hpp +1 -7
@@ 1,16 1,10 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, 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

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

#pragma once

#include "HomeScreenLayoutClassic.hpp"

namespace gui
{
    class HomeScreenLayoutClassicWithQuotes : public HomeScreenLayoutClassic
    {
      public:
        explicit HomeScreenLayoutClassicWithQuotes(std::string name);

      protected:
        void buildInterface() override;

        VBox *textBox{nullptr};
        TextFixedSize *quotes{nullptr};
        TextFixedSize *author{nullptr};
        VBox *imgBox{nullptr};
        Image *quoteImg{nullptr};

      private:
        void showQuotes();
        void hideQuotes();
    };
}; // namespace gui

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

#pragma once

#include "HomeScreenLayoutClassicWithQuotes.hpp"

namespace gui
{
    class HomeScreenLayoutClassicWithQuotesAmPm : public HomeScreenLayoutClassicWithQuotes
    {
      public:
        explicit HomeScreenLayoutClassicWithQuotesAmPm(std::string name);

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

      protected:
        void buildInterface() override;

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

M products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutNames.hpp => products/BellHybrid/apps/common/include/common/layouts/HomeScreenLayoutNames.hpp +11 -9
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 7,14 7,16 @@ namespace gui
{
    namespace layout
    {
        constexpr auto Classic              = "Classic";
        constexpr auto ClassicWithBattery   = "ClassicWithBattery";
        constexpr auto ClassicWithAmPm      = "ClassicWithAmPm";
        constexpr auto ClassicWithDate      = "ClassicWithDate";
        constexpr auto VerticalSimple       = "VerticalSimple";
        constexpr auto VerticalWithDate     = "VerticalWithDate";
        constexpr auto VerticalWithAmPm     = "VerticalWithAmPm";
        constexpr auto VerticalWithDateAmPm = "VerticalWithDateAmPm";
        constexpr auto Classic               = "Classic";
        constexpr auto ClassicWithBattery    = "ClassicWithBattery";
        constexpr auto ClassicWithAmPm       = "ClassicWithAmPm";
        constexpr auto ClassicWithDate       = "ClassicWithDate";
        constexpr auto ClassicWithQuotes     = "ClassicWithQuotes";
        constexpr auto ClassicWithQuotesAmPm = "ClassicWithQuotesAmPm";
        constexpr auto VerticalSimple        = "VerticalSimple";
        constexpr auto VerticalWithDate      = "VerticalWithDate";
        constexpr auto VerticalWithAmPm      = "VerticalWithAmPm";
        constexpr auto VerticalWithDateAmPm  = "VerticalWithDateAmPm";

#if CONFIG_ENABLE_TEMP == 1
        constexpr auto ClassicWithTemp = "ClassicWithTemp";

M products/BellHybrid/apps/common/include/common/widgets/BellConnectionStatus.hpp => products/BellHybrid/apps/common/include/common/widgets/BellConnectionStatus.hpp +1 -0
@@ 15,6 15,7 @@ namespace gui
        BellConnectionStatus(Item *parent);
        void setFont(const UTF8 &fontName);
        void show(bool visibility);
        bool isVisible() const;

      private:
        Text *statusText = nullptr;

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassic.cpp +13 -0
@@ 276,6 276,9 @@ namespace gui

    void HomeScreenLayoutClassic::setTextDescription(const UTF8 &desc)
    {
        if (onShowMessage != nullptr) {
            onShowMessage();
        }
        statusBox->setVisible(false);
        bottomText->setVisible(true);
        bottomText->setRichText(desc);


@@ 289,6 292,9 @@ namespace gui
        bottomText->setVisible(false);
        statusBox->resizeItems();
        statusBox->informContentChanged();
        if (onHideMessage != nullptr) {
            onHideMessage();
        }
    }

    bool HomeScreenLayoutClassic::isBatteryVisibilityAllowed(const Store::Battery &batteryContext)


@@ 352,6 358,13 @@ namespace gui
    }
    auto HomeScreenLayoutClassic::updateUsbStatus(bool isConnected) -> void
    {
        if (isConnected && (onShowMessage != nullptr)) {
            onShowMessage();
        }
        else if (!isConnected && (onHideMessage != nullptr))
        {
            onHideMessage();
        }
        connectionStatus->show(isConnected);
        connectionStatus->informContentChanged();
        adjustConnectionStatusPosition();

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithDate.cpp +5 -5
@@ 39,12 39,12 @@ namespace gui
        infoBox->addWidget(date);

        // Assume format is 12h
        time->setMargins({style::homescreen_classic::ampm_time_margin_w, 0, 0, 0});
        time->setMargins({mainWindow::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->setMinimumSize(mainWindow::ampm::layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMaximumSize(mainWindow::ampm::layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMargins({mainWindow::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);


@@ 73,7 73,7 @@ namespace gui
    {
        HomeScreenLayoutClassic::setTimeFormat(fmt);
        if (fmt == utils::time::Locale::TimeFormat::FormatTime12H) {
            time->setMargins({style::homescreen_classic::ampm_time_margin_w, 0, 0, 0});
            time->setMargins({bellMainStyle::mainWindow::ampm::time_margin_w, 0, 0, 0});
            ampm->setVisible(true);
        }
        else {

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

#include "layouts/HomeScreenLayoutClassicWithQuotes.hpp"
#include "data/BellMainStyle.hpp"

#include <widgets/text/TextFixedSize.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>
#include <widgets/BellConnectionStatus.hpp>

namespace
{
    constexpr auto maxTimeBoxHeight{148U};
    constexpr auto textBoxHeight{120U};

    constexpr auto imgBoxHeight{52U};
    constexpr auto imgTopMargin{10U};

    constexpr auto quoteImageName{"bell_quote"};
    constexpr auto quoteFont{style::window::font::mediumbiglight};
    constexpr auto quoteHeight{70U};

    constexpr auto authorFont{style::window::font::mediumbigbold};
    constexpr auto authorHeight{42U};
}; // namespace

namespace gui
{
    HomeScreenLayoutClassicWithQuotes::HomeScreenLayoutClassicWithQuotes(std::string name)
        : HomeScreenLayoutClassic(std::move(name))
    {
        buildInterface();
        onShowMessage = [this]() { hideQuotes(); };
        onHideMessage = [this]() {
            if (!connectionStatus->isVisible()) {
                showQuotes();
            }
        };
    }

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

        this->centerBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));

        timeHBox->setMaximumHeight(maxTimeBoxHeight);
        timeHBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));

        time->setMaximumHeight(maxTimeBoxHeight);
        time->setFont(style::window::font::huge);
        time->setMargins({0, 0, 0, 0});

        imgBox = new VBox(this->centerBox);
        imgBox->setMinimumSize(style::homescreen_classic::status_box_layout_w, imgBoxHeight);
        imgBox->setEdges(RectangleEdge::None);
        imgBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        imgBox->setVisible(true);

        quoteImg = new Image(imgBox, quoteImageName, gui::ImageTypeSpecifier::W_M);
        quoteImg->setMargins({0, imgTopMargin, 0, 0});
        quoteImg->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));

        // We do not display information about the battery status at any time
        // only about the status of the USB connection
        widgetBox->removeWidget(infoBox);
        widgetBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));

        textBox = new VBox(nullptr);
        textBox->setMinimumSize(style::bell_base_layout::last_layout_w, textBoxHeight);
        textBox->setEdges(RectangleEdge::None);
        textBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        textBox->setVisible(true);

        quotes = new TextFixedSize(nullptr);
        quotes->setMaximumSize(style::bell_base_layout::last_layout_w, quoteHeight);
        quotes->setMargins({0, 0, 0, 0});
        quotes->setFont(quoteFont);
        quotes->setText("Wherever you are, and whatever you do, be in love.");
        quotes->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        quotes->setEdges(RectangleEdge::None);
        quotes->activeItem = false;
        quotes->drawUnderline(false);
        quotes->setVisible(true);

        author = new TextFixedSize(nullptr);
        author->setMaximumSize(style::bell_base_layout::last_layout_w, authorHeight);
        author->setMargins({0, 0, 0, 0});
        author->setFont(authorFont);
        author->setText("-Rumi");
        author->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        author->setEdges(RectangleEdge::None);
        author->activeItem = false;
        author->drawUnderline(false);
        author->setVisible(true);

        textBox->addWidget(quotes);
        textBox->addWidget(author);

        statusBox->setVisible(false);
        this->lastBox->addWidget(textBox);

        resizeItems();
    }

    void HomeScreenLayoutClassicWithQuotes::showQuotes()
    {
        if (!textBox->visible) {
            statusBox->setVisible(false);
            textBox->setVisible(true);
            textBox->informContentChanged();
            imgBox->setVisible(true);
            imgBox->informContentChanged();
        }
    }

    void HomeScreenLayoutClassicWithQuotes::hideQuotes()
    {
        if (textBox->visible) {
            textBox->setVisible(false);
            imgBox->setVisible(false);
            statusBox->setVisible(true);
            statusBox->informContentChanged();
        }
    }

}; // namespace gui

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

#include "layouts/HomeScreenLayoutClassicWithQuotesAmPm.hpp"
#include "data/BellMainStyle.hpp"

#include <widgets/text/TextFixedSize.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>

namespace gui
{
    HomeScreenLayoutClassicWithQuotesAmPm::HomeScreenLayoutClassicWithQuotesAmPm(std::string name)
        : HomeScreenLayoutClassicWithQuotes(std::move(name))
    {
        buildInterface();
    }

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

        time->setMargins({mainWindow::ampm::time_margin_w, 0, 0, 0});

        ampm = new TextFixedSize(timeHBox);
        ampm->setMinimumSize(mainWindow::ampm::layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMaximumSize(mainWindow::ampm::layout_w, style::bell_base_layout::center_layout_h);
        ampm->setMargins({mainWindow::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 HomeScreenLayoutClassicWithQuotesAmPm::setTime(std::time_t newTime)
    {
        HomeScreenLayoutClassic::setTime(newTime);
        const auto t = std::localtime(&newTime);

        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 HomeScreenLayoutClassicWithQuotesAmPm::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        HomeScreenLayoutClassic::setTimeFormat(fmt);
        if (fmt == utils::time::Locale::TimeFormat::FormatTime12H) {
            time->setMargins({bellMainStyle::mainWindow::ampm::time_margin_w, 0, 0, 0});
            ampm->setVisible(true);
        }
        else {
            time->setMargins({0, 0, 0, 0});
            ampm->setVisible(false);
        }
    }

}; // namespace gui

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayouts.cpp +8 -0
@@ 8,6 8,8 @@
#include <common/layouts/HomeScreenLayoutClassicWithAmPm.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithBattery.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithDate.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithQuotes.hpp>
#include <common/layouts/HomeScreenLayoutClassicWithQuotesAmPm.hpp>
#if CONFIG_ENABLE_TEMP == 1
#include <common/layouts/HomeScreenLayoutClassicWithTemp.hpp>
#endif


@@ 27,6 29,8 @@ namespace gui::factory
                 []() { return new HomeScreenLayoutClassicWithBattery(gui::layout::ClassicWithBattery); }},
                {gui::layout::ClassicWithDate,
                 []() { return new HomeScreenLayoutClassicWithDate(gui::layout::ClassicWithDate); }},
                {gui::layout::ClassicWithQuotes,
                 []() { return new HomeScreenLayoutClassicWithQuotes(gui::layout::ClassicWithQuotes); }},
                {gui::layout::VerticalSimple,
                 []() { return new HomeScreenLayoutVerticalSimple(gui::layout::VerticalSimple); }},
            {


@@ 54,6 58,10 @@ namespace gui::factory
                 []() { return new HomeScreenLayoutClassicWithBattery(gui::layout::ClassicWithBattery); }},
                {gui::layout::ClassicWithDate,
                 []() { return new HomeScreenLayoutClassicWithDate(gui::layout::ClassicWithDate); }},
                {gui::layout::ClassicWithQuotes,
                 []() { return new HomeScreenLayoutClassicWithQuotes(gui::layout::ClassicWithQuotes); }},
                {gui::layout::ClassicWithQuotesAmPm,
                 []() { return new HomeScreenLayoutClassicWithQuotesAmPm(gui::layout::ClassicWithQuotesAmPm); }},
                {gui::layout::VerticalSimple,
                 []() { return new HomeScreenLayoutVerticalSimple(gui::layout::VerticalSimple); }},
                {gui::layout::VerticalWithAmPm,

M products/BellHybrid/apps/common/src/widgets/BellConnectionStatus.cpp => products/BellHybrid/apps/common/src/widgets/BellConnectionStatus.cpp +5 -0
@@ 38,4 38,9 @@ namespace gui
    {
        statusText->setVisible(visibility);
    }

    bool BellConnectionStatus::isVisible() const
    {
        return statusText->visible;
    }
} // namespace gui

M products/BellHybrid/assets/assets_common.json => products/BellHybrid/assets/assets_common.json +1 -0
@@ 65,6 65,7 @@
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/shortcuts_step_bedside_lamp_W_G.vpi", "output": "assets/images/shortcuts_step_bedside_lamp_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/big_information_W_G.vpi", "output": "assets/images/big_information_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/big_bell_battery_charging_W_G.vpi", "output": "assets/images/big_bell_battery_charging_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_quote_W_M.vpi", "output": "assets/images/bell_quote_W_M.vpi"},

        {"name": "release_audio.tgz", "tarfile" :"./image/assets/audio/bell/chimes/Blissful_Dream.mp3", "output": "assets/audio/chimes/Blissful_Dream.mp3"},
        {"name": "release_audio.tgz", "tarfile" :"./image/assets/audio/bell/chimes/Gentle_Chime.mp3", "output": "assets/audio/chimes/Gentle_Chime.mp3"},

M products/BellHybrid/assets/assets_proprietary.json => products/BellHybrid/assets/assets_proprietary.json +1 -1
@@ 81,7 81,7 @@
        {
            "name": "./fonts/bell/gt_pressura_regular_170.mpf",
            "output": "assets/fonts/gt_pressura/gt_pressura_regular_170.mpf",
            "ref": "0cf242e02002bc0af4216a00ac7501a1fbe1ba1e"
            "ref": "a495a5acbbb19e8b5c1d670a3041cfc1f046db33"
        },
        {
            "name": "./fonts/bell/gt_pressura_light_32.mpf",