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.
This commit is contained in:
parent
6393fed2d4
commit
abecd9e393
|
@ -948,9 +948,9 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
|
|||
ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun));
|
||||
ME_Repaint(editor);
|
||||
}
|
||||
else {
|
||||
ME_Scroll(editor, 0, ys-yprev);
|
||||
ME_Repaint(editor);
|
||||
else
|
||||
{
|
||||
ME_ScrollUp(editor, ys-yprev);
|
||||
}
|
||||
assert(pCursor->pRun);
|
||||
assert(pCursor->pRun->type == diRun);
|
||||
|
@ -1001,9 +1001,9 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
|
|||
ME_EnsureVisible(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun));
|
||||
ME_Repaint(editor);
|
||||
}
|
||||
else {
|
||||
ME_Scroll(editor, 0, ys-yprev);
|
||||
ME_Repaint(editor);
|
||||
else
|
||||
{
|
||||
ME_ScrollUp(editor,ys-yprev);
|
||||
}
|
||||
assert(pCursor->pRun);
|
||||
assert(pCursor->pRun->type == diRun);
|
||||
|
|
|
@ -1135,7 +1135,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
ed->nParagraphs = 1;
|
||||
ed->nLastSelStart = ed->nLastSelEnd = 0;
|
||||
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
|
||||
ed->nScrollPosY = 0;
|
||||
ed->nZoomNumerator = ed->nZoomDenominator = 0;
|
||||
ed->bRedraw = TRUE;
|
||||
ed->bHideSelection = FALSE;
|
||||
|
@ -1151,11 +1150,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
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);
|
||||
|
||||
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD)
|
||||
|
@ -1410,7 +1404,6 @@ get_msg_name(UINT msg)
|
|||
* RichEditANSIWndProc (RICHED20.10)
|
||||
*/
|
||||
LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
SCROLLINFO si;
|
||||
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
|
||||
|
||||
TRACE("hWnd %p msg %04x (%s) %08x %08lx\n",
|
||||
|
@ -1583,9 +1576,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case EM_SETSCROLLPOS:
|
||||
{
|
||||
POINT *point = (POINT *)lParam;
|
||||
/* Native behavior when point->y is too large is very odd / dosn't follow MSDN.
|
||||
This seems to be a pretty close approximation of what it does. */
|
||||
ME_Scroll(editor, 0, -(min(point->y, (editor->nTotalLength - 1)) - editor->nScrollPosY));
|
||||
ME_ScrollAbs(editor, point->y);
|
||||
return 0;
|
||||
}
|
||||
case EM_AUTOURLDETECT:
|
||||
|
@ -1599,7 +1590,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
case EM_GETAUTOURLDETECT:
|
||||
{
|
||||
return editor->AutoURLDetect_bEnable;
|
||||
return editor->AutoURLDetect_bEnable;
|
||||
}
|
||||
case EM_EXSETSEL:
|
||||
{
|
||||
|
@ -1630,11 +1621,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
case EM_SHOWSCROLLBAR:
|
||||
{
|
||||
if (wParam == SB_VERT)
|
||||
editor->bScrollY = lParam;
|
||||
else if (wParam == SB_HORZ)
|
||||
editor->bScrollX = lParam;
|
||||
ME_UpdateScrollBar(editor);
|
||||
ShowScrollBar(editor->hWnd, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
case EM_SETTEXTEX:
|
||||
|
@ -1769,7 +1756,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case EM_GETFIRSTVISIBLELINE:
|
||||
{
|
||||
ME_DisplayItem *p = editor->pBuffer->pFirst;
|
||||
int y = editor->nScrollPosY;
|
||||
int y = ME_GetYScrollPos(editor);
|
||||
int ypara = 0;
|
||||
int count = 0;
|
||||
int ystart, yend;
|
||||
|
@ -1798,22 +1785,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
case EM_LINESCROLL:
|
||||
{
|
||||
int nPos = editor->nScrollPosY, nEnd= editor->nTotalLength - editor->sizeWindow.cy;
|
||||
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);
|
||||
}
|
||||
}
|
||||
ME_ScrollDown(editor, lParam * 8); /* FIXME follow the original */
|
||||
return TRUE; /* Should return false if a single line richedit control */
|
||||
}
|
||||
case WM_CLEAR:
|
||||
|
@ -1853,36 +1825,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case EM_SCROLLCARET:
|
||||
{
|
||||
int top, bottom; /* row's edges relative to document top */
|
||||
int nPos;
|
||||
ME_DisplayItem *para, *row;
|
||||
|
||||
|
||||
nPos = ME_GetYScrollPos(editor);
|
||||
row = ME_RowStart(editor->pCursors[0].pRun);
|
||||
para = ME_GetParagraph(row);
|
||||
top = para->member.para.nYPos + row->member.row.nYPos;
|
||||
bottom = top + row->member.row.nHeight;
|
||||
|
||||
if ((top < editor->nScrollPosY)
|
||||
|| (editor->nScrollPosY + editor->sizeWindow.cy < bottom))
|
||||
{
|
||||
int dy;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (top < nPos) /* caret above window */
|
||||
ME_ScrollAbs(editor, top);
|
||||
else if (nPos + editor->sizeWindow.cy < bottom) /*below*/
|
||||
ME_ScrollAbs(editor, bottom - editor->sizeWindow.cy);
|
||||
return 0;
|
||||
}
|
||||
case WM_SETFONT:
|
||||
|
@ -2066,7 +2021,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
{
|
||||
POINT *point = (POINT *)lParam;
|
||||
point->x = 0; /* FIXME side scrolling not implemented */
|
||||
point->y = editor->nScrollPosY;
|
||||
point->y = ME_GetYScrollPos(editor);
|
||||
return 1;
|
||||
}
|
||||
case EM_GETTEXTRANGE:
|
||||
|
@ -2300,13 +2255,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case WM_CREATE:
|
||||
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL)
|
||||
{ /* Squelch the default horizontal scrollbar it would make */
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_POS | SIF_RANGE;
|
||||
si.nMax = 0;
|
||||
si.nMin = 0;
|
||||
si.nPos = 0;
|
||||
SetScrollInfo(hWnd, SB_HORZ, &si, FALSE);
|
||||
}
|
||||
ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
|
||||
}
|
||||
ME_CommitUndo(editor);
|
||||
ME_WrapMarkedParagraphs(editor);
|
||||
ME_MoveCaret(editor);
|
||||
|
@ -2428,79 +2378,51 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
case EM_SCROLL: /* fall through */
|
||||
case WM_VSCROLL:
|
||||
{
|
||||
int nEnd;
|
||||
int nPos = editor->nScrollPosY;
|
||||
int origNPos = nPos;
|
||||
int lineHeight = 24;
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_PAGE|SIF_POS|SIF_RANGE|SIF_TRACKPOS;
|
||||
GetScrollInfo(hWnd, SB_VERT, &si);
|
||||
int origNPos;
|
||||
int lineHeight;
|
||||
|
||||
origNPos = ME_GetYScrollPos(editor);
|
||||
lineHeight = 24;
|
||||
|
||||
if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle)
|
||||
lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight;
|
||||
lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight;
|
||||
if (lineHeight <= 0) lineHeight = 24;
|
||||
switch(LOWORD(wParam)) {
|
||||
case SB_LINEUP:
|
||||
nPos -= lineHeight;
|
||||
if (nPos<0) nPos = 0;
|
||||
break;
|
||||
case SB_LINEDOWN:
|
||||
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
nEnd = editor->nTotalLength - editor->sizeWindow.cy;
|
||||
if (nEnd < 0) nEnd = 0;
|
||||
nPos += lineHeight;
|
||||
if (nPos>=nEnd) nPos = nEnd;
|
||||
break;
|
||||
}
|
||||
case SB_PAGEUP:
|
||||
nPos -= editor->sizeWindow.cy;
|
||||
if (nPos<0) nPos = 0;
|
||||
break;
|
||||
case SB_PAGEDOWN:
|
||||
nEnd = editor->nTotalLength - editor->sizeWindow.cy;
|
||||
if (nEnd < 0) nEnd = 0;
|
||||
nPos += editor->sizeWindow.cy;
|
||||
if (nPos>=nEnd) nPos = nEnd;
|
||||
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);
|
||||
}
|
||||
case SB_LINEUP:
|
||||
ME_ScrollUp(editor,lineHeight);
|
||||
break;
|
||||
case SB_LINEDOWN:
|
||||
ME_ScrollDown(editor,lineHeight);
|
||||
break;
|
||||
case SB_PAGEUP:
|
||||
ME_ScrollUp(editor,editor->sizeWindow.cy);
|
||||
break;
|
||||
case SB_PAGEDOWN:
|
||||
ME_ScrollDown(editor,editor->sizeWindow.cy);
|
||||
break;
|
||||
case SB_THUMBTRACK:
|
||||
case SB_THUMBPOSITION:
|
||||
ME_ScrollAbs(editor,HIWORD(wParam));
|
||||
break;
|
||||
}
|
||||
if (msg == EM_SCROLL)
|
||||
return 0x00010000 | (((nPos - origNPos)/lineHeight) & 0xffff);
|
||||
return 0x00010000 | (((ME_GetYScrollPos(editor) - origNPos)/lineHeight) & 0xffff);
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
int gcWheelDelta = 0, nPos = editor->nScrollPosY, nEnd = editor->nTotalLength - editor->sizeWindow.cy;
|
||||
int gcWheelDelta;
|
||||
UINT pulScrollLines;
|
||||
|
||||
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
|
||||
gcWheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
gcWheelDelta = -GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
|
||||
if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
|
||||
nPos += pulScrollLines * (gcWheelDelta / WHEEL_DELTA) * 8; /* 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);
|
||||
}
|
||||
{
|
||||
/* FIXME follow the original */
|
||||
ME_ScrollDown(editor,pulScrollLines * (gcWheelDelta / WHEEL_DELTA) * 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2933,7 +2855,7 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
|
|||
url.cpMin=text_pos;
|
||||
url.cpMax=car_pos-1;
|
||||
ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
|
||||
ME_Repaint(editor);
|
||||
ME_RewrapRepaint(editor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
||||
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);
|
||||
|
||||
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
|
||||
|
@ -228,15 +227,22 @@ void ME_Repaint(ME_TextEditor *editor);
|
|||
void ME_RewrapRepaint(ME_TextEditor *editor);
|
||||
void ME_UpdateRepaint(ME_TextEditor *editor);
|
||||
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);
|
||||
COLORREF ME_GetBackColor(ME_TextEditor *editor);
|
||||
void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
|
||||
void ME_InvalidateSelection(ME_TextEditor *editor);
|
||||
void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor);
|
||||
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 */
|
||||
extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
|
||||
|
||||
|
|
|
@ -306,8 +306,6 @@ typedef struct tagME_TextEditor
|
|||
int nLastSelStart, nLastSelEnd;
|
||||
ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara;
|
||||
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
|
||||
BOOL bScrollX, bScrollY;
|
||||
int nScrollPosY;
|
||||
int nZoomNumerator, nZoomDenominator;
|
||||
RECT rcFormat;
|
||||
BOOL bRedraw;
|
||||
|
|
|
@ -96,36 +96,42 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpda
|
|||
|
||||
void ME_Repaint(ME_TextEditor *editor)
|
||||
{
|
||||
ME_Cursor *pCursor = &editor->pCursors[0];
|
||||
|
||||
if (ME_WrapMarkedParagraphs(editor)) {
|
||||
ME_UpdateScrollBar(editor);
|
||||
}
|
||||
if (editor->bRedraw)
|
||||
if (ME_WrapMarkedParagraphs(editor))
|
||||
{
|
||||
ME_EnsureVisible(editor, pCursor->pRun);
|
||||
UpdateWindow(editor->hWnd);
|
||||
ME_UpdateScrollBar(editor);
|
||||
FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n");
|
||||
}
|
||||
ME_SendOldNotify(editor, EN_UPDATE);
|
||||
UpdateWindow(editor->hWnd);
|
||||
}
|
||||
|
||||
void ME_UpdateRepaint(ME_TextEditor *editor)
|
||||
{
|
||||
/*
|
||||
InvalidateRect(editor->hWnd, NULL, TRUE);
|
||||
*/
|
||||
/* Should be called whenever the contents of the control have changed */
|
||||
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_Repaint(editor);
|
||||
ME_SendOldNotify(editor, EN_UPDATE);
|
||||
ME_SendSelChange(editor);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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_WrapMarkedParagraphs(editor);
|
||||
ME_UpdateScrollBar(editor);
|
||||
|
||||
ME_Repaint(editor);
|
||||
}
|
||||
|
||||
|
@ -375,88 +381,118 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
|||
SetTextAlign(c->hDC, align);
|
||||
}
|
||||
|
||||
void ME_Scroll(ME_TextEditor *editor, int cx, int cy)
|
||||
void ME_ScrollAbs(ME_TextEditor *editor, int absY)
|
||||
{
|
||||
SCROLLINFO si;
|
||||
HWND hWnd = editor->hWnd;
|
||||
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_POS;
|
||||
GetScrollInfo(hWnd, SB_VERT, &si);
|
||||
si.nPos = editor->nScrollPosY -= cy;
|
||||
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
||||
if (editor->bRedraw)
|
||||
{
|
||||
if (abs(cy) > editor->sizeWindow.cy)
|
||||
InvalidateRect(editor->hWnd, NULL, TRUE);
|
||||
else
|
||||
ScrollWindowEx(hWnd, cx, cy, NULL, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE);
|
||||
}
|
||||
ME_Scroll(editor, absY, 1);
|
||||
}
|
||||
|
||||
void ME_UpdateScrollBar(ME_TextEditor *editor)
|
||||
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)
|
||||
{
|
||||
HWND hWnd = editor->hWnd;
|
||||
SCROLLINFO si;
|
||||
BOOL bUpdateScrollBars;
|
||||
si.cbSize = sizeof(si);
|
||||
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
|
||||
GetScrollInfo(hWnd, SB_VERT, &si);
|
||||
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;
|
||||
int nOrigPos, nNewPos, nActualScroll;
|
||||
|
||||
nOrigPos = ME_GetYScrollPos(editor);
|
||||
|
||||
si.nMin = 0;
|
||||
si.nPage = editor->sizeWindow.cy;
|
||||
|
||||
if (editor->bScrollY)
|
||||
si.nMax = editor->nTotalLength;
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_POS;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
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 (abs(nActualScroll) > editor->sizeWindow.cy)
|
||||
InvalidateRect(editor->hWnd, NULL, TRUE);
|
||||
else
|
||||
si.nMax = 0;
|
||||
|
||||
SetScrollInfo(hWnd, SB_VERT, &si, FALSE);
|
||||
ScrollWindowEx(editor->hWnd, 0, nActualScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE);
|
||||
ME_Repaint(editor);
|
||||
}
|
||||
|
||||
ME_UpdateScrollBar(editor);
|
||||
}
|
||||
|
||||
|
||||
void ME_UpdateScrollBar(ME_TextEditor *editor)
|
||||
{
|
||||
/* 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;
|
||||
BOOL bScrollBarWasVisible,bScrollBarWillBeVisible;
|
||||
|
||||
if (ME_WrapMarkedParagraphs(editor))
|
||||
FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
|
||||
|
||||
hWnd = editor->hWnd;
|
||||
si.cbSize = sizeof(si);
|
||||
bScrollBarWasVisible = ME_GetYScrollVisible(editor);
|
||||
bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
|
||||
|
||||
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
|
||||
{
|
||||
ShowScrollBar(hWnd, SB_VERT, bScrollBarWillBeVisible);
|
||||
ME_MarkAllForWrapping(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)
|
||||
{
|
||||
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)
|
||||
|
@ -464,7 +500,6 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
|
|||
ME_DisplayItem *pRow = ME_FindItemBack(pRun, diStartRow);
|
||||
ME_DisplayItem *pPara = ME_FindItemBack(pRun, diParagraph);
|
||||
int y, yrel, yheight, yold;
|
||||
HWND hWnd = editor->hWnd;
|
||||
|
||||
assert(pRow);
|
||||
assert(pPara);
|
||||
|
@ -473,24 +508,11 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
|
|||
yheight = pRow->member.row.nHeight;
|
||||
yold = ME_GetYScrollPos(editor);
|
||||
yrel = y - yold;
|
||||
if (yrel < 0) {
|
||||
editor->nScrollPosY = y;
|
||||
SetScrollPos(hWnd, SB_VERT, y, TRUE);
|
||||
if (editor->bRedraw)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (y < yold)
|
||||
ME_ScrollAbs(editor,y);
|
||||
else if (yrel + yheight > editor->sizeWindow.cy)
|
||||
ME_ScrollAbs(editor,y+yheight-editor->sizeWindow.cy);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue