aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Editor.cxx53
-rw-r--r--src/PositionCache.cxx12
-rw-r--r--src/Selection.cxx36
-rw-r--r--src/Selection.h22
4 files changed, 74 insertions, 49 deletions
diff --git a/src/Editor.cxx b/src/Editor.cxx
index d3a65dc57..6218ad195 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -2234,6 +2234,7 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
bool overrideBackground, ColourAllocated background,
bool drawWrapMarkEnd, ColourAllocated wrapColour) {
+ const int posLineStart = pdoc->LineStart(line);
int styleMask = pdoc->stylingBitsMask;
PRectangle rcSegment = rcLine;
@@ -2249,8 +2250,21 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
if (virtualSpace) {
rcSegment.left = xEol + xStart;
rcSegment.right = xEol + xStart + virtualSpace;
- // TODO: draw selection where needed
surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ if (!hideSelection && vsDraw.selAlpha == SC_ALPHA_NOALPHA) {
+ SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line))));
+ for (size_t r=0; r<sel.Count(); r++) {
+ SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+ if (!portion.Empty()) {
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+ rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+ rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+ rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+ }
+ }
+ }
}
int posAfterLineEnd = pdoc->LineStart(line + 1);
@@ -2860,19 +2874,21 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
}
if (!hideSelection && vsDraw.selAlpha != SC_ALPHA_NOALPHA) {
// For each selection draw
+ int virtualSpaces = 0;
+ if (subLine == (ll->lines - 1)) {
+ virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line));
+ }
+ SelectionSegment virtualSpaceRange(SelectionPosition(posLineStart), SelectionPosition(posLineStart + lineEnd, virtualSpaces));
for (size_t r=0; r<sel.Count(); r++) {
- SelectionPosition spStart;
- SelectionPosition spEnd;
- if (sel.Range(r).Intersect(posLineStart, posLineStart + lineEnd, spStart, spEnd)) {
- if (!(spStart == spEnd)) {
- const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
- rcSegment.left = xStart + ll->positions[spStart.Position() - posLineStart] - subLineStart + spStart.VirtualSpace() * spaceWidth;
- rcSegment.right = xStart + ll->positions[spEnd.Position() - posLineStart] - subLineStart + spEnd.VirtualSpace() * spaceWidth;
- rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
- rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw),
- (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAlpha / 2);
- }
+ SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+ if (!portion.Empty()) {
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+ rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+ rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+ rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw),
+ (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAlpha / 2);
}
}
}
@@ -7842,13 +7858,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
}
case SCI_GETLINESELSTARTPOSITION:
case SCI_GETLINESELENDPOSITION: {
+ SelectionSegment segmentLine(SelectionPosition(pdoc->LineStart(wParam)),
+ SelectionPosition(pdoc->LineEnd(wParam)));
for (size_t r=0; r<sel.Count(); r++) {
- int posLineStart = pdoc->LineStart(wParam);
- int posLineEnd = pdoc->LineEnd(wParam);
- SelectionPosition spStart;
- SelectionPosition spEnd;
- if (sel.Range(r).Intersect(posLineStart, posLineEnd, spStart, spEnd)) {
- return (iMessage == SCI_GETLINESELSTARTPOSITION) ? spStart.Position() : spEnd.Position();
+ SelectionSegment portion = sel.Range(r).Intersect(segmentLine);
+ if (portion.start.IsValid()) {
+ return (iMessage == SCI_GETLINESELSTARTPOSITION) ? portion.start.Position() : portion.end.Position();
}
}
return INVALID_POSITION;
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index b727ec465..42f5fa3f3 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -412,13 +412,13 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
nextBreak--;
}
+ SelectionSegment segmentLine(SelectionPosition(posLineStart), SelectionPosition(posLineStart + lineEnd));
for (size_t r=0; r<ll->psel->Count(); r++) {
- SelectionPosition spStart;
- SelectionPosition spEnd;
- if (ll->psel->Range(r).Intersect(posLineStart, posLineStart + lineEnd, spStart, spEnd)) {
- Insert(spStart.Position() - posLineStart - 1);
- Insert(spEnd.Position() - posLineStart - 1);
- }
+ SelectionSegment portion = ll->psel->Range(r).Intersect(segmentLine);
+ if (portion.start.IsValid())
+ Insert(portion.start.Position() - posLineStart - 1);
+ if (portion.end.IsValid())
+ Insert(portion.end.Position() - posLineStart - 1);
}
Insert(ll->edgeColumn - 1);
diff --git a/src/Selection.cxx b/src/Selection.cxx
index d4d4d8fe8..28a70b62b 100644
--- a/src/Selection.cxx
+++ b/src/Selection.cxx
@@ -111,30 +111,20 @@ bool SelectionRange::ContainsCharacter(int posCharacter) const {
return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
}
-bool SelectionRange::Intersect(int start, int end, SelectionPosition &selStart, SelectionPosition &selEnd) const {
- SelectionPosition spEnd(end, 100000); // Large amount of virtual space
- SelectionPosition spStart(start);
- SelectionPosition first;
- SelectionPosition last;
- if (anchor > caret) {
- first = caret;
- last = anchor;
+SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
+ SelectionSegment inOrder(caret, anchor);
+ if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
+ SelectionSegment portion = check;
+ if (portion.start < inOrder.start)
+ portion.start = inOrder.start;
+ if (portion.end > inOrder.end)
+ portion.end = inOrder.end;
+ if (portion.start > portion.end)
+ return SelectionSegment();
+ else
+ return portion;
} else {
- first = anchor;
- last = caret;
- }
- if ((first < spEnd) && (last > spStart)) {
- if (start > first.Position())
- selStart = SelectionPosition(start);
- else
- selStart = first;
- if (spEnd < last)
- selEnd = SelectionPosition(end);
- else
- selEnd = last;
- return true;
- } else {
- return false;
+ return SelectionSegment();
}
}
diff --git a/src/Selection.h b/src/Selection.h
index 94d6fc65e..0cb1200f8 100644
--- a/src/Selection.h
+++ b/src/Selection.h
@@ -56,6 +56,26 @@ public:
}
};
+// Ordered range to make drawing simpler
+struct SelectionSegment {
+ SelectionPosition start;
+ SelectionPosition end;
+ SelectionSegment() {
+ }
+ SelectionSegment(SelectionPosition a, SelectionPosition b) {
+ if (a < b) {
+ start = a;
+ end = b;
+ } else {
+ start = b;
+ end = a;
+ }
+ }
+ bool Empty() const {
+ return start == end;
+ }
+};
+
struct SelectionRange {
SelectionPosition caret;
SelectionPosition anchor;
@@ -87,7 +107,7 @@ struct SelectionRange {
bool Contains(int pos) const;
bool Contains(SelectionPosition sp) const;
bool ContainsCharacter(int posCharacter) const;
- bool Intersect(int start, int end, SelectionPosition &selStart, SelectionPosition &selEnd) const;
+ SelectionSegment Intersect(SelectionSegment check) const;
SelectionPosition Start() const {
return (anchor < caret) ? anchor : caret;
}