diff options
-rw-r--r-- | src/Decoration.cxx | 111 | ||||
-rw-r--r-- | src/Decoration.h | 84 | ||||
-rw-r--r-- | src/Document.cxx | 10 | ||||
-rw-r--r-- | src/Document.h | 2 | ||||
-rw-r--r-- | src/EditView.cxx | 20 | ||||
-rw-r--r-- | src/Editor.cxx | 28 | ||||
-rw-r--r-- | src/PositionCache.cxx | 6 | ||||
-rw-r--r-- | test/unit/testDecoration.cxx | 60 |
8 files changed, 201 insertions, 120 deletions
diff --git a/src/Decoration.cxx b/src/Decoration.cxx index da763741b..6a3269214 100644 --- a/src/Decoration.cxx +++ b/src/Decoration.cxx @@ -26,15 +26,97 @@ using namespace Scintilla; -Decoration::Decoration(int indicator_) : indicator(indicator_) { -} +namespace { -Decoration::~Decoration() { -} +class Decoration : public IDecoration { + int indicator; +public: + RunStyles<Sci::Position, int> rs; -bool Decoration::Empty() const { - return (rs.Runs() == 1) && (rs.AllSameAs(0)); -} + explicit Decoration(int indicator_) : indicator(indicator_) { + } + ~Decoration() { + } + + bool Empty() const override { + return (rs.Runs() == 1) && (rs.AllSameAs(0)); + } + int Indicator() const override { + return indicator; + } + Sci::Position Length() const override { + return rs.Length(); + } + int ValueAt(Sci::Position position) const override { + return rs.ValueAt(static_cast<Sci::Position>(position)); + } + Sci::Position StartRun(Sci::Position position) const override { + return rs.StartRun(static_cast<Sci::Position>(position)); + } + Sci::Position EndRun(Sci::Position position) const override { + return rs.EndRun(static_cast<Sci::Position>(position)); + } + void SetValueAt(Sci::Position position, int value) override { + rs.SetValueAt(static_cast<Sci::Position>(position), value); + } + void InsertSpace(Sci::Position position, Sci::Position insertLength) override { + rs.InsertSpace(static_cast<Sci::Position>(position), static_cast<Sci::Position>(insertLength)); + } + Sci::Position Runs() const override { + return rs.Runs(); + } +}; + +class DecorationList : public IDecorationList { + int currentIndicator; + int currentValue; + Decoration *current; // Cached so FillRange doesn't have to search for each call. + Sci::Position lengthDocument; + // Ordered by indicator + std::vector<std::unique_ptr<Decoration>> decorationList; + std::vector<const IDecoration*> decorationView; // Read-only view of decorationList + bool clickNotified; + + Decoration *DecorationFromIndicator(int indicator); + Decoration *Create(int indicator, Sci::Position length); + void Delete(int indicator); + void DeleteAnyEmpty(); + void SetView(); +public: + + DecorationList(); + ~DecorationList(); + + const std::vector<const IDecoration*> &View() const override { + return decorationView; + } + + void SetCurrentIndicator(int indicator) override; + int GetCurrentIndicator() const override { return currentIndicator; } + + void SetCurrentValue(int value) override; + int GetCurrentValue() const override { return currentValue; } + + // Returns changed=true if some values may have changed + FillResult<Sci::Position> FillRange(Sci::Position position, int value, Sci::Position fillLength) override; + + void InsertSpace(Sci::Position position, Sci::Position insertLength) override; + void DeleteRange(Sci::Position position, Sci::Position deleteLength) override; + + void DeleteLexerDecorations() override; + + int AllOnFor(Sci::Position position) const override; + int ValueAt(int indicator, Sci::Position position) override; + Sci::Position Start(int indicator, Sci::Position position) override; + Sci::Position End(int indicator, Sci::Position position) override; + + bool ClickNotified() const override { + return clickNotified; + } + void SetClickNotified(bool notified) override { + clickNotified = notified; + } +}; DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(nullptr), lengthDocument(0), clickNotified(false) { @@ -190,3 +272,18 @@ Sci::Position DecorationList::End(int indicator, Sci::Position position) { } return 0; } + +} + +namespace Scintilla { + +std::unique_ptr<IDecoration> DecorationCreate(int indicator) { + return std::unique_ptr<Decoration>(new Decoration(indicator)); +} + +std::unique_ptr<IDecorationList> DecorationListCreate() { + return std::unique_ptr<DecorationList>(new DecorationList()); +} + +} + diff --git a/src/Decoration.h b/src/Decoration.h index 86397fde1..76f00ec55 100644 --- a/src/Decoration.h +++ b/src/Decoration.h @@ -9,68 +9,50 @@ namespace Scintilla { -class Decoration { - int indicator; +class IDecoration { public: - RunStyles<Sci::Position, int> rs; - - explicit Decoration(int indicator_); - ~Decoration(); - - bool Empty() const; - int Indicator() const { - return indicator; - } + virtual ~IDecoration() {} + virtual bool Empty() const = 0; + virtual int Indicator() const = 0; + virtual Sci::Position Length() const = 0; + virtual int ValueAt(Sci::Position position) const = 0; + virtual Sci::Position StartRun(Sci::Position position) const = 0; + virtual Sci::Position EndRun(Sci::Position position) const = 0; + virtual void SetValueAt(Sci::Position position, int value) = 0; + virtual void InsertSpace(Sci::Position position, Sci::Position insertLength) = 0; + virtual Sci::Position Runs() const = 0; }; -class DecorationList { - int currentIndicator; - int currentValue; - Decoration *current; // Cached so FillRange doesn't have to search for each call. - Sci::Position lengthDocument; - // Ordered by indicator - std::vector<std::unique_ptr<Decoration>> decorationList; - std::vector<const Decoration*> decorationView; // Read-only view of decorationList - bool clickNotified; - - Decoration *DecorationFromIndicator(int indicator); - Decoration *Create(int indicator, Sci::Position length); - void Delete(int indicator); - void DeleteAnyEmpty(); - void SetView(); +class IDecorationList { public: + virtual ~IDecorationList() {} - DecorationList(); - ~DecorationList(); - - const std::vector<const Decoration*> &View() const { return decorationView; } + virtual const std::vector<const IDecoration*> &View() const =0; - void SetCurrentIndicator(int indicator); - int GetCurrentIndicator() const { return currentIndicator; } + virtual void SetCurrentIndicator(int indicator) = 0; + virtual int GetCurrentIndicator() const = 0; - void SetCurrentValue(int value); - int GetCurrentValue() const { return currentValue; } + virtual void SetCurrentValue(int value) = 0; + virtual int GetCurrentValue() const = 0; // Returns with changed=true if some values may have changed - FillResult<Sci::Position> FillRange(Sci::Position position, int value, Sci::Position fillLength); - - void InsertSpace(Sci::Position position, Sci::Position insertLength); - void DeleteRange(Sci::Position position, Sci::Position deleteLength); - - void DeleteLexerDecorations(); + virtual FillResult<Sci::Position> FillRange(Sci::Position position, int value, Sci::Position fillLength) = 0; + virtual void InsertSpace(Sci::Position position, Sci::Position insertLength) = 0; + virtual void DeleteRange(Sci::Position position, Sci::Position deleteLength) = 0; + virtual void DeleteLexerDecorations() = 0; + + virtual int AllOnFor(Sci::Position position) const = 0; + virtual int ValueAt(int indicator, Sci::Position position) = 0; + virtual Sci::Position Start(int indicator, Sci::Position position) = 0; + virtual Sci::Position End(int indicator, Sci::Position position) = 0; + + virtual bool ClickNotified() const = 0; + virtual void SetClickNotified(bool notified) = 0; +}; - int AllOnFor(Sci::Position position) const; - int ValueAt(int indicator, Sci::Position position); - Sci::Position Start(int indicator, Sci::Position position); - Sci::Position End(int indicator, Sci::Position position); +std::unique_ptr<IDecoration> DecorationCreate(int indicator); - bool ClickNotified() const { - return clickNotified; - } - void SetClickNotified(bool notified) { - clickNotified = notified; - } -}; +std::unique_ptr<IDecorationList> DecorationListCreate(); } diff --git a/src/Document.cxx b/src/Document.cxx index edb60a26a..04a83d7ff 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -125,6 +125,8 @@ Document::Document(int options) : perLineData[ldMargin].reset(new LineAnnotation()); perLineData[ldAnnotation].reset(new LineAnnotation()); + decorations = DecorationListCreate(); + cb.SetPerLine(this); } @@ -2243,11 +2245,11 @@ void Document::IncrementStyleClock() { } void SCI_METHOD Document::DecorationSetCurrentIndicator(int indicator) { - decorations.SetCurrentIndicator(indicator); + decorations->SetCurrentIndicator(indicator); } void SCI_METHOD Document::DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) { - const FillResult<Sci::Position> fr = decorations.FillRange( + const FillResult<Sci::Position> fr = decorations->FillRange( static_cast<Sci::Position>(position), value, static_cast<Sci::Position>(fillLength)); if (fr.changed) { const DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER, @@ -2290,9 +2292,9 @@ void Document::NotifySavePoint(bool atSavePoint) { void Document::NotifyModified(DocModification mh) { if (mh.modificationType & SC_MOD_INSERTTEXT) { - decorations.InsertSpace(mh.position, mh.length); + decorations->InsertSpace(mh.position, mh.length); } else if (mh.modificationType & SC_MOD_DELETETEXT) { - decorations.DeleteRange(mh.position, mh.length); + decorations->DeleteRange(mh.position, mh.length); } for (const WatcherWithUserData &watcher : watchers) { watcher.watcher->NotifyModified(this, mh, watcher.userData); diff --git a/src/Document.h b/src/Document.h index 5293fb25e..327422434 100644 --- a/src/Document.h +++ b/src/Document.h @@ -263,7 +263,7 @@ public: bool backspaceUnindents; double durationStyleOneLine; - DecorationList decorations; + std::unique_ptr<IDecorationList> decorations; Document(int options); // Deleted so Document objects can not be copied. diff --git a/src/EditView.cxx b/src/EditView.cxx index 7605ce839..d9ca751a0 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -1042,25 +1042,25 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS const Sci::Position lineStart = ll->LineStart(subLine); const Sci::Position posLineEnd = posLineStart + lineEnd; - for (const Decoration *deco : model.pdoc->decorations.View()) { + for (const IDecoration *deco : model.pdoc->decorations->View()) { if (under == vsDraw.indicators[deco->Indicator()].under) { Sci::Position startPos = posLineStart + lineStart; - if (!deco->rs.ValueAt(startPos)) { - startPos = deco->rs.EndRun(startPos); + if (!deco->ValueAt(startPos)) { + startPos = deco->EndRun(startPos); } - while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { - const Range rangeRun(deco->rs.StartRun(startPos), deco->rs.EndRun(startPos)); + while ((startPos < posLineEnd) && (deco->ValueAt(startPos))) { + const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos)); const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() && rangeRun.ContainsCharacter(hoverIndicatorPos); - const int value = deco->rs.ValueAt(startPos); + const int value = deco->ValueAt(startPos); const Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal; const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart, surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, drawState, value); startPos = endPos; - if (!deco->rs.ValueAt(startPos)) { - startPos = deco->rs.EndRun(startPos); + if (!deco->ValueAt(startPos)) { + startPos = deco->EndRun(startPos); } } } @@ -1660,8 +1660,8 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } if (vsDraw.indicatorsSetFore) { // At least one indicator sets the text colour so see if it applies to this segment - for (const Decoration *deco : model.pdoc->decorations.View()) { - const int indicatorValue = deco->rs.ValueAt(ts.start + posLineStart); + for (const IDecoration *deco : model.pdoc->decorations->View()) { + const int indicatorValue = deco->ValueAt(ts.start + posLineStart); if (indicatorValue) { const Indicator &indicator = vsDraw.indicators[deco->Indicator()]; const bool hover = indicator.IsDynamic() && diff --git a/src/Editor.cxx b/src/Editor.cxx index c324da787..27eb840ad 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -2109,7 +2109,7 @@ void Editor::ClearAll() { } void Editor::ClearDocumentStyle() { - pdoc->decorations.DeleteLexerDecorations(); + pdoc->decorations->DeleteLexerDecorations(); pdoc->StartStyling(0, '\377'); pdoc->SetStyleFor(pdoc->Length(), 0); pcs->ShowAll(); @@ -2394,10 +2394,10 @@ void Editor::NotifyPainted() { } void Editor::NotifyIndicatorClick(bool click, Sci::Position position, int modifiers) { - const int mask = pdoc->decorations.AllOnFor(position); - if ((click && mask) || pdoc->decorations.ClickNotified()) { + const int mask = pdoc->decorations->AllOnFor(position); + if ((click && mask) || pdoc->decorations->ClickNotified()) { SCNotification scn = {}; - pdoc->decorations.SetClickNotified(click); + pdoc->decorations->SetClickNotified(click); scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; scn.modifiers = modifiers; scn.position = position; @@ -4671,9 +4671,9 @@ void Editor::SetHoverIndicatorPosition(Sci::Position position) { if (!vs.indicatorsDynamic) return; if (position != INVALID_POSITION) { - for (const Decoration *deco : pdoc->decorations.View()) { + for (const IDecoration *deco : pdoc->decorations->View()) { if (vs.indicators[deco->Indicator()].IsDynamic()) { - if (pdoc->decorations.ValueAt(deco->Indicator(), position)) { + if (pdoc->decorations->ValueAt(deco->Indicator(), position)) { hoverIndicatorPos = position; } } @@ -7374,15 +7374,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { pdoc->DecorationSetCurrentIndicator(static_cast<int>(wParam)); break; case SCI_GETINDICATORCURRENT: - return pdoc->decorations.GetCurrentIndicator(); + return pdoc->decorations->GetCurrentIndicator(); case SCI_SETINDICATORVALUE: - pdoc->decorations.SetCurrentValue(static_cast<int>(wParam)); + pdoc->decorations->SetCurrentValue(static_cast<int>(wParam)); break; case SCI_GETINDICATORVALUE: - return pdoc->decorations.GetCurrentValue(); + return pdoc->decorations->GetCurrentValue(); case SCI_INDICATORFILLRANGE: - pdoc->DecorationFillRange(static_cast<int>(wParam), pdoc->decorations.GetCurrentValue(), static_cast<int>(lParam)); + pdoc->DecorationFillRange(static_cast<int>(wParam), pdoc->decorations->GetCurrentValue(), static_cast<int>(lParam)); break; case SCI_INDICATORCLEARRANGE: @@ -7390,16 +7390,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_INDICATORALLONFOR: - return pdoc->decorations.AllOnFor(static_cast<int>(wParam)); + return pdoc->decorations->AllOnFor(static_cast<int>(wParam)); case SCI_INDICATORVALUEAT: - return pdoc->decorations.ValueAt(static_cast<int>(wParam), static_cast<int>(lParam)); + return pdoc->decorations->ValueAt(static_cast<int>(wParam), static_cast<int>(lParam)); case SCI_INDICATORSTART: - return pdoc->decorations.Start(static_cast<int>(wParam), static_cast<int>(lParam)); + return pdoc->decorations->Start(static_cast<int>(wParam), static_cast<int>(lParam)); case SCI_INDICATOREND: - return pdoc->decorations.End(static_cast<int>(wParam), static_cast<int>(lParam)); + return pdoc->decorations->End(static_cast<int>(wParam), static_cast<int>(lParam)); case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index bf28223d5..2086b7190 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -470,12 +470,12 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin } } if (pvsDraw && pvsDraw->indicatorsSetFore) { - for (const Decoration *deco : pdoc->decorations.View()) { + for (const IDecoration *deco : pdoc->decorations->View()) { if (pvsDraw->indicators[deco->Indicator()].OverridesTextFore()) { - Sci::Position startPos = deco->rs.EndRun(posLineStart); + Sci::Position startPos = deco->EndRun(posLineStart); while (startPos < (posLineStart + lineRange.end)) { Insert(static_cast<int>(startPos - posLineStart)); - startPos = deco->rs.EndRun(startPos); + startPos = deco->EndRun(startPos); } } } diff --git a/test/unit/testDecoration.cxx b/test/unit/testDecoration.cxx index d2fbc7df2..b8e880c2c 100644 --- a/test/unit/testDecoration.cxx +++ b/test/unit/testDecoration.cxx @@ -26,27 +26,27 @@ using namespace Scintilla; TEST_CASE("Decoration") { - Decoration deco(indicator); + std::unique_ptr<IDecoration> deco = DecorationCreate(indicator); SECTION("HasCorrectIndicator") { - REQUIRE(indicator == deco.Indicator()); + REQUIRE(indicator == deco->Indicator()); } SECTION("IsEmptyInitially") { - REQUIRE(0 == deco.rs.Length()); - REQUIRE(1 == deco.rs.Runs()); - REQUIRE(deco.Empty()); + REQUIRE(0 == deco->Length()); + REQUIRE(1 == deco->Runs()); + REQUIRE(deco->Empty()); } SECTION("SimpleSpace") { - deco.rs.InsertSpace(0, 1); - REQUIRE(deco.Empty()); + deco->InsertSpace(0, 1); + REQUIRE(deco->Empty()); } SECTION("SimpleRun") { - deco.rs.InsertSpace(0, 1); - deco.rs.SetValueAt(0, 2); - REQUIRE(!deco.Empty()); + deco->InsertSpace(0, 1); + deco->SetValueAt(0, 2); + REQUIRE(!deco->Empty()); } } @@ -54,41 +54,41 @@ TEST_CASE("Decoration") { TEST_CASE("DecorationList") { - DecorationList decol; + std::unique_ptr<IDecorationList> decol = DecorationListCreate(); SECTION("HasCorrectIndicator") { - decol.SetCurrentIndicator(indicator); - REQUIRE(indicator == decol.GetCurrentIndicator()); + decol->SetCurrentIndicator(indicator); + REQUIRE(indicator == decol->GetCurrentIndicator()); } SECTION("HasCorrectCurrentValue") { const int value = 55; - decol.SetCurrentValue(value); - REQUIRE(value == decol.GetCurrentValue()); + decol->SetCurrentValue(value); + REQUIRE(value == decol->GetCurrentValue()); } SECTION("ExpandSetValues") { - decol.SetCurrentIndicator(indicator); - decol.InsertSpace(0, 9); + decol->SetCurrentIndicator(indicator); + decol->InsertSpace(0, 9); const int value = 59; - Sci::Position position = 4; - Sci::Position fillLength = 3; - auto fr = decol.FillRange(position, value, fillLength); + const Sci::Position position = 4; + const Sci::Position fillLength = 3; + auto fr = decol->FillRange(position, value, fillLength); REQUIRE(fr.changed); REQUIRE(fr.position == 4); REQUIRE(fr.fillLength == 3); - REQUIRE(decol.ValueAt(indicator, 5) == value); - REQUIRE(decol.AllOnFor(5) == (1 << indicator)); - REQUIRE(decol.Start(indicator, 5) == 4); - REQUIRE(decol.End(indicator, 5) == 7); + REQUIRE(decol->ValueAt(indicator, 5) == value); + REQUIRE(decol->AllOnFor(5) == (1 << indicator)); + REQUIRE(decol->Start(indicator, 5) == 4); + REQUIRE(decol->End(indicator, 5) == 7); const int indicatorB=6; - decol.SetCurrentIndicator(indicatorB); - fr = decol.FillRange(position, value, fillLength); + decol->SetCurrentIndicator(indicatorB); + fr = decol->FillRange(position, value, fillLength); REQUIRE(fr.changed); - REQUIRE(decol.AllOnFor(5) == ((1 << indicator) | (1 << indicatorB))); - decol.DeleteRange(5, 1); - REQUIRE(decol.Start(indicatorB, 5) == 4); - REQUIRE(decol.End(indicatorB, 5) == 6); + REQUIRE(decol->AllOnFor(5) == ((1 << indicator) | (1 << indicatorB))); + decol->DeleteRange(5, 1); + REQUIRE(decol->Start(indicatorB, 5) == 4); + REQUIRE(decol->End(indicatorB, 5) == 6); } } |