summaryrefslogtreecommitdiffstats
path: root/scintilla/src
diff options
context:
space:
mode:
Diffstat (limited to 'scintilla/src')
-rw-r--r--scintilla/src/CaseConvert.cxx9
-rw-r--r--scintilla/src/CaseConvert.h3
-rw-r--r--scintilla/src/Catalogue.cxx1
-rw-r--r--scintilla/src/CellBuffer.h16
-rw-r--r--scintilla/src/ContractionState.cxx32
-rw-r--r--scintilla/src/ContractionState.h8
-rw-r--r--scintilla/src/Document.cxx12
-rw-r--r--scintilla/src/EditModel.cxx1
-rw-r--r--scintilla/src/EditModel.h1
-rw-r--r--scintilla/src/EditView.cxx236
-rw-r--r--scintilla/src/EditView.h8
-rw-r--r--scintilla/src/Editor.cxx74
-rw-r--r--scintilla/src/Editor.h9
-rw-r--r--scintilla/src/Indicator.cxx15
-rw-r--r--scintilla/src/Indicator.h2
-rw-r--r--scintilla/src/PositionCache.cxx8
-rw-r--r--scintilla/src/PositionCache.h12
-rw-r--r--scintilla/src/ScintillaBase.cxx14
-rw-r--r--scintilla/src/ScintillaBase.h4
-rw-r--r--scintilla/src/SparseVector.h186
-rw-r--r--scintilla/src/ViewStyle.cxx13
-rw-r--r--scintilla/src/ViewStyle.h4
22 files changed, 576 insertions, 92 deletions
diff --git a/scintilla/src/CaseConvert.cxx b/scintilla/src/CaseConvert.cxx
index b4c8bcf..66185ba 100644
--- a/scintilla/src/CaseConvert.cxx
+++ b/scintilla/src/CaseConvert.cxx
@@ -11,6 +11,7 @@
#include <cstring>
#include <stdexcept>
+#include <string>
#include <vector>
#include <algorithm>
@@ -630,6 +631,14 @@ size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixe
return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed);
}
+std::string CaseConvertString(const std::string &s, enum CaseConversion conversion) {
+ std::string retMapped(s.length() * maxExpansionCaseConversion, 0);
+ size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(),
+ conversion);
+ retMapped.resize(lenMapped);
+ return retMapped;
+}
+
#ifdef SCI_NAMESPACE
}
#endif
diff --git a/scintilla/src/CaseConvert.h b/scintilla/src/CaseConvert.h
index 60de227..7a01003 100644
--- a/scintilla/src/CaseConvert.h
+++ b/scintilla/src/CaseConvert.h
@@ -40,6 +40,9 @@ const int maxExpansionCaseConversion=3;
// If there is not enough space then 0 is returned.
size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion);
+// Converts a mixed case string using a particular conversion.
+std::string CaseConvertString(const std::string &s, enum CaseConversion conversion);
+
#ifdef SCI_NAMESPACE
}
#endif
diff --git a/scintilla/src/Catalogue.cxx b/scintilla/src/Catalogue.cxx
index 0c1e22c..560720d 100644
--- a/scintilla/src/Catalogue.cxx
+++ b/scintilla/src/Catalogue.cxx
@@ -111,6 +111,7 @@ int Scintilla_LinkLexers() {
//LINK_LEXER(lmDMAP);
//LINK_LEXER(lmDMIS);
//LINK_LEXER(lmECL);
+ //LINK_LEXER(lmEDIFACT);
//LINK_LEXER(lmEiffel);
//LINK_LEXER(lmEiffelkw);
//LINK_LEXER(lmErlang);
diff --git a/scintilla/src/CellBuffer.h b/scintilla/src/CellBuffer.h
index a515202..323ddfe 100644
--- a/scintilla/src/CellBuffer.h
+++ b/scintilla/src/CellBuffer.h
@@ -47,22 +47,6 @@ public:
int LineStart(int line) const {
return starts.PositionFromPartition(line);
}
-
- int MarkValue(int line);
- int AddMark(int line, int marker);
- void MergeMarkers(int pos);
- void DeleteMark(int line, int markerNum, bool all);
- void DeleteMarkFromHandle(int markerHandle);
- int LineFromHandle(int markerHandle);
-
- void ClearLevels();
- int SetLevel(int line, int level);
- int GetLevel(int line);
-
- int SetLineState(int line, int state);
- int GetLineState(int line);
- int GetMaxLineState();
-
};
enum actionType { insertAction, removeAction, startAction, containerAction };
diff --git a/scintilla/src/ContractionState.cxx b/scintilla/src/ContractionState.cxx
index bd2d120..289e669 100644
--- a/scintilla/src/ContractionState.cxx
+++ b/scintilla/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/scintilla/src/ContractionState.h b/scintilla/src/ContractionState.h
index 70a3e4c..fe6886f 100644
--- a/scintilla/src/ContractionState.h
+++ b/scintilla/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/scintilla/src/Document.cxx b/scintilla/src/Document.cxx
index babf37b..6ad44d6 100644
--- a/scintilla/src/Document.cxx
+++ b/scintilla/src/Document.cxx
@@ -16,8 +16,16 @@
#include <vector>
#include <algorithm>
+#define NOEXCEPT
+
#ifndef NO_CXX11_REGEX
#include <regex>
+#if defined(__GLIBCXX__)
+// If using the GNU implementation of <regex> then have 'noexcept' so can use
+// when defining regex iterators to keep Clang analyze happy.
+#undef NOEXCEPT
+#define NOEXCEPT noexcept
+#endif
#endif
#include "Platform.h"
@@ -2570,7 +2578,7 @@ public:
Position position;
ByteIterator(const Document *doc_ = 0, Position position_ = 0) : doc(doc_), position(position_) {
}
- ByteIterator(const ByteIterator &other) {
+ ByteIterator(const ByteIterator &other) NOEXCEPT {
doc = other.doc;
position = other.position;
}
@@ -2745,7 +2753,7 @@ class UTF8Iterator : public std::iterator<std::bidirectional_iterator_tag, wchar
public:
UTF8Iterator(const Document *doc_=0, Position position_=0) : doc(doc_), position(position_) {
}
- UTF8Iterator(const UTF8Iterator &other) {
+ UTF8Iterator(const UTF8Iterator &other) NOEXCEPT {
doc = other.doc;
position = other.position;
}
diff --git a/scintilla/src/EditModel.cxx b/scintilla/src/EditModel.cxx
index 35903c6..0f64e07 100644
--- a/scintilla/src/EditModel.cxx
+++ b/scintilla/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/scintilla/src/EditModel.h b/scintilla/src/EditModel.h
index 021bf67..847fd72 100644
--- a/scintilla/src/EditModel.h
+++ b/scintilla/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/scintilla/src/EditView.cxx b/scintilla/src/EditView.cxx
index e6cd8fc..8ffc1bc 100644
--- a/scintilla/src/EditView.cxx
+++ b/scintilla/src/EditView.cxx
@@ -306,21 +306,25 @@ static const char *ControlCharacterString(unsigned char ch) {
}
}
-static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid) {
- int ydiff = static_cast<int>(rcTab.bottom - rcTab.top) / 2;
- int xhead = static_cast<int>(rcTab.right) - 1 - ydiff;
- if (xhead <= rcTab.left) {
- ydiff -= static_cast<int>(rcTab.left) - xhead - 1;
- xhead = static_cast<int>(rcTab.left) - 1;
- }
+static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, const ViewStyle &vsDraw) {
if ((rcTab.left + 2) < (rcTab.right - 1))
surface->MoveTo(static_cast<int>(rcTab.left) + 2, ymid);
else
surface->MoveTo(static_cast<int>(rcTab.right) - 1, ymid);
surface->LineTo(static_cast<int>(rcTab.right) - 1, ymid);
- surface->LineTo(xhead, ymid - ydiff);
- surface->MoveTo(static_cast<int>(rcTab.right) - 1, ymid);
- surface->LineTo(xhead, ymid + ydiff);
+
+ // Draw the arrow head if needed
+ if (vsDraw.tabDrawMode == tdLongArrow) {
+ int ydiff = static_cast<int>(rcTab.bottom - rcTab.top) / 2;
+ int xhead = static_cast<int>(rcTab.right) - 1 - ydiff;
+ if (xhead <= rcTab.left) {
+ ydiff -= static_cast<int>(rcTab.left) - xhead - 1;
+ xhead = static_cast<int>(rcTab.left) - 1;
+ }
+ surface->LineTo(xhead, ymid - ydiff);
+ surface->MoveTo(static_cast<int>(rcTab.right) - 1, ymid);
+ surface->LineTo(xhead, ymid + ydiff);
+ }
}
void EditView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw) {
@@ -596,19 +600,24 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co
}
}
-Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, const ViewStyle &vs) {
+Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine,
+ const ViewStyle &vs, PointEnd pe) {
Point pt;
if (pos.Position() == INVALID_POSITION)
return pt;
- const int line = model.pdoc->LineFromPosition(pos.Position());
- const int lineVisible = model.cs.DisplayFromDoc(line);
- //Platform::DebugPrintf("line=%d\n", line);
- AutoLineLayout ll(llc, RetrieveLineLayout(line, model));
+ int lineDoc = model.pdoc->LineFromPosition(pos.Position());
+ int posLineStart = model.pdoc->LineStart(lineDoc);
+ if ((pe & peLineEnd) && (lineDoc > 0) && (pos.Position() == posLineStart)) {
+ // Want point at end of first line
+ lineDoc--;
+ posLineStart = model.pdoc->LineStart(lineDoc);
+ }
+ const int lineVisible = model.cs.DisplayFromDoc(lineDoc);
+ AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
if (surface && ll) {
- const int posLineStart = model.pdoc->LineStart(line);
- LayoutLine(model, line, surface, vs, ll, model.wrapWidth);
+ LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth);
const int posInLine = pos.Position() - posLineStart;
- pt = ll->PointFromPosition(posInLine, vs.lineHeight);
+ pt = ll->PointFromPosition(posInLine, vs.lineHeight, pe);
pt.y += (lineVisible - topLine) * vs.lineHeight;
pt.x += vs.textStart - model.xOffset;
}
@@ -616,6 +625,31 @@ Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, S
return pt;
}
+Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs) {
+ Range rangeSubLine = Range(0,0);
+ if (lineVisible < 0) {
+ return rangeSubLine;
+ }
+ const int lineDoc = model.cs.DocFromDisplay(lineVisible);
+ const int positionLineStart = model.pdoc->LineStart(lineDoc);
+ AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model));
+ if (surface && ll) {
+ LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth);
+ const int lineStartSet = model.cs.DisplayFromDoc(lineDoc);
+ const int subLine = lineVisible - lineStartSet;
+ if (subLine < ll->lines) {
+ rangeSubLine = ll->SubLineRange(subLine);
+ if (subLine == ll->lines-1) {
+ rangeSubLine.end = model.pdoc->LineStart(lineDoc + 1) -
+ positionLineStart;
+ }
+ }
+ }
+ rangeSubLine.start += positionLineStart;
+ rangeSubLine.end += positionLineStart;
+ return rangeSubLine;
+}
+
SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs) {
pt.x = pt.x - vs.textStart;
int visibleLine = static_cast<int>(floor(pt.y / vs.lineHeight));
@@ -845,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;
}
@@ -914,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;
@@ -963,14 +987,23 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle
}
static void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, const ViewStyle &vsDraw,
- const LineLayout *ll, int xStart, PRectangle rcLine, int subLine, Indicator::DrawState drawState, int value) {
+ const LineLayout *ll, int xStart, PRectangle rcLine, int secondCharacter, int subLine, Indicator::DrawState drawState, int value) {
const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)];
PRectangle rcIndic(
ll->positions[startPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent,
ll->positions[endPos] + xStart - subLineStart,
rcLine.top + vsDraw.maxAscent + 3);
- vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, drawState, value);
+ PRectangle rcFirstCharacter = rcIndic;
+ // Allow full descent space for character indicators
+ rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent;
+ if (secondCharacter >= 0) {
+ rcFirstCharacter.right = ll->positions[secondCharacter] + xStart - subLineStart;
+ } else {
+ // Indicator continued from earlier line so make an empty box and don't draw
+ rcFirstCharacter.right = rcFirstCharacter.left;
+ }
+ vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, rcFirstCharacter, drawState, value);
}
static void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
@@ -993,8 +1026,9 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS
rangeRun.ContainsCharacter(hoverIndicatorPos);
const int value = deco->rs.ValueAt(startPos);
Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal;
+ const int posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1);
DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
- surface, vsDraw, ll, xStart, rcLine, subLine, drawState, value);
+ surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, drawState, value);
startPos = endPos;
if (!deco->rs.ValueAt(startPos)) {
startPos = deco->rs.EndRun(startPos);
@@ -1012,19 +1046,110 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS
if (rangeLine.ContainsCharacter(model.braces[0])) {
int braceOffset = model.braces[0] - posLineStart;
if (braceOffset < ll->numCharsInLine) {
- DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, subLine, Indicator::drawNormal, 1);
+ const int secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[0] + 1, 1) - posLineStart;
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1);
}
}
if (rangeLine.ContainsCharacter(model.braces[1])) {
int braceOffset = model.braces[1] - posLineStart;
if (braceOffset < ll->numCharsInLine) {
- DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, subLine, Indicator::drawNormal, 1);
+ const int secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[1] + 1, 1) - posLineStart;
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1);
}
}
}
}
}
+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;
}
@@ -1537,7 +1662,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
PRectangle rcTab(rcSegment.left + 1, rcSegment.top + tabArrowHeight,
rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent);
if (customDrawTabArrow == NULL)
- DrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2));
+ DrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2), vsDraw);
else
customDrawTabArrow(surface, rcTab, static_cast<int>(rcSegment.top + vsDraw.lineHeight / 2));
}
@@ -1743,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);
}
@@ -1878,7 +2005,8 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
ll->SetBracesHighlight(rangeLine, model.braces, static_cast<char>(model.bracesMatchStyle),
static_cast<int>(model.highlightGuideColumn * vsDraw.spaceWidth), bracesIgnoreStyle);
- if (leftTextOverlap && bufferedDraw) {
+ if (leftTextOverlap && (bufferedDraw || ((phasesDraw < phasesMultiple) && (*it & drawBack)))) {
+ // Clear the left margin
PRectangle rcSpacer = rcLine;
rcSpacer.right = rcSpacer.left;
rcSpacer.left -= 1;
@@ -1955,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/scintilla/src/EditView.h b/scintilla/src/EditView.h
index 79a8865..83dd8bb 100644
--- a/scintilla/src/EditView.h
+++ b/scintilla/src/EditView.h
@@ -111,7 +111,9 @@ public:
void LayoutLine(const EditModel &model, int line, Surface *surface, const ViewStyle &vstyle,
LineLayout *ll, int width = LineLayout::wrapWidthInfinite);
- Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, const ViewStyle &vs);
+ Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine,
+ const ViewStyle &vs, PointEnd pe);
+ Range RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs);
SelectionPosition SPositionFromLocation(Surface *surface, const EditModel &model, Point pt, bool canReturnInvalid,
bool charPosition, bool virtualSpace, const ViewStyle &vs);
SelectionPosition SPositionFromLineX(Surface *surface, const EditModel &model, int lineDoc, int x, const ViewStyle &vs);
@@ -122,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,
@@ -138,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/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx
index a19feba..5ee9721 100644
--- a/scintilla/src/Editor.cxx
+++ b/scintilla/src/Editor.cxx
@@ -363,14 +363,14 @@ SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const
}
}
-Point Editor::LocationFromPosition(SelectionPosition pos) {
+Point Editor::LocationFromPosition(SelectionPosition pos, PointEnd pe) {
RefreshStyleData();
AutoSurface surface(this);
- return view.LocationFromPosition(surface, *this, pos, topLine, vs);
+ return view.LocationFromPosition(surface, *this, pos, topLine, vs, pe);
}
-Point Editor::LocationFromPosition(int pos) {
- return LocationFromPosition(SelectionPosition(pos));
+Point Editor::LocationFromPosition(int pos, PointEnd pe) {
+ return LocationFromPosition(SelectionPosition(pos), pe);
}
int Editor::XFromPosition(int pos) {
@@ -2424,13 +2424,7 @@ void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctr
}
bool Editor::NotifyMarginClick(Point pt, int modifiers) {
- int marginClicked = -1;
- int x = vs.textStart - vs.fixedColumnWidth;
- for (size_t margin = 0; margin < vs.ms.size(); margin++) {
- if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
- marginClicked = static_cast<int>(margin);
- x += vs.ms[margin].width;
- }
+ const int marginClicked = vs.MarginFromLocation(pt);
if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) {
int position = pdoc->LineStart(LineFromLocation(pt));
if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) {
@@ -2471,6 +2465,22 @@ bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
return NotifyMarginClick(pt, ModifierFlags(shift, ctrl, alt));
}
+bool Editor::NotifyMarginRightClick(Point pt, int modifiers) {
+ int marginRightClicked = vs.MarginFromLocation(pt);
+ if ((marginRightClicked >= 0) && vs.ms[marginRightClicked].sensitive) {
+ int position = pdoc->LineStart(LineFromLocation(pt));
+ SCNotification scn = {};
+ scn.nmhdr.code = SCN_MARGINRIGHTCLICK;
+ scn.modifiers = modifiers;
+ scn.position = position;
+ scn.margin = marginRightClicked;
+ NotifyParent(scn);
+ return true;
+ } else {
+ return false;
+ }
+}
+
void Editor::NotifyNeedShown(int pos, int len) {
SCNotification scn = {};
scn.nmhdr.code = SCN_NEEDSHOWN;
@@ -3156,6 +3166,12 @@ void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) {
} while (!cs.GetVisible(lineDoc));
}
+Range Editor::RangeDisplayLine(int lineVisible) {
+ RefreshStyleData();
+ AutoSurface surface(this);
+ return view.RangeDisplayLine(surface, *this, lineVisible, vs);
+}
+
int Editor::StartEndDisplayLine(int pos, bool start) {
RefreshStyleData();
AutoSurface surface(this);
@@ -3948,7 +3964,7 @@ CaseFolder *Editor::CaseFolderForEncoding() {
long Editor::FindText(
uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD,
///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
- sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range.
+ sptr_t lParam) { ///< @c Sci_TextToFind structure: The text to search for in the given range.
Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
@@ -4594,6 +4610,11 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifie
ShowCaretAtCurrentPosition();
}
+void Editor::RightButtonDownWithModifiers(Point pt, unsigned int, int modifiers) {
+ if (NotifyMarginRightClick(pt, modifiers))
+ return;
+}
+
void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
return ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
}
@@ -5589,7 +5610,7 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
SetEmptySelection(sel.MainCaret() + lengthInserted);
}
-bool Editor::ValidMargin(uptr_t wParam) {
+bool Editor::ValidMargin(uptr_t wParam) const {
return wParam < vs.ms.size();
}
@@ -6304,6 +6325,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
Redraw();
break;
+ case SCI_GETTABDRAWMODE:
+ return vs.tabDrawMode;
+
+ case SCI_SETTABDRAWMODE:
+ vs.tabDrawMode = static_cast<TabDrawMode>(wParam);
+ Redraw();
+ break;
+
case SCI_GETWHITESPACESIZE:
return vs.whitespaceSize;
@@ -6724,15 +6753,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETIMEINTERACTION:
return imeInteraction;
-#ifdef INCLUDE_DEPRECATED_FEATURES
- case SCI_SETUSEPALETTE:
- InvalidateStyleRedraw();
- break;
-
- case SCI_GETUSEPALETTE:
- return 0;
-#endif
-
// Marker definition and setting
case SCI_MARKERDEFINE:
if (wParam <= MARKER_MAX) {
@@ -7076,6 +7096,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;
diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h
index 74fc46f..16e6aaa 100644
--- a/scintilla/src/Editor.h
+++ b/scintilla/src/Editor.h
@@ -285,8 +285,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int LinesToScroll() const;
int MaxScrollPos() const;
SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
- Point LocationFromPosition(SelectionPosition pos);
- Point LocationFromPosition(int pos);
+ Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault);
+ Point LocationFromPosition(int pos, PointEnd pe=peDefault);
int XFromPosition(int pos);
int XFromPosition(SelectionPosition sp);
SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
@@ -439,6 +439,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
bool NotifyMarginClick(Point pt, int modifiers);
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
+ bool NotifyMarginRightClick(Point pt, int modifiers);
void NotifyNeedShown(int pos, int len);
void NotifyDwelling(Point pt, bool state);
void NotifyZoom();
@@ -465,6 +466,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
SelectionPosition PositionUpOrDown(SelectionPosition spStart, int direction, int lastX);
void CursorUpOrDown(int direction, Selection::selTypes selt);
void ParaUpOrDown(int direction, Selection::selTypes selt);
+ Range RangeDisplayLine(int lineVisible);
int StartEndDisplayLine(int pos, bool start);
int VCHomeDisplayPosition(int position);
int VCHomeWrapPosition(int position);
@@ -507,6 +509,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void DwellEnd(bool mouseMoved);
void MouseLeave();
virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
+ virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void ButtonMoveWithModifiers(Point pt, int modifiers);
void ButtonMove(Point pt);
@@ -571,7 +574,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void AddStyledText(char *buffer, int appendLength);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
- bool ValidMargin(uptr_t wParam);
+ bool ValidMargin(uptr_t wParam) const;
void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
diff --git a/scintilla/src/Indicator.cxx b/scintilla/src/Indicator.cxx
index bae8130..3fa4588 100644
--- a/scintilla/src/Indicator.cxx
+++ b/scintilla/src/Indicator.cxx
@@ -24,7 +24,7 @@ static PRectangle PixelGridAlign(const PRectangle &rc) {
return PRectangle::FromInts(int(rc.left + 0.5), int(rc.top), int(rc.right + 0.5), int(rc.bottom));
}
-void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, DrawState drawState, int value) const {
+void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const {
StyleAndColour sacDraw = sacNormal;
if (Flags() & SC_INDICFLAG_VALUEFORE) {
sacDraw.fore = value & SC_INDICVALUEMASK;
@@ -170,6 +170,19 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
} else if (sacDraw.style == INDIC_COMPOSITIONTHIN) {
PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1);
surface->FillRectangle(rcComposition, sacDraw.fore);
+ } else if (sacDraw.style == INDIC_POINT || sacDraw.style == INDIC_POINTCHARACTER) {
+ if (rcCharacter.Width() >= 0.1) {
+ const int pixelHeight = static_cast<int>(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase
+ const XYPOSITION x = (sacDraw.style == INDIC_POINT) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2);
+ const int ix = static_cast<int>(x + 0.5f);
+ const int iy = static_cast<int>(rc.top + 1.0f);
+ Point pts[] = {
+ Point::FromInts(ix - pixelHeight, iy + pixelHeight), // Left
+ Point::FromInts(ix + pixelHeight, iy + pixelHeight), // Right
+ Point::FromInts(ix, iy) // Top
+ };
+ surface->Polygon(pts, 3, sacDraw.fore, sacDraw.fore);
+ }
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(static_cast<int>(rc.left), ymid);
surface->LineTo(static_cast<int>(rc.right), ymid);
diff --git a/scintilla/src/Indicator.h b/scintilla/src/Indicator.h
index d6f88ba..72c935a 100644
--- a/scintilla/src/Indicator.h
+++ b/scintilla/src/Indicator.h
@@ -40,7 +40,7 @@ public:
Indicator(int style_, ColourDesired fore_=ColourDesired(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) :
sacNormal(style_, fore_), sacHover(style_, fore_), under(under_), fillAlpha(fillAlpha_), outlineAlpha(outlineAlpha_), attributes(0) {
}
- void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, DrawState drawState, int value) const;
+ void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const;
bool IsDynamic() const {
return !(sacNormal == sacHover);
}
diff --git a/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx
index c9cf637..66b634a 100644
--- a/scintilla/src/PositionCache.cxx
+++ b/scintilla/src/PositionCache.cxx
@@ -217,7 +217,7 @@ int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition)
return range.end;
}
-Point LineLayout::PointFromPosition(int posInLine, int lineHeight) const {
+Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const {
Point pt;
// In case of very long line put x at arbitrary large position
if (posInLine > maxLineLength) {
@@ -232,6 +232,12 @@ Point LineLayout::PointFromPosition(int posInLine, int lineHeight) const {
pt.x = positions[posInLine] - positions[rangeSubLine.start];
if (rangeSubLine.start != 0) // Wrapped lines may be indented
pt.x += wrapIndent;
+ if (pe & peSubLineEnd) // Return end of first subline not start of next
+ break;
+ } else if ((pe & peLineEnd) && (subLine == (lines-1))) {
+ pt.x = positions[numCharsInLine] - positions[rangeSubLine.start];
+ if (rangeSubLine.start != 0) // Wrapped lines may be indented
+ pt.x += wrapIndent;
}
} else {
break;
diff --git a/scintilla/src/PositionCache.h b/scintilla/src/PositionCache.h
index 2c4443c..e5b8e8d 100644
--- a/scintilla/src/PositionCache.h
+++ b/scintilla/src/PositionCache.h
@@ -16,6 +16,15 @@ static inline bool IsEOLChar(char ch) {
return (ch == '\r') || (ch == '\n');
}
+// There are two points for some positions and this enumeration
+// can choose between the end of the first line or subline
+// and the start of the next line or subline.
+enum PointEnd {
+ peDefault = 0x0,
+ peLineEnd = 0x1,
+ peSubLineEnd = 0x2
+};
+
/**
*/
class LineLayout {
@@ -28,6 +37,7 @@ private:
bool inCache;
public:
enum { wrapWidthInfinite = 0x7ffffff };
+
int maxLineLength;
int numCharsInLine;
int numCharsBeforeEOL;
@@ -64,7 +74,7 @@ public:
void RestoreBracesHighlight(Range rangeLine, const Position braces[], bool ignoreStyle);
int FindBefore(XYPOSITION x, int lower, int upper) const;
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const;
- Point PointFromPosition(int posInLine, int lineHeight) const;
+ Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const;
int EndLineStyle() const;
};
diff --git a/scintilla/src/ScintillaBase.cxx b/scintilla/src/ScintillaBase.cxx
index ef9aeb0..df899a7 100644
--- a/scintilla/src/ScintillaBase.cxx
+++ b/scintilla/src/ScintillaBase.cxx
@@ -64,7 +64,7 @@ using namespace Scintilla;
#endif
ScintillaBase::ScintillaBase() {
- displayPopupMenu = true;
+ displayPopupMenu = SC_POPUP_ALL;
listType = 0;
maxListWidth = 0;
multiAutoCMode = SC_MULTIAUTOC_ONCE;
@@ -478,6 +478,11 @@ void ScintillaBase::CallTipClick() {
NotifyParent(scn);
}
+bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const {
+ return (displayPopupMenu == SC_POPUP_ALL ||
+ (displayPopupMenu == SC_POPUP_TEXT && !PointInSelMargin(ptInWindowCoordinates)));
+}
+
void ScintillaBase::ContextMenu(Point pt) {
if (displayPopupMenu) {
bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
@@ -510,6 +515,11 @@ void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool
ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
}
+void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
+ CancelModes();
+ Editor::RightButtonDownWithModifiers(pt, curTime, modifiers);
+}
+
#ifdef SCI_LEXER
#ifdef SCI_NAMESPACE
@@ -970,7 +980,7 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
break;
case SCI_USEPOPUP:
- displayPopupMenu = wParam != 0;
+ displayPopupMenu = static_cast<int>(wParam);
break;
#ifdef SCI_LEXER
diff --git a/scintilla/src/ScintillaBase.h b/scintilla/src/ScintillaBase.h
index e2eb7f1..31b1cc8 100644
--- a/scintilla/src/ScintillaBase.h
+++ b/scintilla/src/ScintillaBase.h
@@ -40,7 +40,7 @@ protected:
enum { maxLenInputIME = 200 };
- bool displayPopupMenu;
+ int displayPopupMenu;
Menu popup;
AutoComplete ac;
@@ -84,10 +84,12 @@ protected:
virtual void CreateCallTipWindow(PRectangle rc) = 0;
virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;
+ bool ShouldDisplayPopup(Point ptInWindowCoordinates) const;
void ContextMenu(Point pt);
virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
+ virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
void NotifyStyleToNeeded(int endStyleNeeded);
void NotifyLexerChanged(Document *doc, void *userData);
diff --git a/scintilla/src/SparseVector.h b/scintilla/src/SparseVector.h
new file mode 100644
index 0000000..f96b36b
--- /dev/null
+++ b/scintilla/src/SparseVector.h
@@ -0,0 +1,186 @@
+// Scintilla source code edit control
+/** @file SparseVector.h
+ ** Hold data sparsely associated with elements in a range.
+ **/
+// Copyright 2016 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SPARSEVECTOR_H
+#define SPARSEVECTOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// SparseVector is similar to RunStyles but is more efficient for cases where values occur
+// for one position instead of over a range of positions.
+template <typename T>
+class SparseVector {
+private:
+ Partitioning *starts;
+ SplitVector<T> *values;
+ // Private so SparseVector objects can not be copied
+ SparseVector(const SparseVector &);
+ void ClearValue(int partition) {
+ values->SetValueAt(partition, T());
+ }
+ void CommonSetValueAt(int position, T value) {
+ // Do the work of setting the value to allow for specialization of SetValueAt.
+ assert(position < Length());
+ const int partition = starts->PartitionFromPosition(position);
+ const int startPartition = starts->PositionFromPartition(partition);
+ if (value == T()) {
+ // Setting the empty value is equivalent to deleting the position
+ if (position == 0) {
+ ClearValue(partition);
+ } else if (position == startPartition) {
+ // Currently an element at this position, so remove
+ ClearValue(partition);
+ starts->RemovePartition(partition);
+ values->Delete(partition);
+ }
+ // Else element remains empty
+ } else {
+ if (position == startPartition) {
+ // Already a value at this position, so replace
+ ClearValue(partition);
+ values->SetValueAt(partition, value);
+ } else {
+ // Insert a new element
+ starts->InsertPartition(partition + 1, position);
+ values->InsertValue(partition + 1, 1, value);
+ }
+ }
+ }
+public:
+ SparseVector() {
+ starts = new Partitioning(8);
+ values = new SplitVector<T>();
+ values->InsertValue(0, 2, T());
+ }
+ ~SparseVector() {
+ delete starts;
+ starts = NULL;
+ // starts dead here but not used by ClearValue.
+ for (int part = 0; part < values->Length(); part++) {
+ ClearValue(part);
+ }
+ delete values;
+ values = NULL;
+ }
+ int Length() const {
+ return starts->PositionFromPartition(starts->Partitions());
+ }
+ int Elements() const {
+ return starts->Partitions();
+ }
+ int PositionOfElement(int element) const {
+ return starts->PositionFromPartition(element);
+ }
+ T ValueAt(int position) const {
+ assert(position < Length());
+ const int partition = starts->PartitionFromPosition(position);
+ const int startPartition = starts->PositionFromPartition(partition);
+ if (startPartition == position) {
+ return values->ValueAt(partition);
+ } else {
+ return T();
+ }
+ }
+ void SetValueAt(int position, T value) {
+ CommonSetValueAt(position, value);
+ }
+ void InsertSpace(int position, int insertLength) {
+ assert(position <= Length()); // Only operation that works at end.
+ const int partition = starts->PartitionFromPosition(position);
+ const int startPartition = starts->PositionFromPartition(partition);
+ if (startPartition == position) {
+ T valueCurrent = values->ValueAt(partition);
+ // Inserting at start of run so make previous longer
+ if (partition == 0) {
+ // Inserting at start of document so ensure 0
+ if (valueCurrent != T()) {
+ ClearValue(0);
+ starts->InsertPartition(1, 0);
+ values->InsertValue(1, 1, valueCurrent);
+ starts->InsertText(0, insertLength);
+ } else {
+ starts->InsertText(partition, insertLength);
+ }
+ } else {
+ if (valueCurrent != T()) {
+ starts->InsertText(partition - 1, insertLength);
+ } else {
+ // Insert at end of run so do not extend style
+ starts->InsertText(partition, insertLength);
+ }
+ }
+ } else {
+ starts->InsertText(partition, insertLength);
+ }
+ }
+ void DeletePosition(int position) {
+ assert(position < Length());
+ int partition = starts->PartitionFromPosition(position);
+ const int startPartition = starts->PositionFromPartition(partition);
+ if (startPartition == position) {
+ if (partition == 0) {
+ ClearValue(0);
+ } else if (partition == starts->Partitions()) {
+ // This should not be possible
+ ClearValue(partition);
+ throw std::runtime_error("SparseVector: deleting end partition.");
+ } else {
+ ClearValue(partition);
+ starts->RemovePartition(partition);
+ values->Delete(partition);
+ // Its the previous partition now that gets smaller
+ partition--;
+ }
+ }
+ starts->InsertText(partition, -1);
+ }
+ void Check() const {
+ if (Length() < 0) {
+ throw std::runtime_error("SparseVector: Length can not be negative.");
+ }
+ if (starts->Partitions() < 1) {
+ throw std::runtime_error("SparseVector: Must always have 1 or more partitions.");
+ }
+ if (starts->Partitions() != values->Length() - 1) {
+ throw std::runtime_error("SparseVector: Partitions and values different lengths.");
+ }
+ // The final element can not be set
+ if (values->ValueAt(values->Length() - 1) != T()) {
+ throw std::runtime_error("SparseVector: Unused style at end changed.");
+ }
+ }
+};
+
+// The specialization for const char * makes copies and deletes them as needed.
+
+template<>
+inline void SparseVector<const char *>::ClearValue(int partition) {
+ const char *value = values->ValueAt(partition);
+ delete []value;
+ values->SetValueAt(partition, NULL);
+}
+
+template<>
+inline void SparseVector<const char *>::SetValueAt(int position, const char *value) {
+ // Make a copy of the string
+ if (value) {
+ const size_t len = strlen(value);
+ char *valueCopy = new char[len + 1]();
+ std::copy(value, value + len, valueCopy);
+ CommonSetValueAt(position, valueCopy);
+ } else {
+ CommonSetValueAt(position, NULL);
+ }
+}
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx
index 0f026c4..292c888 100644
--- a/scintilla/src/ViewStyle.cxx
+++ b/scintilla/src/ViewStyle.cxx
@@ -153,6 +153,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
textStart = source.textStart;
zoomLevel = source.zoomLevel;
viewWhitespace = source.viewWhitespace;
+ tabDrawMode = source.tabDrawMode;
whitespaceSize = source.whitespaceSize;
viewIndentationGuides = source.viewIndentationGuides;
viewEOL = source.viewEOL;
@@ -293,6 +294,7 @@ void ViewStyle::Init(size_t stylesSize_) {
textStart = marginInside ? fixedColumnWidth : leftMarginWidth;
zoomLevel = 0;
viewWhitespace = wsInvisible;
+ tabDrawMode = tdLongArrow;
whitespaceSize = 1;
viewIndentationGuides = ivNone;
viewEOL = false;
@@ -445,6 +447,17 @@ int ViewStyle::ExternalMarginWidth() const {
return marginInside ? 0 : fixedColumnWidth;
}
+int ViewStyle::MarginFromLocation(Point pt) const {
+ int margin = -1;
+ int x = textStart - fixedColumnWidth;
+ for (size_t i = 0; i < ms.size(); i++) {
+ if ((pt.x >= x) && (pt.x < x + ms[i].width))
+ margin = static_cast<int>(i);
+ x += ms[i].width;
+ }
+ return margin;
+}
+
bool ViewStyle::ValidStyle(size_t styleIndex) const {
return styleIndex < styles.size();
}
diff --git a/scintilla/src/ViewStyle.h b/scintilla/src/ViewStyle.h
index 381ef79..2f7afe6 100644
--- a/scintilla/src/ViewStyle.h
+++ b/scintilla/src/ViewStyle.h
@@ -55,6 +55,8 @@ enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2, wsVisibleOnlyInIndent=3};
+enum TabDrawMode {tdLongArrow=0, tdStrikeOut=1};
+
typedef std::map<FontSpecification, FontRealised *> FontMap;
enum WrapMode { eWrapNone, eWrapWord, eWrapChar, eWrapWhitespace };
@@ -133,6 +135,7 @@ public:
int textStart; ///< Starting x position of text within the view
int zoomLevel;
WhiteSpaceVisibility viewWhitespace;
+ TabDrawMode tabDrawMode;
int whitespaceSize;
IndentView viewIndentationGuides;
bool viewEOL;
@@ -184,6 +187,7 @@ public:
void SetStyleFontName(int styleIndex, const char *name);
bool ProtectionActive() const;
int ExternalMarginWidth() const;
+ int MarginFromLocation(Point pt) const;
bool ValidStyle(size_t styleIndex) const;
void CalcLargestMarkerHeight();
ColourOptional Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const;