diff options
Diffstat (limited to 'scintilla/src')
-rw-r--r-- | scintilla/src/CaseConvert.cxx | 9 | ||||
-rw-r--r-- | scintilla/src/CaseConvert.h | 3 | ||||
-rw-r--r-- | scintilla/src/Catalogue.cxx | 1 | ||||
-rw-r--r-- | scintilla/src/CellBuffer.h | 16 | ||||
-rw-r--r-- | scintilla/src/ContractionState.cxx | 32 | ||||
-rw-r--r-- | scintilla/src/ContractionState.h | 8 | ||||
-rw-r--r-- | scintilla/src/Document.cxx | 12 | ||||
-rw-r--r-- | scintilla/src/EditModel.cxx | 1 | ||||
-rw-r--r-- | scintilla/src/EditModel.h | 1 | ||||
-rw-r--r-- | scintilla/src/EditView.cxx | 236 | ||||
-rw-r--r-- | scintilla/src/EditView.h | 8 | ||||
-rw-r--r-- | scintilla/src/Editor.cxx | 74 | ||||
-rw-r--r-- | scintilla/src/Editor.h | 9 | ||||
-rw-r--r-- | scintilla/src/Indicator.cxx | 15 | ||||
-rw-r--r-- | scintilla/src/Indicator.h | 2 | ||||
-rw-r--r-- | scintilla/src/PositionCache.cxx | 8 | ||||
-rw-r--r-- | scintilla/src/PositionCache.h | 12 | ||||
-rw-r--r-- | scintilla/src/ScintillaBase.cxx | 14 | ||||
-rw-r--r-- | scintilla/src/ScintillaBase.h | 4 | ||||
-rw-r--r-- | scintilla/src/SparseVector.h | 186 | ||||
-rw-r--r-- | scintilla/src/ViewStyle.cxx | 13 | ||||
-rw-r--r-- | scintilla/src/ViewStyle.h | 4 |
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;
|