/// <summary> /// Calculate index of the next word. /// </summary> public static int Calc_NextWord(IViewInternal view) { int index; Document doc = view.Document; // if EOL code comes, return just after them if (Utl.IsEol(doc, doc.CaretIndex)) { return(Utl.SkipOneEol(doc, doc.CaretIndex)); } // if the caret is at the end of document, return end of document index = doc.CaretIndex + 1; if (doc.Length <= index) { return(doc.Length); } // seek to next word starting position index = doc.WordProc.NextWordStart(doc, index); // skip trailling whitespace if (Utl.IsWhiteSpace(doc, index)) { index = doc.WordProc.NextWordStart(doc, index + 1); } return(index); }
/// <summary> /// Calculate index of the location /// where the caret should move to after pressing "up" key. /// </summary> public static int Calc_Up(IViewInternal view) { Point pt; int newIndex; Document doc = view.Document; // get screen location of the caret pt = view.GetVirPosFromIndex(doc.CaretIndex); // calculate next location pt.X = view.GetDesiredColumn(); pt.Y -= view.LineSpacing; newIndex = view.GetIndexFromVirPos(pt); if (newIndex < 0) { return(doc.CaretIndex); // don't move } // In line selection mode, // moving caret across the line which contains the anchor position // should select the line and a line above. // To select a line above, calculate index of the char at one more line above. if (doc.SelectionMode == TextDataType.Line && newIndex == doc.AnchorIndex && view.IsLineHeadIndex(newIndex)) { pt.Y -= view.LineSpacing; if (0 <= pt.Y) { newIndex = view.GetIndexFromVirPos(pt); } } return(newIndex); }
/// <summary> /// Calculate index of the previous word. /// </summary> public static int Calc_PrevWord(IViewInternal view) { int index; int startIndex; Document doc = view.Document; // if the caret is at the head of document, return head of document index = doc.CaretIndex - 1; if (index <= 0) { return(0); } // skip whitespace startIndex = index; if (Utl.IsWhiteSpace(doc, index)) { index = doc.WordProc.PrevWordStart(doc, index) - 1; if (index < 0) { return(0); } } DebugUtl.Assert(0 <= index && index <= doc.Length); // if EOL code comes, return just before them if (Utl.IsEol(doc, index)) { if (startIndex != index) { // do not skip this EOL code // if this was detected after skipping whitespaces return(index + 1); } else if (doc[index] == '\r') { return(index); } else { DebugUtl.Assert(doc[index] == '\n'); if (0 <= index - 1 && doc[index - 1] == '\r') { return(index - 1); } else { return(index); } } } // seek to previous word starting position index = doc.WordProc.PrevWordStart(doc, index); return(index); }
void SetSelection_Rect(int anchor, int caret, IViewInternal view) { // calculate graphical position of both anchor and new caret Point anchorPos = view.GetVirPosFromIndex(anchor); Point caretPos = view.GetVirPosFromIndex(caret); // calculate ranges selected by the rectangle made with the two points ViewParam.RectSelectRanges = view.GetRectSelectRanges(MakeRect(anchorPos, caretPos)); // set selection SetSelection_Normal(anchor, caret); }
/// <summary> /// Calculate index of the first non-whitespace char of the line where caret is at. /// </summary> public static int Calc_LineHeadSmart(IViewInternal view) { int lineHeadIndex, firstNonSpaceIndex; Document doc = view.Document; lineHeadIndex = view.GetLineHeadIndexFromCharIndex(doc.CaretIndex); firstNonSpaceIndex = lineHeadIndex; while (firstNonSpaceIndex < doc.Length && Utl.IsWhiteSpace(doc, firstNonSpaceIndex)) { firstNonSpaceIndex++; } return((firstNonSpaceIndex == doc.CaretIndex) ? lineHeadIndex : firstNonSpaceIndex); }
/// <summary> /// Calculate index of the location /// where the caret should move to after pressing "left" key. /// </summary> public static int Calc_Left(IViewInternal view) { Document doc = view.Document; if (doc.CaretIndex - 1 < 0) { return(0); } // Avoid placing caret at middle of an undividable character sequences. int newCaretIndex = doc.CaretIndex - 1; while (doc.IsNotDividableIndex(newCaretIndex)) { newCaretIndex--; } return(newCaretIndex); }
/// <summary> /// Calculate index of the location /// where the caret should move to after pressing "right" key. /// </summary> public static int Calc_Right(IViewInternal view) { Document doc = view.Document; if (doc.Length < doc.CaretIndex + 1) { return(doc.Length); } // Avoid placing caret at middle of an undividable character sequences. int newCaretIndex = doc.CaretIndex + 1; while (doc.IsNotDividableIndex(newCaretIndex)) { newCaretIndex++; } return(newCaretIndex); }
/// <summary> /// Calculate index of the end location of the line where caret is at. /// </summary> public static int Calc_LineEnd(IViewInternal view) { Document doc = view.Document; int line, column; int offset = -1; view.GetLineColumnIndexFromCharIndex(doc.CaretIndex, out line, out column); if (view.LineCount <= line + 1) { return(doc.Length); } int nextIndex = view.GetCharIndexFromLineColumnIndex(line + 1, 0); if (0 <= nextIndex - 1 && doc.GetCharAt(nextIndex - 1) == '\n' && 0 <= nextIndex - 2 && doc.GetCharAt(nextIndex - 2) == '\r') { offset = -2; } return(nextIndex + offset); }
/// <summary> /// Calculate index of the location /// where the caret should move to after pressing "down" key. /// </summary> public static int Calc_Down(IViewInternal view) { Point pt; int newIndex; Document doc = view.Document; // get screen location of the caret pt = view.GetVirPosFromIndex(doc.CaretIndex); // calculate next location pt.X = view.GetDesiredColumn(); pt.Y += view.LineSpacing; /* NOT NEEDED because View.GetIndexFromVirPos handles this case. * if( view.Height - view.LineSpacing < pt.Y ) * { * return doc.CaretIndex; // no lines below. don't move. * }*/ newIndex = view.GetIndexFromVirPos(pt); // In line selection mode, // moving caret across the line which contains the anchor position // should select the line and a line below. // To select a line below, calculate index of the char at one more line below. if (doc.SelectionMode == TextDataType.Line && view.IsLineHeadIndex(newIndex)) { Point pt2 = new Point(pt.X, pt.Y + view.LineSpacing); int skippedNewIndex = view.GetIndexFromVirPos(pt2); if (skippedNewIndex == doc.AnchorIndex) { newIndex = skippedNewIndex; } } return(newIndex); }
/// <summary> /// Calculate end index of the file. /// </summary> public static int Calc_FileEnd(IViewInternal view) { return(view.Document.Length); }
/// <summary> /// Calculate first index of the file. /// </summary> public static int Calc_FileHead(IViewInternal view) { return(0); }
/// <summary> /// Calculate index of the first char of the line where caret is at. /// </summary> public static int Calc_LineHead(IViewInternal view) { return(view.GetLineHeadIndexFromCharIndex( view.Document.CaretIndex )); }
void SetSelection_Line(int anchor, int caret, IViewInternal view) { int toLineIndex; // get line index of the lines where selection starts and ends toLineIndex = view.GetLineIndexFromCharIndex(caret); if (ViewParam.LineSelectionAnchor1 < 0 || (anchor != ViewParam.LineSelectionAnchor1 && anchor != ViewParam.LineSelectionAnchor2)) { //-- line selection anchor changed or did not exists -- // select between head of the line and end of the line int fromLineIndex = view.GetLineIndexFromCharIndex(anchor); anchor = view.GetLineHeadIndex(fromLineIndex); if (fromLineIndex + 1 < view.LineCount) { caret = view.GetLineHeadIndex(fromLineIndex + 1); } else { caret = _Document.Length; } ViewParam.LineSelectionAnchor1 = anchor; ViewParam.LineSelectionAnchor2 = anchor; } else if (ViewParam.LineSelectionAnchor1 < caret) { //-- selecting to the line (or after) where selection started -- // select between head of the starting line and the end of the destination line anchor = view.GetLineHeadIndexFromCharIndex(ViewParam.LineSelectionAnchor1); if (view.IsLineHeadIndex(caret) == false) { toLineIndex = view.GetLineIndexFromCharIndex(caret); if (toLineIndex + 1 < view.LineCount) { caret = view.GetLineHeadIndex(toLineIndex + 1); } else { caret = _Document.Length; } } } else // if( caret < LineSelectionAnchor ) { //-- selecting to foregoing lines where selection started -- // select between head of the destination line and end of the starting line int anchorLineIndex; caret = view.GetLineHeadIndex(toLineIndex); anchorLineIndex = view.GetLineIndexFromCharIndex(ViewParam.LineSelectionAnchor1); if (anchorLineIndex + 1 < view.LineCount) { anchor = view.GetLineHeadIndex(anchorLineIndex + 1); } else { anchor = _Document.Length; } //DO_NOT//ViewParam.LineSelectionAnchor1 = anchor; ViewParam.LineSelectionAnchor2 = anchor; } // apply new selection SetSelection_Normal(anchor, caret); }
public void SetSelection(int anchor, int caret, IViewInternal view) { Debug.Assert(0 <= anchor && anchor <= _Document.Length, "parameter 'anchor' out of" + " range (anchor:" + anchor + ", Document.Length:" + _Document.Length + ")"); Debug.Assert(0 <= caret && caret <= _Document.Length, "parameter 'caret' out of range" + " (anchor:" + anchor + ", Document.Length:" + _Document.Length + ")"); Debug.Assert(ViewParam.SelectionMode == TextDataType.Normal || view != null); // ensure that document can be divided at given index if (anchor < caret) { while (_Document.IsNotDividableIndex(anchor)) { anchor--; } while (_Document.IsNotDividableIndex(caret)) { caret++; } } else if (caret < anchor) { while (_Document.IsNotDividableIndex(caret)) { caret--; } while (_Document.IsNotDividableIndex(anchor)) { anchor++; } } else // if( anchor == caret ) { while (_Document.IsNotDividableIndex(caret)) { caret--; } anchor = caret; } // set selection if (SelectionMode == TextDataType.Rectangle) { ClearLineSelectionData(); ViewParam.OriginalAnchorIndex = -1; SetSelection_Rect(anchor, caret, view); } else if (SelectionMode == TextDataType.Line) { ClearRectSelectionData(); ViewParam.OriginalAnchorIndex = -1; SetSelection_Line(anchor, caret, view); } else if (SelectionMode == TextDataType.Words) { ClearLineSelectionData(); ClearRectSelectionData(); SetSelection_Words(anchor, caret); } else { ClearLineSelectionData(); ClearRectSelectionData(); ViewParam.OriginalAnchorIndex = -1; SetSelection_Normal(anchor, caret); } }