aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy <roy.mail.net@gmail.com>2017-11-12 10:31:01 +0200
committerRoy <roy.mail.net@gmail.com>2017-11-12 10:31:01 +0200
commit255c97282edaf2e0e17ce3ad253653c36dd56243 (patch)
treee50a412fb877af2da5fa45c0a6a68710844f34f3 /Software
parent5af3faff68fb32e0f7da874eb0c4652b8c282183 (diff)
downloadTango-255c97282edaf2e0e17ce3ad253653c36dd56243.tar.gz
Tango-255c97282edaf2e0e17ce3ad253653c36dd56243.zip
Fix previous commit ?
Diffstat (limited to 'Software')
-rw-r--r--Software/PMR/Messages/Common/MessageType.proto6
-rw-r--r--Software/PMR/Messages/Stubs/Calculate.proto10
-rw-r--r--Software/PMR/Messages/Stubs/Progress.proto14
-rw-r--r--Software/Visual Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs137
-rw-r--r--Software/Visual Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs33
-rw-r--r--Software/Visual Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs124
-rw-r--r--Software/Visual Studio/Tango.Core/ExtensionMethods/StringExtensions.cs24
-rw-r--r--Software/Visual Studio/Tango.Core/Helpers/AssemblyHelper.cs2
-rw-r--r--Software/Visual Studio/Tango.Core/Helpers/PathHelper.cs2
-rw-r--r--Software/Visual Studio/Tango.Core/IParameterized.cs21
-rw-r--r--Software/Visual Studio/Tango.Core/ParameterIgnoreAttribute.cs17
-rw-r--r--Software/Visual Studio/Tango.Core/ParameterItem.cs157
-rw-r--r--Software/Visual Studio/Tango.Core/ParameterItemAttribute.cs140
-rw-r--r--Software/Visual Studio/Tango.Core/ParameterItemMode.cs23
-rw-r--r--Software/Visual Studio/Tango.Core/Tango.Core.csproj9
-rw-r--r--Software/Visual Studio/Tango.Emulations/Emulators/MachineEmulator.cs25
-rw-r--r--Software/Visual Studio/Tango.PMR/Common/MessageType.cs15
-rw-r--r--Software/Visual Studio/Tango.PMR/Stubs/Calculate.cs (renamed from Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs)131
-rw-r--r--Software/Visual Studio/Tango.PMR/Stubs/Progress.cs249
-rw-r--r--Software/Visual Studio/Tango.PMR/Tango.PMR.csproj3
-rw-r--r--Software/Visual Studio/Tango.Protobuf/Compilers/JavaCompiler.cs2
-rw-r--r--Software/Visual Studio/Tango.Protobuf/ProtoCompiler.cs4
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml11
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs473
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs42
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs23
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs24
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/IsEnumConverter.cs24
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/IsNullConverter.cs23
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs47
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Converters/StringFormatConverter.cs42
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs45
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs58
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml45
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs177
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml129
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs242
-rw-r--r--Software/Visual Studio/Tango.SharedUI/Tango.SharedUI.csproj42
-rw-r--r--Software/Visual Studio/Tango.SharedUI/packages.config4
-rw-r--r--Software/Visual Studio/Tango.Stubs/AvailableStub.cs30
-rw-r--r--Software/Visual Studio/Tango.Stubs/IStub.cs16
-rw-r--r--Software/Visual Studio/Tango.Stubs/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual Studio/Tango.Stubs/StubAttribute.cs21
-rw-r--r--Software/Visual Studio/Tango.Stubs/StubBase.cs83
-rw-r--r--Software/Visual Studio/Tango.Stubs/StubState.cs17
-rw-r--r--Software/Visual Studio/Tango.Stubs/Stubs/Calculate.cs36
-rw-r--r--Software/Visual Studio/Tango.Stubs/Stubs/Progress.cs30
-rw-r--r--Software/Visual Studio/Tango.Stubs/Tango.Stubs.csproj92
-rw-r--r--Software/Visual Studio/Tango.Stubs/packages.config4
-rw-r--r--Software/Visual Studio/Tango.Transport/ITransporter.cs22
-rw-r--r--Software/Visual Studio/Tango.Transport/TransportMessage.cs11
-rw-r--r--Software/Visual Studio/Tango.Transport/TransportMessageBase.cs11
-rw-r--r--Software/Visual Studio/Tango.Transport/TransporterBase.cs56
-rw-r--r--Software/Visual Studio/Tango.sln6
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml8
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs10
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml55
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs22
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj29
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs30
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs41
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs63
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs42
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml29
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs29
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml73
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs33
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml28
-rw-r--r--Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs36
69 files changed, 3444 insertions, 124 deletions
diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto
index 857e6874c..2f37c807b 100644
--- a/Software/PMR/Messages/Common/MessageType.proto
+++ b/Software/PMR/Messages/Common/MessageType.proto
@@ -8,6 +8,8 @@ enum MessageType
RGB = 0;
Job = 1;
Segment = 2;
- Stub1Request = 3;
- Stub1Response = 4;
+ CalculateRequest = 3;
+ CalculateResponse = 4;
+ ProgressRequest = 5;
+ ProgressResponse = 6;
}
diff --git a/Software/PMR/Messages/Stubs/Calculate.proto b/Software/PMR/Messages/Stubs/Calculate.proto
index e202613ff..197b327e7 100644
--- a/Software/PMR/Messages/Stubs/Calculate.proto
+++ b/Software/PMR/Messages/Stubs/Calculate.proto
@@ -3,13 +3,13 @@ syntax = "proto3";
package Tango.PMR.Stubs;
option java_package = "com.twine.tango.pmr.stubs";
-message Stub1Request
+message CalculateRequest
{
- int32 A = 1;
- int32 B = 2;
+ double A = 1;
+ double B = 2;
}
-message Stub1Response
+message CalculateResponse
{
- int32 Sum = 1;
+ double Sum = 1;
} \ No newline at end of file
diff --git a/Software/PMR/Messages/Stubs/Progress.proto b/Software/PMR/Messages/Stubs/Progress.proto
new file mode 100644
index 000000000..3a5222a30
--- /dev/null
+++ b/Software/PMR/Messages/Stubs/Progress.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package Tango.PMR.Stubs;
+option java_package = "com.twine.tango.pmr.stubs";
+
+message ProgressRequest
+{
+
+}
+
+message ProgressResponse
+{
+ double Progress = 1;
+} \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs b/Software/Visual Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs
new file mode 100644
index 000000000..16fd43728
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+/// <exclude/>
+/// <summary>
+/// Contains a collection of DependencyObject extension methods.
+/// </summary>
+public static class DependencyObjectExtensions
+{
+ /// <summary>
+ /// Invokes the current dependency object dispatcher.
+ /// </summary>
+ /// <param name="dependencyObject">The dependency object.</param>
+ /// <param name="action">The action.</param>
+ public static void BeginInvoke(this DependencyObject dependencyObject, Action action)
+ {
+ dependencyObject.Dispatcher.BeginInvoke(action);
+ }
+
+ /// <summary>
+ /// Invokes the specified action.
+ /// </summary>
+ /// <param name="dependencyObject">The dependency object.</param>
+ /// <param name="action">The action.</param>
+ public static void Invoke(this DependencyObject dependencyObject, Action action)
+ {
+ dependencyObject.Dispatcher.Invoke(action);
+ }
+
+ /// <summary>
+ /// Determines whether this object is currently in design time mode.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns></returns>
+ public static bool IsInDesignMode(this DependencyObject obj)
+ {
+ return (DesignerProperties.GetIsInDesignMode(obj));
+ }
+
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <param name="converter">Binding converter.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode, IValueConverter converter = null)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ binding.Converter = converter;
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Create asynchronous binding between target and source.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding BindAsync(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ binding.IsAsync = true;
+ binding.BindsDirectlyToSource = true;
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property name.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, String sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Clears bindings from the specified dependency property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="dependencyProperty">The dependency property.</param>
+ public static void Unbind(this DependencyObject target, DependencyProperty dependencyProperty)
+ {
+ BindingOperations.ClearBinding(target, dependencyProperty);
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs b/Software/Visual Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs
new file mode 100644
index 000000000..106dd4f44
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+public static class EnumExtensions
+{
+ /// <summary>
+ /// Gets the Enum value description.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns></returns>
+ public static String ToDescription(this Enum value)
+ {
+ FieldInfo fi = value.GetType().GetField(value.ToString());
+
+ DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
+
+ if (attributes != null &&
+ attributes.Length > 0)
+ return attributes[0].Description;
+ else
+ return value.ToString();
+ }
+
+ public static int ToInt32(this Enum value)
+ {
+ return (int)((object)value);
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs b/Software/Visual Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs
new file mode 100644
index 000000000..5ee853f35
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core;
+
+/// <summary>
+/// Contains extension methods for <see cref="IParameterized"/>.
+/// </summary>
+public static class IParameterizedExtensions
+{
+ /// <summary>
+ /// Creates an observable collection of the parameterized object.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="mode">The parameters update mode.</param>
+ /// <returns></returns>
+ public static ObservableCollection<ParameterItem> CreateParametersCollection(this IParameterized instance, ParameterItemMode mode)
+ {
+ var ps = new ObservableCollection<ParameterItem>();
+
+ int index = 0;
+
+ List<Type> types = new List<Type>();
+ Type currentType = instance.GetType();
+
+ while (true)
+ {
+ if (typeof(IParameterized).IsAssignableFrom(currentType) && currentType != typeof(IParameterized))
+ {
+ types.Add(currentType);
+ currentType = currentType.BaseType;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ List<PropertyInfo> properties = new List<PropertyInfo>();
+
+ foreach (var type in types)
+ {
+ foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ var paramAtt = prop.GetCustomAttributes(typeof(ParameterItemAttribute), false).Cast<ParameterItemAttribute>().FirstOrDefault();
+ var ignore = prop.GetCustomAttributes(typeof(ParameterIgnoreAttribute), false).Cast<ParameterIgnoreAttribute>().FirstOrDefault();
+
+ if (ignore == null && !properties.Exists(x => x.Name == prop.Name))
+ {
+ var item = instance.CreateParameterItem(prop, paramAtt, index++, mode);
+ ps.Add(item);
+ properties.Add(prop);
+ }
+ }
+ }
+
+ return ps;
+ }
+
+ /// <summary>
+ /// Creates the parameter item.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="propertyInfo">The property information.</param>
+ /// <param name="attribute">The attribute.</param>
+ /// <param name="index">The index.</param>
+ /// <param name="mode">The mode.</param>
+ /// <returns></returns>
+ public static ParameterItem CreateParameterItem(this IParameterized instance, PropertyInfo propertyInfo, ParameterItemAttribute attribute, int index, ParameterItemMode mode)
+ {
+ ParameterItem item = new ParameterItem();
+ item.Name = propertyInfo.Name.ToTitle();
+ item.Index = index;
+ item.Type = propertyInfo.PropertyType;
+ item.Value = propertyInfo.GetValue(instance, null);
+
+ if (attribute != null)
+ {
+ item.Minimum = attribute.Minimum;
+ item.Maximum = attribute.Maximum;
+ item.CustomEditorTypeName = attribute.CustomEditorTypeName;
+ item.ExtraObject = attribute.ExtraObject;
+
+ if (attribute.Name != null)
+ {
+ item.Name = attribute.Name;
+ }
+ }
+
+ if (mode == ParameterItemMode.Event)
+ {
+ item.ParameterValueChanged += (sender, e) =>
+ {
+ propertyInfo.SetValue(instance, e.Value);
+ };
+ }
+ else if (mode == ParameterItemMode.Binding)
+ {
+ item.Bind(ParameterItem.ValueProperty, instance as DependencyObject, propertyInfo.Name, System.Windows.Data.BindingMode.TwoWay);
+ }
+
+ return item;
+ }
+
+ /// <summary>
+ /// Creates the parameter item.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="propertyName">Name of the property.</param>
+ /// <param name="attribute">The attribute.</param>
+ /// <param name="index">The index.</param>
+ /// <param name="mode">The mode.</param>
+ /// <returns></returns>
+ public static ParameterItem CreateParameterItem(this IParameterized instance, String propertyName, ParameterItemAttribute attribute, int index, ParameterItemMode mode)
+ {
+ return instance.CreateParameterItem(instance.GetType().GetProperty(propertyName), attribute, index, mode);
+ }
+}
+
diff --git a/Software/Visual Studio/Tango.Core/ExtensionMethods/StringExtensions.cs b/Software/Visual Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
index 049c9c4af..5699d27a0 100644
--- a/Software/Visual Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
+++ b/Software/Visual Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
@@ -2,10 +2,24 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
public static class StringExtensions
{
+ private static Regex titleRegEx;
+
+ /// <summary>
+ /// Initializes the <see cref="StringExtensions"/> class.
+ /// </summary>
+ static StringExtensions()
+ {
+ titleRegEx = new Regex(@"
+ (?<=[A-Z])(?=[A-Z][a-z]) |
+ (?<=[^A-Z])(?=[A-Z]) |
+ (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
+ }
+
/// <summary>
/// Normal ToString conversion with null checking.
/// </summary>
@@ -25,4 +39,14 @@ public static class StringExtensions
{
return str.Split(new[] { '\r', '\n' }).ToList();
}
+
+ /// <summary>
+ /// Formats the string to title style.
+ /// </summary>
+ /// <param name="str">The string.</param>
+ /// <returns></returns>
+ public static String ToTitle(this String str)
+ {
+ return titleRegEx.Replace(str, " ");
+ }
}
diff --git a/Software/Visual Studio/Tango.Core/Helpers/AssemblyHelper.cs b/Software/Visual Studio/Tango.Core/Helpers/AssemblyHelper.cs
index 405020e66..d3322514a 100644
--- a/Software/Visual Studio/Tango.Core/Helpers/AssemblyHelper.cs
+++ b/Software/Visual Studio/Tango.Core/Helpers/AssemblyHelper.cs
@@ -6,7 +6,7 @@ using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-namespace Tango.Core.Helpers
+namespace Tango.SharedUI.Helpers
{
public static class AssemblyHelper
{
diff --git a/Software/Visual Studio/Tango.Core/Helpers/PathHelper.cs b/Software/Visual Studio/Tango.Core/Helpers/PathHelper.cs
index fa52eb42b..c375722e7 100644
--- a/Software/Visual Studio/Tango.Core/Helpers/PathHelper.cs
+++ b/Software/Visual Studio/Tango.Core/Helpers/PathHelper.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Tango.Core.Helpers
+namespace Tango.SharedUI.Helpers
{
public static class PathHelper
{
diff --git a/Software/Visual Studio/Tango.Core/IParameterized.cs b/Software/Visual Studio/Tango.Core/IParameterized.cs
new file mode 100644
index 000000000..e6f36b4c6
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/IParameterized.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a component that exposes some of it's properties as an observable collection of <see cref="ParameterItem"/> which can be bound to UI controls.
+ /// </summary>
+ public interface IParameterized
+ {
+ /// <summary>
+ /// Gets a bind-able observable collection of the component properties.
+ /// </summary>
+ [ParameterIgnore]
+ ReadOnlyObservableCollection<ParameterItem> Parameters { get; set; }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/ParameterIgnoreAttribute.cs b/Software/Visual Studio/Tango.Core/ParameterIgnoreAttribute.cs
new file mode 100644
index 000000000..0bbca6a06
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ParameterIgnoreAttribute.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents an attribute for specifying properties to ignore as parameters.
+ /// </summary>
+ /// <seealso cref="System.Attribute" />
+ public class ParameterIgnoreAttribute : Attribute
+ {
+
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/ParameterItem.cs b/Software/Visual Studio/Tango.Core/ParameterItem.cs
new file mode 100644
index 000000000..53a3df269
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ParameterItem.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a component parameter name and value which can be bound to UI elements.
+ /// </summary>
+ /// <seealso cref="System.Windows.DependencyObject" />
+ public class ParameterItem : DependencyObject
+ {
+ internal bool disableParamEvent;
+
+ /// <summary>
+ /// Occurs when the parameter value has changed.
+ /// </summary>
+ public event EventHandler<ParameterItem> ParameterValueChanged;
+
+ /// <summary>
+ /// Gets or sets the parameter index.
+ /// </summary>
+ public int Index
+ {
+ get { return (int)GetValue(IndexProperty); }
+ set { SetValue(IndexProperty, value); }
+ }
+ public static readonly DependencyProperty IndexProperty =
+ DependencyProperty.Register("Index", typeof(int), typeof(ParameterItem), new PropertyMetadata(0));
+
+ /// <summary>
+ /// Gets or sets the parameter value type.
+ /// </summary>
+ public Type Type
+ {
+ get { return (Type)GetValue(TypeProperty); }
+ set { SetValue(TypeProperty, value); }
+ }
+ public static readonly DependencyProperty TypeProperty =
+ DependencyProperty.Register("Type", typeof(Type), typeof(ParameterItem), new PropertyMetadata(typeof(double)));
+
+
+ /// <summary>
+ /// Gets or sets the parameter name.
+ /// </summary>
+ public String Name
+ {
+ get { return (String)GetValue(NameProperty); }
+ set { SetValue(NameProperty, value); }
+ }
+ public static readonly DependencyProperty NameProperty =
+ DependencyProperty.Register("Name", typeof(String), typeof(ParameterItem), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the current parameter value.
+ /// </summary>
+ public object Value
+ {
+ get { return (object)GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+ public static readonly DependencyProperty ValueProperty =
+ DependencyProperty.Register("Value", typeof(object), typeof(ParameterItem), new PropertyMetadata(null, new PropertyChangedCallback(OnValueChanged)));
+
+
+ /// <summary>
+ /// Gets or sets the minimum parameter value.
+ /// </summary>
+ public object Minimum
+ {
+ get { return (object)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(object), typeof(ParameterItem), new PropertyMetadata(0.0d));
+
+
+ /// <summary>
+ /// Gets or sets the maximum parameter value.
+ /// </summary>
+ public object Maximum
+ {
+ get { return (object)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(object), typeof(ParameterItem), new PropertyMetadata(1.0d));
+
+
+ /// <summary>
+ /// Gets or sets an optional extra object.
+ /// </summary>
+ public object ExtraObject
+ {
+ get { return (object)GetValue(ExtraObjectProperty); }
+ set { SetValue(ExtraObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ExtraObjectProperty =
+ DependencyProperty.Register("ExtraObject", typeof(object), typeof(ParameterItem), new PropertyMetadata(null));
+
+
+ /// <summary>
+ /// Gets or sets an optional custom editor.
+ /// </summary>
+ public String CustomEditorTypeName
+ {
+ get { return (String)GetValue(CustomEditorTypeNameProperty); }
+ set { SetValue(CustomEditorTypeNameProperty, value); }
+ }
+ public static readonly DependencyProperty CustomEditorTypeNameProperty =
+ DependencyProperty.Register("CustomEditorType", typeof(String), typeof(ParameterItem), new PropertyMetadata(null));
+
+
+ /// <summary>
+ /// Gets a value indicating whether this instance requires custom editor.
+ /// </summary>
+ public bool HasCustomEditor
+ {
+ get { return CustomEditorTypeName != null; }
+ }
+
+ /// <summary>
+ /// Called when value has changed.
+ /// </summary>
+ /// <param name="d">The d.</param>
+ /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+ private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ (d as ParameterItem).OnParameterChanged();
+ }
+
+ /// <summary>
+ /// Called when the parameter value has changed.
+ /// </summary>
+ protected virtual void OnParameterChanged()
+ {
+ if (!disableParamEvent)
+ {
+ if (ParameterValueChanged != null) ParameterValueChanged(this, this);
+ }
+ }
+
+ /// <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/Tango.Core/ParameterItemAttribute.cs b/Software/Visual Studio/Tango.Core/ParameterItemAttribute.cs
new file mode 100644
index 000000000..68405fe64
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ParameterItemAttribute.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a parameter item attribute for used for default, min and max values definition of properties.
+ /// </summary>
+ /// <seealso cref="System.Attribute" />
+ public class ParameterItemAttribute : Attribute
+ {
+ /// <summary>
+ /// Gets or sets the custom parameter name.
+ /// </summary>
+ public String Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default value.
+ /// </summary>
+ public object Default { get; set; }
+
+ /// <summary>
+ /// Gets or sets the minimum value.
+ /// </summary>
+ public object Minimum { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum value.
+ /// </summary>
+ public object Maximum { get; set; }
+
+ /// <summary>
+ /// Gets or sets an optional extra object.
+ /// </summary>
+ public object ExtraObject { get; set; }
+
+ /// <summary>
+ /// Gets or sets an optional custom editor type name.
+ /// </summary>
+ public String CustomEditorTypeName { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ public ParameterItemAttribute()
+ {
+ Default = null;
+ Minimum = 0.0d;
+ Maximum = 1.0d;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ public ParameterItemAttribute(String name, object minimumValue, object maximumValue, object defaultValue) : this()
+ {
+ Name = name;
+ Default = defaultValue;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ public ParameterItemAttribute(String name, object minimumValue, double maximumValue) : this(name, minimumValue, maximumValue, null)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ public ParameterItemAttribute(object minimumValue, object maximumValue) : this()
+ {
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="customParameterEditorTypeName">Type of the custom parameter editor type name.</param>
+ public ParameterItemAttribute(String customParameterEditorTypeName) : this()
+ {
+ CustomEditorTypeName = customParameterEditorTypeName;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="customParameterEditorTypeName">Name of the custom parameter editor type.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ /// <param name="extraObject">The extra object.</param>
+ public ParameterItemAttribute(String name, String customParameterEditorTypeName, object minimumValue, object maximumValue, object defaultValue, object extraObject) : this()
+ {
+ Name = name;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ Default = defaultValue;
+ CustomEditorTypeName = customParameterEditorTypeName;
+ ExtraObject = extraObject;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="customParameterEditorTypeName">Custom parameter editor type.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ /// <param name="extraObject">The extra object.</param>
+ public ParameterItemAttribute(String name, Type customParameterEditorType, object minimumValue, object maximumValue, object defaultValue, object extraObject)
+ : this()
+ {
+ Name = name;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ Default = defaultValue;
+ CustomEditorTypeName = customParameterEditorType.AssemblyQualifiedName;
+ ExtraObject = extraObject;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/ParameterItemMode.cs b/Software/Visual Studio/Tango.Core/ParameterItemMode.cs
new file mode 100644
index 000000000..71cb0f139
--- /dev/null
+++ b/Software/Visual Studio/Tango.Core/ParameterItemMode.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a <see cref="ParameterItem"/> update mode.
+ /// </summary>
+ public enum ParameterItemMode
+ {
+ /// <summary>
+ /// Update by binding.
+ /// </summary>
+ Binding,
+ /// <summary>
+ /// Update by event.
+ /// </summary>
+ Event
+ }
+}
diff --git a/Software/Visual Studio/Tango.Core/Tango.Core.csproj b/Software/Visual Studio/Tango.Core/Tango.Core.csproj
index 7b469bfdc..012f95f5e 100644
--- a/Software/Visual Studio/Tango.Core/Tango.Core.csproj
+++ b/Software/Visual Studio/Tango.Core/Tango.Core.csproj
@@ -35,6 +35,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows" />
+ <Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -47,9 +48,17 @@
<Compile Include="..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
+ <Compile Include="ExtensionMethods\DependencyObjectExtensions.cs" />
+ <Compile Include="ExtensionMethods\EnumExtensions.cs" />
+ <Compile Include="ExtensionMethods\IParameterizedExtensions.cs" />
<Compile Include="ExtensionMethods\StringExtensions.cs" />
<Compile Include="Helpers\AssemblyHelper.cs" />
<Compile Include="Helpers\PathHelper.cs" />
+ <Compile Include="IParameterized.cs" />
+ <Compile Include="ParameterIgnoreAttribute.cs" />
+ <Compile Include="ParameterItem.cs" />
+ <Compile Include="ParameterItemAttribute.cs" />
+ <Compile Include="ParameterItemMode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/Software/Visual Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual Studio/Tango.Emulations/Emulators/MachineEmulator.cs
index 8c986cb95..c84a3e3ee 100644
--- a/Software/Visual Studio/Tango.Emulations/Emulators/MachineEmulator.cs
+++ b/Software/Visual Studio/Tango.Emulations/Emulators/MachineEmulator.cs
@@ -51,17 +51,32 @@ namespace Tango.Emulations.Emulators
{
switch (container.Type)
{
- case MessageType.Stub1Request:
+ case MessageType.CalculateRequest:
Task.Factory.StartNew(() =>
{
- Thread.Sleep(1000);
- var request = MessageFactory.ParseContainer<Stub1Request>(container);
- var response = MessageFactory.CreateContainer<Stub1Response>(container.Token);
+ Thread.Sleep(2000);
+ var request = MessageFactory.ParseContainer<CalculateRequest>(container);
+ var response = MessageFactory.CreateContainer<CalculateResponse>(container.Token);
response.Message.Sum = request.A + request.B;
- response.Container.Token = container.Token;
Transporter.SendResponse(response);
});
break;
+ case MessageType.ProgressRequest:
+
+ var r = MessageFactory.ParseContainer<ProgressRequest>(container);
+
+ Task.Factory.StartNew(() =>
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ Thread.Sleep(500);
+ var res = MessageFactory.CreateContainer<ProgressResponse>(container.Token);
+ res.Message.Progress = i;
+ Transporter.SendResponse(res);
+ }
+ });
+
+ break;
}
}
diff --git a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
index c2ca7a47d..0012627bb 100644
--- a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
+++ b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs
@@ -22,10 +22,11 @@ namespace Tango.PMR.Common {
static MessageTypeReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbipRCgtNZXNz",
- "YWdlVHlwZRIHCgNSR0IQABIHCgNKb2IQARILCgdTZWdtZW50EAISEAoMU3R1",
- "YjFSZXF1ZXN0EAMSEQoNU3R1YjFSZXNwb25zZRAEQhwKGmNvbS50d2luZS50",
- "YW5nby5wbXIuY29tbW9uYgZwcm90bzM="));
+ "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiqEAQoLTWVz",
+ "c2FnZVR5cGUSBwoDUkdCEAASBwoDSm9iEAESCwoHU2VnbWVudBACEhQKEENh",
+ "bGN1bGF0ZVJlcXVlc3QQAxIVChFDYWxjdWxhdGVSZXNwb25zZRAEEhMKD1By",
+ "b2dyZXNzUmVxdWVzdBAFEhQKEFByb2dyZXNzUmVzcG9uc2UQBkIcChpjb20u",
+ "dHdpbmUudGFuZ28ucG1yLmNvbW1vbmIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null));
@@ -38,8 +39,10 @@ namespace Tango.PMR.Common {
[pbr::OriginalName("RGB")] Rgb = 0,
[pbr::OriginalName("Job")] Job = 1,
[pbr::OriginalName("Segment")] Segment = 2,
- [pbr::OriginalName("Stub1Request")] Stub1Request = 3,
- [pbr::OriginalName("Stub1Response")] Stub1Response = 4,
+ [pbr::OriginalName("CalculateRequest")] CalculateRequest = 3,
+ [pbr::OriginalName("CalculateResponse")] CalculateResponse = 4,
+ [pbr::OriginalName("ProgressRequest")] ProgressRequest = 5,
+ [pbr::OriginalName("ProgressResponse")] ProgressResponse = 6,
}
#endregion
diff --git a/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs b/Software/Visual Studio/Tango.PMR/Stubs/Calculate.cs
index 7d4960e9b..75aa074e1 100644
--- a/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs
+++ b/Software/Visual Studio/Tango.PMR/Stubs/Calculate.cs
@@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: Stub1.proto
+// source: Calculate.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -9,41 +9,42 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Tango.PMR.Stubs {
- /// <summary>Holder for reflection information generated from Stub1.proto</summary>
- public static partial class Stub1Reflection {
+ /// <summary>Holder for reflection information generated from Calculate.proto</summary>
+ public static partial class CalculateReflection {
#region Descriptor
- /// <summary>File descriptor for Stub1.proto</summary>
+ /// <summary>File descriptor for Calculate.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
- static Stub1Reflection() {
+ static CalculateReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "CgtTdHViMS5wcm90bxIPVGFuZ28uUE1SLlN0dWJzIiQKDFN0dWIxUmVxdWVz",
- "dBIJCgFBGAEgASgFEgkKAUIYAiABKAUiHAoNU3R1YjFSZXNwb25zZRILCgNT",
- "dW0YASABKAVCGwoZY29tLnR3aW5lLnRhbmdvLnBtci5zdHVic2IGcHJvdG8z"));
+ "Cg9DYWxjdWxhdGUucHJvdG8SD1RhbmdvLlBNUi5TdHVicyIoChBDYWxjdWxh",
+ "dGVSZXF1ZXN0EgkKAUEYASABKAESCQoBQhgCIAEoASIgChFDYWxjdWxhdGVS",
+ "ZXNwb25zZRILCgNTdW0YASABKAFCGwoZY29tLnR3aW5lLnRhbmdvLnBtci5z",
+ "dHVic2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Request), global::Tango.PMR.Stubs.Stub1Request.Parser, new[]{ "A", "B" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Response), global::Tango.PMR.Stubs.Stub1Response.Parser, new[]{ "Sum" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.CalculateRequest), global::Tango.PMR.Stubs.CalculateRequest.Parser, new[]{ "A", "B" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.CalculateResponse), global::Tango.PMR.Stubs.CalculateResponse.Parser, new[]{ "Sum" }, null, null, null)
}));
}
#endregion
}
#region Messages
- public sealed partial class Stub1Request : pb::IMessage<Stub1Request> {
- private static readonly pb::MessageParser<Stub1Request> _parser = new pb::MessageParser<Stub1Request>(() => new Stub1Request());
+ public sealed partial class CalculateRequest : pb::IMessage<CalculateRequest> {
+ private static readonly pb::MessageParser<CalculateRequest> _parser = new pb::MessageParser<CalculateRequest>(() => new CalculateRequest());
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Stub1Request> Parser { get { return _parser; } }
+ public static pb::MessageParser<CalculateRequest> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[0]; }
+ get { return global::Tango.PMR.Stubs.CalculateReflection.Descriptor.MessageTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -52,28 +53,28 @@ namespace Tango.PMR.Stubs {
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Request() {
+ public CalculateRequest() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Request(Stub1Request other) : this() {
+ public CalculateRequest(CalculateRequest other) : this() {
a_ = other.a_;
b_ = other.b_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Request Clone() {
- return new Stub1Request(this);
+ public CalculateRequest Clone() {
+ return new CalculateRequest(this);
}
/// <summary>Field number for the "A" field.</summary>
public const int AFieldNumber = 1;
- private int a_;
+ private double a_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int A {
+ public double A {
get { return a_; }
set {
a_ = value;
@@ -82,9 +83,9 @@ namespace Tango.PMR.Stubs {
/// <summary>Field number for the "B" field.</summary>
public const int BFieldNumber = 2;
- private int b_;
+ private double b_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int B {
+ public double B {
get { return b_; }
set {
b_ = value;
@@ -93,11 +94,11 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
- return Equals(other as Stub1Request);
+ return Equals(other as CalculateRequest);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Stub1Request other) {
+ public bool Equals(CalculateRequest other) {
if (ReferenceEquals(other, null)) {
return false;
}
@@ -112,8 +113,8 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (A != 0) hash ^= A.GetHashCode();
- if (B != 0) hash ^= B.GetHashCode();
+ if (A != 0D) hash ^= A.GetHashCode();
+ if (B != 0D) hash ^= B.GetHashCode();
return hash;
}
@@ -124,37 +125,37 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (A != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(A);
+ if (A != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(A);
}
- if (B != 0) {
- output.WriteRawTag(16);
- output.WriteInt32(B);
+ if (B != 0D) {
+ output.WriteRawTag(17);
+ output.WriteDouble(B);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (A != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(A);
+ if (A != 0D) {
+ size += 1 + 8;
}
- if (B != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(B);
+ if (B != 0D) {
+ size += 1 + 8;
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Stub1Request other) {
+ public void MergeFrom(CalculateRequest other) {
if (other == null) {
return;
}
- if (other.A != 0) {
+ if (other.A != 0D) {
A = other.A;
}
- if (other.B != 0) {
+ if (other.B != 0D) {
B = other.B;
}
}
@@ -167,12 +168,12 @@ namespace Tango.PMR.Stubs {
default:
input.SkipLastField();
break;
- case 8: {
- A = input.ReadInt32();
+ case 9: {
+ A = input.ReadDouble();
break;
}
- case 16: {
- B = input.ReadInt32();
+ case 17: {
+ B = input.ReadDouble();
break;
}
}
@@ -181,14 +182,14 @@ namespace Tango.PMR.Stubs {
}
- public sealed partial class Stub1Response : pb::IMessage<Stub1Response> {
- private static readonly pb::MessageParser<Stub1Response> _parser = new pb::MessageParser<Stub1Response>(() => new Stub1Response());
+ public sealed partial class CalculateResponse : pb::IMessage<CalculateResponse> {
+ private static readonly pb::MessageParser<CalculateResponse> _parser = new pb::MessageParser<CalculateResponse>(() => new CalculateResponse());
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Stub1Response> Parser { get { return _parser; } }
+ public static pb::MessageParser<CalculateResponse> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[1]; }
+ get { return global::Tango.PMR.Stubs.CalculateReflection.Descriptor.MessageTypes[1]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -197,27 +198,27 @@ namespace Tango.PMR.Stubs {
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Response() {
+ public CalculateResponse() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Response(Stub1Response other) : this() {
+ public CalculateResponse(CalculateResponse other) : this() {
sum_ = other.sum_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Stub1Response Clone() {
- return new Stub1Response(this);
+ public CalculateResponse Clone() {
+ return new CalculateResponse(this);
}
/// <summary>Field number for the "Sum" field.</summary>
public const int SumFieldNumber = 1;
- private int sum_;
+ private double sum_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Sum {
+ public double Sum {
get { return sum_; }
set {
sum_ = value;
@@ -226,11 +227,11 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
- return Equals(other as Stub1Response);
+ return Equals(other as CalculateResponse);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Stub1Response other) {
+ public bool Equals(CalculateResponse other) {
if (ReferenceEquals(other, null)) {
return false;
}
@@ -244,7 +245,7 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Sum != 0) hash ^= Sum.GetHashCode();
+ if (Sum != 0D) hash ^= Sum.GetHashCode();
return hash;
}
@@ -255,27 +256,27 @@ namespace Tango.PMR.Stubs {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (Sum != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(Sum);
+ if (Sum != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(Sum);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (Sum != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Sum);
+ if (Sum != 0D) {
+ size += 1 + 8;
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Stub1Response other) {
+ public void MergeFrom(CalculateResponse other) {
if (other == null) {
return;
}
- if (other.Sum != 0) {
+ if (other.Sum != 0D) {
Sum = other.Sum;
}
}
@@ -288,8 +289,8 @@ namespace Tango.PMR.Stubs {
default:
input.SkipLastField();
break;
- case 8: {
- Sum = input.ReadInt32();
+ case 9: {
+ Sum = input.ReadDouble();
break;
}
}
diff --git a/Software/Visual Studio/Tango.PMR/Stubs/Progress.cs b/Software/Visual Studio/Tango.PMR/Stubs/Progress.cs
new file mode 100644
index 000000000..2a00e15de
--- /dev/null
+++ b/Software/Visual Studio/Tango.PMR/Stubs/Progress.cs
@@ -0,0 +1,249 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Progress.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Stubs {
+
+ /// <summary>Holder for reflection information generated from Progress.proto</summary>
+ public static partial class ProgressReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for Progress.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ProgressReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Cg5Qcm9ncmVzcy5wcm90bxIPVGFuZ28uUE1SLlN0dWJzIhEKD1Byb2dyZXNz",
+ "UmVxdWVzdCIkChBQcm9ncmVzc1Jlc3BvbnNlEhAKCFByb2dyZXNzGAEgASgB",
+ "QhsKGWNvbS50d2luZS50YW5nby5wbXIuc3R1YnNiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.ProgressRequest), global::Tango.PMR.Stubs.ProgressRequest.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.ProgressResponse), global::Tango.PMR.Stubs.ProgressResponse.Parser, new[]{ "Progress" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class ProgressRequest : pb::IMessage<ProgressRequest> {
+ private static readonly pb::MessageParser<ProgressRequest> _parser = new pb::MessageParser<ProgressRequest>(() => new ProgressRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ProgressRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.ProgressReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest(ProgressRequest other) : this() {
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest Clone() {
+ return new ProgressRequest(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ProgressRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ProgressRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ProgressRequest other) {
+ if (other == null) {
+ return;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class ProgressResponse : pb::IMessage<ProgressResponse> {
+ private static readonly pb::MessageParser<ProgressResponse> _parser = new pb::MessageParser<ProgressResponse>(() => new ProgressResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ProgressResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.ProgressReflection.Descriptor.MessageTypes[1]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse(ProgressResponse other) : this() {
+ progress_ = other.progress_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse Clone() {
+ return new ProgressResponse(this);
+ }
+
+ /// <summary>Field number for the "Progress" field.</summary>
+ public const int ProgressFieldNumber = 1;
+ private double progress_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double Progress {
+ get { return progress_; }
+ set {
+ progress_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ProgressResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ProgressResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Progress != other.Progress) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Progress != 0D) hash ^= Progress.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Progress != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(Progress);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Progress != 0D) {
+ size += 1 + 8;
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ProgressResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Progress != 0D) {
+ Progress = other.Progress;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 9: {
+ Progress = input.ReadDouble();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj
index 8039b352a..dd873fe90 100644
--- a/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj
+++ b/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj
@@ -53,7 +53,8 @@
<Compile Include="Jobs\Segment.cs" />
<Compile Include="MessageFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Stubs\Stub1.cs" />
+ <Compile Include="Stubs\Calculate.cs" />
+ <Compile Include="Stubs\Progress.cs" />
<Compile Include="TangoMessage.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Software/Visual Studio/Tango.Protobuf/Compilers/JavaCompiler.cs b/Software/Visual Studio/Tango.Protobuf/Compilers/JavaCompiler.cs
index 55f0cf77f..80d8961c3 100644
--- a/Software/Visual Studio/Tango.Protobuf/Compilers/JavaCompiler.cs
+++ b/Software/Visual Studio/Tango.Protobuf/Compilers/JavaCompiler.cs
@@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Tango.Core.Helpers;
+using Tango.SharedUI.Helpers;
using Tango.Logging;
namespace Tango.Protobuf.Compilers
diff --git a/Software/Visual Studio/Tango.Protobuf/ProtoCompiler.cs b/Software/Visual Studio/Tango.Protobuf/ProtoCompiler.cs
index c77199c21..c047b8680 100644
--- a/Software/Visual Studio/Tango.Protobuf/ProtoCompiler.cs
+++ b/Software/Visual Studio/Tango.Protobuf/ProtoCompiler.cs
@@ -6,8 +6,8 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-using Tango.Core;
-using Tango.Core.Helpers;
+using Tango.SharedUI;
+using Tango.SharedUI.Helpers;
using Tango.Logging;
namespace Tango.Protobuf
diff --git a/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml b/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml
new file mode 100644
index 000000000..33e3758a5
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml
@@ -0,0 +1,11 @@
+<UserControl x:Class="Tango.SharedUI.Controls.MultiTransitionControl"
+ 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:d="http://schemas.microsoft.com/expression/blend/2008"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="300" ClipToBounds="True">
+ <Grid x:Name="mainGrid">
+
+ </Grid>
+</UserControl>
diff --git a/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs b/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs
new file mode 100644
index 000000000..83cb49de2
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs
@@ -0,0 +1,473 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+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.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.SharedUI.Controls
+{
+ /// <summary>
+ /// Represents a control for holding a list of content controls and creates transition effects between them.
+ /// </summary>
+ public partial class MultiTransitionControl : UserControl
+ {
+ private int index;
+ private bool freezeAnimation;
+ private ContentControl element1 = null;
+ private ContentControl element2 = null;
+ private ContentControl fromElement;
+ private ContentControl toElement;
+ private Action navigationCompleteAction;
+ private bool _loaded;
+
+ #region Events
+ /// <summary>
+ /// Occurs when the transition has completed.
+ /// </summary>
+ public event Action<MultiTransitionControl> TransitionComplete;
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initialize a new instance of MultiTransitionControl.
+ /// </summary>
+ public MultiTransitionControl()
+ {
+ Controls = new List<ContentControl>();
+
+ index = 0;
+ InitializeComponent();
+ this.Loaded += MultiTransitionControl_Loaded;
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ private void MultiTransitionControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (!_loaded)
+ {
+ foreach (ContentControl control in Controls)
+ {
+ control.Visibility = System.Windows.Visibility.Hidden;
+ mainGrid.Children.Add(control);
+ }
+
+ if (Controls.Count > 0)
+ {
+ Controls[0].Visibility = System.Windows.Visibility.Visible;
+ SelectedControl = Controls[0];
+ fromElement = SelectedControl;
+ }
+
+ _loaded = true;
+ }
+ }
+
+ private void ani_BackCompleted(object sender, EventArgs e)
+ {
+ fromElement = toElement;
+ toElement = null;
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ index++;
+ freezeAnimation = false;
+ IsAnimating = false;
+
+ OnTransitionCompleted();
+ }
+
+ private void ani_NextCompleted(object sender, EventArgs e)
+ {
+ fromElement = toElement;
+ toElement = null;
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ index++;
+ freezeAnimation = false;
+ IsAnimating = false;
+
+ OnTransitionCompleted();
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the available content controls nested in the MultiTransitionControl.
+ /// </summary>
+ public List<ContentControl> Controls { get; set; }
+
+ /// <summary>
+ /// Gets or sets the transition style.
+ /// </summary>
+ public TransitionTypeEnum TransitionType
+ {
+ get { return (TransitionTypeEnum)GetValue(TransitionTypeProperty); }
+ set { SetValue(TransitionTypeProperty, value); }
+ }
+ public static readonly DependencyProperty TransitionTypeProperty =
+ DependencyProperty.Register("TransitionType", typeof(TransitionTypeEnum), typeof(MultiTransitionControl), new PropertyMetadata(TransitionTypeEnum.Fade) { PropertyChangedCallback = new PropertyChangedCallback(TransitionTypeChanged) });
+ private static void TransitionTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ (d as MultiTransitionControl).ResetTransformation();
+ }
+
+ /// <summary>
+ /// This is where the actual transition occurs.
+ /// </summary>
+ private double Mix
+ {
+ get { return (double)GetValue(MixProperty); }
+ set
+ {
+ SetValue(MixProperty, value);
+ if (!freezeAnimation)
+ {
+ UpdateMix(value);
+ }
+ }
+ }
+ private static readonly DependencyProperty MixProperty =
+ DependencyProperty.Register("Mix", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(new PropertyChangedCallback(MixChanged)));
+ private static void MixChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ MultiTransitionControl tr = d as MultiTransitionControl;
+ double value = (double)e.NewValue;
+ tr.UpdateMix(value);
+ }
+
+
+ /// <summary>
+ /// Gets or sets whether to always include a cross fade transition along with the selected transition style.
+ /// </summary>
+ public bool AlwaysFade
+ {
+ get { return (bool)GetValue(AlwaysFadeProperty); }
+ set { SetValue(AlwaysFadeProperty, value); }
+ }
+ public static readonly DependencyProperty AlwaysFadeProperty =
+ DependencyProperty.Register("AlwaysFade", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));
+
+
+ /// <summary>
+ /// Gets or sets the interval in milliseconds for the transition to complete.
+ /// </summary>
+ public int AnimationTime
+ {
+ get { return (int)GetValue(AnimationTimeProperty); }
+ set { SetValue(AnimationTimeProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationTimeProperty =
+ DependencyProperty.Register("AnimationTime", typeof(int), typeof(MultiTransitionControl), new PropertyMetadata(1000));
+
+
+ /// <summary>
+ /// Gets or sets the transition 'ease in' time.
+ /// </summary>
+ public double AnimationAcceleration
+ {
+ get { return (double)GetValue(AnimationAccelerationProperty); }
+ set { SetValue(AnimationAccelerationProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationAccelerationProperty =
+ DependencyProperty.Register("AnimationAcceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));
+
+
+ /// <summary>
+ /// Gets or sets the transition 'ease out' time.
+ /// </summary>
+ public double AnimationDeceleration
+ {
+ get { return (double)GetValue(AnimationDecelerationProperty); }
+ set { SetValue(AnimationDecelerationProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationDecelerationProperty =
+ DependencyProperty.Register("AnimationDeceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));
+
+
+ /// <summary>
+ /// Gets or sets whether a transition is taking place at the moment.
+ /// </summary>
+ public bool IsAnimating
+ {
+ get { return (bool)GetValue(IsAnimatingProperty); }
+ private set { SetValue(IsAnimatingProperty, value); }
+ }
+ public static readonly DependencyProperty IsAnimatingProperty =
+ DependencyProperty.Register("IsAnimating", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));
+
+
+ /// <summary>
+ /// Gets or sets currently visible content control.
+ /// </summary>
+ public ContentControl SelectedControl
+ {
+ get { return (ContentControl)GetValue(SelectedControlProperty); }
+ set { SetValue(SelectedControlProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedControlProperty =
+ DependencyProperty.Register("SelectedControl", typeof(ContentControl), typeof(MultiTransitionControl), new PropertyMetadata(null));
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Updates the mix.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ private void UpdateMix(double value)
+ {
+ if (freezeAnimation) return;
+
+ if (element1 == null || element2 == null)
+ {
+ return;
+ }
+
+ element1.Visibility = System.Windows.Visibility.Visible;
+ element2.Visibility = System.Windows.Visibility.Visible;
+
+ if (TransitionType == TransitionTypeEnum.Fade)
+ {
+ element1.RenderTransform = null;
+ element2.RenderTransform = null;
+ element1.Opacity = value;
+ element2.Opacity = 1 - value;
+ return;
+ }
+ else if (TransitionType == TransitionTypeEnum.Slide)
+ {
+ double v = value * 100;
+ v = (v * this.ActualWidth) / 100;
+ element2.RenderTransform = new TranslateTransform(v, 0);
+ element1.RenderTransform = new TranslateTransform(v - this.ActualWidth, 0);
+ }
+ else if (TransitionType == TransitionTypeEnum.Zoom)
+ {
+ element1.RenderTransformOrigin = new Point(0.5, 0.5);
+ element2.RenderTransformOrigin = new Point(0.5, 0.5);
+ element1.RenderTransform = new ScaleTransform(value, value);
+ element2.RenderTransform = new ScaleTransform(1 - value, 1 - value);
+ }
+ else if (TransitionType == TransitionTypeEnum.Spin)
+ {
+ double v = value * 100;
+ v = (v * 360) / 100;
+
+ var group1 = new TransformGroup();
+ group1.Children.Add(new RotateTransform(v));
+ group1.Children.Add(new ScaleTransform(value, value));
+
+ var group2 = new TransformGroup();
+ group2.Children.Add(new RotateTransform(360 - v));
+ group2.Children.Add(new ScaleTransform(1 - value, 1 - value));
+
+ element1.RenderTransform = group1;
+ element2.RenderTransform = group2;
+ }
+ else if (TransitionType == TransitionTypeEnum.Carousel)
+ {
+ double v = value * 100;
+ v = (v * this.ActualWidth) / 100;
+
+ var group1 = new TransformGroup();
+ group1.Children.Add(new ScaleTransform(value, value));
+ group1.Children.Add(new TranslateTransform(v - this.ActualWidth, 0));
+
+ var group2 = new TransformGroup();
+ group2.Children.Add(new TranslateTransform(v * 2, 0));
+ group2.Children.Add(new ScaleTransform(1 - value, 1 - value));
+
+ element1.RenderTransform = group1;
+ element2.RenderTransform = group2;
+ }
+ else if (TransitionType == TransitionTypeEnum.Skew)
+ {
+ double v = value * 100;
+ v = (v * 180) / 100;
+ element2.RenderTransform = new SkewTransform(v, 0);
+ element1.RenderTransform = new SkewTransform(v - 180, 0);
+ }
+ else if (TransitionType == TransitionTypeEnum.Push)
+ {
+ element1.RenderTransformOrigin = new Point(1, 0.5);
+ element2.RenderTransformOrigin = new Point(0, 0.5);
+ element1.RenderTransform = new ScaleTransform(value, 1);
+ element2.RenderTransform = new ScaleTransform(1 - value, 1);
+ }
+ if (AlwaysFade)
+ {
+ element1.Opacity = value;
+ element2.Opacity = 1 - value;
+ }
+ }
+
+ /// <summary>
+ /// Resets the transformation.
+ /// </summary>
+ private void ResetTransformation()
+ {
+ foreach (ContentControl control in Controls)
+ {
+ control.RenderTransformOrigin = new Point(0.5, 0.5);
+ }
+ }
+
+ /// <summary>
+ /// Execute a transition between the current selected control and the specified content control tag.
+ /// </summary>
+ /// <param name="tag">Tag of content control to navigate to.</param>
+ /// <param name="dataContext">DataContext to assign to the specified content control.</param>
+ /// <param name="navigationComplete">Navigation completed callback delegate.</param>
+ public void AutoNavigate(object tag, object dataContext = null, Action navigationComplete = null)
+ {
+ if (IsAnimating)
+ {
+ return;
+ }
+
+ ContentControl control = Controls.SingleOrDefault(x => x.Tag != null && x.Tag.ToString() == tag.ToString());
+
+ if (control == SelectedControl)
+ {
+ return;
+ }
+
+ if (control == null)
+ {
+ throw new Exception("Control with tag '" + tag.ToString() + "' not found! (Transition Control)");
+ }
+
+ if (dataContext != null)
+ {
+ control.DataContext = dataContext;
+ }
+
+ if (Controls.IndexOf(control) > Controls.IndexOf(fromElement))
+ {
+ navigationCompleteAction = navigationComplete;
+ toElement = control;
+ SelectedControl = control;
+ Next();
+ }
+ else if (Controls.IndexOf(control) < Controls.IndexOf(fromElement))
+ {
+ navigationCompleteAction = navigationComplete;
+ toElement = control;
+ SelectedControl = control;
+ Back();
+ }
+ }
+
+ private void Next()
+ {
+ if (IsAnimating)
+ {
+ return;
+ }
+
+ IsAnimating = true;
+
+ if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
+ {
+ element1 = toElement;
+ element2 = fromElement;
+ }
+ else
+ {
+ element1 = fromElement;
+ element2 = toElement;
+ }
+
+ if (element2 == null)
+ {
+ SelectedControl = Controls[0];
+ fromElement = SelectedControl;
+ element2 = fromElement;
+ }
+
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ freezeAnimation = false;
+
+ DoubleAnimation ani = new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
+ ani.AccelerationRatio = AnimationAcceleration;
+ ani.DecelerationRatio = AnimationDeceleration;
+ ani.Completed += ani_NextCompleted;
+ this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
+ }
+
+ private void Back()
+ {
+ if (IsAnimating) return;
+
+ IsAnimating = true;
+
+ if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
+ {
+ element1 = toElement;
+ element2 = fromElement;
+ }
+ else
+ {
+ element1 = fromElement;
+ element2 = toElement;
+ }
+
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 1;
+ freezeAnimation = false;
+
+ DoubleAnimation ani = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
+ ani.Completed += ani_BackCompleted;
+ ani.AccelerationRatio = AnimationAcceleration;
+ ani.DecelerationRatio = AnimationDeceleration;
+ this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
+ }
+
+ #endregion
+
+ #region Virtuals
+
+ /// <summary>
+ /// Called when [transition completed].
+ /// </summary>
+ protected virtual void OnTransitionCompleted()
+ {
+ if (TransitionComplete != null) TransitionComplete(this);
+
+ if (SelectedControl != null)
+ {
+ Panel.SetZIndex(SelectedControl, Controls.Max(x => Panel.GetZIndex(x)) + 1);
+ }
+
+ if (navigationCompleteAction != null)
+ {
+ navigationCompleteAction();
+ navigationCompleteAction = null;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs b/Software/Visual Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs
new file mode 100644
index 000000000..1a57c9d56
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Tango.SharedUI.Controls
+{
+ /// <summary>
+ /// Represents a MultiTransitionControl transition style.
+ /// </summary>
+ public enum TransitionTypeEnum
+ {
+ /// <summary>
+ /// Generate a cross fade between controls.
+ /// </summary>
+ Fade,
+ /// <summary>
+ /// Generate slide effect from left to right.
+ /// </summary>
+ Slide,
+ /// <summary>
+ /// Generate zoom in/out effect.
+ /// </summary>
+ Zoom,
+ /// <summary>
+ /// Generate twirl effect.
+ /// </summary>
+ Spin,
+ /// <summary>
+ /// Generate a carousel like slide effect.
+ /// </summary>
+ Carousel,
+ /// <summary>
+ /// Skew the controls to place.
+ /// </summary>
+ Skew,
+ /// <summary>
+ /// Generate an effect similar to slide but instead squeeze the controls.
+ /// </summary>
+ Push
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs
new file mode 100644
index 000000000..15ef23292
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class DoubleToIntConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return System.Convert.ToDouble(value);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return System.Convert.ToInt32(value);
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs
new file mode 100644
index 000000000..1699647bb
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class EnumToItemsSourceConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Type result = value as Type;
+ return Enum.GetValues(result).Cast<object>().Select(e => new { Value = e, DisplayName = (e as Enum).ToDescription() });
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/IsEnumConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/IsEnumConverter.cs
new file mode 100644
index 000000000..3404d3ea4
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/IsEnumConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class IsEnumConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Type t = value as Type;
+ return t.IsEnum;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/IsNullConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/IsNullConverter.cs
new file mode 100644
index 000000000..7c2b3494d
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/IsNullConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class IsNullConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value == null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs
new file mode 100644
index 000000000..3022ee07e
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.Core;
+using Tango.SharedUI.Editors;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class ParameterItemEditorTypeToEditorConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ try
+ {
+ ParameterItem item = values[0] as ParameterItem;
+
+ if (item != null)
+ {
+ Type editorType = Type.GetType(item.CustomEditorTypeName);
+
+ if (editorType != null)
+ {
+ IParameterItemEditor editor = Activator.CreateInstance(editorType) as IParameterItemEditor;
+ editor.ParameterItem = item;
+ editor.ParameterizedObject = values[1] as IParameterized;
+ return editor;
+ }
+ }
+
+ return null;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Converters/StringFormatConverter.cs b/Software/Visual Studio/Tango.SharedUI/Converters/StringFormatConverter.cs
new file mode 100644
index 000000000..19815f903
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Converters/StringFormatConverter.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class StringFormatConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ String stringValue = values[0].ToString();
+ String format = values[1] != null ? values[1].ToString() : null;
+ var resultString = Regex.Match(stringValue, @"^-?[0-9]\d*(\.\d+)?$").Value;
+
+ if (String.IsNullOrWhiteSpace(resultString)) return "";
+
+ if (resultString == "-") return resultString;
+
+ return System.Convert.ToDouble(resultString).ToString(format != null ? format : "");
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ String resultString;
+
+ if (value.ToString() == "-" || value.ToString() == ".")
+ {
+ resultString = value.ToString() + 0;
+ }
+ else
+ {
+ resultString = Regex.Match(value.ToString(), @"^-?[0-9]\d*(\.\d+)?$").Value;
+ }
+ return new object[] { System.Convert.ToDouble(String.IsNullOrWhiteSpace(resultString) ? "0" : resultString) };
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs b/Software/Visual Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs
new file mode 100644
index 000000000..2cc117bfd
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a custom <see cref="ParameterItem"/> editor.
+ /// </summary>
+ /// <example>
+ /// <para class="example-title">
+ /// <img class="exampleIcon" src="../Icons/CodeExample.png" />
+ /// <i>
+ /// The following example demonstrates how to implement the IParameterized interface, implement a custom parameter editor and use the ParameterizedEditor to display/edit the object.
+ /// </i>
+ /// </para>
+ /// <para><img class="exampleImage" src="../Media/ParameterizedEditorExample.png" /></para>
+ /// <i>Implement IParameterized.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/IParameterizedExample.cs" title="Implement IParameterized interface." />
+ /// <i>Custom editor.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml" title="Implement custom editor." />
+ /// <i>Custom editor code behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml.cs" title="Implement custom editor." />
+ /// <i>Use the ParameterizedEditor to display the parameterized object.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml" title="Use ParameterizedEditor." />
+ /// <i>Code-Behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml.cs" title="Use ParameterizedEditor." />
+ /// </example>
+ /// <seealso cref="IParameterized"/>
+ public interface IParameterItemEditor
+ {
+ /// <summary>
+ /// Gets or sets the parameter item.
+ /// </summary>
+ ParameterItem ParameterItem { get; set; }
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ IParameterized ParameterizedObject { get; set; }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs
new file mode 100644
index 000000000..bb0a321f5
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using Tango.Core;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a <see cref="ParameterItem"/> editor base class.
+ /// </summary>
+ public class ParameterItemEditor : UserControl, IParameterItemEditor
+ {
+ /// <summary>
+ /// Gets or sets the parameter item.
+ /// </summary>
+ public ParameterItem ParameterItem
+ {
+ get { return (ParameterItem)GetValue(ParameterItemProperty); }
+ set { SetValue(ParameterItemProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterItemProperty =
+ DependencyProperty.Register("ParameterItem", typeof(ParameterItem), typeof(ParameterItemEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ public IParameterized ParameterizedObject
+ {
+ get { return (IParameterized)GetValue(ParameterizedObjectProperty); }
+ set { SetValue(ParameterizedObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterizedObjectProperty =
+ DependencyProperty.Register("ParameterizedObject", typeof(IParameterized), typeof(ParameterItemEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemEditor"/> class.
+ /// </summary>
+ public ParameterItemEditor()
+ {
+ DataContext = ParameterItem;
+ this.Loaded += ParameterItemEditor_Loaded;
+ }
+
+ /// <summary>
+ /// Handles the Loaded event of the ParameterItemEditor control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void ParameterItemEditor_Loaded(object sender, RoutedEventArgs e)
+ {
+ DataContext = ParameterItem;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml
new file mode 100644
index 000000000..57bf3f6ff
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml
@@ -0,0 +1,45 @@
+<local:ParameterItemEditor
+ 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:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Tango.SharedUI.Editors"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters"
+ x:Class="Tango.SharedUI.Editors.ParameterItemNumericUpDownEditor"
+ mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="150" Background="Transparent" BorderBrush="DimGray" BorderThickness="1">
+
+ <UserControl.Resources>
+ <converters:StringFormatConverter x:Key="StringFormatConverter"/>
+ </UserControl.Resources>
+
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="113*"/>
+ <ColumnDefinition Width="37*" MinWidth="30" />
+ </Grid.ColumnDefinitions>
+
+ <Grid Grid.Column="1">
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <RepeatButton x:Name="btnUp" Style="{x:Null}" Background="#151515" Click="btnUp_Click" Grid.Row="0" Padding="2" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <fa:ImageAwesome Icon="ArrowUp" Width="5" Height="5" Foreground="Gainsboro" />
+ </RepeatButton>
+ <RepeatButton x:Name="btnDown" Style="{x:Null}" Background="#151515" Click="btnDown_Click" Grid.Row="1" Padding="2" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <fa:ImageAwesome Icon="ArrowDown" Width="5" Height="5" Foreground="Gainsboro" />
+ </RepeatButton>
+ </Grid>
+
+ <Grid>
+ <TextBox x:Name="txtValue" KeyDown="txtValue_KeyDown" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}" VerticalContentAlignment="Center" Background="Transparent" HorizontalContentAlignment="Center" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <MultiBinding Converter="{StaticResource StringFormatConverter}" Mode="TwoWay">
+ <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}" Path="Value" Mode="TwoWay" />
+ <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}" Path="Format"/>
+ </MultiBinding>
+ </TextBox>
+ </Grid>
+ </Grid>
+</local:ParameterItemEditor>
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs
new file mode 100644
index 000000000..ddc046127
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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.SharedUI;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a simple numeric up down editor.
+ /// </summary>
+ public partial class ParameterItemNumericUpDownEditor : ParameterItemEditor
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemNumericUpDownEditor"/> class.
+ /// </summary>
+ public ParameterItemNumericUpDownEditor()
+ {
+ InitializeComponent();
+
+ this.Loaded += ParameterItemNumericUpDownEditor_Loaded;
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public double Value
+ {
+ get { return (double)GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+ public static readonly DependencyProperty ValueProperty =
+ DependencyProperty.Register("Value", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(0.0, null, (d, value) => { return (d as ParameterItemNumericUpDownEditor).OnCoerceValue((double)value); }));
+
+ /// <summary>
+ /// Gets or sets the minimum value.
+ /// </summary>
+ public double Minimum
+ {
+ get { return (double)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(0.0));
+
+ /// <summary>
+ /// Gets or sets the maximum value.
+ /// </summary>
+ public double Maximum
+ {
+ get { return (double)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(100.0));
+
+ /// <summary>
+ /// Gets or sets the tick frequency for the up/down buttons.
+ /// </summary>
+ public double Tick
+ {
+ get { return (double)GetValue(TickProperty); }
+ set { SetValue(TickProperty, value); }
+ }
+ public static readonly DependencyProperty TickProperty =
+ DependencyProperty.Register("Tick", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(1.0));
+
+ /// <summary>
+ /// Gets or sets the value display format.
+ /// </summary>
+ public String Format
+ {
+ get { return (String)GetValue(FormatProperty); }
+ set { SetValue(FormatProperty, value); }
+ }
+ public static readonly DependencyProperty FormatProperty =
+ DependencyProperty.Register("Format", typeof(String), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata("0.0"));
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the value is editable through keyboard.
+ /// </summary>
+ public bool IsReadOnly
+ {
+ get { return (bool)GetValue(IsReadOnlyProperty); }
+ set { SetValue(IsReadOnlyProperty, value); }
+ }
+ public static readonly DependencyProperty IsReadOnlyProperty =
+ DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(false));
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Invoked before the value has changed.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns></returns>
+ protected virtual object OnCoerceValue(double value)
+ {
+ if (value > Maximum) return Maximum;
+ if (value < Minimum) return Minimum;
+
+ return value;
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ /// <summary>
+ /// Handles the Click event of the btnUp control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void btnUp_Click(object sender, RoutedEventArgs e)
+ {
+ Value += Tick;
+ }
+
+ /// <summary>
+ /// Handles the Click event of the btnDown control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void btnDown_Click(object sender, RoutedEventArgs e)
+ {
+ Value -= Tick;
+ }
+
+ /// <summary>
+ /// Handles the KeyDown event of the txtValue control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
+ private void txtValue_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter || e.Key == Key.Escape)
+ {
+ BindingOperations.GetBindingExpressionBase((TextBox)txtValue, TextBox.TextProperty).UpdateSource();
+ }
+ }
+
+ /// <summary>
+ /// Handles the Loaded event of the ParameterItemNumericUpDownEditor control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void ParameterItemNumericUpDownEditor_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (ParameterItem != null)
+ {
+ Minimum = Convert.ToDouble(ParameterItem.Minimum);
+ Maximum = Convert.ToDouble(ParameterItem.Maximum);
+ this.Bind(ValueProperty, ParameterItem, Tango.Core.ParameterItem.ValueProperty, BindingMode.TwoWay);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml
new file mode 100644
index 000000000..d80852b73
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml
@@ -0,0 +1,129 @@
+<UserControl x:Class="Tango.SharedUI.Editors.ParameterizedEditor"
+ 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:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Tango.SharedUI.Editors"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+
+ <UserControl.Resources>
+ <converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter"></converters:EnumToItemsSourceConverter>
+ <converters:IsEnumConverter x:Key="IsEnumConverter"></converters:IsEnumConverter>
+ <converters:ParameterItemEditorTypeToEditorConverter x:Key="ParameterItemEditorTypeToEditorConverter"></converters:ParameterItemEditorTypeToEditorConverter>
+ <converters:DoubleToIntConverter x:Key="DoubleToIntConverter"></converters:DoubleToIntConverter>
+ <converters:IsNullConverter x:Key="IsNullConverter"></converters:IsNullConverter>
+ </UserControl.Resources>
+
+ <Grid>
+ <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Background="Transparent">
+ <ItemsControl Grid.Row="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ParameterizedObject.Parameters}" HorizontalContentAlignment="Stretch">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <ContentControl Content="{Binding}" Padding="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemPadding}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemMargin}" MinHeight="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemMinHeight}">
+ <ContentControl.Style>
+ <Style TargetType="ContentControl">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Resources>
+ <DataTemplate x:Key="slide">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <Slider Orientation="Horizontal" HorizontalAlignment="Stretch" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value}" ToolTip="{Binding Value}"></Slider>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="slideInteger">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <Slider TickFrequency="1" IsSnapToTickEnabled="True" Orientation="Horizontal" HorizontalAlignment="Stretch" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value,Converter={StaticResource DoubleToIntConverter}}"></Slider>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="numUpDown">
+ <Grid Margin="0 0 0 4" x:Name="grid">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ <TextBlock VerticalAlignment="Center" Grid.Column="0" Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <local:ParameterItemNumericUpDownEditor Grid.Column="1" Minimum="-10000" Maximum="10000" Height="25" Value="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=DataContext.Value,Mode=TwoWay}"></local:ParameterItemNumericUpDownEditor>
+ </Grid>
+ </DataTemplate>
+ <DataTemplate x:Key="enum">
+ <StackPanel Margin="0 0 0 4">
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <ComboBox Foreground="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Foreground}" ItemsSource="{Binding Type,Converter={StaticResource EnumToItemsSourceConverter},Mode=OneTime}" SelectedValue="{Binding Value}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="chk">
+ <CheckBox Margin="0 5 0 5" IsChecked="{Binding Value}" Foreground="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Foreground}" Content="{Binding Name}"></CheckBox>
+ </DataTemplate>
+ <DataTemplate x:Key="text">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="custom">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <ContentPresenter>
+ <ContentPresenter.Content>
+ <MultiBinding Converter="{StaticResource ParameterItemEditorTypeToEditorConverter}">
+ <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType=StackPanel}"></Binding>
+ <Binding Path="ParameterizedObject" RelativeSource="{RelativeSource AncestorType=local:ParameterizedEditor}"></Binding>
+ </MultiBinding>
+ </ContentPresenter.Content>
+ </ContentPresenter>
+ </StackPanel>
+ </DataTemplate>
+ </Style.Resources>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Double}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=DoubleTemplate,FallbackValue={StaticResource slide},TargetNullValue={StaticResource slide}}"></Setter>
+ </DataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Type}" Value="{x:Type sys:Double}"></Condition>
+ <Condition Binding="{Binding Maximum,Converter={StaticResource IsNullConverter}}" Value="True"></Condition>
+ <Condition Binding="{Binding Minimum,Converter={StaticResource IsNullConverter}}" Value="True"></Condition>
+ </MultiDataTrigger.Conditions>
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=DoubleUpDownTemplate,FallbackValue={StaticResource numUpDown},TargetNullValue={StaticResource numUpDown}}"></Setter>
+ </MultiDataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Int32}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Int32Template,FallbackValue={StaticResource slideInteger},TargetNullValue={StaticResource slideInteger}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Single}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=SingleTemplate,FallbackValue={StaticResource slide},TargetNullValue={StaticResource slide}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type,Converter={StaticResource IsEnumConverter}}" Value="True">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=EnumTemplate,FallbackValue={StaticResource enum},TargetNullValue={StaticResource enum}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Boolean}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=BooleanTemplate,FallbackValue={StaticResource chk},TargetNullValue={StaticResource chk}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:String}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=StringTemplate,FallbackValue={StaticResource text},TargetNullValue={StaticResource text}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding HasCustomEditor}" Value="True">
+ <Setter Property="ContentTemplate" Value="{StaticResource custom}"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ContentControl.Style>
+ </ContentControl>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs
new file mode 100644
index 000000000..f24cdb9af
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs
@@ -0,0 +1,242 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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.Core;
+using Tango.SharedUI;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// <para><img class="classImage" src="../Media/ParameterizedEditor.png" /></para>
+ /// Represents a scrollable list of auto generated editable controls for objects which inherits from <see cref="IParameterized"/>.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The following types are natively supported for display and edit:
+ /// </para>
+ /// <list type="bullet">
+ /// <item>Double</item>
+ /// <item>Single</item>
+ /// <item>Int32</item>
+ /// <item>Boolean</item>
+ /// <item>String</item>
+ /// <item>Point</item>
+ /// <item>Enum</item>
+ /// <item>Color</item>
+ /// <item>Brush</item>
+ /// </list>
+ /// <para>
+ /// See <see cref="IParameterItemEditor"/> to implement other property types using custom editors.
+ /// </para>
+ /// </remarks>
+ /// <example>
+ /// <para class="example-title">
+ /// <img class="exampleIcon" src="../Icons/CodeExample.png" />
+ /// <i>
+ /// The following example demonstrates how to implement the IParameterized interface, implement a custom parameter editor and use the ParameterizedEditor to display/edit the object.
+ /// </i>
+ /// </para>
+ /// <para><img class="exampleImage" src="../Media/ParameterizedEditorExample.png" /></para>
+ /// <i>Implement IParameterized.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/IParameterizedExample.cs" title="Implement IParameterized interface." />
+ /// <i>Custom editor.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml" title="Implement custom editor." />
+ /// <i>Custom editor code behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml.cs" title="Implement custom editor." />
+ /// <i>Use the ParameterizedEditor to display the parameterized object.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml" title="Use ParameterizedEditor." />
+ /// <i>Code-Behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml.cs" title="Use ParameterizedEditor." />
+ /// </example>
+ /// <seealso cref="Tango.SharedUI.HybridControl" />
+ public partial class ParameterizedEditor : UserControl
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterizedEditor"/> class.
+ /// </summary>
+ public ParameterizedEditor()
+ {
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ public IParameterized ParameterizedObject
+ {
+ get { return (IParameterized)GetValue(ParameterizedObjectProperty); }
+ set { SetValue(ParameterizedObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterizedObjectProperty =
+ DependencyProperty.Register("ParameterizedObject", typeof(IParameterized), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets a single item padding.
+ /// </summary>
+ public Thickness ItemPadding
+ {
+ get { return (Thickness)GetValue(ItemPaddingProperty); }
+ set { SetValue(ItemPaddingProperty, value); }
+ }
+ public static readonly DependencyProperty ItemPaddingProperty =
+ DependencyProperty.Register("ItemPadding", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ /// <summary>
+ /// Gets or sets a single item margin.
+ /// </summary>
+ public Thickness ItemMargin
+ {
+ get { return (Thickness)GetValue(ItemMarginProperty); }
+ set { SetValue(ItemMarginProperty, value); }
+ }
+ public static readonly DependencyProperty ItemMarginProperty =
+ DependencyProperty.Register("ItemMargin", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ /// <summary>
+ /// Gets or sets a single item minimum height.
+ /// </summary>
+ public double ItemMinHeight
+ {
+ get { return (double)GetValue(ItemMinHeightProperty); }
+ set { SetValue(ItemMinHeightProperty, value); }
+ }
+ public static readonly DependencyProperty ItemMinHeightProperty =
+ DependencyProperty.Register("ItemMinHeight", typeof(double), typeof(ParameterizedEditor), new PropertyMetadata(0.0));
+
+ /// <summary>
+ /// Gets or sets a single item label margin.
+ /// </summary>
+ public Thickness ItemLabelMargin
+ {
+ get { return (Thickness)GetValue(ItemLabelMarginProperty); }
+ set { SetValue(ItemLabelMarginProperty, value); }
+ }
+ public static readonly DependencyProperty ItemLabelMarginProperty =
+ DependencyProperty.Register("ItemLabelMargin", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ #region Templates
+
+ /// <summary>
+ /// Gets or sets the double template.
+ /// </summary>
+ public DataTemplate DoubleTemplate
+ {
+ get { return (DataTemplate)GetValue(DoubleTemplateProperty); }
+ set { SetValue(DoubleTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty DoubleTemplateProperty =
+ DependencyProperty.Register("DoubleTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the int32 template.
+ /// </summary>
+ public DataTemplate Int32Template
+ {
+ get { return (DataTemplate)GetValue(Int32TemplateProperty); }
+ set { SetValue(Int32TemplateProperty, value); }
+ }
+ public static readonly DependencyProperty Int32TemplateProperty =
+ DependencyProperty.Register("Int32Template", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the single template.
+ /// </summary>
+ public DataTemplate SingleTemplate
+ {
+ get { return (DataTemplate)GetValue(SingleTemplateProperty); }
+ set { SetValue(SingleTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty SingleTemplateProperty =
+ DependencyProperty.Register("SingleTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the double up down template.
+ /// </summary>
+ public DataTemplate DoubleUpDownTemplate
+ {
+ get { return (DataTemplate)GetValue(DoubleUpDownTemplateProperty); }
+ set { SetValue(DoubleUpDownTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty DoubleUpDownTemplateProperty =
+ DependencyProperty.Register("DoubleUpDownTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the boolean template.
+ /// </summary>
+ public DataTemplate BooleanTemplate
+ {
+ get { return (DataTemplate)GetValue(BooleanTemplateProperty); }
+ set { SetValue(BooleanTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty BooleanTemplateProperty =
+ DependencyProperty.Register("BooleanTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the enum template.
+ /// </summary>
+ public DataTemplate EnumTemplate
+ {
+ get { return (DataTemplate)GetValue(EnumTemplateProperty); }
+ set { SetValue(EnumTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty EnumTemplateProperty =
+ DependencyProperty.Register("EnumTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the color template.
+ /// </summary>
+ public DataTemplate ColorTemplate
+ {
+ get { return (DataTemplate)GetValue(ColorTemplateProperty); }
+ set { SetValue(ColorTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty ColorTemplateProperty =
+ DependencyProperty.Register("ColorTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the brush template.
+ /// </summary>
+ public DataTemplate BrushTemplate
+ {
+ get { return (DataTemplate)GetValue(BrushTemplateProperty); }
+ set { SetValue(BrushTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty BrushTemplateProperty =
+ DependencyProperty.Register("BrushTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the point template.
+ /// </summary>
+ public DataTemplate PointTemplate
+ {
+ get { return (DataTemplate)GetValue(PointTemplateProperty); }
+ set { SetValue(PointTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty PointTemplateProperty =
+ DependencyProperty.Register("PointTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the string template.
+ /// </summary>
+ public DataTemplate StringTemplate
+ {
+ get { return (DataTemplate)GetValue(StringTemplateProperty); }
+ set { SetValue(StringTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty StringTemplateProperty =
+ DependencyProperty.Register("StringTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ #endregion
+ }
+}
diff --git a/Software/Visual Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual Studio/Tango.SharedUI/Tango.SharedUI.csproj
index d01e7b2f3..c04c8692a 100644
--- a/Software/Visual Studio/Tango.SharedUI/Tango.SharedUI.csproj
+++ b/Software/Visual Studio/Tango.SharedUI/Tango.SharedUI.csproj
@@ -30,6 +30,9 @@
<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="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
@@ -49,14 +52,53 @@
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="Commands\RelayCommand.cs" />
+ <Compile Include="Controls\MultiTransitionControl.xaml.cs">
+ <DependentUpon>MultiTransitionControl.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\TransitionTypeEnum.cs" />
<Compile Include="Converters\BooleanInverseConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityInverseConverter.cs" />
+ <Compile Include="Converters\DoubleToIntConverter.cs" />
<Compile Include="Converters\EnumToDescriptionConverter.cs" />
+ <Compile Include="Converters\EnumToItemsSourceConverter.cs" />
+ <Compile Include="Converters\IsEnumConverter.cs" />
+ <Compile Include="Converters\IsNullConverter.cs" />
<Compile Include="Converters\NullObjectToBooleanConverter.cs" />
+ <Compile Include="Converters\ParameterItemEditorTypeToEditorConverter.cs" />
<Compile Include="Converters\PathToShortPathConverter.cs" />
+ <Compile Include="Converters\StringFormatConverter.cs" />
+ <Compile Include="Editors\IParameterItemEditor.cs" />
+ <Compile Include="Editors\ParameterItemEditor.cs" />
+ <Compile Include="Editors\ParameterItemNumericUpDownEditor.xaml.cs">
+ <DependentUpon>ParameterItemNumericUpDownEditor.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Editors\ParameterizedEditor.xaml.cs">
+ <DependentUpon>ParameterizedEditor.xaml</DependentUpon>
+ </Compile>
<Compile Include="ExtendedObject.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="Controls\MultiTransitionControl.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Editors\ParameterItemNumericUpDownEditor.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Editors\ParameterizedEditor.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.SharedUI/packages.config b/Software/Visual Studio/Tango.SharedUI/packages.config
new file mode 100644
index 000000000..86110f9d8
--- /dev/null
+++ b/Software/Visual Studio/Tango.SharedUI/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Stubs/AvailableStub.cs b/Software/Visual Studio/Tango.Stubs/AvailableStub.cs
new file mode 100644
index 000000000..64fbfbe9b
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/AvailableStub.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport;
+
+namespace Tango.Stubs
+{
+ public class AvailableStub
+ {
+ public Type Type { get; set; }
+
+ public String Name { get; set; }
+
+ public String Description { get; set; }
+
+ public AvailableStub(Type type, String name, String description)
+ {
+ Type = type;
+ Name = name;
+ Description = description;
+ }
+
+ public StubBase CreateInstance(ITransporter transporter)
+ {
+ return Activator.CreateInstance(Type, transporter) as StubBase;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/IStub.cs b/Software/Visual Studio/Tango.Stubs/IStub.cs
new file mode 100644
index 000000000..70629ea8f
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/IStub.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.Stubs
+{
+ public interface IStub : IParameterized
+ {
+ StubState State { get; }
+ Task<String> Run(Action<String> multiResponseCallback);
+ Task<String> Cancel();
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Stubs/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..c91630b59
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Stubs Collection")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Stubs/StubAttribute.cs b/Software/Visual Studio/Tango.Stubs/StubAttribute.cs
new file mode 100644
index 000000000..20fe1dea0
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/StubAttribute.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Stubs
+{
+ public class StubAttribute : Attribute
+ {
+ public String Name { get; set; }
+
+ public String Description { get; set; }
+
+ public StubAttribute(String name, String description)
+ {
+ Name = name;
+ Description = description;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/StubBase.cs b/Software/Visual Studio/Tango.Stubs/StubBase.cs
new file mode 100644
index 000000000..9270a8702
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/StubBase.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Logging;
+using Tango.SharedUI;
+using Tango.Transport;
+
+namespace Tango.Stubs
+{
+ public abstract class StubBase : ExtendedObject, IStub
+ {
+ [ParameterIgnore]
+ public ITransporter Transporter { get; set; }
+
+ [ParameterIgnore]
+ public ReadOnlyObservableCollection<ParameterItem> Parameters { get; set; }
+
+ private StubState _state;
+ [ParameterIgnore]
+ public StubState State
+ {
+ get { return _state; }
+ protected set { _state = value; RaisePropertyChanged(nameof(State)); }
+ }
+
+
+ public StubBase(ITransporter transporter)
+ {
+ Transporter = transporter;
+ Parameters = new ReadOnlyObservableCollection<ParameterItem>(this.CreateParametersCollection(ParameterItemMode.Event));
+ }
+
+ public virtual Task<String> Cancel()
+ {
+ return Task<String>.Factory.StartNew(() =>
+ {
+ return "";
+ });
+ }
+
+ public async virtual Task<String> Run(Action<String> multiResponseCallback)
+ {
+ String response = String.Empty;
+
+ try
+ {
+ LogManager.Log("Executing stub " + this.GetType().Name + "...");
+ State = StubState.Running;
+ response = await OnRun(multiResponseCallback);
+ State = StubState.Passed;
+ LogManager.Log("Stub completed successfully.");
+ }
+ catch (Exception ex)
+ {
+ State = StubState.Failed;
+ response = LogManager.Log(ex, "Stub failed.").ToString();
+ }
+
+ return response;
+ }
+
+ protected abstract Task<String> OnRun(Action<String> multiResponseCallback);
+
+ public static List<AvailableStub> GetAvailableStubs()
+ {
+ List<AvailableStub> results = new List<AvailableStub>();
+
+ foreach (Type type in Assembly.GetAssembly(typeof(StubBase)).GetTypes().Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(StubBase))))
+ {
+ StubAttribute att = type.GetCustomAttributes(typeof(StubAttribute), true).FirstOrDefault() as StubAttribute;
+ AvailableStub availableStub = new AvailableStub(type, att.Name, att.Description);
+ results.Add(availableStub);
+ }
+
+ return results;
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/StubState.cs b/Software/Visual Studio/Tango.Stubs/StubState.cs
new file mode 100644
index 000000000..1839bc3dc
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/StubState.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Stubs
+{
+ public enum StubState
+ {
+ Stopped,
+ Running,
+ Passed,
+ Failed,
+ Canceled,
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/Stubs/Calculate.cs b/Software/Visual Studio/Tango.Stubs/Stubs/Calculate.cs
new file mode 100644
index 000000000..36c353dfd
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/Stubs/Calculate.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Stubs;
+using Tango.Transport;
+
+namespace Tango.Stubs.Stubs
+{
+ [Stub("Calculate", "Calculate two numbers and return the result.")]
+ public class Calculate : StubBase
+ {
+ public Calculate(ITransporter transporter) : base(transporter)
+ {
+ }
+
+ [ParameterItem(Minimum = null, Maximum = null)]
+ public double NumberA { get; set; }
+
+ [ParameterItem(Minimum = null, Maximum = null)]
+ public double NumberB { get; set; }
+
+ protected async override Task<string> OnRun(Action<String> multiResponseCallback)
+ {
+ var request = MessageFactory.CreateContainer<CalculateRequest>();
+ request.Message.A = NumberA;
+ request.Message.B = NumberB;
+ var response = await Transporter.SendRequest<CalculateRequest, CalculateResponse>(request);
+ return response.Sum.ToString();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/Stubs/Progress.cs b/Software/Visual Studio/Tango.Stubs/Stubs/Progress.cs
new file mode 100644
index 000000000..323f2b35e
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/Stubs/Progress.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Stubs;
+using Tango.Transport;
+
+namespace Tango.Stubs.Stubs
+{
+ [Stub("Progress", "Check for multiple response request")]
+ public class Progress : StubBase
+ {
+ public Progress(ITransporter transporter) : base(transporter)
+ {
+ }
+
+ protected override Task<string> OnRun(Action<String> multiResponseCallback)
+ {
+ Transporter.SendMultiRequest<ProgressRequest, ProgressResponse>(MessageFactory.CreateContainer<ProgressRequest>(), (response) =>
+ {
+ multiResponseCallback(response.Progress.ToString());
+ });
+
+ return Task.FromResult<String>("");
+ }
+ }
+}
diff --git a/Software/Visual Studio/Tango.Stubs/Tango.Stubs.csproj b/Software/Visual Studio/Tango.Stubs/Tango.Stubs.csproj
new file mode 100644
index 000000000..f4dbf9bb4
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/Tango.Stubs.csproj
@@ -0,0 +1,92 @@
+<?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>{1981B537-39E9-4E7D-8430-27466481AEEE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Stubs</RootNamespace>
+ <AssemblyName>Tango.Stubs</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </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="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="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="AvailableStub.cs" />
+ <Compile Include="IStub.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Stubs\Progress.cs" />
+ <Compile Include="Stubs\Calculate.cs" />
+ <Compile Include="StubAttribute.cs" />
+ <Compile Include="StubBase.cs" />
+ <Compile Include="StubState.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Emulations\Tango.Emulations.csproj">
+ <Project>{63561e19-ff5a-414b-a5ef-e30711543e1d}</Project>
+ <Name>Tango.Emulations</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.Protobuf\Tango.Protobuf.csproj">
+ <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project>
+ <Name>Tango.Protobuf</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.SharedUI\Tango.SharedUI.csproj">
+ <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Stubs/packages.config b/Software/Visual Studio/Tango.Stubs/packages.config
new file mode 100644
index 000000000..e7e6cbade
--- /dev/null
+++ b/Software/Visual Studio/Tango.Stubs/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual Studio/Tango.Transport/ITransporter.cs b/Software/Visual Studio/Tango.Transport/ITransporter.cs
index 5142b68f1..6699e1f58 100644
--- a/Software/Visual Studio/Tango.Transport/ITransporter.cs
+++ b/Software/Visual Studio/Tango.Transport/ITransporter.cs
@@ -44,6 +44,28 @@ namespace Tango.Transport
Task<Response> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter) where Request : IMessage<Request> where Response : IMessage<Response>;
/// <summary>
+ /// Sends a request through all adapters which is expected to return multiple response messages.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ /// <returns></returns>
+ void SendMultiRequest<Request, Response>(TangoMessage<Request> request, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a request through the specified adapter which is expected to return multiple response messages.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ /// <returns></returns>
+ void SendMultiRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter,Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
/// Sends a response.
/// </summary>
/// <typeparam name="Response">The type of the response.</typeparam>
diff --git a/Software/Visual Studio/Tango.Transport/TransportMessage.cs b/Software/Visual Studio/Tango.Transport/TransportMessage.cs
index e10c736a5..4f864f9f6 100644
--- a/Software/Visual Studio/Tango.Transport/TransportMessage.cs
+++ b/Software/Visual Studio/Tango.Transport/TransportMessage.cs
@@ -15,6 +15,8 @@ namespace Tango.Transport
{
private TaskCompletionSource<T> _completionSource;
+ public Action<T> ResponseCallback { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="TransportMessage{T}"/> class.
/// </summary>
@@ -45,5 +47,14 @@ namespace Tango.Transport
{
_completionSource.SetException(ex);
}
+
+ /// <summary>
+ /// Invokes the response callback.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ public override void InvokeResponseCallback(object response)
+ {
+ ResponseCallback((T)response);
+ }
}
}
diff --git a/Software/Visual Studio/Tango.Transport/TransportMessageBase.cs b/Software/Visual Studio/Tango.Transport/TransportMessageBase.cs
index c20b11555..d15e17755 100644
--- a/Software/Visual Studio/Tango.Transport/TransportMessageBase.cs
+++ b/Software/Visual Studio/Tango.Transport/TransportMessageBase.cs
@@ -17,6 +17,11 @@ namespace Tango.Transport
public ITransportAdapter Adapter { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether this instance is multi response.
+ /// </summary>
+ public bool IsMultiResponse { get; set; }
+
+ /// <summary>
/// Gets or sets the message token.
/// </summary>
public String Token { get; set; }
@@ -49,6 +54,12 @@ namespace Tango.Transport
public abstract void SetException(Exception ex);
/// <summary>
+ /// Invokes the response callback.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ public abstract void InvokeResponseCallback(object response);
+
+ /// <summary>
/// Initializes a new instance of the <see cref="TransportMessageBase"/> class.
/// </summary>
/// <param name="token">The token.</param>
diff --git a/Software/Visual Studio/Tango.Transport/TransporterBase.cs b/Software/Visual Studio/Tango.Transport/TransporterBase.cs
index 073499225..9090bbfa2 100644
--- a/Software/Visual Studio/Tango.Transport/TransporterBase.cs
+++ b/Software/Visual Studio/Tango.Transport/TransporterBase.cs
@@ -287,6 +287,36 @@ namespace Tango.Transport
}
/// <summary>
+ /// Sends a request through all adapters which is expected to return multiple response messages.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ public void SendMultiRequest<Request, Response>(TangoMessage<Request> request, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ SendMultiRequest(request, null, responseCallback);
+ }
+
+ /// <summary>
+ /// Sends a request through the specified adapter which is expected to return multiple response messages.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="request">The request.</param>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ public void SendMultiRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ TransportMessage<Response> message = new TransportMessage<Response>(adapter, request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), null)
+ {
+ IsMultiResponse = true,
+ ResponseCallback = responseCallback,
+ };
+ _sendingQueue.Enqueue(message);
+ }
+
+ /// <summary>
/// Sends a response.
/// </summary>
/// <typeparam name="Response">The type of the response.</typeparam>
@@ -406,15 +436,29 @@ namespace Tango.Transport
if (request != null)
{
- _pendingRequests.Remove(request);
-
- try
+ if (!request.IsMultiResponse)
{
- request.SetResult(OnParseContainer(container));
+ _pendingRequests.Remove(request);
+
+ try
+ {
+ request.SetResult(OnParseContainer(container));
+ }
+ catch (Exception ex)
+ {
+ request.SetException(ex);
+ }
}
- catch (Exception ex)
+ else
{
- request.SetException(ex);
+ try
+ {
+ request.InvokeResponseCallback(OnParseContainer(container));
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
}
}
else
diff --git a/Software/Visual Studio/Tango.sln b/Software/Visual Studio/Tango.sln
index dff95ce1a..88b353994 100644
--- a/Software/Visual Studio/Tango.sln
+++ b/Software/Visual Studio/Tango.sln
@@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MachineEM.UI", "Utili
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MobileEM.UI", "Utilities\Tango.MobileEM.UI\Tango.MobileEM.UI.csproj", "{372401B3-FFEB-483F-965F-261506B3FDFB}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Stubs", "Tango.Stubs\Tango.Stubs.csproj", "{1981B537-39E9-4E7D-8430-27466481AEEE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -93,6 +95,10 @@ Global
{372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{372401B3-FFEB-483F-965F-261506B3FDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{372401B3-FFEB-483F-965F-261506B3FDFB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml
index 5aa87af23..83d97bea5 100644
--- a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml
@@ -1,6 +1,7 @@
<Application x:Class="Tango.MobileEM.UI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:vm="clr-namespace:Tango.MobileEM.UI.ViewModels"
xmlns:local="clr-namespace:Tango.MobileEM.UI"
StartupUri="MainWindow.xaml">
<Application.Resources>
@@ -14,6 +15,13 @@
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Red.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
+
+ <!--View Models-->
+ <ResourceDictionary>
+ <vm:MainWindowVM x:Key="MainWindowVM"></vm:MainWindowVM>
+ <vm:MainViewVM x:Key="MainViewVM"></vm:MainViewVM>
+ <vm:StubsViewVM x:Key="StubsViewVM"></vm:StubsViewVM>
+ </ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs
index 9819b418d..57e3ddcad 100644
--- a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs
@@ -5,6 +5,9 @@ using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
+using Tango.Emulations.Emulators;
+using Tango.Transport.Adapters;
+using Tango.Transport.Transporters;
namespace Tango.MobileEM.UI
{
@@ -13,5 +16,12 @@ namespace Tango.MobileEM.UI
/// </summary>
public partial class App : Application
{
+ public static MobileEmulator Emulator { get; set; }
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+ Emulator = new MobileEmulator(new ProtoTransporter(new TcpTransportAdapter("127.0.0.1", 9999)));
+ }
}
}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml
index 7cd7213c5..1280b76f8 100644
--- a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml
@@ -5,10 +5,12 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:views="clr-namespace:Tango.MobileEM.UI.Views"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:Tango.MobileEM.UI"
mc:Ignorable="d"
- Title="Tango Machine Emulator" Height="558" Width="354" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}">
+ Title="Tango Machine Emulator" Height="668" Width="416" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{StaticResource MainWindowVM}">
<Grid>
<Grid>
<Image Source="Images/phone.png" RenderOptions.BitmapScalingMode="Fant" Stretch="Fill"></Image>
@@ -31,24 +33,47 @@
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
- <Grid>
- <Button Width="100" Height="50" Click="Button_Click">SEND</Button>
- </Grid>
+ <controls:MultiTransitionControl x:Name="TransitionControl" AlwaysFade="True" TransitionType="Zoom" AnimationTime="500">
+ <controls:MultiTransitionControl.Controls>
+ <ContentControl Tag="MainView">
+ <views:MainView DataContext="{StaticResource MainViewVM}"></views:MainView>
+ </ContentControl>
+ <ContentControl Tag="StubsView">
+ <views:StubsView DataContext="{StaticResource StubsViewVM}"></views:StubsView>
+ </ContentControl>
+ <ContentControl Tag="StubView">
+ <views:StubView></views:StubView>
+ </ContentControl>
+ </controls:MultiTransitionControl.Controls>
+ </controls:MultiTransitionControl>
- <UniformGrid Grid.Row="1" Columns="2" Background="#151515">
- <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StopCommand}">
- <StackPanel Orientation="Horizontal">
- <fa:ImageAwesome Icon="Unlink" Width="16"></fa:ImageAwesome>
- <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Disconnect</TextBlock>
- </StackPanel>
- </Button>
- <Button Margin="5 5 0 5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StartCommand}">
+ <Grid Grid.Row="1" Background="#151515">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="40"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding BackCommand}">
<StackPanel Orientation="Horizontal">
- <fa:ImageAwesome Icon="Link" Width="16"></fa:ImageAwesome>
- <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Connect</TextBlock>
+ <fa:ImageAwesome Icon="ArrowLeft" Width="16"></fa:ImageAwesome>
</StackPanel>
</Button>
- </UniformGrid>
+
+ <UniformGrid Columns="2" Grid.Column="1">
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StopCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Unlink" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Disconnect</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Margin="5 5 0 5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StartCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Link" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Connect</TextBlock>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
</Grid>
</Grid>
</Grid>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs
index 72e8a480f..f003f708f 100644
--- a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs
@@ -26,29 +26,23 @@ namespace Tango.MobileEM.UI
/// </summary>
public partial class MainWindow : MetroWindow
{
- #region Properties
-
- public MobileEmulator Emulator
- {
- get { return (MobileEmulator)GetValue(EmulatorProperty); }
- set { SetValue(EmulatorProperty, value); }
- }
- public static readonly DependencyProperty EmulatorProperty =
- DependencyProperty.Register("Emulator", typeof(MobileEmulator), typeof(MainWindow), new PropertyMetadata(null));
-
- #endregion
+ public static MainWindow Instance { get; private set; }
public MainWindow()
{
LogManager.RegisterLogger(new VSOutputLogger());
-
- Emulator = new MobileEmulator(new ProtoTransporter(new TcpTransportAdapter("127.0.0.1", 9999)));
InitializeComponent();
+ Instance = this;
}
- private void Button_Click(object sender, RoutedEventArgs e)
+ public static void NavigateTo(Type view)
{
+ Instance.TransitionControl.AutoNavigate(view.Name);
+ }
+ public static void NavigateTo(Type view, object context)
+ {
+ Instance.TransitionControl.AutoNavigate(view.Name, context);
}
}
}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj
index e376ad738..9546deaed 100644
--- a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj
@@ -66,6 +66,19 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="ViewModels\MainWindowVM.cs" />
+ <Compile Include="ViewModels\StubsViewVM.cs" />
+ <Compile Include="ViewModels\StubViewVM.cs" />
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\StubsView.xaml.cs">
+ <DependentUpon>StubsView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\StubView.xaml.cs">
+ <DependentUpon>StubView.xaml</DependentUpon>
+ </Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -78,6 +91,18 @@
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\StubsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\StubView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -135,6 +160,10 @@
<Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</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>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..fdb751422
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class MainViewVM : ExtendedObject
+ {
+ #region Commands
+
+ public RelayCommand StubsCommand { get; set; }
+
+ #endregion
+
+ public MainViewVM()
+ {
+ StubsCommand = new RelayCommand(NavigateToStubs);
+ }
+
+ private void NavigateToStubs()
+ {
+ MainWindow.NavigateTo(typeof(StubsView));
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs
new file mode 100644
index 000000000..cd5c9bf93
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Emulations.Emulators;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Transport.Adapters;
+using Tango.Transport.Transporters;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class MainWindowVM : ExtendedObject
+ {
+ /// <summary>
+ /// Gets or sets the mobile emulator.
+ /// </summary>
+ public MobileEmulator Emulator
+ {
+ get { return App.Emulator; }
+ }
+
+ public RelayCommand BackCommand { get; set; }
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainWindowVM"/> class.
+ /// </summary>
+ public MainWindowVM()
+ {
+ BackCommand = new RelayCommand(Back);
+ }
+
+ private void Back()
+ {
+ MainWindow.NavigateTo(typeof(MainView));
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs
new file mode 100644
index 000000000..645df6a13
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Documents;
+using Tango.Logging;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Stubs;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class StubViewVM : ExtendedObject
+ {
+ private bool _running;
+
+ public RelayCommand RunCommand { get; set; }
+ public RelayCommand CancelCommand { get; set; }
+ public RelayCommand ClearCommand { get; set; }
+ public StubBase Stub { get; set; }
+ public AvailableStub AvailableStub { get; set; }
+
+ private String _response;
+
+ public String Response
+ {
+ get { return _response; }
+ set { _response = value; RaisePropertyChanged(nameof(Response)); }
+ }
+
+
+ public StubViewVM(AvailableStub availableStub, StubBase stub)
+ {
+ AvailableStub = availableStub;
+ Stub = stub;
+ RunCommand = new RelayCommand(Run,(x) => !_running);
+ CancelCommand = new RelayCommand(Cancel,(x) => _running);
+ ClearCommand = new RelayCommand(() => Response = String.Empty);
+ }
+
+ private async void Run()
+ {
+ _running = true;
+ InvalidateRelayCommands();
+ Response += await Stub.Run((response) =>
+ {
+ _running = false;
+ Response += response + Environment.NewLine;
+ InvalidateRelayCommands();
+
+ }) + Environment.NewLine;
+
+ _running = false;
+ InvalidateRelayCommands();
+ }
+
+ private async void Cancel()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs
new file mode 100644
index 000000000..480ba1c7c
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.Stubs;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class StubsViewVM : ExtendedObject
+ {
+ public List<AvailableStub> AvailableStubs { get; set; }
+ private AvailableStub _selectedStub;
+
+ public AvailableStub SelectedStub
+ {
+ get { return _selectedStub; }
+ set
+ {
+ _selectedStub = value; RaisePropertyChanged(nameof(SelectedStub));
+ OnStubSelected(value);
+ }
+ }
+
+
+ public StubsViewVM()
+ {
+ AvailableStubs = StubBase.GetAvailableStubs();
+ }
+
+ private void OnStubSelected(AvailableStub availableStub)
+ {
+ if (availableStub != null)
+ {
+ StubBase stub = availableStub.CreateInstance(App.Emulator.Transporter);
+ MainWindow.NavigateTo(typeof(StubView), new StubViewVM(availableStub, stub));
+ }
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml
new file mode 100644
index 000000000..3c8caa918
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml
@@ -0,0 +1,29 @@
+<UserControl x:Class="Tango.MobileEM.UI.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:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+
+ <Grid Margin="20">
+ <UniformGrid Rows="2">
+ <Button Width="100" Height="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StubsCommand}">
+ <StackPanel Orientation="Vertical">
+ <fa:ImageAwesome Icon="Cogs" Width="32"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10">Stubs</TextBlock>
+ </StackPanel>
+ </Button>
+
+ <Button Width="100" Height="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding MonitoringCommand}">
+ <StackPanel Orientation="Vertical">
+ <fa:ImageAwesome Icon="Gratipay" Width="32"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10">Monitoring</TextBlock>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs
new file mode 100644
index 000000000..c33fb0fe1
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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.SharedUI.Commands;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public MainView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml
new file mode 100644
index 000000000..c0fa65b91
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml
@@ -0,0 +1,73 @@
+<UserControl x:Class="Tango.MobileEM.UI.Views.StubView"
+ 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:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:editors="clr-namespace:Tango.SharedUI.Editors;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="400" d:DesignWidth="300">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="50"/>
+ <RowDefinition Height="105*"/>
+ <RowDefinition Height="68*"/>
+ </Grid.RowDefinitions>
+ <Grid VerticalAlignment="Top" Background="#151515">
+ <StackPanel Orientation="Horizontal" Margin="5">
+ <fa:ImageAwesome Icon="Cogs" Foreground="Red" Width="24" Height="24" VerticalAlignment="Center"></fa:ImageAwesome>
+ <StackPanel Margin="5 0 0 0" VerticalAlignment="Center">
+ <TextBlock Margin="2" FontSize="14" Text="{Binding AvailableStub.Name}"></TextBlock>
+ <TextBlock Margin="2" FontSize="12" Text="{Binding AvailableStub.Description}"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="1" Background="#202020">
+ <editors:ParameterizedEditor ParameterizedObject="{Binding Stub}" Margin="10" ItemMargin="10" ItemLabelMargin="0 0 0 5" />
+ </Grid>
+
+ <Grid Grid.Row="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="40"/>
+ </Grid.RowDefinitions>
+
+ <Grid Background="Black">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="20"/>
+ <RowDefinition Height="40*"/>
+ </Grid.RowDefinitions>
+
+ <TextBlock Background="#151515" Foreground="Red" VerticalAlignment="Center" FontSize="11" Margin="5 0 0 0">Response</TextBlock>
+
+ <TextBox x:Name="txtResponse" TextChanged="txtResponse_TextChanged" Grid.Row="1" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" Background="Transparent" Foreground="Gainsboro" FontSize="10" BorderThickness="0" IsReadOnly="True" Padding="5" Text="{Binding Response}">
+
+ </TextBox>
+ </Grid>
+
+ <Grid Grid.Row="1" Background="Black">
+ <Rectangle VerticalAlignment="Top" Stroke="#202020" StrokeThickness="1"></Rectangle>
+ <UniformGrid Columns="3" HorizontalAlignment="Right">
+ <Button Cursor="Hand" Width="35" Height="35" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ClearCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Refresh" Foreground="Gainsboro" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="35" Height="35" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding CancelCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Stop" Foreground="Red" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="35" Height="35" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding RunCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Play" Width="16" Foreground="LimeGreen"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs
new file mode 100644
index 000000000..8ce034020
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for StubView.xaml
+ /// </summary>
+ public partial class StubView : UserControl
+ {
+ public StubView()
+ {
+ InitializeComponent();
+ }
+
+ private void txtResponse_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ txtResponse.ScrollToEnd();
+ }
+ }
+}
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml
new file mode 100644
index 000000000..effbd48fe
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml
@@ -0,0 +1,28 @@
+<UserControl x:Class="Tango.MobileEM.UI.Views.StubsView"
+ 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:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+ <Grid>
+ <ListBox x:Name="list" Background="Transparent" ItemsSource="{Binding AvailableStubs}" SelectedItem="{Binding SelectedStub}" SelectedIndex="-1" SelectionChanged="ListBox_SelectionChanged">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Grid>
+ <StackPanel Orientation="Horizontal" Margin="2 10 0 10">
+ <fa:ImageAwesome Icon="Cogs" Foreground="Red" Width="24" Height="24" VerticalAlignment="Center"></fa:ImageAwesome>
+ <StackPanel Margin="5 0 0 0" VerticalAlignment="Center">
+ <TextBlock Margin="2" FontSize="14" Text="{Binding Name}"></TextBlock>
+ <TextBlock Margin="2" FontSize="12" Text="{Binding Description}"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black" StrokeThickness="1"></Rectangle>
+ </Grid>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs
new file mode 100644
index 000000000..7c42ba82c
--- /dev/null
+++ b/Software/Visual Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+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;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for StubsView.xaml
+ /// </summary>
+ public partial class StubsView : UserControl
+ {
+ public StubsView()
+ {
+ InitializeComponent();
+ }
+
+ private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.AddedItems.Count > 0)
+ {
+ list.SelectedIndex = -1;
+ }
+ }
+ }
+}