~aleteoryx/muditaos

ref: 7fbaf735ed99f5b0d26adb686cfa6ed2bb4267d5 muditaos/module-gui/gui/widgets/TextLine.hpp -rw-r--r-- 4.9 KiB
7fbaf735 — Przemyslaw Brudny [EGD-7813] Option Window titles localizations fix 4 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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 <numeric>
#include <list>
#include "Common.hpp"
#include "RawText.hpp"
#include "TextDocument.hpp"
#include "BoxLayout.hpp"
#include "TextLineCursor.hpp"

namespace gui
{
    enum class UnderlineDrawMode
    {
        WholeLine,
        Concurrent
    };

    struct UnderLineProperties
    {
        bool draw                           = false;
        Position underLinePadding           = 0;
        unsigned int thickness              = 1;
        Length underlineHeight              = 0;
        UnderlineDrawMode drawUnderlineMode = UnderlineDrawMode::WholeLine;
    };

    /// interface element for TextDocument->getLine() <-- Text
    class TextLine
    {
        unsigned int shownLetterCount = 0;
        Length widthUsed              = 0;
        Length heightUsed             = 0;
        Length maxWidth               = 0;
        std::list<RawText *> lineContent;
        Rect *underline = nullptr;
        UnderLineProperties underLineProperties;
        TextBlock::End end                  = TextBlock::End::None;
        Position storedYOffset              = 0;
        bool lineEnd                        = false;
        bool lineVisible                    = true;
        bool breakLineDashAddition          = false;
        bool removeTrailingSpace            = false;
        unsigned int lineStartBlockNumber   = text::npos;
        unsigned int lineStartBlockPosition = text::npos;

        unsigned int calculateSignsToShow(BlockCursor &localCursor, UTF8 &text, unsigned int space);
        UTF8 textToPrint(unsigned int signsCountToShow, UTF8 &text);
        void createUnderline(unsigned int max_w, unsigned int max_height);
        void updateUnderline(const short &x, const short &y);
        void setLineStartConditions(unsigned int startBlockNumber, unsigned int startBlockPosition);

      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 &&) noexcept;

        TextLine(BlockCursor &cursor,
                 unsigned int max_width,
                 unsigned int init_height,
                 UnderLineProperties underLineProperties)
            : TextLine(cursor, max_width)
        {
            this->underLineProperties                 = underLineProperties;
            this->underLineProperties.underlineHeight = init_height;
        }

        ~TextLine();

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

        /// count of elements in whole TextLine
        [[nodiscard]] unsigned int count() const noexcept
        {
            return std::accumulate(lineContent.begin(), lineContent.end(), 0U, [](const auto sum, const auto &content) {
                return sum + content->getTextLength();
            });
        }

        [[nodiscard]] bool empty() const noexcept
        {
            return ((end == TextBlock::End::Newline && count() == 1) || (end == TextBlock::End::None && count() == 0));
        }

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

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

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

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

        [[nodiscard]] auto isVisible() const noexcept
        {
            return lineVisible;
        }

        void setVisible(bool val) noexcept
        {
            lineVisible = val;
        }

        [[nodiscard]] auto getLineStartBlockNumber() const noexcept
        {
            return lineStartBlockNumber;
        }

        [[nodiscard]] auto getLineStartBlockPosition() const noexcept
        {
            return lineStartBlockPosition;
        }

        [[nodiscard]] int32_t getX() const noexcept
        {
            return lineContent.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);
        [[nodiscard]] const Item *getElement(unsigned int pos) const noexcept;
        [[nodiscard]] auto getText(unsigned int pos) const -> UTF8;
    };
} // namespace gui