richedit: Implemented the horizontal scrollbar.
This commit is contained in:
parent
01ee55a8f6
commit
e6fedf879c
|
@ -214,9 +214,9 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
|
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
|
||||||
*x = c.rcView.left + run->member.run.pt.x + sz.cx;
|
*x = c.rcView.left + run->member.run.pt.x + sz.cx - editor->horz_si.nPos;
|
||||||
*y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
|
*y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline
|
||||||
+ run->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
|
+ run->member.run.pt.y - pSizeRun->member.run.nAscent - editor->vert_si.nPos;
|
||||||
ME_DestroyContext(&c, editor->hWnd);
|
ME_DestroyContext(&c, editor->hWnd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1025,8 @@ int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact)
|
||||||
if (isExact) *isExact = FALSE;
|
if (isExact) *isExact = FALSE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
y += ME_GetYScrollPos(editor);
|
x += editor->horz_si.nPos;
|
||||||
|
y += editor->vert_si.nPos;
|
||||||
bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL);
|
bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL);
|
||||||
if (isExact) *isExact = bResult;
|
if (isExact) *isExact = bResult;
|
||||||
return (ME_GetParagraph(cursor.pRun)->member.para.nCharOfs
|
return (ME_GetParagraph(cursor.pRun)->member.para.nCharOfs
|
||||||
|
@ -1102,7 +1103,8 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
|
||||||
|
|
||||||
editor->nUDArrowX = -1;
|
editor->nUDArrowX = -1;
|
||||||
|
|
||||||
y += ME_GetYScrollPos(editor);
|
x += editor->horz_si.nPos;
|
||||||
|
y += editor->vert_si.nPos;
|
||||||
|
|
||||||
tmp_cursor = editor->pCursors[0];
|
tmp_cursor = editor->pCursors[0];
|
||||||
is_selection = ME_IsSelection(editor);
|
is_selection = ME_IsSelection(editor);
|
||||||
|
@ -1164,7 +1166,8 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
|
||||||
|
|
||||||
if (editor->nSelectionType == stDocument)
|
if (editor->nSelectionType == stDocument)
|
||||||
return;
|
return;
|
||||||
y += ME_GetYScrollPos(editor);
|
x += editor->horz_si.nPos;
|
||||||
|
y += editor->vert_si.nPos;
|
||||||
|
|
||||||
tmp_cursor = editor->pCursors[0];
|
tmp_cursor = editor->pCursors[0];
|
||||||
/* FIXME: do something with the return value of ME_FindPixelPos */
|
/* FIXME: do something with the return value of ME_FindPixelPos */
|
||||||
|
@ -1179,9 +1182,9 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
|
||||||
{
|
{
|
||||||
/* The scroll the cursor towards the other end, since it was the one
|
/* The scroll the cursor towards the other end, since it was the one
|
||||||
* extended by ME_ExtendAnchorSelection */
|
* extended by ME_ExtendAnchorSelection */
|
||||||
ME_EnsureVisible(editor, editor->pCursors[1].pRun);
|
ME_EnsureVisible(editor, &editor->pCursors[1]);
|
||||||
} else {
|
} else {
|
||||||
ME_EnsureVisible(editor, editor->pCursors[0].pRun);
|
ME_EnsureVisible(editor, &editor->pCursors[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ME_InvalidateSelection(editor);
|
ME_InvalidateSelection(editor);
|
||||||
|
@ -1400,7 +1403,8 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
|
||||||
ME_UpdateSelection(editor, &tmp_curs);
|
ME_UpdateSelection(editor, &tmp_curs);
|
||||||
if (yprev < editor->sizeWindow.cy)
|
if (yprev < editor->sizeWindow.cy)
|
||||||
{
|
{
|
||||||
ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun));
|
ME_Cursor startCursor = {ME_FindItemFwd(editor->pBuffer->pFirst, diRun), 0};
|
||||||
|
ME_EnsureVisible(editor, &startCursor);
|
||||||
ME_Repaint(editor);
|
ME_Repaint(editor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1453,7 +1457,8 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
|
||||||
ME_UpdateSelection(editor, &tmp_curs);
|
ME_UpdateSelection(editor, &tmp_curs);
|
||||||
if (yprev >= editor->nTotalLength-editor->sizeWindow.cy)
|
if (yprev >= editor->nTotalLength-editor->sizeWindow.cy)
|
||||||
{
|
{
|
||||||
ME_EnsureVisible(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun));
|
ME_Cursor endCursor = {ME_FindItemBack(editor->pBuffer->pLast, diRun), 0};
|
||||||
|
ME_EnsureVisible(editor, &endCursor);
|
||||||
ME_Repaint(editor);
|
ME_Repaint(editor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1645,7 +1650,7 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
|
||||||
ME_InvalidateSelection(editor);
|
ME_InvalidateSelection(editor);
|
||||||
ME_Repaint(editor);
|
ME_Repaint(editor);
|
||||||
HideCaret(editor->hWnd);
|
HideCaret(editor->hWnd);
|
||||||
ME_EnsureVisible(editor, tmp_curs.pRun);
|
ME_EnsureVisible(editor, &tmp_curs);
|
||||||
ME_ShowCaret(editor);
|
ME_ShowCaret(editor);
|
||||||
ME_SendSelChange(editor);
|
ME_SendSelChange(editor);
|
||||||
return success;
|
return success;
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
- EM_GETREDONAME 2.0
|
- EM_GETREDONAME 2.0
|
||||||
+ EM_GETSEL
|
+ EM_GETSEL
|
||||||
+ EM_GETSELTEXT (ANSI&Unicode)
|
+ EM_GETSELTEXT (ANSI&Unicode)
|
||||||
+ EM_GETSCROLLPOS 3.0 (only Y value valid)
|
+ EM_GETSCROLLPOS 3.0
|
||||||
! - EM_GETTHUMB
|
! - EM_GETTHUMB
|
||||||
+ EM_GETTEXTEX 2.0
|
+ EM_GETTEXTEX 2.0
|
||||||
+ EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
|
+ EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
|
||||||
|
@ -137,12 +137,14 @@
|
||||||
+ WM_GETDLGCODE (the current implementation is incomplete)
|
+ WM_GETDLGCODE (the current implementation is incomplete)
|
||||||
+ WM_GETTEXT (ANSI&Unicode)
|
+ WM_GETTEXT (ANSI&Unicode)
|
||||||
+ WM_GETTEXTLENGTH (ANSI version sucks)
|
+ WM_GETTEXTLENGTH (ANSI version sucks)
|
||||||
|
+ WM_HSCROLL
|
||||||
+ WM_PASTE
|
+ WM_PASTE
|
||||||
+ WM_SETFONT
|
+ WM_SETFONT
|
||||||
+ WM_SETTEXT (resets undo stack !) (proper style?) ANSI&Unicode
|
+ WM_SETTEXT (resets undo stack !) (proper style?) ANSI&Unicode
|
||||||
- WM_STYLECHANGING
|
- WM_STYLECHANGING
|
||||||
- WM_STYLECHANGED (things like read-only flag)
|
- WM_STYLECHANGED (things like read-only flag)
|
||||||
+ WM_UNICHAR
|
+ WM_UNICHAR
|
||||||
|
+ WM_VSCROLL
|
||||||
|
|
||||||
Notifications
|
Notifications
|
||||||
|
|
||||||
|
@ -184,7 +186,7 @@
|
||||||
- ES_VERTICAL
|
- ES_VERTICAL
|
||||||
- ES_WANTRETURN (don't know how to do WM_GETDLGCODE part)
|
- ES_WANTRETURN (don't know how to do WM_GETDLGCODE part)
|
||||||
- WS_SETFONT
|
- WS_SETFONT
|
||||||
- WS_HSCROLL
|
+ WS_HSCROLL
|
||||||
+ WS_VSCROLL
|
+ WS_VSCROLL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -197,7 +199,6 @@
|
||||||
* - pictures/OLE objects (not just smiling faces that lack API support ;-) )
|
* - pictures/OLE objects (not just smiling faces that lack API support ;-) )
|
||||||
* - COM interface (looks like a major pain in the TODO list)
|
* - COM interface (looks like a major pain in the TODO list)
|
||||||
* - calculate heights of pictures (half-done)
|
* - calculate heights of pictures (half-done)
|
||||||
* - horizontal scrolling (not even started)
|
|
||||||
* - hysteresis during wrapping (related to scrollbars appearing/disappearing)
|
* - hysteresis during wrapping (related to scrollbars appearing/disappearing)
|
||||||
* - find/replace
|
* - find/replace
|
||||||
* - how to implement EM_FORMATRANGE and EM_DISPLAYBAND ? (Mission Impossible)
|
* - how to implement EM_FORMATRANGE and EM_DISPLAYBAND ? (Mission Impossible)
|
||||||
|
@ -2681,6 +2682,7 @@ static ME_TextEditor *ME_MakeEditor(HWND hWnd, BOOL bEmulateVersion10)
|
||||||
ed->pCursors[2] = ed->pCursors[0];
|
ed->pCursors[2] = ed->pCursors[0];
|
||||||
ed->pCursors[3] = ed->pCursors[1];
|
ed->pCursors[3] = ed->pCursors[1];
|
||||||
ed->nLastTotalLength = ed->nTotalLength = 0;
|
ed->nLastTotalLength = ed->nTotalLength = 0;
|
||||||
|
ed->nLastTotalWidth = ed->nTotalWidth = 0;
|
||||||
ed->nUDArrowX = -1;
|
ed->nUDArrowX = -1;
|
||||||
ed->nSequence = 0;
|
ed->nSequence = 0;
|
||||||
ed->rgbBackColor = -1;
|
ed->rgbBackColor = -1;
|
||||||
|
@ -2730,13 +2732,19 @@ static ME_TextEditor *ME_MakeEditor(HWND hWnd, BOOL bEmulateVersion10)
|
||||||
|
|
||||||
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
|
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
|
||||||
|
|
||||||
/* Default vertical scrollbar information */
|
/* Default scrollbar information */
|
||||||
ed->vert_si.cbSize = sizeof(SCROLLINFO);
|
ed->vert_si.cbSize = sizeof(SCROLLINFO);
|
||||||
ed->vert_si.nMin = 0;
|
ed->vert_si.nMin = 0;
|
||||||
ed->vert_si.nMax = 0;
|
ed->vert_si.nMax = 0;
|
||||||
ed->vert_si.nPage = 0;
|
ed->vert_si.nPage = 0;
|
||||||
ed->vert_si.nPos = 0;
|
ed->vert_si.nPos = 0;
|
||||||
|
|
||||||
|
ed->horz_si.cbSize = sizeof(SCROLLINFO);
|
||||||
|
ed->horz_si.nMin = 0;
|
||||||
|
ed->horz_si.nMax = 0;
|
||||||
|
ed->horz_si.nPage = 0;
|
||||||
|
ed->horz_si.nPos = 0;
|
||||||
|
|
||||||
OleInitialize(NULL);
|
OleInitialize(NULL);
|
||||||
|
|
||||||
return ed;
|
return ed;
|
||||||
|
@ -3156,7 +3164,7 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
case EM_SETSCROLLPOS:
|
case EM_SETSCROLLPOS:
|
||||||
{
|
{
|
||||||
POINT *point = (POINT *)lParam;
|
POINT *point = (POINT *)lParam;
|
||||||
ME_ScrollAbs(editor, point->y);
|
ME_ScrollAbs(editor, point->x, point->y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case EM_AUTOURLDETECT:
|
case EM_AUTOURLDETECT:
|
||||||
|
@ -3363,7 +3371,7 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
case EM_GETFIRSTVISIBLELINE:
|
case EM_GETFIRSTVISIBLELINE:
|
||||||
{
|
{
|
||||||
ME_DisplayItem *p = editor->pBuffer->pFirst;
|
ME_DisplayItem *p = editor->pBuffer->pFirst;
|
||||||
int y = ME_GetYScrollPos(editor);
|
int y = editor->vert_si.nPos;
|
||||||
int ypara = 0;
|
int ypara = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int ystart, yend;
|
int ystart, yend;
|
||||||
|
@ -3433,7 +3441,7 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
case EM_SCROLLCARET:
|
case EM_SCROLLCARET:
|
||||||
ME_EnsureVisible(editor, editor->pCursors[0].pRun);
|
ME_EnsureVisible(editor, &editor->pCursors[0]);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_SETFONT:
|
case WM_SETFONT:
|
||||||
{
|
{
|
||||||
|
@ -3588,8 +3596,8 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
case EM_GETSCROLLPOS:
|
case EM_GETSCROLLPOS:
|
||||||
{
|
{
|
||||||
POINT *point = (POINT *)lParam;
|
POINT *point = (POINT *)lParam;
|
||||||
point->x = 0; /* FIXME side scrolling not implemented */
|
point->x = editor->horz_si.nPos;
|
||||||
point->y = ME_GetYScrollPos(editor);
|
point->y = editor->vert_si.nPos;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case EM_GETTEXTRANGE:
|
case EM_GETTEXTRANGE:
|
||||||
|
@ -3837,7 +3845,6 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
ME_DisplayItem *pRun;
|
ME_DisplayItem *pRun;
|
||||||
int nCharOfs, nOffset, nLength;
|
int nCharOfs, nOffset, nLength;
|
||||||
POINTL pt = {0,0};
|
POINTL pt = {0,0};
|
||||||
SCROLLINFO si;
|
|
||||||
|
|
||||||
nCharOfs = wParam;
|
nCharOfs = wParam;
|
||||||
/* detect which API version we're dealing with */
|
/* detect which API version we're dealing with */
|
||||||
|
@ -3854,10 +3861,8 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top;
|
pt.y += ME_GetParagraph(pRun)->member.para.pt.y + editor->rcFormat.top;
|
||||||
pt.x += editor->rcFormat.left;
|
pt.x += editor->rcFormat.left;
|
||||||
|
|
||||||
|
pt.x -= editor->horz_si.nPos;
|
||||||
pt.y -= editor->vert_si.nPos;
|
pt.y -= editor->vert_si.nPos;
|
||||||
si.cbSize = sizeof(si);
|
|
||||||
si.fMask = SIF_POS;
|
|
||||||
if (GetScrollInfo(editor->hWnd, SB_HORZ, &si)) pt.x -= si.nPos;
|
|
||||||
|
|
||||||
if (wParam >= 0x40000) {
|
if (wParam >= 0x40000) {
|
||||||
*(POINTL *)wParam = pt;
|
*(POINTL *)wParam = pt;
|
||||||
|
@ -3869,10 +3874,6 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
SCROLLINFO si;
|
SCROLLINFO si;
|
||||||
|
|
||||||
ME_SetDefaultFormatRect(editor);
|
ME_SetDefaultFormatRect(editor);
|
||||||
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & WS_HSCROLL)
|
|
||||||
{ /* Squelch the default horizontal scrollbar it would make */
|
|
||||||
ShowScrollBar(editor->hWnd, SB_HORZ, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
si.cbSize = sizeof(si);
|
si.cbSize = sizeof(si);
|
||||||
si.fMask = SIF_PAGE | SIF_RANGE;
|
si.fMask = SIF_PAGE | SIF_RANGE;
|
||||||
|
@ -3882,6 +3883,7 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
si.nMin = 0;
|
si.nMin = 0;
|
||||||
si.nPage = 0;
|
si.nPage = 0;
|
||||||
SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
|
SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
|
||||||
|
SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
|
||||||
|
|
||||||
ME_CommitUndo(editor);
|
ME_CommitUndo(editor);
|
||||||
ME_WrapMarkedParagraphs(editor);
|
ME_WrapMarkedParagraphs(editor);
|
||||||
|
@ -4046,13 +4048,56 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
case EM_STOPGROUPTYPING:
|
case EM_STOPGROUPTYPING:
|
||||||
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
|
||||||
return 0;
|
return 0;
|
||||||
|
case WM_HSCROLL:
|
||||||
|
{
|
||||||
|
const int scrollUnit = 7;
|
||||||
|
|
||||||
|
switch(LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case SB_LEFT:
|
||||||
|
ME_ScrollAbs(editor, 0, 0);
|
||||||
|
break;
|
||||||
|
case SB_RIGHT:
|
||||||
|
ME_ScrollAbs(editor,
|
||||||
|
editor->horz_si.nMax - (int)editor->horz_si.nPage,
|
||||||
|
editor->vert_si.nMax - (int)editor->vert_si.nPage);
|
||||||
|
break;
|
||||||
|
case SB_LINELEFT:
|
||||||
|
ME_ScrollLeft(editor, scrollUnit);
|
||||||
|
break;
|
||||||
|
case SB_LINERIGHT:
|
||||||
|
ME_ScrollRight(editor, scrollUnit);
|
||||||
|
break;
|
||||||
|
case SB_PAGELEFT:
|
||||||
|
ME_ScrollLeft(editor, editor->sizeWindow.cx);
|
||||||
|
break;
|
||||||
|
case SB_PAGERIGHT:
|
||||||
|
ME_ScrollRight(editor, editor->sizeWindow.cx);
|
||||||
|
break;
|
||||||
|
case SB_THUMBTRACK:
|
||||||
|
case SB_THUMBPOSITION:
|
||||||
|
{
|
||||||
|
SCROLLINFO sbi;
|
||||||
|
sbi.cbSize = sizeof(sbi);
|
||||||
|
sbi.fMask = SIF_TRACKPOS;
|
||||||
|
/* Try to get 32-bit track position value. */
|
||||||
|
if (!GetScrollInfo(editor->hWnd, SB_HORZ, &sbi))
|
||||||
|
/* GetScrollInfo failed, settle for 16-bit value in wParam. */
|
||||||
|
sbi.nTrackPos = HIWORD(wParam);
|
||||||
|
|
||||||
|
ME_HScrollAbs(editor, sbi.nTrackPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EM_SCROLL: /* fall through */
|
case EM_SCROLL: /* fall through */
|
||||||
case WM_VSCROLL:
|
case WM_VSCROLL:
|
||||||
{
|
{
|
||||||
int origNPos;
|
int origNPos;
|
||||||
int lineHeight;
|
int lineHeight;
|
||||||
|
|
||||||
origNPos = ME_GetYScrollPos(editor);
|
origNPos = editor->vert_si.nPos;
|
||||||
lineHeight = 24;
|
lineHeight = 24;
|
||||||
|
|
||||||
if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle)
|
if (editor && editor->pBuffer && editor->pBuffer->pDefaultStyle)
|
||||||
|
@ -4061,6 +4106,14 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
|
|
||||||
switch(LOWORD(wParam))
|
switch(LOWORD(wParam))
|
||||||
{
|
{
|
||||||
|
case SB_TOP:
|
||||||
|
ME_ScrollAbs(editor, 0, 0);
|
||||||
|
break;
|
||||||
|
case SB_BOTTOM:
|
||||||
|
ME_ScrollAbs(editor,
|
||||||
|
editor->horz_si.nMax - (int)editor->horz_si.nPage,
|
||||||
|
editor->vert_si.nMax - (int)editor->vert_si.nPage);
|
||||||
|
break;
|
||||||
case SB_LINEUP:
|
case SB_LINEUP:
|
||||||
ME_ScrollUp(editor,lineHeight);
|
ME_ScrollUp(editor,lineHeight);
|
||||||
break;
|
break;
|
||||||
|
@ -4084,12 +4137,12 @@ static LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
|
||||||
/* GetScrollInfo failed, settle for 16-bit value in wParam. */
|
/* GetScrollInfo failed, settle for 16-bit value in wParam. */
|
||||||
sbi.nTrackPos = HIWORD(wParam);
|
sbi.nTrackPos = HIWORD(wParam);
|
||||||
|
|
||||||
ME_ScrollAbs(editor, sbi.nTrackPos);
|
ME_VScrollAbs(editor, sbi.nTrackPos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg == EM_SCROLL)
|
if (msg == EM_SCROLL)
|
||||||
return 0x00010000 | (((ME_GetYScrollPos(editor) - origNPos)/lineHeight) & 0xffff);
|
return 0x00010000 | (((editor->vert_si.nPos - origNPos)/lineHeight) & 0xffff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
|
|
|
@ -233,7 +233,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
||||||
void ME_Repaint(ME_TextEditor *editor);
|
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_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
|
void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor);
|
||||||
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);
|
||||||
|
@ -242,11 +242,14 @@ int ME_twips2pointsY(ME_Context *c, int y);
|
||||||
|
|
||||||
/* scroll functions in paint.c */
|
/* scroll functions in paint.c */
|
||||||
|
|
||||||
void ME_ScrollAbs(ME_TextEditor *editor, int absY);
|
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y);
|
||||||
|
void ME_HScrollAbs(ME_TextEditor *editor, int x);
|
||||||
|
void ME_VScrollAbs(ME_TextEditor *editor, int y);
|
||||||
void ME_ScrollUp(ME_TextEditor *editor, int cy);
|
void ME_ScrollUp(ME_TextEditor *editor, int cy);
|
||||||
void ME_ScrollDown(ME_TextEditor *editor, int cy);
|
void ME_ScrollDown(ME_TextEditor *editor, int cy);
|
||||||
|
void ME_ScrollLeft(ME_TextEditor *editor, int cx);
|
||||||
|
void ME_ScrollRight(ME_TextEditor *editor, int cx);
|
||||||
void ME_UpdateScrollBar(ME_TextEditor *editor);
|
void ME_UpdateScrollBar(ME_TextEditor *editor);
|
||||||
int ME_GetYScrollPos(ME_TextEditor *editor);
|
|
||||||
|
|
||||||
/* other functions in paint.c */
|
/* other functions in paint.c */
|
||||||
int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
|
int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
|
||||||
|
|
|
@ -189,7 +189,7 @@ typedef struct tagME_Paragraph
|
||||||
int nCharOfs;
|
int nCharOfs;
|
||||||
int nFlags;
|
int nFlags;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
int nHeight;
|
int nHeight, nWidth;
|
||||||
int nLastPaintYPos, nLastPaintHeight;
|
int nLastPaintYPos, nLastPaintHeight;
|
||||||
int nRows;
|
int nRows;
|
||||||
struct tagME_DisplayItem *prev_para, *next_para, *document;
|
struct tagME_DisplayItem *prev_para, *next_para, *document;
|
||||||
|
@ -333,6 +333,7 @@ typedef struct tagME_TextEditor
|
||||||
int nCursors;
|
int nCursors;
|
||||||
SIZE sizeWindow;
|
SIZE sizeWindow;
|
||||||
int nTotalLength, nLastTotalLength;
|
int nTotalLength, nLastTotalLength;
|
||||||
|
int nTotalWidth, nLastTotalWidth;
|
||||||
int nUDArrowX;
|
int nUDArrowX;
|
||||||
int nSequence;
|
int nSequence;
|
||||||
COLORREF rgbBackColor;
|
COLORREF rgbBackColor;
|
||||||
|
@ -374,8 +375,8 @@ typedef struct tagME_TextEditor
|
||||||
/* Track previous notified selection */
|
/* Track previous notified selection */
|
||||||
CHARRANGE notified_cr;
|
CHARRANGE notified_cr;
|
||||||
|
|
||||||
/* Cache previously set vertical scrollbar info */
|
/* Cache previously set scrollbar info */
|
||||||
SCROLLINFO vert_si;
|
SCROLLINFO vert_si, horz_si;
|
||||||
|
|
||||||
BOOL bMouseCaptured;
|
BOOL bMouseCaptured;
|
||||||
} ME_TextEditor;
|
} ME_TextEditor;
|
||||||
|
|
|
@ -29,7 +29,6 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
||||||
{
|
{
|
||||||
ME_DisplayItem *item;
|
ME_DisplayItem *item;
|
||||||
ME_Context c;
|
ME_Context c;
|
||||||
int yoffset;
|
|
||||||
int ys, ye;
|
int ys, ye;
|
||||||
HRGN oldRgn;
|
HRGN oldRgn;
|
||||||
|
|
||||||
|
@ -43,15 +42,14 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
||||||
rcUpdate->right, rcUpdate->bottom);
|
rcUpdate->right, rcUpdate->bottom);
|
||||||
|
|
||||||
editor->nSequence++;
|
editor->nSequence++;
|
||||||
yoffset = ME_GetYScrollPos(editor);
|
|
||||||
ME_InitContext(&c, editor, hDC);
|
ME_InitContext(&c, editor, hDC);
|
||||||
SetBkMode(hDC, TRANSPARENT);
|
SetBkMode(hDC, TRANSPARENT);
|
||||||
ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */
|
ME_MoveCaret(editor); /* Calls ME_WrapMarkedParagraphs */
|
||||||
item = editor->pBuffer->pFirst->next;
|
item = editor->pBuffer->pFirst->next;
|
||||||
/* This context point is an offset for the paragraph positions stored
|
/* This context point is an offset for the paragraph positions stored
|
||||||
* during wrapping. It shouldn't be modified during painting. */
|
* during wrapping. It shouldn't be modified during painting. */
|
||||||
c.pt.x = c.rcView.left;
|
c.pt.x = c.rcView.left - editor->horz_si.nPos;
|
||||||
c.pt.y = c.rcView.top - yoffset;
|
c.pt.y = c.rcView.top - editor->vert_si.nPos;
|
||||||
while(item != editor->pBuffer->pLast)
|
while(item != editor->pBuffer->pLast)
|
||||||
{
|
{
|
||||||
assert(item->type == diParagraph);
|
assert(item->type == diParagraph);
|
||||||
|
@ -113,9 +111,11 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
||||||
if (!IsRectEmpty(&rc))
|
if (!IsRectEmpty(&rc))
|
||||||
FillRect(hDC, &rc, c.editor->hbrBackground);
|
FillRect(hDC, &rc, c.editor->hbrBackground);
|
||||||
}
|
}
|
||||||
if (editor->nTotalLength != editor->nLastTotalLength)
|
if (editor->nTotalLength != editor->nLastTotalLength ||
|
||||||
|
editor->nTotalWidth != editor->nLastTotalWidth)
|
||||||
ME_SendRequestResize(editor, FALSE);
|
ME_SendRequestResize(editor, FALSE);
|
||||||
editor->nLastTotalLength = editor->nTotalLength;
|
editor->nLastTotalLength = editor->nTotalLength;
|
||||||
|
editor->nLastTotalWidth = editor->nTotalWidth;
|
||||||
ME_DestroyContext(&c, NULL);
|
ME_DestroyContext(&c, NULL);
|
||||||
|
|
||||||
SelectClipRgn(hDC, oldRgn);
|
SelectClipRgn(hDC, oldRgn);
|
||||||
|
@ -149,7 +149,7 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
|
||||||
|
|
||||||
/* Ensure that the cursor is visible */
|
/* Ensure that the cursor is visible */
|
||||||
pCursor = &editor->pCursors[0];
|
pCursor = &editor->pCursors[0];
|
||||||
ME_EnsureVisible(editor, pCursor->pRun);
|
ME_EnsureVisible(editor, pCursor);
|
||||||
|
|
||||||
/* send EN_CHANGE if the event mask asks for it */
|
/* send EN_CHANGE if the event mask asks for it */
|
||||||
if(editor->nEventMask & ENM_CHANGE)
|
if(editor->nEventMask & ENM_CHANGE)
|
||||||
|
@ -619,7 +619,7 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT
|
||||||
/* Native richedit doesn't support paragraph borders in v1.0 - 4.1,
|
/* Native richedit doesn't support paragraph borders in v1.0 - 4.1,
|
||||||
* but might support it in later versions. */
|
* but might support it in later versions. */
|
||||||
if (hasParaBorder) {
|
if (hasParaBorder) {
|
||||||
int pen_width;
|
int pen_width, rightEdge;
|
||||||
COLORREF pencr;
|
COLORREF pencr;
|
||||||
HPEN pen = NULL, oldpen = NULL;
|
HPEN pen = NULL, oldpen = NULL;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
|
@ -629,6 +629,9 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT
|
||||||
else
|
else
|
||||||
pencr = pen_colors[(para->pFmt->wBorders >> 12) & 0xF];
|
pencr = pen_colors[(para->pFmt->wBorders >> 12) & 0xF];
|
||||||
|
|
||||||
|
rightEdge = c->pt.x + max(c->editor->sizeWindow.cx,
|
||||||
|
c->editor->nTotalWidth);
|
||||||
|
|
||||||
pen_width = ME_GetBorderPenWidth(c->editor, idx);
|
pen_width = ME_GetBorderPenWidth(c->editor, idx);
|
||||||
pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
|
pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
|
||||||
oldpen = SelectObject(c->hDC, pen);
|
oldpen = SelectObject(c->hDC, pen);
|
||||||
|
@ -641,51 +644,51 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT
|
||||||
|
|
||||||
if (para->pFmt->wBorders & 1)
|
if (para->pFmt->wBorders & 1)
|
||||||
{
|
{
|
||||||
MoveToEx(c->hDC, c->rcView.left, y + bounds->top, NULL);
|
MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
|
||||||
LineTo(c->hDC, c->rcView.left, y + para->nHeight - bounds->bottom);
|
LineTo(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom);
|
||||||
if (border_details[idx].dble) {
|
if (border_details[idx].dble) {
|
||||||
rc.left = c->rcView.left + 1;
|
rc.left = c->pt.x + 1;
|
||||||
rc.right = rc.left + border_width;
|
rc.right = rc.left + border_width;
|
||||||
rc.top = y + bounds->top;
|
rc.top = y + bounds->top;
|
||||||
rc.bottom = y + para->nHeight - bounds->bottom;
|
rc.bottom = y + para->nHeight - bounds->bottom;
|
||||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||||
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + bounds->top + DD(4), NULL);
|
MoveToEx(c->hDC, c->pt.x + pen_width + 1, y + bounds->top + DD(4), NULL);
|
||||||
LineTo(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - bounds->bottom - DD(8));
|
LineTo(c->hDC, c->pt.x + pen_width + 1, y + para->nHeight - bounds->bottom - DD(8));
|
||||||
}
|
}
|
||||||
bounds->left += border_width;
|
bounds->left += border_width;
|
||||||
}
|
}
|
||||||
if (para->pFmt->wBorders & 2)
|
if (para->pFmt->wBorders & 2)
|
||||||
{
|
{
|
||||||
MoveToEx(c->hDC, c->rcView.right - 1, y + bounds->top, NULL);
|
MoveToEx(c->hDC, rightEdge - 1, y + bounds->top, NULL);
|
||||||
LineTo(c->hDC, c->rcView.right - 1, y + para->nHeight - bounds->bottom);
|
LineTo(c->hDC, rightEdge - 1, y + para->nHeight - bounds->bottom);
|
||||||
if (border_details[idx].dble) {
|
if (border_details[idx].dble) {
|
||||||
rc.left = c->rcView.right - pen_width - 1;
|
rc.left = rightEdge - pen_width - 1;
|
||||||
rc.right = c->rcView.right - 1;
|
rc.right = rc.left + pen_width;
|
||||||
rc.top = y + bounds->top;
|
rc.top = y + bounds->top;
|
||||||
rc.bottom = y + para->nHeight - bounds->bottom;
|
rc.bottom = y + para->nHeight - bounds->bottom;
|
||||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||||
MoveToEx(c->hDC, c->rcView.right - 1 - pen_width - 1, y + bounds->top + DD(4), NULL);
|
MoveToEx(c->hDC, rightEdge - 1 - pen_width - 1, y + bounds->top + DD(4), NULL);
|
||||||
LineTo(c->hDC, c->rcView.right - 1 - pen_width - 1, y + para->nHeight - bounds->bottom - DD(8));
|
LineTo(c->hDC, rightEdge - 1 - pen_width - 1, y + para->nHeight - bounds->bottom - DD(8));
|
||||||
}
|
}
|
||||||
bounds->right += border_width;
|
bounds->right += border_width;
|
||||||
}
|
}
|
||||||
if (para->pFmt->wBorders & 4)
|
if (para->pFmt->wBorders & 4)
|
||||||
{
|
{
|
||||||
MoveToEx(c->hDC, c->rcView.left, y + bounds->top, NULL);
|
MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
|
||||||
LineTo(c->hDC, c->rcView.right, y + bounds->top);
|
LineTo(c->hDC, rightEdge, y + bounds->top);
|
||||||
if (border_details[idx].dble) {
|
if (border_details[idx].dble) {
|
||||||
MoveToEx(c->hDC, c->rcView.left + DD(1), y + bounds->top + pen_width + 1, NULL);
|
MoveToEx(c->hDC, c->pt.x + DD(1), y + bounds->top + pen_width + 1, NULL);
|
||||||
LineTo(c->hDC, c->rcView.right - DD(2), y + bounds->top + pen_width + 1);
|
LineTo(c->hDC, rightEdge - DD(2), y + bounds->top + pen_width + 1);
|
||||||
}
|
}
|
||||||
bounds->top += border_width;
|
bounds->top += border_width;
|
||||||
}
|
}
|
||||||
if (para->pFmt->wBorders & 8)
|
if (para->pFmt->wBorders & 8)
|
||||||
{
|
{
|
||||||
MoveToEx(c->hDC, c->rcView.left, y + para->nHeight - bounds->bottom - 1, NULL);
|
MoveToEx(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom - 1, NULL);
|
||||||
LineTo(c->hDC, c->rcView.right, y + para->nHeight - bounds->bottom - 1);
|
LineTo(c->hDC, rightEdge, y + para->nHeight - bounds->bottom - 1);
|
||||||
if (border_details[idx].dble) {
|
if (border_details[idx].dble) {
|
||||||
MoveToEx(c->hDC, c->rcView.left + DD(1), y + para->nHeight - bounds->bottom - 1 - pen_width - 1, NULL);
|
MoveToEx(c->hDC, c->pt.x + DD(1), y + para->nHeight - bounds->bottom - 1 - pen_width - 1, NULL);
|
||||||
LineTo(c->hDC, c->rcView.right - DD(2), y + para->nHeight - bounds->bottom - 1 - pen_width - 1);
|
LineTo(c->hDC, rightEdge - DD(2), y + para->nHeight - bounds->bottom - 1 - pen_width - 1);
|
||||||
}
|
}
|
||||||
bounds->bottom += border_width;
|
bounds->bottom += border_width;
|
||||||
}
|
}
|
||||||
|
@ -926,8 +929,12 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
|
||||||
}
|
}
|
||||||
ME_DrawParaDecoration(c, para, y, &bounds);
|
ME_DrawParaDecoration(c, para, y, &bounds);
|
||||||
y += bounds.top;
|
y += bounds.top;
|
||||||
rc.left += bounds.left;
|
if (bounds.left || bounds.right) {
|
||||||
rc.right -= bounds.right;
|
rc.left = max(rc.left, c->pt.x + bounds.left);
|
||||||
|
rc.right = min(rc.right, c->pt.x - bounds.right
|
||||||
|
+ max(c->editor->sizeWindow.cx,
|
||||||
|
c->editor->nTotalWidth));
|
||||||
|
}
|
||||||
|
|
||||||
for (p = paragraph->next; p != para->next_para; p = p->next)
|
for (p = paragraph->next; p != para->next_para; p = p->next)
|
||||||
{
|
{
|
||||||
|
@ -947,6 +954,16 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
|
||||||
if (visible) {
|
if (visible) {
|
||||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||||
}
|
}
|
||||||
|
if (bounds.right)
|
||||||
|
{
|
||||||
|
/* If scrolled to the right past the end of the text, then
|
||||||
|
* there may be space to the right of the paragraph border. */
|
||||||
|
RECT rcAfterBrdr = rc;
|
||||||
|
rcAfterBrdr.left = rc.right + bounds.right;
|
||||||
|
rcAfterBrdr.right = c->rcView.right;
|
||||||
|
if (RectVisible(c->hDC, &rcAfterBrdr))
|
||||||
|
FillRect(c->hDC, &rcAfterBrdr, c->editor->hbrBackground);
|
||||||
|
}
|
||||||
if (me_debug)
|
if (me_debug)
|
||||||
{
|
{
|
||||||
const WCHAR wszRowDebug[] = {'r','o','w','[','%','d',']',0};
|
const WCHAR wszRowDebug[] = {'r','o','w','[','%','d',']',0};
|
||||||
|
@ -1013,157 +1030,192 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
|
||||||
SetTextAlign(c->hDC, align);
|
SetTextAlign(c->hDC, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ME_Scroll(ME_TextEditor *editor, int value, int type)
|
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
|
||||||
{
|
{
|
||||||
SCROLLINFO si;
|
|
||||||
int nOrigPos, nNewPos, nActualScroll;
|
|
||||||
HWND hWnd;
|
|
||||||
LONG winStyle;
|
LONG winStyle;
|
||||||
BOOL bScrollBarIsVisible, bScrollBarWillBeVisible;
|
BOOL bScrollBarIsVisible, bScrollBarWillBeVisible;
|
||||||
|
int scrollX = 0, scrollY = 0;
|
||||||
|
|
||||||
nOrigPos = ME_GetYScrollPos(editor);
|
if (editor->horz_si.nPos != x) {
|
||||||
|
x = min(x, editor->horz_si.nMax);
|
||||||
si.cbSize = sizeof(SCROLLINFO);
|
x = max(x, editor->horz_si.nMin);
|
||||||
si.fMask = SIF_POS;
|
SetScrollPos(editor->hWnd, SB_HORZ, x, TRUE);
|
||||||
|
scrollX = editor->horz_si.nPos - x;
|
||||||
switch (type)
|
editor->horz_si.nPos = x;
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
/*Scroll absolutely*/
|
|
||||||
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, TRUE);
|
if (editor->vert_si.nPos != y) {
|
||||||
editor->vert_si.nPos = nNewPos;
|
y = min(y, editor->vert_si.nMax - (int)editor->vert_si.nPage);
|
||||||
nActualScroll = nOrigPos - nNewPos;
|
y = max(y, editor->vert_si.nMin);
|
||||||
if (abs(nActualScroll) > editor->sizeWindow.cy)
|
SetScrollPos(editor->hWnd, SB_VERT, y, TRUE);
|
||||||
|
scrollY = editor->vert_si.nPos - y;
|
||||||
|
editor->vert_si.nPos = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(scrollX) > editor->sizeWindow.cx ||
|
||||||
|
abs(scrollY) > editor->sizeWindow.cy)
|
||||||
InvalidateRect(editor->hWnd, NULL, TRUE);
|
InvalidateRect(editor->hWnd, NULL, TRUE);
|
||||||
else
|
else
|
||||||
ScrollWindowEx(editor->hWnd, 0, nActualScroll, &editor->rcFormat,
|
ScrollWindowEx(editor->hWnd, scrollX, scrollY, &editor->rcFormat,
|
||||||
&editor->rcFormat, NULL, NULL, SW_INVALIDATE);
|
&editor->rcFormat, NULL, NULL, SW_INVALIDATE);
|
||||||
ME_Repaint(editor);
|
ME_Repaint(editor);
|
||||||
|
|
||||||
hWnd = editor->hWnd;
|
winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
|
||||||
winStyle = GetWindowLongW(hWnd, GWL_STYLE);
|
bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
|
||||||
|
bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx)
|
||||||
|
|| (winStyle & ES_DISABLENOSCROLL);
|
||||||
|
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
|
||||||
|
ShowScrollBar(editor->hWnd, SB_HORZ, bScrollBarWillBeVisible);
|
||||||
|
|
||||||
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
|
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
|
||||||
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
|
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy)
|
||||||
|| (winStyle & ES_DISABLENOSCROLL);
|
|| (winStyle & ES_DISABLENOSCROLL);
|
||||||
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
|
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
|
||||||
{
|
ShowScrollBar(editor->hWnd, SB_VERT, bScrollBarWillBeVisible);
|
||||||
ShowScrollBar(hWnd, SB_VERT, bScrollBarWillBeVisible);
|
|
||||||
}
|
|
||||||
ME_UpdateScrollBar(editor);
|
ME_UpdateScrollBar(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ME_ScrollAbs(ME_TextEditor *editor, int absY)
|
void ME_HScrollAbs(ME_TextEditor *editor, int x)
|
||||||
{
|
{
|
||||||
ME_Scroll(editor, absY, 1);
|
ME_ScrollAbs(editor, x, editor->vert_si.nPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ME_VScrollAbs(ME_TextEditor *editor, int y)
|
||||||
|
{
|
||||||
|
ME_ScrollAbs(editor, editor->horz_si.nPos, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ME_ScrollUp(ME_TextEditor *editor, int cy)
|
void ME_ScrollUp(ME_TextEditor *editor, int cy)
|
||||||
{
|
{
|
||||||
ME_Scroll(editor, cy, 2);
|
ME_VScrollAbs(editor, editor->vert_si.nPos - cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ME_ScrollDown(ME_TextEditor *editor, int cy)
|
void ME_ScrollDown(ME_TextEditor *editor, int cy)
|
||||||
{
|
{
|
||||||
ME_Scroll(editor, cy, 3);
|
ME_VScrollAbs(editor, editor->vert_si.nPos + cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL ME_GetYScrollVisible(ME_TextEditor *editor)
|
void ME_ScrollLeft(ME_TextEditor *editor, int cx)
|
||||||
{ /* Returns true if the scrollbar is visible */
|
{
|
||||||
return (editor->vert_si.nMax - editor->vert_si.nMin > editor->vert_si.nPage);
|
ME_HScrollAbs(editor, editor->horz_si.nPos - cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ME_ScrollRight(ME_TextEditor *editor, int cx)
|
||||||
|
{
|
||||||
|
ME_HScrollAbs(editor, editor->horz_si.nPos + cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ME_UpdateScrollBar(ME_TextEditor *editor)
|
void ME_UpdateScrollBar(ME_TextEditor *editor)
|
||||||
{
|
{
|
||||||
/* Note that this is the only function that should ever call SetScrolLInfo
|
/* Note that this is the only function that should ever call
|
||||||
* with SIF_PAGE or SIF_RANGE. SetScrollPos and SetScrollRange should never
|
* SetScrollInfo with SIF_PAGE or SIF_RANGE. */
|
||||||
* be used at all. */
|
|
||||||
|
|
||||||
HWND hWnd;
|
|
||||||
SCROLLINFO si;
|
SCROLLINFO si;
|
||||||
BOOL bScrollBarWasVisible,bScrollBarWillBeVisible;
|
BOOL bScrollBarWasVisible, bScrollBarWillBeVisible;
|
||||||
|
|
||||||
if (ME_WrapMarkedParagraphs(editor))
|
if (ME_WrapMarkedParagraphs(editor))
|
||||||
FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
|
FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
|
||||||
|
|
||||||
hWnd = editor->hWnd;
|
|
||||||
si.cbSize = sizeof(si);
|
si.cbSize = sizeof(si);
|
||||||
bScrollBarWasVisible = ME_GetYScrollVisible(editor);
|
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
|
||||||
bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
|
if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
|
||||||
|
si.fMask |= SIF_DISABLENOSCROLL;
|
||||||
|
|
||||||
if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
|
/* Update horizontal scrollbar */
|
||||||
|
bScrollBarWasVisible = editor->horz_si.nMax > editor->horz_si.nPage;
|
||||||
|
bScrollBarWillBeVisible = editor->nTotalWidth > editor->sizeWindow.cx;
|
||||||
|
if (editor->horz_si.nPos && !bScrollBarWillBeVisible)
|
||||||
{
|
{
|
||||||
ME_ScrollAbs(editor, 0);
|
ME_HScrollAbs(editor, 0);
|
||||||
/* ME_ScrollAbs will call this function,
|
/* ME_HScrollAbs will call this function,
|
||||||
* so nothing else needs to be done here. */
|
* so nothing else needs to be done here. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
|
si.nMin = 0;
|
||||||
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_DISABLENOSCROLL)
|
si.nMax = editor->nTotalWidth;
|
||||||
|
si.nPos = editor->horz_si.nPos;
|
||||||
|
si.nPage = editor->sizeWindow.cx;
|
||||||
|
|
||||||
|
if (si.nMin != editor->horz_si.nMin ||
|
||||||
|
si.nMax != editor->horz_si.nMax ||
|
||||||
|
si.nPage != editor->horz_si.nPage)
|
||||||
{
|
{
|
||||||
si.fMask |= SIF_DISABLENOSCROLL;
|
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
|
||||||
bScrollBarWillBeVisible = TRUE;
|
editor->horz_si.nMin = si.nMin;
|
||||||
|
editor->horz_si.nMax = si.nMax;
|
||||||
|
editor->horz_si.nPage = si.nPage;
|
||||||
|
if (bScrollBarWillBeVisible || bScrollBarWasVisible)
|
||||||
|
SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si.fMask & SIF_DISABLENOSCROLL)
|
||||||
|
bScrollBarWillBeVisible = TRUE;
|
||||||
|
|
||||||
|
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
|
||||||
|
ShowScrollBar(editor->hWnd, SB_HORZ, bScrollBarWillBeVisible);
|
||||||
|
|
||||||
|
/* Update vertical scrollbar */
|
||||||
|
bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
|
||||||
|
bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy;
|
||||||
|
|
||||||
|
if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
|
||||||
|
{
|
||||||
|
ME_VScrollAbs(editor, 0);
|
||||||
|
/* ME_VScrollAbs will call this function,
|
||||||
|
* so nothing else needs to be done here. */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
si.nMin = 0;
|
|
||||||
si.nMax = editor->nTotalLength;
|
si.nMax = editor->nTotalLength;
|
||||||
si.nPos = editor->vert_si.nPos;
|
si.nPos = editor->vert_si.nPos;
|
||||||
si.nPage = editor->sizeWindow.cy;
|
si.nPage = editor->sizeWindow.cy;
|
||||||
|
|
||||||
if (!(si.nMin == editor->vert_si.nMin &&
|
if (si.nMin != editor->vert_si.nMin ||
|
||||||
si.nMax == editor->vert_si.nMax &&
|
si.nMax != editor->vert_si.nMax ||
|
||||||
si.nPage == editor->vert_si.nPage))
|
si.nPage != editor->vert_si.nPage)
|
||||||
{
|
{
|
||||||
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
|
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
|
||||||
editor->vert_si.nMin = si.nMin;
|
editor->vert_si.nMin = si.nMin;
|
||||||
editor->vert_si.nMax = si.nMax;
|
editor->vert_si.nMax = si.nMax;
|
||||||
editor->vert_si.nPage = si.nPage;
|
editor->vert_si.nPage = si.nPage;
|
||||||
if (bScrollBarWillBeVisible || bScrollBarWasVisible)
|
if (bScrollBarWillBeVisible || bScrollBarWasVisible)
|
||||||
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (si.fMask & SIF_DISABLENOSCROLL)
|
||||||
|
bScrollBarWillBeVisible = TRUE;
|
||||||
|
|
||||||
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
|
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
|
||||||
ShowScrollBar(hWnd, SB_VERT, bScrollBarWillBeVisible);
|
ShowScrollBar(editor->hWnd, SB_VERT, bScrollBarWillBeVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ME_GetYScrollPos(ME_TextEditor *editor)
|
void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
|
||||||
{
|
{
|
||||||
return editor->vert_si.nPos;
|
ME_Run *pRun = &pCursor->pRun->member.run;
|
||||||
}
|
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
|
||||||
|
ME_DisplayItem *pPara = ME_FindItemBack(pCursor->pRun, diParagraph);
|
||||||
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
|
int x, y, yheight;
|
||||||
{
|
|
||||||
ME_DisplayItem *pRow = ME_FindItemBack(pRun, diStartRow);
|
|
||||||
ME_DisplayItem *pPara = ME_FindItemBack(pRun, diParagraph);
|
|
||||||
int y, yrel, yheight, yold;
|
|
||||||
|
|
||||||
assert(pRow);
|
assert(pRow);
|
||||||
assert(pPara);
|
assert(pPara);
|
||||||
|
|
||||||
y = pPara->member.para.pt.y+pRow->member.row.pt.y;
|
x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset);
|
||||||
yheight = pRow->member.row.nHeight;
|
if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
|
||||||
yold = ME_GetYScrollPos(editor);
|
x = x + 1 - editor->sizeWindow.cx;
|
||||||
yrel = y - yold;
|
else if (x > editor->horz_si.nPos)
|
||||||
|
x = editor->horz_si.nPos;
|
||||||
|
|
||||||
if (y < yold)
|
y = pPara->member.para.pt.y + pRow->member.row.pt.y;
|
||||||
ME_ScrollAbs(editor,y);
|
yheight = pRow->member.row.nHeight;
|
||||||
else if (yrel + yheight > editor->sizeWindow.cy)
|
|
||||||
ME_ScrollAbs(editor,y+yheight-editor->sizeWindow.cy);
|
if (y < editor->vert_si.nPos)
|
||||||
|
ME_ScrollAbs(editor, x, y);
|
||||||
|
else if (y + yheight > editor->vert_si.nPos + editor->sizeWindow.cy)
|
||||||
|
ME_ScrollAbs(editor, x, y + yheight - editor->sizeWindow.cy);
|
||||||
|
else if (x != editor->horz_si.nPos)
|
||||||
|
ME_ScrollAbs(editor, x, editor->vert_si.nPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -621,12 +621,9 @@ static void test_EM_POSFROMCHAR(void)
|
||||||
SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINERIGHT, 0);
|
SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINERIGHT, 0);
|
||||||
result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 0, 0);
|
result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, 0, 0);
|
||||||
ok(HIWORD(result) == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", HIWORD(result));
|
ok(HIWORD(result) == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", HIWORD(result));
|
||||||
todo_wine {
|
|
||||||
/* Fails on builtin because horizontal scrollbar is not being shown */
|
|
||||||
ok((signed short)(LOWORD(result)) < xpos,
|
ok((signed short)(LOWORD(result)) < xpos,
|
||||||
"EM_POSFROMCHAR reports x=%hd, expected value less than %d\n",
|
"EM_POSFROMCHAR reports x=%hd, expected value less than %d\n",
|
||||||
(signed short)(LOWORD(result)), xpos);
|
(signed short)(LOWORD(result)), xpos);
|
||||||
}
|
|
||||||
SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINELEFT, 0);
|
SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINELEFT, 0);
|
||||||
|
|
||||||
/* Test around end of text that doesn't end in a newline. */
|
/* Test around end of text that doesn't end in a newline. */
|
||||||
|
|
|
@ -133,6 +133,7 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
para->member.para.nWidth = max(para->member.para.nWidth, width);
|
||||||
row = ME_MakeRow(ascent+descent, ascent, width);
|
row = ME_MakeRow(ascent+descent, ascent, width);
|
||||||
if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
|
if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
|
||||||
pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
|
pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
|
||||||
|
@ -536,6 +537,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
|
||||||
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
|
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
|
||||||
ME_DisplayItem *p, *pRow;
|
ME_DisplayItem *p, *pRow;
|
||||||
|
|
||||||
|
tp->member.para.nWidth = 0;
|
||||||
/* remove all items that will be reinserted by paragraph wrapper anyway */
|
/* remove all items that will be reinserted by paragraph wrapper anyway */
|
||||||
tp->member.para.nRows = 0;
|
tp->member.para.nRows = 0;
|
||||||
for (p = tp->next; p!=tp->member.para.next_para; p = p->next) {
|
for (p = tp->next; p!=tp->member.para.next_para; p = p->next) {
|
||||||
|
@ -578,6 +580,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
||||||
ME_Context c;
|
ME_Context c;
|
||||||
BOOL bModified = FALSE;
|
BOOL bModified = FALSE;
|
||||||
int yStart = -1;
|
int yStart = -1;
|
||||||
|
int totalWidth = 0;
|
||||||
|
|
||||||
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
||||||
c.pt.x = 0;
|
c.pt.x = 0;
|
||||||
|
@ -638,6 +641,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
||||||
ME_DisplayItem *startRowPara;
|
ME_DisplayItem *startRowPara;
|
||||||
int prevHeight, nHeight, bottomBorder = 0;
|
int prevHeight, nHeight, bottomBorder = 0;
|
||||||
ME_DisplayItem *cell = ME_FindItemBack(item, diCell);
|
ME_DisplayItem *cell = ME_FindItemBack(item, diCell);
|
||||||
|
item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth;
|
||||||
if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART))
|
if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART))
|
||||||
{
|
{
|
||||||
/* Last row, the bottom border is added to the height. */
|
/* Last row, the bottom border is added to the height. */
|
||||||
|
@ -707,12 +711,15 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
|
||||||
}
|
}
|
||||||
c.pt.y += item->member.para.nHeight;
|
c.pt.y += item->member.para.nHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalWidth = max(totalWidth, item->member.para.nWidth);
|
||||||
item = item->member.para.next_para;
|
item = item->member.para.next_para;
|
||||||
}
|
}
|
||||||
editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
|
editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
|
||||||
editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
|
editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
|
||||||
|
|
||||||
editor->nTotalLength = c.pt.y;
|
editor->nTotalLength = c.pt.y;
|
||||||
|
editor->nTotalWidth = totalWidth;
|
||||||
editor->pBuffer->pLast->member.para.pt.x = 0;
|
editor->pBuffer->pLast->member.para.pt.x = 0;
|
||||||
editor->pBuffer->pLast->member.para.pt.y = c.pt.y;
|
editor->pBuffer->pLast->member.para.pt.y = c.pt.y;
|
||||||
|
|
||||||
|
@ -732,7 +739,7 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor)
|
||||||
|
|
||||||
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
||||||
rc = c.rcView;
|
rc = c.rcView;
|
||||||
ofs = ME_GetYScrollPos(editor);
|
ofs = editor->vert_si.nPos;
|
||||||
|
|
||||||
item = editor->pBuffer->pFirst;
|
item = editor->pBuffer->pFirst;
|
||||||
while(item != editor->pBuffer->pLast) {
|
while(item != editor->pBuffer->pLast) {
|
||||||
|
@ -772,6 +779,7 @@ ME_SendRequestResize(ME_TextEditor *editor, BOOL force)
|
||||||
info.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
|
info.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
|
||||||
info.nmhdr.code = EN_REQUESTRESIZE;
|
info.nmhdr.code = EN_REQUESTRESIZE;
|
||||||
info.rc = rc;
|
info.rc = rc;
|
||||||
|
info.rc.right = editor->nTotalWidth;
|
||||||
info.rc.bottom = editor->nTotalLength;
|
info.rc.bottom = editor->nTotalLength;
|
||||||
|
|
||||||
editor->nEventMask &= ~ENM_REQUESTRESIZE;
|
editor->nEventMask &= ~ENM_REQUESTRESIZE;
|
||||||
|
|
Loading…
Reference in New Issue