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 0470f26f9..2fe2eb318 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::make_unique<Decoration>(indicator); +} + +std::unique_ptr<IDecorationList> DecorationListCreate() { +	return std::make_unique<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 e0373a752..70f52c054 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -121,6 +121,8 @@ Document::Document(int options) :  	perLineData[ldMargin] = std::make_unique<LineAnnotation>();  	perLineData[ldAnnotation] = std::make_unique<LineAnnotation>(); +	decorations = DecorationListCreate(); +  	cb.SetPerLine(this);  } @@ -2239,11 +2241,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, @@ -2286,9 +2288,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 2ff17f8d2..4e3ac3a21 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 2bafa43dd..37a6a9f9e 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 d00d2cb98..80e32d1ae 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);  	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;  				}  			} @@ -7383,15 +7383,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: @@ -7399,16 +7399,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 3bb0f7e28..20a2ddda3 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);  	}  }  | 
