static void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType) { /* pCursor[0] is the end of the selection * pCursor[1] is the start of the selection (or the position selection anchor) * pCursor[2] and [3] are the selection anchors that are backed up * so they are kept when the selection changes for drag selection. */ editor->nSelectionType = selectionType; switch(selectionType) { case stPosition: break; case stWord: ME_MoveCursorWords(editor, &editor->pCursors[0], +1); editor->pCursors[1] = editor->pCursors[0]; ME_MoveCursorWords(editor, &editor->pCursors[1], -1); break; case stLine: case stParagraph: { ME_DisplayItem *pItem; ME_DIType fwdSearchType, backSearchType; if (selectionType == stParagraph) { backSearchType = diParagraph; fwdSearchType = diParagraphOrEnd; } else { backSearchType = diStartRow; fwdSearchType = diStartRowOrParagraphOrEnd; } pItem = ME_FindItemFwd(editor->pCursors[0].pRun, fwdSearchType); assert(pItem); if (pItem->type == diTextEnd) editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); else editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[0].nOffset = 0; pItem = ME_FindItemBack(pItem, backSearchType); editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[1].nOffset = 0; break; } case stDocument: /* Select everything with cursor anchored from the start of the text */ editor->nSelectionType = stDocument; 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; break; default: assert(0); } /* Store the anchor positions for extending the selection. */ editor->pCursors[2] = editor->pCursors[0]; editor->pCursors[3] = editor->pCursors[1]; }
void ME_SelectWord(ME_TextEditor *editor) { if (!(editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA)) ME_MoveCursorWords(editor, &editor->pCursors[0], -1); ME_MoveCursorWords(editor, &editor->pCursors[1], +1); ME_InvalidateSelection(editor); ME_SendSelChange(editor); }
/* Extends the selection with a word, line, or paragraph selection type. * * The selection is anchored by editor->pCursors[2-3] such that the text * between the anchors will remain selected, and one end will be extended. * * editor->pCursors[0] should have the position to extend the selection to * before this function is called. * * Nothing will be done if editor->nSelectionType equals stPosition. */ static void ME_ExtendAnchorSelection(ME_TextEditor *editor) { ME_Cursor tmp_cursor; int curOfs, anchorStartOfs, anchorEndOfs; if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument) return; curOfs = ME_GetCursorOfs(&editor->pCursors[0]); anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]); anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]); tmp_cursor = editor->pCursors[0]; editor->pCursors[0] = editor->pCursors[2]; editor->pCursors[1] = editor->pCursors[3]; if (curOfs < anchorStartOfs) { /* Extend the left side of selection */ editor->pCursors[1] = tmp_cursor; if (editor->nSelectionType == stWord) ME_MoveCursorWords(editor, &editor->pCursors[1], -1); else { ME_DisplayItem *pItem; ME_DIType searchType = ((editor->nSelectionType == stLine) ? diStartRowOrParagraph:diParagraph); pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType); editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); editor->pCursors[1].nOffset = 0; } } else if (curOfs >= anchorEndOfs) { /* Extend the right side of selection */ editor->pCursors[0] = tmp_cursor; if (editor->nSelectionType == stWord) ME_MoveCursorWords(editor, &editor->pCursors[0], +1); else { ME_DisplayItem *pItem; ME_DIType searchType = ((editor->nSelectionType == stLine) ? diStartRowOrParagraphOrEnd:diParagraphOrEnd); pItem = ME_FindItemFwd(editor->pCursors[0].pRun, searchType); if (pItem->type == diTextEnd) editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); else editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); editor->pCursors[0].nOffset = 0; } } }
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; }