diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
23 files changed, 836 insertions, 167 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config index 250f57a4d..d38c3ed69 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> - <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections> <startup> @@ -11,6 +10,63 @@ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> + <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> </providers> </entityFramework> + <system.data> + <DbProviderFactories> + <remove invariant="System.Data.SQLite.EF6" /> + <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> + <remove invariant="System.Data.SQLite" /> + <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /> + </DbProviderFactories> + </system.data> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> </configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml index 6974f54be..8e5876e79 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml @@ -9,64 +9,9 @@ <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> <!-- Accent and AppTheme setting --> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml"> - </ResourceDictionary> - <!--Material Design--> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.lightblue.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/materialdesigncolor.yellow.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.CheckBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ListBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.RadioButton.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.TextBlock.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Label.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.Slider.xaml"> - </ResourceDictionary> - <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/materialdesigntheme.ProgressBar.xaml"/> - - - <!--MahApps Brushes--> - <ResourceDictionary> - <SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}" /> - <SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}" /> - <SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}" /> - <SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}" /> - <SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}" /> - <SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}" /> - <LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5"> - <GradientStop Color="{DynamicResource Primary700}" Offset="0" /> - <GradientStop Color="{DynamicResource Primary300}" Offset="1" /> - </LinearGradientBrush> - <SolidColorBrush x:Key="CheckmarkFill" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}" /> - <SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}" /> - <SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4" /> - </ResourceDictionary> + <ResourceDictionary Source="pack://application:,,,/Tango.MachineStudio.Common;component/Resources/MaterialDesign.xaml"></ResourceDictionary> - <!-- Include the Dragablz Material Design style --> + <!-- Include the Dragablz Material Design style --> <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml"/> <ResourceDictionary> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs index 9193cfd3e..dfbc0eb77 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs @@ -14,6 +14,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.Core.Helpers; using Tango.MachineStudio.Common.StudioApplication; namespace Tango.MachineStudio.UI @@ -29,6 +30,7 @@ namespace Tango.MachineStudio.UI { InitializeComponent(); Instance = this; + ThreadsHelper.SetDisptacher(Dispatcher); this.Closing += MainWindow_Closing; } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs index 689ac7b38..9a8a6bc96 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs @@ -10,6 +10,7 @@ using Tango.Core; using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Modules; +using Tango.MachineStudio.Stubs; namespace Tango.MachineStudio.UI.Modules { @@ -49,6 +50,10 @@ namespace Tango.MachineStudio.UI.Modules { if (!_loaded) { + //Preloaded + AllModules.Add(new StubsModule()); + //Preloaded + AllModules.Clear(); string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); @@ -63,8 +68,11 @@ namespace Tango.MachineStudio.UI.Modules { foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IStudioModule).IsAssignableFrom(x))) { - var module = Activator.CreateInstance(moduleType) as IStudioModule; - AllModules.Add(module); + if (!AllModules.ToList().Exists(x => x.GetType() == moduleType)) + { + var module = Activator.CreateInstance(moduleType) as IStudioModule; + AllModules.Add(module); + } } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs index 10314ae62..15f2fe422 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs @@ -11,7 +11,10 @@ namespace Tango.MachineStudio.UI.Navigation { public void NavigateTo(NavigationView view) { - MainWindow.Instance.TransitionControl.AutoNavigate(view.ToString()); + MainWindow.Instance.Dispatcher.Invoke(() => + { + MainWindow.Instance.TransitionControl.AutoNavigate(view.ToString()); + }); } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs index b1ba03109..d4d053eaf 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs @@ -15,6 +15,8 @@ namespace Tango.MachineStudio.UI.Notifications { public class DefaultNotificationProvider : ExtendedObject, INotificationProvider { + private static List<Type> viewTypes; + public ObservableCollection<TaskItem> TaskItems { get; private set; } public bool HasTaskItems @@ -35,48 +37,126 @@ namespace Tango.MachineStudio.UI.Notifications TaskItems = new ObservableCollection<TaskItem>(); } - public bool ShowModalWindow<T>(PackIconKind icon, string title, object context) where T : FrameworkElement - { - return ShowModalWindow(icon, title, Activator.CreateInstance<T>(), context); - } - - public bool? ShowModalWindow(Window window) + public bool? ShowDialog(PackIconKind icon, Brush iconColor, string message, bool hasCancel) { - window.Owner = Application.Current.MainWindow; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; - bool result = window.ShowDialog().Value; + + var result = new MessageBoxWindow() + { + Owner = Application.Current.MainWindow, + Message = message, + IconKind = icon, + IconColor = iconColor, + HasCancel = hasCancel + + }.ShowDialog(); + MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; return result; } - public bool ShowModalWindow(PackIconKind icon, string title, FrameworkElement content, object context) + public void ShowModalDialog<View, VM>(Action<VM> onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM { - DialogWindow dialog = new DialogWindow(content); - dialog.DataContext = context; - dialog.InnerTitle = title; + var view = Activator.CreateInstance<View>(); + DialogWindow dialog = new DialogWindow(); dialog.Owner = Application.Current.MainWindow; + dialog.InnerContent = view; MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; - bool result = dialog.ShowDialog().Value; + view.Loaded += (x, y) => + { + VM context = view.DataContext as VM; + dialog.DataContext = context; + + Action onAcceptAction = null; + onAcceptAction = new Action(() => + { + dialog.Close(); + onAccept(context); + context.Accepted -= onAcceptAction; + }); + + Action onCancelAction = null; + onCancelAction = new Action(() => + { + dialog.Close(); + + if (onCancel != null) + { + onCancel(); + } + + context.Canceled -= onCancelAction; + }); + + context.Accepted += onAcceptAction; + context.Canceled += onCancelAction; + + context.OnShow(); + }; + dialog.ShowDialog(); MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; - return result; } - public bool? ShowDialog(PackIconKind icon, Brush iconColor, string message, bool hasCancel) + public void ShowModalDialog<VM>(Action<VM> onAccept, Action onCancel) where VM : DialogViewVM { - MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; + String viewName = typeof(VM).Name.Replace("VM", ""); - var result = new MessageBoxWindow() + if (viewTypes == null) { - Owner = Application.Current.MainWindow, - Message = message, - IconKind = icon, - IconColor = iconColor, - HasCancel = hasCancel + viewTypes = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.Contains("MachineStudio")).SelectMany(x => x.GetTypes()).ToList(); + } - }.ShowDialog(); + var viewType = viewTypes.SingleOrDefault(x => x.Name == viewName); + + if (viewType == null) + { + throw new NullReferenceException("Could not locate view " + viewName); + } + var view = Activator.CreateInstance(viewType) as FrameworkElement; + DialogWindow dialog = new DialogWindow(); + dialog.Owner = Application.Current.MainWindow; + dialog.InnerContent = view; + MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible; + view.Loaded += (x, y) => + { + VM context = view.DataContext as VM; + dialog.DataContext = context; + + Action onAcceptAction = null; + onAcceptAction = new Action(() => + { + dialog.Close(); + onAccept(context); + context.Accepted -= onAcceptAction; + }); + + Action onCancelAction = null; + onCancelAction = new Action(() => + { + dialog.Close(); + + if (onCancel != null) + { + onCancel(); + } + + context.Canceled -= onCancelAction; + }); + + context.Accepted += onAcceptAction; + context.Canceled += onCancelAction; + + context.OnShow(); + }; + + dialog.ShowDialog(); MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden; - return result; + } + + public void ShowModalDialog<VM>(Action<VM> onAccept) where VM : DialogViewVM + { + ShowModalDialog<VM>(onAccept, null); } public void ShowError(string message) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml index 2a8dd9f28..c11e2e11b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml @@ -1,4 +1,4 @@ -<mahapps:MetroWindow x:Class="Tango.MachineStudio.UI.Windows.DialogWindow" +<Window x:Class="Tango.MachineStudio.UI.Windows.DialogWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" @@ -7,18 +7,22 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows" mc:Ignorable="d" - Title="Machine Studio" Height="450" Width="650" EnableDWMDropShadow="True" ShowCloseButton="False" WindowTransitionsEnabled="False" ShowMaxRestoreButton="False" ShowMinButton="False" TitleCaps="False" BorderThickness="1" WindowStartupLocation="CenterOwner"> + Title="Machine Studio" MinHeight="220" SizeToContent="WidthAndHeight" MinWidth="600" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterOwner" Background="Transparent"> <Grid> - <Border Margin="16"> - <DockPanel LastChildFill="True"> - <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" VerticalAlignment="Top"> - <materialDesign:PackIcon Kind="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=IconKind}" VerticalAlignment="Center" Width="32" Height="32" Foreground="{StaticResource AccentColorBrush}" /> - <TextBlock Margin="10 0 0 0" Foreground="{StaticResource AccentColorBrush}" FontSize="16" Text="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=InnerTitle}"></TextBlock> - </StackPanel> - <ScrollViewer Margin="0 10 0 10" VerticalScrollBarVisibility="Auto" Padding="5"> - <ContentPresenter x:Name="presenter"></ContentPresenter> - </ScrollViewer> - </DockPanel> - </Border> + <Grid> + <Border Background="White" CornerRadius="10" Padding="10" Margin="20"> + <Border.Effect> + <DropShadowEffect ShadowDepth="0" BlurRadius="10"></DropShadowEffect> + </Border.Effect> + + <Grid> + <ContentPresenter x:Name="presenter" Content="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=InnerContent}"></ContentPresenter> + + <Button Command="{Binding CloseCommand}" HorizontalAlignment="Right" VerticalAlignment="Top" Width="20" Height="20" Margin="0 -6 -4 0" Padding="0" Style="{StaticResource MaterialDesignFlatButton}" Foreground="Black"> + <materialDesign:PackIcon Kind="Close" Width="16" Height="16"></materialDesign:PackIcon> + </Button> + </Grid> + </Border> + </Grid> </Grid> -</mahapps:MetroWindow> +</Window> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml.cs index 31dd3d644..d1bc0564b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml.cs @@ -20,51 +20,23 @@ namespace Tango.MachineStudio.UI.Windows /// <summary> /// Interaction logic for DialogWindow.xaml /// </summary> - public partial class DialogWindow : MetroWindow + public partial class DialogWindow : Window { public DialogWindow() { InitializeComponent(); } - - - public String InnerTitle - { - get { return (String)GetValue(InnerTitleProperty); } - set { SetValue(InnerTitleProperty, value); } - } - public static readonly DependencyProperty InnerTitleProperty = - DependencyProperty.Register("InnerTitle", typeof(String), typeof(DialogWindow), new PropertyMetadata(null)); - - - - public PackIconKind IconKind + public FrameworkElement InnerContent { - get { return (PackIconKind)GetValue(IconKindProperty); } - set { SetValue(IconKindProperty, value); } + get { return (FrameworkElement)GetValue(InnerContentProperty); } + set { SetValue(InnerContentProperty, value); } } - public static readonly DependencyProperty IconKindProperty = - DependencyProperty.Register("IconKind", typeof(PackIconKind), typeof(DialogWindow), new PropertyMetadata(PackIconKind.Information)); - + // Using a DependencyProperty as the backing store for InnerContent. This enables animation, styling, binding, etc... + public static readonly DependencyProperty InnerContentProperty = + DependencyProperty.Register("InnerContent", typeof(FrameworkElement), typeof(DialogWindow), new PropertyMetadata(null)); - public DialogWindow(FrameworkElement content) : this() - { - presenter.Content = content; - } - - private void OnOKClicked(object sender, RoutedEventArgs e) - { - DialogResult = true; - Close(); - } - - private void OnCancelClicked(object sender, RoutedEventArgs e) - { - DialogResult = false; - Close(); - } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/MessageBoxWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/MessageBoxWindow.xaml index 4f3b826fe..a89f8eeca 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/MessageBoxWindow.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/MessageBoxWindow.xaml @@ -24,7 +24,7 @@ <Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" Click="OnOKClicked"> ACCEPT </Button> - <Button Visibility="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=HasCancel,Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource MaterialDesignFlatButton}" IsCancel="True" Margin="0 8 8 0" Click="OnCancelClicked"> + <Button Visibility="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=HasCancel,Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource MaterialDesignFlatButton}" IsCancel="False" Margin="0 8 8 0" Click="OnCancelClicked"> CANCEL </Button> </StackPanel> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs index b95a74a3e..336681801 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -11,10 +11,13 @@ using Tango.MachineStudio.Common.Navigation; using GalaSoft.MvvmLight.Ioc; using System.Reflection; using System.Collections; +using Tango.Integration.Services; +using Tango.Core; +using Tango.Logging; namespace Tango.MachineStudio.UI.StudioApplication { - public class DefaultStudioApplicationManager : IStudioApplicationManager + public class DefaultStudioApplicationManager : ExtendedObject, IStudioApplicationManager { private INavigationManager _navigationManager; @@ -23,12 +26,60 @@ namespace Tango.MachineStudio.UI.StudioApplication _navigationManager = navigationManager; } + public bool IsShuttingDown { get; private set; } + + private IExternalBridgeClient _connectedMachine; + + public IExternalBridgeClient ConnectedMachine + { + get { return _connectedMachine; } + set + { + _connectedMachine = value; + RaisePropertyChangedAuto(); + RaisePropertyChanged(nameof(IsMachineConnected)); + + if (_connectedMachine != null) + { + _connectedMachine.StateChanged -= ConnectedMachine_StateChanged; + _connectedMachine.StateChanged += ConnectedMachine_StateChanged; + } + } + } + + private void ConnectedMachine_StateChanged(object sender, Transport.TransportComponentState e) + { + if (e == Transport.TransportComponentState.Disconnected || e == Transport.TransportComponentState.Failed) + { + ConnectedMachine = null; + } + + } + + public bool IsMachineConnected + { + get { return ConnectedMachine != null; } + } + public async void ShutDown() { - _navigationManager.NavigateTo(NavigationView.ShutdownView); + if (IsShuttingDown) return; + + IsShuttingDown = true; await Task.Factory.StartNew(async () => { + try + { + if (ConnectedMachine != null) + { + ConnectedMachine.Disconnect().Wait(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disconnecting from machine."); + } //Do Shutdown Procedures... foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownRequestBlocker>()) @@ -36,14 +87,12 @@ namespace Tango.MachineStudio.UI.StudioApplication var result = await vm.OnShutdownRequest(); if (!result) { - ThreadsHelper.InvokeUI(() => - { - _navigationManager.NavigateTo(NavigationView.MainView); - }); + IsShuttingDown = false; return; } } + _navigationManager.NavigateTo(NavigationView.ShutdownView); Thread.Sleep(3000); Environment.Exit(0); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index be0c1a829..89823e4f7 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -58,6 +58,9 @@ <Reference Include="GalaSoft.MvvmLight.Platform, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL"> <HintPath>..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath> </Reference> + <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL"> <HintPath>..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath> </Reference> @@ -74,9 +77,27 @@ <HintPath>..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll</HintPath> </Reference> <Reference Include="System" /> + <Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> <Reference Include="System.Drawing" /> + <Reference Include="System.Numerics" /> + <Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Linq, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Reactive.Linq.3.1.1\lib\net46\System.Reactive.Linq.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.PlatformServices, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Reactive.PlatformServices.3.1.1\lib\net46\System.Reactive.PlatformServices.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> + </Reference> + <Reference Include="System.Windows" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath> @@ -110,6 +131,8 @@ <Compile Include="SupervisingController\IMainView.cs" /> <Compile Include="ViewModels\LoadingViewVM.cs" /> <Compile Include="ViewModels\LoginViewVM.cs" /> + <Compile Include="ViewModels\MachineConnectionViewVM.cs" /> + <Compile Include="ViewModels\MachineLoginViewVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\ShutdownViewVM.cs" /> @@ -119,6 +142,12 @@ <Compile Include="Views\LoginView.xaml.cs"> <DependentUpon>LoginView.xaml</DependentUpon> </Compile> + <Compile Include="Views\MachineConnectionView.xaml.cs"> + <DependentUpon>MachineConnectionView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\MachineLoginView.xaml.cs"> + <DependentUpon>MachineLoginView.xaml</DependentUpon> + </Compile> <Compile Include="Views\MainView.xaml.cs"> <DependentUpon>MainView.xaml</DependentUpon> </Compile> @@ -159,6 +188,14 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\MachineConnectionView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Views\MachineLoginView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\MainView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -216,10 +253,18 @@ <Project>{38197109-8610-4d3f-92b9-16d48df94d7c}</Project> <Name>Tango.DAL.Remote</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj"> + <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> + <Name>Tango.Integration</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.Logging\Tango.Logging.csproj"> <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> <Name>Tango.Logging</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.Settings\Tango.Settings.csproj"> <Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project> <Name>Tango.Settings</Name> @@ -228,10 +273,22 @@ <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="..\Modules\Tango.MachineStudio.DB\Tango.MachineStudio.DB.csproj"> <Project>{94f7acf8-55e1-4a02-b9bc-a818413fdbbf}</Project> <Name>Tango.MachineStudio.DB</Name> </ProjectReference> + <ProjectReference Include="..\Modules\Tango.MachineStudio.Stubs\Tango.MachineStudio.Stubs.csproj"> + <Project>{22c2aa72-9493-4d0d-b421-8ef9789fb192}</Project> + <Name>Tango.MachineStudio.Stubs</Name> + </ProjectReference> + <ProjectReference Include="..\Modules\Tango.MachineStudio.Synchronization\Tango.MachineStudio.Synchronization.csproj"> + <Project>{12d0c43c-391f-4c74-92ab-82e9a9beeb9b}</Project> + <Name>Tango.MachineStudio.Synchronization</Name> + </ProjectReference> <ProjectReference Include="..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj"> <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> <Name>Tango.MachineStudio.Common</Name> @@ -251,6 +308,51 @@ </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> - <PostBuildEvent>$(TargetDir)linkgen.exe -s "$(TargetPath)" -d "$(TargetDir)Utilities\Machine Studio.lnk"</PostBuildEvent> + <PostBuildEvent>$(TargetDir)linkgen.exe -s "$(TargetPath)" -d "$(TargetDir)Utilities\Machine Studio.lnk" + +RD /S /Q "$(TargetDir)cs\" +RD /S /Q "$(TargetDir)da\" +RD /S /Q "$(TargetDir)de\" +RD /S /Q "$(TargetDir)es\" +RD /S /Q "$(TargetDir)fa\" +RD /S /Q "$(TargetDir)fi\" +RD /S /Q "$(TargetDir)fr\" +RD /S /Q "$(TargetDir)it\" +RD /S /Q "$(TargetDir)ko\" +RD /S /Q "$(TargetDir)mk\" +RD /S /Q "$(TargetDir)nl\" +RD /S /Q "$(TargetDir)pl\" +RD /S /Q "$(TargetDir)pt\" +RD /S /Q "$(TargetDir)ru\" +RD /S /Q "$(TargetDir)sv\" +RD /S /Q "$(TargetDir)tr\" +RD /S /Q "$(TargetDir)zh-CN\" +RD /S /Q "$(TargetDir)af\" +RD /S /Q "$(TargetDir)ar\" +RD /S /Q "$(TargetDir)dn-BD\" +RD /S /Q "$(TargetDir)el\" +RD /S /Q "$(TargetDir)fi-FI\" +RD /S /Q "$(TargetDir)fr-BE\" +RD /S /Q "$(TargetDir)he\" +RD /S /Q "$(TargetDir)hr\" +RD /S /Q "$(TargetDir)hu\" +RD /S /Q "$(TargetDir)id\" +RD /S /Q "$(TargetDir)ja\" +RD /S /Q "$(TargetDir)lv\" +RD /S /Q "$(TargetDir)nb\" +RD /S /Q "$(TargetDir)ro\" +RD /S /Q "$(TargetDir)sk\" +RD /S /Q "$(TargetDir)sl\" +RD /S /Q "$(TargetDir)sr\" +RD /S /Q "$(TargetDir)sr-Latn\" +RD /S /Q "$(TargetDir)uk\" +RD /S /Q "$(TargetDir)uz-Cyrl-UZ\" +RD /S /Q "$(TargetDir)uz-Latn-UZ\" +RD /S /Q "$(TargetDir)vi\" +RD /S /Q "$(TargetDir)zh-Hans\" +RD /S /Q "$(TargetDir)zh-Hant\" +RD /S /Q "$(TargetDir)bg\" +RD /S /Q "$(TargetDir)bn-BD\" +RD /S /Q "$(TargetDir)nb-NO\"</PostBuildEvent> </PropertyGroup> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index f4a7a7502..70912ba98 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -2,6 +2,7 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Ioc; using Microsoft.Practices.ServiceLocation; using System; +using Tango.Integration.Services; using Tango.Logging; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Modules; @@ -48,17 +49,24 @@ namespace Tango.MachineStudio.UI SimpleIoc.Default.Unregister<INavigationManager>(); SimpleIoc.Default.Unregister<IStudioModuleLoader>(); SimpleIoc.Default.Unregister<IStudioApplicationManager>(); + SimpleIoc.Default.Unregister<ExternalBridgeScanner>(); SimpleIoc.Default.Register<INotificationProvider, DefaultNotificationProvider>(); SimpleIoc.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>(); SimpleIoc.Default.Register<INavigationManager, DefaultNavigationManager>(); SimpleIoc.Default.Register<IStudioModuleLoader, DefaultStudioModuleLoader>(); SimpleIoc.Default.Register<IStudioApplicationManager, DefaultStudioApplicationManager>(); + SimpleIoc.Default.Register<ExternalBridgeScanner, ExternalBridgeScanner>(); SimpleIoc.Default.Register<MainViewVM>(); SimpleIoc.Default.Register<LoadingViewVM>(); SimpleIoc.Default.Register<ShutdownViewVM>(); SimpleIoc.Default.Register<LoginViewVM>(); + SimpleIoc.Default.Register<MachineConnectionViewVM>(); + SimpleIoc.Default.Register<MachineLoginViewVM>(); + + LogManager.RegisterLogger(new VSOutputLogger()); + LogManager.RegisterLogger(new FileLogger()); //Register View (Supervising Controller Pattern). if (!ViewModelBase.IsInDesignModeStatic) @@ -99,5 +107,21 @@ namespace Tango.MachineStudio.UI return ServiceLocator.Current.GetInstance<LoginViewVM>(); } } + + public MachineConnectionViewVM MachineConnectionViewVM + { + get + { + return ServiceLocator.Current.GetInstance<MachineConnectionViewVM>(); + } + } + + public MachineLoginViewVM MachineLoginViewVM + { + get + { + return ServiceLocator.Current.GetInstance<MachineLoginViewVM>(); + } + } } }
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs index f50b734f4..f213af0d4 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs @@ -31,7 +31,6 @@ namespace Tango.MachineStudio.UI.ViewModels { StaThreadHelper.StartStaThread(() => { - Thread.Sleep(3000); try { ObservablesEntitiesAdapter.Instance.Initialize(); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs new file mode 100644 index 000000000..b8b888e86 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Integration.Services; +using Tango.MachineStudio.Common.Notifications; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UI.ViewModels +{ + public class MachineConnectionViewVM : DialogViewVM + { + private ExternalBridgeScanner _scanner; + + public ExternalBridgeScanner Scanner + { + get { return _scanner; } + set { _scanner = value; RaisePropertyChangedAuto(); } + } + + private IExternalBridgeClient _selectedMachine; + + public IExternalBridgeClient SelectedMachine + { + get { return _selectedMachine; } + set { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + public RelayCommand ConnectCommand { get; set; } + + public MachineConnectionViewVM(ExternalBridgeScanner scanner) + { + Scanner = scanner; + ConnectCommand = new RelayCommand(Connect,(x) => SelectedMachine != null); + Scanner.Start(); + } + + private void Connect() + { + if (SelectedMachine != null) + { + Accept(); + } + } + + public override void OnShow() + { + base.OnShow(); + + Scanner.AvailableMachines.Clear(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs new file mode 100644 index 000000000..a6ee9ee2a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; + +namespace Tango.MachineStudio.UI.ViewModels +{ + public class MachineLoginViewVM : DialogViewVM + { + public String Password { get; set; } + + public RelayCommand<String> LoginCommand { get; set; } + + public RelayCommand CancelCommand { get; set; } + + public MachineLoginViewVM() + { + LoginCommand = new RelayCommand<string>(Login); + CancelCommand = new RelayCommand(Cancel); + } + + private void Login(string password) + { + Password = password; + Accept(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index 7ef47fabd..92c0afa21 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -7,18 +7,24 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using Tango.Core.Commands; +using Tango.Logging; using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Modules; using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.UI.SupervisingController; +using Tango.MachineStudio.UI.Views; +using Tango.PMR.Stubs; using Tango.SharedUI; +using Tango.Transport.Adapters; namespace Tango.MachineStudio.UI.ViewModels { public class MainViewVM : ViewModel<IMainView> { private IStudioModule _currentModule; + private bool _isDisconnecting; public IStudioModule CurrentModule { @@ -26,6 +32,15 @@ namespace Tango.MachineStudio.UI.ViewModels set { _currentModule = value; RaisePropertyChangedAuto(); } } + private bool _isModuleLoaded; + + public bool IsModuleLoaded + { + get { return _isModuleLoaded; } + set { _isModuleLoaded = value; RaisePropertyChangedAuto(); } + } + + private bool _isMenuOpened; public bool IsMenuOpened @@ -38,6 +53,10 @@ namespace Tango.MachineStudio.UI.ViewModels public RelayCommand HomeCommand { get; set; } + public RelayCommand ConnectCommand { get; set; } + + public RelayCommand DisconnectCommand { get; set; } + private IAuthenticationProvider _authenticationProvider; public IAuthenticationProvider AuthenticationProvider { @@ -61,20 +80,86 @@ namespace Tango.MachineStudio.UI.ViewModels set { _notificationProvider = value; RaisePropertyChangedAuto(); } } + private IStudioApplicationManager _applicationManager; + + public IStudioApplicationManager ApplicationManager + { + get { return _applicationManager; } + set { _applicationManager = value; RaisePropertyChangedAuto(); } + } + + public MainViewVM( IMainView view, IAuthenticationProvider authenticationProvider, IStudioModuleLoader studioModuleLoader, - INotificationProvider notificationProvider) : base(view) + INotificationProvider notificationProvider, + IStudioApplicationManager applicationManager) : base(view) { AuthenticationProvider = authenticationProvider; StudioModuleLoader = studioModuleLoader; NotificationProvider = notificationProvider; + ApplicationManager = applicationManager; StartModuleCommand = new RelayCommand<IStudioModule>(StartModule); HomeCommand = new RelayCommand(Home); + ConnectCommand = new RelayCommand(ConnectToMachine); + DisconnectCommand = new RelayCommand(DisconnectFromMachine,(x) => ApplicationManager.IsMachineConnected && !_isDisconnecting); + } + + private async void DisconnectFromMachine() + { + using (_notificationProvider.PushTaskItem("Disconnecting from machine...")) + { + _isDisconnecting = true; + InvalidateRelayCommands(); + await ApplicationManager.ConnectedMachine.Disconnect(); + ApplicationManager.ConnectedMachine = null; + _isDisconnecting = false; + InvalidateRelayCommands(); + } + } + + private void ConnectToMachine() + { + _notificationProvider.ShowModalDialog<MachineConnectionViewVM>((x) => + { + if (x.SelectedMachine != null) + { + _notificationProvider.ShowModalDialog<MachineLoginViewVM>(async (login) => + { + using (NotificationProvider.PushTaskItem("Connecting to machine " + x.SelectedMachine.SerialNumber + "...")) + { + try + { + await x.SelectedMachine.Connect(); + var authenticated = await x.SelectedMachine.Authenticate(login.Password); + if (!authenticated) + { + _notificationProvider.ShowError("It seems like you are not authorized to access the selected machine."); + } + else + { + ApplicationManager.ConnectedMachine = x.SelectedMachine; + } + } + catch (Exception ex) + { + LogManager.Log(ex); + _notificationProvider.ShowError(ex.Message); + } + + InvalidateRelayCommands(); + } + }); + + InvalidateRelayCommands(); + } + + InvalidateRelayCommands(); + }); } private void Home() @@ -85,7 +170,16 @@ namespace Tango.MachineStudio.UI.ViewModels private void StartModule(IStudioModule module) { IsMenuOpened = false; - CurrentModule = module; + + if (module != null) + { + CurrentModule = module; + IsModuleLoaded = true; + } + else + { + IsModuleLoaded = false; + } } protected override void OnViewAttached() diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml new file mode 100644 index 000000000..32108c652 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml @@ -0,0 +1,85 @@ +<UserControl x:Class="Tango.MachineStudio.UI.Views.MachineConnectionView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" + mc:Ignorable="d" + d:DesignHeight="300" d:DesignWidth="300" Width="600" Height="400" Background="White" DataContext="{Binding MachineConnectionViewVM, Source={StaticResource Locator}}"> + + <UserControl.Resources> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></converters:BooleanToVisibilityConverter> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"></converters:BooleanToVisibilityInverseConverter> + <converters:BooleanInverseConverter x:Key="BooleanInverseConverter"></converters:BooleanInverseConverter> + </UserControl.Resources> + + <Grid> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="80"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + + <Grid> + <StackPanel Orientation="Horizontal" Margin="10"> + <Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image> + <TextBlock Text="Machine Connection" VerticalAlignment="Center" Margin="10 0 0 0" FontSize="20"></TextBlock> + </StackPanel> + </Grid> + + <Grid Grid.Row="1" Margin="10 0 10 10"> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="50"/> + </Grid.RowDefinitions> + + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="30"/> + <RowDefinition Height="223*"/> + </Grid.RowDefinitions> + + <Grid> + <TextBlock VerticalAlignment="Center" Margin="0 0 0 0" Text="Scanning for machine on your local network..."></TextBlock> + + <!--<Button Command="{Binding ScanCommand}" HorizontalAlignment="Right" Width="40" Padding="0" Style="{StaticResource MaterialDesignFlatButton}" Foreground="Black" ToolTip="Scan"> + <materialDesign:PackIcon Kind="Refresh" Width="24" Height="24"></materialDesign:PackIcon> + </Button>--> + </Grid> + + <Grid Grid.Row="1"> + <ListBox ItemsSource="{Binding Scanner.AvailableMachines}" SelectedItem="{Binding SelectedMachine}" Margin="0 0 0 7" BorderThickness="1" BorderBrush="Gainsboro"> + <ListBox.ItemTemplate> + <DataTemplate> + <StackPanel Orientation="Horizontal"> + <Image Source="/Images/machine-trans.png" Width="38" Height="38" RenderOptions.BitmapScalingMode="Fant"></Image> + <StackPanel Margin="10 0 0 0"> + <TextBlock FontSize="11"> + <Run FontWeight="Bold">S/N:</Run> <Run Text="{Binding SerialNumber,Mode=OneWay}"></Run> + </TextBlock> + <TextBlock FontSize="11"> + <Run FontWeight="Bold">IP Address:</Run> <Run Text="{Binding IPAddress,Mode=OneWay}"></Run> + </TextBlock> + <TextBlock FontSize="11"> + <Run FontWeight="Bold">Organization:</Run> <Run Text="{Binding Organization,Mode=OneWay}"></Run> + </TextBlock> + </StackPanel> + </StackPanel> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> + + <mahapps:MetroProgressBar VerticalAlignment="Bottom" Height="1" IsIndeterminate="True"></mahapps:MetroProgressBar> + </Grid> + </Grid> + + <Grid Grid.Row="1"> + <Button HorizontalAlignment="Right" Width="140" Command="{Binding ConnectCommand}">CONNECT</Button> + </Grid> + </Grid> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml.cs new file mode 100644 index 000000000..6c8e305e9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml.cs @@ -0,0 +1,28 @@ +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.UI.Views +{ + /// <summary> + /// Interaction logic for MachineConnectionView.xaml + /// </summary> + public partial class MachineConnectionView : UserControl + { + public MachineConnectionView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml new file mode 100644 index 000000000..04f787c41 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml @@ -0,0 +1,39 @@ +<UserControl x:Class="Tango.MachineStudio.UI.Views.MachineLoginView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" + mc:Ignorable="d" + d:DesignHeight="200" d:DesignWidth="550" Background="White" DataContext="{Binding MachineLoginViewVM, Source={StaticResource Locator}}"> + <Grid> + <DockPanel LastChildFill="True"> + <StackPanel Margin="10" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" DockPanel.Dock="Bottom"> + <Button Command="{Binding LoginCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Password}" Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0"> + LOGIN + </Button> + <Button Command="{Binding CancelCommand}" Style="{StaticResource MaterialDesignFlatButton}" Margin="0 8 0 0"> + CANCEL + </Button> + </StackPanel> + <Grid Margin="10"> + <StackPanel> + <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> + <Grid> + <Image Source="../Images/machine-trans.png" Width="42" RenderOptions.BitmapScalingMode="Fant"></Image> + <materialDesign:PackIcon Kind="Lock" VerticalAlignment="Bottom" Width="24" Height="24" HorizontalAlignment="Right" Foreground="{StaticResource AccentColorBrush}" /> + </Grid> + <TextBlock Padding="0 10 0 0" TextWrapping="Wrap" Margin="10 0 0 0" VerticalAlignment="Top" FontSize="18" Text="Machine Login" Width="400"></TextBlock> + </StackPanel> + + <StackPanel Margin="60 0 0 0"> + <TextBlock Margin="0 15 0 0">Enter machine password</TextBlock> + <PasswordBox x:Name="txtPass" Margin="0 0 0 0" HorizontalAlignment="Left" PasswordChanged="txtPass_PasswordChanged" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="*********" Width="300" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" /> + </StackPanel> + </StackPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml.cs new file mode 100644 index 000000000..c5161b477 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml.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 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.UI.Views +{ + /// <summary> + /// Interaction logic for MachineLoginView.xaml + /// </summary> + public partial class MachineLoginView : UserControl + { + public MachineLoginView() + { + InitializeComponent(); + + this.Loaded += MachineLoginView_Loaded; + } + + private void MachineLoginView_Loaded(object sender, RoutedEventArgs e) + { + txtPass.Focusable = true; + txtPass.Focus(); + txtPass.Password = String.Empty; + Password = String.Empty; + } + + public String Password + { + get { return (String)GetValue(PasswordProperty); } + set { SetValue(PasswordProperty, value); } + } + public static readonly DependencyProperty PasswordProperty = + DependencyProperty.Register("Password", typeof(String), typeof(MachineLoginView), new PropertyMetadata(null)); + + private void txtPass_PasswordChanged(object sender, RoutedEventArgs e) + { + Password = txtPass.Password; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index cb7378666..14858c049 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -26,7 +26,7 @@ </Style.Triggers> </Style> </Grid.Style> - + <materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}"> <materialDesign:DrawerHost.LeftDrawerContent> <StackPanel MinWidth="300"> @@ -84,17 +84,48 @@ x:Name="MenuToggleButton"/> <materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False"> <StackPanel> - <Button Content="Home"/> - <Button Content="Nice Popup"/> - <Button Content="Can't Touch This" IsEnabled="False" /> + <Button Content="Machine Connection" Command="{Binding ConnectCommand}" /> + <Button Content="Disconnect Machine" Command="{Binding DisconnectCommand}" /> <Separator/> - <Button Content="Goodbye"/> + <Button Content="Exit" /> </StackPanel> </materialDesign:PopupBox> - <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Height="60" HorizontalAlignment="Center"> - <Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image> - <TextBlock Text="Machine Studio" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36"/> - </StackPanel> + <Grid> + <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Height="60" HorizontalAlignment="Center"> + <Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image> + <TextBlock Text="Machine Studio" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36"/> + </StackPanel> + + <Grid HorizontalAlignment="Right"> + <StackPanel Orientation="Horizontal"> + <Button Margin="10 0 0 0" Style="{StaticResource MaterialDesignFlatButton}" FontSize="12" ToolTip="Connect to machine on the local network" BorderThickness="0" Command="{Binding ConnectCommand}"> + <!--<Button.Background> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Color="White" Offset="0.4" /> + <GradientStop Color="#75E0FA" Offset="1"/> + </LinearGradientBrush> + </Button.Background>--> + <StackPanel Orientation="Horizontal"> + <TextBlock Text="Machine Connection" VerticalAlignment="Center" Foreground="White"></TextBlock> + <materialDesign:PackIcon Margin="10 0 0 0" Width="16" Height="16"> + <materialDesign:PackIcon.Style> + <Style TargetType="materialDesign:PackIcon"> + <Setter Property="Foreground" Value="#FF6767"></Setter> + <Setter Property="Kind" Value="LanDisconnect"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding ApplicationManager.IsMachineConnected,Mode=OneWay}" Value="True"> + <Setter Property="Foreground" Value="#03FF8E"></Setter> + <Setter Property="Kind" Value="LanConnect"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </materialDesign:PackIcon.Style> + </materialDesign:PackIcon> + </StackPanel> + </Button> + </StackPanel> + </Grid> + </Grid> </DockPanel> </materialDesign:ColorZone> @@ -166,22 +197,22 @@ <Setter Property="Opacity" Value="0"></Setter> <Style.Triggers> - <DataTrigger Binding="{Binding CurrentModule}" Value="{x:Null}"> + <DataTrigger Binding="{Binding IsModuleLoaded}" Value="False"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> - <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="0" Duration="00:00:0.2"></DoubleAnimation> - <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" Duration="00:00:0.2"></DoubleAnimation> - <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:0.2"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="0" Duration="00:00:0.5"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" Duration="00:00:0.5"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:0.5"></DoubleAnimation> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> <DataTrigger.ExitActions> <BeginStoryboard> <Storyboard> - <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1" Duration="00:00:0.2"></DoubleAnimation> - <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1" Duration="00:00:0.2"></DoubleAnimation> - <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:0.2"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1" Duration="00:00:0.5"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1" Duration="00:00:0.5"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:0.5"></DoubleAnimation> </Storyboard> </BeginStoryboard> </DataTrigger.ExitActions> @@ -189,7 +220,7 @@ </Style.Triggers> </Style> </Grid.Style> - <ContentPresenter Content="{Binding CurrentModule.MainView}"></ContentPresenter> + <ContentPresenter Content="{Binding CurrentModule.MainView}"/> </Grid> </Grid> @@ -204,16 +235,16 @@ <Style.Triggers> <DataTrigger Binding="{Binding NotificationProvider.HasTaskItems}" Value="True"> <DataTrigger.EnterActions> - <BeginStoryboard> + <BeginStoryboard HandoffBehavior="Compose"> <Storyboard> - <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1" Duration="00:00:0.2"></DoubleAnimation> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" FillBehavior="HoldEnd" To="1" Duration="00:00:0.2"></DoubleAnimation> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> <DataTrigger.ExitActions> - <BeginStoryboard> + <BeginStoryboard HandoffBehavior="Compose"> <Storyboard> - <DoubleAnimation BeginTime="00:00:01" Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" From="1" Duration="00:00:0.5"></DoubleAnimation> + <DoubleAnimation BeginTime="00:00:02" FillBehavior="HoldEnd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" From="1" Duration="00:00:0.5"></DoubleAnimation> </Storyboard> </BeginStoryboard> </DataTrigger.ExitActions> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs index 520b69741..f52393e1c 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Practices.ServiceLocation; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,9 +10,12 @@ 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 Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.UI.Notifications; using Tango.MachineStudio.UI.SupervisingController; using Tango.SharedUI; using Tango.SharedUI.Controls; diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config index 3a7265a72..ae67b1d1c 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config @@ -4,10 +4,17 @@ <package id="Dragablz" version="0.0.3.197" targetFramework="net46" /> <package id="EntityFramework" version="6.0.0" targetFramework="net46" /> <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" /> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" /> <package id="MahApps.Metro" version="1.5.0" targetFramework="net46" /> <package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" /> <package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" /> <package id="MvvmLight" version="5.3.0.0" targetFramework="net46" /> <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net46" /> <package id="SimpleValidator" version="0.6.1.0" targetFramework="net46" /> + <package id="System.Reactive" version="3.1.1" targetFramework="net46" /> + <package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" /> + <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net46" /> + <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net46" /> + <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net46" /> + <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net46" /> </packages>
\ No newline at end of file |
