aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs
diff options
context:
space:
mode:
authorRoy <roy.mail.net@gmail.com>2017-12-26 21:16:15 +0200
committerRoy <roy.mail.net@gmail.com>2017-12-26 21:16:15 +0200
commit2ea2bb5bcd96045f1bd6cb4c3d8b8416dbaa05dc (patch)
treea21ff27fff08876e835df82c5242def1f0d09c17 /Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs
parent6450fc175114a6f8d0b75cb21386d1bb0c902711 (diff)
downloadTango-2ea2bb5bcd96045f1bd6cb4c3d8b8416dbaa05dc.tar.gz
Tango-2ea2bb5bcd96045f1bd6cb4c3d8b8416dbaa05dc.zip
MERGE
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Images/stubs.jpgbin0 -> 96798 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/AssemblyInfo.cs18
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.Designer.cs92
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.resx124
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Resources/CodeTabTemplate.cs20
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubManager.cs181
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubOnExecuteParameters.cs30
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubsModule.cs39
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Tango.MachineStudio.Stubs.csproj183
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModelLocator.cs33
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/CodeTabVM.cs100
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs525
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/StubSnippetVM.cs47
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml319
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml.cs53
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/app.config51
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/packages.config11
19 files changed, 1863 insertions, 0 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Images/stubs.jpg b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Images/stubs.jpg
new file mode 100644
index 000000000..f9dd9b246
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Images/stubs.jpg
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..45c89075b
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/AssemblyInfo.cs
@@ -0,0 +1,18 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+[assembly: AssemblyTitle("Tango - Machine Studio Stubs Module")]
+
+[assembly: ComVisible(false)]
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..e712344b4
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.Designer.cs
@@ -0,0 +1,92 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.MachineStudio.Stubs.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.MachineStudio.Stubs.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to using System;
+ ///using System.Text;
+ ///using System.Linq;
+ ///using System.Drawing;
+ ///using System.Diagnostics;
+ ///using System.Windows.Forms;
+ ///using System.Threading;
+ ///using System.Threading.Tasks;
+ ///using System.Collections.Generic;
+ ///using Tango.Stubs.UI;
+ ///
+ ///public void OnExecute(StubManager stubManager)
+ ///{
+ /// for (int i = 0; i &lt; 10; i++)
+ /// {
+ /// stubManager.Run(&quot;calculate&quot;, 10, 5);
+ /// Thread.Sleep(10);
+ /// }
+ ///}
+ ///
+ ///.
+ /// </summary>
+ internal static string CodeTabTemplate {
+ get {
+ return ResourceManager.GetString("CodeTabTemplate", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.resx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.resx
new file mode 100644
index 000000000..7693cadac
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Resources.resx
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="CodeTabTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Resources\CodeTabTemplate.cs;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..465246f32
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Tango.MachineStudio.Stubs.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.settings b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Resources/CodeTabTemplate.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Resources/CodeTabTemplate.cs
new file mode 100644
index 000000000..b21e6e758
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Resources/CodeTabTemplate.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Text;
+using System.Linq;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using Tango.MachineStudio.Stubs;
+
+public void OnExecute(StubManager stubManager)
+{
+ for (int i = 0; i < 10; i++)
+ {
+ stubManager.Run("calculate", 10, 5);
+ Thread.Sleep(10);
+ }
+}
+
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubManager.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubManager.cs
new file mode 100644
index 000000000..8e0eafa3a
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubManager.cs
@@ -0,0 +1,181 @@
+using Google.Protobuf;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.PMR;
+using Tango.PMR.Common;
+using Tango.Stubs;
+using Tango.Transport;
+using Tango.Transport.Adapters;
+
+namespace Tango.MachineStudio.Stubs
+{
+ /// <summary>
+ /// Represents a manager capable of executing stub scripts asynchronously.
+ /// </summary>
+ public class StubManager
+ {
+ private ITransportAdapter _adapter; //Holds the USB transport adapter.
+
+ /// <summary>
+ /// Occurs when the stub has failed to execute.
+ /// </summary>
+ public event EventHandler<Exception> Failed;
+
+ /// <summary>
+ /// Occurs when the stub has completed successfully.
+ /// </summary>
+ public event EventHandler<String> Completed;
+
+ /// <summary>
+ /// Occurs when the stub has been initialized and executed.
+ /// </summary>
+ public event EventHandler<String> Executed;
+
+ /// <summary>
+ /// Gets a value indicating whether this <see cref="StubManager"/> is aborted.
+ /// </summary>
+ internal bool Aborted { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StubManager"/> class.
+ /// </summary>
+ /// <param name="adapter">The adapter.</param>
+ public StubManager(ITransportAdapter adapter)
+ {
+ _adapter = adapter;
+ }
+
+ /// <summary>
+ /// Aborts the current script.
+ /// </summary>
+ internal void Abort()
+ {
+ Aborted = true;
+ }
+
+ /// <summary>
+ /// Runs the specified stub name.
+ /// </summary>
+ /// <param name="stubName">Name of the stub.</param>
+ /// <param name="args">The arguments.</param>
+ public void Run(String stubName, params Object[] args)
+ {
+ if (Aborted) return;
+
+ var stubType = StubBase.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == stubName.ToLower() || x.Name.Replace("Request", "").ToLower() == stubName.ToLower());
+ if (stubType == null)
+ {
+ OnFailed(new ArgumentException("Invalid stub '" + stubName + "'."));
+ return;
+ }
+
+ var stubProps = stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+ if (stubProps.Length > args.Length)
+ {
+ OnFailed(new ArgumentOutOfRangeException("Not enough arguments for " + stubType.Name + "."));
+ return;
+ }
+
+ Executed?.Invoke(this, stubType.Name);
+
+ try
+ {
+ MessageContainer container = new MessageContainer();
+ container.Token = Guid.NewGuid().ToString();
+ container.Type = MessageFactory.ParseMessageType(stubType.Name);
+
+ Object request = Activator.CreateInstance(stubType);
+
+ int argIndex = 0;
+ foreach (var prop in stubProps)
+ {
+ String arg = args[argIndex++].ToString();
+
+ if (prop.PropertyType == typeof(UInt32))
+ {
+ prop.SetValue(request, UInt32.Parse(arg));
+ }
+ else if (prop.PropertyType == typeof(bool))
+ {
+ prop.SetValue(request, bool.Parse(arg));
+ }
+ else
+ {
+ object converted = Convert.ChangeType(arg, prop.PropertyType);
+ prop.SetValue(request, converted);
+ }
+ }
+
+ container.Data = typeof(IMessage).GetExtensionMethod(typeof(ByteString).Assembly, "ToByteString").Invoke(request, new object[] { request }) as ByteString;
+
+ byte[] requestData = container.ToByteArray();
+
+ bool done = false;
+
+ Task.Factory.StartNew(() =>
+ {
+ _adapter.Write(requestData);
+
+ DateTime startTime = DateTime.Now;
+
+ MessageContainer responseContainer = null;
+
+ _adapter.DataAvailable += (sender, data) =>
+ {
+ responseContainer = MessageFactory.ParseContainer(data);
+ };
+
+ while (responseContainer == null)
+ {
+ Thread.Sleep(2);
+
+ if (DateTime.Now > startTime.AddSeconds(2))
+ {
+ done = true;
+ OnFailed(new TimeoutException("Response has failed to arrive after 2 seconds."));
+ return;
+ }
+ }
+
+ IMessage message = MessageFactory.ParseMessageFromContainer(responseContainer);
+ OnCompleted(JsonConvert.SerializeObject(message, Formatting.Indented));
+ done = true;
+ });
+
+ while (!done)
+ {
+ Thread.Sleep(2);
+ }
+ }
+ catch (Exception ex)
+ {
+ OnFailed(ex);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="Failed"/> event.
+ /// </summary>
+ /// <param name="ex">The exception.</param>
+ protected virtual void OnFailed(Exception ex)
+ {
+ Failed?.Invoke(this, ex);
+ }
+
+ /// <summary>
+ /// Raises the <see cref="Completed"/> event.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ protected virtual void OnCompleted(String response)
+ {
+ Completed?.Invoke(this, response);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubOnExecuteParameters.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubOnExecuteParameters.cs
new file mode 100644
index 000000000..761375818
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubOnExecuteParameters.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Scripting;
+
+namespace Tango.MachineStudio.Stubs
+{
+ /// <summary>
+ /// Represents the global object which will be sent to the scripting engine.
+ /// </summary>
+ /// <seealso cref="Tango.Scripting.OnExecuteParameters" />
+ public class StubOnExecuteParameters : OnExecuteParameters
+ {
+ /// <summary>
+ /// Provides access to the script stub manager.
+ /// </summary>
+ public StubManager stubManager;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="StubOnExecuteParameters"/> class.
+ /// </summary>
+ /// <param name="manager">The manager.</param>
+ public StubOnExecuteParameters(StubManager manager)
+ {
+ stubManager = manager;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubsModule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubsModule.cs
new file mode 100644
index 000000000..2c4b6c76e
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/StubsModule.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using Tango.DAL.Observables;
+using Tango.MachineStudio.Common;
+using Tango.MachineStudio.Stubs.Views;
+using Tango.SharedUI.Helpers;
+
+namespace Tango.MachineStudio.Stubs
+{
+ public class StubsModule : IStudioModule
+ {
+ public string Name => "Stubs";
+
+ public string Description => "Execute machine tests using an interactive C# scripting editor";
+
+ public BitmapSource Image => ResourceHelper.GetImageFromResources("Images/stubs.jpg");
+
+ public FrameworkElement MainView => new MainView();
+
+ public Permissions Permission => Permissions.RunSynchronizationModule;
+
+ public bool IsInitialized => true;
+
+ public void Dispose()
+ {
+ //throw new NotImplementedException();
+ }
+
+ public void Initialize()
+ {
+ //throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Tango.MachineStudio.Stubs.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Tango.MachineStudio.Stubs.csproj
new file mode 100644
index 000000000..436a8b3ff
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Tango.MachineStudio.Stubs.csproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{22C2AA72-9493-4D0D-B421-8EF9789FB192}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <RootNamespace>Tango.MachineStudio.Stubs</RootNamespace>
+ <AssemblyName>Tango.MachineStudio.Stubs</AssemblyName>
+ <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\..\Build\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath>
+ </Reference>
+ <Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
+ </Reference>
+ <Reference Include="GalaSoft.MvvmLight.Extras, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=669f0b5e8f868abf, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll</HintPath>
+ </Reference>
+ <Reference Include="GalaSoft.MvvmLight.Platform, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignColors, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll</HintPath>
+ </Reference>
+ <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xaml">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\CodeTabTemplate.cs" />
+ <Compile Include="StubManager.cs" />
+ <Compile Include="StubOnExecuteParameters.cs" />
+ <Compile Include="ViewModelLocator.cs" />
+ <Compile Include="ViewModels\CodeTabVM.cs" />
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="ViewModels\StubSnippetVM.cs" />
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ <SubType>
+ </SubType>
+ </Compile>
+ <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="StubsModule.cs" />
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="app.config" />
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\SideChains\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">
+ <Project>{6c55b776-26d4-4db3-a6ab-87e783b2f3d1}</Project>
+ <Name>ICSharpCode.AvalonEdit</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.DAL.Observables\Tango.DAL.Observables.csproj">
+ <Project>{0ecd6da8-7aa6-48d9-8b65-279d176ad9af}</Project>
+ <Name>Tango.DAL.Observables</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Integration\Tango.Integration.csproj">
+ <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project>
+ <Name>Tango.Integration</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Scripting\Tango.Scripting.csproj">
+ <Project>{401989e7-ae1e-4002-b0ee-9a9f63740b97}</Project>
+ <Name>Tango.Scripting</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Settings\Tango.Settings.csproj">
+ <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
+ <Name>Tango.Settings</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Stubs\Tango.Stubs.csproj">
+ <Project>{1981b537-39e9-4e7d-8430-27466481aeee}</Project>
+ <Name>Tango.Stubs</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
+ <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
+ <Name>Tango.MachineStudio.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\stubs.jpg" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModelLocator.cs
new file mode 100644
index 000000000..02ac1b8dd
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModelLocator.cs
@@ -0,0 +1,33 @@
+using GalaSoft.MvvmLight.Ioc;
+using Microsoft.Practices.ServiceLocation;
+using Tango.MachineStudio.Stubs.ViewModels;
+
+namespace Tango.MachineStudio.Stubs
+{
+ /// <summary>
+ /// This class contains static references to all the view models in the
+ /// application and provides an entry point for the bindings.
+ /// </summary>
+ public static class ViewModelLocator
+ {
+ /// <summary>
+ /// Initializes a new instance of the ViewModelLocator class.
+ /// </summary>
+ static ViewModelLocator()
+ {
+ ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
+
+ //SimpleIoc.Default.Unregister<INotificationProvider>();
+
+ SimpleIoc.Default.Register<MainViewVM>();
+ }
+
+ public static MainViewVM MainViewVM
+ {
+ get
+ {
+ return ServiceLocator.Current.GetInstance<MainViewVM>();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/CodeTabVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/CodeTabVM.cs
new file mode 100644
index 000000000..451e1a1f0
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/CodeTabVM.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.Stubs.ViewModels
+{
+ /// <summary>
+ /// Represents a single script editor tab view model;
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public class CodeTabVM : ViewModel
+ {
+ private String _title;
+ /// <summary>
+ /// Gets or sets the script title/file name.
+ /// </summary>
+ public String Title
+ {
+ get
+ {
+ return File != null ? Path.GetFileName(File) : _title;
+ }
+ set
+ {
+ _title = value;
+ RaisePropertyChanged(nameof(Title));
+ }
+ }
+
+ private String _file;
+ /// <summary>
+ /// Gets or sets the full script file path.
+ /// </summary>
+ public String File
+ {
+ get { return _file; }
+ set
+ {
+ _file = value;
+ RaisePropertyChanged(nameof(File));
+ RaisePropertyChanged(nameof(Title));
+ }
+ }
+
+ private String _code;
+ /// <summary>
+ /// Gets or sets the script code.
+ /// </summary>
+ public String Code
+ {
+ get { return _code; }
+ set { _code = value; RaisePropertyChanged(nameof(Code)); }
+ }
+
+ private bool _isRunning;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is running.
+ /// </summary>
+ public bool IsRunning
+ {
+ get { return _isRunning; }
+ set { _isRunning = value; RaisePropertyChangedAuto(); }
+ }
+
+ private RelayCommand _insertCodeSnippetCommand;
+ /// <summary>
+ /// Gets or sets the insert snippet command. (Inserts stub snippet to editor)
+ /// </summary>
+ public RelayCommand InsertSnippetCommand
+ {
+ get { return _insertCodeSnippetCommand; }
+ set { _insertCodeSnippetCommand = value; RaisePropertyChanged(nameof(InsertSnippetCommand)); }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CodeTabVM"/> class.
+ /// </summary>
+ public CodeTabVM()
+ {
+ Title = "untitled";
+ Code = Properties.Resources.CodeTabTemplate;
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return Title;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..d7e641735
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/MainViewVM.cs
@@ -0,0 +1,525 @@
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core.Commands;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.StudioApplication;
+using Tango.Scripting;
+using Tango.Settings;
+using Tango.SharedUI;
+using Tango.Stubs;
+using Tango.Transport;
+using Tango.Transport.Adapters;
+
+namespace Tango.MachineStudio.Stubs.ViewModels
+{
+ /// <summary>
+ /// Represents the script execution utility main view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public class MainViewVM : ViewModel
+ {
+ private UsbTransportAdapter _adapter; //Holds the USB transport adapter.
+ private StubManager _stubManager;
+ private INotificationProvider _notification;
+
+ #region Properties
+
+ public IStudioApplicationManager ApplicationManager { get; set; }
+
+ private bool _useConnectedMachine;
+ /// <summary>
+ /// Gets or sets a value indicating whether [use connected machine].
+ /// </summary>
+ public bool UseConnectedMachine
+ {
+ get { return _useConnectedMachine; }
+ set { _useConnectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the code tabs.
+ /// </summary>
+ public ObservableCollection<CodeTabVM> CodeTabs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the additional highlight C# types.
+ /// </summary>
+ public ObservableCollection<KeyValuePair<String, Type>> HighlightTypes { get; set; }
+
+ /// <summary>
+ /// Gets or sets the collection of stub snippets.
+ /// </summary>
+ public ObservableCollection<StubSnippetVM> StubSnippets { get; set; }
+
+ private StubSnippetVM _selectedStubSnippet;
+ /// <summary>
+ /// Gets or sets the selected stub snippet.
+ /// </summary>
+ public StubSnippetVM SelectedStubSnippet
+ {
+ get { return _selectedStubSnippet; }
+ set { _selectedStubSnippet = value; RaisePropertyChanged(nameof(SelectedStubSnippet)); }
+ }
+
+ private String _log;
+ /// <summary>
+ /// Gets or sets the current response log.
+ /// </summary>
+ public String Log
+ {
+ get { return _log; }
+ set { _log = value; RaisePropertyChanged(nameof(Log)); }
+ }
+
+ private CodeTabVM _selectedCodeTab;
+ /// <summary>
+ /// Gets or sets the selected code tab.
+ /// </summary>
+ public CodeTabVM SelectedCodeTab
+ {
+ get { return _selectedCodeTab; }
+ set { _selectedCodeTab = value; RaisePropertyChanged(nameof(SelectedCodeTab)); InvalidateRelayCommands(); }
+ }
+
+ private bool _isConnected;
+ /// <summary>
+ /// Gets or sets a value indicating whether the USB adapter is connected.
+ /// </summary>
+ public bool IsConnected
+ {
+ get { return _isConnected; }
+ set { _isConnected = value; RaisePropertyChanged(nameof(IsConnected)); InvalidateRelayCommands(); }
+ }
+
+ private List<String> _ports;
+ /// <summary>
+ /// Gets or sets the available USB ports.
+ /// </summary>
+ public List<String> Ports
+ {
+ get { return _ports; }
+ set { _ports = value; RaisePropertyChanged(nameof(Ports)); }
+ }
+
+ private String _selectedPort;
+ /// <summary>
+ /// Gets or sets the selected USB port.
+ /// </summary>
+ public String SelectedPort
+ {
+ get { return _selectedPort; }
+ set { _selectedPort = value; RaisePropertyChanged(nameof(SelectedPort)); InvalidateRelayCommands(); }
+ }
+
+ private String _status;
+ /// <summary>
+ /// Gets or sets the current status bar text.
+ /// </summary>
+ public String Status
+ {
+ get { return _status; }
+ set { _status = value; RaisePropertyChanged(nameof(Status)); }
+ }
+
+ private bool _isRunning;
+ /// <summary>
+ /// Gets or sets a value indicating whether a stub is currently running.
+ /// </summary>
+ public bool IsRunning
+ {
+ get { return _isRunning; }
+ set { _isRunning = value; RaisePropertyChanged(nameof(IsRunning)); InvalidateRelayCommands(); }
+ }
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the new command.
+ /// </summary>
+ public RelayCommand NewCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the close tab command.
+ /// </summary>
+ public RelayCommand<CodeTabVM> CloseTabCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the run command.
+ /// </summary>
+ public RelayCommand RunCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop command.
+ /// </summary>
+ public RelayCommand StopCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the toggle connection command.
+ /// </summary>
+ public RelayCommand ToggleConnectionCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the open command.
+ /// </summary>
+ public RelayCommand OpenCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save command.
+ /// </summary>
+ public RelayCommand SaveCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save as command.
+ /// </summary>
+ public RelayCommand SaveAsCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stub snippet selected command.
+ /// </summary>
+ public RelayCommand StubSnippetSelectedCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the insert snippet command.
+ /// </summary>
+ public RelayCommand<String> InsertSnippetCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the exit command.
+ /// </summary>
+ public RelayCommand ExitCommand { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainViewVM"/> class.
+ /// </summary>
+ public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notification)
+ {
+ ApplicationManager = applicationManager;
+ _notification = notification;
+
+ CodeTabs = new ObservableCollection<CodeTabVM>();
+
+ NewCommand = new RelayCommand(CreateNewTab);
+ CloseTabCommand = new RelayCommand<CodeTabVM>(OnTabClosing);
+ RunCommand = new RelayCommand(RunTab, (x) => (IsConnected || UseConnectedMachine) && !IsRunning && SelectedCodeTab != null);
+ StopCommand = new RelayCommand(StopTab, (x) => (IsConnected || UseConnectedMachine) && IsRunning && SelectedCodeTab != null);
+ InsertSnippetCommand = new RelayCommand<string>((x) => { });
+
+ HighlightTypes = new ObservableCollection<KeyValuePair<string, Type>>();
+ HighlightTypes.Add(new KeyValuePair<string, Type>("stubManager", typeof(StubManager)));
+
+ StubSnippets = new ObservableCollection<StubSnippetVM>();
+
+ foreach (var stubType in StubBase.GetAvailableRequestStubs())
+ {
+ StubSnippetVM snippet = new StubSnippetVM();
+ snippet.Name = stubType.Name.Replace("Stub_", "");
+ snippet.Code = String.Format("stubManager.Run(\"{0}\" ,{1});", stubType.Name, String.Join(", ", stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(x => x.PropertyType.Name == "string" ? "\"string\"" : x.PropertyType.Name)));
+ StubSnippets.Add(snippet);
+ }
+
+ ToggleConnectionCommand = new RelayCommand(ToggleConnection, (x) => !IsRunning);
+ OpenCommand = new RelayCommand(OpenFile);
+ SaveCommand = new RelayCommand(SaveFile);
+ SaveAsCommand = new RelayCommand(SaveAsFile);
+ StubSnippetSelectedCommand = new RelayCommand(OnStubSnippetSelected);
+ ExitCommand = new RelayCommand(() => Application.Current.Shutdown());
+
+ Ports = new List<string>()
+ {
+ "COM1",
+ "COM2",
+ "COM3",
+ "COM4",
+ "COM5",
+ "COM6",
+ "COM7",
+ "COM8",
+ "COM9",
+ };
+
+ SelectedPort = SettingsManager.Default.StubsUI.SelectedPort != null ? SettingsManager.Default.StubsUI.SelectedPort : Ports.First();
+
+ Status = "Ready";
+
+ if (SettingsManager.Default.StubsUI.LastTabs.Count > 0)
+ {
+ foreach (var file in SettingsManager.Default.StubsUI.LastTabs)
+ {
+ if (File.Exists(file))
+ {
+ OpenFile(file);
+ }
+ }
+ }
+ else
+ {
+ CreateNewTab();
+ }
+
+ Application.Current.Exit += Current_Exit;
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Called when a stub snippet is double clicked.
+ /// </summary>
+ protected virtual void OnStubSnippetSelected()
+ {
+ if (SelectedStubSnippet != null)
+ {
+ if (InsertSnippetCommand != null)
+ {
+ InsertSnippetCommand.Execute(SelectedStubSnippet.Code);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when user closes a script tab.
+ /// </summary>
+ /// <param name="codeTab">The code tab.</param>
+ protected virtual void OnTabClosing(CodeTabVM codeTab)
+ {
+ CodeTabs.Remove(codeTab);
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ /// <summary>
+ /// Saves the selected script file.
+ /// </summary>
+ private void SaveFile()
+ {
+ if (SelectedCodeTab != null)
+ {
+ if (SelectedCodeTab.File == null)
+ {
+ SaveAsFile();
+ }
+ else
+ {
+ File.WriteAllText(SelectedCodeTab.File, SelectedCodeTab.Code);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Saves the selected script file.
+ /// </summary>
+ private void SaveAsFile()
+ {
+ if (SelectedCodeTab != null)
+ {
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Filter = "C# Script Files|*.cs";
+ dlg.DefaultExt = ".cs";
+ if (dlg.ShowDialog().Value)
+ {
+ File.WriteAllText(dlg.FileName, SelectedCodeTab.Code);
+ SelectedCodeTab.File = dlg.FileName;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Opens a script from HD.
+ /// </summary>
+ private void OpenFile()
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Filter = "C# Script Files|*.cs";
+ dlg.Multiselect = true;
+ if (dlg.ShowDialog().Value)
+ {
+ foreach (var file in dlg.FileNames)
+ {
+ OpenFile(file);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Opens the file.
+ /// </summary>
+ /// <param name="file">The file.</param>
+ private void OpenFile(String file)
+ {
+ var newTab = new CodeTabVM();
+ newTab.File = file;
+ newTab.Code = File.ReadAllText(file);
+ CodeTabs.Add(newTab);
+ SelectedCodeTab = newTab;
+ }
+
+ /// <summary>
+ /// Toggles the USB adapter connection.
+ /// </summary>
+ private void ToggleConnection()
+ {
+ try
+ {
+ if (!IsConnected)
+ {
+ _adapter = new UsbTransportAdapter(SelectedPort);
+ _adapter.Connect().Wait();
+ IsConnected = true;
+ }
+ else
+ {
+ _adapter.Disconnect().Wait();
+ IsConnected = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.ToString(), "Tango");
+ }
+ }
+
+ /// <summary>
+ /// Creates a new script tab.
+ /// </summary>
+ private void CreateNewTab()
+ {
+ var newTab = new CodeTabVM();
+ CodeTabs.Add(newTab);
+ SelectedCodeTab = newTab;
+ }
+
+ /// <summary>
+ /// Runs the selected script tab.
+ /// </summary>
+ private async void RunTab()
+ {
+ if (UseConnectedMachine && !ApplicationManager.IsMachineConnected)
+ {
+ _notification.ShowError("Cannot execute stub while 'Connected Machine' is set but not machine connected.");
+ return;
+ }
+
+ IsRunning = true;
+ SelectedCodeTab.IsRunning = true;
+ Log = (DateTime.Now.ToTimeString() + ": ") + "Executing script '" + SelectedCodeTab.Title + "'..." + Environment.NewLine;
+
+ await Task.Factory.StartNew(async () =>
+ {
+ try
+ {
+ ITransportAdapter adapter = _adapter;
+
+ if (ApplicationManager.IsMachineConnected && UseConnectedMachine)
+ {
+ adapter = ApplicationManager.ConnectedMachine.Adapters.First();
+ }
+
+ _stubManager = new StubManager(adapter);
+ var thisStubManager = _stubManager;
+ _stubManager.Completed += Manager_Completed;
+ _stubManager.Failed += Manager_Failed;
+ _stubManager.Executed += Manager_Executed;
+
+ ScriptEngine engine = new ScriptEngine(new StubOnExecuteParameters(_stubManager));
+
+ engine.ReferencedAssemblies.Add(this.GetType());
+ await engine.Run(SelectedCodeTab.Code);
+
+ if (!thisStubManager.Aborted)
+ {
+ IsRunning = false;
+ SelectedCodeTab.IsRunning = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ IsRunning = false;
+ SelectedCodeTab.IsRunning = false;
+ MessageBox.Show(ex.Message, "Tango");
+ }
+ });
+ }
+
+ /// <summary>
+ /// Stops the currently current script.
+ /// </summary>
+ private void StopTab()
+ {
+ if (_stubManager != null)
+ {
+ _stubManager.Abort();
+ IsRunning = false;
+ SelectedCodeTab.IsRunning = false;
+ Status = "Stopped!";
+ Log += (DateTime.Now.ToTimeString() + ": ") + "Stopped!" + Environment.NewLine;
+ }
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ /// <summary>
+ /// Handled the <see cref="StubManager"/> Executed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="stubName">Name of the stub.</param>
+ private void Manager_Executed(object sender, string stubName)
+ {
+ Log += (DateTime.Now.ToTimeString() + ": ") + "Executing '" + stubName + "'..." + Environment.NewLine;
+ Status = "Executing " + stubName + "...";
+ }
+
+ /// <summary>
+ /// Handled the <see cref="StubManager"/> Failed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="ex">The exception.</param>
+ private void Manager_Failed(object sender, Exception ex)
+ {
+ if (IsRunning)
+ {
+ Log += (DateTime.Now.ToTimeString() + ": ") + ex.Message + Environment.NewLine;
+ Status = "Failed!";
+ }
+ }
+
+ /// <summary>
+ /// Handled the <see cref="StubManager"/> Completed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="response">The response.</param>
+ private void Manager_Completed(object sender, string response)
+ {
+ Log += (DateTime.Now.ToTimeString() + ": ") + "Response Received:" + Environment.NewLine;
+ Log += (DateTime.Now.ToTimeString() + ": ") + response + Environment.NewLine;
+ Status = "Completed";
+ }
+
+ private void Current_Exit(object sender, ExitEventArgs e)
+ {
+ SettingsManager.Default.MachineStudio.StubsModule.SelectedPort = SelectedPort;
+ SettingsManager.Default.MachineStudio.StubsModule.LastTabs = CodeTabs.Select(x => x.File).ToList();
+ SettingsManager.SaveDefaultSettings();
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/StubSnippetVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/StubSnippetVM.cs
new file mode 100644
index 000000000..d99906f20
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/ViewModels/StubSnippetVM.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.Stubs.ViewModels
+{
+ /// <summary>
+ /// Represents a single stub snippet view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public class StubSnippetVM : ViewModel
+ {
+ private String _name;
+ /// <summary>
+ /// Gets or sets the stub name.
+ /// </summary>
+ public String Name
+ {
+ get { return _name; }
+ set { _name = value; RaisePropertyChanged(nameof(Name)); }
+ }
+
+ private String _code;
+ /// <summary>
+ /// Gets or sets the snippet code.
+ /// </summary>
+ public String Code
+ {
+ get { return _code; }
+ set { _code = value; RaisePropertyChanged(nameof(Code)); }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml
new file mode 100644
index 000000000..5a71b48d1
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml
@@ -0,0 +1,319 @@
+<UserControl x:Class="Tango.MachineStudio.Stubs.Views.MainView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:views="clr-namespace:Tango.MachineStudio.Stubs.Views"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:global="clr-namespace:Tango.MachineStudio.Stubs"
+ xmlns:local="clr-namespace:Tango.MachineStudio.Stubs.Views"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ mc:Ignorable="d"
+ d:DesignHeight="720" d:DesignWidth="1280" Background="#202020" Foreground="Gainsboro" DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
+ <UserControl.Resources>
+
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
+
+ <!-- Accent and AppTheme setting -->
+
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
+
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml" />
+
+ <ResourceDictionary>
+ <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
+ <converters:BooleanInverseConverter x:Key="BooleanInverseConverter"></converters:BooleanInverseConverter>
+ <Style BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type TabItem}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=IsSelected}" Value="True">
+ <Setter Property="Background" Value="#007ACC"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ <Setter Property="mahapps:ControlsHelper.HeaderFontSize" Value="12"></Setter>
+ <Setter Property="HeaderTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Border>
+ <StackPanel Orientation="Horizontal">
+ <mahapps:ProgressRing Width="5" Height="5" Margin="0 0 5 0" Foreground="White" Visibility="{Binding IsRunning,Converter={StaticResource BooleanToVisibilityConverter}}"></mahapps:ProgressRing>
+ <TextBlock Text="{Binding Title}" ToolTip="{Binding File}" Foreground="Gainsboro" VerticalAlignment="Center"></TextBlock>
+ <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.CloseTabCommand}" CommandParameter="{Binding}" Margin="5 0 0 0" Cursor="Hand" Width="24" Height="24" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Width="10" Height="10" Icon="Close" Foreground="Gainsboro"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Border>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Grid Background="#181818">
+ <controls:ScriptEditorControl Text="{Binding Code,Mode=TwoWay}" InsertSnippetCommand="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.InsertSnippetCommand,Mode=TwoWay}" SaveCommand="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.SaveCommand}" HighlightTypes="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.HighlightTypes}" RunCommand="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.RunCommand}" StopCommand="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.StopCommand}" />
+ </Grid>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
+ <UserControl.Style>
+ <Style TargetType="UserControl">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsRunning}" Value="True">
+ <Setter Property="Cursor" Value="AppStarting"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </UserControl.Style>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <Menu IsMainMenu="True" BorderThickness="0" Height="30" Padding="0 10 0 0">
+ <MenuItem Header="File">
+ <MenuItem Header="New" Command="{Binding NewCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="FileOutline" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Open" MinWidth="150" Command="{Binding OpenCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="FolderOutline" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Save" Command="{Binding SaveCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Save" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Save as" Command="{Binding SaveAsCommand}">
+ <MenuItem.Icon>
+ <Grid>
+ <fa:ImageAwesome Icon="Save" Width="10" Foreground="Gainsboro" Margin="2" />
+ <fa:ImageAwesome Icon="Save" Width="10" Foreground="Gainsboro" Margin="2 -5 -5 2" />
+ </Grid>
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Exit" Command="{Binding ExitCommand}">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="SignOut" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="Edit">
+ <MenuItem Header="Cut" MinWidth="150" Command="Cut">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Cut" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Copy" Command="Copy">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Copy" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Paste" Command="Paste">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Paste" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <Separator/>
+ <MenuItem Header="Undo" Command="Undo">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Undo" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Redo" Command="Redo">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Repeat" Width="12" Foreground="Gainsboro" Margin="2" />
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ <MenuItem Header="Build">
+ <MenuItem Header="Run (F5)" MinWidth="150" Command="{Binding RunCommand}" >
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Play" Width="12" Margin="2">
+ <fa:ImageAwesome.Style>
+ <Style TargetType="fa:ImageAwesome">
+ <Setter Property="Foreground" Value="#8DD28A"></Setter>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </fa:ImageAwesome.Style>
+ </fa:ImageAwesome>
+ </MenuItem.Icon>
+ </MenuItem>
+ <MenuItem Header="Stop" Command="{Binding StopCommand}" IsEnabled="False">
+ <MenuItem.Icon>
+ <fa:ImageAwesome Icon="Stop" Width="12" Margin="2">
+ <fa:ImageAwesome.Style>
+ <Style TargetType="fa:ImageAwesome">
+ <Setter Property="Foreground" Value="#F38B76"></Setter>
+ <Style.Triggers>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="Gray"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </fa:ImageAwesome.Style>
+ </fa:ImageAwesome>
+ </MenuItem.Icon>
+ </MenuItem>
+ </MenuItem>
+ </Menu>
+ </Grid>
+
+ <Grid Grid.Row="2">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*"/>
+ <ColumnDefinition Width="250"/>
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="5"/>
+ <RowDefinition Height="0.5*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <TabControl x:Name="tabControl" Margin="5" ItemsSource="{Binding CodeTabs}" SelectedItem="{Binding SelectedCodeTab}">
+
+ </TabControl>
+
+ <Grid HorizontalAlignment="Right" Margin="0 45 40 0" VerticalAlignment="Top" Visibility="{Binding IsRunning,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <StackPanel Orientation="Horizontal">
+ <mahapps:ProgressRing Foreground="#007ACC" Width="20" Height="20"></mahapps:ProgressRing>
+ <TextBlock Text="Running..." FontStyle="Italic" Margin="10 0 0 0" FontSize="14" VerticalAlignment="Center"></TextBlock>
+ </StackPanel>
+ </Grid>
+ </Grid>
+
+ <Grid Grid.Column="1" Grid.RowSpan="3">
+ <Grid VerticalAlignment="Bottom" Height="25" Background="#007ACC">
+
+ </Grid>
+ <DockPanel>
+ <GroupBox Header="COMMUNICATION PORT" VerticalAlignment="Top" DockPanel.Dock="Top" Margin="0 2 0 0">
+ <StackPanel>
+ <Grid VerticalAlignment="Center">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"></ColumnDefinition>
+ <ColumnDefinition Width="*"></ColumnDefinition>
+ </Grid.ColumnDefinitions>
+ <CheckBox x:Name="chkUseCurrentMachine" ToolTip="Use the currently connected machine to execute stubs" Margin="0 0 0 0" VerticalAlignment="Center" IsChecked="{Binding UseConnectedMachine}">Connected Machine</CheckBox>
+ <ComboBox Grid.Column="1" IsEnabled="{Binding ElementName=chkUseCurrentMachine,Path=IsChecked,Converter={StaticResource BooleanInverseConverter}}" Margin="10 0 0 0" BorderThickness="0" ItemsSource="{Binding Ports}" Height="35" SelectedItem="{Binding SelectedPort}"></ComboBox>
+ </Grid>
+ </StackPanel>
+ </GroupBox>
+
+ <GroupBox Header="CONNECTION" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Margin="0 10 0 25">
+ <StackPanel>
+ <Button IsEnabled="{Binding ElementName=chkUseCurrentMachine,Path=IsChecked,Converter={StaticResource BooleanInverseConverter}}" Height="50" MinWidth="100" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ToggleConnectionCommand}">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource AccentedSquareButtonStyle}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsConnected}" Value="False">
+ <Setter Property="Content">
+ <Setter.Value>
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Link" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">CONNECT</TextBlock>
+ </StackPanel>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsConnected}" Value="True">
+ <Setter Property="Content">
+ <Setter.Value>
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Unlink" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">DISCONNECT</TextBlock>
+ </StackPanel>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ </StackPanel>
+ </GroupBox>
+
+ <GroupBox Header="STUB SNIPPETS" Margin="0 10 0 0">
+ <Grid>
+ <ListBox BorderThickness="0" ItemsSource="{Binding StubSnippets}" HorizontalContentAlignment="Stretch" SelectedItem="{Binding SelectedStubSnippet}">
+ <ListBox.ItemContainerStyle>
+ <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="Margin" Value="0 2 0 2"></Setter>
+ <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
+ </Style>
+ </ListBox.ItemContainerStyle>
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Border BorderThickness="1" BorderBrush="#007ACC" Padding="8" Background="Transparent">
+ <Border.InputBindings>
+ <MouseBinding Gesture="LeftDoubleClick" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.StubSnippetSelectedCommand}"/>
+ </Border.InputBindings>
+ <Grid>
+ <fa:ImageAwesome Icon="ArrowLeft" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5 0 0 0" Foreground="#007ACC" Width="16" Height="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" FontSize="11" HorizontalAlignment="Center" Text="{Binding Name}"></TextBlock>
+ </Grid>
+ </Border>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+ </GroupBox>
+ </DockPanel>
+ </Grid>
+
+ <GridSplitter Margin="5 0 5 0" Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center">
+ <GridSplitter.Background>
+ <LinearGradientBrush>
+ <GradientStop/>
+ <GradientStop Color="#007ACC" Offset="0.5"/>
+ <GradientStop Offset="1"/>
+ </LinearGradientBrush>
+ </GridSplitter.Background>
+ </GridSplitter>
+
+ <Grid Grid.Row="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="25"/>
+ </Grid.RowDefinitions>
+ <GroupBox Header="Response">
+ <Grid Background="#151515">
+ <TextBox x:Name="txtLog" FontFamily="Lucida Console" TextChanged="TextBox_TextChanged" Background="Transparent" Text="{Binding Log}" BorderThickness="0" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Padding="5" IsReadOnly="True" TextWrapping="Wrap" FontSize="11" Foreground="Gainsboro"></TextBox>
+ </Grid>
+ </GroupBox>
+ <StatusBar Background="#007ACC" Grid.Row="1">
+ <TextBlock Text="{Binding Status}"></TextBlock>
+ </StatusBar>
+ </Grid>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml.cs
new file mode 100644
index 000000000..5eee980de
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/Views/MainView.xaml.cs
@@ -0,0 +1,53 @@
+using Microsoft.Practices.ServiceLocation;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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 Tango.MachineStudio.Stubs.ViewModels;
+using Tango.SharedUI.Controls;
+
+namespace Tango.MachineStudio.Stubs.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public MainView() : base()
+ {
+ InitializeComponent();
+ this.Loaded += MainView_Loaded;
+ }
+
+ private void MainView_Loaded(object sender, RoutedEventArgs e)
+ {
+ ServiceLocator.Current.GetInstance<MainViewVM>().CodeTabs.RemoveAt(0);
+ }
+
+ //Auto scroll to bottom of response log each time it is changed.
+ private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ Task.Factory.StartNew(() =>
+ {
+ Thread.Sleep(50);
+
+ this.Dispatcher.Invoke(() =>
+ {
+ txtLog.SelectionStart = txtLog.Text.Length;
+ txtLog.ScrollToEnd();
+ });
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/app.config
new file mode 100644
index 000000000..5d794b958
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/app.config
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/packages.config
new file mode 100644
index 000000000..a29d1ec82
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Stubs/packages.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CommonServiceLocator" version="1.3" targetFramework="net46" />
+ <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" />
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
+ <package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />
+ <package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />
+ <package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" />
+ <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net46" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net46" />
+</packages> \ No newline at end of file