| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619 |
- using ICSharpCode.AvalonEdit.CodeCompletion;
- using ICSharpCode.AvalonEdit.Document;
- using ICSharpCode.AvalonEdit.Editing;
- using ICSharpCode.AvalonEdit.Folding;
- using Microsoft.Win32;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.Windows.Threading;
- using TeamAAS_VP.Core;
- using TeamAAS_VP.Models;
- using TeamAAS_VP.ViewModels.DebugMod;
- using Prism.Commands;
- using TeamAAS_VP;
- using TeamAAS_VP.Resources.Languages;
- namespace TeamAAS_VP.Controls
- {
- /// <summary>
- /// ScriptEditControl.xaml 的交互逻辑
- /// </summary>
- public partial class ScriptEditControl : UserControl
- {
- /// <summary>
- /// 当前app的所有程序集中的类
- /// </summary>
- Dictionary<string, Type> ClassMemberlist = new Dictionary<string, Type>();
- #region 属性
- private double _fontSize = 14;
- public double FontSize
- {
- get { return _fontSize; }
- set { _fontSize = value;
- this.textEditor.FontSize = value;
- }
- }
- private TextDocument _document = new TextDocument();
- public TextDocument Document
- {
- get { return _document; }
- set { _document = value;
- }
- }
- private TextArea _mTextArea;
- public TextArea mTextArea
- {
- get { return _mTextArea; }
- set { _mTextArea = value; }
- }
- private ObservableCollection<ScriptCompileMessage> _CompileMessageList = new ObservableCollection<ScriptCompileMessage>();
- public ObservableCollection<ScriptCompileMessage> CompileMessageList
- {
- get { return _CompileMessageList; }
- set {
- _CompileMessageList = value;
- this.messagelist.ItemsSource = value;
- }
- }
- private bool _IsCompile = true;
- public bool IsCompile
- {
- get { return _IsCompile; }
- set { _IsCompile = value;
- this.Dispatcher.Invoke(new Action(() => {
- this.btn1.IsEnabled = value;
- this.btn2.IsEnabled = value;
- this.btn3.IsEnabled = value;
- this.btn4.IsEnabled = value;
- this.btn5.IsEnabled = value;
- this.btn6.IsEnabled = value;
- this.btn7.IsEnabled = value;
- this.btn8.IsEnabled = value;
- this.btn9.IsEnabled = value;
- this.btn10.IsEnabled = value;
- this.btn11.IsEnabled = value;
- this.btn12.IsEnabled = value;
- this.btnShowEndOfLine.IsEnabled= value;
- this.btnShowLineNumbers.IsEnabled= value;
- this.btnWordWrap.IsEnabled= value;
- this.textEditor.IsEnabled= value;
- }));
- }
- }
- [Bindable(true)]
- [Category("Common")]
- [DefaultValue("")]
- public string Text
- {
- get { return (string)GetValue(TextProperty); }
- set { SetValue(TextProperty, value);
- }
- }
- // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty TextProperty =
- DependencyProperty.Register("Text", typeof(string), typeof(ScriptEditControl), new PropertyMetadata(default(string),new PropertyChangedCallback(OnValueChanged)));
-
- private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is ScriptEditControl control)
- {
- if (e.NewValue!=e.OldValue)
- {
- if (!control.isWrite)
- {
- control.textEditor.Document.Text = (string)e.NewValue;
- }
-
- }
- }
- }
- [Bindable(true)]
- [Category("Common")]
- [DefaultValue("")]
- public string ScriptPath
- {
- get { return (string)GetValue(ScriptPathProperty); }
- set { SetValue(ScriptPathProperty, value); }
- }
- // Using a DependencyProperty as the backing store for ScriptPath. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ScriptPathProperty =
- DependencyProperty.Register("ScriptPath", typeof(string), typeof(ScriptEditControl), new PropertyMetadata(default(string), new PropertyChangedCallback(OnPathChanged)));
- private static void OnPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is ScriptEditControl control)
- {
- if (e.NewValue != e.OldValue)
- {
-
- }
- }
- }
- [Bindable(true)]
- [Category("Common")]
- [DefaultValue("")]
- public string CompileType
- {
- get { return (string)GetValue(CompileTypeProperty); }
- set { SetValue(CompileTypeProperty, value); }
- }
- // Using a DependencyProperty as the backing store for CompileType. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CompileTypeProperty =
- DependencyProperty.Register("CompileType", typeof(string), typeof(ScriptEditControl), new PropertyMetadata(default(string)));
- #endregion
- #region 命令
- #endregion
- #region 事件
- public static readonly RoutedEvent SaveScriptEvent=EventManager.RegisterRoutedEvent("OnSaveScript", RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(ScriptEditControl));
- public event RoutedEventHandler OnSaveScript
- {
- add { AddHandler(SaveScriptEvent, value);}
- remove { RemoveHandler(SaveScriptEvent, value);}
- }
- #endregion
- public ScriptEditControl()
- {
- InitializeComponent();
- this.Loaded += ScriptEditControl_Loaded;
- this.textEditor.PreviewMouseWheel += TextEditor_PreviewMouseWheel;
- this.messagelist.SelectionChanged += Messagelist_SelectionChanged;
- this.textEditor.Document = Document;
- this.textEditor.Document.TextChanged += Document_TextChanged;
- this.messagelist.ItemsSource= new ObservableCollection<ScriptCompileMessage>();
- }
- bool isWrite = false;
- private void Document_TextChanged(object sender, EventArgs e)
- {
- isWrite = true;
- Text = this.textEditor.Document.Text;
- isWrite = false;
- }
- #region 方法
- bool isFirst=true;
- private async void ScriptEditControl_Loaded(object sender, RoutedEventArgs e)
- {
- if (isFirst)
- {
- textEditor.Options.HighlightCurrentLine = true;
- mTextArea = textEditor.TextArea;
- textEditor.TextArea.TextEntering += TextArea_TextEntering;
- textEditor.TextArea.TextEntered += TextArea_TextEntered;
- //textEditor.PreviewMouseWheel += vm.TextEditor_PreviewMouseWheel;
- ICSharpCode.AvalonEdit.Search.SearchPanel.Install(textEditor);
- foldingManager = FoldingManager.Install(textEditor.TextArea);
- foldingStrategy = new BraceFoldingStrategy();
- DispatcherTimer foldingUpdateTimer = new DispatcherTimer();
- foldingUpdateTimer.Interval = TimeSpan.FromSeconds(2);
- foldingUpdateTimer.Tick += delegate { UpdateFoldings(); };
- foldingUpdateTimer.Start();
- await Task.Run(() =>
- {
- try
- {
- var cc = GetTypesInNamespace(Assembly.GetExecutingAssembly(), "TeamAAS_VP");
- foreach (var item in GetTypesInNamespace(Assembly.GetExecutingAssembly(), "TeamAAS_VP"))
- {
- if (!item.IsPublic)
- {
- continue;
- }
- ClassMemberlist.Add(item.Name, item);
- }
- //获取当前应用域中加载的所有程序集数组
- Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
- foreach (var item in assemblies)
- {
- try
- {
- foreach (var item1 in GetTypesInNamespace(Assembly.Load(item.FullName)))
- {
- if (!item1.IsPublic)
- {
- continue;
- }
- ClassMemberlist.Add(item1.Name, item1);
- }
- }
- catch (Exception)
- {
- }
- }
- }
- catch (Exception)
- {
- }
- });
- isFirst = false;
- }
- }
- /// <summary>
- /// 打开脚本文件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- OpenFileDialog dlg = new OpenFileDialog();
- dlg.Title = Lang.打开脚本;
- dlg.Filter = $"{Lang.脚本文件}|*.cs|{Lang.所有文件}.*|*.*";
- dlg.CheckFileExists = true;
- if (dlg.ShowDialog() ?? false)
- {
- this.textEditor.Document.Text = FileHelper.ReadFile(dlg.FileName);
- }
- }
- catch (Exception)
- {
- }
- }
- /// <summary>
- /// 保存脚本
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Button_Click_1(object sender, RoutedEventArgs e)
- {
- try
- {
- if (string.IsNullOrEmpty(ScriptPath))
- {
- return;
- }
- FileHelper.WriteFile(this.textEditor.Document.Text, ScriptPath);
- RoutedEventArgs args = new RoutedEventArgs(ScriptEditControl.SaveScriptEvent, Text);
- RaiseEvent(args);
- MessageBox.Show("Succed!");
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogError("保存脚本文件时出错",ex);
- MessageBox.Show(ex.Message);
- }
- }
- /// <summary>
- /// 另存为
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Button_Click_2(object sender, RoutedEventArgs e)
- {
- try
- {
- SaveFileDialog dlg = new SaveFileDialog();
- dlg.Title = $"{Lang.保存脚本}";
- dlg.DefaultExt = ".cs";
- dlg.Filter = $"C# {Lang.文件} (*.cs)|*.cs|{Lang.所有文件} (*.txt)|*.txt|All files (*.*)|*.*";
- if (dlg.ShowDialog() ?? false)
- {
- FileHelper.WriteFile(this.textEditor.Document.Text, dlg.FileName);
- }
- }
- catch (Exception)
- {
- }
- }
- /// <summary>
- /// 字体放大
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Button_Click_3(object sender, RoutedEventArgs e)
- {
- if (FontSize < 50)
- {
- FontSize += 1;
- }
- }
- /// <summary>
- /// 字体缩小
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Button_Click_4(object sender, RoutedEventArgs e)
- {
- if (FontSize > 1)
- FontSize -= 1;
- }
- /// <summary>
- /// 编译
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private async void Button_Click_5(object sender, RoutedEventArgs e)
- {
- IsCompile = false;
- CompileMessageList.Clear();
- this.messagelist.ItemsSource = CompileMessageList;
- CompileMessageList.Add(new ScriptCompileMessage() { DT = DateTime.Now, Kind = MaterialDesignThemes.Wpf.PackIconKind.InformationSlabCircleOutline, FontColol = new SolidColorBrush(Colors.Black), Message = "开始编译...!" });
- if (!string.IsNullOrEmpty(CompileType) && CompileType== "VisionScripting")
- {
- var rst = await ScriptHelper.CompileVisionScriptingAsync(this.textEditor.Document.Text,null,null,null,null,null,null);
- if (rst.Item1)
- {
- CompileMessageList.Add(new ScriptCompileMessage() { DT = DateTime.Now, Kind = MaterialDesignThemes.Wpf.PackIconKind.CheckCircle, FontColol = new SolidColorBrush(Colors.Green), Message = "编译完成!" });
- //rst.Item3.Invoke(rst.Item4,null);
- }
- else
- {
- foreach (var item in rst.Item2)
- {
- CompileMessageList.Add(new ScriptCompileMessage() { DT = DateTime.Now, Kind = MaterialDesignThemes.Wpf.PackIconKind.CloseCircle, FontColol = new SolidColorBrush(Colors.Red), Message = item });
- }
- }
- }
- else
- {
- var rst = await ScriptHelper.CompileAsync(this.textEditor.Document.Text, null, null, null);
- if (rst.Item1)
- {
- CompileMessageList.Add(new ScriptCompileMessage() { DT = DateTime.Now, Kind = MaterialDesignThemes.Wpf.PackIconKind.CheckCircle, FontColol = new SolidColorBrush(Colors.Green), Message = "编译完成!" });
- //rst.Item3.Invoke(rst.Item4,null);
- }
- else
- {
- foreach (var item in rst.Item2)
- {
- CompileMessageList.Add(new ScriptCompileMessage() { DT = DateTime.Now, Kind = MaterialDesignThemes.Wpf.PackIconKind.CloseCircle, FontColol = new SolidColorBrush(Colors.Red), Message = item });
- }
- }
- }
-
- this.messagelist.ItemsSource = CompileMessageList;
- IsCompile = true;
- }
- CompletionWindow completionWindow;
- public void TextArea_TextEntered(object sender, System.Windows.Input.TextCompositionEventArgs e)
- {
- if (e.Text == ".")
- {
- //1.获取.前面的字符串
- // 获取当前光标位置
- int caretOffset = mTextArea.Caret.Offset;
- // 获取当前光标位置前面的单词(以空格、标点等作为分隔符)
- TextDocument document = Document;
- int startOffset = Math.Max(0, caretOffset - 1); // 从当前位置的前一个字符开始
- // 找到单词的起始位置
- while (startOffset >= 0 && !char.IsWhiteSpace(document.GetCharAt(startOffset)))
- {
- startOffset--;
- }
- startOffset++; // 回到单词的起始位置
- // 获取单词的文本
- int endOffset = caretOffset - 1;
- // 使用 AvalonEdit 提供的 TextUtilities 获取当前位置前面的单词
- string word = document.GetText(startOffset, endOffset - startOffset);
- //2.检索字符串,并得到对象
- var type = word.GetType();
- foreach (var item in ClassMemberlist)
- {
- if (item.Key.ToLower().Trim(' ') == word.ToLower().Trim(' '))
- {
- type = item.Value;
- break;
- }
- }
- if (type == null)
- return;
- //3.检索对象中所有的属性,字段,事件,方法,并做提示
- // open code completion after the user has pressed dot:
- completionWindow = new CompletionWindow(((ICSharpCode.AvalonEdit.Editing.TextArea)sender));
- // provide AvalonEdit with the data:
- IList<ICompletionData> data = completionWindow.CompletionList.CompletionData;
- System.Reflection.MethodInfo[] methodInfos = type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static);
- System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static); // System.Reflection.BindingFlags.Public| System.Reflection.BindingFlags.Static
- System.Reflection.EventInfo[] eventInfos = type.GetEvents(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static);
- System.Reflection.FieldInfo[] fieldInfos = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static);
- List<String> proposals = new List<string>();
- //遍历字段
- foreach (var item in fieldInfos)
- {
- data.Add(new ScriptCompletionData(item.Name, CoreMemberType.Field));
- }
- //遍历属性
- foreach (var item in propertyInfos)
- {
- data.Add(new ScriptCompletionData(item.Name, CoreMemberType.Property));
- }
- //遍历方法
- foreach (var item in methodInfos)
- {
- if (item.IsSpecialName)
- {
- continue;
- }
- if (item.ToString().Split(' ').Length >= 2)
- {
- data.Add(new ScriptCompletionData(item.ToString().Split(" ".ToCharArray(), 2)[1].Replace(" ", ""), CoreMemberType.Void));
- }
- else
- {
- data.Add(new ScriptCompletionData(item.Name, CoreMemberType.Void));
- }
- }
- //遍历事件
- foreach (var item in eventInfos)
- {
- data.Add(new ScriptCompletionData(item.Name, CoreMemberType.Event));
- }
- completionWindow.Show();
- completionWindow.Closed += delegate {
- completionWindow = null;
- };
- }
- else if (e.Text == "(")
- {
- Document.Insert(mTextArea.Caret.Offset, ")");
- mTextArea.Caret.Offset = mTextArea.Caret.Offset - 1;
- }
- else if (e.Text == "{")
- {
- Document.Insert(mTextArea.Caret.Offset, "}");
- mTextArea.Caret.Offset = mTextArea.Caret.Offset - 1;
- }
- }
- public void TextArea_TextEntering(object sender, System.Windows.Input.TextCompositionEventArgs e)
- {
- if (e.Text.Length > 0 && completionWindow != null)
- {
- if (!char.IsLetterOrDigit(e.Text[0]))
- {
- // Whenever a non-letter is typed while the completion window is open,
- // insert the currently selected element.
- completionWindow.CompletionList.RequestInsertion(e);
- }
- }
- // do not set e.Handled=true - we still want to insert the character that was typed
- }
- /// <summary>
- /// 获取指定命名空间下的所有类
- /// </summary>
- /// <param name="assembly"></param>
- /// <param name="nameSpace"></param>
- /// <returns></returns>
- private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace = null)
- {
- if (nameSpace == null)
- {
- return assembly.GetTypes();
- }
- else
- {
- return assembly.GetTypes();
- //return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
- }
- }
- public void TextEditor_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
- {
- // 检查是否按下了 Ctrl 键
- if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
- {
- // 根据鼠标滚轮方向调整字体大小
- if (e.Delta > 0)
- {
- Button_Click_3(null,null);
- }
- else
- {
- Button_Click_4(null,null);
- }
- // 禁止事件继续传播,防止影响文本编辑器的滚动
- e.Handled = true;
- }
- }
- /// <summary>
- /// 编辑输出信息选中时
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Messagelist_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- ListView listView = sender as ListView;
- ScriptCompileMessage item = listView.SelectedItem as ScriptCompileMessage;
- if (item == null)
- {
- return;
- }
- if (item.Kind != MaterialDesignThemes.Wpf.PackIconKind.CloseCircle)
- {
- return;
- }
- // 正则表达式
- string pattern = @"<script>\((\d+),(\d+)\): error (\w+): (.*)";
- // 匹配正则表达式
- Match match = Regex.Match(item.Message, pattern);
- // 如果匹配成功,提取各个部分
- if (match.Success)
- {
- string fullMatch = match.Groups[0].Value; // 完整匹配结果
- string lineNumber = match.Groups[1].Value; // 行号
- string charNumber = match.Groups[2].Value; // 字符号
- string errorCode = match.Groups[3].Value; // 错误编码
- string errorDescription = match.Groups[4].Value; // 错误信息
- mTextArea.Caret.Line = int.Parse(lineNumber);
- mTextArea.Caret.BringCaretToView();
- }
- }
- #endregion
- #region Folding
- FoldingManager foldingManager;
- object foldingStrategy;
- void UpdateFoldings()
- {
- if (foldingStrategy is BraceFoldingStrategy)
- {
- ((BraceFoldingStrategy)foldingStrategy).UpdateFoldings(foldingManager, textEditor.Document);
- }
- if (foldingStrategy is XmlFoldingStrategy)
- {
- ((XmlFoldingStrategy)foldingStrategy).UpdateFoldings(foldingManager, textEditor.Document);
- }
- }
- #endregion
- }
- }
|