aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorTse Kit Yam <me@kytse.com>2016-11-29 14:14:21 +1100
committerTse Kit Yam <me@kytse.com>2016-11-29 14:14:21 +1100
commit4ae76e455aec66826a284356d63cc2b5995c0b2f (patch)
treec0466475514dee0da647dfa800cb1ccfc4647f0e /src
parent6bed4e4aa02025e1bd0c294a44c9371fb6b176f1 (diff)
downloadscintilla-mirror-4ae76e455aec66826a284356d63cc2b5995c0b2f.tar.gz
Textual tags may be displayed on folded lines with SCI_TOGGLEFOLDSHOWTEXT.
Diffstat (limited to 'src')
-rw-r--r--src/ContractionState.cxx32
-rw-r--r--src/ContractionState.h8
-rw-r--r--src/EditModel.cxx1
-rw-r--r--src/EditModel.h1
-rw-r--r--src/EditView.cxx139
-rw-r--r--src/EditView.h4
-rw-r--r--src/Editor.cxx10
7 files changed, 179 insertions, 16 deletions
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx
index 80f79de29..41627c173 100644
--- a/src/ContractionState.cxx
+++ b/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/src/ContractionState.h b/src/ContractionState.h
index 96cbf0763..622696939 100644
--- a/src/ContractionState.h
+++ b/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/src/EditModel.cxx b/src/EditModel.cxx
index 35903c6b8..0f64e07f9 100644
--- a/src/EditModel.cxx
+++ b/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/src/EditModel.h b/src/EditModel.h
index 021bf6770..847fd728d 100644
--- a/src/EditModel.h
+++ b/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/src/EditView.cxx b/src/EditView.cxx
index 04eea0ea5..8ffc1bcff 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -879,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;
}
@@ -948,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;
@@ -1071,6 +1061,95 @@ static void DrawIndicators(Surface *surface, const EditModel &model, const ViewS
}
}
+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;
}
@@ -1789,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);
}
@@ -2002,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/src/EditView.h b/src/EditView.h
index dcfa352f4..83dd8bb1f 100644
--- a/src/EditView.h
+++ b/src/EditView.h
@@ -124,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,
@@ -140,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/src/Editor.cxx b/src/Editor.cxx
index 558b642b0..43d28a8c0 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -7059,6 +7059,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;