diff options
| -rw-r--r-- | include/Scintilla.h | 26 | ||||
| -rw-r--r-- | include/Scintilla.iface | 21 | ||||
| -rw-r--r-- | src/Editor.cxx | 60 | ||||
| -rw-r--r-- | src/LexCPP.cxx | 9 | ||||
| -rw-r--r-- | src/LineMarker.cxx | 144 | 
5 files changed, 248 insertions, 12 deletions
| diff --git a/include/Scintilla.h b/include/Scintilla.h index 636428e1f..ac7614804 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -88,6 +88,24 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,  #define SC_MARK_ARROWDOWN 6  #define SC_MARK_MINUS 7  #define SC_MARK_PLUS 8 +#define SC_MARK_VLINE 9 +#define SC_MARK_LCORNER 10 +#define SC_MARK_TCORNER 11 +#define SC_MARK_BOXPLUS 12 +#define SC_MARK_BOXPLUSCONNECTED 13 +#define SC_MARK_BOXMINUS 14 +#define SC_MARK_BOXMINUSCONNECTED 15 +#define SC_MARK_LCORNERCURVE 16 +#define SC_MARK_TCORNERCURVE 17 +#define SC_MARK_CIRCLEPLUS 18 +#define SC_MARK_CIRCLEPLUSCONNECTED 19 +#define SC_MARK_CIRCLEMINUS 20 +#define SC_MARK_CIRCLEMINUSCONNECTED 21 +#define SC_MARKNUM_FOLDEREND 25 +#define SC_MARKNUM_FOLDEROPENMID 26 +#define SC_MARKNUM_FOLDERMIDTAIL 27 +#define SC_MARKNUM_FOLDERTAIL 28 +#define SC_MARKNUM_FOLDERSUB 29  #define SC_MARKNUM_FOLDER 30  #define SC_MARKNUM_FOLDEROPEN 31  #define SCI_MARKERDEFINE 2040 @@ -553,7 +571,13 @@ struct SCNotification {  	int listType;	// SCN_USERLISTSELECTION  }; -#define SC_MASK_FOLDERS ((1<<SC_MARKNUM_FOLDER) | (1<<SC_MARKNUM_FOLDEROPEN)) +#define SC_MASK_FOLDERS ((1<<SC_MARKNUM_FOLDER) | \ +	(1<<SC_MARKNUM_FOLDEROPEN) | \ +	(1<<SC_MARKNUM_FOLDERSUB) | \ +	(1<<SC_MARKNUM_FOLDERTAIL) | \ +	(1<<SC_MARKNUM_FOLDERMIDTAIL) | \ +	(1<<SC_MARKNUM_FOLDEROPENMID) | \ +	(1<<SC_MARKNUM_FOLDEREND))  // Deprecation section listing all API features that are deprecated and will  // will be removed completely in a future version. diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 5c486aad3..abfe7aba9 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -210,6 +210,27 @@ val SC_MARK_ARROWDOWN=6  val SC_MARK_MINUS=7  val SC_MARK_PLUS=8 +# Shapes used for outlining column +val SC_MARK_VLINE=9 +val SC_MARK_LCORNER=10 +val SC_MARK_TCORNER=11 +val SC_MARK_BOXPLUS=12 +val SC_MARK_BOXPLUSCONNECTED=13 +val SC_MARK_BOXMINUS=14 +val SC_MARK_BOXMINUSCONNECTED=15 +val SC_MARK_LCORNERCURVE=16 +val SC_MARK_TCORNERCURVE=17 +val SC_MARK_CIRCLEPLUS=18 +val SC_MARK_CIRCLEPLUSCONNECTED=19 +val SC_MARK_CIRCLEMINUS=20 +val SC_MARK_CIRCLEMINUSCONNECTED=21 + +# Markers used for outlining column +val SC_MARKNUM_FOLDEREND=25 +val SC_MARKNUM_FOLDEROPENMID=26 +val SC_MARKNUM_FOLDERMIDTAIL=27 +val SC_MARKNUM_FOLDERTAIL=28 +val SC_MARKNUM_FOLDERSUB=29  val SC_MARKNUM_FOLDER=30  val SC_MARKNUM_FOLDEROPEN=31 diff --git a/src/Editor.cxx b/src/Editor.cxx index 4c95b29b8..436b20795 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -712,14 +712,64 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {  			int visibleLine = topLine;  			int line = cs.DocFromDisplay(visibleLine);  			int yposScreen = 0; - +			bool needWhiteClosure = false; +			int level = pdoc->GetLevel(line); +			if (level & SC_FOLDLEVELWHITEFLAG) { +				int lineBack = line-1; +				while ((lineBack > 0) && (level & SC_FOLDLEVELWHITEFLAG)) { +					lineBack--; +					level = pdoc->GetLevel(lineBack); +				} +				if (!(level & SC_FOLDLEVELHEADERFLAG) && (lineBack > 0)) { +					int levelPrev = pdoc->GetLevel(lineBack-1); +					if ((level & SC_FOLDLEVELNUMBERMASK) < (levelPrev & SC_FOLDLEVELNUMBERMASK)) +						needWhiteClosure = true; +				} +			}  			while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) { +				level = pdoc->GetLevel(line); +				int levelNext = pdoc->GetLevel(line+1);  				int marks = pdoc->GetMark(line); -				if (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) { +				int levelNum = level & SC_FOLDLEVELNUMBERMASK; +				int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK; +				if (level & SC_FOLDLEVELHEADERFLAG) {  					if (cs.GetExpanded(line)) { -						marks |= 1 << SC_MARKNUM_FOLDEROPEN; +						if (levelNum == SC_FOLDLEVELBASE) +							marks |= 1 << SC_MARKNUM_FOLDEROPEN; +						else  +							marks |= 1 << SC_MARKNUM_FOLDEROPENMID; +					} else { +						if (levelNum == SC_FOLDLEVELBASE) +							marks |= 1 << SC_MARKNUM_FOLDER; +						else +							marks |= 1 << SC_MARKNUM_FOLDEREND; +					} +					needWhiteClosure = false; +				} else if (level & SC_FOLDLEVELWHITEFLAG) { +					if (needWhiteClosure) { +						if (levelNext & SC_FOLDLEVELWHITEFLAG) { +							marks |= 1 << SC_MARKNUM_FOLDERSUB; +						} else if (levelNum > SC_FOLDLEVELBASE) { +							marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; +						} else { +							marks |= 1 << SC_MARKNUM_FOLDERTAIL; +							needWhiteClosure = false; +						} +					} else if (levelNum > SC_FOLDLEVELBASE) { +						marks |= 1 << SC_MARKNUM_FOLDERSUB; +					} +				} else if (levelNum > SC_FOLDLEVELBASE) { +					if (levelNextNum < levelNum) { +						if (levelNext & SC_FOLDLEVELWHITEFLAG) { +							marks |= 1 << SC_MARKNUM_FOLDERSUB; +							needWhiteClosure = true; +						} else if (levelNextNum > SC_FOLDLEVELBASE) { +							marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; +						} else { +							marks |= 1 << SC_MARKNUM_FOLDERTAIL; +						}  					} else { -						marks |= 1 << SC_MARKNUM_FOLDER; +						marks |= 1 << SC_MARKNUM_FOLDERSUB;  					}  				}  				marks &= vs.ms[margin].mask; @@ -748,8 +798,6 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {  				if (marks) {  					for (int markBit = 0; (markBit < 32) && marks; markBit++) {  						if (marks & 1) { -							rcMarker.top++; -							rcMarker.bottom--;  							vs.markers[markBit].Draw(surface, rcMarker);  						}  						marks >>= 1; diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx index 512581807..c5e55df8b 100644 --- a/src/LexCPP.cxx +++ b/src/LexCPP.cxx @@ -332,15 +332,20 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle, WordLis                              Accessor &styler) {  	bool foldComment = styler.GetPropertyInt("fold.comment");  	bool foldCompact = styler.GetPropertyInt("fold.compact", 1); -	unsigned int lengthDoc = startPos + length; +	unsigned int endPos = startPos + length;  	int visibleChars = 0;  	int lineCurrent = styler.GetLine(startPos); +	// Move back one line in case deletion wrecked current line fold state +	if (lineCurrent > 0) { +		lineCurrent--; +		startPos = styler.LineStart(lineCurrent); +	}  	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;  	int levelCurrent = levelPrev;  	char chNext = styler[startPos];  	int styleNext = styler.StyleAt(startPos);  	int style = initStyle; -	for (unsigned int i = startPos; i < lengthDoc; i++) { +	for (unsigned int i = startPos; i < endPos; i++) {  		char ch = chNext;  		chNext = styler.SafeGetCharAt(i + 1);  		int stylePrev = style; diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx index 90c2710ce..7414b5b4d 100644 --- a/src/LineMarker.cxx +++ b/src/LineMarker.cxx @@ -10,13 +10,47 @@  #include "Scintilla.h"  #include "LineMarker.h" -void LineMarker::Draw(Surface *surface, PRectangle &rc) { +static void DrawBox(Surface *surface, int centreX, int centreY, int armSize) { +	surface->MoveTo(centreX - armSize, centreY - armSize); +	surface->LineTo(centreX + armSize, centreY - armSize); +	surface->LineTo(centreX + armSize, centreY + armSize); +	surface->LineTo(centreX - armSize, centreY + armSize); +	surface->LineTo(centreX - armSize, centreY - armSize); +} + +static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, Colour fore, Colour back) { +	PRectangle rcCircle; +	rcCircle.left = centreX - armSize; +	rcCircle.top = centreY - armSize; +	rcCircle.right = centreX + armSize + 1; +	rcCircle.bottom = centreY + armSize + 1; +	surface->Ellipse(rcCircle, back, fore); +} + +static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize) { +	surface->MoveTo(centreX - armSize + 2, centreY); +	surface->LineTo(centreX + armSize - 2 + 1, centreY); +	surface->MoveTo(centreX, centreY - armSize + 2); +	surface->LineTo(centreX, centreY + armSize - 2 + 1); +} + +static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize) { +	surface->MoveTo(centreX - armSize + 2, centreY); +	surface->LineTo(centreX + armSize - 2 + 1, centreY); +} + +void LineMarker::Draw(Surface *surface, PRectangle &rcWhole) { +	// Restrict most shapes a bit +	PRectangle rc = rcWhole; +	rc.top++; +	rc.bottom--;  	int minDim = Platform::Minimum(rc.Width(), rc.Height());  	minDim--;	// Ensure does not go beyond edge  	int centreX = (rc.right + rc.left) / 2;  	int centreY = (rc.bottom + rc.top) / 2;  	int dimOn2 = minDim / 2;  	int dimOn4 = minDim / 4; +	int armSize = dimOn2-2;  	if (rc.Width() > (rc.Height() * 2)) {  		// Wide column is line number so move to left to try to avoid overlapping number  		centreX = rc.left + dimOn2 + 1; @@ -52,7 +86,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {                   		fore.allocated, back.allocated);  	} else if (markType == SC_MARK_PLUS) { -		int armSize = dimOn2-2;  		Point pts[] = {      		Point(centreX - armSize, centreY - 1),      		Point(centreX - 1, centreY - 1), @@ -71,7 +104,6 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {                   		fore.allocated, back.allocated);  	} else if (markType == SC_MARK_MINUS) { -		int armSize = dimOn2-2;  		Point pts[] = {      		Point(centreX - armSize, centreY - 1),      		Point(centreX + armSize, centreY -1), @@ -88,8 +120,114 @@ void LineMarker::Draw(Surface *surface, PRectangle &rc) {  		rcSmall.right = rc.right - 1;  		rcSmall.bottom = rc.bottom - 2;  		surface->RectangleDraw(rcSmall, fore.allocated, back.allocated); +		  	} else if (markType == SC_MARK_EMPTY) {  		// An invisible marker so don't draw anything +		 +	} else if (markType == SC_MARK_VLINE) { +		surface->PenColour(back.allocated); +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, rcWhole.bottom); +		 +	} else if (markType == SC_MARK_LCORNER) { +		surface->PenColour(back.allocated); +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, rc.top + dimOn2); +		surface->LineTo(rc.right - 2, rc.top + dimOn2); +		 +	} else if (markType == SC_MARK_TCORNER) { +		surface->PenColour(back.allocated); +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, rcWhole.bottom); +		surface->MoveTo(centreX, rc.top + dimOn2); +		surface->LineTo(rc.right - 2, rc.top + dimOn2); +		 +	} else if (markType == SC_MARK_LCORNERCURVE) { +		surface->PenColour(back.allocated); +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, rc.top + dimOn2-3); +		surface->LineTo(centreX+3, rc.top + dimOn2); +		surface->LineTo(rc.right - 1, rc.top + dimOn2); +		 +	} else if (markType == SC_MARK_TCORNERCURVE) { +		surface->PenColour(back.allocated); +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, rcWhole.bottom); +		 +		surface->MoveTo(centreX, rc.top + dimOn2-3); +		surface->LineTo(centreX+3, rc.top + dimOn2); +		surface->LineTo(rc.right - 1, rc.top + dimOn2); +		 +	} else if (markType == SC_MARK_BOXPLUS) { +		surface->PenColour(back.allocated); +		DrawBox(surface, centreX, centreY, armSize); +		DrawPlus(surface, centreX, centreY, armSize); +		 +	} else if (markType == SC_MARK_BOXPLUSCONNECTED) { +		surface->PenColour(back.allocated); +		DrawBox(surface, centreX, centreY, armSize); +		DrawPlus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, centreY - armSize); +		 +	} else if (markType == SC_MARK_BOXMINUS) { +		surface->PenColour(back.allocated); +		DrawBox(surface, centreX, centreY, armSize); +		DrawMinus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +	} else if (markType == SC_MARK_BOXMINUSCONNECTED) { +		surface->PenColour(back.allocated); +		DrawBox(surface, centreX, centreY, armSize); +		DrawMinus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, centreY - armSize); +		 +	} else if (markType == SC_MARK_CIRCLEPLUS) { +		DrawCircle(surface, centreX, centreY, armSize, fore.allocated, back.allocated); +		surface->PenColour(back.allocated); +		DrawPlus(surface, centreX, centreY, armSize); +		 +	} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { +		DrawCircle(surface, centreX, centreY, armSize, fore.allocated, back.allocated); +		surface->PenColour(back.allocated); +		DrawPlus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, centreY - armSize); +		 +	} else if (markType == SC_MARK_CIRCLEMINUS) { +		DrawCircle(surface, centreX, centreY, armSize, fore.allocated, back.allocated); +		surface->PenColour(back.allocated); +		DrawMinus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +	} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { +		DrawCircle(surface, centreX, centreY, armSize, fore.allocated, back.allocated); +		surface->PenColour(back.allocated); +		DrawMinus(surface, centreX, centreY, armSize); +		 +		surface->MoveTo(centreX, centreY + armSize); +		surface->LineTo(centreX, rcWhole.bottom); +		 +		surface->MoveTo(centreX, rcWhole.top); +		surface->LineTo(centreX, centreY - armSize); +		  	} else { // SC_MARK_SHORTARROW  		Point pts[] = {  			Point(centreX, centreY + dimOn2), | 
