aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/EditView.cxx51
-rw-r--r--src/Editor.cxx50
-rw-r--r--src/Geometry.h4
-rw-r--r--src/ViewStyle.cxx19
-rw-r--r--src/ViewStyle.h10
5 files changed, 81 insertions, 53 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx
index 5549e73db..2b389ecee 100644
--- a/src/EditView.cxx
+++ b/src/EditView.cxx
@@ -919,35 +919,35 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r
textBack, textFore);
}
-static void DrawFrame(Surface *surface, ColourAlpha colour, int alpha, PRectangle rcFrame) {
- if (alpha != SC_ALPHA_NOALPHA) {
- surface->AlphaRectangle(rcFrame, 0, FillStroke(ColourAlpha(colour, alpha)));
- } else {
- surface->FillRectangleAligned(rcFrame, Fill(colour));
+static void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, int subLine) {
+ const std::optional<ColourAlpha> caretlineBack = vsDraw.ElementColour(SC_ELEMENT_CARET_LINE_BACK);
+ if (!caretlineBack) {
+ return;
}
-}
-static void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, int subLine) {
+ const ColourAlpha colourFrame = (vsDraw.caretLine.layer == Layer::base) ?
+ caretlineBack->Opaque() : *caretlineBack;
+
const int width = vsDraw.GetFrameWidth();
- if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.alpha != SC_ALPHA_NOALPHA) {
+
+ // 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::over) {
// Left
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.left, rcLine.top, rcLine.left + width, rcLine.bottom));
+ surface->FillRectangleAligned(Side(rcLine, Edge::left, width), colourFrame);
}
if (subLine == 0) {
// Top
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.left + width, rcLine.top, rcLine.right - width, rcLine.top + width));
+ surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::top, width), colourFrame);
}
- if (subLine == ll->lines - 1 || vsDraw.caretLine.alpha != SC_ALPHA_NOALPHA) {
+ if (subLine == ll->lines - 1 || vsDraw.caretLine.layer == Layer::over) {
// Right
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.right - width, rcLine.top, rcLine.right, rcLine.bottom));
+ surface->FillRectangleAligned(Side(rcLine, Edge::right, width), colourFrame);
}
if (subLine == ll->lines - 1) {
// Bottom
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.left + width, rcLine.bottom - width, rcLine.right - width, rcLine.bottom));
+ surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::bottom, width), colourFrame);
}
}
@@ -1082,10 +1082,9 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle
drawWrapMarkEnd = ll->LineStart(subLine + 1) != 0;
}
if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) {
- const int width = vsDraw.GetFrameWidth();
// Draw right of frame under marker
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.right - width, rcLine.top, rcLine.right, rcLine.bottom));
+ surface->FillRectangleAligned(Side(rcLine, Edge::right, vsDraw.GetFrameWidth()),
+ vsDraw.ElementColour(SC_ELEMENT_CARET_LINE_BACK)->Opaque());
}
}
@@ -1667,10 +1666,9 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c
vsDraw.styles[STYLE_DEFAULT].back));
if (vsDraw.IsLineFrameOpaque(caretActive, ll->containsCaret)) {
- const int width = vsDraw.GetFrameWidth();
// Draw left of frame under marker
- DrawFrame(surface, vsDraw.caretLine.background, vsDraw.caretLine.alpha,
- PRectangle(rcLine.left, rcLine.top, rcLine.left + width, rcLine.bottom));
+ surface->FillRectangleAligned(Side(rcLine, Edge::left, vsDraw.GetFrameWidth()),
+ vsDraw.ElementColour(SC_ELEMENT_CARET_LINE_BACK)->Opaque());
}
if (vsDraw.wrap.visualFlags & SC_WRAPVISUALFLAG_START) {
@@ -1872,12 +1870,12 @@ static void DrawTranslucentSelection(Surface *surface, const EditModel &model, c
// Draw any translucent whole line states
static void DrawTranslucentLineState(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, PRectangle rcLine, int subLine) {
- if ((model.caret.active || vsDraw.caretLine.alwaysShow) && vsDraw.caretLine.show && ll->containsCaret &&
- vsDraw.caretLine.alpha != SC_ALPHA_NOALPHA) {
+ if ((model.caret.active || vsDraw.caretLine.alwaysShow) && vsDraw.ElementColour(SC_ELEMENT_CARET_LINE_BACK) && ll->containsCaret &&
+ vsDraw.caretLine.layer == Layer::over) {
if (vsDraw.caretLine.frame) {
DrawCaretLineFramed(surface, vsDraw, ll, rcLine, subLine);
} else {
- SimpleAlphaRectangle(surface, rcLine, vsDraw.caretLine.background, vsDraw.caretLine.alpha);
+ surface->FillRectangleAligned(rcLine, *vsDraw.ElementColour(SC_ELEMENT_CARET_LINE_BACK));
}
}
const int marksOfLine = model.pdoc->GetMark(line);
@@ -2526,7 +2524,6 @@ Sci::Position EditView::FormatRange(bool draw, const Sci_RangeToFormat *pfr, Sur
vsPrint.elementBaseColours.clear();
vsPrint.whitespaceColours.back.reset();
vsPrint.whitespaceColours.fore.reset();
- vsPrint.caretLine.show = false;
vsPrint.caretLine.alwaysShow = false;
// Don't highlight matching braces using indicators
vsPrint.braceHighlightIndicatorSet = false;
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 35ca7bb77..694ac2f5f 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -7248,10 +7248,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return pdoc->GetMaxLineState();
case SCI_GETCARETLINEVISIBLE:
- return vs.caretLine.show;
+ return vs.ElementColour(SC_ELEMENT_CARET_LINE_BACK) ? 1 : 0;
case SCI_SETCARETLINEVISIBLE:
- vs.caretLine.show = wParam != 0;
- InvalidateStyleRedraw();
+ if (wParam) {
+ if (!vs.elementColours.count(SC_ELEMENT_CARET_LINE_BACK)) {
+ vs.elementColours[SC_ELEMENT_CARET_LINE_BACK] = ColourAlpha(0xFF, 0xFF, 0);
+ InvalidateStyleRedraw();
+ }
+ } else {
+ if (vs.ResetElement(SC_ELEMENT_CARET_LINE_BACK)) {
+ InvalidateStyleRedraw();
+ }
+ }
break;
case SCI_GETCARETLINEVISIBLEALWAYS:
return vs.caretLine.alwaysShow;
@@ -7267,16 +7275,38 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
InvalidateStyleRedraw();
break;
case SCI_GETCARETLINEBACK:
- return vs.caretLine.background.OpaqueRGB();
+ if (vs.ElementColour(SC_ELEMENT_CARET_LINE_BACK))
+ return vs.ElementColour(SC_ELEMENT_CARET_LINE_BACK)->OpaqueRGB();
+ else
+ return 0;
+
case SCI_SETCARETLINEBACK:
- vs.caretLine.background = ColourAlpha::FromRGB(static_cast<int>(wParam));
+ vs.SetElementRGB(SC_ELEMENT_CARET_LINE_BACK, static_cast<int>(wParam));
InvalidateStyleRedraw();
break;
+
+ case SCI_GETCARETLINELAYER:
+ return static_cast<sptr_t>(vs.caretLine.layer);
+
+ case SCI_SETCARETLINELAYER:
+ if (vs.caretLine.layer != static_cast<Layer>(wParam)) {
+ vs.caretLine.layer = static_cast<Layer>(wParam);
+ UpdateBaseElements();
+ InvalidateStyleRedraw();
+ }
+ break;
+
case SCI_GETCARETLINEBACKALPHA:
- return vs.caretLine.alpha;
- case SCI_SETCARETLINEBACKALPHA:
- vs.caretLine.alpha = static_cast<int>(wParam);
- InvalidateStyleRedraw();
+ if (vs.caretLine.layer == Layer::base)
+ return SC_ALPHA_NOALPHA;
+ return vs.ElementColour(SC_ELEMENT_CARET_LINE_BACK).value_or(ColourAlpha()).GetAlpha();
+
+ case SCI_SETCARETLINEBACKALPHA: {
+ const Layer layerNew = (wParam == SC_ALPHA_NOALPHA) ? Layer::base : Layer::over;
+ vs.caretLine.layer = layerNew;
+ vs.SetElementAlpha(SC_ELEMENT_CARET_LINE_BACK, static_cast<int>(wParam));
+ InvalidateStyleRedraw();
+ }
break;
// Folding messages
@@ -7441,7 +7471,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
break;
case SCI_SETSELALPHA: {
- Layer layerNew = (wParam == SC_ALPHA_NOALPHA) ? Layer::base : Layer::over;
+ const Layer layerNew = (wParam == SC_ALPHA_NOALPHA) ? Layer::base : Layer::over;
if (vs.selection.layer != layerNew) {
vs.selection.layer = layerNew;
UpdateBaseElements();
diff --git a/src/Geometry.h b/src/Geometry.h
index 01af92969..a6e49ad5b 100644
--- a/src/Geometry.h
+++ b/src/Geometry.h
@@ -129,6 +129,10 @@ public:
return PRectangle(left + delta, top + delta, right - delta, bottom - delta);
}
+ constexpr PRectangle Inset(Point delta) const noexcept {
+ return PRectangle(left + delta.x, top + delta.y, right - delta.x, bottom - delta.y);
+ }
+
constexpr Point Centre() const noexcept {
return Point((left + right) / 2, (top + bottom) / 2);
}
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index a8fcd2d8c..60334c2ea 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -243,10 +243,10 @@ void ViewStyle::Init(size_t stylesSize_) {
caret.style = CARETSTYLE_LINE;
caret.width = 1;
- caretLine.background = ColourAlpha(0xff, 0xff, 0);
- caretLine.show = false;
+ elementColours.erase(SC_ELEMENT_CARET_LINE_BACK);
+ elementAllowsTranslucent.insert(SC_ELEMENT_CARET_LINE_BACK);
caretLine.alwaysShow = false;
- caretLine.alpha = SC_ALPHA_NOALPHA;
+ caretLine.layer = Layer::base;
caretLine.frame = 0;
someStylesProtected = false;
@@ -461,9 +461,10 @@ int ViewStyle::GetFrameWidth() const noexcept {
return std::clamp(caretLine.frame, 1, lineHeight / 3);
}
-bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const noexcept {
- return caretLine.frame && (caretActive || caretLine.alwaysShow) && caretLine.show &&
- (caretLine.alpha == SC_ALPHA_NOALPHA) && lineContainsCaret;
+bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const {
+ return caretLine.frame && (caretActive || caretLine.alwaysShow) &&
+ ElementColour(SC_ELEMENT_CARET_LINE_BACK) &&
+ (caretLine.layer == Layer::base) && lineContainsCaret;
}
// See if something overrides the line background colour: Either if caret is on the line
@@ -474,9 +475,9 @@ bool ViewStyle::IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) cons
// the colour for the highest numbered one is used.
std::optional<ColourAlpha> ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const {
std::optional<ColourAlpha> background;
- if (!caretLine.frame && (caretActive || caretLine.alwaysShow) && caretLine.show &&
- (caretLine.alpha == SC_ALPHA_NOALPHA) && lineContainsCaret) {
- background = caretLine.background;
+ if (!caretLine.frame && (caretActive || caretLine.alwaysShow) &&
+ (caretLine.layer == Layer::base) && lineContainsCaret) {
+ background = ElementColour(SC_ELEMENT_CARET_LINE_BACK);
}
if (!background && marksOfLine) {
int marks = marksOfLine;
diff --git a/src/ViewStyle.h b/src/ViewStyle.h
index 13c489aa2..9f3cae123 100644
--- a/src/ViewStyle.h
+++ b/src/ViewStyle.h
@@ -73,14 +73,10 @@ struct SelectionAppearance {
};
struct CaretLineAppearance {
- // Colour of caret line
- ColourAlpha background;
- // Whether to show the caret line
- bool show;
+ // Whether to draw on base layer or over text
+ Layer layer;
// Also show when non-focused
bool alwaysShow;
- // Translucency. SC_ALPHA_NOALPHA: draw selection background beneath text
- int alpha;
// Non-0: draw a rectangle around line instead of filling line. Value is pixel width of frame
int frame;
};
@@ -222,7 +218,7 @@ public:
bool ValidStyle(size_t styleIndex) const noexcept;
void CalcLargestMarkerHeight() noexcept;
int GetFrameWidth() const noexcept;
- bool IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const noexcept;
+ bool IsLineFrameOpaque(bool caretActive, bool lineContainsCaret) const;
std::optional<ColourAlpha> Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const;
bool SelectionBackgroundDrawn() const noexcept;
bool SelectionTextDrawn() const;