~aleteoryx/muditaos

ref: 782980b261457bc9a54235bd1a0fc90a6bd1484e muditaos/module-gui/gui/widgets/TextLine.hpp -rw-r--r-- 3.8 KiB
782980b2 — PrzeBrudny [EGD-4372] Text addition boundaries added with tests. Removed old bounds checking. Text blocks on newlines split issue fixed. Text widgets cleanups. (#1020) 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
123
124
125
126
// 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 <list>
#include "Common.hpp"
#include "Label.hpp"
#include "TextDocument.hpp"
#include "BoxLayout.hpp"
#include "TextLineCursor.hpp"

namespace gui
{
    class TextCursor;

    enum class UnderlineDrawMode
    {
        WholeLine,
        Concurrent
    };

    /// interface element for TextDocument->getLine() <-- Text
    class TextLine
    {
        unsigned int number_letters_shown = 0;
        Length width_used                 = 0;
        Length height_used                = 0;
        Length max_width                  = 0;
        std::list<Label *> elements_to_show_in_line;
        Rect *underline                     = nullptr;
        bool drawUnderline                  = false;
        UnderlineDrawMode drawUnderlineMode = UnderlineDrawMode::Concurrent;
        Position underlinePadding           = 0;
        TextBlock::End end                  = TextBlock::End::None;
        Position storedYOffset              = 0;
        bool lineEnd                        = false;

        void createUnderline(unsigned int max_w, unsigned int max_height);
        void updateUnderline(const short &x, const short &y);

      public:
        /// creates TextLine with data from text based on TextCursor position filling max_width
        TextLine(BlockCursor &, unsigned int max_width);
        TextLine(TextLine &) = delete;
        TextLine(TextLine &&);

        TextLine(BlockCursor &cursor,
                 unsigned int max_width,
                 unsigned int init_height,
                 bool drawUnderline,
                 UnderlineDrawMode drawUnderlineMode,
                 Position underlinePadding)
            : TextLine(cursor, max_width)
        {
            this->drawUnderline     = drawUnderline;
            this->drawUnderlineMode = drawUnderlineMode;
            this->underlinePadding  = underlinePadding;

            createUnderline(max_width, init_height);
        }

        ~TextLine();

        /// number of letters in Whole TextLines
        [[nodiscard]] unsigned int length() const
        {
            return number_letters_shown;
        }

        /// count of elements in whole TextLine
        [[nodiscard]] unsigned int count() const
        {
            return elements_to_show_in_line.size();
        }

        [[nodiscard]] Length width() const
        {
            return width_used;
        }

        [[nodiscard]] Length height() const
        {
            return height_used;
        }

        [[nodiscard]] TextBlock::End getEnd() const
        {
            return end;
        }

        [[nodiscard]] bool getLineEnd() const
        {
            return lineEnd;
        }

        const Item *getElement(unsigned int pos) const
        {
            unsigned int local_pos = 0;
            for (auto &el : elements_to_show_in_line) {
                local_pos += el->getTextLength();
                if (local_pos >= pos) {
                    return el;
                }
            }
            return nullptr;
        }

        int32_t getX() const
        {
            return elements_to_show_in_line.front()->area().pos(Axis::X);
        }

        void setPosition(const short &x, const short &y);
        void setParent(Item *parent);
        [[nodiscard]] Length getWidth() const;
        [[nodiscard]] Length getWidthTo(unsigned int pos) const;
        void erase();
        /// align TextLine due to alignment axis in parent_width
        ///
        /// moves Text parts in Text. To not call n times callbacks on resize, call prior to setting parent
        void alignH(Alignment align, Length parent_length) const;
        void alignV(Alignment align, Length parent_length, Length lines_height);
        auto getText(unsigned int pos) const -> UTF8;
    };
} // namespace gui