diff --git a/include/document/document.h b/include/document/document.h index aaf0931..57da95a 100644 --- a/include/document/document.h +++ b/include/document/document.h @@ -106,6 +106,11 @@ class Document : public IDocument { explicit Document() {} void updateCursor(); + + GlyphContainer::GlyphList GetCharactersList(); + Glyph::GlyphPtr GetNextCharInDocument(Glyph::GlyphPtr& glyph); + Glyph::GlyphPtr GetPreviousCharInDocument(Glyph::GlyphPtr& glyph); + friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { diff --git a/src/compositor/simple_compositor/simple_compositor.cpp b/src/compositor/simple_compositor/simple_compositor.cpp index c631848..1436cf0 100644 --- a/src/compositor/simple_compositor/simple_compositor.cpp +++ b/src/compositor/simple_compositor/simple_compositor.cpp @@ -1,9 +1,9 @@ +#include "compositor/simple_compositor/simple_compositor.h" + #include #include -#include "compositor/simple_compositor/simple_compositor.h" BOOST_CLASS_EXPORT_IMPLEMENT(SimpleCompositor) - #include #include "document/glyphs/row.h" @@ -36,7 +36,7 @@ void SimpleCompositor::Compose() { } GlyphContainer::GlyphList SimpleCompositor::CutAllCharacters() { - GlyphContainer::GlyphList charactersList; + Glyph::GlyphList charactersList; for (Page::PagePtr page = document->GetFirstPage(); page != nullptr; page = document->GetNextPage(page)) { diff --git a/src/document/document.cpp b/src/document/document.cpp index f6ebea0..4648628 100644 --- a/src/document/document.cpp +++ b/src/document/document.cpp @@ -69,6 +69,17 @@ void Document::Insert(Glyph::GlyphPtr& glyph) { void Document::Remove(Glyph::GlyphPtr& glyph) { assert(glyph != nullptr && "Cannot remove glyph by nullptr"); + + if (glyph == selectedGlyph) { + selectedGlyph = GetPreviousCharInDocument(selectedGlyph); + if (selectedGlyph == nullptr) { + // if there is no character in document, set cursor into the first + // row + selectedGlyph = + this->GetFirstPage()->GetFirstGlyph()->GetFirstGlyph(); + } + } + auto it = std::find(pages.begin(), pages.end(), glyph); if (it != pages.end()) { if (it != pages.begin()) pages.erase(it); @@ -158,4 +169,49 @@ void Document::CutGlyphs(const Point& start, const Point& end) { for (auto& glyph : selectedGlyphs) { this->Remove(glyph); } +} + +GlyphContainer::GlyphList Document::GetCharactersList() { + Glyph::GlyphList charactersList; + + for (Page::PagePtr page = this->GetFirstPage(); page != nullptr; + page = this->GetNextPage(page)) { + for (Glyph::GlyphPtr column = page->GetFirstGlyph(); column != nullptr; + column = page->GetNextGlyph(column)) { + for (Glyph::GlyphPtr row = column->GetFirstGlyph(); row != nullptr; + row = column->GetNextGlyph(row)) { + for (Glyph::GlyphPtr character = row->GetFirstGlyph(); + character != nullptr;) { + charactersList.push_back(character); + character = row->GetNextGlyph(character); + } + } + } + } + + return charactersList; +} + +Glyph::GlyphPtr Document::GetNextCharInDocument(Glyph::GlyphPtr& glyph) { + Glyph::GlyphList charactersList = GetCharactersList(); + auto it = std::find(charactersList.begin(), charactersList.end(), glyph); + + it++; + if (it == charactersList.end()) { + return nullptr; + } else { + return *it; + } +} + +Glyph::GlyphPtr Document::GetPreviousCharInDocument(Glyph::GlyphPtr& glyph) { + Glyph::GlyphList charactersList = GetCharactersList(); + auto it = std::find(charactersList.begin(), charactersList.end(), glyph); + + if (it == charactersList.begin()) { + return nullptr; + } else { + it--; + return *it; + } } \ No newline at end of file diff --git a/test/model/text_editor_tests.cpp b/test/model/text_editor_tests.cpp index c388468..3062b74 100644 --- a/test/model/text_editor_tests.cpp +++ b/test/model/text_editor_tests.cpp @@ -2068,9 +2068,7 @@ TEST(Document_Cursor1, Glyph::GlyphPtr selectedGlyph = d->GetSelectedGlyph(); Row::RowPtr selectedRow = std::dynamic_pointer_cast(selectedGlyph); - EXPECT_TRUE(selectedRow != nullptr); - EXPECT_TRUE(selectedRow == - d->GetFirstPage()->GetFirstGlyph()->GetFirstGlyph()); + EXPECT_EQ(selectedRow, d->GetFirstPage()->GetFirstGlyph()->GetFirstGlyph()); std::cout << *selectedRow << std::endl; } @@ -2085,7 +2083,41 @@ TEST(Document_Cursor2, Glyph::GlyphPtr selectedGlyph = d->GetSelectedGlyph(); Character::CharPtr selectedChar = std::dynamic_pointer_cast(selectedGlyph); - EXPECT_TRUE(selectedChar != nullptr); - EXPECT_TRUE(selectedChar == c1Ptr); + EXPECT_EQ(selectedChar, c1Ptr); std::cout << *selectedChar << std::endl; +} + +TEST(Document_Cursor3, + DocumentCursorAfterInsertedChar_WhenCalles_ReturnGlyphNextToCursor) { + auto d = std::make_shared(std::make_shared()); + + Character c1 = Character(0, 0, 10, 10, 'A'); + Glyph::GlyphPtr c1Ptr = std::make_shared(c1); + d->Insert(c1Ptr); + d->Remove(c1Ptr); + + Glyph::GlyphPtr selectedGlyph = d->GetSelectedGlyph(); + Row::RowPtr selectedRow = std::dynamic_pointer_cast(selectedGlyph); + EXPECT_EQ(selectedRow, d->GetFirstPage()->GetFirstGlyph()->GetFirstGlyph()); + std::cout << *selectedRow << std::endl; +} + +TEST(Document_Cursor4, + DocumentCursorAfterInsertedChar_WhenCalles_ReturnGlyphNextToCursor) { + auto d = std::make_shared(std::make_shared()); + + Character c1 = Character(0, 0, 10, 10, 'A'); + Glyph::GlyphPtr c1Ptr = std::make_shared(c1); + Character c2 = Character(13, 5, 10, 10, 'B'); + Glyph::GlyphPtr c2Ptr = std::make_shared(c2); + d->Insert(c1Ptr); + d->Insert(c2Ptr); + + d->Remove(c2Ptr); + + Glyph::GlyphPtr selectedGlyph = d->GetSelectedGlyph(); + Character::CharPtr selectedChar = + std::dynamic_pointer_cast(selectedGlyph); + EXPECT_EQ(selectedChar, c1Ptr); + // std::cout << *selectedChar << std::endl; } \ No newline at end of file