diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-10 02:02:10 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2021-10-10 02:02:10 +0300 |
commit | 2bcf60285e1c196bf05cd47a8e04beb150b485ef (patch) | |
tree | 1d48f8db0b5f42725998fef197bcb762a9a64fb2 /src/EditView.cxx | |
parent | 371b6e510e62d7d3ca5fd5133f190ef6a7bb72ff (diff) | |
download | scintilla-mirror-2bcf60285e1c196bf05cd47a8e04beb150b485ef.tar.gz |
Added Scintilla::Curses to allow for terminal drawing of the main caret.
This is the patch from scinterm/patches/02-caretstyle_curses.patch.
Diffstat (limited to 'src/EditView.cxx')
-rw-r--r-- | src/EditView.cxx | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx index 3ab4c17a5..e0f52f501 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -1636,7 +1636,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } const bool caretBlinkState = (model.caret.active && model.caret.on) || (!additionalCaretsBlink && !mainCaret); const bool caretVisibleState = additionalCaretsVisible || mainCaret; - if ((xposCaret >= 0) && vsDraw.IsCaretVisible() && + if ((xposCaret >= 0) && vsDraw.IsCaretVisible(mainCaret) && (drawDrag || (caretBlinkState && caretVisibleState))) { bool canDrawBlockCaret = true; bool drawBlockCaret = false; @@ -1660,7 +1660,8 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt if (xposCaret > 0) caretWidthOffset = 0.51f; // Move back so overlaps both character cells. xposCaret += xStart; - const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : vsDraw.CaretShapeForMode(model.inOverstrike); + const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : + vsDraw.CaretShapeForMode(model.inOverstrike, mainCaret); if (drawDrag) { /* Dragging text, use a line caret */ rcCaret.left = std::round(xposCaret - caretWidthOffset); @@ -1733,6 +1734,22 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c } } +// On the curses platform, the terminal is drawing its own caret, so if the +// caret is within the main selection, do not draw the selection at that +// position. +// Use iDoc from DrawBackground and DrawForeground here because PositionCache +// has broken up the line such that, if the caret is inside the main selection, +// the beginning or end of that selection is at the end of a text segment. +// This function should only be called if iDoc is within the main selection. +static InSelection characterInCursesSelection(Sci::Position iDoc, const EditModel &model, const ViewStyle &vsDraw) { + const SelectionPosition& posCaret = model.sel.RangeMain().caret; + const bool caretAtStart = posCaret < model.sel.RangeMain().anchor && posCaret.Position() == iDoc; + const bool caretAtEnd = posCaret > model.sel.RangeMain().anchor && + vsDraw.DrawCaretInsideSelection(false, false) && + model.pdoc->MovePositionOutsideChar(posCaret.Position()-1, -1) == iDoc; + return (caretAtStart || caretAtEnd) ? InSelection::inNone : InSelection::inMain; +} + void EditView::DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart, int subLine, std::optional<ColourRGBA> background) const { @@ -1743,7 +1760,7 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi // Does not take margin into account but not significant const XYPOSITION xStartVisible = static_cast<XYPOSITION>(subLineStart-xStart); - BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, selBackDrawn, model.pdoc, &model.reprs, nullptr); + BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, selBackDrawn, model.pdoc, &model.reprs, &vsDraw); const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background; @@ -1766,7 +1783,9 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi if (rcSegment.right > rcLine.right) rcSegment.right = rcLine.right; - const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + if (vsDraw.IsMainCursesCaret(inSelection == InSelection::inMain)) + inSelection = characterInCursesSelection(iDoc, model, vsDraw); const bool inHotspot = model.hotspot.Valid() && model.hotspot.ContainsCharacter(iDoc); ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, ll->styles[i], i); @@ -2010,7 +2029,9 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } } } - const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + if (vsDraw.IsMainCursesCaret(inSelection == InSelection::inMain)) + inSelection = characterInCursesSelection(iDoc, model, vsDraw); const std::optional<ColourRGBA> selectionFore = SelectionForeground(model, vsDraw, inSelection); if (selectionFore) { textFore = *selectionFore; |