~aleteoryx/muditaos

ref: b8f6cc82804d30df4839146363b6f5ca7687a216 muditaos/module-gui/gui/widgets/PageLayout.cpp -rw-r--r-- 4.1 KiB
b8f6cc82 — Marcin Smoczyński Add changelog for v0.54.1 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PageLayout.hpp"
#include "InputEvent.hpp"
#include "Style.hpp"
#include <log/log.hpp>

namespace gui
{
    PageLayout::PageLayout(Item *parent, const uint32_t &x, const uint32_t &y, const uint32_t &w, const uint32_t &h)
        : BoxLayout(parent, x, y, w, h)
    {
        setPenWidth(style::window::default_border_no_focus_w);
        setPenFocusWidth(style::window::default_border_no_focus_w);

        inputCallback = [this](Item &item, const InputEvent &inputEvent) -> bool {
            unsigned int position = 0;
            bool handled = false;
            // first try with children and find position in pages
            for (auto &el : children) {
                if (el->visible) {
                    handled = el->onInput(inputEvent);
                    if (handled) {
                        return true;
                    }
                    break;
                }
                ++position;
            }
            if (inputEvent.state != InputEvent::State::keyReleasedShort) {
                return false;
            }
            if (!handled) { // children didn't handle -> handle next/prev page with position
                if (inputEvent.keyCode == gui::KeyCode::KEY_UP && position != 0) {
                    return switchPage(position - 1, true);
                }
                if (inputEvent.keyCode == gui::KeyCode::KEY_DOWN && position < children.size() - 1) {
                    return switchPage(position + 1);
                }
            }
            return false;
        };
    }

    PageLayout::PageLayout(Item *parent, const BoundingBox &box) : PageLayout(parent, box.x, box.y, box.w, box.h)
    {}

    VBox *PageLayout::addPage()
    {
        auto el = new VBox();
        el->setPosition(0, 0);                   // setting position IN BOX if relative
        el->setSize(widgetArea.w, widgetArea.h); // set area to parent area
        el->setEdges(RectangleEdge::None);
        // if new element fits && To avoid cyclic addWidget -> call parent addWidget
        BoxLayout::addWidget(el);
        if (el->visible) {
            return el;
        }
        else {
            return nullptr;
        }
    }

    void PageLayout::addWidget(Item *item)
    {
        if (item == nullptr) {
            return;
        }
        if (this->children.size() == 0) {
            // cant add this element to this paged view at all
            if (addPage() == nullptr) {
                return;
            }
        }

        VBox *vbox = dynamic_cast<VBox *>(children.back());
        if (vbox != nullptr) {
            vbox->addWidget(item);
            if (!item->visible) {
                vbox->removeWidget(item);
                item->visible = true;

                // add next page and try again - first set last box to not visible to avoid it's rebuild
                vbox = addPage();
                if (vbox == nullptr) {
                    return;
                }
                // set new (next) page invisible
                vbox->setVisible(false);
                /// to not recure on addWidget
                vbox->addWidget(item);
                if (!vbox->visible) {
                    LOG_ERROR("Child not added on 2nd try, check sizes of Page and children u try to add!");
                }
            }
        }
        return;
    }

    bool PageLayout::switchPage(unsigned int n, bool previous)
    {
        if (children.size() == 0 || n >= children.size()) {
            LOG_ERROR("Cant switch to page %d, num of pages: %u", n, static_cast<unsigned int>(children.size()));
            return false;
        }
        unsigned int i = 0;
        for (auto &el : children) {
            if (i == n) {
                auto ell = dynamic_cast<VBox *>(el);
                if (ell) {
                    ell->setVisible(true, previous);
                }
            }
            else {
                el->setVisible(false);
            }
            ++i;
        }
        return true;
    }
}; // namespace gui