~aleteoryx/muditaos

97bd1178684ed9da607dde251b27497df82d040e — Dawid Wojtas 3 years ago e7b504b
[BH-1577][BH-1578] New Power Nap layout

Add circular progress bar to power nap.
Ringing bell image at the end of the power nap.
A art/bell/big_bell_ringing_W_G.png => art/bell/big_bell_ringing_W_G.png +0 -0
M harmony_changelog.md => harmony_changelog.md +11 -0
@@ 1,5 1,16 @@
# MuditaOS changelog - Harmony

## Unreleased

### Changed / Improved

### Fixed

### Added
#### PowerNap:
* New circular progress bar 
* Ringing bell image at the end of the Power Nap

## [1.6.0 2022-06-14]

### Added

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.10
                            0.0.11
                            ${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.10
                            0.0.11
                            ${MUDITA_CACHE_DIR}
    )
download_asset_json(json-rt1051-target

M products/BellHybrid/apps/application-bell-powernap/data/PowerNapStyle.hpp => products/BellHybrid/apps/application-bell-powernap/data/PowerNapStyle.hpp +43 -1
@@ 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,6 12,48 @@ namespace gui::powerNapStyle
    inline constexpr auto napPeriodFont   = style::window::font::supersizeme;
    inline constexpr auto clockFont       = style::window::font::verybiglight;

    namespace pnStyle
    {
        namespace progress
        {
            constexpr inline auto radius                   = 192;
            constexpr inline auto penWidth                 = 3;
            constexpr inline auto verticalDeviationDegrees = 38;
        } // namespace progress

        namespace timer
        {
            constexpr inline auto marginTop   = 41;
            constexpr inline auto marginRight = 32;
            constexpr inline auto font        = style::window::font::supersizeme;
            constexpr inline auto maxSizeX    = 340;
            constexpr inline auto maxSizeY    = 198;
        } // namespace timer

        namespace pauseIcon
        {
            constexpr inline auto image     = "big_pause";
            constexpr inline auto marginTop = 39;
            constexpr inline auto maxSizeX  = 203;
            constexpr inline auto maxSizeY  = 203;
        } // namespace pauseIcon

        namespace ringIcon
        {
            constexpr inline auto image     = "big_bell_ringing";
            constexpr inline auto marginTop = 39;
            constexpr inline auto maxSizeX  = 210;
            constexpr inline auto maxSizeY  = 203;
        } // namespace ringIcon

        namespace clock
        {
            constexpr inline auto marginTop = 17;
            constexpr inline auto maxSizeX  = 340;
            constexpr inline auto maxSizeY  = 84;
        } // namespace clock
    }     // namespace pnStyle

    namespace progress
    {
        inline constexpr auto bottomDescTopMargin = 20U;

M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.cpp +13 -7
@@ 10,9 10,9 @@
#include <db/SystemSettings.hpp>
#include <service-db/Settings.hpp>
#include <Timers/TimerFactory.hpp>
#include <Utils.hpp>
#include <common/windows/BellFinishedWindow.hpp>
#include <common/windows/SessionPausedWindow.hpp>

#include <Utils.hpp>
#include <gsl/assert>

namespace


@@ 42,7 42,10 @@ namespace app::powernap
    void PowerNapProgressPresenter::setTimer(std::unique_ptr<app::TimerWithCallbacks> &&_timer)
    {
        timer = std::move(_timer);
        timer->registerOnFinishedCallback([this]() { onNapFinished(); });
        timer->registerOnFinishedCallback([this]() {
            getView()->progressFinished();
            onNapFinished();
        });
    }

    void PowerNapProgressPresenter::activate()


@@ 66,15 69,13 @@ namespace app::powernap
    void PowerNapProgressPresenter::pause()
    {
        timer->stop();
        app->switchWindow(gui::window::session_paused::sessionPaused);
        getView()->pause();
    }

    void PowerNapProgressPresenter::resume()
    {
        if (napFinished) {
            return;
        }
        timer->start();
        getView()->resume();
    }

    void PowerNapProgressPresenter::onNapFinished()


@@ 119,4 120,9 @@ namespace app::powernap
        getView()->setTimeFormat(timeModel->getTimeFormat());
    }

    bool PowerNapProgressPresenter::isTimerStopped()
    {
        return timer->isStopped();
    }

} // namespace app::powernap

M products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp => products/BellHybrid/apps/application-bell-powernap/presenter/PowerNapProgressPresenter.hpp +16 -9
@@ 45,6 45,9 @@ namespace app::powernap
            virtual void napEnded()                                         = 0;
            virtual void setTime(std::time_t newTime)                       = 0;
            virtual void setTimeFormat(utils::time::Locale::TimeFormat fmt) = 0;
            virtual void progressFinished()                                 = 0;
            virtual void pause()                                            = 0;
            virtual void resume()                                           = 0;
        };

        class Presenter : public BasePresenter<PowerNapProgressContract::View>


@@ 52,6 55,7 @@ namespace app::powernap
          public:
            virtual void activate()                                                 = 0;
            virtual void endNap()                                                   = 0;
            virtual bool isTimerStopped()                                           = 0;
            virtual void pause()                                                    = 0;
            virtual void resume()                                                   = 0;
            virtual void setTimer(std::unique_ptr<app::TimerWithCallbacks> &&timer) = 0;


@@ 74,6 78,17 @@ namespace app::powernap
        sys::TimerHandle napAlarmTimer;
        bool napFinished{false};

        static constexpr auto endWindowTimeout = std::chrono::seconds{5};

      public:
        PowerNapProgressPresenter(app::ApplicationCommon *app,
                                  settings::Settings *settings,
                                  std::unique_ptr<AbstractSoundsRepository> soundsRepository,
                                  AbstractAudioModel &audioModel,
                                  app::bell_settings::AbstractFrontlightModel &frontLightModel,
                                  std::unique_ptr<AbstractTimeModel> timeModel,
                                  std::unique_ptr<app::bell_settings::AlarmLightOnOffModel> alarmLightOnOffModel);

        void activate() override;
        void endNap() override;
        void pause() override;


@@ 81,18 96,10 @@ namespace app::powernap
        void setTimer(std::unique_ptr<app::TimerWithCallbacks> &&_timer) override;
        void handleUpdateTimeEvent() override;
        bool isNapFinished() override;
        bool isTimerStopped() override;

        void onNapFinished();
        void onNapAlarmFinished();
        void onBeforeShow() override;

      public:
        PowerNapProgressPresenter(app::ApplicationCommon *app,
                                  settings::Settings *settings,
                                  std::unique_ptr<AbstractSoundsRepository> soundsRepository,
                                  AbstractAudioModel &audioModel,
                                  app::bell_settings::AbstractFrontlightModel &frontLightModel,
                                  std::unique_ptr<AbstractTimeModel> timeModel,
                                  std::unique_ptr<app::bell_settings::AlarmLightOnOffModel> alarmLightOnOffModel);
    };
} // namespace app::powernap

M products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp => products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.cpp +95 -76
@@ 5,52 5,11 @@
#include "application-bell-powernap/ApplicationBellPowerNap.hpp"
#include "data/PowerNapStyle.hpp"
#include "data/PowerNapSwitchData.hpp"
#include <apps-common/widgets/BellBaseLayout.hpp>
#include <apps-common/widgets/BarGraph.hpp>
#include <apps-common/widgets/ProgressTimerWithBarGraphAndCounter.hpp>
#include <apps-common/GuiTimer.hpp>
#include <Text.hpp>
#include <keymap/KeyMap.hpp>

namespace
{
    void decorateProgressItem(gui::Rect *item, gui::Alignment::Vertical alignment)
    {
        item->setEdges(gui::RectangleEdge::None);
        item->activeItem = false;
        item->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, alignment));
    }
    void createTitle(gui::VBox *parent)
    {
        auto title = new gui::Text(parent, 0, 0, parent->getWidth(), parent->getHeight() / 2);
        title->setFont(gui::powerNapStyle::descriptionFont);
        title->setText(utils::translate("app_bellmain_power_nap"));
        decorateProgressItem(title, gui::Alignment::Vertical::Top);
    }
    gui::HBarGraph *createProgress(gui::VBox *parent)
    {
        auto progressBox = new gui::HBox(parent, 0, 0, parent->getWidth(), parent->getHeight() / 2);
        decorateProgressItem(progressBox, gui::Alignment::Vertical::Bottom);
        auto progressBar =
            new gui::HBarGraph(progressBox, 0, 0, gui::powerNapStyle::progress::boxesCount, gui::BarGraphStyle::Heavy);
        decorateProgressItem(progressBar, gui::Alignment::Vertical::Center);
        return progressBar;
    }
    gui::TimeFixedWidget *createTimer(gui::Item *parent)
    {
        using namespace style;
        using namespace gui::powerNapStyle;
        auto timer = new gui::TimeFixedWidget(parent,
                                              0,
                                              0,
                                              bell_base_layout::outer_layouts_w,
                                              bell_base_layout::outer_layouts_h - progress::bottomDescTopMargin);
        timer->setFontAndDimensions(napTimerFont);
        timer->setMargins(gui::Margins(0, progress::bottomDescTopMargin, 0, 0));
        decorateProgressItem(timer, gui::Alignment::Vertical::Top);
        return timer;
    }

    inline constexpr auto powernapTimerName = "PowerNapTimer";
    inline constexpr std::chrono::seconds timerTick{1};
} // namespace


@@ 58,10 17,11 @@ namespace
namespace gui
{
    PowerNapProgressWindow::PowerNapProgressWindow(
        app::ApplicationCommon *app, std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> presenter)
        : AppWindow(app, gui::window::name::powernapProgress), presenter{std::move(presenter)}
        app::ApplicationCommon *app,
        std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> &&windowPresenter)
        : AppWindow(app, gui::window::name::powernapProgress), presenter{std::move(windowPresenter)}
    {
        this->presenter->attach(this);
        presenter->attach(this);
        buildInterface();
    }



@@ 69,50 29,89 @@ namespace gui
    {
        AppWindow::buildInterface();

        statusBar->setVisible(false);
        header->setTitleVisibility(false);
        navBar->setVisible(false);

        buildLayout();
        configureTimer();
        // presenter->activate();
    }

    void PowerNapProgressWindow::buildLayout()
    {
        statusBar->setVisible(false);
        auto body = new gui::BellBaseLayout(this, 0, 0, style::bell_base_layout::w, style::bell_base_layout::h, false);
        auto vBox =
            new VBox(body->getCenterBox(), 0, 0, style::bell_base_layout::w, style::bell_base_layout::center_layout_h);
        decorateProgressItem(vBox, gui::Alignment::Vertical::Top);
        createTitle(vBox);
        progressBar = createProgress(vBox);
        timerText   = createTimer(body->lastBox);

        time = new BellStatusClock(body->firstBox);
        time->setMaximumSize(body->firstBox->getWidth(), body->firstBox->getHeight());
        time->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
        body->firstBox->resizeItems();

        dimensionChangedCallback = [&](Item &, const BoundingBox &newDim) -> bool {
            body->setArea({0, 0, newDim.w, newDim.h});
            return true;
        };
        using namespace gui::powerNapStyle;
        const auto progressArcRadius = pnStyle::progress::radius;
        const auto progressArcWidth  = pnStyle::progress::penWidth;
        const auto arcStartAngle     = -90 - pnStyle::progress::verticalDeviationDegrees;
        const auto arcSweepAngle     = 360 - (2 * pnStyle::progress::verticalDeviationDegrees);
        const auto arcProgressSteps  = 1000;

        Arc::ShapeParams arcParams;
        arcParams.setCenterPoint(Point(getWidth() / 2, getHeight() / 2))
            .setRadius(progressArcRadius)
            .setStartAngle(arcStartAngle) // Start drawing the circle from top.
            .setSweepAngle(arcSweepAngle)
            .setPenWidth(progressArcWidth)
            .setBorderColor(ColorFullBlack);

        progress = new ArcProgressBar(this, arcParams, ArcProgressBar::ProgressDirection::CounterClockwise);
        progress->setMaximum(arcProgressSteps);

        mainVBox = new VBox(this, 0, 0, style::window_width, style::window_height);

        clock = new BellStatusClock(mainVBox);
        clock->setMaximumSize(pnStyle::clock::maxSizeX, pnStyle::clock::maxSizeY);
        clock->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        clock->setMargins(gui::Margins(0, pnStyle::clock::marginTop, 0, 0));

        timer = new gui::TimeFixedWidget(mainVBox, 0, 0, pnStyle::timer::maxSizeX, pnStyle::timer::maxSizeY, true);
        timer->setFontAndDimensions(pnStyle::timer::font);
        timer->setMinimumSize(pnStyle::timer::maxSizeX, pnStyle::timer::maxSizeY);
        timer->setMargins(gui::Margins(0, pnStyle::timer::marginTop, pnStyle::timer::marginRight, 0));
        timer->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

        iconPause = new Icon(mainVBox, 0, 0, 0, 0, {}, {});
        iconPause->setMinimumSize(pnStyle::pauseIcon::maxSizeX, pnStyle::pauseIcon::maxSizeY);
        iconPause->setMargins(gui::Margins(0, pnStyle::pauseIcon::marginTop, 0, 0));
        iconPause->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        iconPause->image->set(pnStyle::pauseIcon::image, ImageTypeSpecifier::W_G);
        iconPause->setVisible(false);

        iconRing = new Icon(mainVBox, 0, 0, 0, 0, {}, {});
        iconRing->setMinimumSize(pnStyle::ringIcon::maxSizeX, pnStyle::ringIcon::maxSizeY);
        iconRing->setMargins(gui::Margins(0, pnStyle::ringIcon::marginTop, 0, 0));
        iconRing->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        iconRing->image->set(pnStyle::ringIcon::image, ImageTypeSpecifier::W_G);
        iconRing->setVisible(false);

        mainVBox->resizeItems();
    }

    void PowerNapProgressWindow::configureTimer()
    {
        auto timer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
        auto progressTimer = std::make_unique<app::ProgressTimerWithBarGraphAndCounter>(
            application, *this, powernapTimerName, timerTick, app::ProgressCountdownMode::Increasing);
        timer->attach(progressBar);
        timer->attach(timerText);
        presenter->setTimer(std::move(timer));
        progressTimer->attach(progress);
        progressTimer->attach(timer);
        presenter->setTimer(std::move(progressTimer));
    }

    auto PowerNapProgressWindow::onInput(const InputEvent &inputEvent) -> bool
    bool PowerNapProgressWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease()) {
            const auto key = mapKey(inputEvent.getKeyCode());
            if (presenter->isNapFinished() && key == KeyMap::LightPress) {
            if (presenter->isNapFinished() &&
                (key == KeyMap::LightPress || key == KeyMap::DeepPressDown || key == KeyMap::DeepPressUp)) {
                presenter->endNap();
                return true;
            }
            else if (not presenter->isNapFinished() && key == KeyMap::LightPress) {
                presenter->pause();
                if (presenter->isTimerStopped()) {
                    presenter->resume();
                }
                else {
                    presenter->pause();
                }
                return true;
            }
            else if (not presenter->isNapFinished() && key == KeyMap::Back) {


@@ 132,13 131,13 @@ namespace gui

    void PowerNapProgressWindow::setTime(std::time_t newTime)
    {
        time->setTime(newTime);
        time->setTimeFormatSpinnerVisibility(true);
        clock->setTime(newTime);
        clock->setTimeFormatSpinnerVisibility(true);
    }

    void PowerNapProgressWindow::setTimeFormat(utils::time::Locale::TimeFormat fmt)
    {
        time->setTimeFormat(fmt);
        clock->setTimeFormat(fmt);
    }

    RefreshModes PowerNapProgressWindow::updateTime()


@@ 149,16 148,36 @@ namespace gui
        return RefreshModes::GUI_REFRESH_FAST;
    }

    void PowerNapProgressWindow::pause()
    {
        timer->setVisible(false);
        iconPause->setVisible(true);
        mainVBox->resizeItems();
    }

    void PowerNapProgressWindow::resume()
    {
        timer->setVisible(true);
        iconPause->setVisible(false);
        mainVBox->resizeItems();
    }

    void PowerNapProgressWindow::progressFinished()
    {
        timer->setVisible(false);
        iconPause->setVisible(false);
        iconRing->setVisible(true);
        mainVBox->resizeItems();
    }

    void PowerNapProgressWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        AppWindow::onBeforeShow(mode, data);
        presenter->onBeforeShow();
        updateTime();

        if (mode == ShowMode::GUI_SHOW_INIT) {
            presenter->activate();
        }
        else {
            presenter->resume();
        }
    }
} // namespace gui

M products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp => products/BellHybrid/apps/application-bell-powernap/windows/PowerNapProgressWindow.hpp +24 -14
@@ 4,37 4,47 @@
#pragma once

#include "presenter/PowerNapProgressPresenter.hpp"
#include <common/widgets/BellStatusClock.hpp>
#include <apps-common/widgets/BarGraph.hpp>
#include <apps-common/widgets/TimeFixedWidget.hpp>
#include <common/widgets/BellStatusClock.hpp>
#include <gui/widgets/Icon.hpp>
#include <AppWindow.hpp>
#include <Application.hpp>
#include <InputEvent.hpp>
#include <Text.hpp>

namespace gui
{
    class HBarGraph;
    class Text;
    class PowerNapProgressWindow : public AppWindow, public app::powernap::PowerNapProgressContract::View
    {
        std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> presenter;
        gui::HBarGraph *progressBar     = nullptr;
        gui::TimeFixedWidget *timerText = nullptr;
        gui::BellStatusClock *time      = nullptr;
      public:
        PowerNapProgressWindow(app::ApplicationCommon *app,
                               std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> &&windowPresenter);

        // virtual methods
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onInput(const InputEvent &inputEvent) override;
        void buildInterface() override;
        auto onInput(const InputEvent &inputEvent) -> bool override;
        void progressFinished() override;
        void pause() override;
        void resume() override;

      private:
        std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> presenter;
        gui::VBox *mainVBox           = nullptr;
        gui::ArcProgressBar *progress = nullptr;
        gui::TimeFixedWidget *timer   = nullptr;
        gui::BellStatusClock *clock   = nullptr;
        gui::Icon *iconPause          = nullptr;
        gui::Icon *iconRing           = nullptr;

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

        void buildLayout();
        void configureTimer();

        void napEnded() override;

        void onBeforeShow(ShowMode mode, SwitchData *data) override;

      public:
        PowerNapProgressWindow(app::ApplicationCommon *app,
                               std::shared_ptr<app::powernap::PowerNapProgressContract::Presenter> presenter);
    };
} // namespace gui

M products/BellHybrid/assets/assets_common.json => products/BellHybrid/assets/assets_common.json +1 -0
@@ 52,6 52,7 @@
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/button_rotate_W_G.vpi", "output": "assets/images/bell/button_rotate_W_G.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/alarm_colon_select_W_M.vpi", "output": "assets/images/bell/alarm_colon_select_W_M.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/bell_arrow_down_W_M.vpi", "output": "assets/images/bell/bell_arrow_down_W_M.vpi"},
        {"name": "release.tgz", "tarfile" :"image/assets/images/bell/big_bell_ringing_W_G.vpi", "output": "assets/images/bell/big_bell_ringing_W_G.vpi"},

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