From d38429108f2035d9fab0919271f6715cd1b7eda6 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 31 Jul 2022 22:21:57 +1000 Subject: Add SC_MARK_BAR marker and INDIC_POINT_TOP indicator which are useful for change history. Tweak size of INDIC_POINT and INDIC_POINTCHARACTER. Let translucency of INDIC_COMPOSITIONTHICK be adjusted. --- doc/ScintillaDoc.html | 17 ++++++++++++++--- doc/ScintillaHistory.html | 10 ++++++++++ include/Scintilla.h | 2 ++ include/Scintilla.iface | 2 ++ include/ScintillaTypes.h | 2 ++ src/Indicator.cxx | 20 ++++++++++++++++++-- src/LineMarker.cxx | 31 +++++++++++++++++++++++++++++++ src/MarginView.cxx | 24 +++++++++++++++++++++++- src/ViewStyle.cxx | 15 +++++++++++++++ src/ViewStyle.h | 1 + 10 files changed, 118 insertions(+), 6 deletions(-) diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 3149b06a0..d4c38902b 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -5203,8 +5203,9 @@ struct Sci_TextToFindFull { SC_MARK_LEFTRECT, SC_MARK_FULLRECT, SC_MARK_BOOKMARK, - SC_MARK_VERTICALBOOKMARK, and - SC_MARK_UNDERLINE. + SC_MARK_VERTICALBOOKMARK, + SC_MARK_UNDERLINE, and + SC_MARK_BAR.

The SC_MARK_BACKGROUND marker changes the background colour of the line only. @@ -5770,7 +5771,9 @@ struct Sci_TextToFindFull { A 2-pixel thick underline located at the bottom of the line to try to avoid touching the character base. Each side is inset 1 pixel so that different indicators in this style covering a range appear isolated. - This is similar to an appearance used for the target in Asian language input composition. + This is similar to an appearance used for the target in Asian language input composition. + The translucency of this indicator can be changed with + SCI_INDICSETOUTLINEALPHA. @@ -5807,6 +5810,14 @@ struct Sci_TextToFindFull { Draw a triangle below the centre of the first character of the indicator range. + + INDIC_POINT_TOP + + 22 + + Draw a triangle above the start of the indicator range.. + + diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 11c19f1e3..7895d131a 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -586,6 +586,16 @@ in the margin or in the text.

  • + Add SC_MARK_BAR marker and INDIC_POINT_TOP indicator. + SC_MARK_BAR is an outlined and filled rectangle that takes the full height of the line and 1/3 + of the margin width. + To give a connected appearence, it displays even on wrapped lines and draws end caps on the first and last line. + INDIC_POINT_TOP is the same as INDIC_POINT but draws at the top of the line instead of the bottom. + INDIC_POINT and INDIC_POINTCHARACTER were tweaked to be 1 pixel taller and 2 pixels wider in + two-phase draw mode to be clearer. + The translucency of INDIC_COMPOSITIONTHICK can be changed with SCI_INDICSETOUTLINEALPHA. +
  • +
  • Line state optimized to avoid excess allocations by always allocating for every line. This makes SCI_GETMAXLINESTATE less useful although it can still distinguish cases where line state was never set for any lines. diff --git a/include/Scintilla.h b/include/Scintilla.h index 0b1121cb9..0dacb3c1b 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -152,6 +152,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_MARK_RGBAIMAGE 30 #define SC_MARK_BOOKMARK 31 #define SC_MARK_VERTICALBOOKMARK 32 +#define SC_MARK_BAR 33 #define SC_MARK_CHARACTER 10000 #define SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN 21 #define SC_MARKNUM_HISTORY_SAVED 22 @@ -357,6 +358,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define INDIC_POINTCHARACTER 19 #define INDIC_GRADIENT 20 #define INDIC_GRADIENTCENTRE 21 +#define INDIC_POINT_TOP 22 #define INDIC_CONTAINER 8 #define INDIC_IME 32 #define INDIC_IME_MAX 35 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 09a83142b..646c01a8a 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -358,6 +358,7 @@ val SC_MARK_UNDERLINE=29 val SC_MARK_RGBAIMAGE=30 val SC_MARK_BOOKMARK=31 val SC_MARK_VERTICALBOOKMARK=32 +val SC_MARK_BAR=33 val SC_MARK_CHARACTER=10000 @@ -846,6 +847,7 @@ val INDIC_POINT=18 val INDIC_POINTCHARACTER=19 val INDIC_GRADIENT=20 val INDIC_GRADIENTCENTRE=21 +val INDIC_POINT_TOP=22 # INDIC_CONTAINER, INDIC_IME, INDIC_IME_MAX, and INDIC_MAX are indicator numbers, # not IndicatorStyles so should not really be in the INDIC_ enumeration. diff --git a/include/ScintillaTypes.h b/include/ScintillaTypes.h index 962542011..ba19b1253 100644 --- a/include/ScintillaTypes.h +++ b/include/ScintillaTypes.h @@ -86,6 +86,7 @@ enum class MarkerSymbol { RgbaImage = 30, Bookmark = 31, VerticalBookmark = 32, + Bar = 33, Character = 10000, }; @@ -217,6 +218,7 @@ enum class IndicatorStyle { PointCharacter = 19, Gradient = 20, GradientCentre = 21, + PointTop = 22, }; enum class IndicatorNumbers { diff --git a/src/Indicator.cxx b/src/Indicator.cxx index bd02a01d1..cb7d5deba 100644 --- a/src/Indicator.cxx +++ b/src/Indicator.cxx @@ -252,7 +252,7 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r case IndicatorStyle::CompositionThick: { const PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); - surface->FillRectangle(rcComposition, sacDraw.fore); + surface->FillRectangle(rcComposition, ColourRGBA(sacDraw.fore, outlineAlpha)); } break; @@ -269,7 +269,7 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r const XYPOSITION x = (sacDraw.style == IndicatorStyle::Point) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2); // 0.5f is to hit midpoint of pixels: const XYPOSITION ix = std::round(x) + 0.5f; - const XYPOSITION iy = std::floor(rc.top + 1.0f) + 0.5f; + const XYPOSITION iy = std::floor(rc.top) + 0.5f; const Point pts[] = { Point(ix - pixelHeight, iy + pixelHeight), // Left Point(ix + pixelHeight, iy + pixelHeight), // Right @@ -279,6 +279,22 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r } break; + case IndicatorStyle::PointTop: + if (rcCharacter.Width() >= 0.1) { + const XYPOSITION pixelHeight = std::floor(rc.Height() - 1.0f); // 1 pixel onto previous line if multiphase + const XYPOSITION x = rcCharacter.left; + // 0.5f is to hit midpoint of pixels: + const XYPOSITION ix = std::round(x) + 0.5f; + const XYPOSITION iy = std::floor(rcLine.top) + 0.5f; + const Point pts[] = { + Point(ix - pixelHeight, iy), // Left + Point(ix + pixelHeight, iy), // Right + Point(ix, iy + pixelHeight) // Bottom + }; + surface->Polygon(pts, std::size(pts), FillStroke(sacDraw.fore)); + } + break; + default: // Either IndicatorStyle::Plain or unknown surface->FillRectangle(PRectangle(rcAligned.left, ymid, diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx index df8c3d55a..9794f523c 100644 --- a/src/LineMarker.cxx +++ b/src/LineMarker.cxx @@ -514,6 +514,37 @@ void LineMarker::Draw(Surface *surface, const PRectangle &rcWhole, const Font *f } break; + case MarkerSymbol::Bar: { + PRectangle rcBar = rcWhole; + const XYPOSITION widthBar = std::floor(rcWhole.Width() / 3.0); + rcBar.left = centreX - std::floor(widthBar / 2.0); + rcBar.right = rcBar.left + widthBar; + surface->SetClip(rcWhole); + switch (part) { + case LineMarker::FoldPart::headWithTail: + surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth)); + break; + case LineMarker::FoldPart::head: + rcBar.bottom += 5; + surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth)); + break; + case LineMarker::FoldPart::tail: + rcBar.top -= 5; + surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth)); + break; + case LineMarker::FoldPart::body: + rcBar.top -= 5; + rcBar.bottom += 5; + surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth)); + break; + default: + break; + } + surface->PopClip(); + } + break; + + case MarkerSymbol::Bookmark: { const XYPOSITION halfHeight = std::floor(minDim / 3); Point pts[] = { diff --git a/src/MarginView.cxx b/src/MarginView.cxx index 7d2f4a8cd..6e43c0f0c 100644 --- a/src/MarginView.cxx +++ b/src/MarginView.cxx @@ -283,7 +283,11 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn const bool firstSubLine = visibleLine == firstVisibleLine; const bool lastSubLine = visibleLine == lastVisibleLine; - int marks = firstSubLine ? model.GetMark(lineDoc) : 0; + int marks = model.GetMark(lineDoc); + if (!firstSubLine) { + // Mask off non-continuing marks + marks = marks & vs.maskDrawWrapped; + } bool headWithTail = false; @@ -413,6 +417,24 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn part = LineMarker::FoldPart::tail; } } + if (vs.markers[markBit].markType == MarkerSymbol::Bar) { + const int mask = 1 << markBit; + const bool markBefore = firstSubLine ? (model.GetMark(lineDoc-1) & mask) : true; + const bool markAfter = lastSubLine ? (model.GetMark(lineDoc+1) & mask) : true; + if (markBefore) { + if (markAfter) { + part = LineMarker::FoldPart::body; + } else { + part = LineMarker::FoldPart::tail; + } + } else { + if (markAfter) { + part = LineMarker::FoldPart::head; + } else { + part = LineMarker::FoldPart::headWithTail; + } + } + } vs.markers[markBit].Draw(surface, rcMarker, vs.styles[StyleLineNumber].font.get(), part, marginStyle.style); } marks >>= 1; diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx index 01b94cca1..5160cfc54 100644 --- a/src/ViewStyle.cxx +++ b/src/ViewStyle.cxx @@ -284,6 +284,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) : ViewStyle(source.styles.size()) ms = source.ms; maskInLine = source.maskInLine; maskDrawInText = source.maskDrawInText; + maskDrawWrapped = source.maskDrawWrapped; fixedColumnWidth = source.fixedColumnWidth; marginInside = source.marginInside; textStart = source.textStart; @@ -347,6 +348,17 @@ void ViewStyle::CalculateMarginWidthAndMask() noexcept { break; } } + maskDrawWrapped = 0; + for (int markBit = 0; markBit < 32; markBit++) { + const int maskBit = 1U << markBit; + switch (markers[markBit].markType) { + case MarkerSymbol::Bar: + maskDrawWrapped |= maskBit; + break; + default: // Other marker types do not affect the masks + break; + } + } } void ViewStyle::Refresh(Surface &surface, int tabInChars) { @@ -493,6 +505,9 @@ void ViewStyle::CalcLargestMarkerHeight() noexcept { if (marker.image && marker.image->GetHeight() > largestMarkerHeight) largestMarkerHeight = marker.image->GetHeight(); break; + case MarkerSymbol::Bar: + largestMarkerHeight = lineHeight + 2; + break; default: // Only images have their own natural heights break; } diff --git a/src/ViewStyle.h b/src/ViewStyle.h index c5ee232c3..a91aea501 100644 --- a/src/ViewStyle.h +++ b/src/ViewStyle.h @@ -141,6 +141,7 @@ public: int rightMarginWidth; ///< Spacing margin on right of text int maskInLine = 0; ///< Mask for markers to be put into text because there is nowhere for them to go in margin int maskDrawInText = 0; ///< Mask for markers that always draw in text + int maskDrawWrapped = 0; ///< Mask for markers that draw on wrapped lines std::vector ms; int fixedColumnWidth = 0; ///< Total width of margins bool marginInside; ///< true: margin included in text view, false: separate views -- cgit v1.2.3