BOOL ME_UpdateSelection(ME_TextEditor *editor, const ME_Cursor *pTempCursor) { ME_Cursor old_anchor = editor->pCursors[1]; if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */ { /* any selection was present ? if so, it's no more, repaint ! */ editor->pCursors[1] = editor->pCursors[0]; if (memcmp(pTempCursor, &old_anchor, sizeof(ME_Cursor))) { return TRUE; } return FALSE; } else { if (!memcmp(pTempCursor, &editor->pCursors[1], sizeof(ME_Cursor))) /* starting selection */ { editor->pCursors[1] = *pTempCursor; return TRUE; } } ME_Repaint(editor); return TRUE; }
void ME_RewrapRepaint(ME_TextEditor *editor) { ME_MarkAllForWrapping(editor); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); ME_Repaint(editor); }
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) { /* FIXME: Shift tab should move to the previous cell. */ ME_Cursor fromCursor, toCursor; ME_InvalidateSelection(editor); { int from, to; from = ME_GetCursorOfs(editor, 0); to = ME_GetCursorOfs(editor, 1); if (from <= to) { fromCursor = editor->pCursors[0]; toCursor = editor->pCursors[1]; } else { fromCursor = editor->pCursors[1]; toCursor = editor->pCursors[0]; } } if (!editor->bEmulateVersion10) /* v4.1 */ { if (!ME_IsInTable(toCursor.pRun)) { editor->pCursors[0] = toCursor; editor->pCursors[1] = toCursor; } else { ME_SelectOrInsertNextCell(editor, toCursor.pRun); } } else { /* v1.0 - 3.0 */ if (!ME_IsInTable(fromCursor.pRun)) { editor->pCursors[0] = fromCursor; editor->pCursors[1] = fromCursor; /* FIXME: For some reason the caret is shown at the start of the * previous paragraph in v1.0 to v3.0, and bCaretAtEnd only works * within the paragraph for wrapped lines. */ if (ME_FindItemBack(fromCursor.pRun, diRun)) editor->bCaretAtEnd = TRUE; } else if ((bSelectedRow || !ME_IsInTable(toCursor.pRun))) { ME_SelectOrInsertNextCell(editor, fromCursor.pRun); } else { if (ME_IsSelection(editor) && !toCursor.nOffset) { ME_DisplayItem *run; run = ME_FindItemBack(toCursor.pRun, diRunOrParagraphOrEnd); if (run->type == diRun && run->member.run.nFlags & MERF_TAB) ME_SelectOrInsertNextCell(editor, run); else ME_SelectOrInsertNextCell(editor, toCursor.pRun); } else { ME_SelectOrInsertNextCell(editor, toCursor.pRun); } } } ME_InvalidateSelection(editor); ME_Repaint(editor); HideCaret(editor->hWnd); ME_ShowCaret(editor); ME_SendSelChange(editor); }
void ME_UpdateRepaint(ME_TextEditor *editor) { /* InvalidateRect(editor->hWnd, NULL, TRUE); */ ME_SendOldNotify(editor, EN_CHANGE); ME_Repaint(editor); ME_SendOldNotify(editor, EN_UPDATE); ME_SendSelChange(editor); }
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pLast, *p; int x, y, ys, yd, yp, yprev; ME_Cursor tmp_curs = *pCursor; x = ME_GetXForArrow(editor, pCursor); if (!pCursor->nOffset && editor->bCaretAtEnd) pRun = ME_FindItemBack(pRun, diRun); p = ME_FindItemBack(pRun, diStartRowOrParagraph); assert(p->type == diStartRow); yp = ME_FindItemBack(p, diParagraph)->member.para.nYPos; yprev = ys = y = yp + p->member.row.nYPos; yd = y - editor->sizeWindow.cy; pLast = p; do { p = ME_FindItemBack(p, diStartRowOrParagraph); if (!p) break; if (p->type == diParagraph) { /* crossing paragraphs */ if (p->member.para.prev_para == NULL) break; yp = p->member.para.prev_para->member.para.nYPos; continue; } y = yp + p->member.row.nYPos; if (y < yd) break; pLast = p; yprev = y; } while(1); pCursor->pRun = ME_FindRunInRow(editor, pLast, x, &pCursor->nOffset, &editor->bCaretAtEnd); ME_UpdateSelection(editor, &tmp_curs); if (yprev < editor->sizeWindow.cy) { ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun)); ME_Repaint(editor); } else { ME_ScrollUp(editor, ys-yprev); } assert(pCursor->pRun); assert(pCursor->pRun->type == diRun); }
int ME_SetSelection(ME_TextEditor *editor, int from, int to) { int selectionEnd = 0; const int len = ME_GetTextLength(editor); /* all negative values are effectively the same */ if (from < 0) from = -1; if (to < 0) to = -1; /* select all */ if (from == 0 && to == -1) { editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); editor->pCursors[1].nOffset = 0; editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); editor->pCursors[0].nOffset = 0; ME_InvalidateSelection(editor); ME_ClearTempStyle(editor); return len + 1; } /* if both values are equal and also out of bound, that means to */ /* put the selection at the end of the text */ if ((from == to) && (to < 0 || to > len)) { selectionEnd = 1; } else { /* if from is negative and to is positive then selection is */ /* deselected and caret moved to end of the current selection */ if (from < 0) { int start, end; ME_GetSelection(editor, &start, &end); editor->pCursors[1] = editor->pCursors[0]; ME_Repaint(editor); ME_ClearTempStyle(editor); return end; } /* adjust to if it's a negative value */ if (to < 0) to = len + 1; /* flip from and to if they are reversed */ if (from>to) { int tmp = from; from = to; to = tmp; } /* after fiddling with the values, we find from > len && to > len */ if (from > len) selectionEnd = 1; /* special case with to too big */ else if (to > len) to = len + 1; } if (selectionEnd) { editor->pCursors[1].pRun = editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); editor->pCursors[1].nOffset = editor->pCursors[0].nOffset = 0; ME_InvalidateSelection(editor); ME_ClearTempStyle(editor); return len; } ME_RunOfsFromCharOfs(editor, from, &editor->pCursors[1].pRun, &editor->pCursors[1].nOffset); ME_RunOfsFromCharOfs(editor, to, &editor->pCursors[0].pRun, &editor->pCursors[0].nOffset); return to; }
BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) { int nCursor = 0; ME_Cursor *p = &editor->pCursors[nCursor]; ME_Cursor tmp_curs = *p; BOOL success = FALSE; ME_CheckCharOffsets(editor); switch(nVKey) { case VK_LEFT: editor->bCaretAtEnd = 0; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, -1); else success = ME_MoveCursorChars(editor, &tmp_curs, -1); break; case VK_RIGHT: editor->bCaretAtEnd = 0; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, +1); else success = ME_MoveCursorChars(editor, &tmp_curs, +1); break; case VK_UP: ME_MoveCursorLines(editor, &tmp_curs, -1); break; case VK_DOWN: ME_MoveCursorLines(editor, &tmp_curs, +1); break; case VK_PRIOR: ME_ArrowPageUp(editor, &tmp_curs); break; case VK_NEXT: ME_ArrowPageDown(editor, &tmp_curs); break; case VK_HOME: { if (ctrl) ME_ArrowCtrlHome(editor, &tmp_curs); else ME_ArrowHome(editor, &tmp_curs); editor->bCaretAtEnd = 0; break; } case VK_END: if (ctrl) ME_ArrowCtrlEnd(editor, &tmp_curs); else ME_ArrowEnd(editor, &tmp_curs); break; } if (!extend) editor->pCursors[1] = tmp_curs; *p = tmp_curs; ME_InvalidateSelection(editor); ME_Repaint(editor); HideCaret(editor->hWnd); ME_EnsureVisible(editor, &tmp_curs); ME_ShowCaret(editor); ME_SendSelChange(editor); return success; }
int ME_SetSelection(ME_TextEditor *editor, int from, int to) { int selectionEnd = 0; const int len = ME_GetTextLength(editor); /* all negative values are effectively the same */ if (from < 0) from = -1; if (to < 0) to = -1; /* select all */ if (from == 0 && to == -1) { ME_SetCursorToStart(editor, &editor->pCursors[1]); ME_SetCursorToEnd(editor, &editor->pCursors[0]); editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len; ME_InvalidateSelection(editor); return len + 1; } /* if both values are equal and also out of bound, that means to */ /* put the selection at the end of the text */ if ((from == to) && (to < 0 || to > len)) { selectionEnd = 1; } else { /* if from is negative and to is positive then selection is */ /* deselected and caret moved to end of the current selection */ if (from < 0) { int start, end; ME_GetSelectionOfs(editor, &start, &end); if (start != end) { if (end > len) { editor->pCursors[0].nOffset = 0; end --; } editor->pCursors[1] = editor->pCursors[0]; ME_Repaint(editor); } return end; } /* adjust to if it's a negative value */ if (to < 0) to = len + 1; /* flip from and to if they are reversed */ if (from>to) { int tmp = from; from = to; to = tmp; } /* after fiddling with the values, we find from > len && to > len */ if (from > len) selectionEnd = 1; /* special case with to too big */ else if (to > len) to = len + 1; } if (selectionEnd) { ME_SetCursorToEnd(editor, &editor->pCursors[0]); editor->pCursors[1] = editor->pCursors[0]; ME_InvalidateSelection(editor); return len; } ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]); editor->pCursors[0] = editor->pCursors[1]; ME_MoveCursorChars(editor, &editor->pCursors[0], to - from); /* Selection is not allowed in the middle of an end paragraph run. */ if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA) editor->pCursors[1].nOffset = 0; if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA) { if (to > len) editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len; else editor->pCursors[0].nOffset = 0; } return to; }