M module-gui/gui/widgets/Text.cpp => module-gui/gui/widgets/Text.cpp +19 -0
@@ 602,4 602,23 @@ namespace gui
}
}
+ TextBackup Text::backupText() const
+ {
+ return TextBackup{std::list<TextBlock>(document->getBlocks().begin(), document->getBlocks().end()),
+ cursor->getPosOnScreen()};
+ }
+
+ void Text::restoreFrom(const TextBackup &backup)
+ {
+ setText(std::make_unique<TextDocument>(backup.document));
+
+ // If backup cursor position greater than new text length do not move cursor.
+ if (getText().length() > backup.cursorPos) {
+ auto cursorPosDiff = getText().length() - backup.cursorPos;
+
+ // Move cursor to backup position from end of document.
+ cursor->TextCursor::moveCursor(NavigationDirection::LEFT, cursorPosDiff);
+ }
+ };
+
} /* namespace gui */
M module-gui/gui/widgets/Text.hpp => module-gui/gui/widgets/Text.hpp +10 -0
@@ 25,6 25,12 @@
namespace gui
{
+ struct TextBackup
+ {
+ TextDocument document;
+ unsigned int cursorPos;
+ };
+
class Lines;
/// @brief Widget that holds multiple lines of text.
@@ 107,6 113,10 @@ namespace gui
void setUnderline(const bool val);
virtual void setText(const UTF8 &text);
void setText(std::unique_ptr<TextDocument> &&document);
+
+ TextBackup backupText() const;
+ void restoreFrom(const TextBackup &backup);
+
void setTextChangedCallback(TextChangedCallback &&callback);
void addText(const UTF8 &text);
M module-gui/gui/widgets/TextCursor.cpp => module-gui/gui/widgets/TextCursor.cpp +23 -2
@@ 32,6 32,20 @@ namespace gui
pos_on_screen = document->getText().length();
}
+ TextCursor::Move TextCursor::moveCursor(NavigationDirection direction, unsigned int n)
+ {
+ auto ret = TextCursor::Move::Start;
+
+ for (unsigned int i = 0; i < n; i++) {
+ ret = moveCursor(direction);
+
+ if (ret == Move::Start || ret == Move::End || ret == Move::Error) {
+ break;
+ }
+ }
+ return ret;
+ }
+
TextCursor::Move TextCursor::moveCursor(NavigationDirection direction)
{
debug_text_cursor("Before move cursor: screen pos: %d block: %d pos: %d %s",
@@ 67,6 81,8 @@ namespace gui
if (nr != getBlockNr() && checkCurrentBlockNoNewLine()) {
operator--();
}
+
+ return Move::Left;
}
if (direction == NavigationDirection::RIGHT) {
@@ 79,6 95,8 @@ namespace gui
if (nr != getBlockNr() && checkPreviousBlockNoNewLine()) {
operator++();
}
+
+ return Move::Right;
}
debug_text_cursor("After move cursor: screen pos: %d block: %d pos: %d %s",
@@ 180,6 198,7 @@ namespace gui
moveCursor(NavigationDirection::LEFT);
BlockCursor::removeChar();
}
+
} // namespace gui
const char *c_str(enum gui::TextCursor::Move what)
@@ 193,8 212,10 @@ const char *c_str(enum gui::TextCursor::Move what)
return "Up";
case gui::TextCursor::Move::Down:
return "Down";
- case gui::TextCursor::Move::InLine:
- return "InLine";
+ case gui::TextCursor::Move::Left:
+ return "Left";
+ case gui::TextCursor::Move::Right:
+ return "Right";
case gui::TextCursor::Move::Error:
return "Error";
}
M module-gui/gui/widgets/TextCursor.hpp => module-gui/gui/widgets/TextCursor.hpp +4 -3
@@ 30,8 30,8 @@ namespace gui
End, /// we hit end of document
Up, /// we moved up a line
Down, /// we moved down a line
-
- InLine, /// no action - passed movement by `0` or we are just somewhere comfty in visible range
+ Left, /// we moved left inline
+ Right, /// we moved right inline
Error, /// error - now not implemented
};
@@ 46,6 46,7 @@ namespace gui
/// - with_update - updates position in parent ( if false not - means we handled it already with i.e. addChar or
/// 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...
@@ 60,7 61,7 @@ namespace gui
TextCursor &operator<<(TextBlock);
void removeChar();
- auto getPosOnScreen() const
+ [[nodiscard]] auto getPosOnScreen() const
{
return pos_on_screen;
}
M module-gui/test/test-catch-text/test-gui-Text.cpp => module-gui/test/test-catch-text/test-gui-Text.cpp +69 -0
@@ 67,6 67,16 @@ namespace gui
{
return mode;
}
+
+ auto moveCursor(NavigationDirection direction, unsigned int n)
+ {
+ cursor->TextCursor::moveCursor(direction, n);
+ }
+
+ [[nodiscard]] auto getCursorPos()
+ {
+ return cursor->getPosOnScreen();
+ }
};
} // namespace gui
@@ 241,3 251,62 @@ TEST_CASE("handle text block - moved cursor to end")
text.addText(newline);
REQUIRE(text.getText() == test_text);
}
+
+TEST_CASE("Text backup and restore tests")
+{
+ std::string testStringOneLine = "Test String ";
+ std::string testStringTwoLines = "Test String 1 \n Test String 2";
+ std::string overwriteTestString = "Overwrite test String";
+
+ SECTION("Backup one line text with moved cursor, overwrite text and restore")
+ {
+ mockup::fontManager();
+ auto text = new gui::TestText();
+
+ text->addText(testStringOneLine);
+
+ unsigned int cursorMoveN = 2;
+ text->moveCursor(gui::NavigationDirection::LEFT, cursorMoveN);
+
+ auto backup = text->backupText();
+
+ REQUIRE(backup.document.getText() == text->getText());
+ REQUIRE(backup.document.getText().length() == text->getText().length());
+ REQUIRE(backup.cursorPos == text->getCursorPos());
+
+ text->setText(overwriteTestString);
+
+ REQUIRE(text->getText() != testStringOneLine);
+
+ text->restoreFrom(backup);
+
+ REQUIRE(text->getText() == testStringOneLine);
+ REQUIRE(text->getCursorPos() == testStringOneLine.length() - cursorMoveN);
+ }
+
+ SECTION("Backup two line text with moved cursor, overwrite text and restore")
+ {
+ mockup::fontManager();
+ auto text = new gui::TestText();
+
+ text->addText(testStringTwoLines);
+
+ unsigned int cursorMoveN = 10;
+ text->moveCursor(gui::NavigationDirection::LEFT, cursorMoveN);
+
+ auto backup = text->backupText();
+
+ REQUIRE(backup.document.getText() == text->getText());
+ REQUIRE(backup.document.getText().length() == text->getText().length());
+ REQUIRE(backup.cursorPos == text->getCursorPos());
+
+ text->setText(overwriteTestString);
+
+ REQUIRE(text->getText() != testStringOneLine);
+
+ text->restoreFrom(backup);
+
+ REQUIRE(text->getText() == testStringTwoLines);
+ REQUIRE(text->getCursorPos() == testStringTwoLines.length() - cursorMoveN);
+ }
+}