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:
Dylan Smith 2008-07-09 09:36:12 -04:00 committed by Alexandre Julliard
parent d293b3fc98
commit 7de6c2674a
3 changed files with 75 additions and 16 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);