From 4cf1e800a5743d1194281703a4bcd6df0a910e8f Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 7 Dec 2017 15:34:42 +0200 Subject: Added Avalon editor as SideChain. Implemented scripting control in SharedUI.. --- .../Controls/ScriptEditorControl.xaml.cs | 265 +++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs (limited to 'Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs') diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs new file mode 100644 index 000000000..1f9eeb1aa --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/ScriptEditorControl.xaml.cs @@ -0,0 +1,265 @@ +using ICSharpCode.AvalonEdit.CodeCompletion; +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Editing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +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 Tango.SharedUI; + +namespace Tango.SharedUI.Controls +{ + #region Completion + + internal class CompletionData : ICompletionData + { + private String _description; + + public BitmapSource Source { get; set; } + + public CompletionData(string text, String description) + { + this.Text = text; + _description = description; + } + + public System.Windows.Media.ImageSource Image + { + get { return Source; } + } + + public string Text { get; private set; } + + // Use this property if you want to show a fancy UIElement in the drop down list. + public object Content + { + get { return this.Text; } + } + + public object Description + { + get { return _description; } + } + + public double Priority { get { return 0; } } + + public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) + { + textArea.Document.Replace(completionSegment, this.Text); + } + + public override string ToString() + { + return Text; + } + } + + #endregion + + /// + /// Interaction logic for ScriptEditorControl.xaml + /// + public partial class ScriptEditorControl : UserControl + { + private CompletionWindow completionWindow; + public ScriptEditorControl() + { + InitializeComponent(); + + textEditor.TextArea.IndentationStrategy = new ICSharpCode.AvalonEdit.Indentation.CSharp.CSharpIndentationStrategy(); + textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering; + textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered; + } + + private void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e) + { + if (e.Text == ".") + { + String keyword = textEditor.TextArea.GetJustCurrentWord(); + + if (keyword != null) + { + completionWindow = new CompletionWindow(textEditor.TextArea); + completionWindow.WindowStyle = WindowStyle.None; + completionWindow.AllowsTransparency = true; + completionWindow.ResizeMode = ResizeMode.NoResize; + + IList data = completionWindow.CompletionList.CompletionData; + + bool ok = false; + + List> types = new List>(); + + types.Add(new KeyValuePair("Thread", typeof(Thread))); + types.Add(new KeyValuePair("DateTime", typeof(DateTime))); + types.Add(new KeyValuePair("TimeSpan", typeof(TimeSpan))); + types.Add(new KeyValuePair("Dispatcher", typeof(Dispatcher))); + types.Add(new KeyValuePair("Task", typeof(Task))); + types.Add(new KeyValuePair("list", typeof(IList))); + types.Add(new KeyValuePair("int", typeof(Int32))); + types.Add(new KeyValuePair("double", typeof(Double))); + types.Add(new KeyValuePair("String", typeof(String))); + + var type = types.SingleOrDefault(x => x.Key == keyword); + if (type.Key != null) + { + ok = true; + FillType(type.Value, data); + } + + if (ok) + { + completionWindow.Show(); + completionWindow.Closed += delegate + { + completionWindow = null; + }; + } + } + } + } + + private void textEditor_TextArea_TextEntering(object sender, 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); + } + } + } + + private async void btnStart_Click(object sender, RoutedEventArgs e) + { + btnStart.IsEnabled = false; + btnStop.IsEnabled = true; + gridExecuting.Visibility = Visibility.Visible; + //engine = new ScriptEngine(); + //try + //{ + // await engine.Run(CanvasItem, textEditor.Text); + //} + //catch (Exception ex) + //{ + // txtError.Text = ex.Message; + // gridError.Visibility = Visibility.Visible; + //} + + gridExecuting.Visibility = Visibility.Hidden; + btnStart.IsEnabled = true; + btnStop.IsEnabled = false; + } + + private void btnStop_Click(object sender, RoutedEventArgs e) + { + //engine.Stop(); + } + + private void btnOK_Click(object sender, RoutedEventArgs e) + { + gridError.Visibility = Visibility.Hidden; + } + + private void Save(object sender, RoutedEventArgs e) + { + //CanvasItem.Script = textEditor.Text; + } + + private void FillType(Type type, IList data) + { + List items = new List(); + + foreach (var method in type.GetMethods().Where(x => x.IsPublic && !x.IsSpecialName)) + { + String desc = method.ReturnType.Name + " " + method.Name + "(" + String.Join(", ", method.GetParameters().Select(x => x.ParameterType.Name + " " + x.Name).ToArray()) + ")"; + items.Add(new CompletionData(method.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubmethod.gif") }); + } + foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + String desc = property.PropertyType.Name + " " + property.Name; + items.Add(new CompletionData(property.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubproperty.gif") }); + } + foreach (var ev in type.GetEvents(BindingFlags.Instance | BindingFlags.Public)) + { + try + { + String desc = ev.Name + " " + "(" + String.Join(", ", ev.EventHandlerType.GetMethod("Invoke").GetParameters().Select(x => x.ParameterType.Name + " " + x.Name).ToArray()) + ")"; + items.Add(new CompletionData(ev.Name, desc) { Source = ResourceHelper.GetImageFromResources("Images/pubevent.gif") }); + } + catch { } + } + + foreach (var item in items.OrderBy(x => x.Text)) + { + data.Add(item); + } + } + + private void FillAssembly(Assembly asm, IList data) + { + var q = from t in asm.GetTypes() + where t.IsClass + select t; + + foreach (var type in q) + { + data.Add(new CompletionData(type.Name, "Class") { Source = ResourceHelper.GetImageFromResources("Images/pubclass.gif") }); + } + } + + } + + internal static class DocumentUtils + { + private static Regex _wordRegex = new Regex(@"[^\W\d][\w]*(?<=\w)", RegexOptions.Compiled); + + public static string GetJustCurrentWord(this TextArea textArea) + { + try + { + DocumentLine line = textArea.Document.GetLineByNumber(textArea.Caret.Line); + if (line.Length == 0) + return null; + + int lineCaretPosition = textArea.Caret.Offset - line.Offset; + String l = textArea.Document.GetText(line); + + String trimmed = l.Remove(lineCaretPosition, l.Length - lineCaretPosition); + + return SplitToWords(trimmed).LastOrDefault(x => !String.IsNullOrWhiteSpace(x)); + } + catch + { + return null; + } + } + + public static List SplitToWords(String text) + { + text = text.Replace(".", " "); + text = text.Replace("(", " "); + text = text.Replace(")", " "); + text = text.Replace(",", " "); + var punctuation = text.Where(Char.IsPunctuation).Distinct().ToArray(); + var words = text.Split().Select(x => x.Trim(punctuation)); + return words.ToList(); + } + } +} -- cgit v1.3.1