diff options
author | nyamatongwe <unknown> | 2009-05-03 08:45:26 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2009-05-03 08:45:26 +0000 |
commit | fcd6000ae9db0766a65cc0ab1b7da2cfa2b2f30f (patch) | |
tree | d0ba622e6ceb3efaa9cecb5c094e7e84379e1cd4 | |
parent | 3337bd8eeec8eec42e9f6900cc74c7068c07be71 (diff) | |
download | scintilla-mirror-fcd6000ae9db0766a65cc0ab1b7da2cfa2b2f30f.tar.gz |
Added CharPositionFromPoint and CharPositionFromPointClose and merged the
implementation for these and PositionFromPoint and PositionFromPointClose
into a single function with flags for the different modes.
-rw-r--r-- | doc/ScintillaDoc.html | 10 | ||||
-rw-r--r-- | include/Scintilla.h | 2 | ||||
-rw-r--r-- | include/Scintilla.iface | 7 | ||||
-rw-r--r-- | src/Editor.cxx | 106 | ||||
-rw-r--r-- | src/Editor.h | 3 |
5 files changed, 62 insertions, 66 deletions
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index bf1f0bbb0..ab7cb5da0 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -1007,6 +1007,9 @@ struct TextToFind { <a class="message" href="#SCI_POSITIONFROMPOINT">SCI_POSITIONFROMPOINT(int x, int y)</a><br /> <a class="message" href="#SCI_POSITIONFROMPOINTCLOSE">SCI_POSITIONFROMPOINTCLOSE(int x, int y)</a><br /> + <a class="message" href="#SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</a><br /> + <a class="message" href="#SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int + y)</a><br /> <a class="message" href="#SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(<unused>, int position)</a><br /> <a class="message" href="#SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(<unused>, int @@ -1343,6 +1346,13 @@ struct TextToFind { <code>SCI_POSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the window or not close to any characters.</p> + <p><b id="SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</b><br /> + <b id="SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int y)</b><br /> + <code>SCI_CHARPOSITIONFROMPOINT</code> finds the closest character to a point and + <code>SCI_CHARPOSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the + window or not close to any characters. This is similar to the previous methods but finds characters rather than + inter-character positions.</p> + <p><b id="SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(<unused>, int pos)</b><br /> <b id="SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(<unused>, int pos)</b><br /> These messages return the x and y display pixel location of text at position <code>pos</code> diff --git a/include/Scintilla.h b/include/Scintilla.h index 677cd0325..b31e81831 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -705,6 +705,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_ANNOTATIONGETSTYLEOFFSET 2551 #define UNDO_MAY_COALESCE 1 #define SCI_ADDUNDOACTION 2560 +#define SCI_CHARPOSITIONFROMPOINT 2561 +#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index a2c905fb7..9c9eeb1be 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -1907,6 +1907,13 @@ val UNDO_MAY_COALESCE=1 # Add a container action to the undo stack fun void AddUndoAction=2560(int token, int flags) +# Find the position of a character from a point within the window. +fun position CharPositionFromPoint=2561(int x, int y) + +# Find the position of a character from a point within the window. +# Return INVALID_POSITION if not close to text. +fun position CharPositionFromPointClose=2562(int x, int y) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) diff --git a/src/Editor.cxx b/src/Editor.cxx index aa6f0d52e..0ec0b9160 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -480,20 +480,31 @@ void Editor::SetTopLine(int topLineNew) { posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine)); } -int Editor::PositionFromLocation(Point pt) { +int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) { RefreshStyleData(); + if (canReturnInvalid) { + PRectangle rcClient = GetTextRectangle(); + if (!rcClient.Contains(pt)) + return INVALID_POSITION; + if (pt.x < vs.fixedColumnWidth) + return INVALID_POSITION; + if (pt.y < 0) + return INVALID_POSITION; + } pt.x = pt.x - vs.fixedColumnWidth + xOffset; int visibleLine = pt.y / vs.lineHeight + topLine; if (pt.y < 0) { // Division rounds towards 0 visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine; } - if (visibleLine < 0) + if (!canReturnInvalid && (visibleLine < 0)) visibleLine = 0; int lineDoc = cs.DocFromDisplay(visibleLine); + if (canReturnInvalid && (lineDoc < 0)) + return INVALID_POSITION; if (lineDoc >= pdoc->LinesTotal()) - return pdoc->Length(); + return canReturnInvalid ? INVALID_POSITION : pdoc->Length(); unsigned int posLineStart = pdoc->LineStart(lineDoc); - int retVal = posLineStart; + int retVal = canReturnInvalid ? INVALID_POSITION : posLineStart; AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { @@ -511,68 +522,29 @@ int Editor::PositionFromLocation(Point pt) { } int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd); while (i < lineEnd) { - if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { - return pdoc->MovePositionOutsideChar(i + posLineStart, 1); + if (charPosition) { + if ((pt.x + subLineStart) < (ll->positions[i + 1])) { + return pdoc->MovePositionOutsideChar(i + posLineStart, 1); + } + } else { + if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { + return pdoc->MovePositionOutsideChar(i + posLineStart, 1); + } } i++; } - return lineEnd + posLineStart; - } - retVal = ll->numCharsInLine + posLineStart; - } - return retVal; -} - -// Like PositionFromLocation but INVALID_POSITION returned when not near any text. -int Editor::PositionFromLocationClose(Point pt) { - RefreshStyleData(); - PRectangle rcClient = GetTextRectangle(); - if (!rcClient.Contains(pt)) - return INVALID_POSITION; - if (pt.x < vs.fixedColumnWidth) - return INVALID_POSITION; - if (pt.y < 0) - return INVALID_POSITION; - pt.x = pt.x - vs.fixedColumnWidth + xOffset; - int visibleLine = pt.y / vs.lineHeight + topLine; - if (pt.y < 0) { // Division rounds towards 0 - visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine; - } - int lineDoc = cs.DocFromDisplay(visibleLine); - if (lineDoc < 0) - return INVALID_POSITION; - if (lineDoc >= pdoc->LinesTotal()) - return INVALID_POSITION; - AutoSurface surface(this); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); - if (surface && ll) { - LayoutLine(lineDoc, surface, vs, ll, wrapWidth); - unsigned int posLineStart = pdoc->LineStart(lineDoc); - int lineStartSet = cs.DisplayFromDoc(lineDoc); - int subLine = visibleLine - lineStartSet; - if (subLine < ll->lines) { - int lineStart = ll->LineStart(subLine); - int lineEnd = ll->LineLastVisible(subLine); - int subLineStart = ll->positions[lineStart]; - - if (actualWrapVisualStartIndent != 0) { - if (lineStart != 0) // Wrapped - pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth; - } - int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd); - while (i < lineEnd) { - if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { - return pdoc->MovePositionOutsideChar(i + posLineStart, 1); + if (canReturnInvalid) { + if (pt.x < (ll->positions[lineEnd] - subLineStart)) { + return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1); } - i++; - } - if (pt.x < (ll->positions[lineEnd] - subLineStart)) { - return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1); + } else { + return lineEnd + posLineStart; } } + if (!canReturnInvalid) + return ll->numCharsInLine + posLineStart; } - - return INVALID_POSITION; + return retVal; } /** @@ -3847,7 +3819,7 @@ void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_DOUBLECLICK; scn.line = LineFromLocation(pt); - scn.position = PositionFromLocationClose(pt); + scn.position = PositionFromLocation(pt, true); scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); NotifyParent(scn); @@ -3928,7 +3900,7 @@ void Editor::NotifyNeedShown(int pos, int len) { void Editor::NotifyDwelling(Point pt, bool state) { SCNotification scn = {0}; scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND; - scn.position = PositionFromLocationClose(pt); + scn.position = PositionFromLocation(pt, true); scn.x = pt.x; scn.y = pt.y; NotifyParent(scn); @@ -5511,7 +5483,7 @@ bool Editor::PositionIsHotspot(int position) { } bool Editor::PointIsHotspot(Point pt) { - int pos = PositionFromLocationClose(pt); + int pos = PositionFromLocation(pt, true); if (pos == INVALID_POSITION) return false; return PositionIsHotspot(pos); @@ -6679,10 +6651,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { break; case SCI_POSITIONFROMPOINT: - return PositionFromLocation(Point(wParam, lParam)); + return PositionFromLocation(Point(wParam, lParam), false, false); case SCI_POSITIONFROMPOINTCLOSE: - return PositionFromLocationClose(Point(wParam, lParam)); + return PositionFromLocation(Point(wParam, lParam), true, false); + + case SCI_CHARPOSITIONFROMPOINT: + return PositionFromLocation(Point(wParam, lParam), false, true); + + case SCI_CHARPOSITIONFROMPOINTCLOSE: + return PositionFromLocation(Point(wParam, lParam), true, true); case SCI_GOTOLINE: GoToLine(wParam); diff --git a/src/Editor.h b/src/Editor.h index 3b15920ff..d37606d5a 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -260,8 +260,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int MaxScrollPos(); Point LocationFromPosition(int pos); int XFromPosition(int pos); - int PositionFromLocation(Point pt); - int PositionFromLocationClose(Point pt); + int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false); int PositionFromLineX(int line, int x); int LineFromLocation(Point pt); void SetTopLine(int topLineNew); |