From 02914e8e53c3e72e9fc3a05f8e75078cad4eb0f6 Mon Sep 17 00:00:00 2001 From: Zufu Liu Date: Tue, 24 Aug 2021 11:14:20 +1000 Subject: Feature [feature-requests:#841] SCI_SETCARETLINEHIGHLIGHTSUBLINE enables highlighting just the subline with the caret when wrapping is on. --- call/ScintillaCall.cxx | 8 ++++++++ doc/ScintillaDoc.html | 8 ++++++++ doc/ScintillaHistory.html | 5 +++++ include/Scintilla.h | 2 ++ include/Scintilla.iface | 6 ++++++ include/ScintillaCall.h | 2 ++ include/ScintillaMessages.h | 2 ++ src/EditView.cxx | 16 ++++++++-------- src/Editor.cxx | 7 +++++++ src/ViewStyle.cxx | 1 + src/ViewStyle.h | 2 ++ test/simpleTests.py | 8 ++++++++ 12 files changed, 59 insertions(+), 8 deletions(-) diff --git a/call/ScintillaCall.cxx b/call/ScintillaCall.cxx index 380d73494..c363fc283 100644 --- a/call/ScintillaCall.cxx +++ b/call/ScintillaCall.cxx @@ -696,6 +696,14 @@ void ScintillaCall::SetCaretLineLayer(Scintilla::Layer layer) { Call(Message::SetCaretLineLayer, static_cast(layer)); } +bool ScintillaCall::CaretLineHighlightSubLine() { + return Call(Message::GetCaretLineHighlightSubLine); +} + +void ScintillaCall::SetCaretLineHighlightSubLine(bool subLine) { + Call(Message::SetCaretLineHighlightSubLine, subLine); +} + void ScintillaCall::SetCaretFore(Colour fore) { Call(Message::SetCaretFore, fore); } diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 245b467c4..01f65cbd1 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -3586,6 +3586,8 @@ struct Sci_TextToFind { SCI_GETCARETLINEFRAME → int
SCI_SETCARETLINEVISIBLEALWAYS(bool alwaysVisible)
SCI_GETCARETLINEVISIBLEALWAYS → bool
+ SCI_SETCARETLINEHIGHLIGHTSUBLINE(bool subLine)
+ SCI_GETCARETLINEHIGHLIGHTSUBLINE → bool

SCI_SETCARETPERIOD(int periodMilliseconds)
SCI_GETCARETPERIOD → int
@@ -3775,6 +3777,12 @@ struct Sci_TextToFind { Default behaviour SCI_SETCARETLINEVISIBLEALWAYS(false) the caret line is only visible when the window is in focus.

+

SCI_SETCARETLINEHIGHLIGHTSUBLINE(bool subLine)
+ SCI_GETCARETLINEHIGHLIGHTSUBLINE → bool
+ Choose to highlight only the subline containing the caret instead of the whole line. + Default behaviour SCI_SETCARETLINEHIGHLIGHTSUBLINE(false) the whole caret line is highlighted. +

+

SCI_SETCARETPERIOD(int periodMilliseconds)
SCI_GETCARETPERIOD → int
The rate at which the caret blinks can be set with SCI_SETCARETPERIOD which diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index b266c774e..f404bed0b 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -586,6 +586,11 @@ Feature #203.

  • + Add SCI_SETCARETLINEHIGHLIGHTSUBLINE to highlight just the subline containing the caret instead of + the whole document line. + Feature #841. +
  • +
  • Fix display of fold lines when wrapped so they are only drawn once per line, not on each subline.
  • diff --git a/include/Scintilla.h b/include/Scintilla.h index d08d90e80..a10c9ed82 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -314,6 +314,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SCI_SETSELECTIONLAYER 2763 #define SCI_GETCARETLINELAYER 2764 #define SCI_SETCARETLINELAYER 2765 +#define SCI_GETCARETLINEHIGHLIGHTSUBLINE 2773 +#define SCI_SETCARETLINEHIGHLIGHTSUBLINE 2774 #define SCI_SETCARETFORE 2069 #define SCI_ASSIGNCMDKEY 2070 #define SCI_CLEARCMDKEY 2071 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index c83773803..d5577417d 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -761,6 +761,12 @@ get Layer GetCaretLineLayer=2764(,) # Set the layer of the background of the line containing the caret. set void SetCaretLineLayer=2765(Layer layer,) +# Get only highlighting subline instead of whole line. +get bool GetCaretLineHighlightSubLine=2773(,) + +# Set only highlighting subline instead of whole line. +set void SetCaretLineHighlightSubLine=2774(bool subLine,) + # Set the foreground colour of the caret. set void SetCaretFore=2069(colour fore,) diff --git a/include/ScintillaCall.h b/include/ScintillaCall.h index d65dbc49f..a5a46ed69 100644 --- a/include/ScintillaCall.h +++ b/include/ScintillaCall.h @@ -214,6 +214,8 @@ public: void SetSelectionLayer(Scintilla::Layer layer); Scintilla::Layer CaretLineLayer(); void SetCaretLineLayer(Scintilla::Layer layer); + bool CaretLineHighlightSubLine(); + void SetCaretLineHighlightSubLine(bool subLine); void SetCaretFore(Colour fore); void AssignCmdKey(int keyDefinition, int sciCommand); void ClearCmdKey(int keyDefinition); diff --git a/include/ScintillaMessages.h b/include/ScintillaMessages.h index 48fbaff31..95ed09530 100644 --- a/include/ScintillaMessages.h +++ b/include/ScintillaMessages.h @@ -151,6 +151,8 @@ enum class Message { SetSelectionLayer = 2763, GetCaretLineLayer = 2764, SetCaretLineLayer = 2765, + GetCaretLineHighlightSubLine = 2773, + SetCaretLineHighlightSubLine = 2774, SetCaretFore = 2069, AssignCmdKey = 2070, ClearCmdKey = 2071, diff --git a/src/EditView.cxx b/src/EditView.cxx index e32e791ec..8a303faea 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -951,19 +951,19 @@ static void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const // Avoid double drawing the corners by removing the left and right sides when drawing top and bottom borders const PRectangle rcWithoutLeftRight = rcLine.Inset(Point(width, 0.0)); - if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.layer != Layer::Base) { + if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { // Left surface->FillRectangleAligned(Side(rcLine, Edge::left, width), colourFrame); } - if (subLine == 0) { + if (subLine == 0 || vsDraw.caretLine.subLine) { // Top surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::top, width), colourFrame); } - if (subLine == ll->lines - 1 || vsDraw.caretLine.layer != Layer::Base) { + if (subLine == ll->lines - 1 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { // Right surface->FillRectangleAligned(Side(rcLine, Edge::right, width), colourFrame); } - if (subLine == ll->lines - 1) { + if (subLine == ll->lines - 1 || vsDraw.caretLine.subLine) { // Bottom surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::bottom, width), colourFrame); } @@ -2340,10 +2340,9 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan const int screenLinePaintFirst = static_cast(rcArea.top) / vsDraw.lineHeight; const int xStart = vsDraw.textStart - model.xOffset + static_cast(ptOrigin.x); - SelectionPosition posCaret = model.sel.RangeMain().caret; - if (model.posDrag.IsValid()) - posCaret = model.posDrag; + const SelectionPosition posCaret = model.posDrag.IsValid() ? model.posDrag : model.sel.RangeMain().caret; const Sci::Line lineCaret = model.pdoc->SciLineFromPosition(posCaret.Position()); + const int caretOffset = static_cast(posCaret.Position() - model.pdoc->LineStart(lineCaret)); PRectangle rcTextArea = rcClient; if (vsDraw.marginInside) { @@ -2410,7 +2409,8 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan durLayout += ep.Duration(true); #endif if (ll) { - ll->containsCaret = !hideSelection && (lineDoc == lineCaret); + ll->containsCaret = !hideSelection && (lineDoc == lineCaret) + && (ll->lines == 1 || !vsDraw.caretLine.subLine || ll->InLine(caretOffset, subLine)); ll->hotspot = model.GetHotSpotRange(); PRectangle rcLine = rcTextArea; diff --git a/src/Editor.cxx b/src/Editor.cxx index b4031c8f1..341165776 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -7325,6 +7325,13 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { InvalidateStyleRedraw(); break; + case Message::GetCaretLineHighlightSubLine: + return vs.caretLine.subLine; + case Message::SetCaretLineHighlightSubLine: + vs.caretLine.subLine = wParam != 0; + InvalidateStyleRedraw(); + break; + case Message::GetCaretLineFrame: return vs.caretLine.frame; case Message::SetCaretLineFrame: diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 47f76d357..366151cee 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -265,6 +265,7 @@ void ViewStyle::Init(size_t stylesSize_) { elementColours.erase(Element::CaretLineBack); elementAllowsTranslucent.insert(Element::CaretLineBack); caretLine.alwaysShow = false; + caretLine.subLine = false; caretLine.layer = Layer::Base; caretLine.frame = 0; diff --git a/src/ViewStyle.h b/src/ViewStyle.h index 8b9f125bd..66a853848 100644 --- a/src/ViewStyle.h +++ b/src/ViewStyle.h @@ -63,6 +63,8 @@ struct CaretLineAppearance { Scintilla::Layer layer; // Also show when non-focused bool alwaysShow; + // highlight sub line instead of whole line + bool subLine; // Non-0: draw a rectangle around line instead of filling line. Value is pixel width of frame int frame; }; diff --git a/test/simpleTests.py b/test/simpleTests.py index e8b9e69c4..2b8b7cdd8 100644 --- a/test/simpleTests.py +++ b/test/simpleTests.py @@ -2028,6 +2028,14 @@ class TestElements(unittest.TestCase): self.assertEquals(self.ElementColour(self.ed.SC_ELEMENT_LIST_BACK), self.testColourAlpha) self.assertTrue(self.ed.GetElementIsSet(self.ed.SC_ELEMENT_LIST_BACK)) + def testSubline(self): + # Default is false + self.assertEquals(self.ed.CaretLineHighlightSubLine, False) + self.ed.CaretLineHighlightSubLine = True + self.assertEquals(self.ed.CaretLineHighlightSubLine, True) + self.ed.CaretLineHighlightSubLine = False + self.assertEquals(self.ed.CaretLineHighlightSubLine, False) + def testReset(self): self.ed.SetElementColour(self.ed.SC_ELEMENT_SELECTION_ADDITIONAL_TEXT, self.testColourAlpha) self.assertEquals(self.ElementColour(self.ed.SC_ELEMENT_SELECTION_ADDITIONAL_TEXT), self.testColourAlpha) -- cgit v1.2.3