aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config12
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs15
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs43
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs25
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs369
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs47
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj10
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Threading/DefaultDispatcherProvider.cs46
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs41
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineSerialViewVM.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs38
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs4
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml43
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs14
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml18
20 files changed, 604 insertions, 145 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
index 004400788..4147a78ec 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
@@ -39,7 +39,7 @@
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" />
</dependentAssembly>
- <dependentAssembly>
+ <!--<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
@@ -74,11 +74,19 @@
<dependentAssembly>
<assemblyIdentity name="System.Xml.ReaderWriter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
- </dependentAssembly>
+ </dependentAssembly>-->
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.19.8.16603" newVersion="3.19.8.16603" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-3.19.8.16603" newVersion="3.19.8.16603" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> \ No newline at end of file
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 ed2cbdbd7..4e1c36593 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
@@ -37,9 +37,20 @@ namespace Tango.MachineStudio.UI
{
#if DEBUG
- CoreSettings.DefaultDataBaseSource = "localhost\\SQLEXPRESS";
+ CoreSettings.DefaultDataSource = new DataSource()
+ {
+ Address = "localhost\\SQLEXPRESS",
+ Catalog = "Tango",
+ IntegratedSecurity = true,
+ };
#else
- CoreSettings.DefaultDataBaseSource = "twine01\\SQLTWINE";
+
+ CoreSettings.DefaultDataSource = new DataSource()
+ {
+ Address = "twine01\\SQLTWINE",
+ Catalog = "Tango",
+ IntegratedSecurity = true,
+ };
#endif
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 4e5425138..c16f76449 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
@@ -9,6 +9,7 @@ using Tango.BL.Entities;
using Tango.MachineStudio.Common.Authentication;
using Tango.BL;
using Tango.BL.Enumerations;
+using System.Data.Entity;
namespace Tango.MachineStudio.UI.Authentication
{
@@ -48,32 +49,38 @@ namespace Tango.MachineStudio.UI.Authentication
/// <exception cref="AuthenticationException">Login failed for user " + email</exception>
public User Login(string email, string password)
{
- String hash = User.GetPasswordHash(password);
+ using (ObservablesContext db = ObservablesContext.CreateDefault())
+ {
- User user = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Email.ToLower() == email.ToLower() && x.Password == hash);
+ String hash = User.GetPasswordHash(password);
- if (user == null)
- {
- throw new AuthenticationException("Invalid credentials for " + email);
- }
+ db.Roles.Load();
+ db.Permissions.Load();
+ db.RolesPermissions.Load();
- if (!user.HasPermission(Permissions.RunMachineStudio))
- {
- throw new AuthenticationException("It seems like you do not have sufficient privileges to run Machine Studio. Please contact your administrator.");
- }
+ User user = db.Users
+ .Include(x => x.UsersRoles)
+ .Include(x => x.Organization).SingleOrDefault(x => x.Email.ToLower() == email.ToLower() && x.Password == hash);
- if (user != null)
- {
- using (ObservablesContext db = ObservablesContext.CreateDefault())
+ if (user == null)
+ {
+ throw new AuthenticationException("Invalid credentials for " + email);
+ }
+
+ if (!user.HasPermission(Permissions.RunMachineStudio))
{
- var u = db.Users.Single(x => x.Guid == user.Guid);
- u.LastLogin = DateTime.UtcNow;
+ throw new AuthenticationException("It seems like you do not have sufficient privileges to run Machine Studio. Please contact your administrator.");
+ }
+
+ if (user != null)
+ {
+ user.LastLogin = DateTime.UtcNow;
db.SaveChanges();
}
- }
- CurrentUser = user;
- return user;
+ CurrentUser = user;
+ return user;
+ }
}
/// <summary>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
index b8a6cd1c0..44b2ed401 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
@@ -17,7 +17,7 @@
<Viewbox Stretch="Fill">
<Grid x:Name="grid" Width="1920" Height="1100">
<Grid>
- <sharedControls:NavigationControl TransitionAlwaysFades="True" TransitionType="Zoom" x:Name="TransitionControl" x:FieldModifier="public">
+ <sharedControls:NavigationControl TransitionAlwaysFades="True" TransitionType="Zoom" x:Name="NavigationControl" x:FieldModifier="public">
<views:LoadingView sharedControls:NavigationControl.NavigationName="LoadingView"></views:LoadingView>
<views:LoginView sharedControls:NavigationControl.NavigationName="LoginView"></views:LoginView>
<views:MainView sharedControls:NavigationControl.NavigationName="MainView"></views:MainView>
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 26a789d0f..13c3d6779 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Modules/DefaultStudioModuleLoader.cs
@@ -12,9 +12,6 @@ using Tango.Logging;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Authentication;
using Tango.MachineStudio.Common.Modules;
-using Tango.MachineStudio.DB;
-using Tango.MachineStudio.MachineDesigner;
-using Tango.MachineStudio.Stubs;
namespace Tango.MachineStudio.UI.Modules
{
@@ -27,7 +24,6 @@ namespace Tango.MachineStudio.UI.Modules
{
private IAuthenticationProvider _authenticationProvider;
private bool _loaded;
- public event EventHandler ModulesLoaded;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultStudioModuleLoader"/> class.
@@ -78,15 +74,15 @@ namespace Tango.MachineStudio.UI.Modules
{
if (!_loaded)
{
- //Preloaded
+ ////Preloaded
- LogManager.Log(String.Format("Loading module '{0}'...", nameof(StubsModule)));
- AllModules.Add(new StubsModule());
- LogManager.Log(String.Format("Loading module '{0}'...", nameof(DBModule)));
- AllModules.Add(new DBModule());
- LogManager.Log(String.Format("Loading module '{0}'...", nameof(MachineDesignerModule)));
- AllModules.Add(new MachineDesignerModule());
- //Preloaded
+ //LogManager.Log(String.Format("Loading module '{0}'...", nameof(StubsModule)));
+ //AllModules.Add(new StubsModule());
+ //LogManager.Log(String.Format("Loading module '{0}'...", nameof(DBModule)));
+ //AllModules.Add(new DBModule());
+ //LogManager.Log(String.Format("Loading module '{0}'...", nameof(MachineDesignerModule)));
+ //AllModules.Add(new MachineDesignerModule());
+ ////Preloaded
AllModules.Clear();
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
@@ -146,5 +142,10 @@ namespace Tango.MachineStudio.UI.Modules
{
return UserModules.OfType<T>().FirstOrDefault();
}
+
+ /// <summary>
+ /// Occurs when all modules are initialized.
+ /// </summary>
+ public event EventHandler ModulesLoaded;
}
}
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 092b958cc..899ba846e 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Navigation/DefaultNavigationManager.cs
@@ -3,8 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.Commands;
using Tango.MachineStudio.Common;
+using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Navigation;
+using Tango.MachineStudio.Common.Threading;
+using Tango.SharedUI.Controls;
namespace Tango.MachineStudio.UI.Navigation
{
@@ -12,18 +17,372 @@ namespace Tango.MachineStudio.UI.Navigation
/// Represents the Machine Studio default <see cref="INavigationManager">Navigation Manager</see>.
/// </summary>
/// <seealso cref="Tango.MachineStudio.Common.Navigation.INavigationManager" />
- public class DefaultNavigationManager : INavigationManager
+ public class DefaultNavigationManager : ExtendedObject, INavigationManager
{
+ private event Action<Object, Object> NavigationCycleCompleted;
+
+ private IDispatcherProvider _dispatcherProvider;
+ private IStudioModuleLoader _moduleLoader;
+ private Object _currentVM;
+ private String _lastFullPath;
+ private bool _preventHistory;
+ private bool _navigating_back;
+
+ private Stack<String> _navigationHistory;
+
+ /// <summary>
+ /// Gets the current view model.
+ /// </summary>
+ public StudioViewModel CurrentVM
+ {
+ get { return _currentVM as StudioViewModel; }
+ }
+
+ private IStudioModule _currentModule;
+ /// <summary>
+ /// Gets or sets the current module.
+ /// </summary>
+ public IStudioModule CurrentModule
+ {
+ get { return _currentModule; }
+ private set { _currentModule = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Navigates to the previous view.
+ /// </summary>
+ public RelayCommand NavigateBackCommand { get; private set; }
+
+ /// <summary>
+ /// Navigates to the specified full path in command parameter.
+ /// </summary>
+ public RelayCommand<String> NavigateToCommand { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class.
+ /// </summary>
+ /// <param name="moduleLoader">The module loader.</param>
+ public DefaultNavigationManager(IStudioModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider)
+ {
+ _navigationHistory = new Stack<String>();
+ _moduleLoader = moduleLoader;
+
+ NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x));
+ NavigateBackCommand = new RelayCommand(async () => await NavigateBack());
+
+ _dispatcherProvider = dispatcherProvider;
+ }
+
/// <summary>
- /// Navigates to the specified view.
+ /// Navigates to the specified PPC view.
/// </summary>
/// <param name="view">The view.</param>
- public void NavigateTo(NavigationView view)
+ public Task<bool> NavigateTo(NavigationView view, bool pushToHistory = true)
{
- MainWindow.Instance.Dispatcher.Invoke(() =>
+ LogManager.Log($"Navigating to: {view.ToString()}...");
+
+ _dispatcherProvider.Invoke(() =>
{
- MainWindow.Instance.TransitionControl.NavigateTo(view.ToString());
+ MainWindow.Instance.NavigationControl.NavigateTo(view.ToString());
});
+
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Navigates to the specified PPC view with the specified receive object.
+ /// </summary>
+ /// <param name="view">The view.</param>
+ /// <param name="obj"></param>
+ /// <param name="pushToHistory"></param>
+ /// <returns></returns>
+ public Task<bool> NavigateWithObject<TPass>(NavigationView view, TPass obj, bool pushToHistory = true)
+ {
+ LogManager.Log($"Navigating to: {view.ToString()}, with object {typeof(TPass).Name}...");
+ MainWindow.Instance.NavigationControl.NavigateTo(view.ToString());
+ INavigationObjectReceiver<TPass> receiver = MainWindow.Instance.NavigationControl.Elements.FirstOrDefault(x => (x.GetType().Name == view.ToString() || NavigationControl.GetNavigationName(x) == view.ToString()) && x.DataContext is INavigationObjectReceiver<TPass>).DataContext as INavigationObjectReceiver<TPass>;
+
+ if (receiver != null)
+ {
+ receiver.OnNavigatedToWithObject(obj);
+ }
+
+ return Task.FromResult(true);
+ }
+
+ /// <summary>
+ /// Navigates to the specified module.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public Task<bool> NavigateTo<T>(bool pushToHistory = true) where T : IStudioModule
+ {
+ return NavigateTo(typeof(T));
+ }
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView.JobsView).
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ public Task<bool> NavigateTo<T>(string viewPath, bool pushToHistory = true) where T : IStudioModule
+ {
+ return NavigateTo<T>(pushToHistory, viewPath.Split('.'));
+ }
+
+ /// <summary>
+ /// Navigates to the specified module using the view path (e.g MainView,JobsView).
+ /// This method makes it easy to do stuff like NavigateTo(nameof(MainView),nameof(JobsView));
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="viewPath">The view path.</param>
+ public Task<bool> NavigateTo<T>(bool pushToHistory = true, params String[] viewPath) where T : IStudioModule
+ {
+ return NavigateTo(typeof(T), pushToHistory, viewPath);
+ }
+
+ /// <summary>
+ /// Navigates to the specified module and view by full path (e.g Jobs.JobsView).
+ /// </summary>
+ /// <param name="fullPath">The full path.</param>
+ public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true)
+ {
+ String[] path = fullPath.Split('.');
+ var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]);
+
+ if (path.Length == 1 && path[0] == CurrentModule.Name) return true;
+
+ LogManager.Log($"Navigating to: {fullPath}...");
+
+ var fromVM = _currentVM;
+
+ if (_currentVM != null && _currentVM is INavigationBlocker)
+ {
+ if (_navigating_back)
+ {
+ if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest())
+ {
+ return false;
+ }
+ }
+ }
+
+ if (pushToHistory && _lastFullPath != null && !_preventHistory)
+ {
+ _navigationHistory.Push(_lastFullPath);
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ }
+
+ _lastFullPath = fullPath;
+
+ MainWindow.Instance.NavigationControl.NavigateTo(NavigationView.MainView.ToString());
+ var navigationControl = MachineStudio.UI.Views.MainView.Instance.NavigationControl;
+ CurrentModule = module;
+ var moduleView = navigationControl.NavigateTo(module.Name);
+
+ _currentVM = moduleView.DataContext;
+
+ if (path.Length > 1)
+ {
+ var moduleNavigation = moduleView.FindChildOffline<NavigationControl>();
+
+ moduleNavigation.RegisterForLoadedOrNow(async (x, e) =>
+ {
+ foreach (var view in path.Skip(1))
+ {
+ await Task.Delay(100);
+ var v = moduleNavigation.NavigateTo(view);
+
+ if (v != null)
+ {
+ _currentVM = v.DataContext;
+
+ if (view != path.Last())
+ {
+ moduleNavigation = v.FindChildOffline<NavigationControl>();
+ }
+ }
+ else
+ {
+ throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath));
+ }
+ }
+
+ NavigationCycleCompleted?.Invoke(fromVM, _currentVM);
+ });
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Navigates for result.
+ /// </summary>
+ /// <typeparam name="TModule">The type of the module.</typeparam>
+ /// <typeparam name="TView">The type of the view.</typeparam>
+ /// <typeparam name="TResult">The type of the result.</typeparam>
+ /// <typeparam name="TObject">The type of the object.</typeparam>
+ /// <param name="obj">The object.</param>
+ /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
+ /// <returns></returns>
+ public Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true)
+ where TModule : IStudioModule
+ {
+ TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>();
+
+ var fromVM = _currentVM;
+ Object toVM = null;
+
+
+ Action<Object, Object> handler = null;
+
+ handler = (from, to) =>
+ {
+ if (toVM == null)
+ {
+ toVM = to;
+ if (toVM is INavigationResultProvider<TResult, TObject>)
+ {
+ (toVM as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj);
+ }
+ }
+ else
+ {
+ if (to == fromVM && from == toVM)
+ {
+ if (from is INavigationResultProvider<TResult, TObject>)
+ {
+ source.SetResult((from as INavigationResultProvider<TResult, TObject>).GetNavigationResult());
+ }
+ }
+
+ NavigationCycleCompleted -= handler;
+ }
+ };
+
+ NavigationCycleCompleted += handler;
+
+ NavigateTo<TModule>(typeof(TView).Name, pushToHistory);
+
+ return source.Task;
+ }
+
+ /// <summary>
+ /// Navigates to the specified module and view with the specified object.
+ /// </summary>
+ /// <typeparam name="TModule">The type of the module.</typeparam>
+ /// <typeparam name="TView">The type of the view.</typeparam>
+ /// <typeparam name="TPass">The type of the pass.</typeparam>
+ /// <param name="obj">The object.</param>
+ /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param>
+ /// <returns></returns>
+ public Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true) where TModule : IStudioModule
+ {
+ TaskCompletionSource<bool> source = new TaskCompletionSource<bool>();
+
+ Action<Object, Object> handler = null;
+
+ handler = (from, to) =>
+ {
+ if (to is INavigationObjectReceiver<TPass>)
+ {
+ (to as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj);
+ }
+
+ NavigationCycleCompleted -= handler;
+ };
+
+ NavigationCycleCompleted += handler;
+
+ NavigateTo<TModule>(typeof(TView).Name, pushToHistory);
+
+ return source.Task;
+ }
+
+ private Task<bool> NavigateTo(Type moduleType, bool pushToHistory = true, params String[] viewPath)
+ {
+ if (viewPath != null && viewPath.Length > 0)
+ {
+ return NavigateTo(moduleType.Name + "." + String.Join(".", viewPath), pushToHistory);
+ }
+ else
+ {
+ return NavigateTo(moduleType.Name, pushToHistory);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the navigation system is able to navigate to the previous view.
+ /// </summary>
+ public bool CanNavigateBack
+ {
+ get { return _navigationHistory.Count > 0; }
+ }
+
+ /// <summary>
+ /// Navigates to the previous view if <see cref="P:Tango.PPC.Common.Navigation.INavigationManager.CanNavigateBack" /> is true.
+ /// </summary>
+ public async Task<bool> NavigateBack()
+ {
+ LogManager.Log("Navigating back...");
+
+ _navigating_back = true;
+
+ String first = _navigationHistory.Pop();
+ _preventHistory = true;
+
+
+ if (await NavigateTo(first))
+ {
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ _preventHistory = false;
+ _navigating_back = false;
+ return true;
+ }
+ else
+ {
+ _navigationHistory.Push(first);
+ _preventHistory = false;
+ _navigating_back = false;
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Clears the navigation back history.
+ /// </summary>
+ public void ClearHistory()
+ {
+ LogManager.Log("Navigation history cleared.");
+ _navigationHistory.Clear();
+ RaisePropertyChanged(nameof(CanNavigateBack));
+ }
+
+ /// <summary>
+ /// Clears the navigation back history except the specified view type.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public void ClearHistoryExcept<T>()
+ {
+ LogManager.Log($"Navigation history cleared except for {typeof(T).Name}.");
+
+ var history_list = _navigationHistory.ToList();
+ history_list = history_list.Where(x => x.Contains(typeof(T).Name)).Distinct().ToList();
+ _navigationHistory.Clear();
+
+ foreach (var item in history_list)
+ {
+ _navigationHistory.Push(item);
+ }
+
+ RaisePropertyChanged(nameof(CanNavigateBack));
}
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs
index 358775686..2ba2c2d37 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Properties/AssemblyInfo.cs
@@ -4,5 +4,5 @@ using System.Runtime.InteropServices;
[assembly: System.Windows.ThemeInfo(System.Windows.ResourceDictionaryLocation.None, System.Windows.ResourceDictionaryLocation.SourceAssembly)]
[assembly: AssemblyTitle("Tango - Machine Studio")]
-[assembly: AssemblyVersion("2.9.23.18231")]
+[assembly: AssemblyVersion("3.1.32.18235")]
[assembly: ComVisible(false)] \ No newline at end of file
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 ee9337eb3..7c7e18276 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
@@ -43,21 +43,10 @@ namespace Tango.MachineStudio.UI.StudioApplication
_navigationManager = navigationManager;
_openedWindows = new List<Window>();
- Task.Factory.StartNew(() =>
+ Application.Current.MainWindow.ContentRendered += (_, __) =>
{
- while (MainWindow.Instance == null)
- {
- Thread.Sleep(100);
- }
-
- InvokeUI(() =>
- {
- MainWindow.Instance.ContentRendered += (_, __) =>
- {
- TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationStarted());
- };
- });
- });
+ TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationStarted());
+ };
}
/// <summary>
@@ -237,31 +226,6 @@ namespace Tango.MachineStudio.UI.StudioApplication
}
/// <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, params object[] args)
- {
- IStudioModule module = _moduleLoader.UserModules.SingleOrDefault(x => x.Name == moduleName);
-
- if (module != null)
- {
- TangoIOC.Default.GetInstance<ViewModels.MainViewVM>().StartModule(module);
-
- //Notify request listeners.
- foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
- {
- vm.OnModuleRequest(module, args);
- }
- }
- else
- {
- throw new InvalidOperationException("The module was not found or you do not have sufficient privileges.");
- }
- }
-
- /// <summary>
/// Notify the application manager about an external opened window.
/// When application exists. All registered windows will be closed.
/// </summary>
@@ -305,5 +269,10 @@ namespace Tango.MachineStudio.UI.StudioApplication
return EmbeddedResourceHelper.GetEmbeddedResourceText("Tango.MachineStudio.UI.ChangeLog.txt");
}
}
+
+ public void NotifyApplicationReady()
+ {
+ TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationReady());
+ }
}
}
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 724f83680..2ac516903 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
@@ -8,7 +8,7 @@
<OutputType>WinExe</OutputType>
<RootNamespace>Tango.MachineStudio.UI</RootNamespace>
<AssemblyName>Tango.MachineStudio.UI</AssemblyName>
- <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
@@ -168,6 +168,7 @@
<Compile Include="TFS\TeamFoundationServiceExtendedClient.cs" />
<Compile Include="TFS\TeamMembersProvider.cs" />
<Compile Include="TFS\WorkItemValidationAttribute.cs" />
+ <Compile Include="Threading\DefaultDispatcherProvider.cs" />
<Compile Include="ViewModels\AboutViewVM.cs" />
<Compile Include="ViewModels\ConnectedMachineViewVM.cs" />
<Compile Include="ViewModels\LoadingViewVM.cs" />
@@ -432,10 +433,6 @@
<Project>{22c2aa72-9493-4d0d-b421-8ef9789fb192}</Project>
<Name>Tango.MachineStudio.Stubs</Name>
</ProjectReference>
- <ProjectReference Include="..\Modules\Tango.MachineStudio.Synchronization\Tango.MachineStudio.Synchronization.csproj">
- <Project>{12d0c43c-391f-4c74-92ab-82e9a9beeb9b}</Project>
- <Name>Tango.MachineStudio.Synchronization</Name>
- </ProjectReference>
<ProjectReference Include="..\Modules\Tango.MachineStudio.Technician\Tango.MachineStudio.Technician.csproj">
<Project>{5d39c1e1-3ecd-4634-bd1b-2bcf71c54a15}</Project>
<Name>Tango.MachineStudio.Technician</Name>
@@ -566,7 +563,8 @@ copy /Y "$(SolutionDir)Referenced Assemblies\mscoree.dll" "$(TargetDir)"
copy /Y "$(SolutionDir)Referenced Assemblies\msvcp140d.dll" "$(TargetDir)"
copy /Y "$(SolutionDir)Referenced Assemblies\ucrtbased.dll" "$(TargetDir)"
copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140.dll" "$(TargetDir)"
-copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)"</PostBuildEvent>
+copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)"
+copy /Y "$(SolutionDir)Referenced Assemblies\Microsoft.WITDataStore32.dll" "$(TargetDir)"</PostBuildEvent>
</PropertyGroup>
<Import Project="..\..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Threading/DefaultDispatcherProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Threading/DefaultDispatcherProvider.cs
new file mode 100644
index 000000000..611dca6b9
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Threading/DefaultDispatcherProvider.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Threading;
+using Tango.MachineStudio.Common.Threading;
+
+namespace Tango.MachineStudio.UI.Threading
+{
+ /// <summary>
+ /// Represents the default PPC <see cref="IDispatcherProvider"/> which will invoke action on the current application dispatcher.
+ /// </summary>
+ /// <seealso cref="Tango.PPC.Common.Threading.IDispatcherProvider" />
+ public class DefaultDispatcherProvider : IDispatcherProvider
+ {
+ private Dispatcher _dispatcher;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultDispatcherProvider"/> class.
+ /// </summary>
+ /// <param name="dispatcher">The dispatcher.</param>
+ public DefaultDispatcherProvider(Dispatcher dispatcher)
+ {
+ _dispatcher = dispatcher;
+ }
+
+ /// <summary>
+ /// Invokes the specified action asynchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ public void Invoke(Action action)
+ {
+ _dispatcher.BeginInvoke(action);
+ }
+
+ /// <summary>
+ /// Invokes the specified action synchronously.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ public void InvokeSync(Action action)
+ {
+ _dispatcher.Invoke(action);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
index 2c816eb6c..10aa86ad1 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
@@ -1,4 +1,5 @@
using System;
+using System.Windows;
using Tango.Core.DI;
using Tango.Integration.ExternalBridge;
using Tango.Logging;
@@ -11,6 +12,7 @@ using Tango.MachineStudio.Common.Navigation;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Common.Speech;
using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Common.Threading;
using Tango.MachineStudio.Common.Video;
using Tango.MachineStudio.UI.Authentication;
using Tango.MachineStudio.UI.Console;
@@ -21,6 +23,7 @@ using Tango.MachineStudio.UI.Notifications;
using Tango.MachineStudio.UI.StudioApplication;
using Tango.MachineStudio.UI.SupervisingController;
using Tango.MachineStudio.UI.TFS;
+using Tango.MachineStudio.UI.Threading;
using Tango.MachineStudio.UI.ViewModels;
using Tango.MachineStudio.UI.Views;
using Tango.Settings;
@@ -64,7 +67,10 @@ namespace Tango.MachineStudio.UI
TangoIOC.Default.Unregister<ISpeechProvider>();
TangoIOC.Default.Unregister<IHtmlPresenter>();
TangoIOC.Default.Unregister<ITeamFoundationServiceClient>();
+ TangoIOC.Default.Unregister<IDispatcherProvider>();
+
+ TangoIOC.Default.Register<IDispatcherProvider, DefaultDispatcherProvider>(new DefaultDispatcherProvider(Application.Current.Dispatcher));
TangoIOC.Default.Register<INotificationProvider, DefaultNotificationProvider>();
TangoIOC.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>();
TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>();
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 a468dc2e7..215f7afb5 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
@@ -28,7 +28,7 @@ namespace Tango.MachineStudio.UI.ViewModels
/// Represents the Machine Studio loading view, view model.
/// </summary>
/// <seealso cref="Tango.SharedUI.ViewModel" />
- public class LoadingViewVM : StudioViewModelInternal
+ public class LoadingViewVM : StudioViewModel
{
private INotificationProvider _notificationProvider;
private TeamFoundationServiceExtendedClient _tfs;
@@ -141,7 +141,7 @@ namespace Tango.MachineStudio.UI.ViewModels
Status = "Loading, please wait...";
- ObservablesEntitiesAdapter.Instance.Initialize();
+ ObservablesStaticCollections.Instance.Initialize();
_eventLogger.Log(EventTypes.ApplicationStarted, "Application Started!");
@@ -172,5 +172,10 @@ namespace Tango.MachineStudio.UI.ViewModels
}
});
}
+
+ public override void OnApplicationReady()
+ {
+
+ }
}
}
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 f2a4f1143..a37879a5e 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoginViewVM.cs
@@ -51,6 +51,15 @@ namespace Tango.MachineStudio.UI.ViewModels
set { _password = value; RaisePropertyChangedAuto(); }
}
+ private bool _isLogging;
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is logging.
+ /// </summary>
+ public bool IsLogging
+ {
+ get { return _isLogging; }
+ set { _isLogging = value; RaisePropertyChangedAuto(); }
+ }
private bool _rememberMe;
/// <summary>
@@ -81,7 +90,7 @@ namespace Tango.MachineStudio.UI.ViewModels
_navigationManager = navigationManager;
_authenticationProvider = authenticationProvider;
_eventLogger = eventLogger;
- LoginCommand = new RelayCommand(Login);
+ LoginCommand = new RelayCommand(Login,() => !IsLogging);
cryptographer = new Rfc2898Cryptographer();
Email = _settings.LastLoginEmail;
@@ -100,26 +109,38 @@ namespace Tango.MachineStudio.UI.ViewModels
/// <summary>
/// Logins the requested user.
/// </summary>
- private void Login()
+ private async void Login()
{
if (Validate())
{
try
{
- _authenticationProvider.Login(Email, Password);
- _navigationManager.NavigateTo(NavigationView.MainView);
- _settings.LastLoginEmail = Email;
- _settings.RememberMe = RememberMe;
+ IsLogging = true;
+ InvalidateRelayCommands();
- _settings.LastLoginPassword = RememberMe ? cryptographer.Encrypt(Password) : null;
- _settings.Save();
+ await Task.Factory.StartNew(() =>
+ {
+ _authenticationProvider.Login(Email, Password);
+ _navigationManager.NavigateTo(NavigationView.MainView);
+ _settings.LastLoginEmail = Email;
+ _settings.RememberMe = RememberMe;
- _eventLogger.Log("User logged in");
+ _settings.LastLoginPassword = RememberMe ? cryptographer.Encrypt(Password) : null;
+ _settings.Save();
+
+ _eventLogger.Log("User logged in");
+ });
}
- catch
+ catch (Exception)
{
+
_notificationProvider.ShowError("Invalid credentials. Please try again.");
}
+ finally
+ {
+ IsLogging = false;
+ InvalidateRelayCommands();
+ }
}
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineSerialViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineSerialViewVM.cs
index 44cfc6788..db32fe623 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineSerialViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MachineSerialViewVM.cs
@@ -29,7 +29,7 @@ namespace Tango.MachineStudio.UI.ViewModels
var settings = SettingsManager.Default.GetOrCreate<MachineStudioSettings>();
- SelectedMachine = ObservablesEntitiesAdapter.Instance.Machines.SingleOrDefault(x => x.SerialNumber == settings.LastVirtualMachineSerialNumber);
+ SelectedMachine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == settings.LastVirtualMachineSerialNumber);
}
}
}
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 f8320e1f2..ee4435832 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
+using Tango.BL;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.Core.DI;
@@ -515,8 +516,14 @@ namespace Tango.MachineStudio.UI.ViewModels
catch (Exception ex)
{
LogManager.Log(ex);
- _eventLogger.Log(ex, "Error connecting to machine " + x.SelectedMachine.SerialNumber);
+
+ if (x.SelectedMachine != null)
+ {
+ _eventLogger.Log(ex, "Error connecting to machine " + x.SelectedMachine.SerialNumber);
+ }
+
_notificationProvider.ShowError("Could not connect to the selected machine." + Environment.NewLine + ex.Message);
+
}
InvalidateRelayCommands();
@@ -547,8 +554,13 @@ namespace Tango.MachineStudio.UI.ViewModels
{
try
{
- var configuration = ApplicationManager.ConnectedMachine.Machine.Configuration;
- await ApplicationManager.ConnectedMachine.UploadHardwareConfiguration(configuration.HardwareVersion, configuration);
+ using (ObservablesContext db = ObservablesContext.CreateDefault())
+ {
+ var config = db.Adapter.GetConfiguration(s => s.Guid == ApplicationManager.ConnectedMachine.Machine.ConfigurationGuid);
+ var hw = db.Adapter.GetHardwareVersionByMachine(ApplicationManager.ConnectedMachine.Machine.Guid);
+
+ await ApplicationManager.ConnectedMachine.UploadHardwareConfiguration(hw, config);
+ }
NotificationProvider.ShowInfo("Hardware configuration uploaded successfully.");
}
catch (Exception ex)
@@ -623,20 +635,19 @@ namespace Tango.MachineStudio.UI.ViewModels
{
LogManager.Log(String.Format("Starting module '{0}'...", module.Name));
- if (!(MainView.Self as MainView).TransitionControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
+ if (!(MainView.Self as MainView).NavigationControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
{
LogManager.Log("Module was not initialized. Initializing...");
FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
NavigationControl.SetNavigationName(view, module.Name);
- (MainView.Self as MainView).TransitionControl.Elements.Add(view);
+ (MainView.Self as MainView).NavigationControl.Elements.Add(view);
}
}
foreach (var m in StudioModuleLoader.AllModules.Where(x => x != module && !x.InNewWindow))
{
m.IsLoaded = false;
- TangoIOC.Default.GetModuleViewModels(m).ToList().ForEach(x => x.OnNavigatedFrom());
}
if (module != null)
@@ -646,15 +657,13 @@ namespace Tango.MachineStudio.UI.ViewModels
IsModuleLoaded = true;
LogManager.Log(String.Format("Navigating to module '{0}'...", module.Name));
- (MainView.Self as MainView).TransitionControl.NavigateTo(module.Name);
-
- TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(x => x.OnNavigatedTo());
+ (MainView.Self as MainView).NavigationControl.NavigateTo(module.Name);
}
else
{
IsModuleLoaded = false;
LogManager.Log(String.Format("Navigating to Home..."));
- (MainView.Self as MainView).TransitionControl.NavigateTo("Home");
+ (MainView.Self as MainView).NavigationControl.NavigateTo("Home");
}
}
@@ -674,16 +683,16 @@ namespace Tango.MachineStudio.UI.ViewModels
LogManager.Log(String.Format("Starting module '{0}' in new window...", module.Name));
- if (!(MainView.Self as MainView).TransitionControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
+ if (!(MainView.Self as MainView).NavigationControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
{
LogManager.Log("Module was not initialized. Initializing...");
FrameworkElement v = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
NavigationControl.SetNavigationName(v, module.Name);
- (MainView.Self as MainView).TransitionControl.Elements.Add(v);
+ (MainView.Self as MainView).NavigationControl.Elements.Add(v);
}
LogManager.Log("Detaching module view...");
- var view = (MainView.Self as MainView).TransitionControl.GetAndDetach(module.Name);
+ var view = (MainView.Self as MainView).NavigationControl.GetAndDetach(module.Name);
ModuleWindowVM vm = new ModuleWindowVM(module);
ModuleWindow window = new ModuleWindow(this, vm, view);
@@ -694,7 +703,6 @@ namespace Tango.MachineStudio.UI.ViewModels
window.grid.Children.Remove(view);
module.InNewWindow = false;
- TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(v => v.OnNavigatedFrom());
};
window.Owner = MainWindow.Instance;
@@ -702,8 +710,6 @@ namespace Tango.MachineStudio.UI.ViewModels
LogManager.Log("Opening new window...");
window.Show();
- TangoIOC.Default.GetModuleViewModels(module).ToList().ForEach(x => x.OnNavigatedTo());
-
(_applicationManager as DefaultStudioApplicationManager).RegisterOpenedWindow(window);
}
catch (Exception ex)
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs
index f2550c598..c5831f701 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs
@@ -319,9 +319,9 @@ namespace Tango.MachineStudio.UI.ViewModels
try
{
Process p = new Process();
- p.StartInfo.FileName = _appPath + "\\Tango.MachineStudio.Updater.exe";
+ p.StartInfo.FileName = _newPackageTempFolder + "\\Tango.MachineStudio.Updater.exe";
p.StartInfo.UseShellExecute = true;
- p.StartInfo.Arguments = _newPackageTempFolder;
+ p.StartInfo.Arguments = _appPath;
p.Start();
}
catch (Exception ex)
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 08e1006c1..68334ad24 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoginView.xaml
@@ -5,7 +5,9 @@
xmlns:rules="clr-namespace:Tango.MachineStudio.Common.ValidationRules;assembly=Tango.MachineStudio.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:automation="clr-namespace:Tango.MachineStudio.Common.Automation;assembly=Tango.MachineStudio.Common"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
xmlns:helpers="clr-namespace:Tango.SharedUI.Helpers;assembly=Tango.SharedUI"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
mc:Ignorable="d"
@@ -13,6 +15,8 @@
<UserControl.Resources>
<rules:Required x:Key="Required"></rules:Required>
+ <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
+ <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" />
</UserControl.Resources>
@@ -24,21 +28,30 @@
<Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant" Width="100"></Image>
<TextBlock Margin="20 0 0 0" VerticalAlignment="Center" FontSize="70" Foreground="{StaticResource AccentColorBrush}">Machine Studio</TextBlock>
</StackPanel>
- <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="320" Margin="0 120 0 0">
- <TextBlock HorizontalAlignment="Center" FontSize="24">Login to your account</TextBlock>
- <Image Source="/Images/account.png" RenderOptions.BitmapScalingMode="Fant" Width="100" Margin="0 20 0 0"></Image>
- <DockPanel Margin="0 20 0 0">
- <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtEmail, Path=BorderBrush}" Kind="EmailOutline" />
- <TextBox x:Name="txtEmail" IsTabStop="True" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="Email" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Text="{Binding Email,UpdateSourceTrigger=PropertyChanged,ValidatesOnNotifyDataErrors=True}" AutomationProperties.IsRequiredForForm="True" />
- </DockPanel>
- <DockPanel Margin="0 20 0 0">
- <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtPass, Path=BorderBrush}" Kind="Key" />
- <PasswordBox x:Name="txtPass" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding Password,Mode=TwoWay}" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="Password" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" AutomationProperties.IsRequiredForForm="True" />
- </DockPanel>
- <CheckBox Margin="25 20 0 0" IsChecked="{Binding RememberMe}">Remember me</CheckBox>
- <Button AutomationProperties.AutomationId="{x:Static automation:UI.LoginButton}" Margin="25 20 0 0" Height="50" Command="{Binding LoginCommand}" Content="LOGIN">
+ <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="320" Margin="0 120 0 0" Height="398">
- </Button>
- </StackPanel>
+ <Button DockPanel.Dock="Bottom" AutomationProperties.AutomationId="{x:Static automation:UI.LoginButton}" Margin="25 20 0 0" Height="50" Command="{Binding LoginCommand}" Content="LOGIN"></Button>
+
+ <Grid>
+ <StackPanel Visibility="{Binding IsLogging,Converter={StaticResource BooleanToVisibilityInverseConverter}}">
+ <TextBlock HorizontalAlignment="Center" FontSize="24">Login to your account</TextBlock>
+ <Image Source="/Images/account.png" RenderOptions.BitmapScalingMode="Fant" Width="100" Margin="0 20 0 0"></Image>
+ <DockPanel Margin="0 20 0 0">
+ <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtEmail, Path=BorderBrush}" Kind="EmailOutline" />
+ <TextBox x:Name="txtEmail" IsTabStop="True" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="Email" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Text="{Binding Email,UpdateSourceTrigger=PropertyChanged,ValidatesOnNotifyDataErrors=True}" AutomationProperties.IsRequiredForForm="True" />
+ </DockPanel>
+ <DockPanel Margin="0 20 0 0">
+ <materialDesign:PackIcon Margin="0 0 0 0" Width="20" Height="20" VerticalAlignment="Top" Foreground="{Binding ElementName=txtPass, Path=BorderBrush}" Kind="Key" />
+ <PasswordBox x:Name="txtPass" helpers:PasswordHelper.Attach="True" helpers:PasswordHelper.Password="{Binding Password,Mode=TwoWay}" Margin="5 0 0 0" materialDesign:HintAssist.FloatingScale="0.50" materialDesign:HintAssist.Hint="Password" materialDesign:TextFieldAssist.TextBoxViewMargin="1 0 1 0" FontSize="20" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" AutomationProperties.IsRequiredForForm="True" />
+ </DockPanel>
+ <CheckBox Margin="25 20 0 0" IsChecked="{Binding RememberMe}">Remember me</CheckBox>
+ </StackPanel>
+
+ <StackPanel Visibility="{Binding IsLogging,Converter={StaticResource BooleanToVisibilityConverter}}" VerticalAlignment="Center">
+ <mahapps:ProgressRing Width="80" Height="80" IsActive="{Binding IsLogging}"></mahapps:ProgressRing>
+ <TextBlock HorizontalAlignment="Center" Margin="0 30 0 0" FontSize="18" FontStyle="Italic">Logging you in...</TextBlock>
+ </StackPanel>
+ </Grid>
+ </DockPanel>
</Grid>
</UserControl>
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 7044ad32e..9a494f862 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
@@ -12,7 +12,6 @@
xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL"
xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
- xmlns:db="clr-namespace:Tango.MachineStudio.DB.Views;assembly=Tango.MachineStudio.DB"
xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
xmlns:commonConverters="clr-namespace:Tango.MachineStudio.Common.Converters;assembly=Tango.MachineStudio.Common"
mc:Ignorable="d"
@@ -398,7 +397,7 @@
</Grid.RowDefinitions>
<Grid Grid.Row="1">
- <controls:NavigationControl x:Name="TransitionControl" TransitionAlwaysFades="True" TransitionType="Zoom">
+ <controls:NavigationControl x:Name="NavigationControl" TransitionAlwaysFades="True" TransitionType="Zoom">
<Grid controls:NavigationControl.NavigationName="Home">
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
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 1e894f3f2..ca8d7066c 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
@@ -27,6 +27,7 @@ using Tango.SharedUI.Helpers;
using Tango.Logging;
using static Tango.SharedUI.Controls.NavigationControl;
using Tango.Core.DI;
+using Tango.MachineStudio.Common.StudioApplication;
namespace Tango.MachineStudio.UI.Views
{
@@ -37,10 +38,14 @@ namespace Tango.MachineStudio.UI.Views
{
private DefaultStudioModuleLoader _loader;
+ public static MainView Instance { get; set; }
+
public MainView() : base()
{
InitializeComponent();
+ Instance = this;
+
_loader = TangoIOC.Default.GetInstance<IStudioModuleLoader>() as DefaultStudioModuleLoader;
_loader.ModulesLoaded += Loader_ModulesLoaded;
}
@@ -68,11 +73,11 @@ namespace Tango.MachineStudio.UI.Views
ThreadsHelper.InvokeUI(() =>
{
- if (!TransitionControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
+ if (!NavigationControl.Elements.ToList().Exists(x => x.GetType() == module.MainViewType))
{
FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
NavigationControl.SetNavigationName(view, module.Name);
- TransitionControl.Elements.Add(view);
+ NavigationControl.Elements.Add(view);
}
_loader.UserModules.Add(module);
@@ -84,6 +89,11 @@ namespace Tango.MachineStudio.UI.Views
}
item.Pop();
+
+ ThreadsHelper.InvokeUI(() =>
+ {
+ TangoIOC.Default.GetInstance<IStudioApplicationManager>().NotifyApplicationReady();
+ });
});
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
index 3b5affbbf..97c42d58d 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ResolvedIssuesView.xaml
@@ -41,15 +41,7 @@
<DataTemplate>
<Border BorderBrush="#E6E6E6" BorderThickness="0 0 0 1" Padding="5">
<DockPanel>
- <StackPanel Orientation="Horizontal">
- <Image Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant"></Image>
- <StackPanel Margin="5 0 0 0">
- <TextBlock Text="{Binding Title}" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"></TextBlock>
- <TextBlock Text="{Binding Comment,TargetNullValue='Comment',FallbackValue='Comment'}" Foreground="Gray" FontSize="10"></TextBlock>
- </StackPanel>
- </StackPanel>
-
- <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
+ <StackPanel DockPanel.Dock="Right" HorizontalAlignment="Right" Orientation="Horizontal">
<Button Background="#FF8282" BorderBrush="#FF8282" Padding="0" Width="90" Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.DeclineCommand}" CommandParameter="{Binding}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Close" />
@@ -63,6 +55,14 @@
</StackPanel>
</Button>
</StackPanel>
+
+ <StackPanel Orientation="Horizontal" Margin="0 0 10 0" Width="320" HorizontalAlignment="Left">
+ <Image Source="/Images/bug.png" Width="24" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <StackPanel Margin="5 0 0 0" ToolTip="{Binding Comment}">
+ <TextBlock Text="{Binding Title}" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"></TextBlock>
+ <TextBlock Text="{Binding Comment,TargetNullValue='Comment',FallbackValue='Comment'}" TextWrapping="Wrap" Foreground="Gray" FontSize="10"></TextBlock>
+ </StackPanel>
+ </StackPanel>
</DockPanel>
</Border>
</DataTemplate>