aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/Scintilla.h26
-rw-r--r--include/Scintilla.iface21
-rw-r--r--src/Editor.cxx60
-rw-r--r--src/LexCPP.cxx9
-rw-r--r--src/LineMarker.cxx144
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),