diff options
author | Neil Hodgson <nyamatongwe@gmail.com> | 2016-11-05 20:32:17 +1100 |
---|---|---|
committer | Neil Hodgson <nyamatongwe@gmail.com> | 2016-11-05 20:32:17 +1100 |
commit | 8a62263409f5d222ac0d0ccf7bf0e7e0261224a8 (patch) | |
tree | 2fa3fea045c228d40e8a812b8553afd21f7f168a | |
parent | 1e36c7e89248cf5f9e4353673918e79cfcaeb857 (diff) | |
download | scintilla-mirror-8a62263409f5d222ac0d0ccf7bf0e7e0261224a8.tar.gz |
Add options to choose between the locations of a position when there
are multiple locations for one position.
The main current use is to find the location at the end of a line or display
line when the commonly used location is at the start of the next line.
-rw-r--r-- | src/EditView.cxx | 46 | ||||
-rw-r--r-- | src/EditView.h | 4 | ||||
-rw-r--r-- | src/Editor.cxx | 14 | ||||
-rw-r--r-- | src/Editor.h | 5 | ||||
-rw-r--r-- | src/PositionCache.cxx | 8 | ||||
-rw-r--r-- | src/PositionCache.h | 12 |
6 files changed, 72 insertions, 17 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx index 3bca3b58b..59e4e7ab7 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -596,19 +596,24 @@ void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, co } } -Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, const ViewStyle &vs) { +Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, + const ViewStyle &vs, PointEnd pe) { Point pt; if (pos.Position() == INVALID_POSITION) return pt; - const int line = model.pdoc->LineFromPosition(pos.Position()); - const int lineVisible = model.cs.DisplayFromDoc(line); - //Platform::DebugPrintf("line=%d\n", line); - AutoLineLayout ll(llc, RetrieveLineLayout(line, model)); + int lineDoc = model.pdoc->LineFromPosition(pos.Position()); + int posLineStart = model.pdoc->LineStart(lineDoc); + if ((pe & peLineEnd) && (lineDoc > 0) && (pos.Position() == posLineStart)) { + // Want point at end of first line + lineDoc--; + posLineStart = model.pdoc->LineStart(lineDoc); + } + const int lineVisible = model.cs.DisplayFromDoc(lineDoc); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); if (surface && ll) { - const int posLineStart = model.pdoc->LineStart(line); - LayoutLine(model, line, surface, vs, ll, model.wrapWidth); + LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); const int posInLine = pos.Position() - posLineStart; - pt = ll->PointFromPosition(posInLine, vs.lineHeight); + pt = ll->PointFromPosition(posInLine, vs.lineHeight, pe); pt.y += (lineVisible - topLine) * vs.lineHeight; pt.x += vs.textStart - model.xOffset; } @@ -616,6 +621,31 @@ Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, S return pt; } +Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs) { + Range rangeSubLine = Range(0,0); + if (lineVisible < 0) { + return rangeSubLine; + } + const int lineDoc = model.cs.DocFromDisplay(lineVisible); + const int positionLineStart = model.pdoc->LineStart(lineDoc); + AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); + if (surface && ll) { + LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); + const int lineStartSet = model.cs.DisplayFromDoc(lineDoc); + const int subLine = lineVisible - lineStartSet; + if (subLine < ll->lines) { + rangeSubLine = ll->SubLineRange(subLine); + if (subLine == ll->lines-1) { + rangeSubLine.end = model.pdoc->LineStart(lineDoc + 1) - + positionLineStart; + } + } + } + rangeSubLine.start += positionLineStart; + rangeSubLine.end += positionLineStart; + return rangeSubLine; +} + SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs) { pt.x = pt.x - vs.textStart; int visibleLine = static_cast<int>(floor(pt.y / vs.lineHeight)); diff --git a/src/EditView.h b/src/EditView.h index 79a88657a..dcfa352f4 100644 --- a/src/EditView.h +++ b/src/EditView.h @@ -111,7 +111,9 @@ public: void LayoutLine(const EditModel &model, int line, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width = LineLayout::wrapWidthInfinite); - Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, const ViewStyle &vs); + Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, + const ViewStyle &vs, PointEnd pe); + Range RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs); SelectionPosition SPositionFromLocation(Surface *surface, const EditModel &model, Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs); SelectionPosition SPositionFromLineX(Surface *surface, const EditModel &model, int lineDoc, int x, const ViewStyle &vs); diff --git a/src/Editor.cxx b/src/Editor.cxx index 62bc60a09..6950ac66e 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -363,14 +363,14 @@ SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const } } -Point Editor::LocationFromPosition(SelectionPosition pos) { +Point Editor::LocationFromPosition(SelectionPosition pos, PointEnd pe) { RefreshStyleData(); AutoSurface surface(this); - return view.LocationFromPosition(surface, *this, pos, topLine, vs); + return view.LocationFromPosition(surface, *this, pos, topLine, vs, pe); } -Point Editor::LocationFromPosition(int pos) { - return LocationFromPosition(SelectionPosition(pos)); +Point Editor::LocationFromPosition(int pos, PointEnd pe) { + return LocationFromPosition(SelectionPosition(pos), pe); } int Editor::XFromPosition(int pos) { @@ -3150,6 +3150,12 @@ void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) { } while (!cs.GetVisible(lineDoc)); } +Range Editor::RangeDisplayLine(int lineVisible) { + RefreshStyleData(); + AutoSurface surface(this); + return view.RangeDisplayLine(surface, *this, lineVisible, vs); +} + int Editor::StartEndDisplayLine(int pos, bool start) { RefreshStyleData(); AutoSurface surface(this); diff --git a/src/Editor.h b/src/Editor.h index d907a2d0b..9eec7a38a 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -285,8 +285,8 @@ protected: // ScintillaBase subclass needs access to much of Editor int LinesToScroll() const; int MaxScrollPos() const; SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; - Point LocationFromPosition(SelectionPosition pos); - Point LocationFromPosition(int pos); + Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault); + Point LocationFromPosition(int pos, PointEnd pe=peDefault); int XFromPosition(int pos); int XFromPosition(SelectionPosition sp); SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); @@ -465,6 +465,7 @@ protected: // ScintillaBase subclass needs access to much of Editor SelectionPosition PositionUpOrDown(SelectionPosition spStart, int direction, int lastX); void CursorUpOrDown(int direction, Selection::selTypes selt); void ParaUpOrDown(int direction, Selection::selTypes selt); + Range RangeDisplayLine(int lineVisible); int StartEndDisplayLine(int pos, bool start); int VCHomeDisplayPosition(int position); int VCHomeWrapPosition(int position); diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 997a4bfae..45731601a 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -217,7 +217,7 @@ int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) return range.end; } -Point LineLayout::PointFromPosition(int posInLine, int lineHeight) const { +Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const { Point pt; // In case of very long line put x at arbitrary large position if (posInLine > maxLineLength) { @@ -232,6 +232,12 @@ Point LineLayout::PointFromPosition(int posInLine, int lineHeight) const { pt.x = positions[posInLine] - positions[rangeSubLine.start]; if (rangeSubLine.start != 0) // Wrapped lines may be indented pt.x += wrapIndent; + if (pe & peSubLineEnd) // Return end of first subline not start of next + break; + } else if ((pe & peLineEnd) && (subLine == (lines-1))) { + pt.x = positions[numCharsInLine] - positions[rangeSubLine.start]; + if (rangeSubLine.start != 0) // Wrapped lines may be indented + pt.x += wrapIndent; } } else { break; diff --git a/src/PositionCache.h b/src/PositionCache.h index edc0a5ddb..5a829b76b 100644 --- a/src/PositionCache.h +++ b/src/PositionCache.h @@ -16,6 +16,15 @@ static inline bool IsEOLChar(char ch) { return (ch == '\r') || (ch == '\n'); } +// There are two points for some positions and this enumeration +// can choose between the end of the first line or subline +// and the start of the next line or subline. +enum PointEnd { + peDefault = 0x0, + peLineEnd = 0x1, + peSubLineEnd = 0x2 +}; + /** */ class LineLayout { @@ -28,6 +37,7 @@ private: bool inCache; public: enum { wrapWidthInfinite = 0x7ffffff }; + int maxLineLength; int numCharsInLine; int numCharsBeforeEOL; @@ -64,7 +74,7 @@ public: void RestoreBracesHighlight(Range rangeLine, const Position braces[], bool ignoreStyle); int FindBefore(XYPOSITION x, int lower, int upper) const; int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const; - Point PointFromPosition(int posInLine, int lineHeight) const; + Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const; int EndLineStyle() const; }; |