/// <summary> /// 处理鼠标移动事件,包括拖动与选择的处理 /// </summary> /// <param name="sender">事件发送者</param> /// <param name="e">事件参数</param> private void TextCtrl_MouseMove(object sender, MouseEventArgs e) { if (isDragging) { Point mouseAbsPos = e.Location + viewAbsolutePos; if (selections.Find((Rectangle rect) => rect.Contains(mouseAbsPos)) == NULL) { if (ctrlState) { Cursor = Cursors.Hand; } else { Cursor = Cursors.Arrow; } if (showLineNum) { if (e.X > lineNumWidth) { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X - lineNumWidth, e.Y)); } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(0, e.Y)); } } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X, e.Y)); } ValidateCaretPos(); UpdateCaretPos(); } else { Cursor = Cursors.No; } } else if (mouseDown) { if (showLineNum) { if (e.X > lineNumWidth) { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X - lineNumWidth, e.Y)); } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(0, e.Y)); } } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X, e.Y)); } ValidateCaretPos(); selectionEndPos = cursorRelativePos + viewAbsolutePos; UpdateSelection(); } }
private void btnSearch_Click(object sender, EventArgs e) { CPosition result = new CPosition(), result2 = result, tmp; if (txtPattern.Text.Length > 0) { tmp = txt.CursorAbsolutePosition; //int[] sizes = txt.GetLineLengths(); //while (sizes[tmp.y] == tmp.x) //{ // if (tmp.y == sizes.Length - 1) // { // tmp.x = tmp.y = 0; // break; // } // tmp.y++; //} MatchPattern(txtPattern.Text, ref tmp, ref result, ref result2); if (result.x < 0) { MessageBox.Show("找不到匹配的字符串!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { txt.ScrollToAndSelect(result, result2); } } }
/// <summary> /// 滚动到指定位置并选择文段 /// </summary> /// <param name="start">选区起点</param> /// <param name="end">选区终点</param> public void ScrollToAndSelect(CPosition start, CPosition end) { ScrollTo(end); selectionStartPos = start; selectionEndPos = end; UpdateSelection(); }
private void UpdateCaretPos() { CPosition tmp = GetExactCoordOfPos(cursorRelativePos); myCaret.Top = tmp.y; myCaret.Left = tmp.x; }
private void btnReplace_Click(object sender, EventArgs e) { CPosition result = new CPosition(), result2 = result, tmp; if (txtPattern.Text.Length > 0) { tmp = txt.CursorAbsolutePosition; int[] sizes = txt.GetLineLengths(); while (sizes[tmp.y] == tmp.x) { if (tmp.y == sizes.Length - 1) { tmp.x = tmp.y = 0; break; } tmp.y++; } MatchPattern(txtPattern.Text, ref tmp, ref result, ref result2); if (result.x < 0) { MessageBox.Show("找不到匹配的字符串!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { CoreMethods.Replace(txtReplace.Text, ref result, ref result2, ref tmp); txt.UpdateText(); txt.ScrollTo(tmp); } } }
/// <summary> /// 滚动到指定位置 /// </summary> /// <param name="pos">滚动到的位置</param> public void ScrollTo(CPosition pos) { CPosition rel = pos - viewAbsolutePos; if (rel.x >= 0 && rel.y >= 0 && rel.x <= txtFieldSize.Width && rel.y < txtFieldSize.Height) { cursorRelativePos = rel; UpdateCaretPos(); return; } cursorRelativePos.x = pos.x; cursorRelativePos.y = pos.y; viewAbsolutePos.x = 0; viewAbsolutePos.y = 0; ValidateCaretPos(); if (viewAbsolutePos.x + txtFieldSize.Width > lineMaxLen) { viewAbsolutePos.x = lineMaxLen - txtFieldSize.Width; if (viewAbsolutePos.x < 0) { viewAbsolutePos.x = 0; } Invalidate(); } UpdateCaretPos(); if (LineChange != null) { LineChange(this); } }
private void mnuBracketMatch_Click(object sender, EventArgs e) { CPosition inPos = txtMain.CursorAbsolutePosition, outPos = new CPosition(); CoreMethods.MatchBracket(ref inPos, ref outPos); if (outPos.x > 0) { txtMain.ScrollToAndSelect(outPos, outPos + new CPosition(1, 0)); } }
/// <summary> /// 处理鼠标释放事件,包括拖放结束处理和选中的处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TextCtrl_MouseUp(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { return; } if (selectionStartPos > selectionEndPos) { CPosition tmp = selectionEndPos; selectionEndPos = selectionStartPos; selectionStartPos = tmp; } if (isDragging) { Point mouseAbsPos = e.Location + viewAbsolutePos; if (selections.Find((Rectangle rect) => rect.Contains(mouseAbsPos)) == NULL) { if (showLineNum) { if (e.X > lineNumWidth) { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X - lineNumWidth, e.Y)); } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(0, e.Y)); } } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X, e.Y)); } ValidateCaretPos(); CPosition pos = cursorRelativePos + viewAbsolutePos; if (!CoreMethods.Drag(ref selectionStartPos, ref selectionEndPos, ref pos, !ctrlState)) { if (DebugMsgSend != null) { DebugMsgSend("::Drag failed!"); } } UpdateText(); ScrollTo(pos); isSelecting = false; } isDragging = false; Cursor = Cursors.IBeam; } mouseDown = false; if (!isSelecting) { ClearSelection(); Invalidate(); } }
/// <summary> /// 处理鼠标按下事件,包括拖动与选择的处理 /// </summary> /// <param name="sender">事件发送者</param> /// <param name="e">事件参数</param> private void TextCtrl_MouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { return; } if (isSelecting) { CPosition mousePos; if (showLineNum) { if (e.X > lineNumWidth) { mousePos = new CPosition(e.X - lineNumWidth, e.Y); } else { mousePos = new CPosition(0, e.Y); } } else { mousePos = new CPosition(e.X, e.Y); } if (selections.Find((Rectangle rect) => rect.Contains(mousePos)) != NULL) { isDragging = true; return; } else { isDragging = false; } } mouseDown = true; isSelecting = false; if (showLineNum) { if (e.X > lineNumWidth) { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X - lineNumWidth, e.Y)); } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(0, e.Y)); } } else { cursorRelativePos = GetCharPosOfCoord(new CPosition(e.X, e.Y)); } ValidateCaretPos(); selectionStartPos = cursorRelativePos + viewAbsolutePos; UpdateCaretPos(); }
/// <summary> /// 调用核心模块开始匹配算法 /// </summary> /// <param name="pattern">匹配模版</param> /// <param name="pos">起始位置</param> /// <param name="resultB">找到字串的起始点</param> /// <param name="resultE">找到字串的终止点</param> private void MatchPattern(string pattern, ref CPosition pos, ref CPosition resultB, ref CPosition resultE) { if (radbtnBM.Checked) { CoreMethods.Search(pattern, ref pos, ref resultB, ref resultE); } else { CoreMethods.KMPSearch(pattern, ref pos, ref resultB, ref resultE); } }
public TextCtrl() { selectionColor = Color.LightCoral; isDragging = false; lastKeyHandled = false; ctrlState = false; mouseDown = false; isSelecting = false; charWidthUpdated = false; showLineNum = false; charWidth = 8; charHeight = 15; lineNumWidth = 50; texts = new char[][] { new char[] {} }; sizes = new int[] { 0 }; lineNums = new int[] { 0 }; pointers = new IntPtr[] { Marshal.UnsafeAddrOfPinnedArrayElement(texts[0], 0) }; styles = new List <List <CharStyle> >(); selections = new List <Rectangle>(); //int i; //if (File.Exists("test.txt")) // using (StreamReader sr = new StreamReader(new FileStream("test.txt", FileMode.Open))) // while (!sr.EndOfStream) // { // string tmp = sr.ReadLine(); // texts.Add(tmp); // styles.Add(new List<CharStyle>()); // List<CharStyle> lst = styles[styles.Count - 1]; // for (i = 0; i < tmp.Length; i++) // lst.Add(new CharStyle(Color.Black, Color.White)); // if (tmp.Length > lineMaxLen) // lineMaxLen = tmp.Length; // } cursorRelativePos = new CPosition(); viewAbsolutePos = new CPosition(); currFormat = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox); SetStyle(ControlStyles.Selectable, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); InitializeComponent(); myCaret.Visible = false; UpdateCaretPos(); }
/// <summary> /// 处理输入键按下的事件,即输入字符的事件 /// </summary> /// <param name="sender">事件发送者</param> /// <param name="e">事件参数</param> private void TextCtrl_KeyPress(object sender, KeyPressEventArgs e) { if (lastKeyHandled) { return; } if (isSelecting) { if (!CoreMethods.Remove(ref selectionStartPos, ref selectionEndPos)) { if (DebugMsgSend != null) { DebugMsgSend("::Remove failed!"); } } ScrollTo(selectionStartPos); ClearSelection(); } CPosition tmp = cursorRelativePos + viewAbsolutePos; if (e.KeyChar == 13) { e.KeyChar = (char)10; } if (!CoreMethods.InsertC(ref tmp, e.KeyChar)) { if (DebugMsgSend != null) { DebugMsgSend("::InsertChar failed!"); } } UpdateText(); UpdateScrollBars(); if (e.KeyChar == '\t') { cursorRelativePos.x += 4; UpdateCaretPos(); } else { CaretStep(true); } }
public TextCtrl() { texts = new List <string>(new string[] { "Hi! I'm a pig", "I goes ghrr..", "MWAHAHA~", "haha", "hah", "ha", "h", "...", "hey! Can't you say something?", "Oh well...", "well..", "well.", "HELL", "Hi! I'm a pig", "I goes ghrr..", "MWAHAHA~", "haha", "hah", "ha", "h", "...", "hey! Can't you say something?", }); lineMaxLen = 30; cursorRelativePos = new CPosition(); viewAbsolutePos = new CPosition(); currFont = SystemFonts.DefaultFont; SetStyle(ControlStyles.Selectable, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); InitializeComponent(); myCaret.Visible = false; UpdateCaretPos(); }
/// <summary> /// 在选择区域组中添加一个矩形选区。 /// </summary> /// <param name="start">选区开始处的相对坐标</param> /// <param name="end">选区结束处的相对坐标</param> /// <returns>矩形中的字串长度</returns> private int AddRectangle(CPosition start, CPosition end) { if (start == end) { return(0); } int result = end.x - start.x; start = GetExactCoordOfPos(start); end.y++; end = GetExactCoordOfPos(end); if (showLineNum) { selections.Add(new Rectangle(start + new CPosition(lineNumWidth, 0), end - start)); } else { selections.Add(new Rectangle(start, end - start)); } return(result); }
/// <summary> /// 粘贴选区 /// </summary> public void Paste() { if (isSelecting) { if (!CoreMethods.Remove(ref selectionStartPos, ref selectionEndPos)) { if (DebugMsgSend != null) { DebugMsgSend("::Remove failed!"); } } } if (!Clipboard.ContainsText()) { SystemSounds.Beep.Play(); return; } CPosition tmp = cursorRelativePos + viewAbsolutePos, endPos = new CPosition(); CoreMethods.InsertS(ref tmp, Clipboard.GetText(), ref endPos); UpdateText(); ScrollTo(endPos); }
internal static extern bool Remove(ref CPosition start, ref CPosition end);
internal static extern bool Backspace(ref CPosition pos);
internal static extern bool InsertC(ref CPosition pos, char chr);
internal static extern bool Drag(ref CPosition start, ref CPosition end, ref CPosition target, bool isMove);
internal static extern void InsertS(ref CPosition pos, string str, ref CPosition endPos);
/// <summary> /// 从实际坐标转为字符坐标 /// </summary> /// <param name="relativeCoord">实际坐标</param> /// <returns>字符坐标</returns> internal CPosition GetCharPosOfCoord(CPosition relativeCoord) { return(new CPosition((int)((relativeCoord.x - 1.0) / charWidth + 0.5), relativeCoord.y / charHeight)); }
internal CPosition GetExactCoordOfPos(CPosition relativePos) { return(new CPosition(relativePos.x * 9, relativePos.y * 15)); }
internal static extern void Replace(string target, ref CPosition start, ref CPosition end, ref CPosition endPos);
internal static extern void MatchBracket(ref CPosition inpos, ref CPosition outpos);
internal static extern void KMPSearch(string pattern, ref CPosition pos, ref CPosition resultS, ref CPosition resultE);
/// <summary> /// 处理控制键按下的事件,包括功能键、删除键、编辑键的功能实现 /// </summary> /// <param name="sender">事件触发者</param> /// <param name="e">事件参数</param> private void TextCtrl_KeyDown(object sender, KeyEventArgs e) { lastKeyHandled = true; if (e.KeyCode == Keys.Up) { cursorRelativePos.y--; if (!ValidateCaretPos()) { SystemSounds.Beep.Play(); } UpdateCaretPos(); ArrowKeyEndProc(); } else if (e.KeyCode == Keys.Down) { cursorRelativePos.y++; if (!ValidateCaretPos()) { SystemSounds.Beep.Play(); } UpdateCaretPos(); ArrowKeyEndProc(); } else if (e.KeyCode == Keys.Left) { CaretStep(false); } else if (e.KeyCode == Keys.Right) { CaretStep(true); } else if (e.KeyCode == Keys.Home) { cursorRelativePos.x = viewAbsolutePos.x = 0; ValidateCaretPos(); UpdateCaretPos(); Invalidate(); } else if (e.KeyCode == Keys.End) { viewAbsolutePos.x = 0; cursorRelativePos.x = lineMaxLen; ValidateCaretPos(); UpdateCaretPos(); Invalidate(); } else if (e.KeyCode == Keys.PageUp) { cursorRelativePos.y -= txtFieldSize.Height; ValidateCaretPos(); UpdateCaretPos(); Invalidate(); } else if (e.KeyCode == Keys.PageDown) { cursorRelativePos.y += txtFieldSize.Height; ValidateCaretPos(); UpdateCaretPos(); Invalidate(); } else if (e.KeyCode == Keys.C && e.Control) { CopySelection(); } else if (e.KeyCode == Keys.V && e.Control) { Paste(); } else if (e.KeyCode == Keys.F && e.Control) { RequestFind(this); } else if (e.KeyCode == Keys.S && e.Control) { SaveFile(); } else if (e.KeyCode == Keys.A && e.Control) { selectionStartPos.x = selectionStartPos.y = 0; selectionEndPos.y = texts.Length - 1; selectionEndPos.x = sizes[texts.Length - 1]; isSelecting = true; UpdateSelection(); } else if (e.KeyCode == Keys.D && e.Control) { CoreMethods.RemoveLine(cursorRelativePos.y + viewAbsolutePos.y); UpdateText(); ValidateCaretPos(); UpdateCaretPos(); } else if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete) { if (isSelecting) { if (!CoreMethods.Remove(ref selectionStartPos, ref selectionEndPos)) { if (DebugMsgSend != null) { DebugMsgSend("::Remove failed!"); } } ScrollTo(selectionStartPos); ClearSelection(); UpdateText(); } else { if (e.KeyCode == Keys.Delete && !CaretStep(true, true)) { return; } CPosition tmp = cursorRelativePos + viewAbsolutePos; if (!CoreMethods.Backspace(ref tmp)) { if (DebugMsgSend != null) { DebugMsgSend("::Backspace failed!"); } } CaretStep(false, true); tmp = cursorRelativePos + viewAbsolutePos; UpdateText(); UpdateScrollBars(); cursorRelativePos = tmp - viewAbsolutePos; ValidateCaretPos(); UpdateCaretPos(); } } else { lastKeyHandled = false; } ctrlState = e.Control; }
internal static extern void GetSelection(ref CPosition start, ref CPosition end, [MarshalAs(UnmanagedType.LPStr)] StringBuilder result); // 转换托管类型为非托管
/// <summary> /// 从字符位置转为实际坐标 /// </summary> /// <param name="relativePos">相对字符坐标</param> /// <returns>实际坐标</returns> internal CPosition GetExactCoordOfPos(CPosition relativePos) { return(new CPosition((int)(relativePos.x * charWidth + 1), relativePos.y * charHeight)); }