Dylan Smith : richedit: Fix implementation of handling Page Up/Down keys.
Alexandre Julliard
julliard at winehq.org
Fri Jan 16 07:41:52 CST 2009
Module: wine
Branch: master
Commit: 77a94bed984bcb19bb1b7b563537c72c63353a9b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=77a94bed984bcb19bb1b7b563537c72c63353a9b
Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date: Thu Jan 15 11:03:49 2009 -0500
richedit: Fix implementation of handling Page Up/Down keys.
---
dlls/riched20/caret.c | 195 +++++++++++++++++++++++--------------------------
1 files changed, 91 insertions(+), 104 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 3df8566..74c32a3 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -1338,132 +1338,119 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
assert(pCursor->pRun->type == diRun);
}
-static BOOL ME_UpdateSelection(ME_TextEditor *editor, const ME_Cursor *pTempCursor)
+static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
{
- ME_Cursor old_anchor = editor->pCursors[1];
+ ME_DisplayItem *p = ME_FindItemFwd(editor->pBuffer->pFirst, diStartRow);
- if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */
- {
- /* any selection was present ? if so, it's no more, repaint ! */
- editor->pCursors[1] = editor->pCursors[0];
- if (memcmp(pTempCursor, &old_anchor, sizeof(ME_Cursor))) {
- return TRUE;
- }
- return FALSE;
- }
- else
+ if (editor->vert_si.nPos < p->member.row.nHeight)
{
- if (!memcmp(pTempCursor, &editor->pCursors[1], sizeof(ME_Cursor))) /* starting selection */
- {
- editor->pCursors[1] = *pTempCursor;
- return TRUE;
- }
- }
-
- ME_Repaint(editor);
- return TRUE;
-}
+ pCursor->pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun);
+ pCursor->nOffset = 0;
+ editor->bCaretAtEnd = FALSE;
+ /* Native clears seems to clear this x value on page up at the top
+ * of the text, but not on page down at the end of the text.
+ * Doesn't make sense, but we try to be bug for bug compatible. */
+ editor->nUDArrowX = -1;
+ } else {
+ ME_DisplayItem *pRun = pCursor->pRun;
+ ME_DisplayItem *pLast;
+ int x, y, ys, yd, yp, yprev;
+ int yOldScrollPos = editor->vert_si.nPos;
-static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
-{
- ME_DisplayItem *pRun = pCursor->pRun;
- ME_DisplayItem *pLast, *p;
- int x, y, ys, yd, yp, yprev;
- ME_Cursor tmp_curs = *pCursor;
+ x = ME_GetXForArrow(editor, pCursor);
+ if (!pCursor->nOffset && editor->bCaretAtEnd)
+ pRun = ME_FindItemBack(pRun, diRun);
- x = ME_GetXForArrow(editor, pCursor);
- if (!pCursor->nOffset && editor->bCaretAtEnd)
- pRun = ME_FindItemBack(pRun, diRun);
+ p = ME_FindItemBack(pRun, diStartRowOrParagraph);
+ assert(p->type == diStartRow);
+ yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y;
+ yprev = ys = y = yp + p->member.row.pt.y;
- p = ME_FindItemBack(pRun, diStartRowOrParagraph);
- assert(p->type == diStartRow);
- yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y;
- yprev = ys = y = yp + p->member.row.pt.y;
- yd = y - editor->sizeWindow.cy;
- pLast = p;
+ ME_ScrollUp(editor, editor->sizeWindow.cy);
+ /* Only move the cursor by the amount scrolled. */
+ yd = y + editor->vert_si.nPos - yOldScrollPos;
+ pLast = p;
- do {
- p = ME_FindItemBack(p, diStartRowOrParagraph);
- if (!p)
- break;
- if (p->type == diParagraph) { /* crossing paragraphs */
- if (p->member.para.prev_para == NULL)
+ do {
+ p = ME_FindItemBack(p, diStartRowOrParagraph);
+ if (!p)
break;
- yp = p->member.para.prev_para->member.para.pt.y;
- continue;
- }
- y = yp + p->member.row.pt.y;
- if (y < yd)
- break;
- pLast = p;
- yprev = y;
- } while(1);
+ if (p->type == diParagraph) { /* crossing paragraphs */
+ if (p->member.para.prev_para == NULL)
+ break;
+ yp = p->member.para.prev_para->member.para.pt.y;
+ continue;
+ }
+ y = yp + p->member.row.pt.y;
+ if (y < yd)
+ break;
+ pLast = p;
+ yprev = y;
+ } while(1);
- pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset, &editor->bCaretAtEnd);
- ME_UpdateSelection(editor, &tmp_curs);
- if (yprev < editor->sizeWindow.cy)
- {
- ME_Cursor startCursor = {ME_FindItemFwd(editor->pBuffer->pFirst, diRun), 0};
- ME_EnsureVisible(editor, &startCursor);
- ME_Repaint(editor);
- }
- else
- {
- ME_ScrollUp(editor, ys-yprev);
+ pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset,
+ &editor->bCaretAtEnd);
}
assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun);
}
-/* FIXME: in the original RICHEDIT, PageDown always scrolls by the same amount
- of pixels, even if it makes the scroll bar position exceed its normal maximum.
- In such a situation, clicking the scrollbar restores its position back to the
- normal range (ie. sets it to (doclength-screenheight)). */
-
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{
- ME_DisplayItem *pRun = pCursor->pRun;
- ME_DisplayItem *pLast, *p;
- int x, y, ys, yd, yp, yprev;
- ME_Cursor tmp_curs = *pCursor;
+ ME_DisplayItem *pLast;
+ int x, y;
+
+ /* Find y position of the last row */
+ pLast = editor->pBuffer->pLast;
+ y = pLast->member.para.prev_para->member.para.pt.y
+ + ME_FindItemBack(pLast, diStartRow)->member.row.pt.y;
x = ME_GetXForArrow(editor, pCursor);
- if (!pCursor->nOffset && editor->bCaretAtEnd)
- pRun = ME_FindItemBack(pRun, diRun);
- p = ME_FindItemBack(pRun, diStartRowOrParagraph);
- assert(p->type == diStartRow);
- yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y;
- yprev = ys = y = yp + p->member.row.pt.y;
- yd = y + editor->sizeWindow.cy;
- pLast = p;
+ if (editor->vert_si.nPos >= y - editor->sizeWindow.cy)
+ {
+ pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
+ pCursor->nOffset = 0;
+ editor->bCaretAtEnd = FALSE;
+ } else {
+ ME_DisplayItem *pRun = pCursor->pRun;
+ ME_DisplayItem *p;
+ int ys, yd, yp, yprev;
+ int yOldScrollPos = editor->vert_si.nPos;
- do {
- p = ME_FindItemFwd(p, diStartRowOrParagraph);
- if (!p)
- break;
- if (p->type == diParagraph) {
- yp = p->member.para.pt.y;
- continue;
- }
- y = yp + p->member.row.pt.y;
- if (y >= yd)
- break;
+ if (!pCursor->nOffset && editor->bCaretAtEnd)
+ pRun = ME_FindItemBack(pRun, diRun);
+
+ p = ME_FindItemBack(pRun, diStartRowOrParagraph);
+ assert(p->type == diStartRow);
+ yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y;
+ yprev = ys = y = yp + p->member.row.pt.y;
+
+ /* For native richedit controls:
+ * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us
+ * v4.1 can scroll past this position here. */
+ ME_ScrollDown(editor, editor->sizeWindow.cy);
+ /* Only move the cursor by the amount scrolled. */
+ yd = y + editor->vert_si.nPos - yOldScrollPos;
pLast = p;
- yprev = y;
- } while(1);
- pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset, &editor->bCaretAtEnd);
- ME_UpdateSelection(editor, &tmp_curs);
- if (yprev >= editor->nTotalLength-editor->sizeWindow.cy)
- {
- ME_Cursor endCursor = {ME_FindItemBack(editor->pBuffer->pLast, diRun), 0};
- ME_EnsureVisible(editor, &endCursor);
- ME_Repaint(editor);
- }
- else
- {
- ME_ScrollUp(editor,ys-yprev);
+ do {
+ p = ME_FindItemFwd(p, diStartRowOrParagraph);
+ if (!p)
+ break;
+ if (p->type == diParagraph) {
+ yp = p->member.para.pt.y;
+ continue;
+ }
+ y = yp + p->member.row.pt.y;
+ if (y >= yd)
+ break;
+ pLast = p;
+ yprev = y;
+ } while(1);
+
+ pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset,
+ &editor->bCaretAtEnd);
}
assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun);
More information about the wine-cvs
mailing list