~aleteoryx/muditaos

4f8f315ce89f94fde101ed5b4a32e623af3f0e24 — tomaszrogala 5 years ago f11bc1f
[EGD-3823] Create Popup windows (#946)

-Create bargraph widget
-Create Home modes window
-Create Volume window
-Create Brightness window
-PR changes
M image/assets/lang/lang_en.json => image/assets/lang/lang_en.json +6 -0
@@ 74,6 74,12 @@
    "duration_0hmin_0sec" : "%0N:%0S",
    "duration_hour_0min_0sec" : "%H:%0M:%0S",

    "brightness_text" : "BRIGHTNESS",
    "volume_text" : "VOLUME",
    "home_modes_connected" : "CONNECTED",
    "home_modes_notdisturb" : "DO NOT DISTURB",
    "home_modes_offline" : "OFFLINE",

    "app_calendar_title_main" : "Calendar",
    "app_calendar_options_title": "Options",
    "app_calendar_options_edit": "Edit",

M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +21 -15
@@ 11,21 11,27 @@ else()
    message(FATAL_ERROR "Invalid target!")
endif()

set(SOURCES
        "Application.cpp"
        "GuiTimer.cpp"
        "UiCommonActions.cpp"
        "WindowsFactory.cpp"
        "windows/AppWindow.cpp"
        "windows/OptionWindow.cpp"
        "windows/Options.cpp"
        "windows/OptionsWindowOption.cpp"
        "windows/Dialog.cpp"
        "windows/NoEvents.cpp"
        "windows/OptionSetting.cpp"
        "widgets/ButtonOnOff.cpp"
        "widgets/InputBox.cpp"
        )
set( SOURCES 
    "Application.cpp"
    "GuiTimer.cpp"
    "UiCommonActions.cpp"
    "WindowsFactory.cpp"
    "windows/AppWindow.cpp" 
    "windows/OptionWindow.cpp"
    "windows/Options.cpp" 
    "windows/OptionsWindowOption.cpp"
    "windows/Dialog.cpp"
    "windows/NoEvents.cpp"
    "windows/OptionSetting.cpp"
    "widgets/ButtonOnOff.cpp"
    "widgets/InputBox.cpp"
    "windows/VolumeWindow.cpp"
    "windows/BrightnessWindow.cpp"
    "windows/HomeModesWindow.cpp"
    "widgets/BrightnessBox.cpp"
    "widgets/ModesBox.cpp"
    "widgets/BarGraph.cpp"
    )

add_library(${PROJECT_NAME} STATIC ${SOURCES} ${BOARD_SOURCES})


M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +2 -2
@@ 167,8 167,8 @@ namespace app
        }
        gui::DialogMetadata meta;
        meta.text   = utils::localize.get("app_calendar_no_events_information");
        meta.title = title;
        meta.icon  = "phonebook_empty_grey_circle_W_G";
        meta.title  = title;
        meta.icon   = "phonebook_empty_grey_circle_W_G";
        meta.action = [=]() -> bool {
            LOG_DEBUG("Switch to new event window");
            std::unique_ptr<EventRecordData> eventData = std::make_unique<EventRecordData>();

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

#include "BarGraph.hpp"

namespace gui
{
    static inline auto rectAxisLenghtFrom(uint32_t numberOfRectangles) -> uint32_t
    {
        return numberOfRectangles * (style::bargraph::spacing + style::bargraph::rect_axis_length_sml) -
               style::bargraph::spacing;
    }

    void BarGraph::setPercentageValue(unsigned int value)
    {
        const auto percent       = static_cast<float>(value) / 100.0f;
        const auto absoluteValue = numberOfRectangles * percent;
        setValue(absoluteValue);
    }

    Rect *BarGraph::createRectangle(uint32_t width, uint32_t height)
    {
        auto rectangle = new Rect(nullptr, 0, 0, width, height);
        rectangle->setFillColor(ColorFullBlack);
        rectangle->setBorderColor(ColorFullBlack);
        rectangle->setFilled(true);
        rectangle->setRadius(style::bargraph::radius);
        rectangle->setPenWidth(style::window::default_border_focus_w);
        return rectangle;
    }

    Rect *BarGraph::createSpace(uint32_t width, uint32_t height)
    {
        auto space = new Rect(nullptr, 0, 0, width, height);
        space->setEdges(RectangleEdge::None);
        return space;
    }

    VBarGraph::VBarGraph(Item *parent, Position x, Position y, uint32_t numberOfRectangles)
        : VBox(parent, x, y, style::bargraph::rect_axis_length_lrg, rectAxisLenghtFrom(numberOfRectangles))
    {
        setRadius(style::bargraph::radius);
        setEdges(RectangleEdge::None);
        setMaximum(numberOfRectangles);
        std::reverse(std::begin(rectangles), std::end(rectangles));
    }

    void VBarGraph::setMaximum(unsigned int value)
    {
        numberOfRectangles = value;
        setSize(rectAxisLenghtFrom(numberOfRectangles), Axis::Y);
        if (currentLevel > numberOfRectangles) {
            currentLevel = numberOfRectangles;
        }
        if (!rectangles.empty()) {
            erase();
            rectangles.clear();
        }
        for (uint32_t i = 0; i < numberOfRectangles; ++i) {
            auto rectangle =
                createRectangle(style::bargraph::rect_axis_length_lrg, style::bargraph::rect_axis_length_sml);
            addWidget(rectangle);
            rectangles.push_back(rectangle);
            addWidget(createSpace(style::bargraph::rect_axis_length_lrg, style::bargraph::spacing));
        }
    }

    void VBarGraph::update(int value)
    {
        if (value > 0) {
            incrementWith(value);
        }
        else if (value < 0) {
            decrementWith((-value));
        }
    }

    void VBarGraph::setValue(unsigned int value)
    {
        if (const auto levels = static_cast<int>(value) - static_cast<int>(currentLevel); levels > 0) {
            incrementWith(levels);
        }
        else if (levels < 0) {
            decrementWith(-levels);
        }
    }

    void VBarGraph::incrementWith(uint32_t levels)
    {
        if ((currentLevel + levels) <= numberOfRectangles) {
            for (uint32_t i = 0; i < levels; ++i) {
                rectangles[currentLevel]->setFillColor(ColorFullBlack);
                rectangles[currentLevel]->setBorderColor(ColorFullBlack);
                ++currentLevel;
            }
        }
        else {
            LOG_ERROR("bargraph incremented out of size");
        }
    }

    void VBarGraph::decrementWith(uint32_t levels)
    {
        if (currentLevel >= levels) {
            for (uint32_t i = levels; i > 0; --i) {
                --currentLevel;
                rectangles[currentLevel]->setFillColor(ColorTray);
                rectangles[currentLevel]->setBorderColor(ColorTray);
            }
        }
        else {
            LOG_ERROR("bargraph incremented out of size");
        }
    }

    HBarGraph::HBarGraph(Item *parent, Position x, Position y, uint32_t numberOfRectangles)
        : HBox(parent, x, y, rectAxisLenghtFrom(numberOfRectangles), style::bargraph::rect_axis_length_lrg)
    {
        setRadius(style::bargraph::radius);
        setEdges(RectangleEdge::None);
        setMaximum(numberOfRectangles);
    }

    void HBarGraph::setMaximum(unsigned int value)
    {
        numberOfRectangles = value;
        setSize(rectAxisLenghtFrom(numberOfRectangles), Axis::X);
        if (currentLevel > numberOfRectangles) {
            currentLevel = numberOfRectangles;
        }
        if (!rectangles.empty()) {
            erase();
            rectangles.clear();
        }
        for (uint32_t i = 0; i < numberOfRectangles; ++i) {
            auto rectangle =
                createRectangle(style::bargraph::rect_axis_length_sml, style::bargraph::rect_axis_length_lrg);
            addWidget(rectangle);
            rectangles.push_back(rectangle);
            addWidget(createSpace(style::bargraph::spacing, style::bargraph::rect_axis_length_lrg));
        }
    }

    void HBarGraph::update(int value)
    {
        if (value > 0) {
            incrementWith(value);
        }
        else if (value < 0) {
            decrementWith(-value);
        }
    }

    void HBarGraph::setValue(unsigned int value)
    {
        if (const auto levels = static_cast<int>(value) - static_cast<int>(currentLevel); levels > 0) {
            incrementWith(levels);
        }
        else if (levels < 0) {
            decrementWith(levels * -1);
        }
    }

    void HBarGraph::incrementWith(uint32_t levels)
    {
        if ((currentLevel + levels) <= numberOfRectangles) {
            for (uint32_t i = 0; i < levels; ++i) {
                rectangles[currentLevel]->setFillColor(ColorFullBlack);
                rectangles[currentLevel]->setBorderColor(ColorFullBlack);
                ++currentLevel;
            }
        }
        else {
            LOG_ERROR("bargraph incremented out of size");
        }
    }

    void HBarGraph::decrementWith(uint32_t levels)
    {
        if (currentLevel >= levels) {
            for (uint32_t i = levels; i > 0; --i) {
                --currentLevel;
                rectangles[currentLevel]->setFillColor(ColorFullWhite);
                rectangles[currentLevel]->setBorderColor(ColorFullBlack);
            }
        }
        else {
            LOG_ERROR("bargraph incremented out of size");
        }
    }

} /* namespace gui */

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

#pragma once

#include <BoxLayout.hpp>
#include <module-gui/gui/widgets/ProgressBar.hpp>

namespace style::bargraph
{
    constexpr inline auto rect_axis_length_sml = 8;
    constexpr inline auto rect_axis_length_lrg = 20;
    constexpr inline auto spacing              = 17;
    constexpr inline auto radius               = 4;
} // namespace style::bargraph

namespace gui
{
    class BarGraph : public Progress
    {
      protected:
        std::vector<gui::Rect *> rectangles;
        uint32_t numberOfRectangles;
        uint32_t currentLevel = 0;

      public:
        Rect *createRectangle(uint32_t width, uint32_t height);

        Rect *createSpace(uint32_t width, uint32_t height);

        void setPercentageValue(unsigned int value) override;
    };

    class VBarGraph : public VBox, public BarGraph
    {
        void incrementWith(uint32_t levels);
        void decrementWith(uint32_t levels);

      public:
        VBarGraph(Item *parent = nullptr, Position x = 0, Position y = 0, uint32_t numberOfRectangles = 0);
        void setMaximum(unsigned int value) final;
        void setValue(unsigned int value) final;
        void update(int value = 1) final;
    };

    class HBarGraph : public HBox, public BarGraph
    {
        void incrementWith(uint32_t levels);
        void decrementWith(uint32_t levels);

      public:
        HBarGraph(Item *parent = nullptr, Position x = 0, Position y = 0, uint32_t numberOfRectangles = 0);
        void setMaximum(unsigned int value) final;
        void setValue(unsigned int value) final;
        void update(int value = 1) final;
    };

} /* namespace gui */

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

#pragma once

#include <BoxLayout.hpp>
#include <Label.hpp>
#include <module-gui/gui/widgets/Image.hpp>

namespace style::window::brightness
{
    const inline auto title_key = "brightness_text";

    namespace bar
    {
        constexpr inline auto brightness_levels = 5;
        constexpr inline auto left_offset       = 160;
        constexpr inline auto top_offset        = 520;
    } // namespace bar

    namespace box
    {
        constexpr inline auto top_offset = 405;
        constexpr inline auto height     = style::window_height - top_offset;
        constexpr inline auto width      = style::window_width;
    } // namespace box

    namespace title
    {
        constexpr inline auto width  = 213;
        constexpr inline auto height = 33;

        constexpr inline auto space_width  = 20;
        constexpr inline auto arrow_width  = 20;
        constexpr inline auto arrow_height = 20;

        constexpr inline auto label_width  = 135;
        constexpr inline auto label_height = 33;
        constexpr inline auto top_offset   = 463;
        constexpr inline auto left_offset  = 134;
    } // namespace title
} // namespace style::window::brightness

namespace gui
{
    class BrightnessBox : public HBox
    {
        void addArrow(const std::string &arrowName, Alignment::Horizontal aligment);

        void addBrightnessTitle(Item *parent, const std::string &text);

      public:
        BrightnessBox(Item *parent = nullptr, uint32_t x = 0, uint32_t y = 0);
    };
} // namespace gui

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

#include <module-utils/i18/i18.hpp>
#include "BightnessBox.hpp"

namespace gui
{
    BrightnessBox::BrightnessBox(Item *parent, uint32_t x, uint32_t y)
        : HBox(parent, x, y, style::window::brightness::title::width, style::window::brightness::title::height)
    {
        setEdges(RectangleEdge::None);
        addArrow("arrow_left", Alignment::Horizontal::Left);
        addBrightnessTitle(this, utils::localize.get(style::window::brightness::title_key));
        addArrow("arrow_right", Alignment::Horizontal::Right);

        resizeItems();
    }

    void BrightnessBox::addArrow(const std::string &arrowName, Alignment::Horizontal aligment)
    {
        auto arrow = new Image(this, 0, 0, 0, 0);
        arrow->setMinimumSize(style::window::brightness::title::arrow_width, style::window::brightness::title::height);
        arrow->setAlignment(Alignment(aligment, Alignment::Vertical::Center));
        arrow->set(arrowName);
    }

    void BrightnessBox::addBrightnessTitle(Item *parent, const std::string &text)
    {
        auto brightnessTitle = new Label(parent, 0, 0, 0, 0);
        brightnessTitle->setMinimumSize(style::window::brightness::title::label_width,
                                        style::window::brightness::title::label_height);

        brightnessTitle->setEdges(gui::RectangleEdge::None);
        brightnessTitle->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        brightnessTitle->activeItem = false;
        brightnessTitle->setText(text);
        brightnessTitle->setFont(style::window::font::medium);
        brightnessTitle->setMargins(Margins(
            style::window::brightness::title::space_width, 0, style::window::brightness::title::space_width, 0));
    }
} // namespace gui

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

#include <module-utils/i18/i18.hpp>
#include "ModesBox.hpp"

namespace gui
{
    ModesBox::ModesBox(Item *parent, uint32_t x, uint32_t y)
        : VBox(parent, x, y, style::window::modes::width, style::window::modes::height)
    {
        setEdges(RectangleEdge::None);
        addConnected();
        addNotDisturb();
        addOffline();
    }

    void ModesBox::addConnected()
    {
        connected = new ModeRow(this, 0, 0, style::window::modes::width, style::window::modes::connected::height);
        connected->addText(utils::localize.get(style::window::modes::connected::title_key),
                           style::window::font::medium,
                           Margins(style::window::modes::connected::margin::left, 0, 0, 0),
                           style::window::modes::connected::width,
                           style::window::modes::connected::height);
        connected->resizeItems();
    }

    void ModesBox::addNotDisturb()
    {
        notDisturb = new ModeRow(this, 0, 0, style::window::modes::width, style::window::modes::notdisturb::height);
        notDisturb->addText(
            utils::localize.get(style::window::modes::notdisturb::title_key),
            style::window::font::largelight,
            Margins(
                style::window::modes::notdisturb::margin::left, 0, style::window::modes::notdisturb::margin::right, 0),
            style::window::modes::notdisturb::width,
            style::window::modes::notdisturb::height);
        notDisturb->addImage("dot_12px_hard_alpha_W_G");
        notDisturb->setMargins(Margins(
            0, style::window::modes::notdisturb::margin::top, 0, style::window::modes::notdisturb::margin::bottom));
        notDisturb->resizeItems();
    }

    void ModesBox::addOffline()
    {
        offline = new ModeRow(this, 0, 0, style::window::modes::width, style::window::modes::offline::height);

        offline->addText(utils::localize.get(style::window::modes::offline::title_key),
                         style::window::font::medium,
                         Margins(style::window::modes::offline::margin::left, 0, 0, 0),
                         style::window::modes::offline::width,
                         style::window::modes::offline::height);
        offline->resizeItems();
    }

    ModeRow::ModeRow(Item *parent, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
        : HBox(parent, x, y, width, height)
    {
        this->setEdges(RectangleEdge::None);
    }

    void ModeRow::addText(
        const std::string &text, const std::string &fontSize, const Margins &margin, uint32_t width, uint32_t height)
    {
        label = new Label(this, 0, 0, width, height);
        label->setMinimumSize(width, height);
        label->setEdges(gui::RectangleEdge::None);
        label->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Center));
        label->activeItem = false;
        label->setText(text);
        label->setFont(fontSize);
        label->setMargins(margin);
    }

    void ModeRow::addImage(const std::string &imageName)
    {
        img = new Image(this, 0, 0, 0, 0);
        img->setMinimumSize(style::window::modes::image::width, style::window::modes::image::height);
        img->setAlignment(Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
        img->set(imageName);
        img->setMargins(Margins(style::window::modes::image::margin::left, 0, 0, 0));
    }
} // namespace gui

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

#pragma once

#include <BoxLayout.hpp>
#include <Label.hpp>
#include <module-gui/gui/widgets/Image.hpp>

namespace style::window::modes
{
    constexpr inline auto invision_diff = 26;

    constexpr inline auto left_offset   = style::window_width / 4;
    constexpr inline auto top_offset    = 182;
    constexpr inline auto bottom_offset = 257;
    constexpr inline auto height        = style::window_height - top_offset - bottom_offset;
    constexpr inline auto width         = style::window_width - left_offset;

    namespace connected
    {
        constexpr inline auto title_key = "home_modes_connected";
        constexpr inline auto width     = 129;
        constexpr inline auto height    = 33;

        namespace margin
        {
            constexpr inline auto left  = 296 - style::window::modes::left_offset + invision_diff;
            constexpr inline auto right = 20;
        } // namespace margin
    }     // namespace connected

    namespace notdisturb
    {
        constexpr inline auto title_key = "home_modes_notdisturb";
        constexpr inline auto width     = 297 + invision_diff;
        constexpr inline auto height    = 51;

        namespace margin
        {
            constexpr inline auto top    = 20;
            constexpr inline auto left   = 128 - style::window::modes::left_offset;
            constexpr inline auto bottom = 20;
            constexpr inline auto right  = 0;
        } // namespace margin
    }     // namespace notdisturb

    namespace offline
    {
        constexpr inline auto title_key = "home_modes_offline";
        constexpr inline auto width     = 88;
        constexpr inline auto height    = 33;

        namespace margin
        {
            constexpr inline auto left  = 337 - style::window::modes::left_offset + invision_diff;
            constexpr inline auto right = 10;
        } // namespace margin
    }     // namespace offline

    namespace image
    {
        namespace margin
        {
            constexpr inline auto left = 7;
        }
        constexpr inline auto width  = 10;
        constexpr inline auto height = 20;
    } // namespace image

} // namespace style::window::modes

namespace gui
{
    class ModeRow : public HBox
    {
        Label *label = nullptr;
        Image *img   = nullptr;

      public:
        ModeRow(Item *parent = nullptr, uint32_t x = 0, uint32_t y = 0, uint32_t width = 0, uint32_t height = 0);

        void addText(const std::string &text,
                     const std::string &fontSize,
                     const Margins &margin,
                     uint32_t width,
                     uint32_t height);

        void addImage(const std::string &imageName);
    };

    class ModesBox : public VBox
    {
        ModeRow *connected  = nullptr;
        ModeRow *notDisturb = nullptr;
        ModeRow *offline    = nullptr;

        void addConnected();

        void addNotDisturb();

        void addOffline();

      public:
        ModesBox(Item *parent = nullptr, uint32_t x = 0, uint32_t y = 0);
    };
} // namespace gui

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

#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/Arc.hpp>
#include "BrightnessWindow.hpp"

namespace gui
{
    BrightnessWindow::BrightnessWindow(app::Application *app, const std::string &name) : AppWindow(app, name)
    {
        buildInterface();
    }

    void BrightnessWindow::addBox()
    {
        border = new Rect(this,
                          0,
                          style::window::brightness::box::top_offset,
                          style::window::brightness::box::width,
                          style::window::brightness::box::height);
        border->setEdges(RectangleEdge::Top);
    }

    void BrightnessWindow::addBrightnessText()
    {
        brightnessText = new BrightnessBox(
            this, style::window::brightness::title::left_offset, style::window::brightness::title::top_offset);
    }

    void BrightnessWindow::addBrightnessBar()
    {
        brightnessBar = new HBarGraph(this,
                                      style::window::brightness::bar::left_offset + 20,
                                      style::window::brightness::bar::top_offset,
                                      style::window::brightness::bar::brightness_levels);
    }

    void BrightnessWindow::buildInterface()
    {
        AppWindow::buildInterface();
        addBox();
        addBrightnessText();
        addBrightnessBar();
    }

    void BrightnessWindow::rebuild()
    {}

    void BrightnessWindow::destroyInterface()
    {
        erase();
    }

    BrightnessWindow::~BrightnessWindow()
    {
        destroyInterface();
    }

    void BrightnessWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {}

    bool BrightnessWindow::onInput(const gui::InputEvent &inputEvent)
    {
        if (!inputEvent.isShortPress()) {
            return false;
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_VOLUP) {
            brightnessBar->update(1);
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_VOLDN) {
            brightnessBar->update(-1);
        }

        return AppWindow::onInput(inputEvent);
    }
} // namespace gui

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

#pragma once

#include "module-apps/Application.hpp"
#include "AppWindow.hpp"
#include "PageLayout.hpp"
#include "module-apps/widgets/BarGraph.hpp"
#include "module-apps/widgets/BightnessBox.hpp"
#include <functional>

namespace gui
{
    class BrightnessWindow : public AppWindow
    {

      protected:
        Rect *border                  = nullptr;
        BrightnessBox *brightnessText = nullptr;
        HBarGraph *brightnessBar      = nullptr;

      public:
        BrightnessWindow(app::Application *app, const std::string &name);

        ~BrightnessWindow() override;

        void addBox();

        void addBrightnessText();

        void addBrightnessBar();

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

        void rebuild() override;

        void buildInterface() override;

        void destroyInterface() override;

        bool onInput(const gui::InputEvent &inputEvent) override;
    };
}; // namespace gui

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

#include <module-gui/gui/input/InputEvent.hpp>
#include <module-gui/gui/widgets/Arc.hpp>
#include "HomeModesWindow.hpp"

namespace gui
{
    HomeModesWindow::HomeModesWindow(app::Application *app, const std::string &name) : AppWindow(app, name)
    {
        buildInterface();
    }

    void HomeModesWindow::buildInterface()
    {
        AppWindow::buildInterface();
        modesBox = new ModesBox(this, style::window::modes::left_offset, style::window::modes::top_offset);
    }

    void HomeModesWindow::rebuild()
    {}

    void HomeModesWindow::destroyInterface()
    {
        erase();
    }

    HomeModesWindow::~HomeModesWindow()
    {
        destroyInterface();
    }

    void HomeModesWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {}
} // namespace gui

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

#pragma once

#include "module-apps/Application.hpp"
#include "AppWindow.hpp"
#include "PageLayout.hpp"
#include "module-apps/widgets/BarGraph.hpp"
#include "module-apps/widgets/ModesBox.hpp"
#include <functional>

namespace gui
{
    class HomeModesWindow : public AppWindow
    {
      protected:
        ModesBox *modesBox = nullptr;

      public:
        HomeModesWindow(app::Application *app, const std::string &name);

        ~HomeModesWindow() override;

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

        void rebuild() override;

        void buildInterface() override;

        void destroyInterface() override;
    };
}; // namespace gui

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

#include <module-gui/gui/input/InputEvent.hpp>
#include <module-utils/i18/i18.hpp>
#include "VolumeWindow.hpp"

namespace gui
{
    VolumeWindow::VolumeWindow(app::Application *app, const std::string &name) : AppWindow(app, name)
    {
        buildInterface();
    }

    void VolumeWindow::addVolumeText()
    {
        volumeText = new Label(this,
                               style::window::default_left_margin,
                               title->offset_h(),
                               style::window::default_body_width,
                               style::window::volume::title_height,
                               utils::localize.get(style::window::volume::title_key));

        volumeText->setPenWidth(style::window::default_border_no_focus_w);
        volumeText->setFont(style::window::font::mediumbold);
        volumeText->setAlignment(gui::Alignment(gui::Alignment::Vertical::Center));
        addWidget(volumeText);
    }

    void VolumeWindow::addVolumeBar()
    {
        volumeBar = new VBarGraph(this,
                                  style::window::default_left_margin,
                                  style::window::volume::bar::top_offset,
                                  style::window::volume::bar::volume_levels);
    }

    void VolumeWindow::buildInterface()
    {
        AppWindow::buildInterface();
        addVolumeText();
        addVolumeBar();
    }

    void VolumeWindow::rebuild()
    {}

    void VolumeWindow::destroyInterface()
    {
        erase();
    }

    VolumeWindow::~VolumeWindow()
    {
        destroyInterface();
    }

    void VolumeWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {}

    bool VolumeWindow::onInput(const gui::InputEvent &inputEvent)
    {
        if (!inputEvent.isShortPress()) {
            return false;
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_VOLUP) {
            volumeBar->update(1);
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_VOLDN) {
            volumeBar->update(-1);
        }

        return AppWindow::onInput(inputEvent);
    }
} // namespace gui

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

#pragma once

#include "module-apps/Application.hpp"
#include "AppWindow.hpp"
#include "PageLayout.hpp"
#include "module-apps/widgets/BarGraph.hpp"
#include <functional>

namespace style::window::volume
{
    constexpr inline auto title_height = 33;
    constexpr inline auto title_key    = "volume_text";

    namespace bar
    {
        constexpr inline auto volume_levels = 10;
        constexpr inline auto top_offset    = 179;
    } // namespace bar

} // namespace style::window::volume
namespace gui
{
    class VolumeWindow : public AppWindow
    {

      protected:
        Label *volumeText    = nullptr;
        VBarGraph *volumeBar = nullptr;

      public:
        VolumeWindow(app::Application *app, const std::string &name);

        ~VolumeWindow() override;

        void addVolumeText();
        void addVolumeBar();
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
        bool onInput(const gui::InputEvent &inputEvent) override;
    };
}; // namespace gui

M module-gui/gui/widgets/BoxLayout.cpp => module-gui/gui/widgets/BoxLayout.cpp +1 -0
@@ 576,6 576,7 @@ namespace gui
    {
        type = ItemType::VBOX;
    }

    VBox::VBox(Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h)
        : BoxLayout(parent, x, y, w, h)
    {

M module-gui/gui/widgets/ProgressBar.cpp => module-gui/gui/widgets/ProgressBar.cpp +12 -2
@@ 40,6 40,11 @@ namespace gui
        currentValue = std::clamp(value, 0U, maxValue);
    }

    void ProgressBar::update(int value) noexcept
    {
        setValue(currentValue + value);
    }

    void ProgressBar::setPercentageValue(unsigned int value) noexcept
    {
        const auto percent       = static_cast<float>(value) / 100.0f;


@@ 89,7 94,7 @@ namespace gui
        progressIndicator = new Circle(this, indicatorParams);
    }

    Point CircularProgressBar::calculateProgressIndicatorCenter() const noexcept
    Point CircularProgressBar::calculateProgressIndicatorCenter() const
    {
        using namespace trigonometry;
        const auto sweepAngleRadians = toRadians(progressArc->getSweepAngle() + progressArc->getStartAngle());


@@ 110,6 115,11 @@ namespace gui
        currentValue = std::clamp(value, 0U, maxValue);
    }

    void CircularProgressBar::update(int value) noexcept
    {
        setValue(currentValue + value);
    }

    void CircularProgressBar::setPercentageValue(unsigned int value) noexcept
    {
        const auto percent       = static_cast<float>(value) / 100.0f;


@@ 117,7 127,7 @@ namespace gui
        setValue(absoluteValue);
    }

    float CircularProgressBar::getPercentageValue() const noexcept
    float CircularProgressBar::getPercentageValue() const
    {
        if (maxValue == 0) {
            return .0f;

M module-gui/gui/widgets/ProgressBar.hpp => module-gui/gui/widgets/ProgressBar.hpp +8 -5
@@ 16,9 16,10 @@ namespace gui
      public:
        virtual ~Progress() noexcept = default;

        virtual void setMaximum(unsigned int value) noexcept         = 0;
        virtual void setValue(unsigned int value) noexcept           = 0;
        virtual void setPercentageValue(unsigned int value) noexcept = 0;
        virtual void setMaximum(unsigned int value)         = 0;
        virtual void setValue(unsigned int value)           = 0;
        virtual void update(int value = 1)                  = 0;
        virtual void setPercentageValue(unsigned int value) = 0;
    };

    class ProgressBar : public Rect, public Progress


@@ 28,6 29,7 @@ namespace gui

        void setMaximum(unsigned int value) noexcept override;
        void setValue(unsigned int value) noexcept override;
        void update(int value = 1) noexcept override;
        void setPercentageValue(unsigned int value) noexcept override;

        void buildDrawListImplementation(std::list<Command> &commands) override;


@@ 48,6 50,7 @@ namespace gui

        void setMaximum(unsigned int value) noexcept override;
        void setValue(unsigned int value) noexcept override;
        void update(int value = 1) noexcept override;
        void setPercentageValue(unsigned int value) noexcept override;

        void buildDrawListImplementation(std::list<Command> &commands) override;


@@ 56,8 59,8 @@ namespace gui
      private:
        void createWidgets();

        auto calculateProgressIndicatorCenter() const noexcept -> Point;
        auto getPercentageValue() const noexcept -> float;
        auto calculateProgressIndicatorCenter() const -> Point;
        auto getPercentageValue() const -> float;

        unsigned int maxValue     = 0U;
        unsigned int currentValue = 0U;