diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ContractionState.cxx | 32 | ||||
| -rw-r--r-- | src/ContractionState.h | 8 | ||||
| -rw-r--r-- | src/EditModel.cxx | 1 | ||||
| -rw-r--r-- | src/EditModel.h | 1 | ||||
| -rw-r--r-- | src/EditView.cxx | 139 | ||||
| -rw-r--r-- | src/EditView.h | 4 | ||||
| -rw-r--r-- | src/Editor.cxx | 10 | 
7 files changed, 179 insertions, 16 deletions
| diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx index 80f79de29..41627c173 100644 --- a/src/ContractionState.cxx +++ b/src/ContractionState.cxx @@ -6,6 +6,7 @@  // The License.txt file describes the conditions under which this software may be distributed.  #include <string.h> +#include <assert.h>  #include <stdexcept>  #include <algorithm> @@ -16,13 +17,14 @@  #include "SplitVector.h"  #include "Partitioning.h"  #include "RunStyles.h" +#include "SparseVector.h"  #include "ContractionState.h"  #ifdef SCI_NAMESPACE  using namespace Scintilla;  #endif -ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) { +ContractionState::ContractionState() : visible(0), expanded(0), heights(0), foldDisplayTexts(0), displayLines(0), linesInDocument(1) {  	//InsertLine(0);  } @@ -35,6 +37,7 @@ void ContractionState::EnsureData() {  		visible = new RunStyles();  		expanded = new RunStyles();  		heights = new RunStyles(); +		foldDisplayTexts = new SparseVector<const char *>();  		displayLines = new Partitioning(4);  		InsertLines(0, linesInDocument);  	} @@ -47,6 +50,8 @@ void ContractionState::Clear() {  	expanded = 0;  	delete heights;  	heights = 0; +	delete foldDisplayTexts; +	foldDisplayTexts = 0;  	delete displayLines;  	displayLines = 0;  	linesInDocument = 1; @@ -108,6 +113,8 @@ void ContractionState::InsertLine(int lineDoc) {  		expanded->SetValueAt(lineDoc, 1);  		heights->InsertSpace(lineDoc, 1);  		heights->SetValueAt(lineDoc, 1); +		foldDisplayTexts->InsertSpace(lineDoc, 1); +		foldDisplayTexts->SetValueAt(lineDoc, NULL);  		int lineDisplay = DisplayFromDoc(lineDoc);  		displayLines->InsertPartition(lineDoc, lineDisplay);  		displayLines->InsertText(lineDoc, 1); @@ -132,6 +139,7 @@ void ContractionState::DeleteLine(int lineDoc) {  		visible->DeleteRange(lineDoc, 1);  		expanded->DeleteRange(lineDoc, 1);  		heights->DeleteRange(lineDoc, 1); +		foldDisplayTexts->DeletePosition(lineDoc);  	}  } @@ -184,6 +192,24 @@ bool ContractionState::HiddenLines() const {  	}  } +const char *ContractionState::GetFoldDisplayText(int lineDoc) const { +	Check(); +	return foldDisplayTexts->ValueAt(lineDoc); +} + +bool ContractionState::SetFoldDisplayText(int lineDoc, const char *text) { +	EnsureData(); +	const char *foldText = foldDisplayTexts->ValueAt(lineDoc); +	if (!foldText || 0 != strcmp(text, foldText)) { +		foldDisplayTexts->SetValueAt(lineDoc, text); +		Check(); +		return true; +	} else { +		Check(); +		return false; +	} +} +  bool ContractionState::GetExpanded(int lineDoc) const {  	if (OneToOne()) {  		return true; @@ -209,6 +235,10 @@ bool ContractionState::SetExpanded(int lineDoc, bool isExpanded) {  	}  } +bool ContractionState::GetFoldDisplayTextShown(int lineDoc) const { +	return !GetExpanded(lineDoc) && GetFoldDisplayText(lineDoc); +} +  int ContractionState::ContractedNext(int lineDocStart) const {  	if (OneToOne()) {  		return -1; diff --git a/src/ContractionState.h b/src/ContractionState.h index 96cbf0763..622696939 100644 --- a/src/ContractionState.h +++ b/src/ContractionState.h @@ -12,6 +12,9 @@  namespace Scintilla {  #endif +template<class T> +class SparseVector; +  /**   */  class ContractionState { @@ -19,6 +22,7 @@ class ContractionState {  	RunStyles *visible;  	RunStyles *expanded;  	RunStyles *heights; +	SparseVector<const char *> *foldDisplayTexts;  	Partitioning *displayLines;  	int linesInDocument; @@ -51,8 +55,12 @@ public:  	bool SetVisible(int lineDocStart, int lineDocEnd, bool isVisible);  	bool HiddenLines() const; +	const char *GetFoldDisplayText(int lineDoc) const; +	bool SetFoldDisplayText(int lineDoc, const char *text); +  	bool GetExpanded(int lineDoc) const;  	bool SetExpanded(int lineDoc, bool isExpanded); +	bool GetFoldDisplayTextShown(int lineDoc) const;  	int ContractedNext(int lineDocStart) const;  	int GetHeight(int lineDoc) const; diff --git a/src/EditModel.cxx b/src/EditModel.cxx index 35903c6b8..0f64e07f9 100644 --- a/src/EditModel.cxx +++ b/src/EditModel.cxx @@ -65,6 +65,7 @@ EditModel::EditModel() {  	primarySelection = true;  	imeInteraction = imeWindowed;  	foldFlags = 0; +	foldDisplayTextStyle = SC_FOLDDISPLAYTEXT_HIDDEN;  	hotspot = Range(invalidPosition);  	hoverIndicatorPos = invalidPosition;  	wrapWidth = LineLayout::wrapWidthInfinite; diff --git a/src/EditModel.h b/src/EditModel.h index 021bf6770..847fd728d 100644 --- a/src/EditModel.h +++ b/src/EditModel.h @@ -45,6 +45,7 @@ public:  	enum IMEInteraction { imeWindowed, imeInline } imeInteraction;  	int foldFlags; +	int foldDisplayTextStyle;  	ContractionState cs;  	// Hotspot support  	Range hotspot; diff --git a/src/EditView.cxx b/src/EditView.cxx index 04eea0ea5..8ffc1bcff 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -879,7 +879,7 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle  	int alpha = SC_ALPHA_NOALPHA;  	if (!hideSelection) {  		int posAfterLineEnd = model.pdoc->LineStart(line + 1); -		eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; +		eolInSelection = (lastSubLine == true) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0;  		alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;  	} @@ -948,25 +948,15 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle  		}  	} -	// Fill the remainder of the line  	rcSegment.left = rcSegment.right;  	if (rcSegment.left < rcLine.left)  		rcSegment.left = rcLine.left;  	rcSegment.right = rcLine.right; -	if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { -		surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); -	} else { -		if (background.isSet) { -			surface->FillRectangle(rcSegment, background); -		} else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { -			surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); -		} else { -			surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back); -		} -		if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { -			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); -		} +	bool fillRemainder = !lastSubLine || model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || !model.cs.GetFoldDisplayTextShown(line); +	if (fillRemainder) { +		// Fill the remainder of the line +		FillLineRemainder(surface, model, vsDraw, ll, line, rcSegment, subLine);  	}  	bool drawWrapMarkEnd = false; @@ -1071,6 +1061,95 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS  	}  } +void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +							  int line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase) { +	const bool lastSubLine = subLine == (ll->lines - 1); +	if (!lastSubLine) +		return; + +	if ((model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN) || !model.cs.GetFoldDisplayTextShown(line)) +		return; + +	PRectangle rcSegment = rcLine; +	const char *foldDisplayText = model.cs.GetFoldDisplayText(line); +	const int lengthFoldDisplayText = static_cast<int>(strlen(foldDisplayText)); +	FontAlias fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; +	const int widthFoldDisplayText = static_cast<int>(surface->WidthText(fontText, foldDisplayText, lengthFoldDisplayText)); + +	int eolInSelection = 0; +	int alpha = SC_ALPHA_NOALPHA; +	if (!hideSelection) { +		int posAfterLineEnd = model.pdoc->LineStart(line + 1); +		eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; +		alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; +	} + +	const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; +	XYPOSITION virtualSpace = model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)) * spaceWidth; +	rcSegment.left = xStart + static_cast<XYPOSITION>(ll->positions[ll->numCharsInLine] - subLineStart) + spaceWidth + virtualSpace; +	rcSegment.right = rcSegment.left + static_cast<XYPOSITION>(widthFoldDisplayText); + +	ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); +	FontAlias textFont = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; +	ColourDesired textFore = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].fore; +	if (eolInSelection && (vsDraw.selColours.fore.isSet)) { +		textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; +	} +	ColourDesired textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, +											false, STYLE_FOLDDISPLAYTEXT, -1); + +	if (model.trackLineWidth) { +		if (rcSegment.right + 1> lineWidthMaxSeen) { +			// Fold display text border drawn on rcSegment.right with width 1 is the last visble object of the line +			lineWidthMaxSeen = static_cast<int>(rcSegment.right + 1); +		} +	} + +	if ((phasesDraw != phasesOne) && (phase & drawBack)) { +		surface->FillRectangle(rcSegment, textBack); + +		// Fill Remainder of the line +		PRectangle rcRemainder = rcSegment; +		rcRemainder.left = rcRemainder.right + 1; +		if (rcRemainder.left < rcLine.left) +			rcRemainder.left = rcLine.left; +		rcRemainder.right = rcLine.right; +		FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); +	} + +	if (phase & drawText) { +		if (phasesDraw != phasesOne) { +			surface->DrawTextTransparent(rcSegment, textFont, +				rcSegment.top + vsDraw.maxAscent, foldDisplayText, +				lengthFoldDisplayText, textFore); +		} else { +			surface->DrawTextNoClip(rcSegment, textFont, +				rcSegment.top + vsDraw.maxAscent, foldDisplayText, +				lengthFoldDisplayText, textFore, textBack); +		} +	} + +	if (phase & drawIndicatorsFore) { +		if (model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_BOXED) { +			surface->PenColour(textFore); +			surface->MoveTo(static_cast<int>(rcSegment.left), static_cast<int>(rcSegment.top)); +			surface->LineTo(static_cast<int>(rcSegment.left), static_cast<int>(rcSegment.bottom)); +			surface->MoveTo(static_cast<int>(rcSegment.right), static_cast<int>(rcSegment.top)); +			surface->LineTo(static_cast<int>(rcSegment.right), static_cast<int>(rcSegment.bottom)); +			surface->MoveTo(static_cast<int>(rcSegment.left), static_cast<int>(rcSegment.top)); +			surface->LineTo(static_cast<int>(rcSegment.right), static_cast<int>(rcSegment.top)); +			surface->MoveTo(static_cast<int>(rcSegment.left), static_cast<int>(rcSegment.bottom - 1)); +			surface->LineTo(static_cast<int>(rcSegment.right), static_cast<int>(rcSegment.bottom - 1)); +		} +	} + +	if (phase & drawSelectionTranslucent) { +		if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && alpha != SC_ALPHA_NOALPHA) { +			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); +		} +	} +} +  static bool AnnotationBoxedOrIndented(int annotationVisible) {  	return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED;  } @@ -1789,6 +1868,8 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl  			xStart, subLine, subLineStart, background);  	} +	DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); +  	if (!hideSelection && (phase & drawSelectionTranslucent)) {  		DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart);  	} @@ -2002,6 +2083,34 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan  	}  } +void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +	int line, PRectangle rcArea, int subLine) { +		int eolInSelection = 0; +		int alpha = SC_ALPHA_NOALPHA; +		if (!hideSelection) { +			int posAfterLineEnd = model.pdoc->LineStart(line + 1); +			eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; +			alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; +		} + +		ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + +		if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { +			surface->FillRectangle(rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); +		} else { +			if (background.isSet) { +				surface->FillRectangle(rcArea, background); +			} else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { +				surface->FillRectangle(rcArea, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); +			} else { +				surface->FillRectangle(rcArea, vsDraw.styles[STYLE_DEFAULT].back); +			} +			if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { +				SimpleAlphaRectangle(surface, rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); +			} +		} +} +  // Space (3 space characters) between line numbers and text when printing.  #define lineNumberPrintSpace "   " diff --git a/src/EditView.h b/src/EditView.h index dcfa352f4..83dd8bb1f 100644 --- a/src/EditView.h +++ b/src/EditView.h @@ -124,6 +124,8 @@ public:  	void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine,  		int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,  		ColourOptional background); +	void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +		int line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase);  	void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,  		int line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);  	void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int line, @@ -140,6 +142,8 @@ public:  		int lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);  	void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient,  		const ViewStyle &vsDraw); +	void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +		int line, PRectangle rcArea, int subLine);  	long FormatRange(bool draw, Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure,  		const EditModel &model, const ViewStyle &vs);  }; diff --git a/src/Editor.cxx b/src/Editor.cxx index 558b642b0..43d28a8c0 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -7059,6 +7059,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {  		Redraw();  		break; +	case SCI_TOGGLEFOLDSHOWTEXT: +		cs.SetFoldDisplayText(static_cast<int>(wParam), CharPtrFromSPtr(lParam)); +		FoldLine(static_cast<int>(wParam), SC_FOLDACTION_TOGGLE); +		break; + +	case SCI_FOLDDISPLAYTEXTSETSTYLE: +		foldDisplayTextStyle = static_cast<int>(wParam); +		Redraw(); +		break; +  	case SCI_TOGGLEFOLD:  		FoldLine(static_cast<int>(wParam), SC_FOLDACTION_TOGGLE);  		break; | 
