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