aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2000-06-21 02:59:25 +0000
committernyamatongwe <devnull@localhost>2000-06-21 02:59:25 +0000
commit6d3878dca546f21822b087d70bea23db9437c0a9 (patch)
treedce2610a6c578021e13c36d3e4e2c9f4a2eb6dfc
parent507a9f0685923e0b06597f717daa3b362db1b6ef (diff)
downloadscintilla-mirror-6d3878dca546f21822b087d70bea23db9437c0a9.tar.gz
Added indentation guide API.
View whitespace has setting to only see outside indentation. Indentation guide highlight.
-rw-r--r--include/Scintilla.h9
-rw-r--r--include/Scintilla.iface28
-rw-r--r--src/Editor.cxx138
-rw-r--r--src/Editor.h11
-rw-r--r--src/ScintillaBase.cxx2
-rw-r--r--src/ViewStyle.cxx4
-rw-r--r--src/ViewStyle.h4
-rw-r--r--win32/PlatWin.cxx2
-rw-r--r--win32/ScintillaWin.cxx16
9 files changed, 165 insertions, 49 deletions
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 7e31d5db1..9f42fef0f 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -51,6 +51,10 @@ void Scintilla_RegisterClasses(HINSTANCE hInstance);
#define SC_UNDOCOLLECT_NONE 0
#define SC_UNDOCOLLECT_AUTOSTART 1
+#define SCWS_INVISIBLE 0
+#define SCWS_VISIBLEALWAYS 1
+#define SCWS_VISIBLEAFTERINDENT 2
+
#define SCI_GETVIEWWS SCI_START + 20
#define SCI_SETVIEWWS SCI_START + 21
#define SCI_GOTOLINE SCI_START + 24
@@ -120,6 +124,7 @@ void Scintilla_RegisterClasses(HINSTANCE hInstance);
#define STYLE_BRACELIGHT 34
#define STYLE_BRACEBAD 35
#define STYLE_CONTROLCHAR 36
+#define STYLE_INDENTGUIDE 37
#define STYLE_MAX 127
#define SC_CHARSET_ANSI 0
@@ -217,6 +222,10 @@ void Scintilla_RegisterClasses(HINSTANCE hInstance);
#define SCI_SETHSCROLLBAR SCI_START + 130
#define SCI_GETHSCROLLBAR SCI_START + 131
+#define SCI_SETINDENTATIONGUIDES SCI_START + 132
+#define SCI_GETINDENTATIONGUIDES SCI_START + 133
+#define SCI_SETHIGHLIGHTGUIDE SCI_START + 134
+#define SCI_GETHIGHLIGHTGUIDE SCI_START + 135
#define SCI_CALLTIPSHOW SCI_START + 200
#define SCI_CALLTIPCANCEL SCI_START + 201
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index 8aac3fdc8..f3eec65df 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -108,11 +108,16 @@ fun int MarkerLineFromHandle=2017(int handle,)
# Delete a marker.
fun void MarkerDeleteHandle=2018(int handle,)
+val SCWS_INVISIBLE=0
+val SCWS_VISIBLEALWAYS=1
+val SCWS_VISIBLEAFTERINDENT=2
+
# Are white space characters currently visible?
-get bool GetViewWS=2020(,)
+# Returns one of SCWS_* constants.
+get int GetViewWS=2020(,)
-# Make white space characters visible or invisible.
-set void SetViewWS=2021(bool viewWS,)
+# Make white space characters invisible, always visible or visible outside indentation.
+set void SetViewWS=2021(int viewWS,)
# Set caret to start of a line and ensure it is visible.
fun void GotoLine=2024(int line,)
@@ -439,12 +444,25 @@ get position GetLineIndentPosition=2128(int line,)
# Retrieve the column number of a position, taking tab width into account.
get int GetColumn=2129(position pos,)
-# Show or hide the horizontal scroll bar
+# Show or hide the horizontal scroll bar.
set void SetHScrollBar=2130(bool show,)
-# Is the horizontal scroll bar visible.
+# Is the horizontal scroll bar visible?
get bool GetHScrollBar=2131(,)
+# Show or hide indentation guides.
+set void SetIndentationGuides=2132(bool show,)
+
+# Are the indentation guides visible?
+get bool GetIndentationGuides=2133(,)
+
+# Set the highlighted indentation guide column.
+# 0 = no highlighted guide.
+set void SetHighlightGuide=2134(int column,)
+
+# Get the highlighted indentation guide column.
+get int GetHighlightGuide=2135(,)
+
# Show a call tip containing a definition near position pos.
fun void CallTipShow=2200(position pos, string definition)
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 878baacff..8596eb8f9 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -81,7 +81,8 @@ Editor::Editor() {
braces[0]=invalidPosition;
braces[1]=invalidPosition;
bracesMatchStyle = STYLE_BRACEBAD;
-
+ highlightGuideColumn = 0;
+
edgeState = EDGE_NONE;
theEdge = 0;
@@ -119,6 +120,7 @@ void Editor::DropGraphics() {
pixmapLine.Release();
pixmapSelMargin.Release();
pixmapSelPattern.Release();
+ pixmapIndentGuide.Release();
}
void Editor::InvalidateStyleData() {
@@ -729,6 +731,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font;
char styleByte = 0;
int styleMask = pdoc->stylingBitsMask;
+ ll.xHighlightGuide = 0;
for (int charInDoc = posLineStart;
charInDoc < posLineEnd && numCharsInLine < LineLayout::maxLineLength - 1;
charInDoc++) {
@@ -778,7 +781,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
ll.numCharsInLine = numCharsInLine;
}
-void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout &ll) {
+void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
+ PRectangle rcLine, LineLayout &ll) {
PRectangle rcSegment = rcLine;
@@ -802,7 +806,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
marks = pdoc->GetMark(line) & vsDraw.maskInLine;
}
- bool inIndentation = true;
+ bool inIndentation = true;
+ int indentWidth = pdoc->indentInChars * vs.spaceWidth;
+
int posLineStart = pdoc->LineStart(line);
int posLineEnd = pdoc->LineStart(line + 1);
@@ -816,8 +822,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
int iDoc = i + posLineStart;
// If there is the end of a style run for any reason
if ((ll.styles[i] != ll.styles[i + 1]) ||
- IsControlCharacter(ll.chars[i]) || IsControlCharacter(ll.chars[i + 1]) ||
- ((selStart != selEnd) && ((iDoc + 1 == selStart) || (iDoc + 1 == selEnd))) ||
+ IsControlCharacter(ll.chars[i]) || IsControlCharacter(ll.chars[i + 1]) ||
+ ((selStart != selEnd) && ((iDoc + 1 == selStart) || (iDoc + 1 == selEnd))) ||
(i == (theEdge-1))) {
int styleMain = ll.styles[i];
Colour textBack = vsDraw.styles[styleMain].back.allocated;
@@ -840,22 +846,31 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
rcSegment.left = ll.positions[i] + xStart;
rcSegment.right = ll.positions[i + 1] + xStart;
surface->FillRectangle(rcSegment, textBack);
- if (vsDraw.viewWhitespace) {
- surface->PenColour(textFore);
- if (inIndentation) {
- if (ll.positions[i] > 0) {
- surface->MoveTo(rcSegment.left + 1, rcSegment.top);
- surface->LineTo(rcSegment.left + 1, rcSegment.bottom);
- }
- } else {
- PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4,
- rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
- DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2);
- }
+ if ((vsDraw.viewWhitespace != wsInvisible) || ((inIndentation && vsDraw.viewIndentationGuides))) {
+ surface->PenColour(textFore);
+ }
+ if (inIndentation && vsDraw.viewIndentationGuides) {
+ for (int xIG = ll.positions[i] / indentWidth * indentWidth; xIG < ll.positions[i + 1]; xIG += indentWidth) {
+ if (xIG >= ll.positions[i] && xIG > 0) {
+ Point from(0, ((lineVisible & 1) && (vs.lineHeight & 1)) ? 1 : 0);
+ PRectangle rcCopyArea(xIG + xStart + 1, rcSegment.top, xIG + xStart + 2, rcSegment.bottom);
+ surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == xIG) ?
+ pixmapIndentGuideHighlight : pixmapIndentGuide);
+ }
+ }
+ //if (ll.positions[i] > 0 && (ll.positions[i] % indentWidth == 0)) {
+ //}
+ }
+ if (vsDraw.viewWhitespace != wsInvisible) {
+ if (inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
+ PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4,
+ rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
+ DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2);
+ }
}
// Manage control character display
} else if (IsControlCharacter(ll.chars[i])) {
- inIndentation = false;
+ inIndentation = false;
const char *ctrlChar = ControlCharacterString(ll.chars[i]);
rcSegment.left = ll.positions[i] + xStart;
rcSegment.right = ll.positions[i + 1] + xStart;
@@ -878,23 +893,38 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
textBack, textFore);
// Manage normal display
} else {
- inIndentation = false;
rcSegment.left = ll.positions[startseg] + xStart;
rcSegment.right = ll.positions[i + 1] + xStart;
// Only try to draw if really visible - enhances performance by not calling environment to
// draw strings that are completely past the right side of the window.
if (rcSegment.left <= rcLine.right) {
surface->DrawText(rcSegment, textFont,
- rcSegment.top + vsDraw.maxAscent, ll.chars + startseg,
- i - startseg + 1, textFore, textBack);
- if (vsDraw.viewWhitespace) {
+ rcSegment.top + vsDraw.maxAscent, ll.chars + startseg,
+ i - startseg + 1, textFore, textBack);
+ if (vsDraw.viewWhitespace != wsInvisible ||
+ (inIndentation && vs.viewIndentationGuides)) {
for (int cpos = 0; cpos <= i - startseg; cpos++) {
if (ll.chars[cpos + startseg] == ' ') {
- int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2;
- PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
- rcDot.right = rcDot.left + 1;
- rcDot.bottom = rcDot.top + 1;
- surface->FillRectangle(rcDot, textFore);
+ if (vsDraw.viewWhitespace != wsInvisible) {
+ if (inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
+ int xmid = (ll.positions[cpos + startseg] + ll.positions[cpos + startseg + 1]) / 2;
+ PRectangle rcDot(xmid + xStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
+ rcDot.right = rcDot.left + 1;
+ rcDot.bottom = rcDot.top + 1;
+ surface->FillRectangle(rcDot, textFore);
+ }
+ }
+ if (inIndentation && vsDraw.viewIndentationGuides) {
+ int startSpace = ll.positions[cpos + startseg];
+ if (startSpace > 0 && (startSpace % indentWidth == 0)) {
+ Point from(0, ((lineVisible & 1) && (vs.lineHeight & 1)) ? 1 : 0);
+ PRectangle rcCopyArea(startSpace + xStart + 1, rcSegment.top, startSpace + xStart + 2, rcSegment.bottom);
+ surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == ll.positions[cpos + startseg]) ?
+ pixmapIndentGuideHighlight : pixmapIndentGuide);
+ }
+ }
+ } else {
+ inIndentation = false;
}
}
}
@@ -994,7 +1024,23 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
pixmapSelPattern.FillRectangle(rcPattern, vs.selbarlight.allocated);
}
}
-
+ if (!pixmapIndentGuide.Initialised()) {
+ // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line
+ pixmapIndentGuide.InitPixMap(1, vs.lineHeight+1, surfaceWindow);
+ pixmapIndentGuideHighlight.InitPixMap(1, vs.lineHeight+1, surfaceWindow);
+ PRectangle rcIG(0, 0, 1, vs.lineHeight);
+ pixmapIndentGuide.FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated);
+ pixmapIndentGuide.PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated);
+ pixmapIndentGuideHighlight.FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
+ pixmapIndentGuideHighlight.PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
+ for (int stripe = 1; stripe < vs.lineHeight+1; stripe+=2) {
+ pixmapIndentGuide.MoveTo(0, stripe);
+ pixmapIndentGuide.LineTo(2, stripe);
+ pixmapIndentGuideHighlight.MoveTo(0, stripe);
+ pixmapIndentGuideHighlight.LineTo(2, stripe);
+ }
+ }
+
if (bufferedDraw) {
if (!pixmapLine.Initialised()) {
pixmapLine.InitPixMap(rcClient.Width(), rcClient.Height(),
@@ -1096,10 +1142,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
if ((braces[1] >= posLineStart) && (braces[1] < posLineEnd))
ll.styles[braces[1] - posLineStart] =
static_cast<char>(bracesMatchStyle);
+ if ((braces[0] >= posLineStart && braces[1] <= posLineEnd) ||
+ (braces[1] >= posLineStart && braces[0] <= posLineEnd)) {
+ ll.xHighlightGuide = highlightGuideColumn * vs.spaceWidth;
+ }
// Draw the line
if (cs.GetVisible(line))
- DrawLine(surface, vs, line, xStart, rcLine, ll);
+ DrawLine(surface, vs, line, visibleLine, xStart, rcLine, ll);
bool expanded = cs.GetExpanded(line);
if ( (expanded && (foldFlags & 2)) || (!expanded && (foldFlags & 4)) ) {
@@ -1293,7 +1343,7 @@ long Editor::FormatRange(bool draw, FORMATRANGE *pfr) {
// Draw the line
surface->FlushCachedState();
- DrawLine(surface, vsPrint, line, xStart, rcLine, ll);
+ DrawLine(surface, vsPrint, line, line, xStart, rcLine, ll);
ypos += vsPrint.lineHeight;
line++;
@@ -2082,11 +2132,11 @@ int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt) {
return KeyDefault(key, modifiers);
}
-void Editor::SetWhitespaceVisible(bool view) {
- vs.viewWhitespace = view;
+void Editor::SetWhitespaceVisible(int view) {
+ vs.viewWhitespace = static_cast<WhiteSpaceVisibility>(view);
}
-bool Editor::GetWhitespaceVisible() {
+int Editor::GetWhitespaceVisible() {
return vs.viewWhitespace;
}
@@ -3318,10 +3368,10 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
return vs.viewWhitespace;
case SCI_SETVIEWWS:
- vs.viewWhitespace = wParam;
+ vs.viewWhitespace = static_cast<WhiteSpaceVisibility>(wParam);
Redraw();
break;
-
+
case SCI_GOTOLINE:
GoToLine(wParam);
break;
@@ -3434,6 +3484,24 @@ LRESULT Editor::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
case SCI_GETHSCROLLBAR:
return horizontalScrollBarVisible;
+ case SCI_SETINDENTATIONGUIDES:
+ vs.viewIndentationGuides = wParam;
+ Redraw();
+ break;
+
+ case SCI_GETINDENTATIONGUIDES:
+ return vs.viewIndentationGuides;
+
+ case SCI_SETHIGHLIGHTGUIDE:
+ if (highlightGuideColumn != wParam) {
+ highlightGuideColumn = wParam;
+ Redraw();
+ }
+ break;
+
+ case SCI_GETHIGHLIGHTGUIDE:
+ return highlightGuideColumn;
+
case SCI_SETCODEPAGE:
pdoc->dbcsCodePage = wParam;
break;
diff --git a/src/Editor.h b/src/Editor.h
index 808a656be..73b0308c8 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -31,6 +31,8 @@ public:
// Drawing is only performed for maxLineLength characters on each line.
enum {maxLineLength = 4000};
int numCharsInLine;
+ int xHighlightGuide;
+ bool highlightColumn;
char chars[maxLineLength];
char styles[maxLineLength];
char indicators[maxLineLength];
@@ -69,6 +71,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
Surface pixmapLine;
Surface pixmapSelMargin;
Surface pixmapSelPattern;
+ Surface pixmapIndentGuide;
+ Surface pixmapIndentGuideHighlight;
// Intellimouse support - currently only implemented for Windows
unsigned int ucWheelScrollLines;
int cWheelDelta; //wheel delta from roll
@@ -98,6 +102,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool needUpdateUI;
Position braces[2];
int bracesMatchStyle;
+ int highlightGuideColumn;
int edgeState;
int theEdge;
@@ -183,7 +188,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void PaintSelMargin(Surface *surface, PRectangle &rc);
void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout &ll);
- void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+ void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
PRectangle rcLine, LineLayout &ll);
void Paint(Surface *surfaceWindow, PRectangle rcArea);
long FormatRange(bool draw, FORMATRANGE *pfr);
@@ -241,8 +246,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDown(int key, bool shift, bool ctrl, bool alt);
- bool GetWhitespaceVisible();
- void SetWhitespaceVisible(bool view);
+ int GetWhitespaceVisible();
+ void SetWhitespaceVisible(int view);
void Indent(bool forwards);
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 87b84f706..0f7d944fe 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -325,7 +325,7 @@ LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break;
case SCI_AUTOCSETSEPARATOR:
- ac.SetSeparator(wParam);
+ ac.SetSeparator(static_cast<char>(wParam));
break;
case SCI_AUTOCGETSEPARATOR:
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index 580ecc71f..fe2375018 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -83,6 +83,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
fixedColumnWidth = source.fixedColumnWidth;
zoomLevel = source.zoomLevel;
viewWhitespace = source.viewWhitespace;
+ viewIndentationGuides = source.viewIndentationGuides;
viewEOL = source.viewEOL;
showMarkedLines = source.showMarkedLines;
}
@@ -142,7 +143,8 @@ void ViewStyle::Init() {
maskInLine &= ~ms[margin].mask;
}
zoomLevel = 0;
- viewWhitespace = false;
+ viewWhitespace = wsInvisible;
+ viewIndentationGuides = false;
viewEOL = false;
showMarkedLines = true;
}
diff --git a/src/ViewStyle.h b/src/ViewStyle.h
index 4436e83ff..5660368ec 100644
--- a/src/ViewStyle.h
+++ b/src/ViewStyle.h
@@ -26,6 +26,7 @@ public:
const char *Save(const char *name);
};
+enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
class ViewStyle {
public:
FontNames fontNames;
@@ -52,7 +53,8 @@ public:
MarginStyle ms[margins];
int fixedColumnWidth;
int zoomLevel;
- bool viewWhitespace;
+ WhiteSpaceVisibility viewWhitespace;
+ bool viewIndentationGuides;
bool viewEOL;
bool showMarkedLines;
ColourPair caretcolour;
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index a6dfb8dd6..48fe7f7b8 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -721,7 +721,7 @@ int Platform::Maximum(int a, int b) {
return b;
}
-//#define TRACE
+#define TRACE
#ifdef TRACE
void Platform::DebugPrintf(const char *format, ...) {
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 829b973fa..25af77f99 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -288,7 +288,12 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
break;
case WM_PAINT: {
- //CElapsed ce; ce.Begin();
+ //CElapsed ce; ce.Begin();
+ LARGE_INTEGER perfStart;
+ LARGE_INTEGER perfEnd;
+ LARGE_INTEGER performanceFreq;
+ QueryPerformanceFrequency(&performanceFreq);
+ QueryPerformanceCounter(&perfStart);
paintState = painting;
PAINTSTRUCT ps;
BeginPaint(wMain.GetID(), &ps);
@@ -311,7 +316,14 @@ LRESULT ScintillaWin::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
FullPaint();
}
paintState = notPainting;
- //Platform::DebugPrintf("Paint took %g\n", ce.End());
+ QueryPerformanceCounter(&perfEnd);
+ __int64 start = perfStart.QuadPart;
+ __int64 end = perfEnd.QuadPart;
+ __int64 freq = performanceFreq.QuadPart;
+ __int64 dur = end - start;
+ double per = double(dur) / double(freq);
+ Platform::DebugPrintf("Paint took %5.03g\n", per);
+ //Platform::DebugPrintf("Paint took %g\n", ce.End());
}
break;