aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common
diff options
context:
space:
mode:
authorAvi Levkovich <avi@twine-s.com>2018-02-20 16:45:00 +0200
committerAvi Levkovich <avi@twine-s.com>2018-02-20 16:45:00 +0200
commit6c208c90bc45aff4a7fa214356a42fe7757c5e6f (patch)
tree0d77bc6a0ecfbb53cf42c5462ee19212197ee1bd /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common
parentb0823127f152fe97a6e8fce29e427c7f3db9cf5a (diff)
parent1a573aaa346ec4b8bd58a0e35ab9df571a09b855 (diff)
downloadTango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.tar.gz
Tango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.zip
MERGE
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs20
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml23
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs102
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs53
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs24
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml90
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs179
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml95
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs162
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs58
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PointToMarginConverter.cs5
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/SecondsToGraphPointsConverter.cs27
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs84
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs31
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/IStudioMessageExtensions.cs7
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/UserExtensions.cs14
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/digital-7.ttfbin0 -> 34360 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Helpers/GraphsHelper.cs34
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioModule.cs32
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/IStudioMessage.cs3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Modules/IStudioModuleLoader.cs19
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/INavigationManager.cs7
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/NavigationView.cs3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/BarItem.cs51
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/DialogViewVM.cs23
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/INotificationProvider.cs105
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/TaskItem.cs21
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Properties/AssemblyInfo.cs3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/GradientOffsetSlider.xaml83
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml306
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IModuleRequestListener.cs21
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownListener.cs19
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownRequestBlocker.cs8
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs38
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioModuleBase.cs113
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj75
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ValidationRules/Required.cs12
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/DefaultVideoCaptureProvider.cs44
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/IVideoCaptureProvider.cs21
40 files changed, 1992 insertions, 29 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs
index 488a2f6dc..590936163 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs
@@ -3,18 +3,36 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Tango.DAL.Observables;
+using Tango.Integration.Observables;
namespace Tango.MachineStudio.Common.Authentication
{
+ /// <summary>
+ /// Represents the Machine Studio user authentication provider responsible for the current logged-in user.
+ /// </summary>
public interface IAuthenticationProvider
{
+ /// <summary>
+ /// Occurs when the current logged-in user has changed.
+ /// </summary>
event EventHandler<User> CurrentUserChanged;
+ /// <summary>
+ /// Gets the current logged-in user.
+ /// </summary>
User CurrentUser { get; }
+ /// <summary>
+ /// Performs a user login by the specified email and password.
+ /// </summary>
+ /// <param name="email">The email.</param>
+ /// <param name="password">The password.</param>
+ /// <returns></returns>
User Login(String email, String password);
+ /// <summary>
+ /// Logs-out the current logged-in user.
+ /// </summary>
void Logout();
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml
new file mode 100644
index 000000000..6a9bf9cc9
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml
@@ -0,0 +1,23 @@
+<UserControl x:Class="Tango.MachineStudio.Common.Controls.HiveColorPickerControl"
+ 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:colorPicker="clr-namespace:Tango;assembly=Tango.ColorPicker"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
+ mc:Ignorable="d"
+ d:DesignHeight="250" d:DesignWidth="500" >
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="235"/>
+ <ColumnDefinition Width="43*"/>
+ </Grid.ColumnDefinitions>
+
+ <colorPicker:ColorCanvas SelectedColor="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=SelectedColor,Mode=TwoWay}" Background="Transparent" BorderThickness="0" UsingAlphaChannel="False" />
+
+ <Viewbox Stretch="Uniform" Grid.Column="1" Margin="5">
+ <controls:HiveControl x:Name="hive" Height="250" HexagonSelected="hive_HexagonSelected" MaxSelections="1" Width="250" BorderThickness="1" />
+ </Viewbox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs
new file mode 100644
index 000000000..9432ae9ef
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/HiveColorPickerControl.xaml.cs
@@ -0,0 +1,102 @@
+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.MachineStudio.Common.Controls
+{
+ /// <summary>
+ /// Interaction logic for HiveColorPickerControl.xaml
+ /// </summary>
+ public partial class HiveColorPickerControl : UserControl
+ {
+ public event EventHandler<Color> SelectedColorChanged;
+ private bool _preventHiveSelectedColorChange;
+
+ public bool DemoMode
+ {
+ get { return (bool)GetValue(DemoModeProperty); }
+ set { SetValue(DemoModeProperty, value); }
+ }
+ public static readonly DependencyProperty DemoModeProperty =
+ DependencyProperty.Register("DemoMode", typeof(bool), typeof(HiveColorPickerControl), new PropertyMetadata(false));
+
+ public Color SelectedColor
+ {
+ get { return (Color)GetValue(SelectedColorProperty); }
+ set { SetValue(SelectedColorProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedColorProperty =
+ DependencyProperty.Register("SelectedColor", typeof(Color), typeof(HiveColorPickerControl), new PropertyMetadata(Colors.Red, (d, e) => (d as HiveColorPickerControl).OnSelectedColorChanged()));
+
+ public Color SelectedHiveColor
+ {
+ get { return (Color)GetValue(SelectedHiveColorProperty); }
+ set { SetValue(SelectedHiveColorProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedHiveColorProperty =
+ DependencyProperty.Register("SelectedHiveColor", typeof(Color), typeof(HiveColorPickerControl), new PropertyMetadata(Colors.Red));
+
+ public HiveColorPickerControl()
+ {
+ InitializeComponent();
+
+ hive.Loaded += Hive_Loaded;
+ }
+
+ private void Hive_Loaded(object sender, RoutedEventArgs e)
+ {
+ OnSelectedColorChanged();
+ }
+
+ private void OnSelectedColorChanged()
+ {
+ if (DemoMode)
+ {
+ if (!_preventHiveSelectedColorChange)
+ {
+ GenerateDemoModeHiveColors();
+ }
+ SelectedColorChanged?.Invoke(this, SelectedColor);
+ }
+ }
+
+ private void hive_HexagonSelected(object sender, SharedUI.Controls.HexagonControl hexagon)
+ {
+ SelectedHiveColor = (hexagon.Fill as SolidColorBrush).Color;
+
+ _preventHiveSelectedColorChange = true;
+ SelectedColor = SelectedHiveColor;
+ _preventHiveSelectedColorChange = false;
+ }
+
+ private void GenerateDemoModeHiveColors()
+ {
+ if (hive.CenterHexagon != null)
+ {
+ Random rnd = new Random();
+
+ (hive.CenterHexagon.Fill as SolidColorBrush).Color = SelectedColor;
+
+ int counter = 0;
+
+ foreach (var hexagon in hive.Hexagons.Where(x => x != hive.CenterHexagon).OrderBy(x => rnd.Next()))
+ {
+ (hexagon.Fill as SolidColorBrush).Color = Color.FromRgb((byte)Math.Min(SelectedColor.R + counter++, 255), (byte)Math.Min((SelectedColor.G + counter++), 255), (byte)Math.Min((SelectedColor.B + counter++), 255));
+
+ counter += 4;
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs
new file mode 100644
index 000000000..bf40d459e
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/IRealTimeGraph.cs
@@ -0,0 +1,53 @@
+using RealTimeGraphEx;
+using RealTimeGraphEx.Controllers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.Controls
+{
+ public interface IRealTimeGraph
+ {
+ /// <summary>
+ /// Gets or sets the name of the sensor.
+ /// </summary>
+ String SensorName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the tag.
+ /// </summary>
+ Object Tag { get; set; }
+
+ /// <summary>
+ /// Gets or sets the sensor units.
+ /// </summary>
+ String SensorUnits { get; set; }
+
+ /// <summary>
+ /// Occurs when the graph remove button has been pressed.
+ /// </summary>
+ event EventHandler GraphRemoveButtonPressed;
+
+ /// <summary>
+ /// Occurs when the graph full screen button has been pressed.
+ /// </summary>
+ event EventHandler GraphFullScreenButtonPressed;
+
+ /// <summary>
+ /// Gets or sets the inner real-time graph control.
+ /// </summary>
+ RealTimeGraphExBase InnerGraph { get; set; }
+
+ /// <summary>
+ /// Gets or sets the inner graph controller.
+ /// </summary>
+ GraphControllerBase Controller { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable toolbar buttons.
+ /// </summary>
+ bool EnableToolBar { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs
index 469e3fda5..109b00531 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiChild.cs
@@ -10,19 +10,34 @@ using Tango.Core.Commands;
namespace Tango.MachineStudio.Common.Controls
{
+ /// <summary>
+ /// Represents an <see cref="MdiContainerControl"/> child control.
+ /// </summary>
+ /// <seealso cref="System.Windows.DependencyObject" />
public class MdiChild : DependencyObject
{
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MdiChild"/> class.
+ /// </summary>
public MdiChild()
{
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MdiChild"/> class.
+ /// </summary>
+ /// <param name="header">The header.</param>
+ /// <param name="view">The view.</param>
public MdiChild(String header, FrameworkElement view) : this()
{
Header = header;
View = view;
}
+ /// <summary>
+ /// Gets or sets the icon.
+ /// </summary>
public PackIconKind Icon
{
get { return (PackIconKind)GetValue(IconProperty); }
@@ -31,6 +46,9 @@ namespace Tango.MachineStudio.Common.Controls
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(PackIconKind), typeof(MdiChild), new PropertyMetadata(PackIconKind.LaptopWindows));
+ /// <summary>
+ /// Gets or sets the header.
+ /// </summary>
public String Header
{
get { return (String)GetValue(HeaderProperty); }
@@ -39,6 +57,9 @@ namespace Tango.MachineStudio.Common.Controls
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(String), typeof(MdiChild), new PropertyMetadata(null));
+ /// <summary>
+ /// Gets or sets the view.
+ /// </summary>
public FrameworkElement View
{
get { return (FrameworkElement)GetValue(ViewProperty); }
@@ -47,6 +68,9 @@ namespace Tango.MachineStudio.Common.Controls
public static readonly DependencyProperty ViewProperty =
DependencyProperty.Register("View", typeof(FrameworkElement), typeof(MdiChild), new PropertyMetadata(null));
+ /// <summary>
+ /// Gets or sets the location.
+ /// </summary>
public Point Location
{
get { return (Point)GetValue(LocationProperty); }
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs
index dbf4ee74b..ceeda050b 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml.cs
@@ -20,8 +20,11 @@ using Tango.SharedUI.Helpers;
namespace Tango.MachineStudio.Common.Controls
{
/// <summary>
- /// Interaction logic for MdiContainerControl.xaml
+ /// Represents an MDI-style container
/// </summary>
+ /// <seealso cref="System.Windows.Controls.UserControl" />
+ /// <seealso cref="System.Windows.Markup.IComponentConnector" />
+ /// <seealso cref="System.Windows.Markup.IStyleConnector" />
public partial class MdiContainerControl : UserControl
{
private const int MIN_SIZE = 200;
@@ -63,7 +66,6 @@ namespace Tango.MachineStudio.Common.Controls
return UIHelper.FindChild<Canvas>(itemsControl, "canvas");
}
-
private void OnControlMouseDown(object sender, MouseButtonEventArgs e)
{
Canvas.SetZIndex(sender as FrameworkElement, GetCanvas().Children.OfType<FrameworkElement>().Max(x => Canvas.GetZIndex(x) + 1));
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml
new file mode 100644
index 000000000..2f43869d5
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml
@@ -0,0 +1,90 @@
+<UserControl x:Class="Tango.MachineStudio.Common.Controls.RealTimeGraphControl"
+ 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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:graphEx="clr-namespace:RealTimeGraphEx.FastGraphs;assembly=RealTimeGraphEx"
+ xmlns:components="clr-namespace:RealTimeGraphEx.Components;assembly=RealTimeGraphEx"
+ xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters"
+ xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
+ mc:Ignorable="d"
+ d:DesignHeight="150" d:DesignWidth="300">
+
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <!--RealTimeGraphEx-->
+ <ResourceDictionary Source="pack://application:,,,/RealTimeGraphEx;component/Resources/Resources.xaml"></ResourceDictionary>
+ <ResourceDictionary Source="../Resources/MaterialDesign.xaml"></ResourceDictionary>
+
+ <ResourceDictionary>
+ <Style TargetType="ContentControl" x:Key="graphContent">
+ <Style.Setters>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Grid MouseEnter="Graph_MouseEnter" MouseLeave="Graph_MouseLeave" ClipToBounds="True">
+ <ContentControl Content="{Binding}"></ContentControl>
+ <Grid Opacity="0.8" HorizontalAlignment="Stretch" VerticalAlignment="Top" ClipToBounds="True" Height="35" Margin="0 -35 0 0">
+ <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Top">
+ <Button Margin="0 0 5 0" Click="OnGraphFullScreen" ToolTip="Full Screen" Width="24" Height="24" BorderBrush="Transparent" Background="{StaticResource AccentColorBrush}" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" >
+ <materialDesign:PackIcon Kind="Fullscreen" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" />
+ </Button>
+ <Button Click="OnGraphRemove" ToolTip="Remove" Width="24" Height="24" BorderBrush="Transparent" Background="#FF7777" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" >
+ <materialDesign:PackIcon Kind="CloseCircle" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" />
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style.Setters>
+ </Style>
+ </ResourceDictionary>
+
+ <ResourceDictionary>
+ <converters:SecondsToGraphPointsConverter x:Key="secondsToPoints"></converters:SecondsToGraphPointsConverter>
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Grid>
+ <!--Temperature-->
+ <ContentControl Style="{StaticResource graphContent}" Margin="0 0 0 0" MinHeight="5">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="40"/>
+ <ColumnDefinition Width="438*"/>
+ </Grid.ColumnDefinitions>
+
+ <Border BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1 1 0 1" Background="#90FFFFFF">
+ <StackPanel Orientation="Horizontal">
+ <components:YAxisScroll x:Name="yAxis" Interval="6" Graph="{Binding ElementName=Graph}" Width="35" Foreground="{StaticResource MaterialDesignLightForeground}" VerticalOffset="-5" FontSize="8" StringFormat="#0.0"></components:YAxisScroll>
+ <components:YAxisTicks x:Name="yAxisTicks" SmallTickTemplate="{StaticResource graphTicksTemplate}" Width="5" SmallTicks="6" Foreground="{StaticResource MaterialDesignLightForeground}" BigTicks="10" Graph="{Binding ElementName=Graph}"></components:YAxisTicks>
+ </StackPanel>
+ </Border>
+ <Border Grid.Column="1" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" Background="{DynamicResource graphBackground}" Margin="5 0 0 0">
+ <graphEx:RealTimeGraphExLineErase x:Name="Graph" x:FieldModifier="public" Controller="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Controller}" Antialiased="True" RefreshRate="30" MarkerColor="{StaticResource graphsMarkerColor}" FillGraph="False" Stroke="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Color}" Minimum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Minimum}" Maximum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Maximum}">
+ <graphEx:RealTimeGraphExLineErase.Components>
+ <components:MouseValueToolTip ToolTipTemplate="{StaticResource graphTooltipTemplate}" />
+ <components:GridLines Rows="4" Columns="6" GridBrush="{DynamicResource graphGridLinesBrush}"></components:GridLines>
+ </graphEx:RealTimeGraphExLineErase.Components>
+ <graphEx:RealTimeGraphExLineErase.InnerContent>
+ <Grid>
+ <Label Style="{StaticResource graphLabel}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorName,FallbackValue='Dispenser Motor'}"></TextBlock>
+ <TextBlock Foreground="Gray" Margin="10 0 0 0" FontFamily="Sylfaen Regular" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorUnits,FallbackValue='(hz)'}"></TextBlock>
+ </StackPanel>
+ </Label>
+ </Grid>
+ </graphEx:RealTimeGraphExLineErase.InnerContent>
+ </graphEx:RealTimeGraphExLineErase>
+ </Border>
+ </Grid>
+ </ContentControl>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs
new file mode 100644
index 000000000..dd9aa1414
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphControl.xaml.cs
@@ -0,0 +1,179 @@
+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.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;
+using RealTimeGraphEx;
+using RealTimeGraphEx.Controllers;
+
+namespace Tango.MachineStudio.Common.Controls
+{
+ /// <summary>
+ /// Interaction logic for RealTimeGraphControl.xaml
+ /// </summary>
+ public partial class RealTimeGraphControl : UserControl, IRealTimeGraph
+ {
+ private Grid headerGrid;
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the name of the sensor.
+ /// </summary>
+ public String SensorName
+ {
+ get { return (String)GetValue(SensorNameProperty); }
+ set { SetValue(SensorNameProperty, value); }
+ }
+ public static readonly DependencyProperty SensorNameProperty =
+ DependencyProperty.Register("SensorName", typeof(String), typeof(RealTimeGraphControl), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the sensor units.
+ /// </summary>
+ public String SensorUnits
+ {
+ get { return (String)GetValue(SensorUnitsProperty); }
+ set { SetValue(SensorUnitsProperty, value); }
+ }
+ public static readonly DependencyProperty SensorUnitsProperty =
+ DependencyProperty.Register("SensorUnits", typeof(String), typeof(RealTimeGraphControl), new PropertyMetadata(null));
+
+
+
+ public double Minimum
+ {
+ get { return (double)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(double), typeof(RealTimeGraphControl), new PropertyMetadata(0.0));
+
+
+
+ public double Maximum
+ {
+ get { return (double)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(double), typeof(RealTimeGraphControl), new PropertyMetadata(100.0));
+
+
+
+ public Color Color
+ {
+ get { return (Color)GetValue(ColorProperty); }
+ set { SetValue(ColorProperty, value); }
+ }
+ public static readonly DependencyProperty ColorProperty =
+ DependencyProperty.Register("Color", typeof(Color), typeof(RealTimeGraphControl), new PropertyMetadata(Colors.DodgerBlue));
+
+
+
+ public void InvalidateGraph()
+ {
+ InnerGraph.Clear();
+ yAxis.Render(InnerGraph);
+ yAxisTicks.Render(InnerGraph);
+ }
+
+ /// <summary>
+ /// Gets or sets the inner real-time graph control.
+ /// </summary>
+ public RealTimeGraphExBase InnerGraph { get; set; }
+
+ /// <summary>
+ /// Gets or sets the inner graph controller.
+ /// </summary>
+ public GraphControllerBase Controller { get; set; }
+
+
+ private bool _enableToolbar;
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable toolbar buttons.
+ /// </summary>
+ public bool EnableToolBar
+ {
+ get { return _enableToolbar; }
+ set
+ {
+ _enableToolbar = value;
+
+ if (!value)
+ {
+ if (headerGrid != null)
+ {
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, -35, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+ }
+ }
+ }
+
+
+ #endregion
+
+ #region Events
+
+ public event EventHandler GraphRemoveButtonPressed;
+ public event EventHandler GraphFullScreenButtonPressed;
+
+ #endregion
+
+ public RealTimeGraphControl()
+ {
+ InitializeComponent();
+ EnableToolBar = true;
+ InnerGraph = Graph;
+ Controller = new GraphController();
+ }
+
+ private void OnGraphFullScreen(object sender, RoutedEventArgs e)
+ {
+ GraphFullScreenButtonPressed?.Invoke(this, new EventArgs());
+ }
+
+ private void Graph_MouseEnter(object sender, MouseEventArgs e)
+ {
+ if (EnableToolBar)
+ {
+ Grid mainGrid = sender as Grid;
+ headerGrid = mainGrid.Children.OfType<Grid>().ToList().First();
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, 0, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+ }
+
+ private void Graph_MouseLeave(object sender, MouseEventArgs e)
+ {
+ Grid mainGrid = sender as Grid;
+ headerGrid = mainGrid.Children.OfType<Grid>().ToList().First();
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, -35, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+
+ private void OnGraphRemove(object sender, RoutedEventArgs e)
+ {
+ GraphRemoveButtonPressed?.Invoke(this, new EventArgs());
+ }
+
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml
new file mode 100644
index 000000000..5548c452e
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml
@@ -0,0 +1,95 @@
+<UserControl x:Class="Tango.MachineStudio.Common.Controls.RealTimeGraphMultiControl"
+ 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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:graphEx="clr-namespace:RealTimeGraphEx.FastGraphs;assembly=RealTimeGraphEx"
+ xmlns:components="clr-namespace:RealTimeGraphEx.Components;assembly=RealTimeGraphEx"
+ xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters"
+ xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
+ mc:Ignorable="d"
+ d:DesignHeight="150" d:DesignWidth="300">
+
+ <UserControl.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <!--RealTimeGraphEx-->
+ <ResourceDictionary Source="pack://application:,,,/RealTimeGraphEx;component/Resources/Resources.xaml"></ResourceDictionary>
+ <ResourceDictionary Source="../Resources/MaterialDesign.xaml"></ResourceDictionary>
+
+ <ResourceDictionary>
+ <Style TargetType="ContentControl" x:Key="graphContent">
+ <Style.Setters>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Grid MouseEnter="Graph_MouseEnter" MouseLeave="Graph_MouseLeave" ClipToBounds="True">
+ <ContentControl Content="{Binding}"></ContentControl>
+ <Grid Opacity="0.8" HorizontalAlignment="Stretch" VerticalAlignment="Top" ClipToBounds="True" Height="35" Margin="0 -35 0 0">
+ <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Top">
+ <Button Margin="0 0 5 0" Click="OnGraphFullScreen" ToolTip="Full Screen" Width="24" Height="24" BorderBrush="Transparent" Background="{StaticResource AccentColorBrush}" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" >
+ <materialDesign:PackIcon Kind="Fullscreen" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" />
+ </Button>
+ <Button Click="OnGraphRemove" ToolTip="Remove" Width="24" Height="24" BorderBrush="Transparent" Background="#FF7777" Style="{StaticResource MaterialDesignFloatingActionAccentButton}" >
+ <materialDesign:PackIcon Kind="CloseCircle" HorizontalAlignment="Right" Width="20" Height="20" Foreground="{StaticResource WhiteBrush}" />
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style.Setters>
+ </Style>
+ </ResourceDictionary>
+
+ <ResourceDictionary>
+ <converters:SecondsToGraphPointsConverter x:Key="secondsToPoints"></converters:SecondsToGraphPointsConverter>
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </UserControl.Resources>
+
+ <Grid>
+ <!--Temperature-->
+ <ContentControl Style="{StaticResource graphContent}" Margin="0 0 0 0" MinHeight="5">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="40"/>
+ <ColumnDefinition Width="438*"/>
+ </Grid.ColumnDefinitions>
+
+ <Border BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1 1 0 1" Background="#90FFFFFF">
+ <StackPanel Orientation="Horizontal">
+ <components:YAxisScroll x:Name="yAxis" Interval="6" Graph="{Binding ElementName=Graph}" Width="35" Foreground="{StaticResource MaterialDesignLightForeground}" VerticalOffset="-5" FontSize="8" StringFormat="#0.0"></components:YAxisScroll>
+ <components:YAxisTicks x:Name="yAxisTicks" SmallTickTemplate="{StaticResource graphTicksTemplate}" Width="5" SmallTicks="6" Foreground="{StaticResource MaterialDesignLightForeground}" BigTicks="10" Graph="{Binding ElementName=Graph}"></components:YAxisTicks>
+ </StackPanel>
+ </Border>
+ <Border Grid.Column="1" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" Background="{DynamicResource graphBackground}" Margin="5 0 0 0">
+ <graphEx:RealTimeGraphExMultiLineErase x:Name="Graph" x:FieldModifier="public" Controller="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Controller}" Antialiased="True" RefreshRate="30" MarkerColor="{StaticResource graphsMarkerColor}" FillGraph="False" Minimum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Minimum}" Maximum="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Maximum}" Stroke="DodgerBlue">
+ <graphEx:RealTimeGraphExMultiLineErase.Components>
+ <components:MouseValueToolTip ToolTipTemplate="{StaticResource graphTooltipTemplate}" />
+ <components:GridLines Rows="4" Columns="6" GridBrush="{DynamicResource graphGridLinesBrush}"></components:GridLines>
+ </graphEx:RealTimeGraphExMultiLineErase.Components>
+ <graphEx:RealTimeGraphExMultiLineErase.InnerContent>
+ <Grid>
+ <Label Style="{StaticResource graphLabel}">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorName,FallbackValue='Dispensers Motors'}"></TextBlock>
+ <TextBlock Foreground="Gray" Margin="10 0 0 0" FontFamily="Sylfaen Regular" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl,AncestorLevel=2},Path=SensorUnits,FallbackValue='(hz)'}"></TextBlock>
+ </StackPanel>
+ </Label>
+ </Grid>
+ </graphEx:RealTimeGraphExMultiLineErase.InnerContent>
+ </graphEx:RealTimeGraphExMultiLineErase>
+ </Border>
+
+ <Border Grid.Column="2" Margin="5 0 0 0" HorizontalAlignment="Right" Opacity="0.8">
+ <components:YAxisLegends VerticalAlignment="Center" Margin="0 0 5 0" Graph="{Binding ElementName=Graph}" Width="70" FlowDirection="RightToLeft" LegendTemplate="{StaticResource graphLegendTemplate}">
+ </components:YAxisLegends>
+ </Border>
+ </Grid>
+ </ContentControl>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs
new file mode 100644
index 000000000..8e3b6b6e3
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/RealTimeGraphMultiControl.xaml.cs
@@ -0,0 +1,162 @@
+using RealTimeGraphEx;
+using RealTimeGraphEx.Controllers;
+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.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.MachineStudio.Common.Controls
+{
+ /// <summary>
+ /// Interaction logic for RealTimeGraphControl.xaml
+ /// </summary>
+ public partial class RealTimeGraphMultiControl : UserControl , IRealTimeGraph
+ {
+ private Grid headerGrid;
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the name of the sensor.
+ /// </summary>
+ public String SensorName
+ {
+ get { return (String)GetValue(SensorNameProperty); }
+ set { SetValue(SensorNameProperty, value); }
+ }
+ public static readonly DependencyProperty SensorNameProperty =
+ DependencyProperty.Register("SensorName", typeof(String), typeof(RealTimeGraphMultiControl), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the sensor units.
+ /// </summary>
+ public String SensorUnits
+ {
+ get { return (String)GetValue(SensorUnitsProperty); }
+ set { SetValue(SensorUnitsProperty, value); }
+ }
+ public static readonly DependencyProperty SensorUnitsProperty =
+ DependencyProperty.Register("SensorUnits", typeof(String), typeof(RealTimeGraphMultiControl), new PropertyMetadata(null));
+
+ public double Minimum
+ {
+ get { return (double)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(double), typeof(RealTimeGraphMultiControl), new PropertyMetadata(0.0));
+
+
+
+ public double Maximum
+ {
+ get { return (double)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(double), typeof(RealTimeGraphMultiControl), new PropertyMetadata(100.0));
+
+ public void InvalidateGraph()
+ {
+ InnerGraph.Clear();
+ yAxis.Render(InnerGraph);
+ yAxisTicks.Render(InnerGraph);
+ }
+
+ /// <summary>
+ /// Gets or sets the inner real-time graph control.
+ /// </summary>
+ public RealTimeGraphExBase InnerGraph { get; set; }
+
+ /// <summary>
+ /// Gets or sets the inner graph controller.
+ /// </summary>
+ public GraphControllerBase Controller { get; set; }
+
+ private bool _enableToolbar;
+ /// <summary>
+ /// Gets or sets a value indicating whether to enable toolbar buttons.
+ /// </summary>
+ public bool EnableToolBar
+ {
+ get { return _enableToolbar; }
+ set
+ {
+ _enableToolbar = value;
+
+ if (!value)
+ {
+ if (headerGrid != null)
+ {
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, -35, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Events
+
+ public event EventHandler GraphRemoveButtonPressed;
+ public event EventHandler GraphFullScreenButtonPressed;
+
+ #endregion
+
+ public RealTimeGraphMultiControl()
+ {
+ InitializeComponent();
+ EnableToolBar = true;
+ InnerGraph = Graph;
+ Controller = new GraphMultiController();
+ }
+
+ private void OnGraphFullScreen(object sender, RoutedEventArgs e)
+ {
+ GraphFullScreenButtonPressed?.Invoke(this, new EventArgs());
+ }
+
+ private void Graph_MouseEnter(object sender, MouseEventArgs e)
+ {
+ if (EnableToolBar)
+ {
+ Grid mainGrid = sender as Grid;
+ headerGrid = mainGrid.Children.OfType<Grid>().ToList().First();
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, 0, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+ }
+
+ private void Graph_MouseLeave(object sender, MouseEventArgs e)
+ {
+ Grid mainGrid = sender as Grid;
+ headerGrid = mainGrid.Children.OfType<Grid>().ToList().First();
+ ThicknessAnimation ani = new ThicknessAnimation();
+ ani.To = new Thickness(0, -35, 0, 0);
+ ani.Duration = TimeSpan.FromSeconds(0.2);
+ headerGrid.BeginAnimation(Grid.MarginProperty, ani);
+ }
+
+ private void OnGraphRemove(object sender, RoutedEventArgs e)
+ {
+ GraphRemoveButtonPressed?.Invoke(this, new EventArgs());
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.cs
new file mode 100644
index 000000000..07fd0c446
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/TableGrid.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;
+
+namespace Tango.MachineStudio.Common.Controls
+{
+ public class TableGrid : Grid
+ {
+ public TableGrid()
+ {
+ ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
+ ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
+ this.Loaded += TableGrid_Loaded;
+ }
+
+ private void TableGrid_Loaded(object sender, RoutedEventArgs e)
+ {
+ InvalidateGrid();
+ }
+
+ protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
+ {
+ base.OnVisualChildrenChanged(visualAdded, visualRemoved);
+ }
+
+ protected override Size ArrangeOverride(Size arrangeSize)
+ {
+ return base.ArrangeOverride(arrangeSize);
+ }
+
+ private void InvalidateGrid()
+ {
+ RowDefinitions.Clear();
+ RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
+
+ int currentRow = 0;
+
+ for (int i = 0; i < Children.Count; i++)
+ {
+ SetRow(Children[i], currentRow);
+
+ if (i % 2 != 0)
+ {
+ SetColumn(Children[i], 1);
+ (Children[i] as FrameworkElement).Margin = new Thickness(20, 0, 0, 0);
+ currentRow++;
+ RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
+ }
+
+ (Children[i] as FrameworkElement).VerticalAlignment = VerticalAlignment.Bottom;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PointToMarginConverter.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PointToMarginConverter.cs
index e6587b1ee..94748fb26 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PointToMarginConverter.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/PointToMarginConverter.cs
@@ -9,8 +9,13 @@ using System.Windows.Data;
namespace Tango.MachineStudio.Common.Converters
{
+ /// <summary>
+ /// Represents a <see cref="Point"/> to <see cref="Thickness"/> binding converter.
+ /// </summary>
+ /// <seealso cref="System.Windows.Data.IValueConverter" />
public class PointToMarginConverter : IValueConverter
{
+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Point p = (Point)value;
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/SecondsToGraphPointsConverter.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/SecondsToGraphPointsConverter.cs
new file mode 100644
index 000000000..17df7b9d5
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Converters/SecondsToGraphPointsConverter.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.MachineStudio.Common.Converters
+{
+ /// <summary>
+ /// Converts number of seconds to graph FIFO capacity.
+ /// </summary>
+ /// <seealso cref="System.Windows.Data.IValueConverter" />
+ public class SecondsToGraphPointsConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ double arrLength = double.Parse(parameter.ToString());
+ return Helpers.GraphsHelper.GetMaxPoints(arrLength);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return value;
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs
new file mode 100644
index 000000000..b77619ac2
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Integration.Operators;
+using Tango.MachineStudio.Common.StudioApplication;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.MachineStudio.Common.Diagnostics
+{
+ /// <summary>
+ /// Represents the default diagnostics frame provider.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.Diagnostics.IDiagnosticsFrameProvider" />
+ public class DefaultDiagnosticsFrameProvider : IDiagnosticsFrameProvider
+ {
+ /// <summary>
+ /// Disables the frame delivery from the current connected machine and enables the manual push frame method.
+ /// </summary>
+ public bool Disable { get; set; }
+
+ /// <summary>
+ /// Occurs when a new data frame is available.
+ /// </summary>
+ public event EventHandler<PushDiagnosticsResponse> FrameReceived;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultDiagnosticsFrameProvider"/> class.
+ /// </summary>
+ /// <param name="applicationManager">The application manager.</param>
+ public DefaultDiagnosticsFrameProvider(IStudioApplicationManager applicationManager)
+ {
+ applicationManager.ConnectedMachineChanged += ApplicationManager_ConnectedMachineChanged;
+ }
+
+ /// <summary>
+ /// Applications the manager connected machine changed.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="machine">The machine.</param>
+ private void ApplicationManager_ConnectedMachineChanged(object sender, Integration.Services.IExternalBridgeClient machine)
+ {
+ if (machine != null)
+ {
+ (machine as MachineOperator).DiagnosticsDataAvailable += DefaultDiagnosticsFrameProvider_DiagnosticsDataAvailable;
+ }
+ }
+
+ /// <summary>
+ /// Defaults the diagnostics frame provider diagnostics data available.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="frame">The frame.</param>
+ private void DefaultDiagnosticsFrameProvider_DiagnosticsDataAvailable(object sender, PushDiagnosticsResponse frame)
+ {
+ if (!Disable)
+ {
+ OnFrameReceived(frame);
+ }
+ }
+
+ /// <summary>
+ /// Push frames manual. (Only when Disable = true)
+ /// </summary>
+ /// <param name="frame">The frame.</param>
+ public void PushFrame(PushDiagnosticsResponse frame)
+ {
+ if (Disable)
+ {
+ OnFrameReceived(frame);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="FrameReceived"/> event.
+ /// </summary>
+ /// <param name="frame">The frame.</param>
+ protected virtual void OnFrameReceived(PushDiagnosticsResponse frame)
+ {
+ FrameReceived?.Invoke(this, frame);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs
new file mode 100644
index 000000000..0d63b59b6
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Diagnostics;
+
+namespace Tango.MachineStudio.Common.Diagnostics
+{
+ /// <summary>
+ /// Represents a tango machine diagnostics frame provider.
+ /// </summary>
+ public interface IDiagnosticsFrameProvider
+ {
+ /// <summary>
+ /// Occurs when a new data frame is available.
+ /// </summary>
+ event EventHandler<PushDiagnosticsResponse> FrameReceived;
+
+ /// <summary>
+ /// Disables the frame delivery from the current connected machine and enables the manual push frame method.
+ /// </summary>
+ bool Disable { get; set; }
+
+ /// <summary>
+ /// Push frames manual. (Only when Disable = true)
+ /// </summary>
+ /// <param name="frame">The frame.</param>
+ void PushFrame(PushDiagnosticsResponse frame);
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/IStudioMessageExtensions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/IStudioMessageExtensions.cs
index 83183f328..7ae259e04 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/IStudioMessageExtensions.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/IStudioMessageExtensions.cs
@@ -6,8 +6,15 @@ using System.Text;
using System.Threading.Tasks;
using Tango.MachineStudio.Common.Messages;
+/// <summary>
+/// Contains <see cref="IStudioMessage"/> extension methods.
+/// </summary>
public static class IStudioMessageExtensions
{
+ /// <summary>
+ /// Sends the message.
+ /// </summary>
+ /// <param name="message">The message.</param>
public static void Send(this IStudioMessage message)
{
Messenger.Default.Send(message);
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/UserExtensions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/UserExtensions.cs
deleted file mode 100644
index a6c98319e..000000000
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ExtensionMethods/UserExtensions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.DAL.Observables;
-
-public static class UserExtensions
-{
- public static bool HasPermission(this User user, Permissions permission)
- {
- return user.UsersRoles.Select(x => x.Role).ToList().SelectMany(x => x.RolesPermissions).ToList().Exists(x => x.Permission.Code == permission.ToInt32());
- }
-}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/digital-7.ttf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/digital-7.ttf
new file mode 100644
index 000000000..5dbe6f908
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/digital-7.ttf
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Helpers/GraphsHelper.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Helpers/GraphsHelper.cs
new file mode 100644
index 000000000..53e832eb5
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Helpers/GraphsHelper.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Settings;
+
+namespace Tango.MachineStudio.Common.Helpers
+{
+ /// <summary>
+ /// Contains RealTimeGraphEx helper methods.
+ /// </summary>
+ public static class GraphsHelper
+ {
+ /// <summary>
+ /// Gets the maximum points graph points by correlating between seconds duration from settings and expected graph points per frame.
+ /// </summary>
+ /// <param name="pointsPerFrame">Length of graph points per frame.</param>
+ /// <returns></returns>
+ public static int GetMaxPoints(double pointsPerFrame)
+ {
+ try
+ {
+ double seconds = SettingsManager.Default.MachineStudio.TechnicianModule.GraphsDuration;
+ double pullRate = SettingsManager.Default.MachineStudio.TechnicianModule.GraphsPullingInterval;
+ return (int)(((pullRate * pointsPerFrame * 10 * seconds) * (10 / pullRate)) * 0.65);
+ }
+ catch (Exception)
+ {
+ return 300;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioModule.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioModule.cs
index 902a45a2f..7718c0a7a 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioModule.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/IStudioModule.cs
@@ -5,24 +5,54 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
-using Tango.DAL.Observables;
+using Tango.Integration.Observables;
namespace Tango.MachineStudio.Common
{
+ /// <summary>
+ /// Represents a Machine Studio module.
+ /// </summary>
+ /// <seealso cref="System.IDisposable" />
public interface IStudioModule : IDisposable
{
+ /// <summary>
+ /// Gets the module name.
+ /// </summary>
String Name { get; }
+ /// <summary>
+ /// Gets the module description.
+ /// </summary>
String Description { get; }
+ /// <summary>
+ /// Gets the module cover image.
+ /// </summary>
BitmapSource Image { get; }
+ /// <summary>
+ /// Gets the module entry point view.
+ /// </summary>
FrameworkElement MainView { get; }
+ /// <summary>
+ /// Gets the permission required to see and load this module.
+ /// </summary>
Permissions Permission { get; }
+ /// <summary>
+ /// Gets a value indicating whether this module has been initialized.
+ /// </summary>
bool IsInitialized { get; }
+ /// <summary>
+ /// Perform any operations required to initialize this module.
+ /// </summary>
void Initialize();
+
+ /// <summary>
+ /// Sets a value indicating whether this module is loaded.
+ /// </summary>
+ bool IsLoaded { set; get; }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/IStudioMessage.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/IStudioMessage.cs
index 7d1232c7b..61056ab16 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/IStudioMessage.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/IStudioMessage.cs
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.Common.Messages
{
+ /// <summary>
+ /// Represents an MVVM base interface for MVVM Light Messenger messages.
+ /// </summary>
public interface IStudioMessage
{
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Modules/IStudioModuleLoader.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Modules/IStudioModuleLoader.cs
index d67accbc1..1fd72c53a 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Modules/IStudioModuleLoader.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Modules/IStudioModuleLoader.cs
@@ -7,12 +7,31 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.Common.Modules
{
+ /// <summary>
+ /// Represents a Machine Studio <see cref="IStudioModule"/> modules loading engine.
+ /// </summary>
public interface IStudioModuleLoader
{
+ /// <summary>
+ /// Gets all loaded modules.
+ /// </summary>
ObservableCollection<IStudioModule> AllModules { get; }
+ /// <summary>
+ /// Gets all the user permitted modules.
+ /// </summary>
ObservableCollection<IStudioModule> UserModules { get; }
+ /// <summary>
+ /// Gets the studio module of type T if loaded.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ T GetStudioModule<T>() where T : IStudioModule;
+
+ /// <summary>
+ /// Loads all available Machine Studio modules.
+ /// </summary>
void LoadModules();
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/INavigationManager.cs
index 631f9e2eb..4d1cbea8c 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/INavigationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/INavigationManager.cs
@@ -6,8 +6,15 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.Common.Navigation
{
+ /// <summary>
+ /// Represents the Machine Studio views navigation manager.
+ /// </summary>
public interface INavigationManager
{
+ /// <summary>
+ /// Navigates to the specified view.
+ /// </summary>
+ /// <param name="view">The view.</param>
void NavigateTo(NavigationView view);
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/NavigationView.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/NavigationView.cs
index 77dbaf5b4..db0f0471f 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/NavigationView.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Navigation/NavigationView.cs
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.Common.Navigation
{
+ /// <summary>
+ /// Represents the available views to navigate to using the <see cref="INavigationManager"/>.
+ /// </summary>
public enum NavigationView
{
LoadingView,
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/BarItem.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/BarItem.cs
new file mode 100644
index 000000000..d46bf5b5d
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/BarItem.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core;
+
+namespace Tango.MachineStudio.Common.Notifications
+{
+ public class BarItem : ExtendedObject, IDisposable
+ {
+ private INotificationProvider _notificationProvider;
+
+ public FrameworkElement Element { get; set; }
+
+ public BarItem(INotificationProvider notificationProvider)
+ {
+ _notificationProvider = notificationProvider;
+ }
+
+ public BarItem(INotificationProvider notificationProvider, FrameworkElement element) : this(notificationProvider)
+ {
+ Element = element;
+ }
+
+ /// <summary>
+ /// Removed this item from the queue.
+ /// </summary>
+ public void Pop()
+ {
+ _notificationProvider.PopBarItem(this);
+ }
+
+ /// <summary>
+ /// Pushes this item to the queue.
+ /// </summary>
+ public void Push()
+ {
+ _notificationProvider.PushBarItem(this);
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Pop();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/DialogViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/DialogViewVM.cs
index e5e4cac78..5fcd63071 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/DialogViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/DialogViewVM.cs
@@ -8,11 +8,18 @@ using Tango.SharedUI;
namespace Tango.MachineStudio.Common.Notifications
{
+ /// <summary>
+ /// Represents a dialog view model base class.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
public abstract class DialogViewVM : ViewModel
{
public event Action Accepted;
public event Action Canceled;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DialogViewVM"/> class.
+ /// </summary>
public DialogViewVM()
{
CanClose = true;
@@ -20,25 +27,39 @@ namespace Tango.MachineStudio.Common.Notifications
}
private bool _canClose;
-
+ /// <summary>
+ /// Gets or sets a value indicating whether this dialog can be closed.
+ /// </summary>
public bool CanClose
{
get { return _canClose; }
set { _canClose = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
+ /// <summary>
+ /// Gets or sets the close command.
+ /// </summary>
public RelayCommand CloseCommand { get; set; }
+ /// <summary>
+ /// Called when the dialog has been shown.
+ /// </summary>
public virtual void OnShow()
{
}
+ /// <summary>
+ /// Invokes the <see cref="Accepted"/> event.
+ /// </summary>
protected virtual void Accept()
{
Accepted?.Invoke();
}
+ /// <summary>
+ /// Invokes the <see cref="Canceled"/> event.
+ /// </summary>
protected virtual void Cancel()
{
Canceled?.Invoke();
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/INotificationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/INotificationProvider.cs
index 937a39ec2..e1b6275bd 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/INotificationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/INotificationProvider.cs
@@ -10,34 +10,135 @@ using System.Windows.Media;
namespace Tango.MachineStudio.Common.Notifications
{
+ /// <summary>
+ /// Represents the Machine Studio user notification provider responsible for displaying information, alerts and dialogs to the user.
+ /// </summary>
public interface INotificationProvider
{
+ /// <summary>
+ /// Gets the collection of active task items.
+ /// </summary>
ObservableCollection<TaskItem> TaskItems { get; }
+ /// <summary>
+ /// Gets the collection of active bar items.
+ /// </summary>
+ ObservableCollection<BarItem> BarItems { get; }
+
+ /// <summary>
+ /// Gets the current displayed task item.
+ /// </summary>
TaskItem CurrentTaskItem { get; }
+ /// <summary>
+ /// Gets a value indicating whether there are any queued task items.
+ /// </summary>
bool HasTaskItems { get; }
+ /// <summary>
+ /// Pushes the specified task item to the queue.
+ /// </summary>
+ /// <param name="taskItem">The task item.</param>
void PushTaskItem(TaskItem taskItem);
+ /// <summary>
+ /// Create and push a new task item from the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
TaskItem PushTaskItem(String message);
+ /// <summary>
+ /// Creates and push a new bar item from the specified framework element.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <returns></returns>
+ BarItem PushBarItem(FrameworkElement element);
+
+ /// <summary>
+ /// Pushes the specified bar item.
+ /// </summary>
+ /// <param name="barItem">The bar item.</param>
+ /// <returns></returns>
+ BarItem PushBarItem(BarItem barItem);
+
+ /// <summary>
+ /// Removed the specified task item from the queue.
+ /// </summary>
+ /// <param name="taskItem">The task item.</param>
void PopTaskItem(TaskItem taskItem);
+ /// <summary>
+ /// Removed the specified bar item.
+ /// </summary>
+ /// <param name="barItem">The bar item.</param>
+ void PopBarItem(BarItem barItem);
+
+ /// <summary>
+ /// Creates a new instance of the specified View type and displays it as a modal dialog.
+ /// </summary>
+ /// <typeparam name="View">The type of the view.</typeparam>
+ /// <typeparam name="VM">The type of the view model.</typeparam>
+ /// <param name="onAccept">Accept button callback.</param>
+ /// <param name="onCancel">Cancel button callback.</param>
void ShowModalDialog<View, VM>(Action<VM> onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM;
+ /// <summary>
+ /// Creates a new view by a naming convention of the specified view model type.
+ /// </summary>
+ /// <typeparam name="VM">The type of the view model.</typeparam>
+ /// <param name="onAccept">Accept button callback.</param>
+ /// <param name="onCancel">Cancel button callback.</param>
void ShowModalDialog<VM>(Action<VM> onAccept, Action onCancel) where VM : DialogViewVM;
+ /// <summary>
+ /// Creates a new view by a naming convention of the specified view model type.
+ /// </summary>
+ /// <typeparam name="VM">The type of the view model.</typeparam>
+ /// <param name="onAccept">Accept button callback.</param>
void ShowModalDialog<VM>(Action<VM> onAccept) where VM : DialogViewVM;
- bool? ShowDialog(PackIconKind icon, Brush iconColor, String message, bool hasCancel);
+ /// <summary>
+ /// Display a message box.
+ /// </summary>
+ /// <param name="icon">The icon.</param>
+ /// <param name="iconColor">Color of the icon.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="hasCancel">if set to <c>true</c> displays the cancel button.</param>
+ /// <returns></returns>
+ bool? ShowMessageBox(PackIconKind icon, Brush iconColor, String message, bool hasCancel);
+ /// <summary>
+ /// Shows an information message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
void ShowInfo(String message);
- void ShowWarnning(String message);
+ /// <summary>
+ /// Shows warning message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ void ShowWarning(String message);
+ /// <summary>
+ /// Shows an error message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
void ShowError(String message);
+ /// <summary>
+ /// Shows a question message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
bool ShowQuestion(String message);
+
+ /// <summary>
+ /// Shows a dialog with a text input field and returns the response.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="hint">Text field hint.</param>
+ /// <param name="defaultResponse">Optional default response.</param>
+ /// <returns></returns>
+ String ShowTextInput(String message, String hint, String defaultResponse = null);
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/TaskItem.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/TaskItem.cs
index 0cf5e2c8e..110fbfa74 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/TaskItem.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Notifications/TaskItem.cs
@@ -7,32 +7,53 @@ using Tango.Core;
namespace Tango.MachineStudio.Common.Notifications
{
+ /// <summary>
+ /// Represents a Machine Studio "work-bar" item.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="System.IDisposable" />
public class TaskItem : ExtendedObject, IDisposable
{
private INotificationProvider _notificationProvider;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TaskItem"/> class.
+ /// </summary>
+ /// <param name="notificationProvider">The notification provider.</param>
public TaskItem(INotificationProvider notificationProvider)
{
_notificationProvider = notificationProvider;
}
private String _message;
+ /// <summary>
+ /// Gets or sets the message.
+ /// </summary>
public String Message
{
get { return _message; }
set { _message = value; RaisePropertyChangedAuto(); }
}
+ /// <summary>
+ /// Removed this item from the queue.
+ /// </summary>
public void Pop()
{
_notificationProvider.PopTaskItem(this);
}
+ /// <summary>
+ /// Pushes this item to the queue.
+ /// </summary>
public void Push()
{
_notificationProvider.PushTaskItem(this);
}
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
public void Dispose()
{
Pop();
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Properties/AssemblyInfo.cs
index 33d6edb60..f03b250be 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Properties/AssemblyInfo.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Properties/AssemblyInfo.cs
@@ -15,3 +15,6 @@ using System.Windows;
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
+
+//Friends With
+[assembly: InternalsVisibleTo("Tango.MachineStudio.UI")]
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/GradientOffsetSlider.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/GradientOffsetSlider.xaml
new file mode 100644
index 000000000..28d29a727
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/GradientOffsetSlider.xaml
@@ -0,0 +1,83 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.MachineStudio.Common.Resources"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
+
+
+ <Style x:Key="SliderRepeatButton" TargetType="RepeatButton">
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="OverridesDefaultStyle" Value="true" />
+ <Setter Property="IsTabStop" Value="false" />
+ <Setter Property="Focusable" Value="false" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="RepeatButton">
+ <Border BorderThickness="1" BorderBrush="#8A8A8A" Background="#8A8A8A" Height="3"/>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="SliderRepeatButton1" TargetType="RepeatButton">
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="OverridesDefaultStyle" Value="true" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="RepeatButton">
+ <Border SnapsToDevicePixels="True" Background="#7F7F7F" BorderThickness="1" BorderBrush="#777777" Height="3"/>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="SliderThumb" TargetType="Thumb">
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="OverridesDefaultStyle" Value="true" />
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="Margin" Value="-11 -20 0 0"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Thumb">
+ <Canvas>
+ <materialDesign:PackIcon Kind="MapMarker" Width="24" Background="Transparent" Height="24" IsHitTestVisible="True" Margin="0 0 0 0" />
+ </Canvas>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <ControlTemplate x:Key="Slider" TargetType="Slider">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Track Grid.Row="1" x:Name="PART_Track" >
+ <Track.DecreaseRepeatButton>
+ <RepeatButton Style="{StaticResource SliderRepeatButton1}" Command="Slider.DecreaseLarge" />
+ </Track.DecreaseRepeatButton>
+ <Track.Thumb>
+ <Thumb Style="{StaticResource SliderThumb}" />
+ </Track.Thumb>
+ <Track.IncreaseRepeatButton>
+ <RepeatButton Style="{StaticResource SliderRepeatButton}" Command="Slider.IncreaseLarge" />
+ </Track.IncreaseRepeatButton>
+ </Track>
+ </Grid>
+ </ControlTemplate>
+
+ <Style x:Key="GradientOffsetSlider" TargetType="Slider">
+ <Setter Property="Focusable" Value="False"/>
+ <Setter Property="SnapsToDevicePixels" Value="true" />
+ <Setter Property="OverridesDefaultStyle" Value="true" />
+ <Style.Triggers>
+ <Trigger Property="Orientation" Value="Horizontal">
+ <Setter Property="MinHeight" Value="21" />
+ <Setter Property="MinWidth" Value="104" />
+ <Setter Property="Template" Value="{StaticResource Slider}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml
index 58bb9ef34..ca0685f3c 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml
@@ -1,7 +1,9 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf"
+ xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters;assembly=MaterialDesignThemes.Wpf"
xmlns:editors="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete"
+ xmlns:dragAndDrop="clr-namespace:Tango.DragAndDrop;assembly=Tango.DragAndDrop"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Tango.MachineStudio.Common.Resources">
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
@@ -43,6 +45,7 @@
</ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/>
+ <ResourceDictionary Source="GradientOffsetSlider.xaml" />
<!--MahApps Brushes-->
<ResourceDictionary>
@@ -62,6 +65,11 @@
<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}" />
<SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4" />
</ResourceDictionary>
+
+ <!--Fonts-->
+ <ResourceDictionary>
+ <FontFamily x:Key="digital-7">../Fonts/#digital-7</FontFamily>
+ </ResourceDictionary>
<!--Styles-->
<ResourceDictionary>
@@ -172,6 +180,302 @@
</Setter.Value>
</Setter>
</Style>
+
+
+ <!--Extensions-->
+
+ <FontFamily x:Key="FontName">Segoe UI</FontFamily>
+ <FontFamily x:Key="NotesFont">Lucida Console</FontFamily>
+
+ <sys:Double x:Key="ExtraExtraLargeFontSize">28</sys:Double>
+ <sys:Double x:Key="ExtraLargeFontSize">26</sys:Double>
+ <sys:Double x:Key="LargeFontSize">20</sys:Double>
+ <sys:Double x:Key="MediumFontSize">16</sys:Double>
+ <sys:Double x:Key="SmallFontSize">14</sys:Double>
+ <sys:Double x:Key="MiniFontSize">12</sys:Double>
+ <sys:Double x:Key="TinyFontSize">9</sys:Double>
+
+ <!--Colors-->
+ <Color x:Key="borderColor">Silver</Color>
+ <Color x:Key="graphGridLinesColor">#FFE9E9E9</Color>
+ <Color x:Key="graphsMarkerColor">Gray</Color>
+ <Color x:Key="materialColor">#03A9F4</Color>
+
+ <!--Brushes-->
+ <SolidColorBrush x:Key="borderBrush" Color="{StaticResource borderColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="graphGridLinesBrush" Color="{StaticResource graphGridLinesColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="BlackBrush" Color="#545454"></SolidColorBrush>
+
+ <SolidColorBrush x:Key="graphGridLinesLightBrush" Color="{StaticResource graphGridLinesColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="graphGridLinesDarkBrush" Color="#FF2E2E2E"></SolidColorBrush>
+
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="graphBackgroundLight">
+ <GradientStop Color="White"/>
+ <GradientStop Color="#FFE9E9E9" Offset="1"/>
+ </LinearGradientBrush>
+
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="graphBackgroundDark">
+ <GradientStop Color="Black"/>
+ <GradientStop Color="#FF333333" Offset="1"/>
+ </LinearGradientBrush>
+
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="graphBackground">
+ <GradientStop Color="White"/>
+ <GradientStop Color="#FFE9E9E9" Offset="1"/>
+ </LinearGradientBrush>
+
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="graphLabelBackground" Opacity="0.7">
+ <GradientStop Color="White"/>
+ <GradientStop Color="#FFD9D9D9" Offset="1"/>
+ </LinearGradientBrush>
+
+ <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" x:Key="graphLegendBackground" Opacity="0.7">
+ <GradientStop Color="#FFE9E9E9"/>
+ <GradientStop Color="#FFBDBDBD" Offset="1"/>
+ </LinearGradientBrush>
+
+ <SolidColorBrush Color="#FFF1F1F1" x:Key="topBarBackgroundBrush"></SolidColorBrush>
+ <!--Brushes-->
+
+ <!--Graph Label-->
+ <Style x:Key="graphLabel" TargetType="Label">
+ <Style.Setters>
+ <Setter Property="IsHitTestVisible" Value="False"></Setter>
+ <Setter Property="Margin" Value="-1 -1 0 0"></Setter>
+ <Setter Property="HorizontalAlignment" Value="Left"></Setter>
+ <Setter Property="VerticalAlignment" Value="Top"></Setter>
+ <Setter Property="Padding" Value="0"></Setter>
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <Border Width="Auto" Padding="0 0 20 0" Height="25" BorderBrush="{StaticResource AccentColorBrush}" BorderThickness="1" CornerRadius="0 0 30 0" Background="{StaticResource graphLabelBackground}" >
+ <Label Margin="5 0 0 0" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="{StaticResource TinyFontSize}" Content="{Binding}"></Label>
+ </Border>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style.Setters>
+ </Style>
+ <!--Graph Label-->
+
+
+ <!--Graph Ticks Template-->
+ <DataTemplate x:Key="graphTicksTemplate">
+ <Ellipse Width="3" Height="3" Margin="0 0 0 0" Fill="{StaticResource AccentColorBrush}"></Ellipse>
+ </DataTemplate>
+ <!--Graph Ticks Template-->
+
+ <DataTemplate x:Key="graphTooltipTemplate">
+ <Border CornerRadius="5" BorderThickness="1" BorderBrush="White" Padding="8" MinWidth="50" Margin="20 0 20 0">
+ <Border.Background>
+ <SolidColorBrush Color="Black" Opacity="0.5"></SolidColorBrush>
+ </Border.Background>
+ <TextBlock Foreground="White" FontSize="10" HorizontalAlignment="Center" TextAlignment="Center" Text="{Binding StringFormat='0.000'}"></TextBlock>
+ </Border>
+ </DataTemplate>
+
+ <!--Graph Legend Template-->
+ <DataTemplate x:Key="graphLegendTemplate">
+ <Border Width="20" Height="20" Margin="2">
+ <Grid>
+ <ToggleButton IsChecked="{Binding IsVisible}" Padding="0" Margin="0" Background="Transparent" BorderBrush="{x:Null}" BorderThickness="0">
+ <ToggleButton.Style>
+ <Style TargetType="ToggleButton">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate>
+ <Grid Background="Transparent">
+ <Grid>
+ <Ellipse HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{StaticResource graphLegendBackground}" StrokeThickness="1">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsVisible}" Value="True">
+ <Setter Property="Stroke" Value="{Binding Stroke}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsVisible}" Value="False">
+ <Setter Property="Stroke" Value="Transparent"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <TextBlock FontSize="8" Text="{Binding Name}" VerticalAlignment="Center" Foreground="Black" FontWeight="DemiBold" HorizontalAlignment="Center"></TextBlock>
+ </Grid>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ToggleButton.Style>
+ </ToggleButton>
+ </Grid>
+ </Border>
+ </DataTemplate>
+ <!--Graph Legend Template-->
+
+
+ <Style TargetType="{x:Type ListBoxItem}" x:Key="basicListBoxItem">
+ <Setter Property="Background" Value="Transparent"/>
+ <Setter Property="BorderThickness" Value="0"></Setter>
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
+ <Setter Property="Padding" Value="0"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type ListBoxItem}">
+ <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Background="{TemplateBinding Background}" Padding="0" SnapsToDevicePixels="true">
+ <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsSelected" Value="true">
+ <Setter Property="Background" TargetName="Bd" Value="Transparent"/>
+ </Trigger>
+ <MultiTrigger>
+ <MultiTrigger.Conditions>
+ <Condition Property="IsSelected" Value="true"/>
+ <Condition Property="Selector.IsSelectionActive" Value="false"/>
+ </MultiTrigger.Conditions>
+ <Setter Property="Background" TargetName="Bd" Value="Transparent"/>
+ </MultiTrigger>
+ <Trigger Property="IsEnabled" Value="false">
+ <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <PathGeometry x:Key="CirclePath">M46.615 402.03c6.549 9.313 13.718 18.176 21.456 26.528l23.472-21.728c-6.767-7.3-13.038-15.045-18.768-23.184 L46.615 402.03z M32.007 254.83c0.178-112.07 83.047-206.811 194.096-221.904l-4.192-31.728C81.787 20.041-16.53 148.91 2.314 289.033 c3.942 29.31 12.932 57.716 26.573 83.957l28.368-14.784C40.563 326.311 31.897 290.828 32.007 254.83z M92.807 452.03c8.765 7.252 17.995 13.923 27.632 19.968l16.976-27.2c-8.448-5.292-16.535-11.139-24.208-17.504 L92.807 452.03z M361.761 21.742c-22.756-10.308-46.898-17.229-71.658-20.544l-4.192 31.728 c122.555 16.88 208.221 129.915 191.341 252.469C462.017 396.001 367.656 478.501 256.007 478.83 c-31.831 0.078-63.306-6.694-92.288-19.856l-13.216 29.152c128.788 58.337 280.484 1.225 338.821-127.563 C547.661 231.775 490.549 80.079 361.761 21.742z</PathGeometry>
+
+ <Style TargetType="ContentControl" x:Key="numberBorder">
+ <Style.Setters>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ContentControl">
+ <Grid>
+ <Viewbox>
+ <Path Data="{StaticResource CirclePath}" Fill="{TemplateBinding Foreground}"></Path>
+ </Viewbox>
+ <ContentPresenter Content="{TemplateBinding Content}" />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style.Setters>
+ </Style>
+
+ <Style x:Key="emptyToggleButton" TargetType="ToggleButton">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ToggleButton">
+ <Grid Background="{TemplateBinding Background}">
+ <ContentPresenter />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="emptyButton" TargetType="Button">
+ <Setter Property="Background" Value="Transparent" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Grid Background="{TemplateBinding Background}">
+ <ContentPresenter />
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+
+ <!--Drag & Drop-->
+ <Style x:Key="draggableGrid" TargetType="Grid">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="1"></ScaleTransform>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.Draggable" Value="True"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.DraggingSurface" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}"></Setter>
+ </Style>
+
+ <Style x:Key="droppableGrid" TargetType="Grid">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="1"></ScaleTransform>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.Droppable" Value="True"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.DraggingSurface" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}"></Setter>
+ <Style.Triggers>
+ <Trigger Property="dragAndDrop:DragAndDropService.IsDraggableOver" Value="True">
+ <Setter Property="Opacity" Value="0.5"></Setter>
+ <Trigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation To="0.95" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleX"></DoubleAnimation>
+ <DoubleAnimation To="0.95" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleY"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </Trigger.EnterActions>
+ <Trigger.ExitActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation To="1" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleX"></DoubleAnimation>
+ <DoubleAnimation To="1" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleY"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </Trigger.ExitActions>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="draggableDroppableGrid" TargetType="Grid">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="1"></ScaleTransform>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
+ <Setter Property="Background" Value="Transparent"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.Draggable" Value="True"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.Droppable" Value="True"></Setter>
+ <Setter Property="dragAndDrop:DragAndDropService.DraggingSurface" Value="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}"></Setter>
+ <Style.Triggers>
+ <Trigger Property="dragAndDrop:DragAndDropService.IsDraggableOver" Value="True">
+ <Setter Property="Opacity" Value="0.5"></Setter>
+ <Trigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation To="0.95" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleX"></DoubleAnimation>
+ <DoubleAnimation To="0.95" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleY"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </Trigger.EnterActions>
+ <Trigger.ExitActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation To="1" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleX"></DoubleAnimation>
+ <DoubleAnimation To="1" Duration="00:00:0.2" Storyboard.TargetProperty="RenderTransform.ScaleY"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </Trigger.ExitActions>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ <!--Drag & Drop-->
+
+ <!--Extensions-->
+
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IModuleRequestListener.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IModuleRequestListener.cs
new file mode 100644
index 000000000..b950d7bcd
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IModuleRequestListener.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.StudioApplication
+{
+ /// <summary>
+ /// Represents a type which will be notified when a new module request was made by <see cref="IStudioApplicationManager.RequestModule(string, object)"/>
+ /// </summary>
+ public interface IModuleRequestListener
+ {
+ /// <summary>
+ /// Called when the request has been made.
+ /// </summary>
+ /// <param name="module">The module instance.</param>
+ /// <param name="args">The arguments.</param>
+ void OnRequestModule(IStudioModule module, Object args);
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownListener.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownListener.cs
new file mode 100644
index 000000000..1ca5a7df2
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownListener.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.StudioApplication
+{
+ /// <summary>
+ /// Used to notify view models about application terminating.
+ /// </summary>
+ public interface IShutdownListener
+ {
+ /// <summary>
+ /// Called when the application is about to terminate.
+ /// </summary>
+ void OnShuttingDown();
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownRequestBlocker.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownRequestBlocker.cs
index a157bd598..4d5f968a4 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownRequestBlocker.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IShutdownRequestBlocker.cs
@@ -6,8 +6,16 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.Common.StudioApplication
{
+ /// <summary>
+ /// Represents a component capable of receiving notification for when the Machine Studio shuts down.
+ /// The component can perform it's own shutdown operations, or cancel the current shutdown operation.
+ /// </summary>
public interface IShutdownRequestBlocker
{
+ /// <summary>
+ /// Called when the application is shutting down.
+ /// </summary>
+ /// <returns></returns>
Task<bool> OnShutdownRequest();
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
index 42f4f7b65..c67c34044 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs
@@ -7,12 +7,46 @@ using Tango.Integration.Services;
namespace Tango.MachineStudio.Common.StudioApplication
{
+ /// <summary>
+ /// Represents the Machine Studio application manager.
+ /// </summary>
public interface IStudioApplicationManager
{
- bool IsShuttingDown { get;}
+ /// <summary>
+ /// Occurs when the connected machine property has changed.
+ /// </summary>
+ event EventHandler<IExternalBridgeClient> ConnectedMachineChanged;
+
+ /// <summary>
+ /// Gets a value indicating whether Machine Studio is shutting down.
+ /// </summary>
+ bool IsShuttingDown { get; }
+
+ /// <summary>
+ /// Shutdown the application.
+ /// </summary>
void ShutDown();
+
+ /// <summary>
+ /// Gets or sets the currently connected machine if any.
+ /// </summary>
IExternalBridgeClient ConnectedMachine { get; set; }
+
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="ConnectedMachine"/> is valid.
+ /// </summary>
bool IsMachineConnected { get; }
- bool IsMachineConnectedViaTCP { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="ConnectedMachine"/> is valid and connected through TCP/IP.
+ /// </summary>
+ bool IsMachineConnectedViaTCP { get; }
+
+ /// <summary>
+ /// Loads the specified module if permitted.
+ /// </summary>
+ /// <param name="moduleName">Name of the module.</param>
+ /// <param name="args">The arguments.</param>
+ void RequestModule(String moduleName, Object args);
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioModuleBase.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioModuleBase.cs
new file mode 100644
index 000000000..5c594ab70
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioModuleBase.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using Tango.Integration.Observables;
+
+namespace Tango.MachineStudio.Common
+{
+ /// <summary>
+ /// Represents a base class for studio modules.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.IStudioModule" />
+ public abstract class StudioModuleBase : IStudioModule
+ {
+ private bool _isInitialized;
+ private bool _isLoaded;
+
+ /// <summary>
+ /// Occurs when the user has navigated into or out of this module.
+ /// </summary>
+ public event EventHandler<bool> IsLoadedChanged;
+
+ /// <summary>
+ /// Gets the module name.
+ /// </summary>
+ public abstract string Name { get; }
+
+ /// <summary>
+ /// Gets the module description.
+ /// </summary>
+ public abstract string Description { get; }
+
+ /// <summary>
+ /// Gets the module cover image.
+ /// </summary>
+ public abstract BitmapSource Image { get; }
+
+ /// <summary>
+ /// Gets the module entry point view.
+ /// </summary>
+ public abstract FrameworkElement MainView { get; }
+
+ /// <summary>
+ /// Gets the permission required to see and load this module.
+ /// </summary>
+ public abstract Permissions Permission { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this module has been initialized.
+ /// </summary>
+ public bool IsInitialized
+ {
+ get
+ {
+ return _isInitialized;
+ }
+ private set
+ {
+ _isInitialized = value;
+ }
+ }
+
+ /// <summary>
+ /// Sets a value indicating whether this module is loaded.
+ /// </summary>
+ public bool IsLoaded
+ {
+ get
+ {
+ return _isLoaded;
+ }
+ set
+ {
+ _isLoaded = value;
+ IsLoadedChanged?.Invoke(this, value);
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public abstract void Dispose();
+
+ /// <summary>
+ /// Perform any operations required to initialize this module.
+ /// </summary>
+ public void Initialize()
+ {
+ OnInitialized();
+ IsInitialized = true;
+ }
+
+ /// <summary>
+ /// Called when machine studio initializes this module.
+ /// </summary>
+ protected virtual void OnInitialized()
+ {
+
+ }
+
+ /// <summary>
+ /// Raises the <see cref="IsLoadedChanged"/> event.
+ /// </summary>
+ /// <param name="loaded">if set to <c>true</c> the module is loaded.</param>
+ protected virtual void OnLoadedChanged(bool loaded)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
index 49fee31f1..cd4fc1aeb 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj
@@ -71,13 +71,38 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Controls\HiveColorPickerControl.xaml.cs">
+ <DependentUpon>HiveColorPickerControl.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\IRealTimeGraph.cs" />
+ <Compile Include="Controls\RealTimeGraphMultiControl.xaml.cs">
+ <DependentUpon>RealTimeGraphMultiControl.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\RealTimeGraphControl.xaml.cs">
+ <DependentUpon>RealTimeGraphControl.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\TableGrid.cs" />
+ <Compile Include="Converters\SecondsToGraphPointsConverter.cs" />
+ <Compile Include="Diagnostics\DefaultDiagnosticsFrameProvider.cs" />
+ <Compile Include="Diagnostics\IDiagnosticsFrameProvider.cs" />
+ <Compile Include="Helpers\GraphsHelper.cs" />
+ <Compile Include="Notifications\BarItem.cs" />
<Compile Include="Notifications\DialogViewVM.cs" />
+ <Compile Include="StudioApplication\IModuleRequestListener.cs" />
+ <Compile Include="StudioApplication\IShutdownListener.cs" />
<Compile Include="StudioApplication\IStudioApplicationManager.cs" />
<Compile Include="StudioApplication\IShutdownRequestBlocker.cs" />
<Compile Include="ExtensionMethods\IStudioMessageExtensions.cs" />
<Compile Include="Messages\IStudioMessage.cs" />
<Compile Include="Notifications\TaskItem.cs" />
+ <Compile Include="StudioModuleBase.cs" />
<Compile Include="ValidationRules\Required.cs" />
+ <Compile Include="Video\DefaultVideoCaptureProvider.cs" />
+ <Compile Include="Video\IVideoCaptureProvider.cs" />
+ <Page Include="Controls\HiveColorPickerControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Controls\MdiContainerControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -91,12 +116,23 @@
<DependentUpon>MdiContainerControl.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\PointToMarginConverter.cs" />
- <Compile Include="ExtensionMethods\UserExtensions.cs" />
<Compile Include="IStudioModule.cs" />
<Compile Include="Modules\IStudioModuleLoader.cs" />
<Compile Include="Navigation\INavigationManager.cs" />
<Compile Include="Navigation\NavigationView.cs" />
<Compile Include="Notifications\INotificationProvider.cs" />
+ <Page Include="Controls\RealTimeGraphMultiControl.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Controls\RealTimeGraphControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Resources\GradientOffsetSlider.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Resources\MaterialDesign.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -121,6 +157,7 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.config" />
+ <Resource Include="Fonts\digital-7.ttf" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -128,30 +165,58 @@
</None>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\SideChains\RealTimeGraphEx\RealTimeGraphEx.csproj">
+ <Project>{b9ae25d6-be35-492f-9079-21a7f3e6f7cc}</Project>
+ <Name>RealTimeGraphEx</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj">
<Project>{bb2abb74-ba58-4812-83aa-ec8171f42df4}</Project>
<Name>Tango.AutoComplete</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.ColorPicker\Tango.ColorPicker.csproj">
+ <Project>{a2f5af44-29ff-45d6-9d25-ecda5cce88b5}</Project>
+ <Name>Tango.ColorPicker</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
</ProjectReference>
- <ProjectReference Include="..\..\Tango.DAL.Observables\Tango.DAL.Observables.csproj">
- <Project>{0ecd6da8-7aa6-48d9-8b65-279d176ad9af}</Project>
- <Name>Tango.DAL.Observables</Name>
- </ProjectReference>
<ProjectReference Include="..\..\Tango.DAL.Remote\Tango.DAL.Remote.csproj">
<Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project>
<Name>Tango.DAL.Remote</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.DragAndDrop\Tango.DragAndDrop.csproj">
+ <Project>{b112d89a-a106-41ae-a0c1-4abc84c477f5}</Project>
+ <Name>Tango.DragAndDrop</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Editors\Tango.Editors.csproj">
+ <Project>{de2f2b86-025b-4f26-83a4-38bd48224ed5}</Project>
+ <Name>Tango.Editors</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj">
<Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project>
<Name>Tango.Integration</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Settings\Tango.Settings.csproj">
+ <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
+ <Name>Tango.Settings</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.SharedUI\Tango.SharedUI.csproj">
<Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
<Name>Tango.SharedUI</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Video\Tango.Video.csproj">
+ <Project>{9652f972-2bd1-4283-99cb-fc6240434c17}</Project>
+ <Name>Tango.Video</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ValidationRules/Required.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ValidationRules/Required.cs
index 84f274965..aac00fdf1 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ValidationRules/Required.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/ValidationRules/Required.cs
@@ -8,8 +8,20 @@ using System.Windows.Controls;
namespace Tango.MachineStudio.Common.ValidationRules
{
+ /// <summary>
+ /// Represents a required field validation rule.
+ /// </summary>
+ /// <seealso cref="System.Windows.Controls.ValidationRule" />
public class Required : ValidationRule
{
+ /// <summary>
+ /// When overridden in a derived class, performs validation checks on a value.
+ /// </summary>
+ /// <param name="value">The value from the binding target to check.</param>
+ /// <param name="cultureInfo">The culture to use in this rule.</param>
+ /// <returns>
+ /// A <see cref="T:System.Windows.Controls.ValidationResult" /> object.
+ /// </returns>
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return new ValidationResult(!String.IsNullOrWhiteSpace(value.ToStringSafe()), "Required");
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/DefaultVideoCaptureProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/DefaultVideoCaptureProvider.cs
new file mode 100644
index 000000000..3aa9d4c88
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/DefaultVideoCaptureProvider.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Video.DirectCapture;
+
+namespace Tango.MachineStudio.Common.Video
+{
+ /// <summary>
+ /// Represents the default implementation of <see cref="IVideoCaptureProvider"/>.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.Video.IVideoCaptureProvider" />
+ public class DefaultVideoCaptureProvider : IVideoCaptureProvider
+ {
+ /// <summary>
+ /// Gets the available capture devices.
+ /// </summary>
+ public ObservableCollection<CaptureDevice> AvailableCaptureDevices { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultVideoCaptureProvider"/> class.
+ /// </summary>
+ public DefaultVideoCaptureProvider()
+ {
+ AvailableCaptureDevices = new ObservableCollection<CaptureDevice>();
+
+ var availableDevices = CaptureDevice.GetAvailableCaptureDevices();
+
+ for (int i = 0; i < 3; i++)
+ {
+ if (i > availableDevices.Count - 1)
+ {
+ AvailableCaptureDevices.Add(new CaptureDevice() { Device = null });
+ }
+ else
+ {
+ AvailableCaptureDevices.Add(new CaptureDevice() { Device = availableDevices[i] });
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/IVideoCaptureProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/IVideoCaptureProvider.cs
new file mode 100644
index 000000000..cd797dce2
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Video/IVideoCaptureProvider.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;
+using Tango.Video.DirectCapture;
+
+namespace Tango.MachineStudio.Common.Video
+{
+ /// <summary>
+ /// Represents a video capturing device provider.
+ /// </summary>
+ public interface IVideoCaptureProvider
+ {
+ /// <summary>
+ /// Gets the available capture devices.
+ /// </summary>
+ ObservableCollection<CaptureDevice> AvailableCaptureDevices { get; }
+ }
+}