diff options
author | Neil <nyamatongwe@gmail.com> | 2021-09-14 14:07:43 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2021-09-14 14:07:43 +1000 |
commit | b5836b6b48b619ec715b0acfadff731b734c2176 (patch) | |
tree | 4e0c4a49767d84d5d58c7bef9b8c361d210dffb3 | |
parent | 7da3a338b9fdb8d905c653dbf5d7a8b9ed3b1a07 (diff) | |
download | scintilla-mirror-b5836b6b48b619ec715b0acfadff731b734c2176.tar.gz |
Break up PaintOneMargin more and simplify code.
-rw-r--r-- | src/MarginView.cxx | 196 | ||||
-rw-r--r-- | src/MarginView.h | 2 |
2 files changed, 106 insertions, 92 deletions
diff --git a/src/MarginView.cxx b/src/MarginView.cxx index 16c98d908..41ab68b6c 100644 --- a/src/MarginView.cxx +++ b/src/MarginView.cxx @@ -166,13 +166,81 @@ void MarginView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) } } -static MarkerOutline SubstituteMarkerIfEmpty(MarkerOutline markerCheck, MarkerOutline markerDefault, const ViewStyle &vs) noexcept { +namespace { + +MarkerOutline SubstituteMarkerIfEmpty(MarkerOutline markerCheck, MarkerOutline markerDefault, const ViewStyle &vs) noexcept { if (vs.markers[static_cast<size_t>(markerCheck)].markType == MarkerSymbol::Empty) return markerDefault; return markerCheck; } -void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcOneMargin, size_t margin, +constexpr MarkerOutline TailFromNextLevel(FoldLevel levelNextNum) noexcept { + return (levelNextNum > FoldLevel::Base) ? MarkerOutline::FolderMidTail : MarkerOutline::FolderTail; +} + +int FoldingMark(FoldLevel level, FoldLevel levelNext, bool firstSubLine, bool lastSubLine, + bool isExpanded, bool needWhiteClosure, MarkerOutline folderOpenMid, MarkerOutline folderEnd) noexcept { + + const FoldLevel levelNum = LevelNumberPart(level); + const FoldLevel levelNextNum = LevelNumberPart(levelNext); + + if (LevelIsHeader(level)) { + if (firstSubLine) { + if (levelNum < levelNextNum) { + if (levelNum == FoldLevel::Base) { + return 1 << (isExpanded ? MarkerOutline::FolderOpen : MarkerOutline::Folder); + } else { + return 1 << (isExpanded ? folderOpenMid : folderEnd); + } + } else if (levelNum > FoldLevel::Base) { + return 1 << MarkerOutline::FolderSub; + } + } else { + if (levelNum < levelNextNum) { + if (isExpanded) { + return 1 << MarkerOutline::FolderSub; + } else if (levelNum > FoldLevel::Base) { + return 1 << MarkerOutline::FolderSub; + } + } else if (levelNum > FoldLevel::Base) { + return 1 << MarkerOutline::FolderSub; + } + } + } else if (LevelIsWhitespace(level)) { + if (needWhiteClosure) { + if (LevelIsWhitespace(levelNext)) { + return 1 << MarkerOutline::FolderSub; + } else { + return 1 << TailFromNextLevel(levelNextNum); + } + } else if (levelNum > FoldLevel::Base) { + if (levelNextNum < levelNum) { + return 1 << TailFromNextLevel(levelNextNum); + } else { + return 1 << MarkerOutline::FolderSub; + } + } + } else if (levelNum > FoldLevel::Base) { + if (levelNextNum < levelNum) { + if (LevelIsWhitespace(levelNext)) { + return 1 << MarkerOutline::FolderSub; + } else if (lastSubLine) { + return 1 << TailFromNextLevel(levelNextNum); + } else { + return 1 << MarkerOutline::FolderSub; + } + } else { + return 1 << MarkerOutline::FolderSub; + } + } + + // No folding mark on this line + return 0; +} + +} + +void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOneMargin, const MarginStyle &marginStyle, const EditModel &model, const ViewStyle &vs) { const Point ptOrigin = model.GetVisibleOriginInMain(); const Sci::Line lineStartPaint = static_cast<Sci::Line>(rcOneMargin.top + ptOrigin.y) / vs.lineHeight; @@ -182,7 +250,7 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle // lessening of fold level which implies a 'fold tail' but which should not // be displayed until the last of a sequence of whitespace. bool needWhiteClosure = false; - if (vs.ms[margin].ShowsFolding()) { + if (marginStyle.ShowsFolding()) { const FoldLevel level = model.pdoc->GetFoldLevel(model.pcs->DocFromDisplay(visibleLine)); if (LevelIsWhitespace(level)) { Sci::Line lineBack = model.pcs->DocFromDisplay(visibleLine); @@ -196,11 +264,6 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle needWhiteClosure = true; } } - if (highlightDelimiter.isEnabled) { - const Sci::Line lastLine = model.pcs->DocFromDisplay(topLine + model.LinesOnScreen()) + 1; - model.pdoc->GetHighlightDelimiters(highlightDelimiter, - model.pdoc->SciLineFromPosition(model.sel.MainCaret()), lastLine); - } } // Old code does not know about new markers needed to distinguish all cases @@ -219,51 +282,28 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle const bool firstSubLine = visibleLine == firstVisibleLine; const bool lastSubLine = visibleLine == lastVisibleLine; - int marks = model.pdoc->GetMark(lineDoc); - if (!firstSubLine) - marks = 0; + int marks = firstSubLine ? model.pdoc->GetMark(lineDoc) : 0; bool headWithTail = false; - if (vs.ms[margin].ShowsFolding()) { + if (marginStyle.ShowsFolding()) { // Decide which fold indicator should be displayed const FoldLevel level = model.pdoc->GetFoldLevel(lineDoc); const FoldLevel levelNext = model.pdoc->GetFoldLevel(lineDoc + 1); const FoldLevel levelNum = LevelNumberPart(level); const FoldLevel levelNextNum = LevelNumberPart(levelNext); + const bool isExpanded = model.pcs->GetExpanded(lineDoc); + + marks |= FoldingMark(level, levelNext, firstSubLine, lastSubLine, + isExpanded, needWhiteClosure, folderOpenMid, folderEnd); + + // Change needWhiteClosure and headWithTail if needed if (LevelIsHeader(level)) { - if (firstSubLine) { - if (levelNum < levelNextNum) { - if (model.pcs->GetExpanded(lineDoc)) { - if (levelNum == FoldLevel::Base) - marks |= 1 << MarkerOutline::FolderOpen; - else - marks |= 1 << folderOpenMid; - } else { - if (levelNum == FoldLevel::Base) - marks |= 1 << MarkerOutline::Folder; - else - marks |= 1 << folderEnd; - } - } else if (levelNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderSub; - } - } else { - if (levelNum < levelNextNum) { - if (model.pcs->GetExpanded(lineDoc)) { - marks |= 1 << MarkerOutline::FolderSub; - } else if (levelNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderSub; - } - } else if (levelNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderSub; - } - } needWhiteClosure = false; const Sci::Line firstFollowupLine = model.pcs->DocFromDisplay(model.pcs->DisplayFromDoc(lineDoc + 1)); const FoldLevel firstFollowupLineLevel = model.pdoc->GetFoldLevel(firstFollowupLine); const FoldLevel secondFollowupLineLevelNum = LevelNumberPart(model.pdoc->GetFoldLevel(firstFollowupLine + 1)); - if (!model.pcs->GetExpanded(lineDoc)) { + if (!isExpanded) { if (LevelIsWhitespace(firstFollowupLineLevel) && (levelNum > secondFollowupLineLevelNum)) needWhiteClosure = true; @@ -273,55 +313,21 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle } } else if (LevelIsWhitespace(level)) { if (needWhiteClosure) { - if (LevelIsWhitespace(levelNext)) { - marks |= 1 << MarkerOutline::FolderSub; - } else if (levelNextNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderMidTail; - needWhiteClosure = false; - } else { - marks |= 1 << MarkerOutline::FolderTail; - needWhiteClosure = false; - } - } else if (levelNum > FoldLevel::Base) { - if (levelNextNum < levelNum) { - if (levelNextNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderMidTail; - } else { - marks |= 1 << MarkerOutline::FolderTail; - } - } else { - marks |= 1 << MarkerOutline::FolderSub; - } + needWhiteClosure = LevelIsWhitespace(levelNext); } } else if (levelNum > FoldLevel::Base) { if (levelNextNum < levelNum) { - needWhiteClosure = false; - if (LevelIsWhitespace(levelNext)) { - marks |= 1 << MarkerOutline::FolderSub; - needWhiteClosure = true; - } else if (lastSubLine) { - if (levelNextNum > FoldLevel::Base) { - marks |= 1 << MarkerOutline::FolderMidTail; - } else { - marks |= 1 << MarkerOutline::FolderTail; - } - } else { - marks |= 1 << MarkerOutline::FolderSub; - } - } else { - marks |= 1 << MarkerOutline::FolderSub; + needWhiteClosure = LevelIsWhitespace(levelNext); } } } - marks &= vs.ms[margin].mask; - const PRectangle rcMarker( rcOneMargin.left, - static_cast<XYPOSITION>(yposScreen), + yposScreen, rcOneMargin.right, - static_cast<XYPOSITION>(yposScreen + vs.lineHeight)); - if (vs.ms[margin].style == MarginType::Number) { + yposScreen + vs.lineHeight); + if (marginStyle.style == MarginType::Number) { if (firstSubLine) { std::string sNumber; if (lineDoc >= 0) { @@ -360,14 +366,14 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle customDrawWrapMarker(surface, rcWrapMarker, false, vs.styles[StyleLineNumber].fore); } } - } else if (vs.ms[margin].style == MarginType::Text || vs.ms[margin].style == MarginType::RText) { + } else if (marginStyle.style == MarginType::Text || marginStyle.style == MarginType::RText) { const StyledText stMargin = model.pdoc->MarginStyledText(lineDoc); if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) { if (firstSubLine) { surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); PRectangle rcText = rcMarker; - if (vs.ms[margin].style == MarginType::RText) { + if (marginStyle.style == MarginType::RText) { const int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin); rcText.left = rcText.right - width - 3; } @@ -383,11 +389,13 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle } } + marks &= marginStyle.mask; + if (marks) { for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { LineMarker::FoldPart part = LineMarker::FoldPart::undefined; - if (vs.ms[margin].ShowsFolding() && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { + if (marginStyle.ShowsFolding() && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) { part = LineMarker::FoldPart::body; } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) { @@ -404,7 +412,7 @@ void MarginView::PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle part = LineMarker::FoldPart::tail; } } - vs.markers[markBit].Draw(surface, rcMarker, vs.styles[StyleLineNumber].font.get(), part, vs.ms[margin].style); + vs.markers[markBit].Draw(surface, rcMarker, vs.styles[StyleLineNumber].font.get(), part, marginStyle.style); } marks >>= 1; } @@ -424,14 +432,14 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, rcOneMargin.bottom = rc.bottom; const Point ptOrigin = model.GetVisibleOriginInMain(); - for (size_t margin = 0; margin < vs.ms.size(); margin++) { - if (vs.ms[margin].width > 0) { + for (const MarginStyle &marginStyle : vs.ms) { + if (marginStyle.width > 0) { rcOneMargin.left = rcOneMargin.right; - rcOneMargin.right = rcOneMargin.left + vs.ms[margin].width; + rcOneMargin.right = rcOneMargin.left + marginStyle.width; - if (vs.ms[margin].style != MarginType::Number) { - if (vs.ms[margin].ShowsFolding()) { + if (marginStyle.style != MarginType::Number) { + if (marginStyle.ShowsFolding()) { // Required because of special way brush is created for selection margin // Ensure patterns line up when scrolling with separate margin view // by choosing correctly aligned variant. @@ -440,7 +448,7 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, invertPhase ? *pixmapSelPattern : *pixmapSelPatternOffset1); } else { ColourRGBA colour; - switch (vs.ms[margin].style) { + switch (marginStyle.style) { case MarginType::Back: colour = vs.styles[StyleDefault].back; break; @@ -448,7 +456,7 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, colour = vs.styles[StyleDefault].fore; break; case MarginType::Colour: - colour = vs.ms[margin].back; + colour = marginStyle.back; break; default: colour = vs.styles[StyleLineNumber].back; @@ -460,7 +468,13 @@ void MarginView::PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, surface->FillRectangle(rcOneMargin, vs.styles[StyleLineNumber].back); } - PaintOneMargin(surface, topLine, rc, rcOneMargin, margin, model, vs); + if (marginStyle.ShowsFolding() && highlightDelimiter.isEnabled) { + const Sci::Line lastLine = model.pcs->DocFromDisplay(topLine + model.LinesOnScreen()) + 1; + model.pdoc->GetHighlightDelimiters(highlightDelimiter, + model.pdoc->SciLineFromPosition(model.sel.MainCaret()), lastLine); + } + + PaintOneMargin(surface, rc, rcOneMargin, marginStyle, model, vs); } } diff --git a/src/MarginView.h b/src/MarginView.h index 6088ed3d6..c42b4c344 100644 --- a/src/MarginView.h +++ b/src/MarginView.h @@ -36,7 +36,7 @@ public: void DropGraphics() noexcept; void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw); - void PaintOneMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcMargin, size_t margin, + void PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcMargin, const MarginStyle &marginStyle, const EditModel &model, const ViewStyle &vs); void PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcMargin, const EditModel &model, const ViewStyle &vs); |