diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/EditView.cxx | 51 | ||||
-rw-r--r-- | src/Editor.cxx | 50 | ||||
-rw-r--r-- | src/Geometry.h | 4 | ||||
-rw-r--r-- | src/ViewStyle.cxx | 19 | ||||
-rw-r--r-- | src/ViewStyle.h | 10 |
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; |