~aleteoryx/muditaos

df1d1cdfe2b33b193f23ec281c5f205a6d606de5 — Przemyslaw Brudny 4 years ago 07cc59d
[BH-723] Added ThreeBox and BellBaseLayout

Added ThreeBox template layout type. Applied it to Pure header.
Created BellBaseLayout for most of Bell windows. Modified
SideListView to proper handle new layout with page bar on/off.
M module-apps/application-bell-settings/data/BellSettingsStyle.hpp => module-apps/application-bell-settings/data/BellSettingsStyle.hpp +0 -8
@@ 17,16 17,8 @@ namespace gui
            inline constexpr auto default_body_width    = 400;
        } // namespace settings_window

        namespace time_set_spinner_list_item
        {
            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

M module-apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp => module-apps/application-bell-settings/widgets/TimeFormatSetListItem.cpp +9 -22
@@ 16,43 16,35 @@ 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)
        : BellSideListItem(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->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        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);
        body->centerBox->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 = new Label(body->lastBox);
        bottomDescription->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h);
        bottomDescription->setFont(style::bell_sidelist_item::description_font);
        bottomDescription->setEdges(RectangleEdge::None);
        bottomDescription->activeItem = false;
        bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center));
        bottomDescription->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        bottomDescription->setText(botDesc);

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


@@ 76,18 68,13 @@ namespace gui

        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;

M module-apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp => module-apps/application-bell-settings/widgets/TimeFormatSetListItem.hpp +2 -3
@@ 5,7 5,7 @@

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

#include <functional>



@@ 14,7 14,7 @@ namespace gui
    class Spinner;
    class Label;

    class TimeFormatSetListItem : public gui::SideListItem
    class TimeFormatSetListItem : public gui::BellSideListItem
    {
      public:
        TimeFormatSetListItem() = delete;


@@ 29,7 29,6 @@ namespace gui
        std::function<void(Item &)> onNextCallback;

      private:
        Margins calculateMargins() const noexcept;

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

M module-apps/application-bell-settings/widgets/TimeSetListItem.cpp => module-apps/application-bell-settings/widgets/TimeSetListItem.cpp +3 -14
@@ 11,14 11,11 @@ namespace gui
{
    TimeSetListItem::TimeSetListItem(
        gui::Length x, gui::Length y, gui::Length w, gui::Length h, std::string description)
        : SideListItem(std::move(description))
        : BellSideListItem(std::move(description))
    {
        setMinimumSize(style::sidelistview::list_item::w, style::sidelistview::list_item::h);
        timeSetFmtSpinner = new TimeSetFmtSpinner(body);
        timeSetFmtSpinner->setMinimumSize(bell_settings_style::time_set_spinner_list_item::w,
                                          bell_settings_style::time_set_spinner_list_item::h);

        timeSetFmtSpinner->setMargins(calculateMargins());
        timeSetFmtSpinner = new TimeSetFmtSpinner(body->centerBox);
        timeSetFmtSpinner->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        setFocusItem(body);

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


@@ 33,12 30,4 @@ 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 */

M module-apps/application-bell-settings/widgets/TimeSetListItem.hpp => module-apps/application-bell-settings/widgets/TimeSetListItem.hpp +2 -5
@@ 3,7 3,7 @@

#pragma once

#include <widgets/SideListItem.hpp>
#include <widgets/BellSideListItem.hpp>

#include <string>



@@ 11,14 11,11 @@ namespace gui
{
    class TimeSetFmtSpinner;

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

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

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

M module-apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp => module-apps/application-bell-settings/windows/BellSettingsTimeUnitsWindow.cpp +2 -3
@@ 35,10 35,9 @@ namespace gui

        presenter->createData();

        sidelistview =
            new SideListView(this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider());
        sidelistview = new SideListView(
            this, 0U, 0U, this->getWidth(), this->getHeight(), presenter->getPagesProvider(), PageBarType::None);
        sidelistview->setEdges(RectangleEdge::None);
        sidelistview->setPageBarVisible(false);

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


M module-apps/apps-common/CMakeLists.txt => module-apps/apps-common/CMakeLists.txt +2 -0
@@ 31,6 31,8 @@ target_sources(apps-common
        widgets/BarGraph.cpp
        widgets/BrightnessBox.cpp
        widgets/ButtonOnOff.cpp
        widgets/BellBaseLayout.cpp
        widgets/BellSideListItem.cpp
        widgets/DateWidget.cpp
        widgets/InputBox.cpp
        widgets/ModesBox.cpp

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

#include "BellBaseLayout.hpp"
#include "Style.hpp"

namespace gui
{
    BellBaseLayout::BellBaseLayout(Item *parent, Position x, Position y, Length w, Length h)
        : VThreeBox(parent, x, y, w, h)
    {
        setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::h);
        setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        setEdges(RectangleEdge::None);

        firstBox = new VBox(this, 0, 0, 0, 0);
        firstBox->setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::first_layout_min_h);
        firstBox->setMaximumHeight(style::bell_base_layout::outer_layouts_h);
        firstBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        firstBox->setEdges(RectangleEdge::None);
        firstBox->activeItem = false;

        centerBox = new VBox(this, 0, 0, 0, 0);
        centerBox->setEdges(RectangleEdge::None);
        centerBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        centerBox->setMinimumSize(style::bell_base_layout::w,
                                  style::bell_base_layout::h - 2 * style::bell_base_layout::outer_layouts_h);

        lastBox = new VBox(this, 0, 0, 0, 0);
        lastBox->setMinimumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h);
        lastBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        lastBox->setEdges(RectangleEdge::None);
        lastBox->activeItem = false;

        resizeItems();
    }
} // namespace gui

A module-apps/apps-common/widgets/BellBaseLayout.hpp => module-apps/apps-common/widgets/BellBaseLayout.hpp +24 -0
@@ 0,0 1,24 @@
// 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 <ThreeBox.hpp>

namespace style::bell_base_layout
{
    constexpr inline auto w                  = style::window_width;
    constexpr inline auto h                  = style::window_height;
    constexpr inline auto first_layout_min_h = 50U;
    constexpr inline auto outer_layouts_h    = 120U;
} // namespace style::bell_base_layout

namespace gui
{
    class BellBaseLayout : public VThreeBox<VBox, VBox, VBox>
    {
      public:
        explicit BellBaseLayout(Item *parent, Position x = 0, Position y = 0, Length w = 0, Length h = 0);
    };

} /* namespace gui */

R module-gui/gui/widgets/SideListItem.cpp => module-apps/apps-common/widgets/BellSideListItem.cpp +6 -8
@@ 3,21 3,19 @@

#include "Label.hpp"
#include "ListItemWithDescription.hpp"
#include "SideListItem.hpp"
#include "BellSideListItem.hpp"
#include "Style.hpp"

namespace gui
{
    SideListItem::SideListItem(std::string description) : ListItemWithDescription(description)
    BellSideListItem::BellSideListItem(const std::string &description) : ListItemWithDescription(description)
    {
        setEdges(RectangleEdge::None);
        body = new VBox(this);
        body->setMinimumSize(style::sidelistview::list_item::w, style::sidelistview::list_item::h);
        body->setEdges(RectangleEdge::None);
        body = new BellBaseLayout(this);

        auto topMessage = new Label(body);
        topMessage->setMinimumSize(style::sidelistview::top_message::w, style::sidelistview::top_message::h);
        topMessage->setFont(style::sidelistview::top_message::font);
        auto topMessage = new Label(body->firstBox);
        topMessage->setMaximumSize(style::bell_base_layout::w, style::bell_base_layout::outer_layouts_h);
        topMessage->setFont(style::bell_sidelist_item::description_font);
        topMessage->setEdges(gui::RectangleEdge::None);
        topMessage->activeItem = false;
        topMessage->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));

R module-gui/gui/widgets/SideListItem.hpp => module-apps/apps-common/widgets/BellSideListItem.hpp +10 -5
@@ 3,16 3,21 @@

#pragma once

#include "BoxLayout.hpp"
#include "ListItemWithDescription.hpp"
#include "BellBaseLayout.hpp"
#include <ListItemWithDescription.hpp>

namespace style::bell_sidelist_item
{
    inline constexpr auto description_font = style::window::font::largelight;
} // namespace style::bell_sidelist_item

namespace gui
{
    class SideListItem : public ListItemWithDescription
    class BellSideListItem : public ListItemWithDescription
    {
      public:
        VBox *body = nullptr;
        BellBaseLayout *body = nullptr;

        SideListItem(std::string description);
        explicit BellSideListItem(const std::string &description);
    };
} /* namespace gui */

M module-gui/gui/widgets/CMakeLists.txt => module-gui/gui/widgets/CMakeLists.txt +2 -2
@@ 22,11 22,11 @@ target_sources( ${PROJECT_NAME}
        "${CMAKE_CURRENT_LIST_DIR}/Window.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/BoxLayout.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/BoxLayoutSizeStore.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/ThreeBox.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/header/Header.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/header/IceAction.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/header/AddElementAction.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/header/SearchAction.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/SideListItem.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/SideListView.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/Spinner.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/TextSpinner.cpp"


@@ 81,8 81,8 @@ target_sources( ${PROJECT_NAME}
        "${CMAKE_CURRENT_LIST_DIR}/Rect.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/Window.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/BoxLayout.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/ThreeBox.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/Layout.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/SideListItem.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/SideListView.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/Spinner.hpp"
        "${CMAKE_CURRENT_LIST_DIR}/TextSpinner.hpp"

M module-gui/gui/widgets/SideListView.cpp => module-gui/gui/widgets/SideListView.cpp +8 -12
@@ 13,7 13,8 @@ namespace gui
                               unsigned int y,
                               unsigned int w,
                               unsigned int h,
                               std::shared_ptr<ListItemProvider> prov)
                               std::shared_ptr<ListItemProvider> prov,
                               PageBarType pageBarType)
        : Rect{parent, x, y, w, h}, ListViewEngine(prov)
    {
        setEdges(RectangleEdge::All);


@@ 21,14 22,13 @@ namespace gui
        bodyOverlay = new VBox{this, 0, 0, w, h};
        bodyOverlay->setEdges(RectangleEdge::None);

        createPageBar();
        applyScrollCallbacks();

        auto bodyTopMargin = pageBar->widgetMinimumArea.h + pageBar->getMargins().getSumInAxis(Axis::Y);
        auto bodyHeight    = h - bodyTopMargin;
        if (pageBarType != PageBarType::None) {
            createPageBar();
            applyScrollCallbacks();
        }

        body = new HBox{bodyOverlay, 0, 0, 0, 0};
        body->setMinimumSize(w, bodyHeight);
        body->setMaximumSize(w, h);
        body->setAlignment(Alignment::Horizontal::Center);
        body->setEdges(RectangleEdge::None);
        bodyOverlay->resizeItems();


@@ 58,7 58,7 @@ namespace gui
            return true;
        };

        createArrowsOverlay(0, bodyTopMargin, w, bodyHeight);
        createArrowsOverlay(0, 0, w, h);

        type = gui::ItemType::LIST;
    }


@@ 138,8 138,4 @@ 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 +8 -3
@@ 10,6 10,12 @@

namespace gui
{
    enum class PageBarType
    {
        None,
        Round,
    };

    class SideListView : public Rect, public ListViewEngine
    {
      protected:


@@ 28,9 34,8 @@ namespace gui
                     unsigned int y,
                     unsigned int w,
                     unsigned int h,
                     std::shared_ptr<ListItemProvider> prov);

        auto setPageBarVisible(bool value) noexcept -> void;
                     std::shared_ptr<ListItemProvider> prov,
                     PageBarType pageBarType = PageBarType::None);

        auto onInput(const InputEvent &inputEvent) -> bool override;
    };

M module-gui/gui/widgets/Style.hpp => module-gui/gui/widgets/Style.hpp +3 -21
@@ 243,25 243,12 @@ namespace style
        inline auto arrow_left_image  = "arrow_left_24px_W_G";
        inline auto arrow_right_image = "arrow_right_24px_W_G";

        namespace arrows_hbox
        {
            inline constexpr auto x = 0U;
            inline constexpr auto y = 150U;
            inline constexpr auto w = window_width;
            inline constexpr auto h = 300U;
        } // namespace arrows_hbox
        namespace list_item
        {
            inline constexpr auto w = window_width;
            inline constexpr auto h = 550U;
            inline constexpr auto h = window_height;
        } // namespace list_item
        namespace middle_box
        {
            inline constexpr auto x = 0U;
            inline constexpr auto y = 50U;
            inline constexpr auto w = 480U;
            inline constexpr auto h = 450U;
        } // namespace middle_box

        namespace progress_bar
        {
            inline constexpr auto margin_left   = 0U;


@@ 270,12 257,7 @@ namespace style
            inline constexpr auto margin_bottom = 10U;
            inline constexpr auto h             = 50U;
        } // namespace progress_bar
        namespace top_message
        {
            inline constexpr auto w    = window_width;
            inline constexpr auto h    = 50U;
            inline constexpr auto font = style::window::font::largelight;
        } // namespace top_message

    }     // namespace sidelistview

    namespace margins

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

#include "ThreeBox.hpp"

namespace gui
{
    template <class Parent, class First, class Center, class Last>
    ThreeBox<Parent, First, Center, Last>::ThreeBox(Item *parent, Position x, Position y, Length w, Length h)
        : Parent(parent, x, y, w, h)
    {}

    template <class First, class Center, class Last>
    HThreeBox<First, Center, Last>::HThreeBox(Item *parent, Position x, Position y, Length w, Length h)
        : ThreeBox<HBox, First, Center, Last>(parent, x, y, w, h)
    {}

    template <class First, class Center, class Last>
    VThreeBox<First, Center, Last>::VThreeBox(Item *parent, Position x, Position y, Length w, Length h)
        : ThreeBox<VBox, First, Center, Last>(parent, x, y, w, h)
    {}

    template class HThreeBox<HBox, HBox, HBox>;
    template class VThreeBox<VBox, VBox, VBox>;

} // namespace gui

A module-gui/gui/widgets/ThreeBox.hpp => module-gui/gui/widgets/ThreeBox.hpp +32 -0
@@ 0,0 1,32 @@
// 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 <BoxLayout.hpp>

namespace gui
{
    template <class Parent, class First, class Center, class Last> class ThreeBox : public Parent
    {
      public:
        explicit ThreeBox(Item *parent, Position x = 0, Position y = 0, Length w = 0, Length = 0);
        virtual ~ThreeBox() = default;

        First *firstBox   = nullptr;
        Center *centerBox = nullptr;
        Last *lastBox     = nullptr;
    };

    template <class First, class Center, class Last> class HThreeBox : public ThreeBox<HBox, First, Center, Last>
    {
      public:
        explicit HThreeBox(Item *parent, Position x = 0, Position y = 0, Length w = 0, Length = 0);
    };

    template <class First, class Center, class Last> class VThreeBox : public ThreeBox<VBox, First, Center, Last>
    {
      public:
        explicit VThreeBox(Item *parent, Position x = 0, Position y = 0, Length w = 0, Length = 0);
    };
}; // namespace gui

M module-gui/gui/widgets/header/Header.cpp => module-gui/gui/widgets/header/Header.cpp +26 -26
@@ 8,27 8,27 @@

namespace gui::header
{
    Header::Header(Item *parent, Position x, Position y, Length w, Length h) : HBox(parent, x, y, w, h)
    Header::Header(Item *parent, Position x, Position y, Length w, Length h) : HThreeBox(parent, x, y, w, h)
    {
        setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
        setEdges(RectangleEdge::None);

        leftBox = new HBox(this, 0, 0, 0, 0);
        leftBox->setMinimumSize(style::header::navigation_indicator::box_width, h);
        leftBox->setAlignment(Alignment(Alignment::Vertical::Top));
        leftBox->setEdges(RectangleEdge::None);
        leftBox->setVisible(false);
        firstBox = new HBox(this, 0, 0, 0, 0);
        firstBox->setMinimumSize(style::header::navigation_indicator::box_width, h);
        firstBox->setAlignment(Alignment(Alignment::Vertical::Top));
        firstBox->setEdges(RectangleEdge::None);
        firstBox->setVisible(false);

        centerBox = new HBox(this, 0, 0, 0, 0);
        centerBox->setEdges(RectangleEdge::None);
        centerBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
        centerBox->setMaximumSize(w, h);

        rightBox = new HBox(this, 0, 0, 0, 0);
        rightBox->setMinimumSize(style::header::navigation_indicator::box_width, h);
        rightBox->setAlignment(Alignment(Alignment::Vertical::Top));
        rightBox->setEdges(RectangleEdge::None);
        rightBox->setVisible(false);
        lastBox = new HBox(this, 0, 0, 0, 0);
        lastBox->setMinimumSize(style::header::navigation_indicator::box_width, h);
        lastBox->setAlignment(Alignment(Alignment::Vertical::Top));
        lastBox->setEdges(RectangleEdge::None);
        lastBox->setVisible(false);
    }

    Item *Header::createTitle(const UTF8 &text)


@@ 47,26 47,26 @@ namespace gui::header

    void Header::showOuterBoxes()
    {
        leftBox->setVisible(true);
        rightBox->setVisible(true);
        firstBox->setVisible(true);
        lastBox->setVisible(true);
        resizeItems();
    }

    void Header::hideOuterBoxes()
    {
        if (rightBox->empty() && leftBox->empty()) {
            rightBox->setVisible(false);
            leftBox->setVisible(false);
        if (lastBox->empty() && firstBox->empty()) {
            lastBox->setVisible(false);
            firstBox->setVisible(false);
        }
    }

    void Header::addToLeftBox(Item *item)
    {
        leftBox->erase();
        firstBox->erase();
        showOuterBoxes();
        leftBox->addWidget(item);
        firstBox->addWidget(item);

        leftBox->resizeItems();
        firstBox->resizeItems();
    }

    void Header::addToCenterBox(Item *item)


@@ 79,11 79,11 @@ namespace gui::header

    void Header::addToRightBox(Item *item)
    {
        rightBox->erase();
        lastBox->erase();
        showOuterBoxes();
        rightBox->addWidget(item);
        lastBox->addWidget(item);

        rightBox->resizeItems();
        lastBox->resizeItems();
    }

    void Header::setTitle(const UTF8 &text)


@@ 128,13 128,13 @@ namespace gui::header
    {
        switch (boxSelection) {
        case BoxSelection::Left:
            leftBox->erase();
            firstBox->erase();
            break;
        case BoxSelection::Center:
            centerBox->erase();
            break;
        case BoxSelection::Right:
            rightBox->erase();
            lastBox->erase();
            break;
        }



@@ 146,11 146,11 @@ namespace gui::header
    {
        switch (boxSelection) {
        case BoxSelection::Left:
            return leftBox->visible;
            return firstBox->visible;
        case BoxSelection::Center:
            return centerBox->visible;
        case BoxSelection::Right:
            return rightBox->visible;
            return lastBox->visible;
        }
        return false;
    }

M module-gui/gui/widgets/header/Header.hpp => module-gui/gui/widgets/header/Header.hpp +2 -5
@@ 3,7 3,7 @@

#pragma once

#include <BoxLayout.hpp>
#include <ThreeBox.hpp>
#include <Label.hpp>
#include <Image.hpp>



@@ 16,12 16,9 @@ namespace gui::header
        Right
    };

    class Header : public HBox
    class Header : public HThreeBox<HBox, HBox, HBox>
    {
      private:
        HBox *leftBox   = nullptr;
        HBox *centerBox = nullptr;
        HBox *rightBox  = nullptr;
        Label *title    = nullptr;

        Item *createTitle(const UTF8 &text);