void ME_UpdateScrollBar(ME_TextEditor *editor) { 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; si.nMin = 0; si.nPage = editor->sizeWindow.cy; if (editor->bScrollY) si.nMax = editor->nTotalLength; else si.nMax = 0; SetScrollInfo(hWnd, SB_VERT, &si, FALSE); 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); } }
void ME_RewrapRepaint(ME_TextEditor *editor) { ME_MarkAllForWrapping(editor); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); ME_Repaint(editor); }
void ME_MoveCaret(ME_TextEditor *editor) { int x, y, height; ME_WrapMarkedParagraphs(editor); ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); CreateCaret(editor->hWnd, NULL, 0, height); SetCaretPos(x, y); }
void ME_Repaint(ME_TextEditor *editor) { ME_Cursor *pCursor = &editor->pCursors[0]; if (ME_WrapMarkedParagraphs(editor)) { ME_UpdateScrollBar(editor); } if (editor->bRedraw) { ME_EnsureVisible(editor, pCursor->pRun); UpdateWindow(editor->hWnd); } }
void ME_MoveCaret(ME_TextEditor *editor) { int x, y, height; if (ME_WrapMarkedParagraphs(editor)) ME_UpdateScrollBar(editor); ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); if(editor->bHaveFocus) { CreateCaret(editor->hWnd, NULL, 0, height); SetCaretPos(x, y); } }
void ME_MoveCaret(ME_TextEditor *editor) { int x, y, height; if (ME_WrapMarkedParagraphs(editor)) ME_UpdateScrollBar(editor); ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); if(editor->bHaveFocus && !ME_IsSelection(editor)) { x = min(x, editor->rcFormat.right-1); CreateCaret(editor->hWnd, NULL, 0, height); SetCaretPos(x, y); } }
void ME_InvalidateSelection(ME_TextEditor *editor) { ME_DisplayItem *para1, *para2; int nStart, nEnd; int len = ME_GetTextLength(editor); ME_GetSelection(editor, &nStart, &nEnd); /* if both old and new selection are 0-char (= caret only), then there's no (inverted) area to be repainted, neither old nor new */ if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd) return; ME_WrapMarkedParagraphs(editor); ME_GetSelectionParas(editor, ¶1, ¶2); assert(para1->type == diParagraph); assert(para2->type == diParagraph); /* last selection markers aren't always updated, which means they can point past the end of the document */ if (editor->nLastSelStart > len) editor->nLastSelEnd = len; if (editor->nLastSelEnd > len) editor->nLastSelEnd = len; /* if the start part of selection is being expanded or contracted... */ if (nStart < editor->nLastSelStart) { ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd)); } else if (nStart > editor->nLastSelStart) { ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd)); } /* if the end part of selection is being contracted or expanded... */ if (nEnd < editor->nLastSelEnd) { ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd)); } else if (nEnd > editor->nLastSelEnd) { ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd)); } ME_InvalidateMarkedParagraphs(editor); /* remember the last invalidated position */ ME_GetSelection(editor, &editor->nLastSelStart, &editor->nLastSelEnd); ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara); assert(editor->pLastSelStartPara->type == diParagraph); assert(editor->pLastSelEndPara->type == diParagraph); }
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); ME_WrapMarkedParagraphs(editor); if (pRow) { ME_DisplayItem *pRun; if (editor->bCaretAtEnd && !pCursor->nOffset) { pRow = ME_FindItemBack(pRow, diStartRow); if (!pRow) return; } pRun = ME_FindItemFwd(pRow, diRun); if (pRun) { pCursor->pRun = pRun; pCursor->nOffset = 0; } } editor->bCaretAtEnd = FALSE; }
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); /* bCaretAtEnd doesn't make sense if the cursor isn't set at the first character of the next row */ assert(!editor->bCaretAtEnd || !pCursor->nOffset); ME_WrapMarkedParagraphs(editor); if (pRow) { ME_DisplayItem *pRun; if (editor->bCaretAtEnd && !pCursor->nOffset) { pRow = ME_FindItemBack(pRow, diStartRow); if (!pRow) return; } pRun = ME_FindItemFwd(pRow, diRun); if (pRun) { pCursor->pRun = pRun; pCursor->nOffset = 0; } } editor->bCaretAtEnd = FALSE; }
/* Selects the next table cell or appends a new table row if at end of table */ static void ME_SelectOrInsertNextCell(ME_TextEditor *editor, ME_DisplayItem *run) { ME_DisplayItem *para = ME_GetParagraph(run); int i; assert(run && run->type == diRun); assert(ME_IsInTable(run)); if (!editor->bEmulateVersion10) { /* v4.1 */ ME_DisplayItem *cell; /* Get the initial cell */ if (para->member.para.nFlags & MEPF_ROWSTART) { cell = para->member.para.next_para->member.para.pCell; } else if (para->member.para.nFlags & MEPF_ROWEND) { cell = para->member.para.prev_para->member.para.pCell; } else { cell = para->member.para.pCell; } assert(cell); /* Get the next cell. */ if (cell->member.cell.next_cell && cell->member.cell.next_cell->member.cell.next_cell) { cell = cell->member.cell.next_cell; } else { para = ME_GetTableRowEnd(ME_FindItemFwd(cell, diParagraph)); para = para->member.para.next_para; assert(para); if (para->member.para.nFlags & MEPF_ROWSTART) { cell = para->member.para.next_para->member.para.pCell; } else { /* Insert row */ para = para->member.para.prev_para; para = ME_AppendTableRow(editor, ME_GetTableRowStart(para)); /* Put cursor at the start of the new table row */ para = para->member.para.next_para; editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_WrapMarkedParagraphs(editor); return; } } /* Select cell */ editor->pCursors[1].pRun = ME_FindItemFwd(cell, diRun); editor->pCursors[1].nOffset = 0; assert(editor->pCursors[0].pRun); cell = cell->member.cell.next_cell; editor->pCursors[0].pRun = ME_FindItemBack(cell, diRun); editor->pCursors[0].nOffset = 0; assert(editor->pCursors[1].pRun); } else { /* v1.0 - 3.0 */ if (run->member.run.nFlags & MERF_ENDPARA && ME_IsInTable(ME_FindItemFwd(run, diParagraphOrEnd))) { run = ME_FindItemFwd(run, diRun); assert(run); } for (i = 0; i < 2; i++) { while (!(run->member.run.nFlags & MERF_TAB)) { run = ME_FindItemFwd(run, diRunOrParagraphOrEnd); if (run->type != diRun) { para = run; if (ME_IsInTable(para)) { run = ME_FindItemFwd(para, diRun); assert(run); editor->pCursors[0].pRun = run; editor->pCursors[0].nOffset = 0; i = 1; } else { /* Insert table row */ para = ME_AppendTableRow(editor, para->member.para.prev_para); /* Put cursor at the start of the new table row */ editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_WrapMarkedParagraphs(editor); return; } } } if (i == 0) run = ME_FindItemFwd(run, diRun); editor->pCursors[i].pRun = run; editor->pCursors[i].nOffset = 0; } } }