~aleteoryx/muditaos

ref: 6665a43d2b901b89809c4f18338d8ea6c0b08df7 muditaos/module-apps/application-phonebook/widgets/PhonebookListView.cpp -rw-r--r-- 3.9 KiB
6665a43d — Lefucjusz [BH-1780] Fix uncaught std::filesystem::file_size exception 2 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
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PhonebookListView.hpp"

namespace gui
{
    PhonebookListView::PhonebookListView(Item *parent,
                                         std::uint32_t x,
                                         std::uint32_t y,
                                         std::uint32_t w,
                                         std::uint32_t h,
                                         std::shared_ptr<ListItemProvider> prov)
        : ListView(parent, x, y, w, h, std::move(prov))
    {}

    void PhonebookListView::addLabelMarker(gui::PhonebookItem *item)
    {
        switch (direction) {
        case listview::Direction::Bottom:
            if (labelMark != item->getLabelMarker()) {
                labelMark = item->getLabelMarker();
                body->addWidget(new PhonebookMarkItem(labelMark));
            }
            break;

        case listview::Direction::Top:
            if (currentPageSize == 0) {
                labelMark = item->getLabelMarker();
                break;
            }

            if (labelMark != item->getLabelMarker()) {
                const auto initialSlotsLeft  = getSlotsLeft();
                const auto previousLabelMark = labelMark;
                labelMark                    = item->getLabelMarker();

                body->removeWidget(item);
                body->addWidget(new PhonebookMarkItem(previousLabelMark));

                /* Add item to body even if it won't fit to avoid manual memory
                 * management for item, but apply correction to currentPageSize
                 * if it is not visible. */
                body->addWidget(item);
                if (initialSlotsLeft == 0) {
                    currentPageSize--;
                }

                previousItemIsLabel = true;
            }
            break;
        }
    }

    void PhonebookListView::addItemsOnPage()
    {
        currentPageSize            = 0;
        labelMark                  = "";

        ListItem *item             = nullptr;
        ListItem *previousListItem = nullptr;

        while ((item = provider->getItem(getOrderFromDirection())) != nullptr) {

            /* If direction is top-to-bottom, add label mark before adding phonebook item. */
            if (direction == listview::Direction::Bottom) {
                addLabelMarker(dynamic_cast<gui::PhonebookItem *>(item));
            }

            /* Check if new item fits, if it does - add it, if not - handle label insertion
             * case for bottom-to-top navigation direction. */
            if (getSlotsLeft() > 0) {
                body->addWidget(item);
            }
            else {
                if (direction == listview::Direction::Top) {
                    if (previousItemIsLabel) {
                        break;
                    }
                    body->erase(previousListItem);
                    body->addWidget(new PhonebookMarkItem(labelMark));
                    currentPageSize--;
                }
                break;
            }

            /* If direction is bottom-to-top, add label mark after adding phonebook item. */
            if (direction == listview::Direction::Top) {
                previousItemIsLabel = false;
                addLabelMarker(dynamic_cast<gui::PhonebookItem *>(item));
            }

            previousListItem = item;
            currentPageSize++;
        }

        recalculateStartIndex();

        // Add element on top for first page purpose
        if (startIndex == 0 && direction == listview::Direction::Top) {
            body->addWidget(new PhonebookMarkItem(labelMark));
        }
    }

    std::size_t PhonebookListView::getSlotsLeft()
    {
        const auto singleSlotSpace = getProvider()->getMinimalItemSpaceRequired();
        return body->getPrimarySizeLeft() / singleSlotSpace;
    }
} /* namespace gui */