diff options
author | nyamatongwe <devnull@localhost> | 2004-04-27 22:13:00 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2004-04-27 22:13:00 +0000 |
commit | 8680d7580a9a94f6cd46b2fc21f9d81851a0b3d8 (patch) | |
tree | 211ca7e06ffa83b909aba98c601e0e8907c963b9 /src/Editor.cxx | |
parent | 816681de6b0d5ed45f6886dfaf18f35ef7c7d191 (diff) | |
download | scintilla-mirror-8680d7580a9a94f6cd46b2fc21f9d81851a0b3d8.tar.gz |
Continuation Marker feature from Hans Eckardt.
Diffstat (limited to 'src/Editor.cxx')
-rw-r--r-- | src/Editor.cxx | 211 |
1 files changed, 198 insertions, 13 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx index af5caf46d..63a015ce6 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -385,6 +385,10 @@ Editor::Editor() { docLineLastWrapped = -1; docLastLineToWrap = -1; backgroundWrapEnabled = true; + wrapVisualFlags = 0; + wrapVisualFlagsLocation = 0; + wrapVisualStartIndent = 0; + actualWrapVisualStartIndent = 0; hsStart = -1; hsEnd = -1; @@ -636,9 +640,16 @@ Point Editor::LocationFromPosition(int pos) { if (posInLine > ll->maxLineLength) { pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)]; } + for (int subLine = 0; subLine < ll->lines; subLine++) { if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) { pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)]; + if (actualWrapVisualStartIndent != 0) { + int lineStart = ll->LineStart(subLine); + bool continuedWrapLine = lineStart != 0; + if (continuedWrapLine) + pt.x += actualWrapVisualStartIndent * vs.aveCharWidth; + } } if (posInLine >= ll->LineStart(subLine)) { pt.y += vs.lineHeight; @@ -691,6 +702,12 @@ int Editor::PositionFromLocation(Point pt) { int lineStart = ll->LineStart(subLine); int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; + + if (actualWrapVisualStartIndent != 0) { + bool continuedWrapLine = lineStart != 0; + if (continuedWrapLine) + pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth; + } for (int i = lineStart; i < lineEnd; i++) { if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || IsEOLChar(ll->chars[i])) { @@ -735,6 +752,12 @@ int Editor::PositionFromLocationClose(Point pt) { int lineStart = ll->LineStart(subLine); int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; + + if (actualWrapVisualStartIndent != 0) { + bool continuedWrapLine = lineStart != 0; + if (continuedWrapLine) + pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth; + } for (int i = lineStart; i < lineEnd; i++) { if (pt.x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || IsEOLChar(ll->chars[i])) { @@ -767,6 +790,12 @@ int Editor::PositionFromLineX(int lineDoc, int x) { int lineStart = ll->LineStart(subLine); int lineEnd = ll->LineStart(subLine + 1); int subLineStart = ll->positions[lineStart]; + + if (actualWrapVisualStartIndent != 0) { + bool continuedWrapLine = lineStart != 0; + if (continuedWrapLine) + x -= actualWrapVisualStartIndent * vs.aveCharWidth; + } for (int i = lineStart; i < lineEnd; i++) { if (x < (((ll->positions[i] + ll->positions[i + 1]) / 2) - subLineStart) || IsEOLChar(ll->chars[i])) { @@ -1992,6 +2021,9 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou // Simple common case where line does not need wrapping. ll->lines = 1; } else { + if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) { + width -= vstyle.aveCharWidth; // take into account the space for end wrap mark + } ll->lines = 0; // Calculate line start positions based upon width. // For now this is simplistic - wraps on byte rather than character and @@ -2018,6 +2050,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou ll->lines++; ll->SetLineStart(ll->lines, lastGoodBreak); startOffset = ll->positions[lastGoodBreak]; + // take into account the space for start wrap mark and indent + startOffset -= actualWrapVisualStartIndent * vstyle.aveCharWidth; p = lastGoodBreak + 1; continue; } @@ -2065,9 +2099,56 @@ void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); } +void Editor::DrawWrapMarker(Surface *surface, PRectangle rcPlace, + bool isEndMarker, ColourAllocated wrapColour) { + surface->PenColour(wrapColour); + + enum { xa = 1 }; // gap before start + int w = rcPlace.right - rcPlace.left - xa - 1; + + bool xStraight = isEndMarker; // x-mirrored symbol for start marker + bool yStraight = true; + //bool yStraight= isEndMarker; // comment in for start marker y-mirrowed + + int x0 = xStraight ? rcPlace.left : rcPlace.right - 1; + int y0 = yStraight ? rcPlace.top : rcPlace.bottom - 1; + + int dy = (rcPlace.bottom - rcPlace.top) / 5; + int y = (rcPlace.bottom - rcPlace.top) / 2 + dy; + + struct Relative { + Surface *surface; + int xBase; + int xDir; + int yBase; + int yDir; + void MoveTo(int xRelative, int yRelative) { + surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative); + } + void LineTo(int xRelative, int yRelative) { + surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative); + } + }; + Relative rel = {surface, x0, xStraight?1:-1, y0, yStraight?1:-1}; + + // arrow head + rel.MoveTo(xa, y); + rel.LineTo(xa + 2*w / 3, y - dy); + rel.MoveTo(xa, y); + rel.LineTo(xa + 2*w / 3, y + dy); + + // arrow body + rel.MoveTo(xa, y); + rel.LineTo(xa + w, y); + rel.LineTo(xa + w, y - 2 * dy); + rel.LineTo(xa - 1, // on windows lineto is exclusive endpoint, perhaps GTK not... + y - 2 * dy); +} + void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, int line, int lineEnd, int xStart, int subLine, int subLineStart, - bool overrideBackground, ColourAllocated background) { + bool overrideBackground, ColourAllocated background, + bool drawWrapMarkEnd, ColourAllocated wrapColour) { int styleMask = pdoc->stylingBitsMask; PRectangle rcSegment = rcLine; @@ -2079,6 +2160,7 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin int posLineEnd = pdoc->LineStart(line + 1); bool eolInSelection = (subLine == (ll->lines - 1)) && (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd); + if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { if (primarySelection) surface->FillRectangle(rcSegment, vsDraw.selbackground.allocated); @@ -2099,6 +2181,20 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin } else { surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); } + + if (drawWrapMarkEnd) { + PRectangle rcPlace = rcSegment; + + if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) { + rcPlace.left = xEol + xStart; + rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; + } else { + // draw left of the right text margin, to avoid clipping by the current clip rect + rcPlace.right = rcLine.right - vs.rightMarginWidth; + rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; + } + DrawWrapMarker(surface, rcPlace, true, wrapColour); + } } void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, @@ -2151,9 +2247,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis (!overrideBackground) && (vsDraw.whitespaceBackgroundSet); bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. - int indentWidth = pdoc->indentInChars * vsDraw.spaceWidth; - if (indentWidth == 0) - indentWidth = pdoc->tabInChars * vsDraw.spaceWidth; + int indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth; int posLineStart = pdoc->LineStart(line); @@ -2165,6 +2259,51 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis lineStart = ll->LineStart(subLine); lineEnd = ll->LineStart(subLine + 1); } + + bool drawWrapMarkEnd = false; + + if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) { + if (subLine + 1 < ll->lines) { + drawWrapMarkEnd = ll->LineStart(subLine + 1) != 0; + } + } + + if (actualWrapVisualStartIndent != 0) { + + bool continuedWrapLine = false; + if (subLine < ll->lines) { + continuedWrapLine = ll->LineStart(subLine) != 0; + } + + if (continuedWrapLine) { + // draw continuation rect + PRectangle rcPlace = rcSegment; + + rcPlace.left = ll->positions[startseg] + xStart - subLineStart; + rcPlace.right = rcPlace.left + actualWrapVisualStartIndent * vsDraw.aveCharWidth; + + // default bgnd here.. + surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated); + + // main line style would be below but this would be inconsistent with end markers + // also would possibly not be the style at wrap point + //int styleMain = ll->styles[lineStart]; + //surface->FillRectangle(rcPlace, vsDraw.styles[styleMain].back.allocated); + + if (wrapVisualFlags & SC_WRAPVISUALFLAG_START) { + + if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_START_BY_TEXT) + rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; + else + rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; + + DrawWrapMarker(surface, rcPlace, false, vsDraw.whitespaceForeground.allocated); + } + + xStart += actualWrapVisualStartIndent * vsDraw.aveCharWidth; + } + } + int i; // Background drawing loop @@ -2222,7 +2361,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis if (twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, - xStart, subLine, subLineStart, overrideBackground, background); + xStart, subLine, subLineStart, overrideBackground, background, + drawWrapMarkEnd, vsDraw.whitespaceForeground.allocated); } inIndentation = subLine == 0; // Do not handle indentation except on first subline. @@ -2412,10 +2552,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } } // End of the drawing of the current line - if (!twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, - xStart, subLine, subLineStart, overrideBackground, background); + xStart, subLine, subLineStart, overrideBackground, background, + drawWrapMarkEnd, vsDraw.whitespaceForeground.allocated); } if (vsDraw.edgeState == EDGE_LINE) { @@ -2681,7 +2821,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE; int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK) & ~(0xFFF0000); - int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + int indentationStep = pdoc->IndentSize(); // Draw line above fold if ((FoldLevelPrev < FoldLevelCurr) || @@ -2719,6 +2859,13 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { if ((offset >= ll->LineStart(subLine)) && ((offset < ll->LineStart(subLine + 1)) || offset == ll->numCharsInLine)) { int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart; + + if (actualWrapVisualStartIndent != 0) { + int lineStart = ll->LineStart(subLine); + bool continuedWrapLine = lineStart != 0; + if (continuedWrapLine) + xposCaret += actualWrapVisualStartIndent * vs.aveCharWidth; + } int widthOverstrikeCaret; if (posCaret == pdoc->Length()) { // At end of document widthOverstrikeCaret = vs.aveCharWidth; @@ -3249,7 +3396,7 @@ void Editor::DelCharBack(bool allowLineStartDeletion) { pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) { pdoc->BeginUndoAction(); int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + int indentationStep = pdoc->IndentSize(); if (indentation % indentationStep == 0) { pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); } else { @@ -4292,8 +4439,7 @@ void Editor::Indent(bool forwards) { if (pdoc->GetColumn(currentPos) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) && pdoc->tabIndents) { int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); - //~ pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep); + int indentationStep = pdoc->IndentSize(); pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep); SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); } else { @@ -4317,7 +4463,7 @@ void Editor::Indent(bool forwards) { pdoc->tabIndents) { pdoc->BeginUndoAction(); int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = (pdoc->indentInChars ? pdoc->indentInChars : pdoc->tabInChars); + int indentationStep = pdoc->IndentSize(); pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos)); pdoc->EndUndoAction(); @@ -5996,8 +6142,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_SETTABWIDTH: - if (wParam > 0) + if (wParam > 0) { pdoc->tabInChars = wParam; + if (pdoc->indentInChars == 0) + pdoc->actualIndentInChars = pdoc->tabInChars; + } InvalidateStyleRedraw(); break; @@ -6006,6 +6155,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_SETINDENT: pdoc->indentInChars = wParam; + if (pdoc->indentInChars != 0) + pdoc->actualIndentInChars = pdoc->indentInChars; + else + pdoc->actualIndentInChars = pdoc->tabInChars; InvalidateStyleRedraw(); break; @@ -6068,6 +6221,38 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETWRAPMODE: return wrapState; + case SCI_SETWRAPVISUALFLAGS: + wrapVisualFlags = wParam; + actualWrapVisualStartIndent = wrapVisualStartIndent; + if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0)) + actualWrapVisualStartIndent = 1; // must indent to show start visual + InvalidateStyleRedraw(); + ReconfigureScrollBars(); + break; + + case SCI_GETWRAPVISUALFLAGS: + return wrapVisualFlags; + + case SCI_SETWRAPVISUALFLAGSLOCATION: + wrapVisualFlagsLocation = wParam; + InvalidateStyleRedraw(); + break; + + case SCI_GETWRAPVISUALFLAGSLOCATION: + return wrapVisualFlagsLocation; + + case SCI_SETWRAPSTARTINDENT: + wrapVisualStartIndent = wParam; + actualWrapVisualStartIndent = wrapVisualStartIndent; + if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0)) + actualWrapVisualStartIndent = 1; // must indent to show start visual + InvalidateStyleRedraw(); + ReconfigureScrollBars(); + break; + + case SCI_GETWRAPSTARTINDENT: + return wrapVisualStartIndent; + case SCI_SETLAYOUTCACHE: llc.SetLevel(wParam); break; |