richedit: Added more conditional cursor changes.
Previously the cursor was either an IBEAM, or a reversed arrow when over the selectionbar.
This commit is contained in:
parent
d293b3fc98
commit
7de6c2674a
|
@ -814,11 +814,21 @@ int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
|
|||
+ pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
|
||||
}
|
||||
|
||||
static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
|
||||
/* Finds the run and offset from the pixel position.
|
||||
*
|
||||
* x & y are pixel positions in virtual coordinates into the rich edit control,
|
||||
* so client coordinates must first be adjusted by the scroll position.
|
||||
*
|
||||
* returns TRUE if the result was exactly under the cursor, otherwise returns
|
||||
* FALSE, and result is set to the closest position to the coordinates.
|
||||
*/
|
||||
static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y,
|
||||
ME_Cursor *result, BOOL *is_eol)
|
||||
{
|
||||
ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para;
|
||||
ME_DisplayItem *last = NULL;
|
||||
int rx = 0;
|
||||
BOOL isExact = TRUE;
|
||||
|
||||
if (is_eol)
|
||||
*is_eol = 0;
|
||||
|
@ -857,6 +867,7 @@ static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *resu
|
|||
/* The position is below the last paragraph, so the last row will be used
|
||||
* rather than the end of the text, so the x position will be used to
|
||||
* determine the offset closest to the pixel position. */
|
||||
isExact = FALSE;
|
||||
p = ME_FindItemBack(p, diStartRow);
|
||||
if (p != NULL){
|
||||
p = ME_FindItemFwd(p, diRun);
|
||||
|
@ -885,16 +896,18 @@ static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *resu
|
|||
result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
|
||||
result->nOffset = 0;
|
||||
}
|
||||
return;
|
||||
return isExact;
|
||||
}
|
||||
break;
|
||||
case diStartRow:
|
||||
isExact = FALSE;
|
||||
p = ME_FindItemFwd(p, diRun);
|
||||
if (is_eol) *is_eol = 1;
|
||||
rx = 0; /* FIXME not sure */
|
||||
goto found_here;
|
||||
case diParagraph:
|
||||
case diTextEnd:
|
||||
isExact = FALSE;
|
||||
rx = 0; /* FIXME not sure */
|
||||
p = last;
|
||||
goto found_here;
|
||||
|
@ -905,24 +918,37 @@ static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *resu
|
|||
result->pRun = ME_FindItemBack(p, diRun);
|
||||
result->nOffset = 0;
|
||||
assert(result->pRun->member.run.nFlags & MERF_ENDPARA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ME_CharFromPos(ME_TextEditor *editor, int x, int y)
|
||||
/* Returns the character offset closest to the pixel position
|
||||
*
|
||||
* x & y are pixel positions in client coordinates.
|
||||
*
|
||||
* isExact will be set to TRUE if the run is directly under the pixel
|
||||
* position, FALSE if it not, unless isExact is set to NULL.
|
||||
*/
|
||||
int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact)
|
||||
{
|
||||
ME_Cursor cursor;
|
||||
RECT rc;
|
||||
BOOL bResult;
|
||||
|
||||
GetClientRect(editor->hWnd, &rc);
|
||||
if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom)
|
||||
if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) {
|
||||
if (isExact) *isExact = FALSE;
|
||||
return -1;
|
||||
}
|
||||
y += ME_GetYScrollPos(editor);
|
||||
ME_FindPixelPos(editor, x, y, &cursor, NULL);
|
||||
bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL);
|
||||
if (isExact) *isExact = bResult;
|
||||
return (ME_GetParagraph(cursor.pRun)->member.para.nCharOfs
|
||||
+ cursor.pRun->member.run.nCharOfs + cursor.nOffset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Extends the selection with a word, line, or paragraph selection type.
|
||||
*
|
||||
* The selection is anchored by editor->pCursors[2-3] such that the text
|
||||
|
|
|
@ -1669,6 +1669,8 @@ static int ME_CalculateClickCount(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
static BOOL ME_SetCursor(ME_TextEditor *editor)
|
||||
{
|
||||
POINT pt;
|
||||
BOOL isExact;
|
||||
int offset;
|
||||
DWORD messagePos = GetMessagePos();
|
||||
pt.x = (short)LOWORD(messagePos);
|
||||
pt.y = (short)HIWORD(messagePos);
|
||||
|
@ -1680,7 +1682,35 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
|
|||
SetCursor(hLeft);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
offset = ME_CharFromPos(editor, pt.x, pt.y, &isExact);
|
||||
if (isExact)
|
||||
{
|
||||
if (editor->AutoURLDetect_bEnable)
|
||||
{
|
||||
ME_Cursor cursor;
|
||||
ME_Run *run;
|
||||
ME_CursorFromCharOfs(editor, offset, &cursor);
|
||||
run = &cursor.pRun->member.run;
|
||||
if (editor->AutoURLDetect_bEnable &&
|
||||
run->style->fmt.dwMask & CFM_LINK &&
|
||||
run->style->fmt.dwEffects & CFE_LINK)
|
||||
{
|
||||
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_HAND));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (ME_IsSelection(editor))
|
||||
{
|
||||
int selStart, selEnd;
|
||||
ME_GetSelection(editor, &selStart, &selEnd);
|
||||
if (selStart <= offset && selEnd >= offset) {
|
||||
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_IBEAM));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
|
||||
|
@ -2986,7 +3016,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
case EM_SETZOOM:
|
||||
return ME_SetZoom(editor, wParam, lParam);
|
||||
case EM_CHARFROMPOS:
|
||||
return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL *)lParam)->y);
|
||||
return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL *)lParam)->y, NULL);
|
||||
case EM_POSFROMCHAR:
|
||||
{
|
||||
ME_DisplayItem *pRun;
|
||||
|
@ -3040,8 +3070,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
if (!ME_SetCursor(editor)) goto do_default;
|
||||
return TRUE;
|
||||
return ME_SetCursor(editor);
|
||||
}
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_LBUTTONDOWN:
|
||||
|
@ -3055,6 +3084,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_CalculateClickCount(hWnd, msg, wParam, lParam));
|
||||
SetCapture(hWnd);
|
||||
ME_LinkNotify(editor,msg,wParam,lParam);
|
||||
if (!ME_SetCursor(editor)) goto do_default;
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
|
@ -3064,6 +3094,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
if (GetCapture() == hWnd)
|
||||
ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
|
||||
ME_LinkNotify(editor,msg,wParam,lParam);
|
||||
/* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */
|
||||
if (GetCapture() == hWnd)
|
||||
ME_SetCursor(editor);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
if (GetCapture() == hWnd)
|
||||
|
@ -3075,10 +3108,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
return 0;
|
||||
else
|
||||
{
|
||||
BOOL ret;
|
||||
ret = ME_SetCursor(editor);
|
||||
ME_SetCursor(editor);
|
||||
ME_LinkNotify(editor,msg,wParam,lParam);
|
||||
if (!ret) goto do_default;
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
|
@ -3202,6 +3233,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
|
||||
ME_ReleaseStyle(style);
|
||||
ME_CommitCoalescingUndo(editor);
|
||||
SetCursor(NULL);
|
||||
}
|
||||
|
||||
if (editor->AutoURLDetect_bEnable) ME_UpdateSelectionLinkAttribute(editor);
|
||||
|
@ -3504,6 +3536,7 @@ void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam
|
|||
{
|
||||
int x,y;
|
||||
ME_Cursor tmpCursor;
|
||||
BOOL isExact;
|
||||
int nCharOfs; /* The start of the clicked text. Absolute character offset */
|
||||
|
||||
ME_Run *tmpRun;
|
||||
|
@ -3511,8 +3544,8 @@ void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam
|
|||
ENLINK info;
|
||||
x = (short)LOWORD(lParam);
|
||||
y = (short)HIWORD(lParam);
|
||||
nCharOfs = ME_CharFromPos(editor, x, y);
|
||||
if (nCharOfs < 0) return;
|
||||
nCharOfs = ME_CharFromPos(editor, x, y, &isExact);
|
||||
if (!isExact) return;
|
||||
|
||||
ME_CursorFromCharOfs(editor, nCharOfs, &tmpCursor);
|
||||
tmpRun = &tmpCursor.pRun->member.run;
|
||||
|
|
|
@ -180,7 +180,7 @@ void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType);
|
|||
void ME_HideCaret(ME_TextEditor *ed);
|
||||
void ME_ShowCaret(ME_TextEditor *ed);
|
||||
void ME_MoveCaret(ME_TextEditor *ed);
|
||||
int ME_CharFromPos(ME_TextEditor *editor, int x, int y);
|
||||
int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact);
|
||||
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum);
|
||||
void ME_MouseMove(ME_TextEditor *editor, int x, int y);
|
||||
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
|
||||
|
|
Loading…
Reference in New Issue