4using System.Threading.Tasks;
6using System.Xml.Schema;
9using System.Windows.Controls;
10using System.Windows.Documents;
11using System.Windows.Input;
12using System.Windows.Markup;
13using System.Windows.Media;
14using System.Windows.Media.Imaging;
45 ConsoleOut =
new Script.PrintOutput(
this)
51 private void Input_PreviewKeyDown(
object Sender, KeyEventArgs e)
53 if (e.Key == Key.Enter)
55 if (!Keyboard.Modifiers.HasFlag(ModifierKeys.Control) && !Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
57 this.ExecuteButton_Click(Sender, e);
63 private void ExecuteButton_Click(
object Sender, RoutedEventArgs e)
66 TextBlock ScriptBlock;
67 UIElement ResultBlock =
null;
73 ScriptBlock =
new TextBlock()
75 Text = this.Input.Text,
76 FontFamily =
new FontFamily(
"Courier New"),
77 TextWrapping = TextWrapping.Wrap,
81 ScriptBlock.PreviewMouseDown += this.TextBlock_PreviewMouseDown;
83 this.HistoryPanel.Children.Add(ScriptBlock);
84 this.HistoryScrollViewer.ScrollToBottom();
86 this.Input.Text =
string.Empty;
92 MessageBox.Show(
MainWindow.currentInstance, ex.Message,
"Unable to parse script.", MessageBoxButton.OK, MessageBoxImage.Error);
104 this.Dispatcher.Invoke(async () =>
105 ResultBlock = await this.ShowResult(ResultBlock, e2.
Preview, ScriptBlock));
107 return Task.CompletedTask;
110 this.variables.OnPreview += Preview;
113 Ans = await Exp.
Root.EvaluateAsync(this.variables);
125 this.variables.OnPreview -= Preview;
128 this.variables[
"Ans"] = Ans;
132 ResultBlock = await this.ShowResult(ResultBlock, Ans, ScriptBlock);
138 MainWindow.MessageBox(ex.Message,
"Unable to parse script.", MessageBoxButton.OK, MessageBoxImage.Error);
143 private async Task<UIElement> ShowResult(UIElement ResultBlock,
IElement Ans, TextBlock ScriptBlock)
149 PixelInformation Pixels = G.CreatePixels(this.variables, out
object[] States);
150 return this.AddImageBlock(ScriptBlock, Pixels, G, States, ResultBlock);
156 UIElement Last = ResultBlock ?? ScriptBlock;
160 if (ex is AggregateException ex2)
162 foreach (Exception ex3
in ex2.InnerExceptions)
163 Last = this.AddTextBlock(Last, ex3.Message, Colors.Red, FontWeights.Bold,
null, ex3);
166 Last = this.AddTextBlock(ScriptBlock, ex.Message, Colors.Red, FontWeights.Bold, ResultBlock, ex);
172 StringBuilder Markdown =
new StringBuilder();
174 foreach (
string s2
in M.ColumnNames)
176 Markdown.Append(
"| ");
180 Markdown.AppendLine(
" |");
182 foreach (
string s2
in M.ColumnNames)
183 Markdown.Append(
"|---");
185 Markdown.AppendLine(
"|");
189 for (y = 0; y < M.Rows; y++)
191 for (x = 0; x < M.Columns; x++)
193 Markdown.Append(
"| ");
195 object Item = M.GetElement(x, y).AssociatedObjectValue;
198 if (!(Item is
string s2))
201 s2 = s2.Replace(
"\r\n",
"\n").Replace(
"\r",
"\n").Replace(
"\n",
"<br/>");
206 Markdown.AppendLine(
" |");
210 string XAML = await Doc.GenerateXAML(
ChatView.GetXamlSettings());
212 if (XamlReader.Parse(XAML) is UIElement Parsed)
213 return this.AddBlock(ScriptBlock, Parsed);
218 return this.AddTextBlock(ScriptBlock, Ans.ToString(), Colors.Red, FontWeights.Normal, ResultBlock, Ans);
224 this.variables[
"Ans"] = Ans;
226 if (ex is AggregateException ex2)
228 foreach (Exception ex3
in ex2.InnerExceptions)
229 ScriptBlock = this.AddTextBlock(ScriptBlock, ex3.Message, Colors.Red, FontWeights.Bold,
null, ex3);
232 this.AddTextBlock(ScriptBlock, ex.Message, Colors.Red, FontWeights.Bold, ResultBlock, ex);
238 private TextBlock AddTextBlock(UIElement ScriptBlock,
string s, Color cl, FontWeight Weight, UIElement ResultBlock,
object Tag)
240 if (ResultBlock is TextBlock TextBlock)
247 TextBlock =
new TextBlock()
250 FontFamily =
new FontFamily(
"Courier New"),
251 Foreground =
new SolidColorBrush(cl),
252 TextWrapping = TextWrapping.Wrap,
257 this.AddBlock(ScriptBlock, TextBlock);
263 private UIElement AddBlock(UIElement ScriptBlock, UIElement ResultBlock)
265 if (ScriptBlock is
null)
266 this.HistoryPanel.Children.Add(ResultBlock);
268 this.HistoryPanel.Children.Insert(this.HistoryPanel.Children.IndexOf(ScriptBlock) + 1, ResultBlock);
273 private void TextBlock_PreviewMouseDown(
object Sender, MouseButtonEventArgs e)
275 this.Input.Text = ((TextBlock)Sender).Text;
276 this.Input.SelectAll();
281 private UIElement AddImageBlock(UIElement ScriptBlock,
PixelInformation Pixels,
Graph Graph,
object[] States, UIElement ResultBlock)
283 BitmapImage BitmapImage;
286 using (MemoryStream ms =
new MemoryStream(Bin))
288 BitmapImage =
new BitmapImage();
289 BitmapImage.BeginInit();
290 BitmapImage.CacheOption = BitmapCacheOption.OnLoad;
291 BitmapImage.StreamSource = ms;
292 BitmapImage.EndInit();
295 if (ResultBlock is Image ImageBlock)
297 ImageBlock.Source = BitmapImage;
298 ImageBlock.Width = Pixels.
Width;
299 ImageBlock.Height = Pixels.
Height;
300 ImageBlock.Tag =
new Tuple<byte[], int, int, Graph, object[]>(Bin, Pixels.
Width, Pixels.
Height,
Graph, States);
304 ImageBlock =
new Image()
306 Source = BitmapImage,
307 Width = Pixels.
Width,
309 Tag =
new Tuple<byte[], int, int, Graph, object[]>(Bin, Pixels.
Width, Pixels.
Height,
Graph, States)
312 ImageBlock.PreviewMouseDown += this.ImageBlock_PreviewMouseDown;
314 this.HistoryPanel.Children.Insert(this.HistoryPanel.Children.IndexOf(ScriptBlock) + 1, ImageBlock);
320 private void ImageBlock_PreviewMouseDown(
object Sender, MouseButtonEventArgs e)
322 Image ImageBlock = (Image)Sender;
324 if (e.ChangedButton == MouseButton.Left)
326 Point P = e.GetPosition(ImageBlock);
329 if (ImageBlock.Tag is Tuple<
byte[],
int,
int,
Graph,
object[]> Image && !(Image.Item4 is
null) && !(Image.Item5 is
null))
331 double X = ((double)P.X) * Image.Item2 / ImageBlock.ActualWidth;
332 double Y = ((double)P.Y) * Image.Item3 / ImageBlock.ActualHeight;
334 Script = Image.Item4.GetBitmapClickScript(X, Y, Image.Item5);
337 Script =
"[" + P.X.ToString() +
"," + P.Y.ToString() +
"]";
339 this.Input.Text = Script;
340 this.ExecuteButton_Click(
this, e);
342 else if (e.ChangedButton == MouseButton.Right)
344 BitmapImage Image = (BitmapImage)ImageBlock.Source;
346 SaveFileDialog Dialog =
new SaveFileDialog()
348 Title =
"Save Image",
350 Filter =
"PNG files (*.png)|*.png|All Image files (*.bmp, *.gif, *.jpg, *.jpeg, *.png, *.tif, *.tiff)|*.bmp, *.gif, *.jpg, *.jpeg, *.png, *.tif, *.tiff|All files (*.*)|*.*",
351 OverwritePrompt =
true
354 bool? Result = Dialog.ShowDialog();
355 if (Result.HasValue && Result.Value)
357 BitmapEncoder Encoder;
359 string Extension = System.IO.Path.GetExtension(Dialog.FileName).ToLower();
360 if (Extension.StartsWith(
"."))
361 Extension = Extension.Substring(1);
367 Encoder =
new JpegBitmapEncoder();
371 Encoder =
new BmpBitmapEncoder();
375 Encoder =
new GifBitmapEncoder();
380 Encoder =
new TiffBitmapEncoder();
385 Encoder =
new PngBitmapEncoder();
391 Encoder.Frames.Add(BitmapFrame.Create(Image));
393 using (FileStream File =
new FileStream(Dialog.FileName, System.IO.FileMode.Create))
401 MessageBox.Show(
MainWindow.currentInstance, ex.Message,
"Unable to save image.", MessageBoxButton.OK, MessageBoxImage.Error);
409 internal void Print(
string Output)
413 this.AddTextBlock(
null, Output, Colors.Blue, FontWeights.Normal,
null,
false);
414 return Task.CompletedTask;
418 public void NewButton_Click(
object Sender, RoutedEventArgs e)
420 this.HistoryPanel.Children.Clear();
423 public void SaveButton_Click(
object Sender, RoutedEventArgs e)
425 this.SaveAsButton_Click(Sender, e);
428 public void SaveAsButton_Click(
object Sender, RoutedEventArgs e)
430 SaveFileDialog Dialog =
new SaveFileDialog()
433 CheckPathExists =
true,
434 CreatePrompt =
false,
436 Filter =
"Script Files (*.xml)|*.xml|Script Files (*.script)|*.script|HTML Files (*.html,*.htm)|*.html,*.htm|All Files (*.*)|*.*",
437 Title =
"Save Script"
440 bool? Result = Dialog.ShowDialog(
MainWindow.FindWindow(
this));
442 if (Result.HasValue && Result.Value)
446 switch (Dialog.FilterIndex)
449 using (FileStream f = File.Create(Dialog.FileName))
459 StringBuilder Xml =
new StringBuilder();
465 string Html =
XSL.
Transform(Xml.ToString(), scriptToHtml);
467 File.WriteAllText(Dialog.FileName, Html, System.Text.Encoding.UTF8);
472 using (StreamWriter w = File.CreateText(Dialog.FileName))
474 foreach (Object Obj
in this.HistoryPanel.Children)
476 if (Obj is TextBlock TextBlock && TextBlock.Tag is
bool b && b)
478 string s = TextBlock.Text.TrimEnd();
479 if (!
string.IsNullOrEmpty(s) && !s.EndsWith(
";"))
493 MessageBox.Show(
MainWindow.FindWindow(
this), ex.Message,
"Unable to save file.", MessageBoxButton.OK, MessageBoxImage.Error);
498 private static readonly XslCompiledTransform scriptToHtml =
XSL.
LoadTransform(
"Waher.Client.WPF.Transforms.ScriptToHTML.xslt");
499 private static readonly XmlSchema schema =
XSL.
LoadSchema(
"Waher.Client.WPF.Schema.Script.xsd");
500 private const string scriptNamespace =
"http://waher.se/Schema/Script.xsd";
501 private const string scriptRoot =
"Script";
503 private void SaveAsXml(XmlWriter w)
505 w.WriteStartElement(scriptRoot, scriptNamespace);
507 foreach (
object Object
in this.HistoryPanel.Children)
509 if (Object is TextBlock TextBlock)
512 w.WriteElementString(
"Expression", Exp.Script);
513 else if (TextBlock.Tag is Exception ex)
514 w.WriteElementString(
"Error", ex.Message);
515 else if (TextBlock.Tag is
bool b)
518 w.WriteElementString(
"Result", TextBlock.Text);
520 w.WriteElementString(
"Print", TextBlock.Text);
523 else if (Object is Image ImageBlock)
525 if (ImageBlock.Tag is Tuple<
byte[],
int,
int,
Graph,
object[]> Image)
527 w.WriteStartElement(
"Image");
528 w.WriteAttributeString(
"width", Image.Item2.ToString());
529 w.WriteAttributeString(
"height", Image.Item3.ToString());
530 w.WriteValue(Convert.ToBase64String(Image.Item1));
540 public void OpenButton_Click(
object Sender, RoutedEventArgs e)
544 OpenFileDialog Dialog =
new OpenFileDialog()
547 CheckFileExists =
true,
548 CheckPathExists =
true,
550 Filter =
"Script Files (*.xml)|*.xml|Script Files (*.script)|*.script|All Files (*.*)|*.*",
553 Title =
"Load Script"
556 bool? Result = Dialog.ShowDialog(
MainWindow.FindWindow(
this));
558 if (Result.HasValue && Result.Value)
560 if (Dialog.FilterIndex == 1)
562 XmlDocument Xml =
new XmlDocument()
564 PreserveWhitespace =
true
566 Xml.Load(Dialog.FileName);
568 this.Load(Xml, Dialog.FileName);
572 string Script = File.ReadAllText(Dialog.FileName);
574 this.Input.Text = Script;
575 this.ExecuteButton_Click(
this,
new RoutedEventArgs());
582 MessageBox.Show(ex.Message,
"Unable to load file.", MessageBoxButton.OK, MessageBoxImage.Error);
586 public void Load(XmlDocument Xml,
string FileName)
588 XSL.
Validate(FileName, Xml, scriptRoot, scriptNamespace, schema);
590 this.HistoryPanel.Children.Clear();
592 foreach (XmlNode N
in Xml.DocumentElement.ChildNodes)
594 if (N is XmlElement E)
601 TextBlock ScriptBlock =
new TextBlock()
604 FontFamily =
new FontFamily(
"Courier New"),
605 TextWrapping = TextWrapping.Wrap,
609 ScriptBlock.PreviewMouseDown += this.TextBlock_PreviewMouseDown;
611 this.HistoryPanel.Children.Add(ScriptBlock);
615 this.AddTextBlock(
null, E.InnerText, Colors.Red, FontWeights.Bold,
null,
new Exception(E.InnerText));
619 this.AddTextBlock(
null, E.InnerText, Colors.Red, FontWeights.Normal,
null,
true);
623 this.AddTextBlock(
null, E.InnerText, Colors.Blue, FontWeights.Normal,
null,
false);
627 BitmapImage BitmapImage;
628 byte[] Bin = Convert.FromBase64String(E.InnerText);
632 using (MemoryStream ms =
new MemoryStream(Convert.FromBase64String(E.InnerText)))
634 BitmapImage =
new BitmapImage();
635 BitmapImage.BeginInit();
636 BitmapImage.CacheOption = BitmapCacheOption.OnLoad;
637 BitmapImage.StreamSource = ms;
638 BitmapImage.EndInit();
641 Image ImageBlock =
new System.Windows.Controls.Image()
643 Source = BitmapImage,
646 Tag =
new Tuple<byte[], int, int, Graph, object[]>(Bin, Width, Height,
null,
null)
649 ImageBlock.PreviewMouseDown += this.ImageBlock_PreviewMouseDown;
651 this.HistoryPanel.Children.Add(ImageBlock);
657 this.HistoryScrollViewer.ScrollToBottom();
661 public void Dispose()
663 this.HistoryPanel.Children.Clear();
666 private void Hyperlink_Click(
object Sender, RoutedEventArgs e)
668 string Uri = ((Hyperlink)Sender).NavigateUri.ToString();
669 System.Diagnostics.Process.Start(Uri);
Interaction logic for ChatView.xaml
Interaction logic for ScriptView.xaml
void InitializeComponent()
InitializeComponent
Interaction logic for xaml
const string FileExtensionJpg
jpg
const string FileExtensionPng
png
const string FileExtensionGif
gif
const string FileExtensionBmp
bmp
const string FileExtensionTiff
tif
Contains a markdown document. This markdown document class supports original markdown,...
static string Encode(string s)
Encodes all special characters in a string so that it can be included in a markdown document without ...
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static XmlWriterSettings WriterSettings(bool Indent, bool OmitXmlDeclaration)
Gets an XML writer settings object.
Static class managing loading of XSL resources stored as embedded resources or in content files.
static XmlSchema LoadSchema(string ResourceName)
Loads an XML schema from an embedded resource.
static XslCompiledTransform LoadTransform(string ResourceName)
Loads an XSL transformation from an embedded resource.
static string Transform(string XML, XslCompiledTransform Transform)
Transforms an XML document using an XSL transform.
static void Validate(string ObjectID, XmlDocument Xml, params XmlSchema[] Schemas)
Validates an XML document given a set of XML schemas.
Static class managing the application event log. Applications and services log events on this static ...
static Exception UnnestException(Exception Exception)
Unnests an exception, to extract the relevant inner exception.
Script runtime exception.
IElement ReturnValue
Return value.
Class managing a script expression.
ScriptNode Root
Root script node.
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Event arguments for preview events.
IElement Preview
Preview of result.
Interface for tab view user controls in the client.
Basic interface for all types of elements.
object AssociatedObjectValue
Associated object value.