~aleteoryx/muditaos

7c1c7395e3e62f8ce6a81c325c529993fb5ef7bb — KacperLewandowski 5 years ago 1e603d8
[EGD-3314] Develop new/edit event and custom repeat windows
M image/assets/lang/lang_en.json => image/assets/lang/lang_en.json +1 -0
@@ 90,6 90,7 @@
    "app_calendar_reminder_1_day_before": "1 day before",
    "app_calendar_reminder_2_days_before": "2 days before",
    "app_calendar_reminder_1_week_before": "1 week before",
    "app_calendar_custom_repeat_title": "Custom repeat",

    "app_options_invalid_option": " <Invalid Option> ",
    "app_options_contact_details": "Contact details",

M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +8 -0
@@ 4,6 4,8 @@
#include "windows/CalendarEventsOptionsWindow.hpp"
#include "windows/AllEventsWindow.hpp"
#include "windows/EventDetailWindow.hpp"
#include "windows/NewEditEventWindow.hpp"
#include "windows/CustomRepeatWindow.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "NoEvents.hpp"
#include "Dialog.hpp"


@@ 76,6 78,12 @@ namespace app
        windows.insert(std::pair<std::string, gui::AppWindow *>(
            style::window::calendar::name::details_window,
            new gui::EventDetailWindow(this, style::window::calendar::name::details_window)));
        windows.insert(std::pair<std::string, gui::AppWindow *>(
            style::window::calendar::name::new_edit_event,
            new NewEditEventWindow(this, style::window::calendar::name::new_edit_event)));
        windows.insert(std::pair<std::string, gui::AppWindow *>(
            style::window::calendar::name::custom_repeat_window,
            new CustomRepeatWindow(this, style::window::calendar::name::custom_repeat_window)));
    }

    void ApplicationCalendar::destroyUserInterface()

M module-apps/application-calendar/CMakeLists.txt => module-apps/application-calendar/CMakeLists.txt +5 -0
@@ 7,16 7,21 @@ target_sources( ${PROJECT_NAME}
		"${CMAKE_CURRENT_LIST_DIR}/windows/CalendarEventsOptionsWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/AllEventsWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/EventDetailWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/NewEditEventWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/CustomRepeatWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/DayEventsModel.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/AllEventsModel.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/EventDetailModel.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/EventDetailWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/MonthModel.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/CustomRepeatModel.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/DayEventsItem.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/AllEventsItem.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/CalendarListView.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/EventDetailDescriptionItem.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/RepeatAndReminderItem.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/CheckBoxItem.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/EventTimeItem.cpp"
	PUBLIC
		"${CMAKE_CURRENT_LIST_DIR}/ApplicationCalendar.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/models/DayEventsModel.hpp"

A module-apps/application-calendar/models/CustomRepeatModel.cpp => module-apps/application-calendar/models/CustomRepeatModel.cpp +79 -0
@@ 0,0 1,79 @@
#include "CustomRepeatModel.hpp"
#include "application-calendar/widgets/CheckBoxItem.hpp"
#include <ListView.hpp>
#include <Utils.hpp>

CustomRepeatModel::CustomRepeatModel(app::Application *app) : application(app)
{}

void CustomRepeatModel::requestRecords(const uint32_t offset, const uint32_t limit)
{}

unsigned int CustomRepeatModel::getMinimalItemHeight() const
{
    return 61; // style::window::calendar::item::customrepeat::height;
}

gui::ListItem *CustomRepeatModel::getItem(gui::Order order)
{
    auto app = application;
    // maybe this should be different
    gui::CheckBoxItem *item = nullptr;
    switch (count) {
    case 7:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Monday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 6:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Tuesday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 5:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Wednesday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 4:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Thursday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 3:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Friday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 2:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Saturday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    case 1:
        item = new gui::CheckBoxItem(
            utils::localize.get(style::strings::common::Sunday),
            [app](const UTF8 &text) { app->getCurrentWindow()->bottomBarTemporaryMode(text); },
            [app]() { app->getCurrentWindow()->bottomBarRestoreFromTemporaryMode(); });
        break;
    default:
        return item;
        break;
    }
    count--;
    // item->activatedCallback = [=](gui::Item &item) {
    //    LOG_INFO("Check/Uncheck item");
    //    return true;
    //};
    // item->focusChangedCallback = [=](gui::Item &) {
    //    item->changeFont();
    //    return true;
    //};
    return item;
}

A module-apps/application-calendar/models/CustomRepeatModel.hpp => module-apps/application-calendar/models/CustomRepeatModel.hpp +23 -0
@@ 0,0 1,23 @@
#pragma once
#include "Application.hpp"
#include "application-calendar/widgets/CalendarStyle.hpp"
#include <ListItemProvider.hpp>

class CustomRepeatModel : public gui::ListItemProvider
{
    app::Application *application = nullptr;
    const int daysInWeek          = 7;
    int count                     = 7;

  public:
    CustomRepeatModel(app::Application *app);

    void requestRecords(const uint32_t offset, const uint32_t limit) override;
    // virtual methods for ListViewProvider
    unsigned int getMinimalItemHeight() const override;
    gui::ListItem *getItem(gui::Order order) override;
    int getItemCount() const override
    {
        return daysInWeek;
    };
};

M module-apps/application-calendar/widgets/CalendarStyle.hpp => module-apps/application-calendar/widgets/CalendarStyle.hpp +2 -0
@@ 17,6 17,8 @@ namespace style
                const inline std::string dialog_yes_no     = "DialogYesNo";
                const inline std::string all_events_window = "AllEventsWindow";
                const inline std::string details_window    = "DetailsWindow";
                const inline std::string new_edit_event       = "NewEditEvent";
                const inline std::string custom_repeat_window = "CustomRepeat";
            } // namespace name

            const inline int day_cell_width    = 60;

A module-apps/application-calendar/widgets/CheckBoxItem.cpp => module-apps/application-calendar/widgets/CheckBoxItem.cpp +93 -0
@@ 0,0 1,93 @@
//#include "application-calendar/models/CustomRepeatModel.hpp"
#include "CheckBoxItem.hpp"
#include <ListView.hpp>
#include <Style.hpp>
#include <time/time_conversion.hpp>

namespace gui
{

    CheckBoxItem::CheckBoxItem(const std::string &description,
                               std::function<void(const UTF8 &)> bottomBarTemporaryMode,
                               std::function<void()> bottomBarRestoreFromTemporaryMode)
        : bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
          bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
    {
        setMinimumSize(style::window::default_body_width, 62);
        setMaximumSize(style::window::default_body_width, 62);

        // setEdges(RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);

        hBox = new gui::HBox(this, 0, 0, 400, 0);
        hBox->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        hBox->setPenFocusWidth(style::window::default_border_focus_w);
        hBox->setPenWidth(1);

        inputBoxLabel = new gui::Label(hBox, 0, 0, 0, 0);
        inputBoxLabel->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_BOTTOM);
        inputBoxLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        inputBoxLabel->setFont(style::window::font::medium);
        inputBoxLabel->activeItem = false;

        descriptionLabel = new gui::Label(hBox, 0, 0, 0, 0);
        descriptionLabel->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        descriptionLabel->setFont(style::window::font::medium);
        descriptionLabel->activeItem = false;

        tickImage = new gui::Image(hBox, 0, 0, 0, 0);
        tickImage->setVisible(false);
        tickImage->activeItem = false;

        descriptionLabel->setText(description);
        tickImage->set("small_tick");

        /*this->focusChangedCallback = [&](gui::Item &item) {
            if (focus) {
                setFocusItem(inputBoxLabel);
                if (tickImage->visible) {
                    bottomBarTemporaryMode(utils::localize.get("app_phonebook_uncheck"));
                }
                else {
                    bottomBarTemporaryMode(utils::localize.get("app_phonebook_check"));
                }
            }
            else {
                setFocusItem(nullptr);
                bottomBarRestoreFromTemporaryMode();
            }
            return true;
        };*/
    }

    bool CheckBoxItem::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
    {
        hBox->setPosition(0, 0);
        hBox->setSize(newDim.w, newDim.h);
        LOG_DEBUG("SIZE: %i,  %i", newDim.w, newDim.h);
        inputBoxLabel->setArea(BoundingBox(0, newDim.h - 50, 55, 50));

        descriptionLabel->setArea(BoundingBox(75, newDim.h - 40, 280, 40));

        tickImage->setArea(BoundingBox(12, newDim.h - 35, 30, 30));

        return true;
    }

    void CheckBoxItem::changeFont()
    {}

    bool CheckBoxItem::onActivated(void *data)
    {
        /// TODO: Center check/uncheck, now it is on the left side.
        tickImage->setVisible(!tickImage->visible);
        if (tickImage->visible) {
            bottomBarTemporaryMode(utils::localize.get("app_phonebook_uncheck"));
        }
        else {
            bottomBarTemporaryMode(utils::localize.get("app_phonebook_check"));
        }
        return true;
    }

} /* namespace gui */

A module-apps/application-calendar/widgets/CheckBoxItem.hpp => module-apps/application-calendar/widgets/CheckBoxItem.hpp +32 -0
@@ 0,0 1,32 @@
#pragma once
#include <Label.hpp>
#include <Image.hpp>
#include <ListItem.hpp>
#include <BoxLayout.hpp>

namespace gui
{
    class CheckBoxItem : public ListItem
    {
        gui::HBox *hBox              = nullptr;
        gui::Label *inputBoxLabel    = nullptr;
        gui::Label *descriptionLabel = nullptr;
        gui::Image *tickImage        = nullptr;

        std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr;
        std::function<void()> bottomBarRestoreFromTemporaryMode      = nullptr;
        // bool visibleState = false;

      public:
        CheckBoxItem(const std::string &description,
                     std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
                     std::function<void()> bottomBarRestoreFromTemporaryMode      = nullptr);
        virtual ~CheckBoxItem() = default;

        void changeFont();
        // virtual methods from Item
        bool onActivated(void *data) override;
        bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
    };

} /* namespace gui */

A module-apps/application-calendar/widgets/EventTimeItem.cpp => module-apps/application-calendar/widgets/EventTimeItem.cpp +89 -0
@@ 0,0 1,89 @@
#include "application-calendar/models/CustomRepeatModel.hpp"
#include "EventTimeItem.hpp"
#include <ListView.hpp>
#include <Style.hpp>
#include <time/time_conversion.hpp>

namespace gui
{

    EventTimeItem::EventTimeItem(const std::string &description,
                                 std::function<void(const UTF8 &)> bottomBarTemporaryMode,
                                 std::function<void()> bottomBarRestoreFromTemporaryMode)
        : bottomBarTemporaryMode(std::move(bottomBarTemporaryMode)),
          bottomBarRestoreFromTemporaryMode(std::move(bottomBarRestoreFromTemporaryMode))
    {
        setMinimumSize(style::window::default_body_width, 80);
        setMaximumSize(style::window::default_body_width, 80);

        // setEdges(RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);

        hBox = new gui::HBox(this, 0, 0, 450, 0);
        hBox->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        hBox->setPenFocusWidth(style::window::default_border_focus_w);
        hBox->setPenWidth(1);

        colonLabel = new gui::Label(hBox, 0, 0, 0, 0);
        colonLabel->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        colonLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        colonLabel->setFont(style::window::font::medium);
        colonLabel->setText(":");
        colonLabel->activeItem = false;

        descriptionLabel = new gui::Label(hBox, 0, 0, 0, 0);
        descriptionLabel->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        descriptionLabel->setAlignment(Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        descriptionLabel->setFont(style::window::font::medium);
        descriptionLabel->activeItem = false;

        hourInput = new gui::Text(hBox, 0, 0, 0, 0);
        hourInput->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_BOTTOM);
        hourInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        hourInput->setFont(style::window::font::medium);
        hourInput->setInputMode(new InputMode({InputMode::digit}));
        hourInput->setPenFocusWidth(style::window::default_border_focus_w);
        hourInput->setPenWidth(1);
        hourInput->setEditMode(gui::EditMode::EDIT);

        minuteInput = new gui::Text(hBox, 0, 0, 0, 0);
        minuteInput->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_BOTTOM);
        minuteInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        minuteInput->setFont(style::window::font::medium);
        minuteInput->setInputMode(new InputMode({InputMode::digit}));
        minuteInput->setPenFocusWidth(style::window::default_border_focus_w);
        minuteInput->setPenWidth(1);
        minuteInput->setEditMode(gui::EditMode::EDIT);

        mode12hInput = new gui::Text(hBox, 0, 0, 0, 0);
        mode12hInput->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_BOTTOM);
        mode12hInput->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        mode12hInput->setFont(style::window::font::medium);
        mode12hInput->setInputMode(new InputMode({InputMode::ABC}));
        mode12hInput->setPenFocusWidth(style::window::default_border_focus_w);
        mode12hInput->setPenWidth(1);
        mode12hInput->setEditMode(gui::EditMode::EDIT);

        descriptionLabel->setText(description);
    }

    bool EventTimeItem::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
    {
        hBox->setPosition(0, 0);
        hBox->setSize(newDim.w, newDim.h);
        LOG_DEBUG("SIZE TIME ITEM: %i,  %i", newDim.w, newDim.h);

        descriptionLabel->setArea(BoundingBox(15, 0, 150, 20));
        colonLabel->setArea(BoundingBox(50, 30, 10, 20));
        hourInput->setArea(BoundingBox(15, 20, 140, newDim.h - 20));
        minuteInput->setArea(BoundingBox(175, 20, 140, newDim.h - 20));
        mode12hInput->setArea(BoundingBox(335, 20, 140, newDim.h - 20));

        return true;
    }

    bool EventTimeItem::onActivated(void *data)
    {
        return true;
    }

} /* namespace gui */

A module-apps/application-calendar/widgets/EventTimeItem.hpp => module-apps/application-calendar/widgets/EventTimeItem.hpp +32 -0
@@ 0,0 1,32 @@
#pragma once
#include <Label.hpp>
#include <Text.hpp>
#include <ListItem.hpp>
#include <BoxLayout.hpp>

namespace gui
{
    class EventTimeItem : public ListItem
    {
        gui::HBox *hBox              = nullptr;
        gui::Label *colonLabel       = nullptr;
        gui::Label *descriptionLabel = nullptr;
        gui::Text *hourInput         = nullptr;
        gui::Text *minuteInput       = nullptr;
        gui::Text *mode12hInput      = nullptr;

        std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr;
        std::function<void()> bottomBarRestoreFromTemporaryMode      = nullptr;

      public:
        EventTimeItem(const std::string &description,
                      std::function<void(const UTF8 &text)> bottomBarTemporaryMode = nullptr,
                      std::function<void()> bottomBarRestoreFromTemporaryMode      = nullptr);
        virtual ~EventTimeItem() = default;

        // virtual methods from Item
        bool onActivated(void *data) override;
        bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override;
    };

} /* namespace gui */

M module-apps/application-calendar/windows/CalendarEventsOptionsWindow.cpp => module-apps/application-calendar/windows/CalendarEventsOptionsWindow.cpp +1 -0
@@ 20,6 20,7 @@ namespace gui
        std::list<gui::Option> options;
        options.emplace_back(gui::Option{utils::localize.get("app_calendar_options_edit"), [=](gui::Item &item) {
                                             LOG_INFO("Switch to edit window");
                                             application->switchWindow(style::window::calendar::name::new_edit_event);
                                             return true;
                                         }});
        options.emplace_back(gui::Option{utils::localize.get("app_calendar_options_delete"),

A module-apps/application-calendar/windows/CustomRepeatWindow.cpp => module-apps/application-calendar/windows/CustomRepeatWindow.cpp +44 -0
@@ 0,0 1,44 @@
#include "CustomRepeatWindow.hpp"
#include <gui/widgets/Window.hpp>
#include <gui/widgets/BoxLayout.hpp>
#include <gui/widgets/BottomBar.hpp>
#include <gui/widgets/TopBar.hpp>
#include <Utils.hpp>

namespace app
{

    CustomRepeatWindow::CustomRepeatWindow(app::Application *app, std::string name)
        : AppWindow(app, style::window::calendar::name::custom_repeat_window),
          customRepeatModel{std::make_shared<CustomRepeatModel>(this->application)}
    {
        buildInterface();
    }

    void CustomRepeatWindow::rebuild()
    {
        AppWindow::destroyInterface();
        buildInterface();
    }

    void CustomRepeatWindow::buildInterface()
    {
        AppWindow::buildInterface();

        topBar->setActive(gui::TopBar::Elements::TIME, true);
        bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
        bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));

        setTitle(utils::localize.get("app_calendar_custom_repeat_title"));
        list = new gui::ListView(this,
                                 style::window::calendar::listView_x,
                                 style::window::calendar::listView_y - 8,
                                 style::window::calendar::listView_w,
                                 style::window::calendar::listView_h,
                                 customRepeatModel);
        list->setPenFocusWidth(style::window::default_border_no_focus_w);
        list->setPenWidth(style::window::default_border_no_focus_w);
        setFocusItem(list);
    }

} /* namespace app */

A module-apps/application-calendar/windows/CustomRepeatWindow.hpp => module-apps/application-calendar/windows/CustomRepeatWindow.hpp +24 -0
@@ 0,0 1,24 @@
#pragma once
#include "application-calendar/widgets/CalendarStyle.hpp"
#include "application-calendar/models/CustomRepeatModel.hpp"
#include "windows/AppWindow.hpp"
#include "Application.hpp"
#include <gui/widgets/Item.hpp>
#include <ListView.hpp>

namespace app
{
    class CustomRepeatWindow : public gui::AppWindow
    {
        gui::ListView *list                                  = nullptr;
        std::shared_ptr<CustomRepeatModel> customRepeatModel = nullptr;

      public:
        CustomRepeatWindow(Application *app, std::string name);

        // bool onInput(const gui::InputEvent &inputEvent) override;
        void rebuild() override;
        void buildInterface() override;
    };

} /* namespace app */

A module-apps/application-calendar/windows/NewEditEventWindow.cpp => module-apps/application-calendar/windows/NewEditEventWindow.cpp +96 -0
@@ 0,0 1,96 @@
#include "NewEditEventWindow.hpp"
#include "application-calendar/widgets/CheckBoxItem.hpp"
#include "application-calendar/widgets/EventTimeItem.hpp"
#include <gui/widgets/Window.hpp>
#include <gui/widgets/Span.hpp>
#include <gui/widgets/BoxLayout.hpp>
#include <gui/widgets/BottomBar.hpp>
#include <gui/widgets/TopBar.hpp>

#include <time/time_conversion.hpp>

namespace app
{

    NewEditEventWindow::NewEditEventWindow(app::Application *app, std::string name)
        : AppWindow(app, style::window::calendar::name::new_edit_event)
    {
        buildInterface();
    }

    void NewEditEventWindow::rebuild()
    {
        buildInterface();
    }

    void NewEditEventWindow::buildInterface()
    {
        AppWindow::buildInterface();

        auto ttime = utils::time::Time();
        topBar->setActive(gui::TopBar::Elements::TIME, true);
        bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
        bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
        bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
        bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::strings::common::save));

        setTitle("New/Edit event");

        // Event name box
        eventNameVBox = new gui::VBox(this, 15, 120, 400, 230); // 70
        eventNameVBox->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);

        eventNameLabel = new gui::Label(eventNameVBox, 0, 0, 400, 20);
        eventNameLabel->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_NO_EDGES);
        eventNameLabel->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Top));
        eventNameLabel->setFont(style::window::font::small);
        eventNameLabel->setText("Event name");
        eventNameLabel->activeItem = false;

        // new gui::Span(eventNameVBox, gui::Axis::Y, 30); // spread title & eventNameInput

        eventNameInput = new gui::Text(eventNameVBox, 0, 0, 400, 50);
        eventNameInput->setEdges(gui::RectangleEdgeFlags::GUI_RECT_EDGE_BOTTOM);
        eventNameInput->setAlignment(
            gui::Alignment(gui::Alignment::Horizontal::Left, gui::Alignment::Vertical::Bottom));
        eventNameInput->setFont(style::window::font::medium);
        eventNameInput->setInputMode(new InputMode(
            {InputMode::ABC, InputMode::abc, InputMode::digit},
            [=](const UTF8 &text) { bottomBarTemporaryMode(text); },
            [=]() { bottomBarRestoreFromTemporaryMode(); },
            [=]() { selectSpecialCharacter(); }));
        eventNameInput->setPenFocusWidth(style::window::default_border_focus_w);
        eventNameInput->setPenWidth(1);
        eventNameInput->setEditMode(gui::EditMode::EDIT);

        // All day event box
        checkBox = new gui::CheckBoxItem("All day event");
        eventNameVBox->addWidget(checkBox);

        // time
        startTime = new gui::EventTimeItem("Start");
        eventNameVBox->addWidget(startTime);
        // setFocusItem(eventNameInput);
        setFocusItem(eventNameVBox);
    }

    bool NewEditEventWindow::onInput(const gui::InputEvent &inputEvent)
    {
        if (AppWindow::onInput(inputEvent)) {
            return true;
        }

        if (!inputEvent.isShortPress()) {
            return false;
        }

        if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
            // LOG_DEBUG("TODO: Save event");
            LOG_DEBUG("TEMPORARY: Switch to custom repeat window");
            application->switchWindow(style::window::calendar::name::custom_repeat_window);
            return true;
        }

        return false;
    }
} /* namespace app */

A module-apps/application-calendar/windows/NewEditEventWindow.hpp => module-apps/application-calendar/windows/NewEditEventWindow.hpp +29 -0
@@ 0,0 1,29 @@
#pragma once

#include "application-calendar/widgets/CalendarStyle.hpp"
#include "windows/AppWindow.hpp"
#include "Application.hpp"
#include <gui/widgets/Item.hpp>
#include <gui/widgets/Label.hpp>
#include <gui/widgets/Text.hpp>
#include <gui/widgets/ListItem.hpp>

namespace app
{
    class NewEditEventWindow : public gui::AppWindow
    {
        gui::VBox *eventNameVBox   = nullptr;
        gui::Label *eventNameLabel = nullptr;
        gui::Text *eventNameInput  = nullptr;
        gui::ListItem *checkBox    = nullptr;
        gui::ListItem *startTime   = nullptr;

      public:
        NewEditEventWindow(Application *app, std::string name);

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

} /* namespace app */