Commit abecd9e3 authored by Matt Finnicum's avatar Matt Finnicum Committed by Alexandre Julliard

riched20: Rewrite of scrolling and some redrawing code.

Replaces duplicated scrolling code with re-usable functions. Removes excessive boundary checking on scroll code, since that's done in the scrollbar control anyways. Properly separates repaint calls based on what has changed. Send EN_UPDATE and EN_CHANGE at the right places. Only call EnsureVisible on changes, not all repaints.
parent 6393fed2
...@@ -948,9 +948,9 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) ...@@ -948,9 +948,9 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun)); ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun));
ME_Repaint(editor); ME_Repaint(editor);
} }
else { else
ME_Scroll(editor, 0, ys-yprev); {
ME_Repaint(editor); ME_ScrollUp(editor, ys-yprev);
} }
assert(pCursor->pRun); assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
...@@ -1001,9 +1001,9 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) ...@@ -1001,9 +1001,9 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
ME_EnsureVisible(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun)); ME_EnsureVisible(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun));
ME_Repaint(editor); ME_Repaint(editor);
} }
else { else
ME_Scroll(editor, 0, ys-yprev); {
ME_Repaint(editor); ME_ScrollUp(editor,ys-yprev);
} }
assert(pCursor->pRun); assert(pCursor->pRun);
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
......
...@@ -1135,7 +1135,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ...@@ -1135,7 +1135,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nParagraphs = 1; ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0; ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph); ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
ed->nScrollPosY = 0;
ed->nZoomNumerator = ed->nZoomDenominator = 0; ed->nZoomNumerator = ed->nZoomDenominator = 0;
ed->bRedraw = TRUE; ed->bRedraw = TRUE;
ed->bHideSelection = FALSE; ed->bHideSelection = FALSE;
...@@ -1151,11 +1150,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) { ...@@ -1151,11 +1150,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->pFontCache[i].hFont = NULL; ed->pFontCache[i].hFont = NULL;
} }
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
FIXME("WS_HSCROLL requested, but horizontal scrolling isn't implemented yet.\n");
ed->bScrollX = 0;
ed->bScrollY = GetWindowLongW(hWnd, GWL_STYLE) & WS_VSCROLL;
ME_CheckCharOffsets(ed); ME_CheckCharOffsets(ed);
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD) if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD)
...@@ -1410,7 +1404,6 @@ get_msg_name(UINT msg) ...@@ -1410,7 +1404,6 @@ get_msg_name(UINT msg)
* RichEditANSIWndProc (RICHED20.10) * RichEditANSIWndProc (RICHED20.10)
*/ */
LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
SCROLLINFO si;
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0); ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
TRACE("hWnd %p msg %04x (%s) %08x %08lx\n", TRACE("hWnd %p msg %04x (%s) %08x %08lx\n",
...@@ -1583,9 +1576,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1583,9 +1576,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_SETSCROLLPOS: case EM_SETSCROLLPOS:
{ {
POINT *point = (POINT *)lParam; POINT *point = (POINT *)lParam;
/* Native behavior when point->y is too large is very odd / dosn't follow MSDN. ME_ScrollAbs(editor, point->y);
This seems to be a pretty close approximation of what it does. */
ME_Scroll(editor, 0, -(min(point->y, (editor->nTotalLength - 1)) - editor->nScrollPosY));
return 0; return 0;
} }
case EM_AUTOURLDETECT: case EM_AUTOURLDETECT:
...@@ -1599,7 +1590,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1599,7 +1590,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case EM_GETAUTOURLDETECT: case EM_GETAUTOURLDETECT:
{ {
return editor->AutoURLDetect_bEnable; return editor->AutoURLDetect_bEnable;
} }
case EM_EXSETSEL: case EM_EXSETSEL:
{ {
...@@ -1630,11 +1621,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1630,11 +1621,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case EM_SHOWSCROLLBAR: case EM_SHOWSCROLLBAR:
{ {
if (wParam == SB_VERT) ShowScrollBar(editor->hWnd, wParam, lParam);
editor->bScrollY = lParam;
else if (wParam == SB_HORZ)
editor->bScrollX = lParam;
ME_UpdateScrollBar(editor);
return 0; return 0;
} }
case EM_SETTEXTEX: case EM_SETTEXTEX:
...@@ -1769,7 +1756,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1769,7 +1756,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_GETFIRSTVISIBLELINE: case EM_GETFIRSTVISIBLELINE:
{ {
ME_DisplayItem *p = editor->pBuffer->pFirst; ME_DisplayItem *p = editor->pBuffer->pFirst;
int y = editor->nScrollPosY; int y = ME_GetYScrollPos(editor);
int ypara = 0; int ypara = 0;
int count = 0; int count = 0;
int ystart, yend; int ystart, yend;
...@@ -1798,22 +1785,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1798,22 +1785,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case EM_LINESCROLL: case EM_LINESCROLL:
{ {
int nPos = editor->nScrollPosY, nEnd= editor->nTotalLength - editor->sizeWindow.cy; ME_ScrollDown(editor, lParam * 8); /* FIXME follow the original */
nPos += 8 * lParam; /* FIXME follow the original */
if (nPos>=nEnd)
nPos = nEnd;
if (nPos<0)
nPos = 0;
if (nPos != editor->nScrollPosY) {
int dy = editor->nScrollPosY - nPos;
editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, dy, NULL, NULL);
UpdateWindow(hWnd);
}
}
return TRUE; /* Should return false if a single line richedit control */ return TRUE; /* Should return false if a single line richedit control */
} }
case WM_CLEAR: case WM_CLEAR:
...@@ -1853,36 +1825,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -1853,36 +1825,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_SCROLLCARET: case EM_SCROLLCARET:
{ {
int top, bottom; /* row's edges relative to document top */ int top, bottom; /* row's edges relative to document top */
int nPos;
ME_DisplayItem *para, *row; ME_DisplayItem *para, *row;
nPos = ME_GetYScrollPos(editor);
row = ME_RowStart(editor->pCursors[0].pRun); row = ME_RowStart(editor->pCursors[0].pRun);
para = ME_GetParagraph(row); para = ME_GetParagraph(row);
top = para->member.para.nYPos + row->member.row.nYPos; top = para->member.para.nYPos + row->member.row.nYPos;
bottom = top + row->member.row.nHeight; bottom = top + row->member.row.nHeight;
if ((top < editor->nScrollPosY) if (top < nPos) /* caret above window */
|| (editor->nScrollPosY + editor->sizeWindow.cy < bottom)) ME_ScrollAbs(editor, top);
{ else if (nPos + editor->sizeWindow.cy < bottom) /*below*/
int dy; ME_ScrollAbs(editor, bottom - editor->sizeWindow.cy);
int prevScrollPosY = editor->nScrollPosY;
if (top < editor->nScrollPosY) /* caret above window */
editor->nScrollPosY = top;
else /* caret below window */
editor->nScrollPosY = bottom - editor->sizeWindow.cy;
if (editor->nScrollPosY < 0)
editor->nScrollPosY = 0;
dy = prevScrollPosY - editor->nScrollPosY;
SetScrollPos(hWnd, SB_VERT, editor->nScrollPosY, TRUE);
if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, dy, NULL, NULL);
UpdateWindow(hWnd);
}
}
return 0; return 0;
} }
case WM_SETFONT: case WM_SETFONT:
...@@ -2066,7 +2021,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -2066,7 +2021,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
{ {
POINT *point = (POINT *)lParam; POINT *point = (POINT *)lParam;
point->x = 0; /* FIXME side scrolling not implemented */ point->x = 0; /* FIXME side scrolling not implemented */
point->y = editor->nScrollPosY; point->y = ME_GetYScrollPos(editor);
return 1; return 1;
} }
case EM_GETTEXTRANGE: case EM_GETTEXTRANGE:
...@@ -2300,13 +2255,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -2300,13 +2255,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case WM_CREATE: case WM_CREATE:
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL) if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
{ /* Squelch the default horizontal scrollbar it would make */ { /* Squelch the default horizontal scrollbar it would make */
si.cbSize = sizeof(SCROLLINFO); ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
si.fMask = SIF_POS | SIF_RANGE; }
si.nMax = 0;
si.nMin = 0;
si.nPos = 0;
SetScrollInfo(hWnd, SB_HORZ, &si, FALSE);
}
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_WrapMarkedParagraphs(editor); ME_WrapMarkedParagraphs(editor);
ME_MoveCaret(editor); ME_MoveCaret(editor);
...@@ -2428,79 +2378,51 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ...@@ -2428,79 +2378,51 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_SCROLL: /* fall through */ case EM_SCROLL: /* fall through */
case WM_VSCROLL: case WM_VSCROLL:
{ {
int nEnd; int origNPos;
int nPos = editor->nScrollPosY; int lineHeight;
int origNPos = nPos;
int lineHeight = 24; origNPos = ME_GetYScrollPos(editor);
si.cbSize = sizeof(SCROLLINFO); lineHeight = 24;
si.fMask = SIF_PAGE|SIF_POS|SIF_RANGE|SIF_TRACKPOS;
GetScrollInfo(hWnd, SB_VERT, &si);
if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle) if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle)
lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight; lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight;
if (lineHeight <= 0) lineHeight = 24; if (lineHeight <= 0) lineHeight = 24;
switch(LOWORD(wParam)) {
case SB_LINEUP: switch(LOWORD(wParam))
nPos -= lineHeight;
if (nPos<0) nPos = 0;
break;
case SB_LINEDOWN:
{ {
nEnd = editor->nTotalLength - editor->sizeWindow.cy; case SB_LINEUP:
if (nEnd < 0) nEnd = 0; ME_ScrollUp(editor,lineHeight);
nPos += lineHeight; break;
if (nPos>=nEnd) nPos = nEnd; case SB_LINEDOWN:
break; ME_ScrollDown(editor,lineHeight);
} break;
case SB_PAGEUP: case SB_PAGEUP:
nPos -= editor->sizeWindow.cy; ME_ScrollUp(editor,editor->sizeWindow.cy);
if (nPos<0) nPos = 0; break;
break; case SB_PAGEDOWN:
case SB_PAGEDOWN: ME_ScrollDown(editor,editor->sizeWindow.cy);
nEnd = editor->nTotalLength - editor->sizeWindow.cy; break;
if (nEnd < 0) nEnd = 0; case SB_THUMBTRACK:
nPos += editor->sizeWindow.cy; case SB_THUMBPOSITION:
if (nPos>=nEnd) nPos = nEnd; ME_ScrollAbs(editor,HIWORD(wParam));
break; break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
nPos = si.nTrackPos;
break;
}
if (nPos != editor->nScrollPosY) {
int dy = editor->nScrollPosY - nPos;
editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, dy, NULL, NULL);
UpdateWindow(hWnd);
}
} }
if (msg == EM_SCROLL) if (msg == EM_SCROLL)
return 0x00010000 | (((nPos - origNPos)/lineHeight) & 0xffff); return 0x00010000 | (((ME_GetYScrollPos(editor) - origNPos)/lineHeight) & 0xffff);
break; break;
} }
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
{ {
int gcWheelDelta = 0, nPos = editor->nScrollPosY, nEnd = editor->nTotalLength - editor->sizeWindow.cy; int gcWheelDelta;
UINT pulScrollLines; UINT pulScrollLines;
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
gcWheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); gcWheelDelta = -GET_WHEEL_DELTA_WPARAM(wParam);
if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines) if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
nPos += pulScrollLines * (gcWheelDelta / WHEEL_DELTA) * 8; /* FIXME follow the original */ {
if (nPos>=nEnd) /* FIXME follow the original */
nPos = nEnd; ME_ScrollDown(editor,pulScrollLines * (gcWheelDelta / WHEEL_DELTA) * 8);
if (nPos<0)
nPos = 0;
if (nPos != editor->nScrollPosY) {
int dy = editor->nScrollPosY - nPos;
editor->nScrollPosY = nPos;
SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, dy, NULL, NULL);
UpdateWindow(hWnd);
}
} }
break; break;
} }
...@@ -2933,7 +2855,7 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar) ...@@ -2933,7 +2855,7 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
url.cpMin=text_pos; url.cpMin=text_pos;
url.cpMax=car_pos-1; url.cpMax=car_pos-1;
ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link); ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
ME_Repaint(editor); ME_RewrapRepaint(editor);
break; break;
} }
} }
......
...@@ -173,7 +173,6 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y); ...@@ -173,7 +173,6 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y);
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars); void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style); const WCHAR *str, int len, ME_Style *style);
void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W *pFmt);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl); BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC); void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
...@@ -228,15 +227,22 @@ void ME_Repaint(ME_TextEditor *editor); ...@@ -228,15 +227,22 @@ void ME_Repaint(ME_TextEditor *editor);
void ME_RewrapRepaint(ME_TextEditor *editor); void ME_RewrapRepaint(ME_TextEditor *editor);
void ME_UpdateRepaint(ME_TextEditor *editor); void ME_UpdateRepaint(ME_TextEditor *editor);
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph); void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
void ME_UpdateScrollBar(ME_TextEditor *editor);
int ME_GetYScrollPos(ME_TextEditor *editor);
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun); void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
COLORREF ME_GetBackColor(ME_TextEditor *editor); COLORREF ME_GetBackColor(ME_TextEditor *editor);
void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
void ME_InvalidateSelection(ME_TextEditor *editor); void ME_InvalidateSelection(ME_TextEditor *editor);
void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor); void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor);
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator); BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
/* scroll functions in paint.c */
void ME_ScrollAbs(ME_TextEditor *editor, int absY);
void ME_ScrollUp(ME_TextEditor *editor, int cy);
void ME_ScrollDown(ME_TextEditor *editor, int cy);
void ME_Scroll(ME_TextEditor *editor, int value, int type);
void ME_UpdateScrollBar(ME_TextEditor *editor);
int ME_GetYScrollPos(ME_TextEditor *editor);
BOOL ME_GetYScrollVisible(ME_TextEditor *editor);
/* richole.c */ /* richole.c */
extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *); extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
......
...@@ -306,8 +306,6 @@ typedef struct tagME_TextEditor ...@@ -306,8 +306,6 @@ typedef struct tagME_TextEditor
int nLastSelStart, nLastSelEnd; int nLastSelStart, nLastSelEnd;
ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara; ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara;
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]; ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
BOOL bScrollX, bScrollY;
int nScrollPosY;
int nZoomNumerator, nZoomDenominator; int nZoomNumerator, nZoomDenominator;
RECT rcFormat; RECT rcFormat;
BOOL bRedraw; BOOL bRedraw;
......
...@@ -96,36 +96,42 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpda ...@@ -96,36 +96,42 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpda
void ME_Repaint(ME_TextEditor *editor) void ME_Repaint(ME_TextEditor *editor)
{ {
ME_Cursor *pCursor = &editor->pCursors[0]; if (ME_WrapMarkedParagraphs(editor))
if (ME_WrapMarkedParagraphs(editor)) {
ME_UpdateScrollBar(editor);
}
if (editor->bRedraw)
{ {
ME_EnsureVisible(editor, pCursor->pRun); ME_UpdateScrollBar(editor);
UpdateWindow(editor->hWnd); FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n");
} }
ME_SendOldNotify(editor, EN_UPDATE);
UpdateWindow(editor->hWnd);
} }
void ME_UpdateRepaint(ME_TextEditor *editor) void ME_UpdateRepaint(ME_TextEditor *editor)
{ {
/* /* Should be called whenever the contents of the control have changed */
InvalidateRect(editor->hWnd, NULL, TRUE); ME_Cursor *pCursor;
*/
if (ME_WrapMarkedParagraphs(editor))
ME_UpdateScrollBar(editor);
/* Ensure that the cursor is visible */
pCursor = &editor->pCursors[0];
ME_EnsureVisible(editor, pCursor->pRun);
ME_SendOldNotify(editor, EN_CHANGE); ME_SendOldNotify(editor, EN_CHANGE);
ME_Repaint(editor); ME_Repaint(editor);
ME_SendOldNotify(editor, EN_UPDATE);
ME_SendSelChange(editor); ME_SendSelChange(editor);
} }
void void
ME_RewrapRepaint(ME_TextEditor *editor) ME_RewrapRepaint(ME_TextEditor *editor)
{ {
/* RewrapRepaint should be called whenever the control has changed in
* looks, but not content. Like resizing. */
ME_MarkAllForWrapping(editor); ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor); ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor); ME_UpdateScrollBar(editor);
ME_Repaint(editor); ME_Repaint(editor);
} }
...@@ -375,88 +381,118 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) { ...@@ -375,88 +381,118 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
SetTextAlign(c->hDC, align); SetTextAlign(c->hDC, align);
} }
void ME_Scroll(ME_TextEditor *editor, int cx, int cy) void ME_ScrollAbs(ME_TextEditor *editor, int absY)
{
ME_Scroll(editor, absY, 1);
}
void ME_ScrollUp(ME_TextEditor *editor, int cy)
{
ME_Scroll(editor, cy, 2);
}
void ME_ScrollDown(ME_TextEditor *editor, int cy)
{
ME_Scroll(editor, cy, 3);
}
void ME_Scroll(ME_TextEditor *editor, int value, int type)
{ {
SCROLLINFO si; SCROLLINFO si;
HWND hWnd = editor->hWnd; int nOrigPos, nNewPos, nActualScroll;
nOrigPos = ME_GetYScrollPos(editor);
si.cbSize = sizeof(SCROLLINFO); si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS; si.fMask = SIF_POS;
GetScrollInfo(hWnd, SB_VERT, &si);
si.nPos = editor->nScrollPosY -= cy; switch (type)
SetScrollInfo(hWnd, SB_VERT, &si, TRUE); {
case 1:
/*Scroll absolutly*/
si.nPos = value;
break;
case 2:
/* Scroll up - towards the beginning of the document */
si.nPos = nOrigPos - value;
break;
case 3:
/* Scroll down - towards the end of the document */
si.nPos = nOrigPos + value;
break;
default:
FIXME("ME_Scroll called incorrectly\n");
si.nPos = 0;
}
nNewPos = SetScrollInfo(editor->hWnd, SB_VERT, &si, editor->bRedraw);
nActualScroll = nOrigPos - nNewPos;
if (editor->bRedraw) if (editor->bRedraw)
{ {
if (abs(cy) > editor->sizeWindow.cy) if (abs(nActualScroll) > editor->sizeWindow.cy)
InvalidateRect(editor->hWnd, NULL, TRUE); InvalidateRect(editor->hWnd, NULL, TRUE);
else else
ScrollWindowEx(hWnd, cx, cy, NULL, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE); ScrollWindowEx(editor->hWnd, 0, nActualScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
ME_Repaint(editor);
} }
ME_UpdateScrollBar(editor);
} }
void ME_UpdateScrollBar(ME_TextEditor *editor)
{ void ME_UpdateScrollBar(ME_TextEditor *editor)
HWND hWnd = editor->hWnd; {
/* Note that this is the only funciton that should ever call SetScrolLInfo
* with SIF_PAGE or SIF_RANGE. SetScrollPos and SetScrollRange should never
* be used at all. */
HWND hWnd;
SCROLLINFO si; SCROLLINFO si;
BOOL bUpdateScrollBars; BOOL bScrollBarWasVisible,bScrollBarWillBeVisible;
if (ME_WrapMarkedParagraphs(editor))
FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
hWnd = editor->hWnd;
si.cbSize = sizeof(si); si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; bScrollBarWasVisible = ME_GetYScrollVisible(editor);
GetScrollInfo(hWnd, SB_VERT, &si); bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
bUpdateScrollBars = (editor->bScrollY)&& ((si.nMax != editor->nTotalLength) || (si.nPage != editor->sizeWindow.cy));
if (editor->bScrollY != (si.nMax > 0))
{ /* The scroll bar needs to be shown or hidden */
si.fMask = SIF_RANGE | SIF_PAGE;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
si.nMin = 0; if (bScrollBarWasVisible != bScrollBarWillBeVisible)
si.nPage = editor->sizeWindow.cy; {
ShowScrollBar(hWnd, SB_VERT, bScrollBarWillBeVisible);
if (editor->bScrollY)
si.nMax = editor->nTotalLength;
else
si.nMax = 0;
SetScrollInfo(hWnd, SB_VERT, &si, FALSE);
ME_MarkAllForWrapping(editor); ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor); ME_WrapMarkedParagraphs(editor);
bUpdateScrollBars = TRUE;
}
if (bUpdateScrollBars)
{
int nScroll = 0;
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
if (editor->bScrollY)
{
si.nMax = editor->nTotalLength;
si.nPage = editor->sizeWindow.cy;
if (si.nPos > si.nMax-si.nPage)
{
nScroll = (si.nMax-si.nPage)-si.nPos;
si.nPos = si.nMax-si.nPage;
}
}
else
{
si.nMax = 0;
si.nPage = 0;
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);
} }
si.fMask = SIF_PAGE | SIF_RANGE;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
si.nMin = 0;
si.nMax = editor->nTotalLength;
si.nPage = editor->sizeWindow.cy;
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
} }
int ME_GetYScrollPos(ME_TextEditor *editor) int ME_GetYScrollPos(ME_TextEditor *editor)
{ {
return editor->nScrollPosY; SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(editor->hWnd, SB_VERT, &si);
return si.nPos;
}
BOOL ME_GetYScrollVisible(ME_TextEditor *editor)
{ /* Returns true if the scrollbar is visible */
SCROLLBARINFO sbi;
sbi.cbSize = sizeof(sbi);
GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi);
return ((sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE) == 0);
} }
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun) void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
...@@ -464,7 +500,6 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun) ...@@ -464,7 +500,6 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
ME_DisplayItem *pRow = ME_FindItemBack(pRun, diStartRow); ME_DisplayItem *pRow = ME_FindItemBack(pRun, diStartRow);
ME_DisplayItem *pPara = ME_FindItemBack(pRun, diParagraph); ME_DisplayItem *pPara = ME_FindItemBack(pRun, diParagraph);
int y, yrel, yheight, yold; int y, yrel, yheight, yold;
HWND hWnd = editor->hWnd;
assert(pRow); assert(pRow);
assert(pPara); assert(pPara);
...@@ -473,24 +508,11 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun) ...@@ -473,24 +508,11 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
yheight = pRow->member.row.nHeight; yheight = pRow->member.row.nHeight;
yold = ME_GetYScrollPos(editor); yold = ME_GetYScrollPos(editor);
yrel = y - yold; yrel = y - yold;
if (yrel < 0) {
editor->nScrollPosY = y; if (y < yold)
SetScrollPos(hWnd, SB_VERT, y, TRUE); ME_ScrollAbs(editor,y);
if (editor->bRedraw) else if (yrel + yheight > editor->sizeWindow.cy)
{ ME_ScrollAbs(editor,y+yheight-editor->sizeWindow.cy);
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);
if (editor->bRedraw)
{
ScrollWindow(hWnd, 0, -(newy-yold), NULL, NULL);
UpdateWindow(hWnd);
}
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment