diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Editor.cxx | 53 | ||||
-rw-r--r-- | src/PositionCache.cxx | 12 | ||||
-rw-r--r-- | src/Selection.cxx | 36 | ||||
-rw-r--r-- | src/Selection.h | 22 |
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; } |