/// <summary> /// 初始化构造函数 /// </summary> /// <param name="name">函数块名称</param> public FuncBlockViewModel(string name, ProjectModel _pmodel) { InitializeComponent(); parent = _pmodel; ProgramName = name; model = new FuncBlockModel(String.Empty); IHighlightingDefinition customHighlighting; Assembly assembly = Assembly.GetExecutingAssembly(); Console.WriteLine(assembly.GetManifestResourceNames()); using (Stream s = assembly.GetManifestResourceStream("SamSoarII.AppMain.Project.CustomHighlighting.xshd")) { if (s == null) { throw new InvalidOperationException("Could not find embedded resource"); } using (XmlReader reader = new XmlTextReader(s)) { customHighlighting = ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader.Load(reader, HighlightingManager.Instance); } } HighlightingManager.Instance.RegisterHighlighting("Custom Highlighting", new string[] { ".cool" }, customHighlighting); CodeTextBox.TextArea.TextEntering += textEditor_TextArea_TextEntering; CodeTextBox.TextArea.TextEntered += textEditer_TextArea_TextEntered; CodeTextBox.TextArea.CodeCompleteKeyDown += textEditer_TextArea_CodeCompleteKeyDown; CodeTextBox.TextArea.CodeCompleteKeyUp += textEditer_TextArea_CodeCompleteKeyUp; CodeTextBox.CaretChanged += textEditer_CaretChanged; CodeTextBox.DocumentChanged_Detail += textEditer_DocumentChanged; DispatcherTimer foldingUpdateTimer = new DispatcherTimer(); foldingUpdateTimer.Interval = TimeSpan.FromSeconds(0.5); foldingUpdateTimer.Tick += foldingUpdateTimer_Tick; foldingUpdateTimer.Start(); foldingManager = FoldingManager.Install(CodeTextBox.TextArea); foldingStrategy = new BraceFoldingStrategy(); foldingStrategy.UpdateFoldings(foldingManager, CodeTextBox.Document); CodeTextBox.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.CSharp.CSharpIndentationStrategy(CodeTextBox.Options); //completionWindow = new CompletionWindow(CodeTextBox.TextArea); completionWindow = null; CCSProfix = String.Empty; ccstblocks = new TextBlock[9]; for (int i = 0; i < 9; i++) { ccstblocks[i] = new TextBlock(); ccstblocks[i].FontFamily = new FontFamily("Consolas"); ccstblocks[i].FontSize = 16; Grid.SetRow(ccstblocks[i], i + 1); Grid.SetColumn(ccstblocks[i], 0); CodeCompletePanel.Children.Add(ccstblocks[i]); } CodeTextBox.TextArea.Caret.VisibleChanged += Caret_VisibleChanged; }
void textEditer_TextArea_TextEntered(object sender, TextCompositionEventArgs e) { int tabhigh = 0; int start, end; string inserttext = String.Empty; string currentline = String.Empty; if (e.Text.Length == 1) { if (model.Current is FuncBlock_Comment) { return; } switch (e.Text[0]) { case '{': tabhigh = Math.Max(0, model.Current.Height - 1); inserttext = new string('\t', tabhigh); inserttext = "\n" + inserttext + "\t\n" + inserttext + "}"; CodeTextBox.Text = CodeTextBox.Text.Insert(CodeTextBox.CaretOffset, inserttext); model = new FuncBlockModel(CodeTextBox.Text); CodeTextBox.CaretOffset += tabhigh + 2; oldTime1 = e.Timestamp; break; case '(': inserttext = ")"; CodeTextBox.Text = CodeTextBox.Text.Insert(CodeTextBox.CaretOffset, inserttext); model.Current.InnerOffset += inserttext.Length; oldTime2 = e.Timestamp; break; case ')': if (oldTime2 > 0 && e.Timestamp - oldTime2 < 100) { CodeTextBox.Text = CodeTextBox.Text.Remove(CodeTextBox.CaretOffset-- - 1, 1); } break; case '}': if (oldTime1 > 0 && e.Timestamp - oldTime1 < 100) { CodeTextBox.Text = CodeTextBox.Text.Remove(CodeTextBox.CaretOffset-- - 1, 1); } break; case ';': break; case '/': case '*': end = CodeTextBox.CaretOffset - 1; start = end - 1; if (start >= 0 && CodeTextBox.Text[start] == '/' && CodeTextBox.Text[end] == '/') { model = new FuncBlockModel(CodeTextBox.Text); model.Move(CodeTextBox.CaretOffset); break; } if (start >= 0 && CodeTextBox.Text[start] == '/' && CodeTextBox.Text[end] == '*') { tabhigh = model.Current.Height; inserttext = new string('\t', tabhigh); inserttext = "\n" + inserttext + " *\n" + inserttext + " */"; CodeTextBox.Text = CodeTextBox.Text.Insert(CodeTextBox.CaretOffset, inserttext); CodeTextBox.CaretOffset += tabhigh + 3; model = new FuncBlockModel(CodeTextBox.Text); model.Move(CodeTextBox.CaretOffset); } break; case '\n': if (model.Current is FuncBlock_CommentParagraph) { tabhigh = model.Current.Height; inserttext = new string('\t', tabhigh); inserttext += " *"; CodeTextBox.Text = CodeTextBox.Text.Insert(CodeTextBox.CaretOffset, inserttext); CodeTextBox.CaretOffset += inserttext.Length; } model.Move(CodeTextBox.CaretOffset); break; default: break; } } IsModify = true; //OutputDebug(); }
/// <summary> /// 当代码内容改变时发生 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void textEditer_DocumentChanged(object sender, DocumentChangeEventArgs e) { int offset = e.InsertionLength - e.RemovalLength; model.Move(e.Offset); Regex localRegex = new Regex(@"[\{\}]"); Regex stmtRegex = new Regex(@";"); Regex blankRegex = new Regex(@"^\s*$"); Match insertMatch1 = localRegex.Match(e.InsertedText); Match removeMatch1 = localRegex.Match(e.RemovedText); Match insertMatch2 = stmtRegex.Match(e.InsertedText); Match removeMatch2 = stmtRegex.Match(e.RemovedText); Match insertMatch3 = blankRegex.Match(e.InsertedText); Match removeMatch3 = blankRegex.Match(e.RemovedText); int start = 0; int end = 0; if (model.Current is FuncBlock_Comment) { FuncBlock _parent = model.Current.Parent; start = _parent.IndexStart; end = _parent.IndexEnd - 1; while (end < CodeTextBox.Text.Length && CodeTextBox.Text[end] != '\n') { end++; } _parent.Build(CodeTextBox.Text, start, end, offset); } else if (insertMatch3.Success && removeMatch3.Success) { model.Current.InnerOffset += offset; } else if (insertMatch1.Success || removeMatch1.Success) { model = new FuncBlockModel(CodeTextBox.Text); model.Move(e.Offset); } else { if (model.Current is FuncBlock_FuncHeader) { model.CurrentNode = new LinkedListNode <FuncBlock>(model.Root); } if (model.Current is FuncBlock_Root) { LinkedListNode <FuncBlock> nprev = null; LinkedListNode <FuncBlock> nnext = null; if (model.Current.Current != null) { nprev = model.Current.Current; if (model.Current.Current.Next != null) { nnext = model.Current.Current.Next; } } if (nprev != null && nprev.Value.IndexStart > e.Offset) { nnext = nprev; nprev = nprev.Previous; } while (nprev != null && !(nprev.Value is FuncBlock_Local)) { nprev = nprev.Previous; } while (nnext != null && !(nnext.Value is FuncBlock_Local)) { nnext = nnext.Next; } start = nprev != null ? (nprev.Value.IndexEnd + 1) : (model.Current.IndexStart); end = nnext != null ? (nnext.Value.IndexStart - 2) : (model.Current.IndexEnd - 1); model.Root.Build(CodeTextBox.Text, start, end, offset); } else if (insertMatch2.Success || removeMatch2.Success) { start = model.Current.IndexStart; if (model.Current is FuncBlock_Local) { end = model.Current.IndexEnd; model.Current.Build(CodeTextBox.Text, start, end - 1, offset); } else if (model.Current.Parent is FuncBlock_Local) { end = model.Current.Parent.IndexEnd; model.Current.Parent.Build(CodeTextBox.Text, start, end - 1, offset); } else { throw new Exception(String.Format("Code Structure Error : {0:s} in {1:s}", model.Current.ToString(), model.Current.Parent.ToString())); } } else { if (model.Current is FuncBlock_Local) { start = model.Current.IndexStart; end = model.Current.IndexEnd - 1; model.Current.Build(CodeTextBox.Text, start, end, offset); } else { start = model.Current.IndexStart; end = model.Current.IndexEnd; model.Current.Parent.Build(CodeTextBox.Text, start, end, offset); } } } model.Move(e.Offset); if (e.InsertionLength == 1 && e.RemovalLength == 0) { if (char.IsLetterOrDigit(e.InsertedText[0]) || e.InsertedText[0] == '_') { int wordend = CodeTextBox.CaretOffset - 1; int wordstart = wordend; while (wordstart >= 0 && (Char.IsLetterOrDigit(CodeTextBox.Text[wordstart]) || CodeTextBox.Text[wordstart] == '_')) { wordstart--; } while (wordend < CodeTextBox.Text.Length && (Char.IsLetterOrDigit(CodeTextBox.Text[wordend]) || CodeTextBox.Text[wordend] == '_')) { wordend++; } wordstart++; wordend--; CCSOffset = wordstart; CCSProfix = CodeTextBox.Text.Substring(wordstart, wordend - wordstart + 1); CCSProfixCursor = CodeTextBox.CaretOffset - wordstart; } else if (e.InsertedText[0] != '\n') { CCSProfix = String.Empty; } } else if (e.InsertionLength == 0 && e.RemovalLength == 1) { if (CCSProfix.Length > 0 && CCSProfixCursor > 0) { CCSProfix = CCSProfix.Remove(CCSProfixCursor - 1, 1); CCSProfixCursor--; } } else { CCSProfix = String.Empty; } TextChanged(this, new RoutedEventArgs()); SetXY(CodeTextBox.TextArea.Caret.Column, CodeTextBox.TextArea.Caret.Line); IsModify = true; //OutputDebug(); }