void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) { ME_Context c; ME_InitContext(&c, editor, GetDC(editor->hWnd)); if (editor->bRedraw) { RECT rc = c.rcView; int ofs = ME_GetYScrollPos(editor); ME_DisplayItem *item = editor->pBuffer->pFirst; while(item != editor->pBuffer->pLast) { if (item->member.para.nFlags & MEPF_REPAINT) { rc.top = item->member.para.nYPos - ofs; rc.bottom = item->member.para.nYPos + item->member.para.nHeight - ofs; InvalidateRect(editor->hWnd, &rc, TRUE); } item = item->member.para.next_para; } if (editor->nTotalLength < editor->nLastTotalLength) { rc.top = editor->nTotalLength - ofs; rc.bottom = editor->nLastTotalLength - ofs; InvalidateRect(editor->hWnd, &rc, TRUE); } } ME_DestroyContext(&c, editor->hWnd); }
void ME_LButtonDown(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; int is_selection = 0; editor->nUDArrowX = -1; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; is_selection = ME_IsSelection(editor); ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); if (GetKeyState(VK_SHIFT)>=0) { editor->pCursors[1] = editor->pCursors[0]; } else { if (!is_selection) { editor->pCursors[1] = tmp_cursor; is_selection = 1; } } ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); }
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); y = pPara->member.para.nYPos+pRow->member.row.nYPos; 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); } } }
int ME_CharFromPos(ME_TextEditor *editor, int x, int y) { ME_Cursor cursor; RECT rc; GetClientRect(editor->hWnd, &rc); if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) return -1; y += ME_GetYScrollPos(editor); ME_FindPixelPos(editor, x, y, &cursor, NULL); return (ME_GetParagraph(cursor.pRun)->member.para.nCharOfs + cursor.pRun->member.run.nCharOfs + cursor.nOffset); }
void ME_MouseMove(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; /* FIXME: do something with the return value of ME_FindPixelPos */ if (!editor->linesel) ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd); else ME_FindPixelPos(editor, (y > editor->sely) * editor->rcFormat.right, y, &tmp_cursor, &editor->bCaretAtEnd); if (!memcmp(&tmp_cursor, editor->pCursors, sizeof(tmp_cursor))) return; ME_InvalidateSelection(editor); if (!editor->linesel) editor->pCursors[0] = tmp_cursor; else if (!memcmp(&tmp_cursor, editor->pCursors+2, sizeof(tmp_cursor)) || !memcmp(&tmp_cursor, editor->pCursors+3, sizeof(tmp_cursor))) { editor->pCursors[0] = editor->pCursors[2]; editor->pCursors[1] = editor->pCursors[3]; } else if (y < editor->sely) { editor->pCursors[0] = tmp_cursor; editor->pCursors[1] = editor->pCursors[2]; } else { editor->pCursors[0] = tmp_cursor; editor->pCursors[1] = editor->pCursors[3]; } HideCaret(editor->hWnd); ME_MoveCaret(editor); ME_InvalidateSelection(editor); ShowCaret(editor->hWnd); ME_SendSelChange(editor); }
void ME_MouseMove(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; /* FIXME: do something with the return value of ME_FindPixelPos */ ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd); if (tmp_cursor.pRun == editor->pCursors[0].pRun && tmp_cursor.nOffset == editor->pCursors[0].nOffset) return; ME_InvalidateSelection(editor); editor->pCursors[0] = tmp_cursor; HideCaret(editor->hWnd); ME_MoveCaret(editor); ME_InvalidateSelection(editor); ShowCaret(editor->hWnd); ME_SendSelChange(editor); }
void ME_LButtonDown(ME_TextEditor *editor, int x, int y) { ME_Cursor tmp_cursor; int is_selection = 0; editor->nUDArrowX = -1; y += ME_GetYScrollPos(editor); tmp_cursor = editor->pCursors[0]; is_selection = ME_IsSelection(editor); if (x >= editor->selofs) { ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd); if (GetKeyState(VK_SHIFT)>=0) { editor->pCursors[1] = editor->pCursors[0]; } else if (!is_selection) { editor->pCursors[1] = tmp_cursor; is_selection = 1; } ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); } else { ME_DisplayItem *pRow; editor->linesel = 1; editor->sely = y; /* Set pCursors[0] to beginning of line */ ME_FindPixelPos(editor, x, y, &editor->pCursors[1], &editor->bCaretAtEnd); /* Set pCursors[1] to end of line */ pRow = ME_FindItemFwd(editor->pCursors[1].pRun, diStartRowOrParagraphOrEnd); assert(pRow); /* pCursor[0] is the position where the cursor will be drawn, * pCursor[1] is the other end of the selection range * pCursor[2] and [3] are backups of [0] and [1] so I * don't have to look them up again */ if (pRow->type == diStartRow) { /* FIXME WTF was I thinking about here ? */ ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); assert(pRun); editor->pCursors[0].pRun = pRun; editor->pCursors[0].nOffset = 0; editor->bCaretAtEnd = 1; } else { editor->pCursors[0].pRun = ME_FindItemBack(pRow, diRun); assert(editor->pCursors[0].pRun && editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA); editor->pCursors[0].nOffset = 0; editor->bCaretAtEnd = 0; } editor->pCursors[2] = editor->pCursors[0]; editor->pCursors[3] = editor->pCursors[1]; ME_InvalidateSelection(editor); HideCaret(editor->hWnd); ME_MoveCaret(editor); ShowCaret(editor->hWnd); ME_ClearTempStyle(editor); ME_SendSelChange(editor); } }
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height) { ME_DisplayItem *pCursorRun = pCursor->pRun; ME_DisplayItem *pSizeRun = pCursor->pRun; assert(!pCursor->nOffset || !editor->bCaretAtEnd); assert(height && x && y); assert(!(ME_GetParagraph(pCursorRun)->member.para.nFlags & MEPF_REWRAP)); assert(pCursor->pRun); assert(pCursor->pRun->type == diRun); if (pCursorRun->type == diRun) { ME_DisplayItem *row = ME_FindItemBack(pCursorRun, diStartRowOrParagraph); if (row) { HDC hDC = GetDC(editor->hWnd); ME_Context c; ME_DisplayItem *run = pCursorRun; ME_DisplayItem *para = NULL; SIZE sz = {0, 0}; ME_InitContext(&c, editor, hDC); if (!pCursor->nOffset && !editor->bCaretAtEnd) { ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrStartRow); assert(prev); if (prev->type == diRun) pSizeRun = prev; } assert(row->type == diStartRow); /* paragraph -> run without start row ?*/ para = ME_FindItemBack(row, diParagraph); assert(para); assert(para->type == diParagraph); if (editor->bCaretAtEnd && !pCursor->nOffset && run == ME_FindItemFwd(row, diRun)) { ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph); assert(tmp); if (tmp->type == diRun) { row = ME_FindItemBack(tmp, diStartRow); pSizeRun = run = tmp; assert(run); assert(run->type == diRun); sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, ME_StrLen(run->member.run.strText), row->member.row.nLMargin); } } if (pCursor->nOffset && !(run->member.run.nFlags & MERF_SKIPPED)) { sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, pCursor->nOffset, row->member.row.nLMargin); } *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent; *x = run->member.run.pt.x + sz.cx; *y = para->member.para.nYPos + row->member.row.nBaseline + pSizeRun->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor); ME_DestroyContext(&c, editor->hWnd); return; } } *height = 10; /* FIXME use global font */ *x = 0; *y = 0; }
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpdate) { ME_DisplayItem *item; ME_Context c; int yoffset; editor->nSequence++; yoffset = ME_GetYScrollPos(editor); ME_InitContext(&c, editor, hDC); SetBkMode(hDC, TRANSPARENT); ME_MoveCaret(editor); item = editor->pBuffer->pFirst->next; c.pt.y -= yoffset; while(item != editor->pBuffer->pLast) { int ye; assert(item->type == diParagraph); ye = c.pt.y + item->member.para.nHeight; if (!bOnlyNew || (item->member.para.nFlags & MEPF_REPAINT)) { BOOL bPaint = (rcUpdate == NULL); if (rcUpdate) bPaint = c.pt.y<rcUpdate->bottom && c.pt.y+item->member.para.nHeight>rcUpdate->top; if (bPaint) { ME_DrawParagraph(&c, item); if (!rcUpdate || (rcUpdate->top<=c.pt.y && rcUpdate->bottom>=ye)) item->member.para.nFlags &= ~MEPF_REPAINT; } } c.pt.y = ye; item = item->member.para.next_para; } if (c.pt.y<c.rcView.bottom) { RECT rc; int xs = c.rcView.left, xe = c.rcView.right; int ys = c.pt.y, ye = c.rcView.bottom; if (bOnlyNew) { int y1 = editor->nTotalLength-yoffset, y2 = editor->nLastTotalLength-yoffset; if (y1<y2) ys = y1, ye = y2+1; else ys = ye; } if (rcUpdate && ys!=ye) { xs = rcUpdate->left, xe = rcUpdate->right; if (rcUpdate->top > ys) ys = rcUpdate->top; if (rcUpdate->bottom < ye) ye = rcUpdate->bottom; } if (ye>ys) { rc.left = xs; rc.top = ys; rc.right = xe; rc.bottom = ye; FillRect(hDC, &rc, c.editor->hbrBackground); } if (ys == c.pt.y) /* don't overwrite the top bar */ ys++; } if (editor->nTotalLength != editor->nLastTotalLength) ME_SendRequestResize(editor, FALSE); editor->nLastTotalLength = editor->nTotalLength; ME_DestroyContext(&c); }