aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
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.UI
parentb0823127f152fe97a6e8fce29e427c7f3db9cf5a (diff)
parent1a573aaa346ec4b8bd58a0e35ab9df571a09b855 (diff)
downloadTango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.tar.gz
Tango-6c208c90bc45aff4a7fa214356a42fe7757c5e6f.zip
MERGE
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml5
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs60
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs24
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/White-Abstract.pngbin0 -> 375774 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/exception.pngbin0 -> 1528 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-tcp.pngbin10187 -> 3618 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-usb.pngbin9573 -> 3623 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml48
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs56
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs168
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DialogWindow.xaml.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml44
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml.cs99
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs112
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/SupervisingController/IMainView.cs11
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj36
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs10
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs19
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs25
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs26
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs20
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs98
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ShutdownViewVM.cs3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml48
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml199
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs60
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs15
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml61
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs48
33 files changed, 1102 insertions, 210 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml
index 8e5876e79..fe50851a0 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml
@@ -11,7 +11,10 @@
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/Tango.MachineStudio.Common;component/Resources/MaterialDesign.xaml"></ResourceDictionary>
- <!-- Include the Dragablz Material Design style -->
+ <!--RealTimeGraphEx-->
+ <ResourceDictionary Source="pack://application:,,,/RealTimeGraphEx;component/Resources/Resources.xaml"></ResourceDictionary>
+
+ <!-- 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/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
index ca553de1e..c15a87980 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
@@ -2,10 +2,14 @@
using System.Collections.Generic;
using System.Configuration;
using System.Data;
+using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
-using Tango.DAL.Observables;
+using Tango.Integration.Observables;
+using Tango.Logging;
+using Tango.MachineStudio.UI.Windows;
+using Tango.Settings;
namespace Tango.MachineStudio.UI
{
@@ -14,9 +18,63 @@ namespace Tango.MachineStudio.UI
/// </summary>
public partial class App : Application
{
+ private WpfGlobalExceptionTrapper exceptionTrapper;
+
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
+
+ LogManager.Categories.Clear();
+
+ if (SettingsManager.Default.MachineStudio.LoggingCategories.Count == 0)
+ {
+ SettingsManager.Default.MachineStudio.LoggingCategories.Add(LogCategory.Critical);
+ SettingsManager.Default.MachineStudio.LoggingCategories.Add(LogCategory.Error);
+ SettingsManager.Default.MachineStudio.LoggingCategories.Add(LogCategory.General);
+ SettingsManager.Default.MachineStudio.LoggingCategories.Add(LogCategory.Warning);
+ }
+
+ LogManager.Categories.AddRange(SettingsManager.Default.MachineStudio.LoggingCategories);
+
+ LogManager.RegisterLogger(new VSOutputLogger());
+ LogManager.RegisterLogger(new FileLogger());
+
+ exceptionTrapper = new WpfGlobalExceptionTrapper();
+ exceptionTrapper.Initialize(this);
+ exceptionTrapper.ApplicationCrashed += ExceptionTrapper_ApplicationCrashed;
}
+
+ #region Global Exception Trapping
+
+ /// <summary>
+ /// Handles the ApplicationCrashed event of the ExceptionTrapper.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="ApplicationCrashedEventArgs"/> instance containing the event data.</param>
+ private void ExceptionTrapper_ApplicationCrashed(object sender, ApplicationCrashedEventArgs e)
+ {
+ ExceptionWindow exWin = new ExceptionWindow(e.Exception);
+ exWin.ShowDialog();
+
+ switch (exWin.Resolution)
+ {
+ case ExceptionResolutions.Ignore:
+ e.TryRecover = true;
+ break;
+ case ExceptionResolutions.Restart:
+ e.TryRecover = false;
+ LogManager.Log("User selection was to restart the application. Restarting...");
+ Process.Start(Application.ResourceAssembly.Location);
+ Environment.Exit(0);
+ break;
+ case ExceptionResolutions.Shutdown:
+ e.TryRecover = false;
+ LogManager.Log("User selection was to shutdown the application. Restarting...");
+ Environment.Exit(0);
+ break;
+ }
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
index a30cf0f92..82aba268d 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
@@ -5,15 +5,22 @@ using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
-using Tango.DAL.Observables;
+using Tango.Integration.Observables;
using Tango.MachineStudio.Common.Authentication;
namespace Tango.MachineStudio.UI.Authentication
{
+ /// <summary>
+ /// Represents the default Machine Studio <see cref="IAuthenticationProvider">Authentication provider</see>
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.MachineStudio.Common.Authentication.IAuthenticationProvider" />
public class DefaultAuthenticationProvider : ExtendedObject, IAuthenticationProvider
{
private User _currentUser;
-
+ /// <summary>
+ /// Gets the current logged-in user.
+ /// </summary>
public User CurrentUser
{
get { return _currentUser; }
@@ -25,8 +32,18 @@ namespace Tango.MachineStudio.UI.Authentication
}
}
+ /// <summary>
+ /// Occurs when the current logged-in user has changed.
+ /// </summary>
public event EventHandler<User> CurrentUserChanged;
+ /// <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>
+ /// <exception cref="AuthenticationException">Login failed for user " + email</exception>
public User Login(string email, string password)
{
User user = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email.ToLower() && x.Password == password);
@@ -40,6 +57,9 @@ namespace Tango.MachineStudio.UI.Authentication
return user;
}
+ /// <summary>
+ /// Logs-out the current logged-in user.
+ /// </summary>
public void Logout()
{
CurrentUser = null;
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/White-Abstract.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/White-Abstract.png
new file mode 100644
index 000000000..31bd18c35
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/White-Abstract.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/exception.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/exception.png
new file mode 100644
index 000000000..9a4abb703
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/exception.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-tcp.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-tcp.png
index 2d8c684b7..192cbcaa7 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-tcp.png
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-tcp.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-usb.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-usb.png
index 62fab6225..414bbab04 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-usb.png
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-usb.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
index f07e7f476..e0f0b1f4f 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
@@ -8,27 +8,37 @@
xmlns:views="clr-namespace:Tango.MachineStudio.UI.Views"
xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
mc:Ignorable="d"
- Title="Tango" Height="720" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949">
+ Title="Tango" Height="800" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}">
+
<Grid>
- <sharedControls:MultiTransitionControl AlwaysFade="True" TransitionType="Zoom" x:Name="TransitionControl" x:FieldModifier="public">
- <sharedControls:MultiTransitionControl.Controls>
- <ContentControl Tag="LoadingView">
- <views:LoadingView></views:LoadingView>
- </ContentControl>
- <ContentControl Tag="LoginView">
- <views:LoginView></views:LoginView>
- </ContentControl>
- <ContentControl Tag="MainView">
- <views:MainView></views:MainView>
- </ContentControl>
- <ContentControl Tag="ShutdownView">
- <views:ShutdownView></views:ShutdownView>
- </ContentControl>
- </sharedControls:MultiTransitionControl.Controls>
- </sharedControls:MultiTransitionControl>
+ <Grid.Background>
+ <ImageBrush ImageSource="/Images/White-Abstract.png" Stretch="Fill"></ImageBrush>
+ </Grid.Background>
+ <Viewbox Stretch="Fill" UseLayoutRounding="True" SnapsToDevicePixels="True">
+ <Grid Width="1920" Height="1145">
+ <Grid>
+ <sharedControls:MultiTransitionControl AlwaysFade="True" TransitionType="Zoom" x:Name="TransitionControl" x:FieldModifier="public">
+ <sharedControls:MultiTransitionControl.Controls>
+ <ContentControl Tag="LoadingView">
+ <views:LoadingView></views:LoadingView>
+ </ContentControl>
+ <ContentControl Tag="LoginView">
+ <views:LoginView></views:LoginView>
+ </ContentControl>
+ <ContentControl Tag="MainView">
+ <views:MainView></views:MainView>
+ </ContentControl>
+ <ContentControl Tag="ShutdownView">
+ <views:ShutdownView></views:ShutdownView>
+ </ContentControl>
+ </sharedControls:MultiTransitionControl.Controls>
+ </sharedControls:MultiTransitionControl>
- <Grid Background="Black" Opacity="0.7" x:Name="shadowGrid" Visibility="Hidden">
+ <Grid Background="Black" Opacity="0.7" x:Name="shadowGrid" Visibility="Hidden">
- </Grid>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Viewbox>
</Grid>
</mahapps:MetroWindow>
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 473e66d38..5951137e3 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs
@@ -1,4 +1,5 @@
-using System;
+using GalaSoft.MvvmLight.Ioc;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
@@ -7,6 +8,8 @@ using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
+using Tango.Integration.Observables;
+using Tango.Logging;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Authentication;
using Tango.MachineStudio.Common.Modules;
@@ -16,11 +19,21 @@ using Tango.MachineStudio.Stubs;
namespace Tango.MachineStudio.UI.Modules
{
+ /// <summary>
+ /// Represents the Machine Studio default <see cref="IStudioModuleLoader">module loader</see>.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.MachineStudio.Common.Modules.IStudioModuleLoader" />
public class DefaultStudioModuleLoader : ExtendedObject, IStudioModuleLoader
{
private IAuthenticationProvider _authenticationProvider;
private bool _loaded;
+ public event EventHandler ModulesLoaded;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultStudioModuleLoader"/> class.
+ /// </summary>
+ /// <param name="authenticationProvider">The authentication provider.</param>
public DefaultStudioModuleLoader(IAuthenticationProvider authenticationProvider)
{
_authenticationProvider = authenticationProvider;
@@ -29,12 +42,20 @@ namespace Tango.MachineStudio.UI.Modules
_authenticationProvider.CurrentUserChanged += _authenticationProvider_CurrentUserChanged;
}
- private void _authenticationProvider_CurrentUserChanged(object sender, DAL.Observables.User e)
+ /// <summary>
+ /// Handles the authentication provider user changed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
+ private void _authenticationProvider_CurrentUserChanged(object sender, User e)
{
LoadModules();
}
private ObservableCollection<IStudioModule> _allModules;
+ /// <summary>
+ /// Gets all loaded modules.
+ /// </summary>
public ObservableCollection<IStudioModule> AllModules
{
get { return _allModules; }
@@ -42,12 +63,18 @@ namespace Tango.MachineStudio.UI.Modules
}
private ObservableCollection<IStudioModule> _userModules;
+ /// <summary>
+ /// Gets all the user permitted modules.
+ /// </summary>
public ObservableCollection<IStudioModule> UserModules
{
get { return _userModules; }
private set { _userModules = value; RaisePropertyChangedAuto(); }
}
+ /// <summary>
+ /// Loads all available Machine Studio modules.
+ /// </summary>
public void LoadModules()
{
if (!_loaded)
@@ -70,12 +97,19 @@ namespace Tango.MachineStudio.UI.Modules
if (moduleAssembly != null)
{
- foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IStudioModule).IsAssignableFrom(x)))
+ foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IStudioModule).IsAssignableFrom(x) && !x.IsAbstract))
{
if (!AllModules.ToList().Exists(x => x.GetType() == moduleType))
{
- var module = Activator.CreateInstance(moduleType) as IStudioModule;
- AllModules.Add(module);
+ try
+ {
+ var module = Activator.CreateInstance(moduleType) as IStudioModule;
+ AllModules.Add(module);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Could not load module " + moduleType.Name);
+ }
}
}
}
@@ -92,6 +126,18 @@ namespace Tango.MachineStudio.UI.Modules
{
UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection();
}
+
+ ModulesLoaded?.Invoke(this, new EventArgs());
+ }
+
+ /// <summary>
+ /// Gets the studio module of type T if loaded.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public T GetStudioModule<T>() where T : IStudioModule
+ {
+ return UserModules.OfType<T>().FirstOrDefault();
}
}
}
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 15f2fe422..56abbd702 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs
@@ -3,12 +3,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Navigation;
namespace Tango.MachineStudio.UI.Navigation
{
+ /// <summary>
+ /// Represents the Machine Studio default <see cref="INavigationManager">Navigation Manager</see>.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.Navigation.INavigationManager" />
public class DefaultNavigationManager : INavigationManager
{
+ /// <summary>
+ /// Navigates to the specified view.
+ /// </summary>
+ /// <param name="view">The view.</param>
public void NavigateTo(NavigationView view)
{
MainWindow.Instance.Dispatcher.Invoke(() =>
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 d4d053eaf..1ea22c587 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs
@@ -13,31 +13,68 @@ using System.Collections.ObjectModel;
namespace Tango.MachineStudio.UI.Notifications
{
+ /// <summary>
+ /// Represents the default Machine Studio <see cref="INotificationProvider">Notification Provider</see>.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.MachineStudio.Common.Notifications.INotificationProvider" />
public class DefaultNotificationProvider : ExtendedObject, INotificationProvider
{
+ /// <summary>
+ /// The view types
+ /// </summary>
private static List<Type> viewTypes;
+ /// <summary>
+ /// Gets the collection of active task items.
+ /// </summary>
public ObservableCollection<TaskItem> TaskItems { get; private set; }
+ /// <summary>
+ /// Gets the collection of active bar items.
+ /// </summary>
+ public ObservableCollection<BarItem> BarItems { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether there are any queued task items.
+ /// </summary>
public bool HasTaskItems
{
get { return TaskItems.Count > 0; }
}
+ /// <summary>
+ /// The current task item
+ /// </summary>
private TaskItem _currentTaskItem;
+ /// <summary>
+ /// Gets the current displayed task item.
+ /// </summary>
public TaskItem CurrentTaskItem
{
get { return _currentTaskItem; }
set { _currentTaskItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasTaskItems)); }
}
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultNotificationProvider"/> class.
+ /// </summary>
public DefaultNotificationProvider()
{
TaskItems = new ObservableCollection<TaskItem>();
+ BarItems = new ObservableCollection<BarItem>();
}
- public 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>
+ public bool? ShowMessageBox(PackIconKind icon, Brush iconColor, string message, bool hasCancel)
{
MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
@@ -55,6 +92,13 @@ namespace Tango.MachineStudio.UI.Notifications
return result;
}
+ /// <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>
public void ShowModalDialog<View, VM>(Action<VM> onAccept, Action onCancel) where View : FrameworkElement where VM : DialogViewVM
{
var view = Activator.CreateInstance<View>();
@@ -68,7 +112,7 @@ namespace Tango.MachineStudio.UI.Notifications
dialog.DataContext = context;
Action onAcceptAction = null;
- onAcceptAction = new Action(() =>
+ onAcceptAction = new Action(() =>
{
dialog.Close();
onAccept(context);
@@ -76,7 +120,7 @@ namespace Tango.MachineStudio.UI.Notifications
});
Action onCancelAction = null;
- onCancelAction = new Action(() =>
+ onCancelAction = new Action(() =>
{
dialog.Close();
@@ -97,6 +141,13 @@ namespace Tango.MachineStudio.UI.Notifications
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
+ /// <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>
+ /// <exception cref="NullReferenceException">Could not locate view " + viewName</exception>
public void ShowModalDialog<VM>(Action<VM> onAccept, Action onCancel) where VM : DialogViewVM
{
String viewName = typeof(VM).Name.Replace("VM", "");
@@ -121,6 +172,10 @@ namespace Tango.MachineStudio.UI.Notifications
view.Loaded += (x, y) =>
{
VM context = view.DataContext as VM;
+ if (context == null)
+ {
+ context = Activator.CreateInstance<VM>();
+ }
dialog.DataContext = context;
Action onAcceptAction = null;
@@ -149,42 +204,73 @@ namespace Tango.MachineStudio.UI.Notifications
context.OnShow();
};
-
+
dialog.ShowDialog();
MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
}
+ /// <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>
public void ShowModalDialog<VM>(Action<VM> onAccept) where VM : DialogViewVM
{
ShowModalDialog<VM>(onAccept, null);
}
+ /// <summary>
+ /// Shows an error message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
public void ShowError(string message)
{
- ShowDialog(PackIconKind.Exclamation, Brushes.Red, message, false);
+ ShowMessageBox(PackIconKind.Exclamation, Brushes.Red, message, false);
}
+ /// <summary>
+ /// Shows an information message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
public void ShowInfo(string message)
{
- ShowDialog(PackIconKind.Information, Brushes.Black, message, false);
+ ShowMessageBox(PackIconKind.Information, Brushes.Black, message, false);
}
+ /// <summary>
+ /// Shows a question message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
public bool ShowQuestion(string message)
{
- return ShowDialog(PackIconKind.CommentQuestionOutline, Brushes.Black, message, true).Value;
+ return ShowMessageBox(PackIconKind.CommentQuestionOutline, Brushes.Black, message, true).Value;
}
- public void ShowWarnning(string message)
+ /// <summary>
+ /// Shows warning message box.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ public void ShowWarning(string message)
{
- ShowDialog(PackIconKind.Exclamation, Brushes.DarkOrange, message, false);
+ ShowMessageBox(PackIconKind.Exclamation, Brushes.DarkOrange, message, false);
}
+ /// <summary>
+ /// Pushes the specified task item to the queue.
+ /// </summary>
+ /// <param name="taskItem">The task item.</param>
public void PushTaskItem(TaskItem taskItem)
{
TaskItems.Add(taskItem);
CurrentTaskItem = taskItem;
}
+ /// <summary>
+ /// Create and push a new task item from the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
public TaskItem PushTaskItem(string message)
{
TaskItem item = new TaskItem(this);
@@ -193,6 +279,10 @@ namespace Tango.MachineStudio.UI.Notifications
return item;
}
+ /// <summary>
+ /// Removed the specified task item from the queue.
+ /// </summary>
+ /// <param name="taskItem">The task item.</param>
public void PopTaskItem(TaskItem taskItem)
{
TaskItems.Remove(taskItem);
@@ -204,5 +294,65 @@ namespace Tango.MachineStudio.UI.Notifications
RaisePropertyChanged(nameof(HasTaskItems));
}
+
+ /// <summary>
+ /// Pushes the specified bar item.
+ /// </summary>
+ /// <param name="barItem">The bar item.</param>
+ /// <returns></returns>
+ public BarItem PushBarItem(BarItem barItem)
+ {
+ BarItems.Add(barItem);
+ return barItem;
+ }
+
+ /// <summary>
+ /// Creates and push a new bar item from the specified framework element.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <returns></returns>
+ public BarItem PushBarItem(FrameworkElement element)
+ {
+ BarItem item = new BarItem(this);
+ item.Element = element;
+ PushBarItem(item);
+ return item;
+ }
+
+ /// <summary>
+ /// Removed the specified bar item.
+ /// </summary>
+ /// <param name="barItem">The bar item.</param>
+ public void PopBarItem(BarItem barItem)
+ {
+ BarItems.Remove(barItem);
+ }
+
+ /// <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>
+ public string ShowTextInput(string message, string hint, string defaultResponse = null)
+ {
+ MainWindow.Instance.shadowGrid.Visibility = Visibility.Visible;
+
+ TextInputBoxWindow dlg = new TextInputBoxWindow()
+ {
+ Owner = Application.Current.MainWindow,
+ Message = message,
+ IconKind = PackIconKind.Pencil,
+ IconColor = Brushes.DimGray,
+ Hint = hint,
+ Response = defaultResponse
+ };
+
+ var result = dlg.ShowDialog();
+
+ MainWindow.Instance.shadowGrid.Visibility = Visibility.Hidden;
+ return (result.Value ? dlg.Response : null);
+ }
}
}
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 d1bc0564b..8ed1a4946 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
@@ -36,7 +36,5 @@ namespace Tango.MachineStudio.UI.Windows
// 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));
-
-
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml
new file mode 100644
index 000000000..d2aad7cee
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml
@@ -0,0 +1,44 @@
+<Window x:Class="Tango.MachineStudio.UI.Notifications.TextInputBoxWindow"
+ 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"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Notifications"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ mc:Ignorable="d"
+ Title="Machine Studio" MinHeight="220" MaxHeight="600" SizeToContent="Height" Width="570" Opacity="0" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterOwner" Background="Transparent">
+
+ <Window.Resources>
+ <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
+ </Window.Resources>
+
+ <Grid>
+ <Border Background="White" CornerRadius="10" Padding="10" Margin="20">
+ <Border.Effect>
+ <DropShadowEffect ShadowDepth="0" BlurRadius="10"></DropShadowEffect>
+ </Border.Effect>
+ <DockPanel LastChildFill="True">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" DockPanel.Dock="Bottom">
+ <Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True" Margin="0 8 8 0" Click="OnOKClicked">
+ ACCEPT
+ </Button>
+ <Button Style="{StaticResource MaterialDesignFlatButton}" IsCancel="False" Margin="0 8 8 0" Click="OnCancelClicked">
+ CANCEL
+ </Button>
+ </StackPanel>
+ <Grid>
+ <StackPanel VerticalAlignment="Top" Margin="0 30 0 0">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=IconKind}" VerticalAlignment="Top" Width="50" Height="50" Foreground="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=IconColor}" />
+ <TextBlock Padding="0 10 0 0" TextWrapping="Wrap" Margin="10 0 0 0" VerticalAlignment="Top" FontSize="14" Text="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Message}" Width="400"></TextBlock>
+ </StackPanel>
+
+ <TextBox x:Name="txtText" Margin="60 0 20 0" materialDesign:HintAssist.Hint="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Hint}" Text="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Response,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </Grid>
+ </DockPanel>
+ </Border>
+ </Grid>
+</Window>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml.cs
new file mode 100644
index 000000000..d774c14eb
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/TextInputBoxWindow.xaml.cs
@@ -0,0 +1,99 @@
+using MahApps.Metro.Controls;
+using MaterialDesignThemes.Wpf;
+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.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace Tango.MachineStudio.UI.Notifications
+{
+ /// <summary>
+ /// Interaction logic for TextInputBoxWindow.xaml
+ /// </summary>
+ public partial class TextInputBoxWindow : Window
+ {
+ public TextInputBoxWindow()
+ {
+ InitializeComponent();
+ this.Loaded += TextInputBoxWindow_Loaded;
+ }
+
+ private void TextInputBoxWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ DoubleAnimation ani = new DoubleAnimation();
+ ani.To = 1;
+ ani.Duration = TimeSpan.FromSeconds(0.5);
+ this.BeginAnimation(Window.OpacityProperty, ani);
+
+ txtText.Focus();
+ }
+
+
+
+ public String Hint
+ {
+ get { return (String)GetValue(HintProperty); }
+ set { SetValue(HintProperty, value); }
+ }
+ public static readonly DependencyProperty HintProperty =
+ DependencyProperty.Register("Hint", typeof(String), typeof(TextInputBoxWindow), new PropertyMetadata(null));
+
+
+
+ public String Response
+ {
+ get { return (String)GetValue(ResponseProperty); }
+ set { SetValue(ResponseProperty, value); }
+ }
+ public static readonly DependencyProperty ResponseProperty =
+ DependencyProperty.Register("Response", typeof(String), typeof(TextInputBoxWindow), new PropertyMetadata(null));
+
+
+
+ public String Message
+ {
+ get { return (String)GetValue(MessageProperty); }
+ set { SetValue(MessageProperty, value); }
+ }
+ public static readonly DependencyProperty MessageProperty =
+ DependencyProperty.Register("Message", typeof(String), typeof(TextInputBoxWindow), new PropertyMetadata(null));
+
+ public Brush IconColor
+ {
+ get { return (Brush)GetValue(IconColorProperty); }
+ set { SetValue(IconColorProperty, value); }
+ }
+ public static readonly DependencyProperty IconColorProperty =
+ DependencyProperty.Register("IconColor", typeof(Brush), typeof(TextInputBoxWindow), new PropertyMetadata(Brushes.Black));
+
+ public PackIconKind IconKind
+ {
+ get { return (PackIconKind)GetValue(IconKindProperty); }
+ set { SetValue(IconKindProperty, value); }
+ }
+ public static readonly DependencyProperty IconKindProperty =
+ DependencyProperty.Register("IconKind", typeof(PackIconKind), typeof(TextInputBoxWindow), new PropertyMetadata(PackIconKind.Information));
+
+ 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/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
index de8649c13..886985c92 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
@@ -14,22 +14,50 @@ using System.Collections;
using Tango.Integration.Services;
using Tango.Core;
using Tango.Logging;
+using Tango.MachineStudio.Common.Modules;
+using Tango.MachineStudio.Common;
+using Tango.Settings;
namespace Tango.MachineStudio.UI.StudioApplication
{
+ /// <summary>
+ /// Represents the default Machine Studio <see cref="IStudioApplicationManager">Application Manager</see>.
+ /// </summary>
+ /// <seealso cref="Tango.Core.ExtendedObject" />
+ /// <seealso cref="Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager" />
public class DefaultStudioApplicationManager : ExtendedObject, IStudioApplicationManager
{
private INavigationManager _navigationManager;
+ private IStudioModuleLoader _moduleLoader;
- public DefaultStudioApplicationManager(INavigationManager navigationManager)
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultStudioApplicationManager" /> class.
+ /// </summary>
+ /// <param name="navigationManager">The navigation manager.</param>
+ public DefaultStudioApplicationManager(INavigationManager navigationManager, IStudioModuleLoader moduleLoader)
{
+ _moduleLoader = moduleLoader;
_navigationManager = navigationManager;
}
+ /// <summary>
+ /// Gets a value indicating whether Machine Studio is shutting down.
+ /// </summary>
public bool IsShuttingDown { get; private set; }
+ /// <summary>
+ /// The connected machine
+ /// </summary>
private IExternalBridgeClient _connectedMachine;
+ /// <summary>
+ /// Occurs when the connected machine property has changed.
+ /// </summary>
+ public event EventHandler<IExternalBridgeClient> ConnectedMachineChanged;
+
+ /// <summary>
+ /// Gets or sets the currently connected machine if any.
+ /// </summary>
public IExternalBridgeClient ConnectedMachine
{
get { return _connectedMachine; }
@@ -45,14 +73,24 @@ namespace Tango.MachineStudio.UI.StudioApplication
_connectedMachine.StateChanged -= ConnectedMachine_StateChanged;
_connectedMachine.StateChanged += ConnectedMachine_StateChanged;
}
+
+ ConnectedMachineChanged?.Invoke(this, _connectedMachine);
}
}
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid and connected through TCP/IP.
+ /// </summary>
public bool IsMachineConnectedViaTCP
{
- get { return IsMachineConnected && ConnectedMachine.Type != ExternalBridgeClientType.USB; }
+ get { return IsMachineConnected && ConnectedMachine is ExternalBridgeTcpClient; }
}
+ /// <summary>
+ /// Handles the <see cref="ConnectedMachine"/> state changed event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
private void ConnectedMachine_StateChanged(object sender, Transport.TransportComponentState e)
{
if (e == Transport.TransportComponentState.Disconnected || e == Transport.TransportComponentState.Failed)
@@ -62,11 +100,17 @@ namespace Tango.MachineStudio.UI.StudioApplication
}
+ /// <summary>
+ /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid.
+ /// </summary>
public bool IsMachineConnected
{
get { return ConnectedMachine != null; }
}
+ /// <summary>
+ /// Shutdown the application.
+ /// </summary>
public async void ShutDown()
{
if (IsShuttingDown) return;
@@ -75,6 +119,24 @@ namespace Tango.MachineStudio.UI.StudioApplication
await Task.Factory.StartNew(async () =>
{
+ //Do Shutdown Procedures...
+ foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownRequestBlocker>())
+ {
+ try
+ {
+ var result = await vm.OnShutdownRequest();
+ if (!result)
+ {
+ IsShuttingDown = false;
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error on shutdown request with " + vm.GetType().Name);
+ }
+ }
+
try
{
if (ConnectedMachine != null)
@@ -87,22 +149,52 @@ namespace Tango.MachineStudio.UI.StudioApplication
LogManager.Log(ex, "Error disconnecting from machine.");
}
- //Do Shutdown Procedures...
- foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownRequestBlocker>())
+ foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownListener>())
{
- var result = await vm.OnShutdownRequest();
- if (!result)
- {
- IsShuttingDown = false;
- return;
- }
+ vm.OnShuttingDown();
+ }
+
+ try
+ {
+ SettingsManager.SaveDefaultSettings();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error saving settings.");
}
_navigationManager.NavigateTo(NavigationView.ShutdownView);
+
Thread.Sleep(3000);
+
Environment.Exit(0);
});
}
+
+ /// <summary>
+ /// Loads the specified module if permitted.
+ /// </summary>
+ /// <param name="moduleName">Name of the module.</param>
+ /// <param name="args">The arguments.</param>
+ public void RequestModule(string moduleName, object args)
+ {
+ IStudioModule module = _moduleLoader.UserModules.SingleOrDefault(x => x.Name == moduleName);
+
+ if (module != null)
+ {
+ ServiceLocator.Current.GetInstance<ViewModels.MainViewVM>().StartModule(module);
+
+ //Notify request listeners.
+ foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IModuleRequestListener>())
+ {
+ vm.OnRequestModule(module, args);
+ }
+ }
+ else
+ {
+ throw new InvalidOperationException("The module was not found or you do not have sufficient privileges.");
+ }
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/SupervisingController/IMainView.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/SupervisingController/IMainView.cs
index 70b57027e..fd8ef4be5 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/SupervisingController/IMainView.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/SupervisingController/IMainView.cs
@@ -3,12 +3,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.MachineStudio.Common;
using Tango.SharedUI;
namespace Tango.MachineStudio.UI.SupervisingController
{
+ /// <summary>
+ /// Represents a supervising controller pattern view contract.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.IView" />
public interface IMainView : IView
{
-
+ /// <summary>
+ /// Navigates to the specified studio module.
+ /// </summary>
+ /// <param name="module">The module.</param>
+ void NavigateToModule(IStudioModule module);
}
}
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 df8b65fda..f48561e40 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
@@ -120,6 +120,9 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Compile Include="Notifications\TextInputBoxWindow.xaml.cs">
+ <DependentUpon>TextInputBoxWindow.xaml</DependentUpon>
+ </Compile>
<Compile Include="StudioApplication\DefaultStudioApplicationManager.cs" />
<Compile Include="Authentication\DefaultAuthenticationProvider.cs" />
<Compile Include="Modules\DefaultStudioModuleLoader.cs" />
@@ -157,6 +160,10 @@
<Compile Include="Views\ShutdownView.xaml.cs">
<DependentUpon>ShutdownView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Windows\ExceptionResolutions.cs" />
+ <Compile Include="Windows\ExceptionWindow.xaml.cs">
+ <DependentUpon>ExceptionWindow.xaml</DependentUpon>
+ </Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -172,6 +179,10 @@
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
+ <Page Include="Notifications\TextInputBoxWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Notifications\MessageBoxWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -208,6 +219,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Windows\ExceptionWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -241,14 +256,14 @@
<Resource Include="design.ico" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\SideChains\RealTimeGraphEx\RealTimeGraphEx.csproj">
+ <Project>{b9ae25d6-be35-492f-9079-21a7f3e6f7cc}</Project>
+ <Name>RealTimeGraphEx</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>
@@ -277,6 +292,10 @@
<Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
<Name>Tango.Transport</Name>
</ProjectReference>
+ <ProjectReference Include="..\Modules\Tango.MachineStudio.DataCapture\Tango.MachineStudio.DataCapture.csproj">
+ <Project>{fc337a7f-1214-41d8-9992-78092a3b961e}</Project>
+ <Name>Tango.MachineStudio.DataCapture</Name>
+ </ProjectReference>
<ProjectReference Include="..\Modules\Tango.MachineStudio.DB\Tango.MachineStudio.DB.csproj">
<Project>{94f7acf8-55e1-4a02-b9bc-a818413fdbbf}</Project>
<Name>Tango.MachineStudio.DB</Name>
@@ -297,6 +316,10 @@
<Project>{12d0c43c-391f-4c74-92ab-82e9a9beeb9b}</Project>
<Name>Tango.MachineStudio.Synchronization</Name>
</ProjectReference>
+ <ProjectReference Include="..\Modules\Tango.MachineStudio.Technician\Tango.MachineStudio.Technician.csproj">
+ <Project>{5d39c1e1-3ecd-4634-bd1b-2bcf71c54a15}</Project>
+ <Name>Tango.MachineStudio.Technician</Name>
+ </ProjectReference>
<ProjectReference Include="..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
<Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
<Name>Tango.MachineStudio.Common</Name>
@@ -312,12 +335,15 @@
<Resource Include="Images\account.png" />
</ItemGroup>
<ItemGroup>
- <Folder Include="Controls\" />
+ <Resource Include="Images\White-Abstract.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\external-bridge-tcp.png" />
<Resource Include="Images\external-bridge-usb.png" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\exception.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>$(TargetDir)linkgen.exe -s "$(TargetPath)" -d "$(TargetDir)Utilities\Machine Studio.lnk"
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
index 70912ba98..1907074c0 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
@@ -5,10 +5,12 @@ using System;
using Tango.Integration.Services;
using Tango.Logging;
using Tango.MachineStudio.Common.Authentication;
+using Tango.MachineStudio.Common.Diagnostics;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Navigation;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Common.Video;
using Tango.MachineStudio.UI.Authentication;
using Tango.MachineStudio.UI.Modules;
using Tango.MachineStudio.UI.Navigation;
@@ -17,6 +19,7 @@ using Tango.MachineStudio.UI.StudioApplication;
using Tango.MachineStudio.UI.SupervisingController;
using Tango.MachineStudio.UI.ViewModels;
using Tango.MachineStudio.UI.Views;
+using Tango.Settings;
namespace Tango.MachineStudio.UI
{
@@ -50,6 +53,8 @@ namespace Tango.MachineStudio.UI
SimpleIoc.Default.Unregister<IStudioModuleLoader>();
SimpleIoc.Default.Unregister<IStudioApplicationManager>();
SimpleIoc.Default.Unregister<ExternalBridgeScanner>();
+ SimpleIoc.Default.Unregister<IVideoCaptureProvider>();
+ SimpleIoc.Default.Unregister<IDiagnosticsFrameProvider>();
SimpleIoc.Default.Register<INotificationProvider, DefaultNotificationProvider>();
SimpleIoc.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>();
@@ -57,6 +62,8 @@ namespace Tango.MachineStudio.UI
SimpleIoc.Default.Register<IStudioModuleLoader, DefaultStudioModuleLoader>();
SimpleIoc.Default.Register<IStudioApplicationManager, DefaultStudioApplicationManager>();
SimpleIoc.Default.Register<ExternalBridgeScanner, ExternalBridgeScanner>();
+ SimpleIoc.Default.Register<IVideoCaptureProvider, DefaultVideoCaptureProvider>();
+ SimpleIoc.Default.Register<IDiagnosticsFrameProvider, DefaultDiagnosticsFrameProvider>();
SimpleIoc.Default.Register<MainViewVM>();
SimpleIoc.Default.Register<LoadingViewVM>();
@@ -65,9 +72,6 @@ namespace Tango.MachineStudio.UI
SimpleIoc.Default.Register<MachineConnectionViewVM>();
SimpleIoc.Default.Register<MachineLoginViewVM>();
- LogManager.RegisterLogger(new VSOutputLogger());
- LogManager.RegisterLogger(new FileLogger());
-
//Register View (Supervising Controller Pattern).
if (!ViewModelBase.IsInDesignModeStatic)
{
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 f213af0d4..55a54e8aa 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
@@ -4,8 +4,8 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Tango.Core.Threading;
-using Tango.DAL.Observables;
+using Tango.Core.Helpers;
+using Tango.Integration.Observables;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Navigation;
using Tango.MachineStudio.Common.Notifications;
@@ -13,12 +13,22 @@ using Tango.SharedUI;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the Machine Studio loading view, view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
public class LoadingViewVM : ViewModel
{
private INotificationProvider _notificationProvider;
private INavigationManager _navigationManager;
private IStudioModuleLoader _studioModuleLoader;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LoadingViewVM"/> class.
+ /// </summary>
+ /// <param name="navigationManager">The navigation manager.</param>
+ /// <param name="studioModuleLoader">The studio module loader.</param>
+ /// <param name="notificationProvider">The notification provider.</param>
public LoadingViewVM(INavigationManager navigationManager, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider)
{
_navigationManager = navigationManager;
@@ -27,9 +37,12 @@ namespace Tango.MachineStudio.UI.ViewModels
Load();
}
+ /// <summary>
+ /// Load application modules.
+ /// </summary>
private void Load()
{
- StaThreadHelper.StartStaThread(() =>
+ ThreadsHelper.StartStaThread(() =>
{
try
{
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs
index 6fe90fa99..c5936eea8 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs
@@ -16,6 +16,10 @@ using Tango.SharedUI;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the Machine Studio login view, view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
public class LoginViewVM : ViewModel
{
private IAuthenticationProvider _authenticationProvider;
@@ -24,6 +28,9 @@ namespace Tango.MachineStudio.UI.ViewModels
private Rfc2898Cryptographer cryptographer;
private String _email;
+ /// <summary>
+ /// Gets or sets the email.
+ /// </summary>
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Please enter a valid email")]
public String Email
@@ -33,16 +40,26 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private bool _rememberMe;
-
+ /// <summary>
+ /// Gets or sets a value indicating whether to remember the last user email and password.
+ /// </summary>
public bool RememberMe
{
get { return _rememberMe; }
set { _rememberMe = value; RaisePropertyChangedAuto(); }
}
-
+ /// <summary>
+ /// Gets or sets the login command.
+ /// </summary>
public RelayCommand<String> LoginCommand { get; set; }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LoginViewVM"/> class.
+ /// </summary>
+ /// <param name="authenticationProvider">The authentication provider.</param>
+ /// <param name="navigationManager">The navigation manager.</param>
+ /// <param name="notificationProvider">The notification provider.</param>
public LoginViewVM(IAuthenticationProvider authenticationProvider, INavigationManager navigationManager, INotificationProvider notificationProvider)
{
_notificationProvider = notificationProvider;
@@ -55,6 +72,10 @@ namespace Tango.MachineStudio.UI.ViewModels
RememberMe = SettingsManager.Default.MachineStudio.RememberMe;
}
+ /// <summary>
+ /// Logins the requested user.
+ /// </summary>
+ /// <param name="password">The password.</param>
private void Login(String password)
{
if (Validate())
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs
index b8b888e86..23be8d274 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineConnectionViewVM.cs
@@ -10,10 +10,16 @@ using Tango.SharedUI;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the Machine Studio connection dialog, view model.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.Notifications.DialogViewVM" />
public class MachineConnectionViewVM : DialogViewVM
{
private ExternalBridgeScanner _scanner;
-
+ /// <summary>
+ /// Gets or sets the machine scanner.
+ /// </summary>
public ExternalBridgeScanner Scanner
{
get { return _scanner; }
@@ -21,15 +27,24 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private IExternalBridgeClient _selectedMachine;
-
+ /// <summary>
+ /// Gets or sets the selected machine.
+ /// </summary>
public IExternalBridgeClient SelectedMachine
{
get { return _selectedMachine; }
set { _selectedMachine = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
+ /// <summary>
+ /// Gets or sets the connect command.
+ /// </summary>
public RelayCommand ConnectCommand { get; set; }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineConnectionViewVM"/> class.
+ /// </summary>
+ /// <param name="scanner">The scanner.</param>
public MachineConnectionViewVM(ExternalBridgeScanner scanner)
{
Scanner = scanner;
@@ -37,6 +52,9 @@ namespace Tango.MachineStudio.UI.ViewModels
Scanner.Start();
}
+ /// <summary>
+ /// Connect to the currently selected machine.
+ /// </summary>
private void Connect()
{
if (SelectedMachine != null)
@@ -45,10 +63,12 @@ namespace Tango.MachineStudio.UI.ViewModels
}
}
+ /// <summary>
+ /// Called when the dialog has been shown.
+ /// </summary>
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
index a6ee9ee2a..20c2e3afb 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineLoginViewVM.cs
@@ -8,20 +8,40 @@ using Tango.MachineStudio.Common.Notifications;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the machine login dialog, view model.
+ /// </summary>
+ /// <seealso cref="Tango.MachineStudio.Common.Notifications.DialogViewVM" />
public class MachineLoginViewVM : DialogViewVM
{
+ /// <summary>
+ /// Gets or sets the machine password.
+ /// </summary>
public String Password { get; set; }
+ /// <summary>
+ /// Gets or sets the login command.
+ /// </summary>
public RelayCommand<String> LoginCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the cancel command.
+ /// </summary>
public RelayCommand CancelCommand { get; set; }
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineLoginViewVM"/> class.
+ /// </summary>
public MachineLoginViewVM()
{
LoginCommand = new RelayCommand<string>(Login);
CancelCommand = new RelayCommand(Cancel);
}
+ /// <summary>
+ /// Invoked when user presses the login button.
+ /// </summary>
+ /// <param name="password">The password.</param>
private void Login(string password)
{
Password = password;
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 b21b23935..679ba5ff3 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
@@ -1,4 +1,5 @@
-using System;
+using GalaSoft.MvvmLight.Ioc;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
@@ -7,6 +8,7 @@ using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Commands;
+using Tango.Integration.Services;
using Tango.Logging;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Authentication;
@@ -22,12 +24,19 @@ using Tango.Transport.Adapters;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the Machine Studio main view, view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel{Tango.MachineStudio.UI.SupervisingController.IMainView}" />
public class MainViewVM : ViewModel<IMainView>
{
private IStudioModule _currentModule;
private INavigationManager _navigation;
private bool _isDisconnecting;
+ /// <summary>
+ /// Gets or sets the current loaded module.
+ /// </summary>
public IStudioModule CurrentModule
{
get { return _currentModule; }
@@ -35,33 +44,54 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private bool _isModuleLoaded;
-
+ /// <summary>
+ /// Gets or sets a value indicating whether any module is loaded at the moment.
+ /// </summary>
public bool IsModuleLoaded
{
get { return _isModuleLoaded; }
set { _isModuleLoaded = value; RaisePropertyChangedAuto(); }
}
-
private bool _isMenuOpened;
-
+ /// <summary>
+ /// Gets or sets a value indicating whether the side menu is opened.
+ /// </summary>
public bool IsMenuOpened
{
get { return _isMenuOpened; }
set { _isMenuOpened = value; RaisePropertyChangedAuto(); }
}
+ /// <summary>
+ /// Gets or sets the start module command.
+ /// </summary>
public RelayCommand<IStudioModule> StartModuleCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the home command.
+ /// </summary>
public RelayCommand HomeCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the connect command.
+ /// </summary>
public RelayCommand ConnectCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the disconnect command.
+ /// </summary>
public RelayCommand DisconnectCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the sign-out command.
+ /// </summary>
public RelayCommand SignoutCommand { get; set; }
private IAuthenticationProvider _authenticationProvider;
+ /// <summary>
+ /// Gets or sets the authentication provider.
+ /// </summary>
public IAuthenticationProvider AuthenticationProvider
{
get { return _authenticationProvider; }
@@ -69,7 +99,9 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private IStudioModuleLoader _studioModuleLoader;
-
+ /// <summary>
+ /// Gets or sets the studio module loader.
+ /// </summary>
public IStudioModuleLoader StudioModuleLoader
{
get { return _studioModuleLoader; }
@@ -77,7 +109,9 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private INotificationProvider _notificationProvider;
-
+ /// <summary>
+ /// Gets or sets the notification provider.
+ /// </summary>
public INotificationProvider NotificationProvider
{
get { return _notificationProvider; }
@@ -85,15 +119,24 @@ namespace Tango.MachineStudio.UI.ViewModels
}
private IStudioApplicationManager _applicationManager;
-
+ /// <summary>
+ /// Gets or sets the application manager.
+ /// </summary>
public IStudioApplicationManager ApplicationManager
{
get { return _applicationManager; }
set { _applicationManager = value; RaisePropertyChangedAuto(); }
}
-
-
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainViewVM"/> class.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ /// <param name="authenticationProvider">The authentication provider.</param>
+ /// <param name="studioModuleLoader">The studio module loader.</param>
+ /// <param name="notificationProvider">The notification provider.</param>
+ /// <param name="applicationManager">The application manager.</param>
+ /// <param name="navigationManager">The navigation manager.</param>
public MainViewVM(
IMainView view,
IAuthenticationProvider authenticationProvider,
@@ -116,6 +159,9 @@ namespace Tango.MachineStudio.UI.ViewModels
DisconnectCommand = new RelayCommand(DisconnectFromMachine, (x) => ApplicationManager.IsMachineConnected && !_isDisconnecting);
}
+ /// <summary>
+ /// Disconnected from the current connected machine.
+ /// </summary>
private async void DisconnectFromMachine()
{
using (_notificationProvider.PushTaskItem("Disconnecting from machine..."))
@@ -129,6 +175,9 @@ namespace Tango.MachineStudio.UI.ViewModels
}
}
+ /// <summary>
+ /// Signs-out the current logged-in user.
+ /// </summary>
private void SignOut()
{
_authenticationProvider.Logout();
@@ -137,6 +186,9 @@ namespace Tango.MachineStudio.UI.ViewModels
IsMenuOpened = false;
}
+ /// <summary>
+ /// Opens the machine connection dialog to allow the user to scan and connect to remote machines view USB/TCP.
+ /// </summary>
private void ConnectToMachine()
{
_notificationProvider.ShowModalDialog<MachineConnectionViewVM>(async (x) =>
@@ -152,17 +204,17 @@ namespace Tango.MachineStudio.UI.ViewModels
}
}
- if (x.SelectedMachine.Type != Integration.Services.ExternalBridgeClientType.USB)
+ if (x.SelectedMachine.RequiresAuthentication)
{
_notificationProvider.ShowModalDialog<MachineLoginViewVM>(async (login) =>
{
- using (NotificationProvider.PushTaskItem("Connecting to machine " + x.SelectedMachine.SerialNumber + "..."))
+ using (NotificationProvider.PushTaskItem("Connecting to machine " + x.SelectedMachine.ToString() + "..."))
{
try
{
await x.SelectedMachine.Connect();
- var authenticated = await x.SelectedMachine.Authenticate(login.Password);
+ var authenticated = await x.SelectedMachine.As<IExternalBridgeSecureClient>().Authenticate(login.Password);
if (!authenticated)
{
_notificationProvider.ShowError("It seems like you are not authorized to access the selected machine.");
@@ -184,7 +236,7 @@ namespace Tango.MachineStudio.UI.ViewModels
}
else
{
- using (NotificationProvider.PushTaskItem("Connecting to machine " + x.SelectedMachine.Device + "..."))
+ using (NotificationProvider.PushTaskItem("Connecting to " + x.SelectedMachine.ToString() + "..."))
{
try
{
@@ -208,26 +260,44 @@ namespace Tango.MachineStudio.UI.ViewModels
});
}
+ /// <summary>
+ /// Navigates to the home screen.
+ /// </summary>
private void Home()
{
StartModule(null);
}
- private void StartModule(IStudioModule module)
+ /// <summary>
+ /// Starts the specified module.
+ /// </summary>
+ /// <param name="module">The module.</param>
+ internal void StartModule(IStudioModule module)
{
IsMenuOpened = false;
+ foreach (var m in StudioModuleLoader.AllModules.Where(x => x != module))
+ {
+ m.IsLoaded = false;
+ }
+
if (module != null)
{
CurrentModule = module;
+ CurrentModule.IsLoaded = true;
IsModuleLoaded = true;
+ View.NavigateToModule(module);
}
else
{
IsModuleLoaded = false;
+ View.NavigateToModule(null);
}
}
+ /// <summary>
+ /// Called when the <see cref="T:Tango.SharedUI.IView" /> is loaded and attached.
+ /// </summary>
protected override void OnViewAttached()
{
base.OnViewAttached();
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ShutdownViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ShutdownViewVM.cs
index c7a919a82..ed771f00a 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ShutdownViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ShutdownViewVM.cs
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace Tango.MachineStudio.UI.ViewModels
{
+ /// <summary>
+ /// Represents the Machine Studio shutdown view, view model.
+ /// </summary>
public class ShutdownViewVM
{
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
index 459c8fde8..2478c1155 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
@@ -6,7 +6,7 @@
xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" Cursor="Wait" DataContext="{Binding LoadingViewVM, Source={StaticResource Locator}}" Background="White">
+ d:DesignHeight="720" d:DesignWidth="1280" Cursor="Wait" DataContext="{Binding LoadingViewVM, Source={StaticResource Locator}}" Background="Transparent">
<Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml
index 1531370af..84ba597f2 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml
@@ -7,7 +7,7 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" DataContext="{Binding LoginViewVM, Source={StaticResource Locator}}" Background="White">
+ d:DesignHeight="720" d:DesignWidth="1280" DataContext="{Binding LoginViewVM, Source={StaticResource Locator}}" Background="Transparent">
<UserControl.Resources>
<rules:Required x:Key="Required"></rules:Required>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml
index 4208c2878..1626e67ef 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml
@@ -5,6 +5,7 @@
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:integration="clr-namespace:Tango.Integration.Services;assembly=Tango.Integration"
xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
@@ -43,7 +44,7 @@
</Grid.RowDefinitions>
<Grid>
- <TextBlock VerticalAlignment="Center" Margin="0 0 0 0" Text="Scanning for machine on your local network..."></TextBlock>
+ <TextBlock VerticalAlignment="Center" Margin="0 0 0 0" Text="Scanning for machines on your local environment..."></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>
@@ -51,21 +52,15 @@
</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>
- <Grid>
+ <ListBox ItemsSource="{Binding Scanner.AvailableMachines}" SelectedItem="{Binding SelectedMachine}" Margin="0 0 0 7" BorderThickness="1" BorderBrush="Gainsboro" HorizontalContentAlignment="Stretch">
+ <ListBox.Resources>
+ <DataTemplate DataType="{x:Type integration:ExternalBridgeTcpClient}">
+ <DockPanel>
+ <StackPanel Orientation="Vertical" VerticalAlignment="Center" DockPanel.Dock="Right" ToolTip="Allow incoming diagnostics data">
+ <ToggleButton IsChecked="{Binding EnableDiagnostics}" VerticalAlignment="Center"></ToggleButton>
+ <TextBlock VerticalAlignment="Center" FontSize="10">Diagnostics</TextBlock>
+ </StackPanel>
<StackPanel Orientation="Horizontal">
- <StackPanel.Style>
- <Style TargetType="StackPanel">
- <Setter Property="Visibility" Value="Visible"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding Type}" Value="USB">
- <Setter Property="Visibility" Value="Collapsed"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </StackPanel.Style>
<Image Source="/Images/external-bridge-tcp.png" Width="38" Height="38" RenderOptions.BitmapScalingMode="Fant"></Image>
<StackPanel Margin="10 0 0 0">
<TextBlock FontSize="11">
@@ -79,18 +74,15 @@
</TextBlock>
</StackPanel>
</StackPanel>
-
+ </DockPanel>
+ </DataTemplate>
+ <DataTemplate DataType="{x:Type integration:ExternalBridgeUsbClient}">
+ <DockPanel>
+ <StackPanel Orientation="Vertical" VerticalAlignment="Center" DockPanel.Dock="Right" ToolTip="Allow incoming diagnostics data">
+ <ToggleButton IsChecked="{Binding EnableDiagnostics}" VerticalAlignment="Center"></ToggleButton>
+ <TextBlock VerticalAlignment="Center" FontSize="10">Diagnostics</TextBlock>
+ </StackPanel>
<StackPanel Orientation="Horizontal">
- <StackPanel.Style>
- <Style TargetType="StackPanel">
- <Setter Property="Visibility" Value="Collapsed"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding Type}" Value="USB">
- <Setter Property="Visibility" Value="Visible"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </StackPanel.Style>
<Image Source="/Images/external-bridge-usb.png" Width="38" Height="38" RenderOptions.BitmapScalingMode="Fant"></Image>
<StackPanel Margin="10 0 0 0">
<TextBlock FontSize="11">
@@ -101,9 +93,9 @@
</TextBlock>
</StackPanel>
</StackPanel>
- </Grid>
+ </DockPanel>
</DataTemplate>
- </ListBox.ItemTemplate>
+ </ListBox.Resources>
</ListBox>
<mahapps:MetroProgressBar VerticalAlignment="Bottom" Height="1" IsIndeterminate="True"></mahapps:MetroProgressBar>
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 d7d0f8dc3..479052cc5 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
@@ -4,6 +4,7 @@
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:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
xmlns:dockablz="clr-namespace:Dragablz.Dockablz;assembly=Dragablz"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
@@ -12,7 +13,12 @@
xmlns:db="clr-namespace:Tango.MachineStudio.DB.Views;assembly=Tango.MachineStudio.DB"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1270" Background="White" DataContext="{Binding MainViewVM, Source={StaticResource Locator}}">
+ d:DesignHeight="720" d:DesignWidth="1270" Background="Transparent" DataContext="{Binding MainViewVM, Source={StaticResource Locator}}">
+
+ <UserControl.Resources>
+ <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" />
+ </UserControl.Resources>
+
<Grid>
<Grid.Style>
<Style TargetType="Grid">
@@ -125,8 +131,23 @@
</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}">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <Grid Margin="0 0 20 0">
+ <ItemsControl ItemsSource="{Binding NotificationProvider.BarItems}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <StackPanel Orientation="Horizontal" IsItemsHost="True" VerticalAlignment="Center"></StackPanel>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <ContentControl Margin="0 0 10 0" Content="{Binding Element}" VerticalAlignment="Center"></ContentControl>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Grid>
+
+ <Button VerticalAlignment="Center" 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" />
@@ -134,21 +155,25 @@
</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>
+ <Grid>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <TextBlock Text="Machine Connection" VerticalAlignment="Center" Foreground="White"></TextBlock>
+ <materialDesign:PackIcon Margin="10 0 0 0" Width="24" Height="24">
+ <materialDesign:PackIcon.Style>
+ <Style TargetType="materialDesign:PackIcon">
+ <Setter Property="Foreground" Value="#333333"></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>
+ </Grid>
</StackPanel>
</Button>
</StackPanel>
@@ -165,90 +190,66 @@
</Grid.RowDefinitions>
<Grid Grid.Row="1">
- <Grid.RowDefinitions>
- <RowDefinition Height="150"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
- <Grid>
- <StackPanel Margin="30 20" HorizontalAlignment="Left">
- <TextBlock Style="{StaticResource MaterialDesignDisplay1TextBlock}">Welcome to Machine Studio</TextBlock>
- <TextBlock HorizontalAlignment="Right" Margin="0 5 -130 0" FontStyle="Italic" Style="{StaticResource MaterialDesignSubheadingTextBlock}" Foreground="{StaticResource AccentColorBrush}">Select Your Studio Module...</TextBlock>
- </StackPanel>
- </Grid>
- <ItemsControl ItemsSource="{Binding StudioModuleLoader.UserModules}" Grid.Row="2" Margin="10">
- <ItemsControl.ItemsPanel>
- <ItemsPanelTemplate>
- <WrapPanel IsItemsHost="True"></WrapPanel>
- </ItemsPanelTemplate>
- </ItemsControl.ItemsPanel>
-
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <materialDesign:Card Width="300" Margin="10" Height="400">
- <Grid >
- <Grid.RowDefinitions>
- <RowDefinition Height="180" />
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Image Source="{Binding Image,Mode=OneWay}" Stretch="Fill" RenderOptions.BitmapScalingMode="Fant" />
- <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.StartModuleCommand}" CommandParameter="{Binding}" Grid.Row="0" Margin="0,0,20,-35" HorizontalAlignment="Right" Width="70" Height="70" VerticalAlignment="Bottom" Style="{StaticResource MaterialDesignFloatingActionMiniButton}" ToolTip="Start This Module">
- <materialDesign:PackIcon Kind="Play" Width="30" Height="30" />
- </Button>
- <StackPanel Grid.Row="1" Margin="8,24,8,0">
- <TextBlock FontWeight="Bold" FontSize="20" Text="{Binding Name,Mode=OneWay}"></TextBlock>
- <TextBlock VerticalAlignment="Center" Margin="0 5 0 0" FontSize="14" TextWrapping="Wrap" Text="{Binding Description,Mode=OneWay}"></TextBlock>
- </StackPanel>
- <StackPanel Grid.Row="2" Margin="8" HorizontalAlignment="Right" Orientation="Horizontal">
- <materialDesign:PopupBox Padding="2,0,2,0" Style="{StaticResource MaterialDesignToolPopupBox}">
- <StackPanel>
- <Button Content="More" />
- <Button Content="Options" />
- </StackPanel>
- </materialDesign:PopupBox>
+ <controls:MultiTransitionControl x:Name="TransitionControl" AlwaysFade="True" TransitionType="Zoom">
+ <controls:MultiTransitionControl.Controls>
+ <ContentControl Tag="Home">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="150"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+ <Grid>
+ <StackPanel Margin="30 20" HorizontalAlignment="Left">
+ <TextBlock Style="{StaticResource MaterialDesignDisplay1TextBlock}">Welcome to Machine Studio</TextBlock>
+ <TextBlock HorizontalAlignment="Right" Margin="0 5 -130 0" FontStyle="Italic" Style="{StaticResource MaterialDesignSubheadingTextBlock}" Foreground="{StaticResource AccentColorBrush}">Select Your Studio Module...</TextBlock>
</StackPanel>
</Grid>
- </materialDesign:Card>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
- </Grid>
- <Grid Grid.Row="1" RenderTransformOrigin="0.5,0.5">
- <Grid.Style>
- <Style TargetType="Grid">
- <Setter Property="RenderTransform">
- <Setter.Value>
- <ScaleTransform ScaleX="0" ScaleY="0"></ScaleTransform>
- </Setter.Value>
- </Setter>
- <Setter Property="Opacity" Value="0"></Setter>
+ <Grid Grid.Row="2">
+ <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
+ <ItemsControl ItemsSource="{Binding StudioModuleLoader.UserModules}" Margin="10">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel IsItemsHost="True"></WrapPanel>
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
- <Style.Triggers>
- <DataTrigger Binding="{Binding IsModuleLoaded}" Value="False">
- <DataTrigger.EnterActions>
- <BeginStoryboard>
- <Storyboard>
- <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.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>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Grid.Style>
- <ContentPresenter Content="{Binding CurrentModule.MainView}"/>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <materialDesign:Card Width="300" Margin="10" Height="400">
+ <Grid >
+ <Grid.RowDefinitions>
+ <RowDefinition Height="180" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Image Source="{Binding Image,Mode=OneWay}" Stretch="Fill" RenderOptions.BitmapScalingMode="Fant" />
+ <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.StartModuleCommand}" CommandParameter="{Binding}" Grid.Row="0" Margin="0,0,20,-35" HorizontalAlignment="Right" Width="70" Height="70" VerticalAlignment="Bottom" Style="{StaticResource MaterialDesignFloatingActionMiniButton}" ToolTip="Start This Module">
+ <materialDesign:PackIcon Kind="Play" Width="30" Height="30" />
+ </Button>
+ <StackPanel Grid.Row="1" Margin="8,24,8,0">
+ <TextBlock FontWeight="Bold" FontSize="20" Text="{Binding Name,Mode=OneWay}"></TextBlock>
+ <TextBlock VerticalAlignment="Center" Margin="0 5 0 0" FontSize="14" TextWrapping="Wrap" Text="{Binding Description,Mode=OneWay}"></TextBlock>
+ </StackPanel>
+ <StackPanel Grid.Row="2" Margin="8" HorizontalAlignment="Right" Orientation="Horizontal">
+ <materialDesign:PopupBox Padding="2,0,2,0" Style="{StaticResource MaterialDesignToolPopupBox}">
+ <StackPanel>
+ <Button Content="More" />
+ <Button Content="Options" />
+ </StackPanel>
+ </materialDesign:PopupBox>
+ </StackPanel>
+ </Grid>
+ </materialDesign:Card>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </Grid>
+ </Grid>
+ </ContentControl>
+ </controls:MultiTransitionControl.Controls>
+ </controls:MultiTransitionControl>
</Grid>
</Grid>
@@ -289,7 +290,7 @@
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20 0 0 0">
<mahapps:ProgressRing Width="24" Height="24" Foreground="White"></mahapps:ProgressRing>
- <TextBlock Text="{Binding NotificationProvider.CurrentTaskItem.Message}" Foreground="White" VerticalAlignment="Center" Margin="10 0 0 0"></TextBlock>
+ <TextBlock Text="{Binding NotificationProvider.CurrentTaskItem.Message,Converter={StaticResource StringEllipsisConverter},ConverterParameter=35}" Foreground="White" VerticalAlignment="Center" Margin="10 0 0 0" TextWrapping="Wrap"></TextBlock>
</StackPanel>
</Border>
</Grid>
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 f52393e1c..e6e1557f3 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
@@ -14,11 +14,17 @@ using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
+using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.UI.Modules;
using Tango.MachineStudio.UI.Notifications;
using Tango.MachineStudio.UI.SupervisingController;
using Tango.SharedUI;
using Tango.SharedUI.Controls;
+using Tango.MachineStudio.Common;
+using System.Threading;
+using Tango.Core.Helpers;
+using Tango.SharedUI.Helpers;
namespace Tango.MachineStudio.UI.Views
{
@@ -27,9 +33,63 @@ namespace Tango.MachineStudio.UI.Views
/// </summary>
public partial class MainView : View, IMainView
{
+ private DefaultStudioModuleLoader _loader;
+
public MainView() : base()
{
InitializeComponent();
+
+ _loader = ServiceLocator.Current.GetInstance<IStudioModuleLoader>() as DefaultStudioModuleLoader;
+ _loader.ModulesLoaded += Loader_ModulesLoaded;
+ }
+
+ public void NavigateToModule(IStudioModule module)
+ {
+ TransitionControl.AutoNavigate(module != null ? module.Name : "Home");
+ }
+
+ private void Loader_ModulesLoaded(object sender, EventArgs e)
+ {
+ TransitionControl.Controls.RemoveAll((x) => x.Tag.ToString() != "Home");
+
+ Task.Factory.StartNew(() =>
+ {
+ var item = ServiceLocator.Current.GetInstance<INotificationProvider>().PushTaskItem("Loading Modules...");
+
+ var modules = _loader.UserModules.ToList();
+
+ ThreadsHelper.InvokeUINow(() =>
+ {
+ _loader.UserModules.Clear();
+ });
+
+ Thread.Sleep(1500);
+
+ foreach (var module in modules)
+ {
+ ThreadsHelper.InvokeUI(() =>
+ {
+ TransitionControl.Controls.Add(new ContentControl()
+ {
+ Tag = module.Name,
+ Content = module.MainView
+ });
+
+ _loader.UserModules.Add(module);
+ });
+
+ UIHelper.DoEvents();
+
+ Thread.Sleep(100);
+ }
+
+ ThreadsHelper.InvokeUI(() =>
+ {
+ TransitionControl.RefreshControls();
+ });
+
+ item.Pop();
+ });
}
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml
index 487dfe1f8..dd86238ce 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml
@@ -6,7 +6,7 @@
xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
- d:DesignHeight="720" d:DesignWidth="1280" Cursor="Wait" Background="White" DataContext="{Binding ShutdownViewVM, Source={StaticResource Locator}}">
+ d:DesignHeight="720" d:DesignWidth="1280" Cursor="Wait" Background="Transparent" DataContext="{Binding ShutdownViewVM, Source={StaticResource Locator}}">
<Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs
new file mode 100644
index 000000000..2e7327559
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionResolutions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.UI.Windows
+{
+ public enum ExceptionResolutions
+ {
+ Shutdown,
+ Restart,
+ Ignore
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml
new file mode 100644
index 000000000..c08a08842
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml
@@ -0,0 +1,61 @@
+<Window x:Class="Tango.MachineStudio.UI.Windows.ExceptionWindow"
+ 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"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows"
+ mc:Ignorable="d"
+ WindowStyle="None" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStartupLocation="CenterScreen" d:DesignHeight="300" d:DesignWidth="300" Width="610" Height="410" Background="Transparent" d:DataContext="{d:DesignInstance Type=local:ExceptionWindow, IsDesignTimeCreatable=False}">
+ <Grid>
+ <Border BorderThickness="1" BorderBrush="DodgerBlue" Background="White" Margin="10" CornerRadius="10">
+ <Border.Effect>
+ <DropShadowEffect ShadowDepth="0" BlurRadius="10" />
+ </Border.Effect>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="80"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <StackPanel Orientation="Horizontal" Margin="10">
+ <Image Source="/Images/exception.png" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Text="Machine Studio Error" 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 TextWrapping="Wrap" VerticalAlignment="Center" Margin="0 0 0 0">
+ <Run>Machine Studio encountered an unexpected error. It is recommended to restart the application in order to resolve the issue.</Run>
+ </TextBlock>
+ </Grid>
+
+ <Grid Grid.Row="1" Margin="0 10 0 0">
+ <TextBox Style="{x:Null}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" BorderBrush="#515151" IsReadOnly="True" AcceptsReturn="True" Foreground="#FF5C5C" Padding="2" TextWrapping="Wrap" Text="{Binding Exception}"></TextBox>
+ </Grid>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <Button HorizontalAlignment="Left" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Ignore}">Ignore</Button>
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button Margin="5 0 0 0" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Shutdown}">Shutdown</Button>
+ <Button Margin="5 0 0 0" Width="140" Command="{Binding ResolveCommand}" CommandParameter="{x:Static local:ExceptionResolutions.Restart}">Restart</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Border>
+ </Grid>
+</Window>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs
new file mode 100644
index 000000000..0f74fee17
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml.cs
@@ -0,0 +1,48 @@
+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.Shapes;
+using Tango.Core.Commands;
+using Tango.MachineStudio.UI.ViewModels;
+
+namespace Tango.MachineStudio.UI.Windows
+{
+ /// <summary>
+ /// Interaction logic for ExceptionWindow.xaml
+ /// </summary>
+ public partial class ExceptionWindow : Window
+ {
+ public ExceptionResolutions Resolution { get; set; }
+
+ public String Exception { get; set; }
+
+ public RelayCommand<ExceptionResolutions> ResolveCommand { get; set; }
+
+ public ExceptionWindow()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+
+ public ExceptionWindow(Exception ex) : this()
+ {
+ Exception = ex.FlattenException();
+ ResolveCommand = new RelayCommand<ExceptionResolutions>(Resolve);
+ }
+
+ private void Resolve(ExceptionResolutions resolution)
+ {
+ Resolution = resolution;
+ Close();
+ }
+ }
+}