~aleteoryx/muditaos

07cc59d97869e83b319f930403112d2cbd321248 — Mateusz Piesta 4 years ago 8e64908
[BH-708] Time and units 

Added missing views/windows.
From now home screen properly displays current time.
23 files changed, 388 insertions(+), 57 deletions(-)

M image/assets/lang/English.json
M module-apps/application-bell-main/windows/BellMainWindow.cpp
M module-apps/application-bell-main/windows/BellMainWindow.hpp
M module-apps/application-bell-settings/ApplicationBellSettings.cpp
M module-apps/application-bell-settings/CMakeLists.txt
M module-apps/application-bell-settings/data/BellSettingsStyle.hpp
M module-apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp
M module-apps/application-bell-settings/models/TimeUnitsModel.cpp
M module-apps/application-bell-settings/models/TimeUnitsModel.hpp
A module-apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp
A module-apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp
R module-apps/application-bell-settings/widgets/{TimeSetSpinnerListItem => TimeSetListItem}.cpp
R module-apps/application-bell-settings/widgets/{TimeSetSpinnerListItem => TimeSetListItem}.hpp
A module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.cpp
A module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.hpp
M module-apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp
M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp
M module-gui/gui/widgets/SideListView.cpp
M module-gui/gui/widgets/SideListView.hpp
M module-gui/gui/widgets/Spinner.cpp
M module-gui/gui/widgets/Spinner.hpp
M module-gui/gui/widgets/Style.hpp
M module-gui/gui/widgets/TextSpinner.hpp
M image/assets/lang/English.json => image/assets/lang/English.json +3 -0
@@ 552,7 552,10 @@
  "tethering_phone_mode_change_prohibited": "<text>Tethering is on.<br /><br />Other modes (Connected, DND,<br />Offline) are overriden by this mode<br />and are not working.</text>",
  "tethering_menu_access_decline": "<text>Tethering is on.<br /><br />To access menu,<br />turn tethering off.</text>",

  "app_bell_settings_time_units_time_fmt_top_message": "Time format",
  "app_bell_settings_time_units_time_fmt_bottom_message": "hours",
  "app_bell_settings_time_units_time_message": "Time",
  "app_bell_settings_time_units_finished_message": "Time and units are set.",
  "app_bellmain_next_alarm": "Next alarm",
  "app_bellmain_power_nap": "Power nap",
  "app_bellmain_meditation_timer": "Meditation timer",

M module-apps/application-bell-main/windows/BellMainWindow.cpp => module-apps/application-bell-main/windows/BellMainWindow.cpp +20 -10
@@ 2,21 2,30 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellMainWindow.hpp"

#include <application-bell-main/ApplicationBellMain.hpp>
#include <data/BellMainStyle.hpp>
#include <gui/input/InputEvent.hpp>
#include <i18n/i18n.hpp>
#include <log/log.hpp>
#include <time/time_conversion.hpp>
#include <service-time/api/TimeSettingsApi.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>
#include <widgets/TimeSetSpinner.hpp>

static constexpr uint32_t mockHour   = 10;
static constexpr uint32_t mockMinute = 15;
namespace
{
    constexpr uint32_t mockHour   = 10;
    constexpr uint32_t mockMinute = 15;
} // namespace

namespace gui
{
    BellMainWindow::BellMainWindow(app::Application *app) : AppWindow(app, gui::name::window::main_window)
    {
        buildInterface();

        preBuildDrawListHook = [this](std::list<Command> &cmd) { updateTime(); };
    }

    void BellMainWindow::buildInterface()


@@ 47,11 56,10 @@ namespace gui
        vBox->addWidget(alarmSetSpinner);

        namespace timeLabel = bellMainStyle::mainWindow::timeLabel;
        time = new gui::Label(this, timeLabel::posX, timeLabel::posY, timeLabel::width, timeLabel::height);
        time->setFilled(false);
        time->setBorderColor(gui::ColorNoColor);
        time->setFont(timeLabel::font);
        time                = new TimeSetFmtSpinner(
            this, timeLabel::posX, timeLabel::posY, timeLabel::width, timeLabel::height, stm::api::timeFormat());
        time->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        time->setEditMode(EditMode::Browse);

        namespace temperatureLabel = bellMainStyle::mainWindow::temperatureLabel;
        temperature                = new gui::Label(


@@ 90,7 98,7 @@ namespace gui
    {
        if (alarmEditMode) {
            auto ret = AppWindow::onInput(inputEvent);
            if (ret == false) {
            if (not ret) {
                // alarm setting finished
                alarmEditMode = false;
                setFocusItem(nullptr);


@@ 120,8 128,10 @@ namespace gui
    bool BellMainWindow::updateTime()
    {
        if (time != nullptr) {
            utils::time::Timestamp timestamp{std::time(nullptr)};
            time->setText(timestamp.str("%H:%M"));
            const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
            time->setHour(std::localtime(&now)->tm_hour);
            time->setMinute(std::localtime(&now)->tm_min);
            time->setTimeFormat(stm::api::timeFormat());
            return true;
        }


M module-apps/application-bell-main/windows/BellMainWindow.hpp => module-apps/application-bell-main/windows/BellMainWindow.hpp +13 -12
@@ 3,15 3,16 @@

#pragma once

#include <data/BellAlarmData.hpp>
#include <AppWindow.hpp>
#include <gui/widgets/Spinner.hpp>
#include <widgets/TimeSetSpinner.hpp>
#include <widgets/AlarmSetSpinner.hpp>
#include <BoxLayout.hpp>
#include "data/BellAlarmData.hpp"

#include <apps-common/windows/AppWindow.hpp>

namespace gui
{
    class Label;
    class AlarmSetSpinner;
    class TimeSetFmtSpinner;

    class BellMainWindow : public AppWindow
    {
      public:


@@ 21,14 22,14 @@ namespace gui
        bool onInput(const InputEvent &inputEvent) override;
        bool updateTime() override;

        gui::Label *time        = nullptr;
        gui::Label *temperature = nullptr;
        AlarmSetSpinner *alarmSetSpinner = nullptr;

      private:
        auto handleEnterKey(const InputEvent &inputEvent) -> bool;
        auto handleEditModeEntry() -> void;
        bool alarmEditMode            = false;
        BellAlarm::Status alarmStatus = BellAlarm::Status::DEACTIVATED;

        TimeSetFmtSpinner *time          = nullptr;
        gui::Label *temperature          = nullptr;
        AlarmSetSpinner *alarmSetSpinner = nullptr;
        bool alarmEditMode               = false;
        BellAlarm::Status alarmStatus    = BellAlarm::Status::DEACTIVATED;
    };
} // namespace gui

M module-apps/application-bell-settings/ApplicationBellSettings.cpp => module-apps/application-bell-settings/ApplicationBellSettings.cpp +5 -0
@@ 4,6 4,7 @@
#include "ApplicationBellSettings.hpp"
#include "TimeUnitsPresenter.hpp"
#include "windows/BellSettingsAdvancedWindow.hpp"
#include "windows/BellSettingsFinishedWindow.hpp"
#include "windows/BellSettingsTimeUnitsWindow.hpp"
#include "windows/BellSettingsWindow.hpp"



@@ 44,6 45,10 @@ namespace app
            auto presenter         = std::make_unique<bell_settings::TimeUnitsWindowPresenter>(timeUnitsProvider);
            return std::make_unique<gui::BellSettingsTimeUnitsWindow>(app, std::move(presenter));
        });

        windowsFactory.attach(gui::window::name::bellSettingsFinished, [](Application *app, const std::string &name) {
            return std::make_unique<gui::BellSettingsFinishedWindow>(app);
        });
    }

    sys::MessagePointer ApplicationBellSettings::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M module-apps/application-bell-settings/CMakeLists.txt => module-apps/application-bell-settings/CMakeLists.txt +8 -2
@@ 23,18 23,24 @@ target_sources(application-bell-settings
        ApplicationBellSettings.cpp
        models/TimeUnitsModel.cpp
        presenter/TimeUnitsPresenter.cpp
        widgets/TimeSetSpinnerListItem.cpp
        widgets/TimeSetListItem.cpp
        widgets/TimeFormatSetListItem.cpp
        windows/BellSettingsWindow.cpp
        windows/BellSettingsAdvancedWindow.cpp
        windows/BellSettingsTimeUnitsWindow.cpp
        windows/BellSettingsFinishedWindow.cpp

        models/TimeUnitsModel.hpp
        presenter/TimeUnitsPresenter.hpp
        widgets/TimeSetSpinnerListItem.hpp
        widgets/TimeSetListItem.hpp
        widgets/TimeFormatSetListItem.hpp
        windows/BellSettingsWindow.hpp
        windows/BellSettingsAdvancedWindow.hpp
        windows/BellSettingsTimeUnitsWindow.hpp

    PRIVATE
        windows/BellSettingsFinishedWindow.hpp

    PUBLIC
        include/application-bell-settings/ApplicationBellSettings.hpp
)

M module-apps/application-bell-settings/data/BellSettingsStyle.hpp => module-apps/application-bell-settings/data/BellSettingsStyle.hpp +7 -0
@@ 22,5 22,12 @@ namespace gui
            inline constexpr auto w = 450;
            inline constexpr auto h = 250;
        } // namespace time_set_spinner_list_item

        namespace time_fmt_set_list_item
        {
            inline constexpr auto w    = 129;
            inline constexpr auto h    = 130;
            inline constexpr auto font = style::window::font::supersizemelight;
        } // namespace time_fmt_set_list_item
    }     // namespace bell_settings_style
} // namespace gui

M module-apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp => module-apps/application-bell-settings/include/application-bell-settings/ApplicationBellSettings.hpp +1 -0
@@ 11,6 11,7 @@ namespace gui::window::name
    inline constexpr auto bellSettingsAdvanced  = "BellSettingsAdvanced";
    inline constexpr auto bellSettingsTimeUnits = "BellSettingsTimeUnits";
    inline constexpr auto bellSettingsDialog    = "BellSettingsDialog";
    inline constexpr auto bellSettingsFinished  = "BellSettingsFinished";

} // namespace gui::window::name


M module-apps/application-bell-settings/models/TimeUnitsModel.cpp => module-apps/application-bell-settings/models/TimeUnitsModel.cpp +43 -12
@@ 2,13 2,16 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimeUnitsModel.hpp"
#include "TimeFormatSetListItem.hpp"
#include "TimeSetListItem.hpp"

#include <apps-common/widgets/TimeSetFmtSpinner.hpp>
#include <gui/widgets/ListViewEngine.hpp>
#include <gui/widgets/Style.hpp>
#include <gui/widgets/Text.hpp>
#include <service-time/Constants.hpp>
#include <service-time/api/TimeSettingsApi.hpp>
#include <service-time/service-time/TimeMessage.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>

#include <ctime>



@@ 39,9 42,23 @@ namespace app::bell_settings

    void TimeUnitsModel::createData()
    {
        timeSetWidget = new gui::TimeSetSpinnerListItem(
            0U, 0U, 0, 0, utils::translate("app_bell_settings_time_units_time_message"));
        internalData.push_back(timeSetWidget);

        timeFmtSetListItem =
            new gui::TimeFormatSetListItem(0,
                                           0,
                                           0,
                                           0,
                                           utils::translate("app_bell_settings_time_units_time_fmt_top_message"),
                                           utils::translate("app_bell_settings_time_units_time_fmt_bottom_message"));
        internalData.push_back(timeFmtSetListItem);

        timeSetListItem =
            new gui::TimeSetListItem(0U, 0U, 0, 0, utils::translate("app_bell_settings_time_units_time_message"));
        internalData.push_back(timeSetListItem);

        timeFmtSetListItem->onNextCallback = [this](gui::Item &) {
            timeSetListItem->timeSetFmtSpinner->setTimeFormat(timeFmtSetListItem->getTimeFmt());
        };

        for (auto item : internalData) {
            item->deleteByList = false;


@@ 55,19 72,28 @@ namespace app::bell_settings

    void TimeUnitsModel::saveData()
    {
        std::time_t now         = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        struct std::tm *newTime = std::localtime(&now);
        newTime->tm_hour        = timeSetWidget->timeSetFmtSpinner->getHour();
        newTime->tm_min         = timeSetWidget->timeSetFmtSpinner->getMinute();
        LOG_INFO("Setting new time: %d:%d", newTime->tm_hour, newTime->tm_min);
        const auto now     = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        const auto newTime = std::localtime(&now);
        newTime->tm_hour   = timeSetListItem->timeSetFmtSpinner->getHour();
        newTime->tm_min    = timeSetListItem->timeSetFmtSpinner->getMinute();
        const auto newFmt  = timeFmtSetListItem->getTimeFmt();
        LOG_INFO("Setting new time: %d:%d fmt: %s",
                 newTime->tm_hour,
                 newTime->tm_min,
                 utils::time::Locale::format(newFmt).c_str());
        sendRtcUpdateTimeMessage(std::mktime(newTime));
        sendTimeFmtUpdateMessage(newFmt);
    }

    void TimeUnitsModel::loadData()
    {
        std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        timeSetWidget->timeSetFmtSpinner->setHour(std::localtime(&now)->tm_hour);
        timeSetWidget->timeSetFmtSpinner->setMinute(std::localtime(&now)->tm_min);
        const auto now        = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
        const auto time       = std::localtime(&now);
        const auto timeFormat = stm::api::timeFormat();
        timeSetListItem->timeSetFmtSpinner->setHour(time->tm_hour);
        timeSetListItem->timeSetFmtSpinner->setMinute(time->tm_min);
        timeSetListItem->timeSetFmtSpinner->setTimeFormat(timeFormat);
        timeFmtSetListItem->setTimeFmt(timeFormat);
    }

    auto TimeUnitsModel::requestRecords(uint32_t offset, uint32_t limit) -> void


@@ 81,5 107,10 @@ namespace app::bell_settings
        auto msg = std::make_shared<stm::message::TimeChangeRequestMessage>(newTime);
        application->bus.sendUnicast(std::move(msg), service::name::service_time);
    }
    void TimeUnitsModel::sendTimeFmtUpdateMessage(utils::time::Locale::TimeFormat newFmt)
    {
        auto msg = std::make_shared<stm::message::SetTimeFormatRequest>(newFmt);
        application->bus.sendUnicast(std::move(msg), service::name::service_time);
    }

} // namespace app::bell_settings

M module-apps/application-bell-settings/models/TimeUnitsModel.hpp => module-apps/application-bell-settings/models/TimeUnitsModel.hpp +11 -4
@@ 3,10 3,15 @@

#pragma once

#include "TimeSetSpinnerListItem.hpp"

#include <apps-common/Application.hpp>
#include <apps-common/InternalModel.hpp>
#include <time/time_locale.hpp>

namespace gui
{
    class TimeSetListItem;
    class TimeFormatSetListItem;
} // namespace gui

namespace app::bell_settings
{


@@ 27,9 32,11 @@ namespace app::bell_settings
        [[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;

      private:
        app::Application *application              = nullptr;
        gui::TimeSetSpinnerListItem *timeSetWidget = nullptr;
        app::Application *application                  = nullptr;
        gui::TimeSetListItem *timeSetListItem          = nullptr;
        gui::TimeFormatSetListItem *timeFmtSetListItem = nullptr;

        void sendRtcUpdateTimeMessage(time_t newTime);
        void sendTimeFmtUpdateMessage(utils::time::Locale::TimeFormat newFmt);
    };
} // namespace app::bell_settings

A module-apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp => module-apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp +101 -0
@@ 0,0 1,101 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimeFormatSetListItem.hpp"
#include "BellSettingsStyle.hpp"

#include <gui/core/FontManager.hpp>
#include <gui/core/RawFont.hpp>
#include <gui/widgets/Label.hpp>
#include <gui/widgets/Spinner.hpp>

#include <widgets/TimeSetFmtSpinner.hpp>

namespace
{
    constexpr auto fmtSpinnerMin  = 12U;
    constexpr auto fmtSpinnerMax  = 24U;
    constexpr auto fmtSpinnerStep = 12U;

    uint16_t getFontHeight()
    {
        const gui::RawFont *font = gui::FontManager::getInstance().getFont(style::window::font::supersizemelight);
        return font->info.line_height;
    }
} // namespace

namespace gui
{

    TimeFormatSetListItem::TimeFormatSetListItem(
        Length x, Length y, Length w, Length h, const UTF8 &topDesc, const UTF8 &botDesc)
        : SideListItem(topDesc)
    {
        setMinimumSize(style::sidelistview::list_item::w, style::sidelistview::list_item::h);
        setEdges(RectangleEdge::None);
        setFocusItem(body);

        timeFormat = new Spinner(fmtSpinnerMin, fmtSpinnerMax, fmtSpinnerStep, Boundaries::Continuous);
        timeFormat->setMinimumSize(bell_settings_style::time_fmt_set_list_item::w, getFontHeight());
        timeFormat->setFont(bell_settings_style::time_fmt_set_list_item::font);

        timeFormat->setMargins(calculateMargins());
        timeFormat->setAlignment(Alignment(Alignment::Horizontal::Center));
        timeFormat->setFixedFieldWidth(2);
        timeFormat->setEdges(RectangleEdge::None);
        timeFormat->setCurrentValue(fmtSpinnerMin);
        timeFormat->setFocusEdges(RectangleEdge::None);
        body->addWidget(timeFormat);

        bottomDescription = new Label(body);
        bottomDescription->setMinimumSize(style::sidelistview::top_message::w, style::sidelistview::top_message::h);
        bottomDescription->setFont(style::sidelistview::top_message::font);
        bottomDescription->setEdges(RectangleEdge::None);
        bottomDescription->activeItem = false;
        bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center));
        bottomDescription->setText(botDesc);

        dimensionChangedCallback = [&](Item &, const BoundingBox &newDim) -> bool {
            body->setArea({0, 0, newDim.w, newDim.h});
            return true;
        };

        focusChangedCallback = [&](Item &) {
            setFocusItem(focus ? body : nullptr);
            if (focus) {
                setFocusItem(body);
            }
            else {
                setFocusItem(nullptr);
                if (onNextCallback) {
                    onNextCallback(*this);
                }
            }
            return true;
        };

        inputCallback = [&](Item &, const InputEvent &inputEvent) -> bool { return body->onInput(inputEvent); };
    }
    auto TimeFormatSetListItem::getTimeFmt() const noexcept -> utils::time::Locale::TimeFormat
    {
        return timeFormat->getCurrentValue() == fmtSpinnerMin ? utils::time::Locale::TimeFormat::FormatTime12H
                                                              : utils::time::Locale::TimeFormat::FormatTime24H;
    }
    Margins TimeFormatSetListItem::calculateMargins() const noexcept
    {
        constexpr Position availableHeight =
            style::sidelistview::list_item::h -
            (bell_settings_style::time_fmt_set_list_item::h + (2 * style::sidelistview::top_message::h));
        return Margins{0, availableHeight / 2, 0, availableHeight / 4};
    }
    auto TimeFormatSetListItem::setTimeFmt(utils::time::Locale::TimeFormat fmt) noexcept -> void
    {
        using namespace utils::time;
        if (fmt == Locale::TimeFormat::FormatTime12H) {
            timeFormat->setCurrentValue(fmtSpinnerMin);
        }
        else if (fmt == Locale::TimeFormat::FormatTime24H) {
            timeFormat->setCurrentValue(fmtSpinnerMax);
        }
    }
} // namespace gui
\ No newline at end of file

A module-apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp => module-apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp +38 -0
@@ 0,0 1,38 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <time/time_locale.hpp>
#include <utf8/UTF8.hpp>
#include <widgets/SideListItem.hpp>

#include <functional>

namespace gui
{
    class Spinner;
    class Label;

    class TimeFormatSetListItem : public gui::SideListItem
    {
      public:
        TimeFormatSetListItem() = delete;
        TimeFormatSetListItem(
            gui::Length x, gui::Length y, gui::Length w, gui::Length h, const UTF8 &topDesc, const UTF8 &botDesc);

        auto getTimeFmt() const noexcept -> utils::time::Locale::TimeFormat;
        auto setTimeFmt(utils::time::Locale::TimeFormat fmt) noexcept -> void;

        /// called before next SideListItem is activated
        /// @param `this` : item
        std::function<void(Item &)> onNextCallback;

      private:
        Margins calculateMargins() const noexcept;

        Label *bottomDescription{};
        Spinner *timeFormat{};
    };

} // namespace gui

R module-apps/application-bell-settings/widgets/TimeSetSpinnerListItem.cpp => module-apps/application-bell-settings/widgets/TimeSetListItem.cpp +14 -4
@@ 1,22 1,24 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimeSetListItem.hpp"
#include "BellSettingsStyle.hpp"
#include "TimeSetSpinnerListItem.hpp"

#include <gui/input/InputEvent.hpp>
#include <widgets/TimeSetFmtSpinner.hpp>

namespace gui
{
    TimeSetSpinnerListItem::TimeSetSpinnerListItem(
    TimeSetListItem::TimeSetListItem(
        gui::Length x, gui::Length y, gui::Length w, gui::Length h, std::string description)
        : SideListItem(std::move(description))
    {
        setMinimumSize(style::sidelistview::list_item::w, style::sidelistview::list_item::h);
        timeSetFmtSpinner = new TimeSetFmtSpinner(body);
        timeSetFmtSpinner->setMinimumSize(gui::bell_settings_style::time_set_spinner_list_item::w,
                                          gui::bell_settings_style::time_set_spinner_list_item::h);
        timeSetFmtSpinner->setMinimumSize(bell_settings_style::time_set_spinner_list_item::w,
                                          bell_settings_style::time_set_spinner_list_item::h);

        timeSetFmtSpinner->setMargins(calculateMargins());
        setFocusItem(body);

        dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {


@@ 31,4 33,12 @@ namespace gui

        inputCallback = [&](Item &, const InputEvent &inputEvent) -> bool { return body->onInput(inputEvent); };
    }
    Margins TimeSetListItem::calculateMargins() const noexcept
    {
        constexpr auto ratio = 4;
        constexpr Position availableHeight =
            style::sidelistview::list_item::h -
            (bell_settings_style::time_fmt_set_list_item::h + style::sidelistview::top_message::h);
        return Margins{0, availableHeight / ratio, 0, 0};
    }
} /* namespace gui */

R module-apps/application-bell-settings/widgets/TimeSetSpinnerListItem.hpp => module-apps/application-bell-settings/widgets/TimeSetListItem.hpp +5 -2
@@ 11,11 11,14 @@ namespace gui
{
    class TimeSetFmtSpinner;

    class TimeSetSpinnerListItem : public SideListItem
    class TimeSetListItem : public SideListItem
    {
      public:
        TimeSetFmtSpinner *timeSetFmtSpinner = nullptr;

        TimeSetSpinnerListItem(gui::Length x, gui::Length y, gui::Length w, gui::Length h, std::string description);
        TimeSetListItem(gui::Length x, gui::Length y, gui::Length w, gui::Length h, std::string description);

      private:
        Margins calculateMargins() const noexcept;
    };
} /* namespace gui */

A module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.cpp => module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.cpp +61 -0
@@ 0,0 1,61 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellSettingsFinishedWindow.hpp"

#include <gui/input/InputEvent.hpp>
#include <gui/widgets/Icon.hpp>

namespace
{
    constexpr auto appNameToReturn = gui::window::name::bellSettingsAdvanced;
}

namespace gui
{

    BellSettingsFinishedWindow::BellSettingsFinishedWindow(app::Application *app, const std::string &name)
        : WindowWithTimer(app, name)
    {
        buildInterface();

        timerCallback = [this](Item &, sys::Timer &) {
            application->switchWindow(appNameToReturn);
            return true;
        };
    }
    void BellSettingsFinishedWindow::buildInterface()
    {
        WindowWithTimer::buildInterface();

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

        icon = new Icon(this,
                        0,
                        0,
                        style::window_width,
                        style::window_height,
                        "circle_success",
                        utils::translate("app_bell_settings_time_units_finished_message"));
    }
    bool BellSettingsFinishedWindow::onInput(const InputEvent &inputEvent)
    {
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER) || inputEvent.isShortRelease(KeyCode::KEY_RF)) {
            application->switchWindow(appNameToReturn);
            return true;
        }
        if (AppWindow::onInput(inputEvent)) {
            return true;
        }

        return AppWindow::onInput(inputEvent);
    }
    void BellSettingsFinishedWindow::rebuild()
    {
        erase();
        buildInterface();
    }

} // namespace gui

A module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.hpp => module-apps/application-bell-settings/windows/BellSettingsFinishedWindow.hpp +27 -0
@@ 0,0 1,27 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "application-bell-settings/ApplicationBellSettings.hpp"

#include <apps-common/popups/WindowWithTimer.hpp>

namespace gui
{
    class Icon;

    class BellSettingsFinishedWindow : public WindowWithTimer
    {
      public:
        BellSettingsFinishedWindow(app::Application *app, const std::string &name = window::name::bellSettingsFinished);

      private:
        void buildInterface() override;
        bool onInput(const InputEvent &inputEvent) override;
        void rebuild() override;

        Icon *icon{};
    };

} // namespace gui

M module-apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp => module-apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp +2 -1
@@ 38,6 38,7 @@ namespace gui
        sidelistview =
            new SideListView(this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider());
        sidelistview->setEdges(RectangleEdge::None);
        sidelistview->setPageBarVisible(false);

        sidelistview->rebuildList(listview::RebuildType::Full);



@@ 53,7 54,7 @@ namespace gui
        }
        if (inputEvent.isShortRelease(KeyCode::KEY_ENTER)) {
            presenter->saveData();
            application->returnToPreviousWindow();
            application->switchWindow(window::name::bellSettingsFinished);
            return true;
        }
        if (AppWindow::onInput(inputEvent)) {

M module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp => module-apps/apps-common/widgets/TimeSetFmtSpinner.cpp +9 -3
@@ 2,7 2,6 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TimeSetFmtSpinner.hpp"

#include "TimeSetSpinner.hpp"

#include <date/date.h>


@@ 47,7 46,13 @@ namespace gui
        fmt->setEdges(RectangleEdge::Bottom);

        focusChangedCallback = [&](Item &) {
            setFocusItem(focus ? timeSetSpinner : nullptr);
            if (focus && editMode != EditMode::Browse) {
                setFocusItem(timeSetSpinner);
            }
            else {
                setFocusItem(nullptr);
            }
            setTimeFormat(this->timeFormat);
            return true;
        };



@@ 173,7 178,8 @@ namespace gui
    }
    auto TimeSetFmtSpinner::handleEnterKey() -> bool
    {
        if (focusItem == timeSetSpinner) {
        using namespace utils::time;
        if ((focusItem == timeSetSpinner) && (timeFormat == Locale::TimeFormat::FormatTime12H)) {
            setFocusItem(fmt);
            return true;
        }

M module-gui/gui/widgets/SideListView.cpp => module-gui/gui/widgets/SideListView.cpp +4 -0
@@ 138,4 138,8 @@ namespace gui
        }
        return false;
    }
    auto SideListView::setPageBarVisible(bool value) noexcept -> void
    {
        pageBar->setVisible(value);
    }
} /* namespace gui */

M module-gui/gui/widgets/SideListView.hpp => module-gui/gui/widgets/SideListView.hpp +2 -0
@@ 30,6 30,8 @@ namespace gui
                     unsigned int h,
                     std::shared_ptr<ListItemProvider> prov);

        auto setPageBarVisible(bool value) noexcept -> void;

        auto onInput(const InputEvent &inputEvent) -> bool override;
    };
} /* namespace gui */

M module-gui/gui/widgets/Spinner.cpp => module-gui/gui/widgets/Spinner.cpp +6 -1
@@ 87,12 87,13 @@ namespace gui
    bool Spinner::onFocus(bool state)
    {
        if (focus) {
            setEdges(RectangleEdge::Bottom);
            setEdges(focusEdges);
        }
        else {
            setEdges(RectangleEdge::None);
        }
        showCursor(state);
        updateSpinner();
        return true;
    }



@@ 113,5 114,9 @@ namespace gui
    {
        maxValue = newMaxValue;
    }
    void Spinner::setFocusEdges(RectangleEdge edges)
    {
        focusEdges = edges;
    }

} // namespace gui

M module-gui/gui/widgets/Spinner.hpp => module-gui/gui/widgets/Spinner.hpp +5 -3
@@ 17,6 17,7 @@ namespace gui

        void setMinValue(int newMinValue);
        void setMaxValue(int newMaxValue);
        void setFocusEdges(RectangleEdge edges);

        [[nodiscard]] int getCurrentValue() const noexcept;
        [[nodiscard]] unsigned char getFixedFieldWidth() const noexcept;


@@ 34,9 35,10 @@ namespace gui
        int step;
        int currentValue;
        Boundaries boundaries         = Boundaries::Continuous;
        unsigned char fixedFieldWidth = 0; ///< defins number of chars always displayed,
                                           ///< if curren < fixFieldWidth Label will be filed with 0
                                           ///< value of 0 means no wixed width.
        unsigned char fixedFieldWidth = 0; ///< defines number of chars always displayed,
        ///< if current < fixedFieldWidth Label will be filled with 0
        ///< value of 0 means no fixed width.
        RectangleEdge focusEdges = RectangleEdge::Bottom;
        void updateSpinner();
    };
} // namespace gui

M module-gui/gui/widgets/Style.hpp => module-gui/gui/widgets/Style.hpp +2 -2
@@ 273,8 273,8 @@ namespace style
        namespace top_message
        {
            inline constexpr auto w    = window_width;
            inline constexpr auto h    = 100U;
            inline constexpr auto font = style::window::font::supersizemelight;
            inline constexpr auto h    = 50U;
            inline constexpr auto font = style::window::font::largelight;
        } // namespace top_message
    }     // namespace sidelistview


M module-gui/gui/widgets/TextSpinner.hpp => module-gui/gui/widgets/TextSpinner.hpp +1 -1
@@ 13,7 13,7 @@ namespace gui
    class TextSpinner : public Text
    {
      public:
        using TextRange = std::vector<std::string>;
        using TextRange = std::vector<UTF8>;
        using Position  = std::uint32_t;
        using Range     = std::pair<Position, Position>;