RICHEDIT: PageUp and better scrollbar support (replaces previous
PageUp patch)
Krzysztof Foltman
wdev at foltman.com
Sun Mar 20 08:55:55 CST 2005
ChangeLog:
* PageUp key support (like in the old patch +/- minor fixes)
* Support for "normal" scroll bar functionality (line and page scrolling)
Krzysztof
-------------- next part --------------
Index: caret.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/caret.c,v
retrieving revision 1.7
diff -u -r1.7 caret.c
--- caret.c 19 Mar 2005 17:06:17 -0000 1.7
+++ caret.c 20 Mar 2005 14:52:14 -0000
@@ -112,7 +112,7 @@
}
CreateCaret(editor->hWnd, NULL, 0, pSizeRun->member.run.nAscent+pSizeRun->member.run.nDescent);
SetCaretPos(run->member.run.pt.x+sz.cx,
- para->member.para.nYPos+row->member.row.nBaseline+pSizeRun->member.run.pt.y-pSizeRun->member.run.nAscent-GetScrollPos(editor->hWnd, SB_VERT));
+ para->member.para.nYPos+row->member.row.nBaseline+pSizeRun->member.run.pt.y-pSizeRun->member.run.nAscent-ME_GetYScrollPos(editor));
} else {
assert(0 == "Wrapped paragraph run without a row?");
CreateCaret(editor->hWnd, NULL, 0, 10);
@@ -532,7 +532,7 @@
editor->nUDArrowX = -1;
- y += GetScrollPos(editor->hWnd, SB_VERT);
+ y += ME_GetYScrollPos(editor);
tmp_cursor = editor->pCursors[0];
is_selection = ME_IsSelection(editor);
@@ -563,7 +563,7 @@
{
ME_Cursor tmp_cursor;
- y += GetScrollPos(editor->hWnd, SB_VERT);
+ y += ME_GetYScrollPos(editor);
tmp_cursor = editor->pCursors[0];
if (!ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd))
@@ -697,6 +697,61 @@
assert(pCursor->pRun->type == diRun);
}
+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);
+
+ p = ME_FindItemBack(pRun, diStartRowOrParagraph);
+ assert(p->type == diStartRow);
+ yp = ME_FindItemBack(p, diParagraph)->member.para.nYPos;
+ yprev = ys = y = yp + p->member.row.nYPos;
+ yd = y - editor->sizeWindow.cy;
+ pLast = p;
+
+ do {
+ p = ME_FindItemBack(p, diStartRowOrParagraph);
+ if (!p)
+ break;
+ if (p->type == diParagraph) { /* crossing paragraphs */
+ if (p->member.para.prev_para == NULL)
+ break;
+ yp = p->member.para.prev_para->member.para.nYPos;
+ continue;
+ }
+ y = yp + p->member.row.nYPos;
+ 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_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun));
+ ME_Repaint(editor);
+ }
+ else {
+ ME_Scroll(editor, 0, ys-yprev);
+ ME_Repaint(editor);
+ }
+ 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)). */
+
void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{
ME_DisplayItem *pRun = pCursor->pRun;
@@ -738,8 +793,8 @@
ME_Repaint(editor);
}
else {
- ME_Repaint(editor);
ME_Scroll(editor, 0, ys-yprev);
+ ME_Repaint(editor);
}
assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun);
@@ -865,7 +920,6 @@
{
editor->pCursors[1] = *pTempCursor;
return TRUE;
-/* ME_EnsureVisible(editor, editor->pCursors[0].pRun); */
}
}
@@ -941,6 +995,11 @@
ME_RepaintSelection(editor, &tmp_curs);
ME_SendSelChange(editor);
return TRUE;
+ case VK_PRIOR:
+ ME_ArrowPageUp(editor, p);
+ ME_ClearTempStyle(editor);
+ ME_SendSelChange(editor);
+ return TRUE;
case VK_NEXT:
ME_ArrowPageDown(editor, p);
ME_ClearTempStyle(editor);
Index: editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.17
diff -u -r1.17 editor.c
--- editor.c 19 Mar 2005 17:06:17 -0000 1.17
+++ editor.c 20 Mar 2005 14:52:15 -0000
@@ -564,7 +564,6 @@
ed->pCursors[1].pRun = ME_FindItemFwd(ed->pBuffer->pFirst, diRun);
ed->pCursors[1].nOffset = 0;
ed->nLastTotalLength = ed->nTotalLength = 0;
- ed->nScrollPos = 0;
ed->nUDArrowX = -1;
ed->nSequence = 0;
ed->rgbBackColor = -1;
@@ -575,6 +574,7 @@
ed->nUndoMode = umAddToUndo;
ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0;
+ ed->nScrollPosY = 0;
for (i=0; i<HFONT_CACHE_SIZE; i++)
{
ed->pFontCache[i].nRefs = 0;
@@ -1131,17 +1131,41 @@
}
case WM_VSCROLL:
{
+ int nPos = editor->nScrollPosY;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE|SIF_POS|SIF_RANGE|SIF_TRACKPOS;
GetScrollInfo(hWnd, SB_VERT, &si);
switch(LOWORD(wParam)) {
+ case SB_LINEUP:
+ nPos -= 24; /* FIXME follow the original */
+ if (nPos<0) nPos = 0;
+ break;
+ case SB_LINEDOWN:
+ {
+ int nEnd = editor->nTotalLength - editor->sizeWindow.cy;
+ nPos += 24; /* FIXME follow the original */
+ if (nPos>=nEnd) nPos = nEnd;
+ break;
+ }
+ case SB_PAGEUP:
+ nPos -= editor->sizeWindow.cy;
+ if (nPos<0) nPos = 0;
+ break;
+ case SB_PAGEDOWN:
+ nPos += editor->sizeWindow.cy;
+ if (nPos>=editor->nTotalLength) nPos = editor->nTotalLength-1;
+ break;
case SB_THUMBTRACK:
- SetScrollPos(hWnd, SB_VERT, si.nTrackPos, FALSE);
- ScrollWindow(hWnd, 0, si.nPos-si.nTrackPos, NULL, NULL);
- /* InvalidateRect(hWnd, NULL, TRUE); */
- UpdateWindow(hWnd);
+ case SB_THUMBPOSITION:
+ nPos = si.nTrackPos;
break;
}
+ if (nPos != editor->nScrollPosY) {
+ ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL);
+ editor->nScrollPosY = nPos;
+ SetScrollPos(hWnd, SB_VERT, nPos, FALSE);
+ UpdateWindow(hWnd);
+ }
break;
}
case WM_SIZE:
Index: editor.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.h,v
retrieving revision 1.10
diff -u -r1.10 editor.h
--- editor.h 19 Mar 2005 17:06:17 -0000 1.10
+++ editor.h 20 Mar 2005 14:52:15 -0000
@@ -191,7 +191,7 @@
void ME_UpdateRepaint(ME_TextEditor *editor);
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
void ME_UpdateScrollBar(ME_TextEditor *editor);
-int ME_GetScrollPos(ME_TextEditor *editor);
+int ME_GetYScrollPos(ME_TextEditor *editor);
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
COLORREF ME_GetBackColor(ME_TextEditor *editor);
void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
Index: editstr.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editstr.h,v
retrieving revision 1.6
diff -u -r1.6 editstr.h
--- editstr.h 19 Mar 2005 17:06:17 -0000 1.6
+++ editstr.h 20 Mar 2005 14:52:15 -0000
@@ -231,7 +231,6 @@
ME_Cursor *pCursors;
int nCursors;
SIZE sizeWindow;
- int nScrollPos;
int nTotalLength, nLastTotalLength;
int nUDArrowX;
int nSequence;
@@ -247,6 +246,7 @@
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
ME_OutStream *pStream;
BOOL bScrollX, bScrollY;
+ int nScrollPosY;
} ME_TextEditor;
typedef struct tagME_Context
Index: paint.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/paint.c,v
retrieving revision 1.7
diff -u -r1.7 paint.c
--- paint.c 19 Mar 2005 17:06:17 -0000 1.7
+++ paint.c 20 Mar 2005 14:52:15 -0000
@@ -28,7 +28,7 @@
int yoffset;
editor->nSequence++;
- yoffset = GetScrollPos(editor->hWnd, SB_VERT);
+ yoffset = ME_GetYScrollPos(editor);
ME_InitContext(&c, editor, hDC);
SetBkMode(hDC, TRANSPARENT);
ME_MoveCaret(editor);
@@ -386,9 +386,12 @@
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
GetScrollInfo(hWnd, SB_VERT, &si);
- si.nPos -= cy;
+ si.nPos = editor->nScrollPosY -= cy;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
- ScrollWindow(hWnd, cx, cy, NULL, NULL);
+ if (abs(cy) > editor->sizeWindow.cy)
+ InvalidateRect(editor->hWnd, NULL, TRUE);
+ else
+ ScrollWindowEx(hWnd, cx, cy, NULL, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE);
}
void ME_UpdateScrollBar(ME_TextEditor *editor)
@@ -436,15 +439,16 @@
si.nPos = 0;
}
TRACE("min=%d max=%d page=%d pos=%d shift=%d\n", si.nMin, si.nMax, si.nPage, si.nPos, nScroll);
+ editor->nScrollPosY = si.nPos;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
if (nScroll)
ScrollWindow(hWnd, 0, -nScroll, NULL, NULL);
}
}
-int ME_GetScrollPos(ME_TextEditor *editor)
+int ME_GetYScrollPos(ME_TextEditor *editor)
{
- return GetScrollPos(editor->hWnd, SB_VERT);
+ return editor->nScrollPosY;
}
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
@@ -459,14 +463,16 @@
y = pPara->member.para.nYPos+pRow->member.row.nYPos;
yheight = pRow->member.row.nHeight;
- yold = ME_GetScrollPos(editor);
+ yold = ME_GetYScrollPos(editor);
yrel = y - yold;
if (yrel < 0) {
+ editor->nScrollPosY = y;
SetScrollPos(hWnd, SB_VERT, y, TRUE);
ScrollWindow(hWnd, 0, -yrel, NULL, NULL);
UpdateWindow(hWnd);
} else if (yrel + yheight > editor->sizeWindow.cy) {
int newy = y+yheight-editor->sizeWindow.cy;
+ editor->nScrollPosY = newy;
SetScrollPos(hWnd, SB_VERT, newy, TRUE);
ScrollWindow(hWnd, 0, -(newy-yold), NULL, NULL);
UpdateWindow(hWnd);
More information about the wine-patches
mailing list