aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2021-09-14 14:07:43 +1000
committerNeil <nyamatongwe@gmail.com>2021-09-14 14:07:43 +1000
commitb5836b6b48b619ec715b0acfadff731b734c2176 (patch)
tree4e0c4a49767d84d5d58c7bef9b8c361d210dffb3
parent7da3a338b9fdb8d905c653dbf5d7a8b9ed3b1a07 (diff)
downloadscintilla-mirror-b5836b6b48b619ec715b0acfadff731b734c2176.tar.gz
Break up PaintOneMargin more and simplify code.
-rw-r--r--src/MarginView.cxx196
-rw-r--r--src/MarginView.h2
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);