M changelog.md => changelog.md +1 -0
@@ 5,6 5,7 @@
* `[cellular]` Integration with basic flow for SIM card (cellular<>GUI)
* `[file indexer db]` Added UT fot File Indexer DB
* `[cellular]` Added MMI convertible to action messages.
+* `[text]` Added Up/Down text navigation (without scrolling)
### Fixed
M module-gui/gui/widgets/Lines.cpp => module-gui/gui/widgets/Lines.cpp +3 -3
@@ 93,13 93,13 @@ namespace gui
}
}
- TextLine *Lines::getTextLine(uint32_t line)
+ TextLine *Lines::getLine(unsigned int lineNr)
{
- if (lines.empty() || line >= lines.size()) {
+ if (lines.empty() || lineNr >= lines.size()) {
return nullptr;
}
- auto it = std::next(lines.begin(), line);
+ auto it = std::next(lines.begin(), lineNr);
return &*it;
}
M module-gui/gui/widgets/Lines.hpp => module-gui/gui/widgets/Lines.hpp +1 -8
@@ 17,17 17,11 @@
namespace gui
{
- class Text;
- class TextLineCursor;
-
class Lines
{
Text *text = nullptr;
std::list<TextLine> lines;
- uint32_t max_lines_count = 4;
- uint32_t scroll_position = 0;
-
bool underLine = false;
Position underLinePadding = 0;
@@ 122,8 116,7 @@ namespace gui
auto linesHAlign(Length parentSize) -> void;
auto linesVAlign(Length parentSize) -> void;
- protected:
- TextLine *getTextLine(uint32_t line);
+ TextLine *getLine(unsigned int lineNr);
};
} // namespace gui
M module-gui/gui/widgets/Text.cpp => module-gui/gui/widgets/Text.cpp +4 -1
@@ 475,7 475,10 @@ namespace gui
return false;
}
- if (isMode(EditMode::SCROLL) && (inputEvent.is(KeyCode::KEY_LEFT) || inputEvent.is(KeyCode::KEY_RIGHT))) {
+ // Temporary disabled till text scrolling will ba added
+ // if (isMode(EditMode::SCROLL) && (inputEvent.is(KeyCode::KEY_LEFT) ||
+ // inputEvent.is(KeyCode::KEY_RIGHT))) {
+ if (isMode(EditMode::SCROLL)) {
debug_text("Text in scroll mode ignores left/right navigation");
return false;
}
M module-gui/gui/widgets/Text.hpp => module-gui/gui/widgets/Text.hpp +2 -4
@@ 31,8 31,6 @@ namespace gui
unsigned int cursorPos;
};
- class Lines;
-
/// @brief Widget that holds multiple lines of text.
///
/// Can expand horizontally to it's max size if it needs to fit more text in line
@@ 48,7 46,7 @@ namespace gui
class Text : public Rect
{
friend TextCursor;
- friend Lines;
+ friend TextLineCursor;
protected:
// holds list of labels for displaying currently visible text lines.
@@ 93,7 91,7 @@ namespace gui
[[nodiscard]] auto getSizeMinusPadding(Axis axis, Area val) -> Length;
auto applyParentSizeRestrictions() -> void;
auto calculateAndRequestSize() -> void;
- auto makePreDrawLines(const uint32_t utfVal) -> std::unique_ptr<Lines>;
+ auto makePreDrawLines(uint32_t utfVal) -> std::unique_ptr<Lines>;
auto makePreDrawLines(const TextBlock &textBlock) -> std::unique_ptr<Lines>;
auto checkMaxSignsLimit(unsigned int limitVal) -> InputBound;
M module-gui/gui/widgets/TextCursor.cpp => module-gui/gui/widgets/TextCursor.cpp +6 -8
@@ 58,15 58,13 @@ namespace gui
return Move::Error;
}
- /// left & up - corner case
- if ((checkNpos() || atBegin()) &&
- (direction == NavigationDirection::LEFT || direction == NavigationDirection::UP)) {
+ /// left - corner case
+ if ((checkNpos() || atBegin()) && (direction == NavigationDirection::LEFT)) {
return Move::Start;
}
- /// down & right - corner case
- if ((checkNpos() || atEnd()) &&
- (direction == NavigationDirection::RIGHT || direction == NavigationDirection::DOWN)) {
+ /// right - corner case
+ if ((checkNpos() || atEnd()) && (direction == NavigationDirection::RIGHT)) {
return Move::End;
}
@@ 108,7 106,7 @@ namespace gui
return Move::Error;
}
- std::tuple<const TextLine *, unsigned int, unsigned int> TextCursor::getLine()
+ std::tuple<const TextLine *, unsigned int, unsigned int> TextCursor::getSelectedLine()
{
unsigned int offset_pos = 0;
unsigned int row = 0;
@@ 144,7 142,7 @@ namespace gui
y = getAxisAlignmentValue(Axis::Y, h);
}
else if (text != nullptr || text->lines->size() > 0) {
- auto [line, column, row] = getLine();
+ auto [line, column, row] = getSelectedLine();
if (line == nullptr || column == text::npos || row == text::npos) {
setArea({x, y, w, h});
return;
M module-gui/gui/widgets/TextCursor.hpp => module-gui/gui/widgets/TextCursor.hpp +3 -3
@@ 19,6 19,7 @@ namespace gui
/// and position in gui::Text::Lines shown on screen
class TextCursor : public Rect, public BlockCursor
{
+ protected:
unsigned int pos_on_screen = 0;
Text *text = nullptr;
@@ 36,7 37,7 @@ namespace gui
Error, /// error - now not implemented
};
- TextCursor(gui::Text *parent, unsigned int pos = text::npos, unsigned int block = text::npos);
+ explicit TextCursor(gui::Text *parent, unsigned int pos = text::npos, unsigned int block = text::npos);
TextCursor() = delete;
/// Up Down - end of line movement like in vi
@@ 47,12 48,11 @@ namespace gui
/// removeChar)
virtual Move moveCursor(NavigationDirection direction);
virtual Move moveCursor(NavigationDirection direction, unsigned int n);
- void reset();
// TODO note to self - here should be too UTF8 char handling, not in document...
// cursor can pass processing char directly to TextBlock we are interested in...
// so this should be in BlockCursor in reality
- auto getLine() -> std::tuple<const TextLine *, unsigned int, unsigned int>;
+ auto getSelectedLine() -> std::tuple<const TextLine *, unsigned int, unsigned int>;
void updateView();
// TODO this can move our text out of bonds ( and might need calling expand() in Text)
M module-gui/gui/widgets/TextLine.cpp => module-gui/gui/widgets/TextLine.cpp +57 -57
@@ 28,7 28,7 @@ namespace gui
/// Note - line breaking could be done here with different TextLines to return
/// or via different block types (i.e. numeric block tyle could be not "breakable"
- TextLine::TextLine(BlockCursor &localCursor, unsigned int max_width) : max_width(max_width)
+ TextLine::TextLine(BlockCursor &localCursor, unsigned int maxWidth) : maxWidth(maxWidth)
{
do {
if (!localCursor) { // cursor is faulty
@@ 49,71 49,71 @@ namespace gui
continue;
}
- auto text_format = localCursor->getFormat();
- if (text_format->getFont() == nullptr) {
+ auto textFormat = localCursor->getFormat();
+ if (textFormat->getFont() == nullptr) {
return;
}
- // check if max provided width is enought to enter one char at least
- if (max_width < text_format->getFont()->getCharPixelWidth(text[0])) {
+ // check if max provided width is enough to enter one char at least
+ if (maxWidth < textFormat->getFont()->getCharPixelWidth(text[0])) {
lineEnd = true;
return;
}
- auto can_show = text_format->getFont()->getCharCountInSpace(text, max_width - width_used);
+ auto canShow = textFormat->getFont()->getCharCountInSpace(text, maxWidth - widthUsed);
// we can show nothing - this is the end of this line
- if (can_show == 0) {
+ if (canShow == 0) {
- auto item = buildUITextPart("", text_format);
- width_used = item->getTextNeedSpace();
- height_used = std::max(height_used, item->getTextHeight());
- elements_to_show_in_line.emplace_back(item);
+ auto item = buildUITextPart("", textFormat);
+ widthUsed = item->getTextNeedSpace();
+ heightUsed = std::max(heightUsed, item->getTextHeight());
+ lineContent.emplace_back(item);
end = localCursor->getEnd();
return;
}
// create item for show and update Line data
- auto item = buildUITextPart(text.substr(0, can_show), text_format);
- number_letters_shown += can_show;
- width_used += item->getTextNeedSpace();
- height_used = std::max(height_used, item->getTextHeight());
- elements_to_show_in_line.emplace_back(item);
+ auto item = buildUITextPart(text.substr(0, canShow), textFormat);
+ shownLetterCount += canShow;
+ widthUsed += item->getTextNeedSpace();
+ heightUsed = std::max(heightUsed, item->getTextHeight());
+ lineContent.emplace_back(item);
end = localCursor->getEnd();
- localCursor += can_show;
+ localCursor += canShow;
if (localCursor.checkAndInvalidateBlockChanged() && localCursor.checkPreviousBlockNewLine()) {
return;
}
// not whole text shown, try again for next line if you want
- if (can_show < text.length()) {
+ if (canShow < text.length()) {
return;
}
} while (true);
}
- TextLine::TextLine(TextLine &&from)
+ TextLine::TextLine(TextLine &&from) noexcept
{
- elements_to_show_in_line = std::move(from.elements_to_show_in_line);
- number_letters_shown = from.number_letters_shown;
- width_used = from.width_used;
- height_used = from.height_used;
- underline = from.underline;
- drawUnderline = from.drawUnderline;
- drawUnderlineMode = from.drawUnderlineMode;
- underlinePadding = from.underlinePadding;
- lineEnd = from.lineEnd;
- end = from.end;
- max_width = from.max_width;
+ lineContent = std::move(from.lineContent);
+ shownLetterCount = from.shownLetterCount;
+ widthUsed = from.widthUsed;
+ heightUsed = from.heightUsed;
+ underline = from.underline;
+ drawUnderline = from.drawUnderline;
+ drawUnderlineMode = from.drawUnderlineMode;
+ underlinePadding = from.underlinePadding;
+ lineEnd = from.lineEnd;
+ end = from.end;
+ maxWidth = from.maxWidth;
}
TextLine::~TextLine()
{
- for (auto &el : elements_to_show_in_line) {
+ for (auto &el : lineContent) {
if (el->parent == nullptr) {
delete el;
}
@@ 148,14 148,14 @@ namespace gui
void TextLine::setPosition(const short &x, const short &y)
{
- auto line_x_position = x;
+ auto lineXPosition = x;
updateUnderline(x, y);
- for (auto &el : elements_to_show_in_line) {
- auto scoped_disown = ScopedParentDisown(el);
- el->setArea({line_x_position, y - underlinePadding, el->getWidth(), el->getHeight()});
- line_x_position += el->getWidth();
+ for (auto &el : lineContent) {
+ auto scopedDisown = ScopedParentDisown(el);
+ el->setArea({lineXPosition, y - underlinePadding, el->getWidth(), el->getHeight()});
+ lineXPosition += el->getWidth();
}
}
@@ 167,7 167,7 @@ namespace gui
parent->addWidget(underline);
- for (auto &el : elements_to_show_in_line) {
+ for (auto &el : lineContent) {
parent->addWidget(el);
}
}
@@ 175,7 175,7 @@ namespace gui
Length TextLine::getWidth() const
{
Length width = 0;
- for (auto &line : elements_to_show_in_line) {
+ for (auto &line : lineContent) {
width += line->getWidth();
}
return width;
@@ 184,22 184,22 @@ namespace gui
uint32_t TextLine::getWidthTo(unsigned int pos) const
{
uint32_t width = 0;
- auto curent_pos = 0;
+ auto currentPos = 0;
if (pos == text::npos) {
return 0;
}
- for (auto &el : elements_to_show_in_line) {
+ for (auto &el : lineContent) {
if (el->getFont() == nullptr) {
continue;
}
- if (curent_pos + el->getTextLength() > pos) {
- width += el->getFont()->getPixelWidth(el->getText(), 0, pos - curent_pos);
+ if (currentPos + el->getTextLength() > pos) {
+ width += el->getFont()->getPixelWidth(el->getText(), 0, pos - currentPos);
return width;
}
else {
width += el->getWidth();
}
- curent_pos += el->getTextLength();
+ currentPos += el->getTextLength();
}
return width;
}
@@ 207,7 207,7 @@ namespace gui
UTF8 TextLine::getText(unsigned int pos) const
{
UTF8 text;
- for (auto &label : elements_to_show_in_line) {
+ for (auto &label : lineContent) {
if (label->getFont() == nullptr) {
continue;
}
@@ 219,7 219,7 @@ namespace gui
void TextLine::erase()
{
- for (auto &el : elements_to_show_in_line) {
+ for (auto &el : lineContent) {
if (el->parent != nullptr) {
auto p = el->parent;
p->erase(el);
@@ 234,28 234,28 @@ namespace gui
p->removeWidget(underline);
}
- elements_to_show_in_line.clear();
+ lineContent.clear();
}
- void TextLine::alignH(Alignment line_align, Length parent_length) const
+ void TextLine::alignH(Alignment lineAlign, Length parentLength) const
{
- Position xOffset = line_align.calculateHAlignment(parent_length, getWidth());
+ Position xOffset = lineAlign.calculateHAlignment(parentLength, getWidth());
if (xOffset >= 0) {
if (underline != nullptr && drawUnderlineMode == UnderlineDrawMode::Concurrent)
underline->setPosition(underline->getPosition(Axis::X) + xOffset, Axis::X);
- for (auto &el : elements_to_show_in_line) {
- auto scoped_disown = ScopedParentDisown(el);
+ for (auto &el : lineContent) {
+ auto scopedDisown = ScopedParentDisown(el);
el->setPosition(el->getPosition(Axis::X) + xOffset, Axis::X);
}
}
}
- void TextLine::alignV(Alignment line_align, Length parent_length, Length lines_height)
+ void TextLine::alignV(Alignment lineAlign, Length parentLength, Length linesHeight)
{
- Position yOffset = line_align.calculateVAlignment(parent_length, lines_height);
+ Position yOffset = lineAlign.calculateVAlignment(parentLength, linesHeight);
if (yOffset >= 0 && yOffset != storedYOffset) {
@@ 265,22 265,22 @@ namespace gui
if (underline != nullptr)
underline->setPosition(underline->getPosition(Axis::Y) + yOffset, Axis::Y);
- for (auto &el : elements_to_show_in_line) {
- auto scoped_disown = ScopedParentDisown(el);
+ for (auto &el : lineContent) {
+ auto scopedDisown = ScopedParentDisown(el);
el->setPosition(el->getPosition(Axis::Y) + yOffset, Axis::Y);
}
}
}
- void TextLine::createUnderline(unsigned int width, unsigned int init_height)
+ void TextLine::createUnderline(unsigned int width, unsigned int initHeight)
{
if (drawUnderline) {
- underline = new Rect(nullptr, 0, 0, max_width, init_height);
+ underline = new Rect(nullptr, 0, 0, maxWidth, initHeight);
underline->setEdges(RectangleEdge::Bottom);
if (drawUnderlineMode == UnderlineDrawMode::WholeLine) {
- height_used = std::max(height_used, (Length)init_height);
+ heightUsed = std::max(heightUsed, (Length)initHeight);
}
}
}
M module-gui/gui/widgets/TextLine.hpp => module-gui/gui/widgets/TextLine.hpp +15 -17
@@ 12,8 12,6 @@
namespace gui
{
- class TextCursor;
-
enum class UnderlineDrawMode
{
WholeLine,
@@ 23,11 21,11 @@ namespace gui
/// 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;
+ unsigned int shownLetterCount = 0;
+ Length widthUsed = 0;
+ Length heightUsed = 0;
+ Length maxWidth = 0;
+ std::list<Label *> lineContent;
Rect *underline = nullptr;
bool drawUnderline = false;
UnderlineDrawMode drawUnderlineMode = UnderlineDrawMode::Concurrent;
@@ 43,7 41,7 @@ namespace gui
/// 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(TextLine &&) noexcept;
TextLine(BlockCursor &cursor,
unsigned int max_width,
@@ 65,23 63,23 @@ namespace gui
/// number of letters in Whole TextLines
[[nodiscard]] unsigned int length() const
{
- return number_letters_shown;
+ return shownLetterCount;
}
/// count of elements in whole TextLine
[[nodiscard]] unsigned int count() const
{
- return elements_to_show_in_line.size();
+ return lineContent.size();
}
[[nodiscard]] Length width() const
{
- return width_used;
+ return widthUsed;
}
[[nodiscard]] Length height() const
{
- return height_used;
+ return heightUsed;
}
[[nodiscard]] TextBlock::End getEnd() const
@@ 94,10 92,10 @@ namespace gui
return lineEnd;
}
- const Item *getElement(unsigned int pos) const
+ [[nodiscard]] const Item *getElement(unsigned int pos) const
{
unsigned int local_pos = 0;
- for (auto &el : elements_to_show_in_line) {
+ for (auto &el : lineContent) {
local_pos += el->getTextLength();
if (local_pos >= pos) {
return el;
@@ 106,9 104,9 @@ namespace gui
return nullptr;
}
- int32_t getX() const
+ [[nodiscard]] int32_t getX() const
{
- return elements_to_show_in_line.front()->area().pos(Axis::X);
+ return lineContent.front()->area().pos(Axis::X);
}
void setPosition(const short &x, const short &y);
@@ 121,6 119,6 @@ namespace gui
/// 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;
+ [[nodiscard]] auto getText(unsigned int pos) const -> UTF8;
};
} // namespace gui
M module-gui/gui/widgets/TextLineCursor.cpp => module-gui/gui/widgets/TextLineCursor.cpp +79 -0
@@ 2,3 2,82 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "TextLineCursor.hpp"
+#include "Text.hpp"
+#include "log/log.hpp"
+
+#define debug_text_cursor(...)
+// #define debug_text_cursor(...) LOG_DEBUG(__VA_ARGS__)
+
+gui::TextLineCursor::TextLineCursor(gui::Text *parent, unsigned int pos, unsigned int block)
+ : TextCursor(parent, pos, block)
+{}
+
+auto gui::TextLineCursor::moveCursor(gui::NavigationDirection direction) -> gui::TextCursor::Move
+{
+ debug_text_cursor("Before move cursor: screen pos: %d block: %d pos: %d %s",
+ pos_on_screen,
+ getBlockNr(),
+ BlockCursor::getPosition(),
+ atBegin() ? "at begin" : "middle");
+
+ if (!checkDocument()) {
+ return Move::Error;
+ }
+
+ auto [selectedLine, selectedLineCursorPos, selectedLineNr] = getSelectedLine();
+
+ /// up - corner case
+ if ((checkNpos() || (direction == NavigationDirection::UP && selectedLineNr == 0))) {
+ return Move::Start;
+ }
+
+ /// down - corner case
+ if ((checkNpos() || (direction == NavigationDirection::DOWN && selectedLineNr == text->lines->size() - 1))) {
+ return Move::End;
+ }
+
+ if (direction == NavigationDirection::UP) {
+
+ auto previousLine = text->lines->getLine(selectedLineNr - 1);
+ auto previousLineEndAddition = previousLine->getEnd() == TextBlock::End::Newline ? 1 : 0;
+
+ auto previousLineMoveCount = previousLine->length() > selectedLineCursorPos
+ ? previousLine->length() - previousLineEndAddition - selectedLineCursorPos
+ : 0;
+
+ auto moveCount = selectedLineCursorPos + previousLineEndAddition + previousLineMoveCount;
+
+ TextCursor::moveCursor(NavigationDirection::LEFT, moveCount);
+
+ debug_text_cursor("After move cursor: screen pos: %d block: %d pos: %d %s",
+ pos_on_screen,
+ getBlockNr(),
+ BlockCursor::getPosition(),
+ atBegin() ? "at begin" : "middle");
+
+ return Move::Up;
+ }
+
+ if (direction == NavigationDirection::DOWN) {
+
+ auto nextLine = text->lines->getLine(selectedLineNr + 1);
+ auto nextLineEndAddition = nextLine->getEnd() == TextBlock::End::Newline ? 1 : 0;
+
+ auto nextLineMoveCount = nextLine->length() > selectedLineCursorPos ? selectedLineCursorPos
+ : nextLine->length() - nextLineEndAddition;
+
+ auto moveCount = (selectedLine->length() - selectedLineCursorPos) + nextLineMoveCount;
+
+ TextCursor::moveCursor(NavigationDirection::RIGHT, moveCount);
+
+ debug_text_cursor("After move cursor: screen pos: %d block: %d pos: %d %s",
+ pos_on_screen,
+ getBlockNr(),
+ BlockCursor::getPosition(),
+ atBegin() ? "at begin" : "middle");
+
+ return Move::Down;
+ }
+
+ return TextCursor::moveCursor(direction);
+}
M module-gui/gui/widgets/TextLineCursor.hpp => module-gui/gui/widgets/TextLineCursor.hpp +9 -23
@@ 7,31 7,17 @@
namespace gui
{
+ class Text;
+ class TextDocument;
+
class TextLineCursor : public TextCursor
{
+ protected:
public:
- using TextCursor::TextCursor;
-
- uint32_t getScreenLine() const
- {
- return line;
- }
-
- auto moveCursor(NavigationDirection direction) -> Move
- {
- Move movement = TextCursor::moveCursor(direction);
+ explicit TextLineCursor(gui::Text *parent, unsigned int pos = text::npos, unsigned int block = text::npos);
+ TextLineCursor() = delete;
- if (movement == Move::Down) {
- line++;
- }
- else if (movement == Move::Up) {
- line--;
- }
-
- return movement;
- }
-
- private:
- uint32_t line = 0;
+ auto moveCursor(NavigationDirection direction) -> Move override;
};
-} // namespace gui>
\ No newline at end of file
+
+} // namespace gui
M module-gui/test/test-catch-text/test-gui-Text.cpp => module-gui/test/test-catch-text/test-gui-Text.cpp +2 -2
@@ 49,7 49,7 @@ namespace gui
class TestText : public Text
{
public:
- unsigned int linesSize()
+ [[nodiscard]] unsigned int linesSize()
{
return lines->get().size();
}
@@ 60,7 60,7 @@ namespace gui
return;
}
- auto &linesGet()
+ [[nodiscard]] auto &linesGet()
{
return lines->get();
}
M module-gui/test/test-catch-text/test-gui-TextLineCursor.cpp => module-gui/test/test-catch-text/test-gui-TextLineCursor.cpp +177 -44
@@ 7,66 7,199 @@
#include <mock/buildTextDocument.hpp>
#include <module-gui/gui/widgets/Text.hpp>
#include <mock/multi-line-string.hpp>
+#include "Font.hpp"
+#include "InitializedFontManager.hpp"
+
+namespace gui
+{
+ class TestText : public Text
+ {
+ public:
+ [[nodiscard]] unsigned int linesSize()
+ {
+ return lines->get().size();
+ }
+
+ [[nodiscard]] auto &linesGet()
+ {
+ return lines->get();
+ }
+
+ auto moveCursor(NavigationDirection direction, unsigned int n)
+ {
+ cursor->TextCursor::moveCursor(direction, n);
+ }
+
+ [[nodiscard]] auto getSelectedLine()
+ {
+ return cursor->getSelectedLine();
+ }
+ };
+} // namespace gui
// To be corrected with Text scrolling
-TEST_CASE("TextLineCursor", "[.]")
+TEST_CASE("TextLineCursor")
{
using namespace gui;
- SECTION("default")
+ std::string testStringShortLine = "Test Line "; // 10 sings
+ std::string testStringNormalLine = "Test Normal No Line "; // 20 sings
+ std::string testStringLongLine = "Test Long Long Long Long Line "; // 30 sings
+
+ SECTION("Default position three lines text")
{
- auto texts = mockup::lineStrings(3);
- auto [document, font] = mockup::buildMultilineTestDocument(texts);
- gui::Text text;
- text.setText(std::make_unique<gui::TextDocument>(document));
- auto cursor = new gui::TextLineCursor(&text);
+ mockup::fontManager();
+ auto text = new gui::TestText();
+ text->setMaximumSize(400, 200);
- REQUIRE(cursor->getScreenLine() == 0);
- }
+ text->addText(TextBlock(testStringShortLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringNormalLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringLongLine, Font(27).raw(), TextBlock::End::None));
- SECTION("move cursor down")
- {
- auto texts = mockup::lineStrings(3);
- auto [document, font] = mockup::buildMultilineTestDocument(texts);
-
- gui::Text text;
- text.setText(std::make_unique<gui::TextDocument>(document));
- auto cursor = new gui::TextLineCursor(&text);
- cursor->moveCursor(NavigationDirection::DOWN);
- REQUIRE(cursor->getScreenLine() == 1);
+ auto [selectedLine, selectedLineCursorPos, selectedLineNr] = text->getSelectedLine();
+
+ REQUIRE(selectedLine->getText(0).c_str() == testStringLongLine);
+ REQUIRE(selectedLineCursorPos == testStringLongLine.length());
+ REQUIRE(selectedLineNr == 2);
}
- SECTION("move cursor right")
+ SECTION("Movement three lines text test -> short|normal|long")
{
- auto texts = mockup::lineStrings(3);
- auto [document, font] = mockup::buildMultilineTestDocument(texts);
+ mockup::fontManager();
+ auto text = new gui::TestText();
+ text->setMaximumSize(400, 200);
- gui::Text text;
- text.setText(std::make_unique<gui::TextDocument>(document));
- auto cursor = new gui::TextLineCursor(&text);
- cursor->moveCursor(NavigationDirection::RIGHT);
- REQUIRE(cursor->getScreenLine() == 0);
+ std::tuple<const TextLine *, unsigned int, unsigned int> selectedLine;
- for (size_t i = 0; i < document.getBlocks().front().length(); i++) {
- cursor->moveCursor(NavigationDirection::RIGHT);
- }
- REQUIRE(cursor->getScreenLine() == 1);
+ text->addText(TextBlock(testStringShortLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringNormalLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringLongLine, Font(27).raw(), TextBlock::End::None));
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine);
+ REQUIRE(std::get<1>(selectedLine) == testStringLongLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move Down nothing should happen as cursor is at bottom and right end
+ text->moveCursor(gui::NavigationDirection::DOWN, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine);
+ REQUIRE(std::get<1>(selectedLine) == testStringLongLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move Right nothing should happen as cursor is at bottom and right end
+ text->moveCursor(gui::NavigationDirection::RIGHT, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine);
+ REQUIRE(std::get<1>(selectedLine) == testStringLongLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move Left to line center, line should not change but position should
+ text->moveCursor(gui::NavigationDirection::LEFT, (testStringLongLine.length() / 2));
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine);
+ REQUIRE(std::get<1>(selectedLine) == (testStringLongLine.length() / 2));
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move Up line should change and cursor should be at corresponding position as it fits in upper line
+ text->moveCursor(gui::NavigationDirection::UP, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringNormalLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == (testStringLongLine.length() / 2));
+ REQUIRE(std::get<2>(selectedLine) == 1);
+
+ // Move Up line should change and cursor should be at its end as corresponding position does not fit
+ text->moveCursor(gui::NavigationDirection::UP, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringShortLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringShortLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 0);
+
+ // Move Up line should not change and cursor should not change as it is first line
+ text->moveCursor(gui::NavigationDirection::UP, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringShortLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringShortLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 0);
+
+ // Move Left to line and text beginning
+ text->moveCursor(gui::NavigationDirection::LEFT, testStringShortLine.length());
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringShortLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == 0);
+ REQUIRE(std::get<2>(selectedLine) == 0);
+
+ // Move two times Down line should change and cursor should be at its beginning
+ text->moveCursor(gui::NavigationDirection::DOWN, 2);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine);
+ REQUIRE(std::get<1>(selectedLine) == 0);
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move one time Left line should change and cursor should be at its end
+ text->moveCursor(gui::NavigationDirection::LEFT, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringNormalLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringNormalLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 1);
}
- SECTION("move cursor to end")
+ SECTION("Movement three lines text test -> long|short|normal")
{
- auto texts = mockup::lineStrings(3);
- auto [document, font] = mockup::buildMultilineTestDocument(texts);
+ mockup::fontManager();
+ auto text = new gui::TestText();
+ text->setMaximumSize(400, 200);
- gui::Text text;
- text.setText(std::make_unique<gui::TextDocument>(document));
- auto cursor = new gui::TextLineCursor(&text);
- cursor->moveCursor(NavigationDirection::RIGHT);
- REQUIRE(cursor->getScreenLine() == 0);
+ std::tuple<const TextLine *, unsigned int, unsigned int> selectedLine;
- for (size_t i = 0; i < document.getText().length(); i++) {
- cursor->moveCursor(NavigationDirection::RIGHT);
- }
- REQUIRE(cursor->getScreenLine() == 2);
+ text->addText(TextBlock(testStringLongLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringShortLine, Font(27).raw(), TextBlock::End::Newline));
+ text->addText(TextBlock(testStringNormalLine, Font(27).raw(), TextBlock::End::None));
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringNormalLine);
+ REQUIRE(std::get<1>(selectedLine) == testStringNormalLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 2);
+
+ // Move Up two times, line should change and cursor should be at short line length position
+ text->moveCursor(gui::NavigationDirection::UP, 2);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringShortLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 0);
+
+ // Move Right three times, only cursor pos should change
+ text->moveCursor(gui::NavigationDirection::RIGHT, 3);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringLongLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringShortLine.length() + 3);
+ REQUIRE(std::get<2>(selectedLine) == 0);
+
+ // Move Down one time, line should change and cursor should be at short line end as corresponding do not fit
+ text->moveCursor(gui::NavigationDirection::DOWN, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringShortLine + "\n");
+ REQUIRE(std::get<1>(selectedLine) == testStringShortLine.length());
+ REQUIRE(std::get<2>(selectedLine) == 1);
+
+ // Move Right one time, line should change and cursor should be at next line beginning
+ text->moveCursor(gui::NavigationDirection::RIGHT, 1);
+
+ selectedLine = text->getSelectedLine();
+ REQUIRE(std::get<0>(selectedLine)->getText(0).c_str() == testStringNormalLine);
+ REQUIRE(std::get<1>(selectedLine) == 0);
+ REQUIRE(std::get<2>(selectedLine) == 2);
}
-}>
\ No newline at end of file
+}