// 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 #include #include #include "Alignment.hpp" #include "InputEvent.hpp" #include "TextConstants.hpp" #include "utf8/UTF8.hpp" #include "InputMode.hpp" #include "TextLine.hpp" #include "Translator.hpp" namespace gui { using TextLineStartContition = std::tuple; class Lines { Text *text = nullptr; std::list lines; UnderLineProperties underLineProperties; unsigned int linesSpacing = 0; void addToInvisibleLines(TextLine line); public: explicit Lines(Text *text) : text(text) {} ~Lines() = default; LinesDrawStop stopCondition = LinesDrawStop::None; TextLineStartContition drawStartConditions = {0, 0}; std::list previousLinesStart; void reset() { erase(); stopCondition = LinesDrawStop::None; previousLinesStart.clear(); drawStartConditions = {0, 0}; } void erase() { if (text != nullptr) { for (auto &line : lines) { line.erase(); } } lines.clear(); } void emplace(TextLine &&line) { lines.emplace_back(std::move(line)); } [[nodiscard]] auto &get() { return lines; } [[nodiscard]] auto &last() { return lines.back(); } [[nodiscard]] auto &first() { return lines.front(); } [[nodiscard]] auto size() const noexcept { return lines.size(); } [[nodiscard]] auto countVisible() const noexcept { return std::count_if(lines.begin(), lines.end(), [](const auto &line) { return line.isVisible(); }); } [[nodiscard]] auto empty() const noexcept { return lines.empty(); } [[nodiscard]] auto maxWidth() const noexcept { Length w = 0; // could be std::max_element for (auto &el : lines) { if (el.isVisible()) { w = std::max(el.width(), w); } } return w; } Length calculateLineSpacingAddition() const noexcept { return empty() ? 0 : (size() - 1) * linesSpacing; } Length calculateInitialCursorPosition(Length initHeight) const noexcept { return (empty() ? initHeight : initHeight * size()) + calculateLineSpacingAddition() + underLineProperties.underLinePadding; } [[nodiscard]] auto linesHeight() const noexcept { return calculateLineSpacingAddition() + std::accumulate(lines.begin(), lines.end(), 0U, [](const auto sum, const auto &line) { return line.isVisible() ? sum + line.height() : sum; }); } [[nodiscard]] auto linesLength() const noexcept { return std::accumulate(lines.begin(), lines.end(), 0U, [](const auto sum, const auto &line) { return line.isVisible() ? sum + line.length() : sum; }); } auto setUnderLineProperties(UnderLineProperties val) -> void { underLineProperties = val; } [[nodiscard]] UnderLineProperties &getUnderLineProperties() noexcept { return underLineProperties; } auto setLineSpacing(unsigned int val) -> void { linesSpacing = val; } auto draw(BlockCursor &drawCursor, Length w, Length h, Position lineYPosition, Position lineXPosition) -> void; auto draw(BlockCursor &drawCursor, Length w, Length h, Position lineYPosition, Position lineXPosition, unsigned int linesCount) -> void; auto linesHAlign(Length parentSize) -> void; auto linesVAlign(Length parentSize) -> void; auto addToPreviousLinesStartList(unsigned int lineStartBlockNumber, unsigned int lineStartBlockPosition) -> void; TextLine *getLine(unsigned int lineNr); }; } // namespace gui