diff options
| author | Roy Ben Shabat <Roy@twine-s.com> | 2020-12-30 15:11:34 +0000 |
|---|---|---|
| committer | Roy Ben Shabat <Roy@twine-s.com> | 2020-12-30 15:11:34 +0000 |
| commit | d33c19b3ac6803de4b5c8d475832efef131c1a45 (patch) | |
| tree | ea725abc39def99a755b041c13cba1fe0d594ddc /Software/Visual_Studio/PPC/Tango.PPC.UI | |
| parent | 1bdcaa9f51303bbff682507f31fb3b4414692ca4 (diff) | |
| download | Tango-d33c19b3ac6803de4b5c8d475832efef131c1a45.tar.gz Tango-d33c19b3ac6803de4b5c8d475832efef131c1a45.zip | |
Revert "Hope it is fine"
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI')
121 files changed, 4688 insertions, 396 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config index 77255b814..5272eb35d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config @@ -8,8 +8,13 @@ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /> </startup> <runtime> - <legacyCorruptedStateExceptionsPolicy enabled="true|false"/> + <legacyCorruptedStateExceptionsPolicy enabled="true" /> + <legacyUnhandledExceptionPolicy enabled="1" /> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <!--Required for cefCharp--> + <probing privatePath="x86"/> + <!--<dependentAssembly> <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" /> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs index 0bd9f9d1d..e478dba77 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs @@ -5,15 +5,20 @@ using System.Data; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; +using System.Threading; using System.Threading.Tasks; using System.Windows; using Tango.BL; using Tango.Core; using Tango.Core.DI; using Tango.Core.Helpers; +using Tango.Insights; +using Tango.Integration.Operation; using Tango.Logging; using Tango.PPC.Common; using Tango.PPC.Common.EventLogging; +using Tango.PPC.Common.Helpers; using Tango.PPC.Common.Notifications; using Tango.PPC.Common.WatchDog; using Tango.Settings; @@ -25,7 +30,7 @@ namespace Tango.PPC.UI /// </summary> public partial class App : Application { - private WpfGlobalExceptionTrapper exceptionTrapper; + public static WpfGlobalExceptionTrapper ExceptionTrapper; public static String[] StartupArgs { get; private set; } private LogManager LogManager = LogManager.Default; @@ -36,6 +41,12 @@ namespace Tango.PPC.UI /// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param> protected override void OnStartup(StartupEventArgs e) { + //throw new InvalidOperationException("This is a fake exception!!!"); + + //removed due to possibly causing this issue: + //https://stackoverflow.com/questions/41543956/how-to-debug-not-enough-storage-is-available-to-process-this-command + //ThreadPool.SetMaxThreads(1000, 1000); + //If no debugger is attached and the argument -debug was passed launch the debugger. if (e.Args.Contains("-debug") && !Debugger.IsAttached) { @@ -45,18 +56,34 @@ namespace Tango.PPC.UI StartupArgs = e.Args; //LogManager.RegisterLogger(new ConsoleLogger("Tango PPC Debug")); - LogManager.RegisterLogger(new FileLogger()); + LogManager.RegisterLogger(new FileLogger() + { + EnableAutoLogRemoval = true, + EnableMaxFileSizeLimit = true, + AutoLogRemovalPeriod = TimeSpan.FromDays(30) + }); + +#if DEBUG LogManager.RegisterLogger(new VSOutputLogger()); +#endif - LogManager.Log("Application Started..."); + //Configure machine operator logger. + var operatorLogger = MachineOperator.EmbeddedLogManager.RegisteredLoggers.SingleOrDefault(x => x is FileLogger) as FileLogger; + if (operatorLogger != null) + { + operatorLogger.EnableAutoLogRemoval = true; + operatorLogger.EnableMaxFileSizeLimit = true; + operatorLogger.AutoLogRemovalPeriod = TimeSpan.FromDays(30); + } - base.OnStartup(e); + LogsHelper.SetLogSafe(LogManager.CreateLogSafe()); + LogManager.Log($"Application Started... Version: '{AssemblyHelper.GetCurrentAssemblyVersion()}'."); - exceptionTrapper = new WpfGlobalExceptionTrapper(); - exceptionTrapper.Initialize(this); - exceptionTrapper.ApplicationCrashed += ExceptionTrapper_ApplicationCrashed; + base.OnStartup(e); - LogManager.Categories.Clear(); + ExceptionTrapper = new WpfGlobalExceptionTrapper(); + ExceptionTrapper.Initialize(this); + ExceptionTrapper.ApplicationCrashed += ExceptionTrapper_ApplicationCrashed; CoreSettings.DefaultDataSource = new DataSource() { @@ -65,25 +92,33 @@ namespace Tango.PPC.UI IntegratedSecurity = true, }; - SettingsManager.Default.GetOrCreate<CoreSettings>(); + WebRequest.DefaultWebProxy = null; - var settings = SettingsManager.Default.GetOrCreate<PPCSettings>(); + GetLastApplicationCrashFromWindows(); + } - if (settings.LoggingCategories.Count == 0) - { - settings.LoggingCategories.Add(LogCategory.Critical); - settings.LoggingCategories.Add(LogCategory.Error); - settings.LoggingCategories.Add(LogCategory.Info); - settings.LoggingCategories.Add(LogCategory.Warning); - } + #region Global Exception Trapping - settings.Save(); + private async void GetLastApplicationCrashFromWindows() + { + var logItem = await ExceptionTrapper.GetLastApplicationCrashEventLog(60); + if (logItem != null) + { + LogManager.Log(logItem); - LogManager.Categories.AddRange(settings.LoggingCategories); + try + { + InsightsManager.Default.InsertApplicationException(new InsightsApplicationException() + { + Time = DateTime.UtcNow, + Exception = logItem.Message, + IsApplicationCrash = true + }); + } + catch { } + } } - #region Global Exception Trapping - /// <summary> /// Handles the ApplicationCrashed event of the ExceptionTrapper. /// </summary> @@ -91,7 +126,19 @@ namespace Tango.PPC.UI /// <param name="e">The <see cref="ApplicationCrashedEventArgs"/> instance containing the event data.</param> private void ExceptionTrapper_ApplicationCrashed(object sender, ApplicationCrashedEventArgs e) { - e.TryRecover = true; + List<String> ignoredExceptions = new List<string>() + { + "FocusVisualStyle", + "ThreadAbortException", + "A Task's exception(s) were not observed" + }; + + String exceptionString = e.Exception.ToStringSafe(); + + if (ignoredExceptions.Exists(x => exceptionString.Contains(x))) + { + return; + } try { @@ -100,6 +147,17 @@ namespace Tango.PPC.UI try { + InsightsManager.Default.InsertApplicationException(new InsightsApplicationException() + { + Time = DateTime.UtcNow, + Exception = e.Exception.ToString() + }); + } + catch + { } + + try + { if (Application.Current == null) { new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItem.cs new file mode 100644 index 000000000..c2bdc3926 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItem.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Power; +using Tango.PPC.Common.Notifications; + +namespace Tango.PPC.UI.AppBarItems +{ + public class PowerOffAppBarItem : AppBarItem + { + private StartPowerDownResponse _status; + public StartPowerDownResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Gets or sets the view type. + /// </summary> + public override Type ViewType + { + get + { + return typeof(PowerOffAppBarItemView); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml new file mode 100644 index 000000000..9a9f8e912 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml @@ -0,0 +1,30 @@ +<UserControl x:Class="Tango.PPC.UI.AppBarItems.PowerOffAppBarItemView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.AppBarItems" + mc:Ignorable="d" + d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:PowerOffAppBarItem, IsDesignTimeCreatable=False}"> + <Grid> + <touch:TouchButton Style="{StaticResource TangoFlatButton}" Command="{Binding PressedCommand}" Padding="0"> + <StackPanel VerticalAlignment="Center"> + <TextBlock Text="{Binding Status.Message}" FontSize="{StaticResource TangoDefaultFontSize}" TextTrimming="CharacterEllipsis"></TextBlock> + <ProgressBar Maximum="100" Value="{Binding Status.ProgressPercentage}" Margin="0 10 0 5" Background="{StaticResource TangoGrayBrush}" Height="5" Foreground="{StaticResource TangoPrimaryAccentBrush}" BorderThickness="0" /> + <DockPanel LastChildFill="False"> + <TextBlock DockPanel.Dock="Left"> + + <Run Text="{Binding Status.ProgressPercentage}"></Run><Run>%</Run> + <Run>Completed</Run> + </TextBlock> + + <!--<TextBlock DockPanel.Dock="Right"> + <Run Text="{Binding MachineProvider.MachineOperator.RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToTwoDigitsTimeConverter},FallbackValue=5}"></Run> + <Run FontSize="16" Text="{Binding MachineProvider.MachineOperator.RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToLabelConverter},FallbackValue=min}"></Run> + </TextBlock>--> + </DockPanel> + </StackPanel> + </touch:TouchButton> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs new file mode 100644 index 000000000..fdd7bfc30 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.AppBarItems +{ + /// <summary> + /// Interaction logic for PowerOffAppBarItemView.xaml + /// </summary> + public partial class PowerOffAppBarItemView : UserControl + { + public PowerOffAppBarItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs new file mode 100644 index 000000000..966e78769 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Power; +using Tango.PPC.Common.Notifications; + +namespace Tango.PPC.UI.AppBarItems +{ + public class PowerUpAppBarItem : AppBarItem + { + private StartPowerUpResponse _status; + public StartPowerUpResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Gets or sets the view type. + /// </summary> + public override Type ViewType + { + get + { + return typeof(PowerUpAppBarItemView); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml new file mode 100644 index 000000000..b6b769c69 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml @@ -0,0 +1,30 @@ +<UserControl x:Class="Tango.PPC.UI.AppBarItems.PowerUpAppBarItemView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.AppBarItems" + mc:Ignorable="d" + d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:PowerUpAppBarItem, IsDesignTimeCreatable=False}"> + <Grid> + <touch:TouchButton Style="{StaticResource TangoFlatButton}" Command="{Binding PressedCommand}" Padding="0"> + <StackPanel VerticalAlignment="Center"> + <TextBlock Text="{Binding Status.Message}" FontSize="{StaticResource TangoDefaultFontSize}" TextTrimming="CharacterEllipsis"></TextBlock> + <ProgressBar Maximum="100" Value="{Binding Status.ProgressPercentage}" Margin="0 10 0 5" Background="{StaticResource TangoGrayBrush}" Height="5" Foreground="{StaticResource TangoPrimaryAccentBrush}" BorderThickness="0" /> + <DockPanel LastChildFill="False"> + <TextBlock DockPanel.Dock="Left"> + + <Run Text="{Binding Status.ProgressPercentage}"></Run><Run>%</Run> + <Run>Completed</Run> + </TextBlock> + + <!--<TextBlock DockPanel.Dock="Right"> + <Run Text="{Binding MachineProvider.MachineOperator.RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToTwoDigitsTimeConverter},FallbackValue=5}"></Run> + <Run FontSize="16" Text="{Binding MachineProvider.MachineOperator.RunningJobStatus.RemainingTime,Converter={StaticResource TimeSpanToLabelConverter},FallbackValue=min}"></Run> + </TextBlock>--> + </DockPanel> + </StackPanel> + </touch:TouchButton> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs new file mode 100644 index 000000000..599f24d3b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.AppBarItems +{ + /// <summary> + /// Interaction logic for PowerOffAppBarItemView.xaml + /// </summary> + public partial class PowerUpAppBarItemView : UserControl + { + public PowerUpAppBarItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs index 04e968da2..e7be61b0a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs @@ -46,6 +46,11 @@ namespace Tango.PPC.UI.Authentication } /// <summary> + /// Gets a value indicating whether the authentication provider is using a null user. + /// </summary> + public bool AuthenticationRequired { get; private set; } + + /// <summary> /// Performs a user login by the specified email and password. /// </summary> /// <param name="email">The email.</param> @@ -56,6 +61,9 @@ namespace Tango.PPC.UI.Authentication { return Task.Factory.StartNew<User>(() => { + + AuthenticationRequired = true; + String hash = encrypt ? User.GetPasswordHash(password) : password; LogManager.Log($"Logging in user {email}..."); @@ -82,6 +90,16 @@ namespace Tango.PPC.UI.Authentication }); } + public Task Login() + { + return Task.Factory.StartNew(() => + { + AuthenticationRequired = false; + CurrentUser = null; + CurrentUserChanged?.Invoke(this, CurrentUser); + }); + } + /// <summary> /// Logs-out the current logged-in user. /// </summary> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs index 53e143def..5218d9f70 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -29,7 +30,9 @@ namespace Tango.PPC.UI.Connectivity private IMachineProvider _machineProvider; private Rfc2898Cryptographer _cryptographer; private System.Timers.Timer _updateTimer; + private System.Timers.Timer _lanUpdateTimer; private WiFiNetwork _connectedNetwork; + private PPCSettings _settings; /// <summary> /// Occurs when the connectivity provider state has changed (e.g network connected/disconnected). @@ -43,7 +46,17 @@ namespace Tango.PPC.UI.Connectivity public bool IsConnected { get { return _isConnected; } - set { _isConnected = value; RaisePropertyChangedAuto(); } + private set { _isConnected = value; RaisePropertyChangedAuto(); } + } + + private bool _isLanConnected; + /// <summary> + /// Gets a value indicating whether there is LAN connection. + /// </summary> + public bool IsLanConnected + { + get { return _isLanConnected; } + private set { _isLanConnected = value; RaisePropertyChangedAuto(); } } private bool _isHotspoActive; @@ -116,6 +129,8 @@ namespace Tango.PPC.UI.Connectivity { await RefreshAvailableWiFiNetworks(); }); + + _settings = SettingsManager.Default.GetOrCreate<PPCSettings>(); } /// <summary> @@ -153,6 +168,28 @@ namespace Tango.PPC.UI.Connectivity _updateTimer = new System.Timers.Timer(TimeSpan.FromSeconds(30).TotalMilliseconds); _updateTimer.Elapsed += _updateTimer_Elapsed; _updateTimer.Start(); + + _lanUpdateTimer = new System.Timers.Timer(TimeSpan.FromSeconds(10).TotalMilliseconds); + _lanUpdateTimer.Elapsed += _lanUpdateTimer_Elapsed; + _lanUpdateTimer.Start(); + } + + private void _lanUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + foreach (NetworkInterface net in NetworkInterface.GetAllNetworkInterfaces()) + { + if ((net.NetworkInterfaceType == NetworkInterfaceType.Ethernet + || net.NetworkInterfaceType == NetworkInterfaceType.Ethernet3Megabit + || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetFx + || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetT + || net.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) && net.Name.ToStringOrEmpty().StartsWith("Ethernet") && net.OperationalStatus == OperationalStatus.Up) + { + IsLanConnected = true; + return; + } + } + + IsLanConnected = false; } /// <summary> @@ -223,6 +260,11 @@ namespace Tango.PPC.UI.Connectivity /// <returns></returns> public Task<bool> CheckInternetConnection() { + if (_settings.BypassInternetConnectivityCheck) + { + return Task.FromResult(true); + } + return Task.Factory.StartNew<bool>(() => { try diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml new file mode 100644 index 000000000..3404c032a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml @@ -0,0 +1,49 @@ +<UserControl x:Class="Tango.PPC.UI.Controls.MachineStatusControl" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:operations="clr-namespace:Tango.Integration.Operation;assembly=Tango.Integration" + xmlns:local="clr-namespace:Tango.PPC.UI.Controls" + mc:Ignorable="d" + Width="36" Height="Auto"> + <Grid> + <touch:TouchGifAnimation Width="36" HorizontalAlignment="Center" EnableAnimation="True"> + <touch:TouchGifAnimation.Style> + <Style TargetType="touch:TouchGifAnimation"> + <Setter Property="Source" Value="/Images/GlobalStatus/standby.png"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.Disconnected}"> + <Setter Property="Source" Value="/Images/GlobalStatus/machine_off_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.PowerUp}"> + <Setter Property="Source" Value="/Images/GlobalStatus/getting_ready_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.Standby}"> + <Setter Property="Source" Value="/Images/GlobalStatus/standby_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.ReadyToDye}"> + <Setter Property="Source" Value="/Images/GlobalStatus/Ready_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.GettingReady}"> + <Setter Property="Source" Value="/Images/GlobalStatus/getting_ready_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.Printing}"> + <Setter Property="Source" Value="/Images/GlobalStatus/dyeing_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.ShuttingDown}"> + <Setter Property="Source" Value="/Images/GlobalStatus/shutdown_icon_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.Error}"> + <Setter Property="Source" Value="/Images/GlobalStatus/error_Anim.gif"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Status}" Value="{x:Static operations:MachineStatuses.Service}"> + <Setter Property="Source" Value="/Images/GlobalStatus/service_Anim.gif"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </touch:TouchGifAnimation.Style> + </touch:TouchGifAnimation> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs new file mode 100644 index 000000000..61ecef0ad --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Controls +{ + /// <summary> + /// Interaction logic for MachineStatusControl.xaml + /// </summary> + public partial class MachineStatusControl : UserControl + { + public MachineStatusControl() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml new file mode 100644 index 000000000..66bd0392d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml @@ -0,0 +1,28 @@ +<UserControl x:Class="Tango.PPC.UI.Dialogs.FirmwareUpgradeFromFileView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + mc:Ignorable="d" + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="570" Height="700" d:DataContext="{d:DesignInstance Type=local:FirmwareUpgradeFromFileViewVM, IsDesignTimeCreatable=False}"> + <Grid Margin="20"> + <DockPanel> + <Grid DockPanel.Dock="Bottom"> + <touch:TouchButton HorizontalAlignment="Left" CornerRadius="25" Command="{Binding CloseCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">CANCEL</touch:TouchButton> + <touch:TouchButton HorizontalAlignment="Right" CornerRadius="25" Command="{Binding OKCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">UPGRADE</touch:TouchButton> + </Grid> + <StackPanel> + <Image Source="../Images/firmware.png" Stretch="Uniform" Height="120"></Image> + <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Tango Firmware Upgrade</TextBlock> + <TextBlock Margin="20 10" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center">The selected file contains a firmware upgrade package. Press 'UPGRADE' to start updating your system.</TextBlock> + + <TextBlock TextAlignment="Center" HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> + <Run FontWeight="SemiBold">Firmware:</Run> + <Run Text="{Binding Version}"></Run> + </TextBlock> + </StackPanel> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs new file mode 100644 index 000000000..e7e1eb86c --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Dialogs +{ + /// <summary> + /// Interaction logic for UpdateFromFileView.xaml + /// </summary> + public partial class FirmwareUpgradeFromFileView : UserControl + { + public FirmwareUpgradeFromFileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs new file mode 100644 index 000000000..9a7322565 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common.Publish; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class FirmwareUpgradeFromFileViewVM : DialogViewVM + { + public String Version { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml index f3c471954..ad1c2ece3 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml @@ -3,7 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" mc:Ignorable="d" Background="{StaticResource TangoPrimaryBackgroundBrush}" Width="700" Height="800" d:DataContext="{d:DesignInstance Type=local:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}"> @@ -20,28 +20,59 @@ <Run>The job cannot be completed.</Run> </TextBlock> </StackPanel> - <Grid> + <Grid VerticalAlignment="Top" Margin="0 30 0 0"> <ItemsControl ItemsSource="{Binding Exception.IdsPackLevels}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> - <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" IsItemsHost="True"></StackPanel> + <StackPanel HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Vertical" IsItemsHost="True"></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <StackPanel Margin="15 0" Width="60"> - <TextBlock HorizontalAlignment="Center" Text="{Binding IdsPack.LiquidType.Name}" Margin="-20 0 -20 0" TextTrimming="CharacterEllipsis"></TextBlock> - <Border Margin="0 5 0 0" Height="150" Width="50" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource TangoLightBorderBrush}"> + <Grid Margin="0 0 0 4"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="40" /> + <ColumnDefinition Width="160" /> + <ColumnDefinition Width="1*" /> + </Grid.ColumnDefinitions> + <touch:TouchIcon VerticalAlignment="Center" Width="24" Height="24"> + <touch:TouchIcon.Style> + <Style TargetType="touch:TouchIcon"> + <Setter Property="Icon" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoGreenBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsValid}" Value="False"> + <Setter Property="Icon" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoWarningBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding IsOverMax}" Value="True"> + <Setter Property="Icon" Value="AlertOctagon"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoRedBrush}"></Setter> + </DataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsValid}" Value="True" /> + <Condition Binding="{Binding IsOverMax}" Value="False" /> + </MultiDataTrigger.Conditions> + <Setter Property="Icon" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoGreenBrush}"></Setter> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </touch:TouchIcon.Style> + </touch:TouchIcon> + + <Border Grid.Column="1" Margin="5 0 0 0" Height="45" Width="150" CornerRadius="3" BorderThickness="1" BorderBrush="{StaticResource TangoLightBorderBrush}"> <Grid> - <Border CornerRadius="3" VerticalAlignment="Bottom" Loaded="IdsPackLoaded" MinHeight="5"> + <Border VerticalAlignment="Center" CornerRadius="3" Loaded="IdsPackLoaded" MinHeight="45" HorizontalAlignment="Left" MinWidth="5"> <Border.Background> - <LinearGradientBrush> - <GradientStop Offset="0" Color="#4DFFFFFF" /> + <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Offset="0.5" Color="{Binding IdsPack.LiquidType.LiquidTypeColor}" /> + <GradientStop Offset="1" Color="#4EFFFFFF" /> </LinearGradientBrush> </Border.Background> </Border> - <Rectangle Loaded="Limit_Loaded" Stroke="Red" StrokeThickness="2" VerticalAlignment="Bottom"> + <Rectangle Loaded="Limit_Loaded" Stroke="{StaticResource TangoRedBrush}" StrokeThickness="2" HorizontalAlignment="Left"> <Rectangle.Style> <Style TargetType="Rectangle"> <Style.Triggers> @@ -66,9 +97,18 @@ </Style> </Rectangle.Style> </Rectangle> + + + <TextBlock FontSize="{StaticResource TangoSmallFontSize}" Foreground="{StaticResource TangoDarkForegroundBrush}" HorizontalAlignment="Center" Text="{Binding IdsPack.LiquidType.Name}" VerticalAlignment="Center"> + <TextBlock.Effect> + <DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="White" /> + </TextBlock.Effect> + </TextBlock> + </Grid> </Border> - </StackPanel> + <TextBlock Grid.Column="2" HorizontalAlignment="Left" Text="{Binding Message}" VerticalAlignment="Center" Margin="20,0,0,0" TextWrapping="Wrap" FontSize="{StaticResource TangoSmallFontSize}" Foreground="{StaticResource TangoRedBrush}"></TextBlock> + </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs index 9ec1eec0e..e0f02e4af 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs @@ -33,7 +33,7 @@ namespace Tango.PPC.UI.Dialogs Grid parent = border.Parent as Grid; IDSPackLevel packLevel = border.DataContext as IDSPackLevel; - border.Height = ((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; + border.Width = Math.Max(((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth, 0); } private void Limit_Loaded(object sender, RoutedEventArgs e) @@ -42,8 +42,8 @@ namespace Tango.PPC.UI.Dialogs Grid parent = rect.Parent as Grid; IDSPackLevel packLevel = rect.DataContext as IDSPackLevel; - var top = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; - rect.Margin = new Thickness(0, 0, 0, top); + var left = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth; + rect.Margin = new Thickness(left, 0, 0, 0); if (packLevel.IsValid) { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml new file mode 100644 index 000000000..081778434 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml @@ -0,0 +1,32 @@ +<UserControl x:Class="Tango.PPC.UI.Dialogs.PowerUpView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" + mc:Ignorable="d" + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="600" Height="800" d:DataContext="{d:DesignInstance Type=local:PowerUpViewVM, IsDesignTimeCreatable=False}"> + <Grid> + <StackPanel Margin="0 100 0 0" HorizontalAlignment="Center"> + <touch:TouchGifAnimation Source="../Images/powerup.gif" EnableAnimation="{Binding IsVisible}" /> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}" Margin="0 30 0 0">Continue getting ready for:</TextBlock> + <DockPanel HorizontalAlignment="Center" Margin="0 40 0 0"> + <touch:TouchRadioButton IsChecked="{Binding IsSelectedRml}" /> + <touch:TouchComboBox Margin="20 0 0 0" Width="300" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRml}" DisplayMemberPath="Name" Title="Select thread type"></touch:TouchComboBox> + </DockPanel> + <DockPanel HorizontalAlignment="Left" Margin="0 40 0 0"> + <touch:TouchRadioButton IsChecked="{Binding IsMinimalTemperature}" /> + <TextBlock VerticalAlignment="Center" Margin="20 0 0 0">Minimal temperature</TextBlock> + </DockPanel> + + <touch:TouchButton Command="{Binding OKCommand}" Margin="0 150 0 0" Style="{StaticResource TangoHollowButton}" HorizontalAlignment="Center" Padding="60 15" CornerRadius="25">CONTINUE</touch:TouchButton> + + <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" Visibility="{Binding IsTimeoutEnabled,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Run>auto select in</Run> + <Run Text="{Binding RemainingSeconds}"></Run> + <Run>sec</Run> + </TextBlock> + </StackPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs new file mode 100644 index 000000000..a9767276a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Dialogs +{ + /// <summary> + /// Interaction logic for PowerUpView.xaml + /// </summary> + public partial class PowerUpView : UserControl + { + public PowerUpView() + { + InitializeComponent(); + } + + protected override void OnPreviewMouseUp(MouseButtonEventArgs e) + { + base.OnPreviewMouseUp(e); + (DataContext as PowerUpViewVM).IsTimeoutEnabled = false; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs new file mode 100644 index 000000000..ec4b3bb2b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Timers; +using Tango.BL.Entities; +using Tango.PPC.Common; +using Tango.Settings; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class PowerUpViewVM : DialogViewVM + { + private Timer _timer; + + private List<Rml> _rmls; + public List<Rml> Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private Rml _selectedRml; + public Rml SelectedRml + { + get { return _selectedRml; } + set { _selectedRml = value; RaisePropertyChangedAuto(); } + } + + private bool _isSelectedRml; + public bool IsSelectedRml + { + get { return _isSelectedRml; } + set + { + _isSelectedRml = value; + RaisePropertyChangedAuto(); + + if (_isSelectedRml) + { + IsMinimalTemperature = false; + } + } + } + + private bool _isMinimalTemperature; + public bool IsMinimalTemperature + { + get { return _isMinimalTemperature; } + set + { + _isMinimalTemperature = value; + RaisePropertyChangedAuto(); + + if (_isMinimalTemperature) + { + IsSelectedRml = false; + } + } + } + + private int _remainingSeconds; + public int RemainingSeconds + { + get { return _remainingSeconds; } + set { _remainingSeconds = value; RaisePropertyChangedAuto(); } + } + + private bool _isTimeoutEnabled; + public bool IsTimeoutEnabled + { + get { return _isTimeoutEnabled; } + set + { + _isTimeoutEnabled = value; RaisePropertyChangedAuto(); + + if (!_isTimeoutEnabled) + { + _timer.Stop(); + } + } + } + + public PowerUpViewVM() + { + RemainingSeconds = (int)SettingsManager.Default.GetOrCreate<PPCSettings>().PowerUpScreenTimeout.TotalSeconds; + CanClose = true; + IsMinimalTemperature = true; + IsTimeoutEnabled = true; + _timer = new Timer(); + _timer.Interval = TimeSpan.FromSeconds(1).TotalMilliseconds; + _timer.Elapsed += _timer_Elapsed; + } + + private void _timer_Elapsed(object sender, ElapsedEventArgs e) + { + RemainingSeconds--; + + if (RemainingSeconds == 0) + { + InvokeUI(() => + { + Accept(); + }); + } + } + + protected override void Cancel() + { + _timer.Stop(); + base.Cancel(); + } + + protected override void Accept() + { + _timer.Stop(); + base.Accept(); + } + + public override void OnShow() + { + base.OnShow(); + _timer.Start(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml new file mode 100644 index 000000000..e96b39a63 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml @@ -0,0 +1,52 @@ +<UserControl x:Class="Tango.PPC.UI.Dialogs.SafetyLevelOperationsConfirmationView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" + mc:Ignorable="d" + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="700" Height="900" d:DataContext="{d:DesignInstance Type=local:SafetyLevelOperationsConfirmationViewVM, IsDesignTimeCreatable=False}"> + <Grid Margin="20"> + <DockPanel> + <Grid DockPanel.Dock="Bottom"> + <touch:TouchButton HorizontalAlignment="Left" CornerRadius="25" Command="{Binding CloseCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">DECLINE</touch:TouchButton> + + <Grid HorizontalAlignment="Center"> + <touch:TouchRingProgress Width="50" Height="50" Maximum="{Binding MaxSeconds}" Value="{Binding SecondsRemaining}" /> + <TextBlock Text="{Binding SecondsRemaining}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock> + </Grid> + + <touch:TouchButton HorizontalAlignment="Right" CornerRadius="25" Command="{Binding OKCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">APPROVE</touch:TouchButton> + </Grid> + <StackPanel DockPanel.Dock="Top"> + <touch:TouchIcon Icon="Alert" Foreground="{StaticResource TangoWarningBrush}" Height="120"></touch:TouchIcon> + <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Safety Level Access Request</TextBlock> + <TextBlock Margin="20 10" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center"> + <Run>A remote client is requesting a safety level connection to this machine.</Run> + <LineBreak/> + <Run>Once approved, the remote user will be able to perform any mechanical operation remotely.</Run> + </TextBlock> + </StackPanel> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <TextBlock FontSize="{StaticResource TangoTitleFontSize}">Request Information</TextBlock> + <controls:TableGrid Margin="0 30 0 0" HorizontalAlignment="Center" RowHeight="30" Width="280"> + <TextBlock FontWeight="Bold">Address:</TextBlock> + <TextBlock Text="{Binding Connection.Address}"></TextBlock> + + <TextBlock FontWeight="Bold">Host Name:</TextBlock> + <TextBlock Text="{Binding Connection.Request.HostName}"></TextBlock> + + <TextBlock FontWeight="Bold">App ID:</TextBlock> + <TextBlock Text="{Binding Connection.Request.AppID}"></TextBlock> + + <TextBlock FontWeight="Bold">User:</TextBlock> + <TextBlock Text="{Binding Connection.Request.UserName,TargetNullValue='Unknown',FallbackValue='Unknown'}"></TextBlock> + </controls:TableGrid> + </StackPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs new file mode 100644 index 000000000..ef689f1de --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Dialogs +{ + /// <summary> + /// Interaction logic for SafetyLevelOperationsConfirmationView.xaml + /// </summary> + public partial class SafetyLevelOperationsConfirmationView : UserControl + { + public SafetyLevelOperationsConfirmationView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs new file mode 100644 index 000000000..f8027b4c2 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; +using Tango.Integration.ExternalBridge; +using Tango.PMR.Integration; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class SafetyLevelOperationsConfirmationViewVM : DialogViewVM + { + private DispatcherTimer _timer; + + private int _maxSeconds; + public int MaxSeconds + { + get { return _maxSeconds; } + set { _maxSeconds = value; RaisePropertyChangedAuto(); } + } + + private int _secondsRemaining; + public int SecondsRemaining + { + get { return _secondsRemaining; } + set { _secondsRemaining = value; RaisePropertyChangedAuto(); } + } + + private ExternalBridgeClientConnectedEventArgs _connection; + /// <summary> + /// Gets or sets the last client connection event arguments. + /// </summary> + public ExternalBridgeClientConnectedEventArgs Connection + { + get { return _connection; } + set { _connection = value; RaisePropertyChangedAuto(); } + } + + public SafetyLevelOperationsConfirmationViewVM(ExternalBridgeClientConnectedEventArgs connection) + { + Connection = connection; + + MaxSeconds = 30; + SecondsRemaining = 30; + + _timer = new DispatcherTimer(DispatcherPriority.Background, Application.Current.Dispatcher); + _timer.Interval = TimeSpan.FromMilliseconds(800); + _timer.Tick += _timer_Tick; + } + + public override void OnShow() + { + base.OnShow(); + _timer.Start(); + } + + protected override void Accept() + { + _timer.Stop(); + base.Accept(); + } + + protected override void Cancel() + { + _timer.Stop(); + base.Cancel(); + } + + private void _timer_Tick(object sender, EventArgs e) + { + SecondsRemaining--; + + if (SecondsRemaining == 0) + { + Cancel(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml new file mode 100644 index 000000000..f17860d42 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml @@ -0,0 +1,225 @@ +<UserControl x:Class="Tango.PPC.UI.Dialogs.ThreadBreakView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:commonControls="clr-namespace:Tango.PPC.Common.Controls;assembly=Tango.PPC.Common" + xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" + mc:Ignorable="d" + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="700" Height="1150" d:DataContext="{d:DesignInstance Type=local:ThreadBreakViewVM, IsDesignTimeCreatable=False}"> + <Grid> + <DockPanel> + <StackPanel DockPanel.Dock="Top" Margin="0 30 0 0"> + <Image HorizontalAlignment="Center" Source="/Images/thread_loading.png" Stretch="None"></Image> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoHeaderFontSize}" Margin="0 30 0 0">Thread Break Wizard</TextBlock> + </StackPanel> + + <StackPanel Margin="10 0 0 0" Orientation="Horizontal" DockPanel.Dock="Bottom"> + <touch:TouchButton Command="{Binding BackCommand}"> + <touch:TouchButton.Style> + <Style TargetType="touch:TouchButton" BasedOn="{StaticResource TangoFlatButton}"> + <Setter Property="Foreground" Value="{StaticResource TangoPrimaryAccentBrush}"></Setter> + <Style.Triggers> + <Trigger Property="IsEnabled" Value="False"> + <Setter Property="Foreground" Value="{StaticResource TangoGrayBrush}"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </touch:TouchButton.Style> + <StackPanel> + <touch:TouchIcon Icon="ArrowLeft" Width="24" Height="24" /> + <TextBlock Margin="0 5 0 0" HorizontalAlignment="Center">Back</TextBlock> + </StackPanel> + </touch:TouchButton> + </StackPanel> + + <Grid Margin="0 20 0 0"> + <controls:NavigationControl Margin="0 5 0 0" SelectedObject="{Binding Stage}" TransitionType="Slide" TransitionAlwaysFades="False" TransitionDuration="00:00:0.1" SelectedIndex="0"> + + <!--Guiding Units--> + <Grid controls:NavigationControl.NavigationName="GuidingUnits" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="3" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Padding="30 0" HorizontalAlignment="Left" Command="{Binding GuidingUnitsFoundCantFixCommand}">Found But Can't Fix</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Padding="40 0" HorizontalAlignment="Right" Command="{Binding GuidingUnitsFoundAndFixedCommand}">Found and Fixed</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Padding="50 0" HorizontalAlignment="Right" Command="{Binding GuidingUnitsCantFindItCommand}">Can't Find It</touch:TouchButton> + </UniformGrid> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}">Please check guiding units on both sides of the system and fix/tie the thread if possible.</TextBlock> + </StackPanel> + + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/GuidingUnits/1.jpg"></Image> + </commonControls:ImageGalleryControl> + </DockPanel> + </DockPanel> + </Grid> + + <!--Feeding Units--> + <Grid controls:NavigationControl.NavigationName="FeedingUnits" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="2" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Left" Command="{Binding FeedingUnitsFoundAndFixedCommand}">Found and Fixed</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Right" Command="{Binding FeedingUnitsCantFixCommand}">Can't Fix</touch:TouchButton> + </UniformGrid> + <TextBlock Foreground="{StaticResource TangoErrorBrush}" DockPanel.Dock="Bottom" TextWrapping="Wrap" TextAlignment="Center" Margin="50 20"> + if the thread is out of is route or tangle on one of the components you can go to the maintenance screen and open the component to solve the problem + </TextBlock> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Open the covers and check the feeder and puller and fix/tie if possible. + </TextBlock> + </StackPanel> + + <Grid> + <Grid Visibility="{Binding IsArcHead,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/1.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/2.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/3.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/4.jpg"></Image> + </commonControls:ImageGalleryControl> + </Grid> + + <Grid Visibility="{Binding IsArcHead,Converter={StaticResource BooleanToVisibilityConverter}}"> + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/arc/1.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/arc/2.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/arc/3.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/arc/4.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/FeedingUnits/arc/5.jpg"></Image> + </commonControls:ImageGalleryControl> + </Grid> + </Grid> + </DockPanel> + </DockPanel> + </Grid> + + <!--The Dryer--> + <Grid controls:NavigationControl.NavigationName="TheDryer" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="2" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Left" Command="{Binding TheDryerRemovedSuccessfullyCommand}">Removed Successfully</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Right" Command="{Binding TheDryerCantRemoveCommand}">Can't Remove</touch:TouchButton> + </UniformGrid> + <StackPanel DockPanel.Dock="Bottom" TextElement.Foreground="{StaticResource TangoErrorBrush}" Margin="50 20"> + <DockPanel HorizontalAlignment="Center"> + <touch:TouchIcon Icon="Alert" Foreground="{StaticResource TangoErrorBrush}" /> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">HOT SURFACE!</TextBlock> + </DockPanel> + <TextBlock Margin="0 5 0 0" Foreground="{StaticResource TangoErrorBrush}" TextWrapping="Wrap" TextAlignment="Center"> + Recommended to cool down and/or to wear safety gloves + </TextBlock> + </StackPanel> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Open the dryer, cut the thread and remove any residue. + </TextBlock> + </StackPanel> + + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/TheDryer/1.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/TheDryer/2.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/TheDryer/3.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/TheDryer/4.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/TheDryer/5.jpg"></Image> + </commonControls:ImageGalleryControl> + </DockPanel> + </DockPanel> + </Grid> + + <!--Dryer Close--> + <Grid controls:NavigationControl.NavigationName="DryerClose" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="300" HorizontalAlignment="Center" Command="{Binding OpenThreadLoadingWizardCommand}">Open The Thread Loading Wizard</touch:TouchButton> + </UniformGrid> + <TextBlock DockPanel.Dock="Bottom" TextWrapping="Wrap" TextAlignment="Center" Margin="50 20"> + You will be able to open the thread loading wizard once the dryer door is closed + </TextBlock> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Close the dryer door + </TextBlock> + </StackPanel> + + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/DryerClose/1.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/DryerClose/2.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/DryerClose/3.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/DryerClose/4.jpg"></Image> + </commonControls:ImageGalleryControl> + </DockPanel> + </DockPanel> + </Grid> + + <!--Contact Support--> + <Grid controls:NavigationControl.NavigationName="ContactSupport" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding CloseCommand}">Close</touch:TouchButton> + </UniformGrid> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Please Contact Twine Customer Care + </TextBlock> + </StackPanel> + + <Grid> + <TextBlock HorizontalAlignment="Center" Margin="0 50 0 0" FontSize="40" Foreground="{StaticResource TangoPrimaryAccentBrush}">support@twine-s.com</TextBlock> + </Grid> + </DockPanel> + </DockPanel> + </Grid> + + <!--Jogging--> + <Grid controls:NavigationControl.NavigationName="Jogging" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Verifying thread movement + </TextBlock> + </StackPanel> + + <StackPanel Margin="0 100 0 0"> + <TextBlock HorizontalAlignment="Center" FontWeight="SemiBold">working...</TextBlock> + <touch:TouchBusyIndicator Foreground="{StaticResource TangoGrayBrush}" Width="130" Height="130" Margin="0 40 0 0" StrokeThickness="8" IsIndeterminate="{Binding IsVisible}" /> + </StackPanel> + </DockPanel> + </DockPanel> + </Grid> + + <!--Fixed--> + <Grid controls:NavigationControl.NavigationName="Fixed" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="20" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding CloseCommand}">Close</touch:TouchButton> + </UniformGrid> + <DockPanel> + <StackPanel DockPanel.Dock="Top"> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="40 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}"> + Issue Resolved + </TextBlock> + </StackPanel> + + <Grid> + <touch:TouchIcon Icon="CheckCircleOutline" Foreground="{StaticResource TangoSuccessBrush}" HorizontalAlignment="Center" VerticalAlignment="Top" Width="100" Margin="0 100 0 0" /> + </Grid> + </DockPanel> + </DockPanel> + </Grid> + </controls:NavigationControl> + </Grid> + </DockPanel> + + <touch:TouchIconButton Command="{Binding CloseCommand}" HorizontalAlignment="Right" VerticalAlignment="Top" Icon="Close" Width="45" Height="45" Padding="14" Foreground="{StaticResource TangoDarkForegroundBrush}" /> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs new file mode 100644 index 000000000..c105a9a15 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Dialogs +{ + /// <summary> + /// Interaction logic for ThreadBreakWizard.xaml + /// </summary> + public partial class ThreadBreakView : UserControl + { + public ThreadBreakView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs new file mode 100644 index 000000000..e737f3b12 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Logging; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class ThreadBreakViewVM : DialogViewVM + { + public enum ThreadBreakWizardResult + { + None, + StartThreadLoading + } + + public enum WizardStage + { + Welcome, + GuidingUnits, + FeedingUnits, + Jogging, + TheDryer, + DryerClose, + Fixed, + ContactSupport, + } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + public ThreadBreakWizardResult Result { get; set; } + + private WizardStage _stage; + public WizardStage Stage + { + get { return _stage; } + set { _stage = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _isArcHead; + public bool IsArcHead + { + get { return _isArcHead; } + set { _isArcHead = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand BackCommand { get; set; } + + //Guiding Units + public RelayCommand GuidingUnitsFoundCantFixCommand { get; set; } + public RelayCommand GuidingUnitsCantFindItCommand { get; set; } + public RelayCommand GuidingUnitsFoundAndFixedCommand { get; set; } + + //Feeding Units + public RelayCommand FeedingUnitsCantFixCommand { get; set; } + public RelayCommand FeedingUnitsFoundAndFixedCommand { get; set; } + + //The Dryer + public RelayCommand TheDryerCantRemoveCommand { get; set; } + public RelayCommand TheDryerRemovedSuccessfullyCommand { get; set; } + + //Dryer Close + public RelayCommand OpenThreadLoadingWizardCommand { get; set; } + + public ThreadBreakViewVM() + { + CanClose = true; + TangoIOC.Default.Inject(this); + + MachineProvider.MachineOperator.MachineEventsStateProvider.EventsChanged += MachineEventsStateProvider_EventsChanged; + MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; + + IsArcHead = MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc; + + BackCommand = new RelayCommand(GoBack, CanGoBack); + + //Guiding Units Commands + GuidingUnitsFoundCantFixCommand = new RelayCommand(GuidingUnitsFoundCantFix); + GuidingUnitsCantFindItCommand = new RelayCommand(GuidingUnitsCantFindIt); + GuidingUnitsFoundAndFixedCommand = new RelayCommand(GuidingUnitsFoundAndFixed); + + //Feeding Units Commands + FeedingUnitsCantFixCommand = new RelayCommand(FeedingUnitsCantFix); + FeedingUnitsFoundAndFixedCommand = new RelayCommand(FeedingUnitsFoundAndFixed); + + //The Dryer Commands + TheDryerRemovedSuccessfullyCommand = new RelayCommand(TheDryerRemovedSuccessfully); + TheDryerCantRemoveCommand = new RelayCommand(TheDryerCantRemove); + + OpenThreadLoadingWizardCommand = new RelayCommand(OpenThreadLoadingWizard, () => !MachineProvider.MachineOperator.MachineEventsStateProvider.Events.Any(x => x.Type == BL.Enumerations.EventTypes.DRYER_DOOR_OPEN)); + } + + private void MachineProvider_MachineDisconnected(object sender, EventArgs e) + { + InvokeUI(() => + { + Cancel(); + }); + } + + private void MachineEventsStateProvider_EventsChanged(object sender, IEnumerable<BL.Entities.MachinesEvent> e) + { + InvalidateRelayCommands(); + } + + #region Back + + private bool CanGoBack() + { + return Stage != WizardStage.GuidingUnits && + Stage != WizardStage.Jogging && + Stage != WizardStage.Fixed; + } + + private void GoBack() + { + switch (Stage) + { + case WizardStage.FeedingUnits: + Stage = WizardStage.GuidingUnits; + break; + case WizardStage.TheDryer: + Stage = WizardStage.GuidingUnits; + break; + case WizardStage.ContactSupport: + Stage = WizardStage.TheDryer; + break; + case WizardStage.DryerClose: + Stage = WizardStage.TheDryer; + break; + } + } + + #endregion + + #region Guiding Units Commands + + private async void GuidingUnitsFoundAndFixed() + { + Stage = WizardStage.Jogging; + + try + { + await MachineProvider.MachineOperator.AttemptThreadJogging(); + Stage = WizardStage.Fixed; + } + catch (Exception ex) + { + LogManager.Log(ex, LogCategory.Warning, "Error occurred while attempting to perform thread jogging."); + await NotificationProvider.ShowError($"Thread movement verification failed.\n{ex.FlattenMessage()}"); + Stage = WizardStage.FeedingUnits; + } + } + + private void GuidingUnitsCantFindIt() + { + Stage = WizardStage.FeedingUnits; + } + + private void GuidingUnitsFoundCantFix() + { + Stage = WizardStage.TheDryer; + } + + #endregion + + #region Feeding Units Commands + + private void FeedingUnitsCantFix() + { + Stage = WizardStage.TheDryer; + } + + private async void FeedingUnitsFoundAndFixed() + { + Stage = WizardStage.Jogging; + + try + { + await MachineProvider.MachineOperator.AttemptThreadJogging(); + Stage = WizardStage.Fixed; + } + catch (Exception ex) + { + LogManager.Log(ex, LogCategory.Warning, "Error occurred while attempting to perform thread jogging."); + await NotificationProvider.ShowError($"Thread movement verification failed.\n{ex.FlattenMessage()}"); + Stage = WizardStage.TheDryer; + } + } + + #endregion + + #region The Dryer Commands + + private void TheDryerCantRemove() + { + Stage = WizardStage.ContactSupport; + } + + private void TheDryerRemovedSuccessfully() + { + Stage = WizardStage.DryerClose; + } + + #endregion + + #region Dryer Close Commands + + private void OpenThreadLoadingWizard() + { + Result = ThreadBreakWizardResult.StartThreadLoading; + Accept(); + } + + #endregion + + protected override void Accept() + { + base.Accept(); + CleanUp(); + } + + protected override void Cancel() + { + base.Cancel(); + CleanUp(); + } + + private void CleanUp() + { + MachineProvider.MachineOperator.MachineEventsStateProvider.EventsChanged -= MachineEventsStateProvider_EventsChanged; + MachineProvider.MachineDisconnected -= MachineProvider_MachineDisconnected; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml new file mode 100644 index 000000000..e45065c61 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml @@ -0,0 +1,170 @@ +<UserControl x:Class="Tango.PPC.UI.Dialogs.ThreadLoadingView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:commonControls="clr-namespace:Tango.PPC.Common.Controls;assembly=Tango.PPC.Common" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" + mc:Ignorable="d" + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="700" Height="1150" d:DataContext="{d:DesignInstance Type=local:ThreadLoadingViewVM, IsDesignTimeCreatable=False}"> + <Grid> + <DockPanel> + <StackPanel DockPanel.Dock="Top" Margin="0 30 0 0"> + <Image HorizontalAlignment="Center" Source="/Images/thread_loading.png" Stretch="None"></Image> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoHeaderFontSize}" Margin="0 30 0 0">Thread Loading</TextBlock> + </StackPanel> + + <Grid Margin="0 20 0 0"> + <controls:NavigationControl Margin="0 5 0 0" SelectedObject="{Binding Stage}" TransitionType="Slide" TransitionAlwaysFades="False" TransitionDuration="00:00:0.1" SelectedIndex="0"> + <!--Welcome--> + <Grid controls:NavigationControl.NavigationName="Welcome" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding ContinueCommand}">Continue</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 50 0 0" > + <StackPanel DockPanel.Dock="Top"> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}">Welcome to the automatic thread loading wizard.</TextBlock> + <StackPanel HorizontalAlignment="Center" Margin="0 20 0 0"> + <touch:TouchIcon Icon="Alert" VerticalAlignment="Center" Foreground="{StaticResource TangoErrorBrush}" /> + <TextBlock TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" Margin="0 10 0 0" Width="400"> + <Run>Please ensure there are no thread residue in the system and press</Run> + <Run FontWeight="SemiBold">continue</Run> + </TextBlock> + </StackPanel> + </StackPanel> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg" VerticalAlignment="Center" Margin="50"></Image> + </DockPanel> + </DockPanel> + </Grid> + + <!--Preparing--> + <Grid controls:NavigationControl.NavigationName="Preparing" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding ContinueCommand}">Continue</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 20 0 0"> + <StackPanel VerticalAlignment="Top" DockPanel.Dock="Top" Margin="0 40 0 0"> + <TextBlock Margin="0 50 0 0" FontSize="{StaticResource TangoTitleFontSize}" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center"> + The system is now preparing... + </TextBlock> + <touch:TouchBusyIndicator Width="140" Height="140" StrokeThickness="8" IsIndeterminate="{Binding IsVisible}" Margin="0 50 0 0" Foreground="{StaticResource TangoGrayBrush}" /> + </StackPanel> + </DockPanel> + </DockPanel> + </Grid> + + <!--Ready For Loading--> + <Grid controls:NavigationControl.NavigationName="ReadyForLoading" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding ContinueCommand}">Continue</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 50 0 0"> + <StackPanel DockPanel.Dock="Top"> + <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center"> + <Run>Please select the thread type you are going to load and press</Run> + <Run FontWeight="SemiBold">continue</Run> + </TextBlock> + <touch:TouchComboBox Margin="0 40 0 0" Width="500" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRml}" DisplayMemberPath="Name" Title="Select thread type"></touch:TouchComboBox> + </StackPanel> + + <Grid> + <Grid Visibility="{Binding IsArcHead,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <touch:TouchGifAnimation Margin="50" Source="/Images/thread_loading.gif" VerticalAlignment="Center" Stretch="Uniform" EnableAnimation="{Binding IsVisible}" /> + </Grid> + + <Grid> + <commonControls:ImageGalleryControl Duration="00:00:03"> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.jpg"></Image> + <Image Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg"></Image> + </commonControls:ImageGalleryControl> + </Grid> + </Grid> + </DockPanel> + </DockPanel> + </Grid> + + <!--Finalizing--> + <Grid controls:NavigationControl.NavigationName="Finalizing" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="1" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding ContinueCommand}">Continue</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 20 0 0"> + <StackPanel VerticalAlignment="Center" DockPanel.Dock="Top"> + <TextBlock Margin="0 50 0 0" FontSize="{StaticResource TangoTitleFontSize}" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center"> + The system is now loading the thread... + </TextBlock> + <touch:TouchProgressBar Margin="50 40 50 0" Height="10" IsIndeterminate="{Binding IsVisible}" /> + </StackPanel> + + <Image VerticalAlignment="Center" Margin="50" Stretch="Uniform" Source="/Images/ThreadLoading/NewThread/machine_full.jpg"></Image> + </DockPanel> + </DockPanel> + </Grid> + + <!--Completed--> + <Grid controls:NavigationControl.NavigationName="Completed" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Center" Command="{Binding AbortCommand}">Close</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 50 0 0" > + <StackPanel DockPanel.Dock="Top"> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}">Thread loading completed successfully!</TextBlock> + <touch:TouchIcon Margin="0 40 0 0" Icon="CheckCircleOutline" HorizontalAlignment="Center" Foreground="{StaticResource TangoSuccessBrush}" Width="100" Height="100" /> + </StackPanel> + </DockPanel> + </DockPanel> + </Grid> + + <!--Preparation Error--> + <Grid controls:NavigationControl.NavigationName="PreparationError" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="2" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Left" Command="{Binding AbortCommand}">Close</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Right" Command="{Binding ContinueCommand}">Retry</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 50 0 0" > + <StackPanel DockPanel.Dock="Top"> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}">Something went wrong, press 'retry' to try again</TextBlock> + <touch:TouchIcon Icon="AlertCircleOutline" Margin="0 40 0 0" HorizontalAlignment="Center" Foreground="{StaticResource TangoErrorBrush}" Width="100" Height="100" /> + <TextBlock Margin="0 10 0 0" FontSize="{StaticResource TangoSmallFontSize}" TextAlignment="Center" TextWrapping="Wrap" HorizontalAlignment="Center" Foreground="{StaticResource TangoGrayTextBrush}" Text="{Binding Error}"></TextBlock> + </StackPanel> + </DockPanel> + </DockPanel> + </Grid> + + <!--Finalization Error--> + <Grid controls:NavigationControl.NavigationName="FinalizationError" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <DockPanel> + <UniformGrid Margin="50" Columns="2" DockPanel.Dock="Bottom" Height="55"> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Left" Command="{Binding AbortCommand}">Close</touch:TouchButton> + <touch:TouchButton Style="{StaticResource TangoHollowButton}" Width="250" HorizontalAlignment="Right" Command="{Binding ContinueCommand}">Retry</touch:TouchButton> + </UniformGrid> + <DockPanel Margin="0 50 0 0" > + <StackPanel DockPanel.Dock="Top"> + <TextBlock HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}">Something went wrong, press 'retry' to try again</TextBlock> + <touch:TouchIcon Icon="AlertCircleOutline" Margin="0 40 0 0" HorizontalAlignment="Center" Foreground="{StaticResource TangoErrorBrush}" Width="100" Height="100" /> + <TextBlock Margin="0 10 0 0" FontSize="{StaticResource TangoSmallFontSize}" TextAlignment="Center" TextWrapping="Wrap" HorizontalAlignment="Center" Foreground="{StaticResource TangoGrayTextBrush}" Text="{Binding Error}"></TextBlock> + </StackPanel> + </DockPanel> + </DockPanel> + </Grid> + </controls:NavigationControl> + + </Grid> + </DockPanel> + + <touch:TouchIconButton Command="{Binding AbortCommand}" HorizontalAlignment="Right" VerticalAlignment="Top" Icon="Close" Width="45" Height="45" Padding="14" Foreground="{StaticResource TangoDarkForegroundBrush}" /> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs new file mode 100644 index 000000000..d4c737bcc --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Dialogs +{ + /// <summary> + /// Interaction logic for PowerUpView.xaml + /// </summary> + public partial class ThreadLoadingView : UserControl + { + public ThreadLoadingView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs new file mode 100644 index 000000000..bb503e718 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs @@ -0,0 +1,287 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Integration.Operation; +using Tango.PMR.ThreadLoading; +using Tango.PPC.Common; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.Settings; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class ThreadLoadingViewVM : DialogViewVM + { + public enum ThreadLoadingStage + { + Welcome, + Preparing, + ReadyForLoading, + Finalizing, + Completed, + PreparationError, + FinalizationError, + } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + private PPCSettings _settings; + + private StartThreadLoadingResponse _status; + public StartThreadLoadingResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + private List<Rml> _rmls; + public List<Rml> Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private Rml _selectedRml; + public Rml SelectedRml + { + get { return _selectedRml; } + set { _selectedRml = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private ThreadLoadingStage _stage; + public ThreadLoadingStage Stage + { + get { return _stage; } + set { _stage = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _isArcHead; + public bool IsArcHead + { + get { return _isArcHead; } + set { _isArcHead = value; RaisePropertyChangedAuto(); } + } + + private String _error; + public String Error + { + get { return _error; } + set { _error = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand ContinueCommand { get; set; } + public RelayCommand AbortCommand { get; set; } + + public ThreadLoadingViewVM(bool userInvoked = false) + { + CanClose = false; + + TangoIOC.Default.Inject(this); + _settings = SettingsManager.Default.GetOrCreate<PPCSettings>(); + + MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; + + IsArcHead = MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc; + + ContinueCommand = new RelayCommand(Continue, CanContinue); + AbortCommand = new RelayCommand(Abort); + + AdaptToState(userInvoked); + } + + private void MachineProvider_MachineDisconnected(object sender, EventArgs e) + { + InvokeUI(() => + { + Cancel(); + }); + } + + private void AdaptToState(bool userInvoked = false) + { + var status = MachineProvider.MachineOperator.ThreadLoadingStatus; + + if (status != null) + { + if (status.State == ThreadLoadingState.Preparing) + { + Stage = ThreadLoadingStage.Preparing; + } + else if (status.State == ThreadLoadingState.ReadyForLoading) + { + Stage = ThreadLoadingStage.ReadyForLoading; + } + else if (status.State == ThreadLoadingState.Finalizing) + { + Stage = ThreadLoadingStage.Finalizing; + } + else if (status.State == ThreadLoadingState.PreparationError) + { + OnPreparationError(status.ErrorReason); + } + else if (status.State == ThreadLoadingState.FinalizationError) + { + OnFinalizationError(status.ErrorReason); + } + else if (status.State == ThreadLoadingState.Completed) + { + if (userInvoked) + { + Stage = ThreadLoadingStage.Welcome; + } + else + { + Stage = ThreadLoadingStage.Completed; + } + } + } + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, StartThreadLoadingResponse e) + { + Status = e; + AdaptToState(); + } + + private void Continue() + { + if (Stage == ThreadLoadingStage.Welcome) + { + Stage = ThreadLoadingStage.Preparing; + StartPreparing(); + } + else if (Stage == ThreadLoadingStage.ReadyForLoading) + { + ContinueThreadLoading(); + } + else if (Stage == ThreadLoadingStage.Completed) + { + Accept(); + } + else if (Stage == ThreadLoadingStage.PreparationError) + { + Stage = ThreadLoadingStage.Preparing; + StartPreparing(); + } + else if (Stage == ThreadLoadingStage.FinalizationError) + { + ContinueThreadLoading(); + } + } + + private async void StartPreparing() + { + try + { + await MachineProvider.MachineOperator.StartThreadLoading(); + } + catch (Exception ex) + { + OnPreparationError(ex.Message); + } + } + + private async void ContinueThreadLoading() + { + try + { + Stage = ThreadLoadingStage.Finalizing; + await MachineProvider.MachineOperator.ContinueThreadLoading(SelectedRml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault()); + } + catch (Exception ex) + { + OnFinalizationError(ex.Message); + } + } + + private bool CanContinue() + { + bool canContinue = false; + + if (Stage != ThreadLoadingStage.Preparing && Stage != ThreadLoadingStage.Finalizing) + { + canContinue = true; + } + + if (Stage == ThreadLoadingStage.ReadyForLoading && SelectedRml == null) + { + canContinue = false; + } + + return canContinue; + } + + private void OnPreparationError(String error) + { + Error = error; + Stage = ThreadLoadingStage.PreparationError; + } + + private void OnFinalizationError(String error) + { + Error = error; + Stage = ThreadLoadingStage.FinalizationError; + } + + private void Abort() + { + Cancel(); + } + + public async override void OnShow() + { + base.OnShow(); + + LogManager.Log("Loading site RMLS..."); + + List<Rml> rmls = new List<Rml>(); + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).WithActiveParametersGroup().BuildListAsync(); + } + + var selectedRml = rmls.SingleOrDefault(x => x.Guid == _settings.LoadedRmlGuid); + + Rmls = rmls; + SelectedRml = selectedRml != null ? selectedRml : rmls.FirstOrDefault(); + } + + protected override void Cancel() + { + CleanUp(); + base.Cancel(); + } + + protected override void Accept() + { + CleanUp(); + base.Accept(); + } + + private void CleanUp() + { + MachineProvider.MachineOperator.ThreadLoadingStatusChanged -= MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineDisconnected -= MachineProvider_MachineDisconnected; + + if (SelectedRml != null) + { + _settings.LoadedRmlGuid = SelectedRml.Guid; + _settings.Save(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml index 231f5dabb..6f70b954d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml @@ -6,21 +6,24 @@ xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" mc:Ignorable="d" - Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="550" Height="450" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="570" Height="700" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> <Grid Margin="20"> <DockPanel> - <StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal"> - <touch:TouchButton Command="{Binding CloseCommand}" CornerRadius="25" Style="{StaticResource TangoMessageBoxButton}" HorizontalContentAlignment="Center" DockPanel.Dock="Right" Width="120" Height="50" VerticalAlignment="Bottom">CANCEL</touch:TouchButton> - <touch:TouchButton Command="{Binding OKCommand}" CornerRadius="25" Style="{StaticResource TangoMessageBoxButton}" Foreground="{StaticResource TangoPrimaryAccentBrush}" HorizontalContentAlignment="Center" DockPanel.Dock="Right" Width="120" Height="50" VerticalAlignment="Bottom">UPDATE</touch:TouchButton> - </StackPanel> + <Grid DockPanel.Dock="Bottom"> + <touch:TouchButton HorizontalAlignment="Left" CornerRadius="25" Command="{Binding CloseCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">CANCEL</touch:TouchButton> + <touch:TouchButton HorizontalAlignment="Right" CornerRadius="25" Command="{Binding OKCommand}" Style="{StaticResource TangoHollowButton}" Width="150" Height="50" VerticalAlignment="Bottom">UPDATE</touch:TouchButton> + </Grid> <StackPanel> <Image Source="../Images/update.png" Stretch="Uniform" Height="120"></Image> - <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">UPDATE PACKAGE</TextBlock> + <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Tango Update Package</TextBlock> <TextBlock Margin="20 10" HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center">The selected file contains a software update package. Press 'UPDATE' to start updating your system.</TextBlock> - <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> - <Run>Version</Run> - <Run Text="{Binding Version}"></Run> + <TextBlock TextAlignment="Center" HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> + <Run FontWeight="SemiBold">Application:</Run> + <Run Text="{Binding PublishInfo.ApplicationVersion}"></Run> + <LineBreak/> + <Run FontWeight="SemiBold">Firmware:</Run> + <Run Text="{Binding FirmwareVersion,Mode=OneWay}"></Run> </TextBlock> </StackPanel> </DockPanel> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs index b9e876809..a38b0431a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs @@ -3,12 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.PPC.Common.Publish; using Tango.SharedUI; namespace Tango.PPC.UI.Dialogs { public class UpdateFromFileViewVM : DialogViewVM { - public String Version { get; set; } + public PublishInfo PublishInfo { get; set; } + + public String FirmwareVersion + { + get { return PublishInfo.GetFirmwareVersion(); } + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png Binary files differnew file mode 100644 index 000000000..b4b50e4ac --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png Binary files differnew file mode 100644 index 000000000..a0dc77f92 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png Binary files differnew file mode 100644 index 000000000..ba351ee66 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png Binary files differnew file mode 100644 index 000000000..9aa8e2db6 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png Binary files differnew file mode 100644 index 000000000..158bab095 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg Binary files differnew file mode 100644 index 000000000..3b2f58620 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg Binary files differnew file mode 100644 index 000000000..a2f5ae568 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg Binary files differnew file mode 100644 index 000000000..6069e9c29 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg Binary files differnew file mode 100644 index 000000000..7588d68e2 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG Binary files differnew file mode 100644 index 000000000..68921f1ca --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG Binary files differnew file mode 100644 index 000000000..a8b5d9ba4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG Binary files differnew file mode 100644 index 000000000..407f1eae6 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG Binary files differnew file mode 100644 index 000000000..52063b213 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg Binary files differnew file mode 100644 index 000000000..68921f1ca --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg Binary files differnew file mode 100644 index 000000000..a8b5d9ba4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg Binary files differnew file mode 100644 index 000000000..407f1eae6 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg Binary files differnew file mode 100644 index 000000000..52063b213 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg Binary files differnew file mode 100644 index 000000000..fa2c8312d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG Binary files differnew file mode 100644 index 000000000..8d58771d4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg Binary files differnew file mode 100644 index 000000000..81aa412ec --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG Binary files differnew file mode 100644 index 000000000..68921f1ca --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG Binary files differnew file mode 100644 index 000000000..a8b5d9ba4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG Binary files differnew file mode 100644 index 000000000..9f200198d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG Binary files differnew file mode 100644 index 000000000..fa2c8312d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG Binary files differnew file mode 100644 index 000000000..7956b0695 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg Binary files differnew file mode 100644 index 000000000..4ca8677cd --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg Binary files differnew file mode 100644 index 000000000..f41898bc1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg Binary files differnew file mode 100644 index 000000000..212edc547 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg Binary files differnew file mode 100644 index 000000000..d8da5726d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg Binary files differnew file mode 100644 index 000000000..a8b5d9ba4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg Binary files differnew file mode 100644 index 000000000..86dd6f397 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg Binary files differnew file mode 100644 index 000000000..9d36f3642 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg Binary files differnew file mode 100644 index 000000000..6ac67aa46 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png Binary files differnew file mode 100644 index 000000000..3a712af49 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png Binary files differnew file mode 100644 index 000000000..15be3b163 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png Binary files differnew file mode 100644 index 000000000..af3ea4850 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif Binary files differnew file mode 100644 index 000000000..793007cc4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png Binary files differnew file mode 100644 index 000000000..277599070 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif Binary files differnew file mode 100644 index 000000000..dd07593e2 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif Binary files differnew file mode 100644 index 000000000..867107140 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif Binary files differnew file mode 100644 index 000000000..f435d38d1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png Binary files differnew file mode 100644 index 000000000..e60aaf425 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif Binary files differnew file mode 100644 index 000000000..b6a974084 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png Binary files differnew file mode 100644 index 000000000..5d536e7ae --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png Binary files differnew file mode 100644 index 000000000..9bbea3368 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png Binary files differnew file mode 100644 index 000000000..c95dfa015 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs new file mode 100644 index 000000000..e960fa020 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; +using Tango.BL.Enumerations; +using Tango.PPC.Common; +using Tango.PPC.UI.Views; + +namespace Tango.PPC.UI +{ + [PPCModule(100)] + public class InternalModule : PPCModuleBase + { + public InternalModule() + { + IsVisibleInMenu = false; + } + + /// <summary> + /// Gets the module name. + /// </summary> + public override string Name + { + get + { + return "Internal"; + } + } + + /// <summary> + /// Gets the module description. + /// </summary> + public override string Description + { + get + { + return "Internal Module"; + } + } + + /// <summary> + /// Gets the module cover image. + /// </summary> + public override BitmapSource Image + { + get + { + return null; + } + } + + /// <summary> + /// Gets the module entry point view type. + /// </summary> + public override Type MainViewType + { + get + { + return typeof(InternalModuleView); + } + } + + /// <summary> + /// Gets the permission required to see and load this module. + /// </summary> + public override Permissions Permission + { + get + { + return Permissions.RunPPC; + } + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public override void Dispose() + { + //Dispose module here... + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs index b90a1afff..bf621ff2e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs @@ -61,6 +61,12 @@ namespace Tango.PPC.UI has_touch = true; } } + +#if !DEBUG + ForceTouch(); + has_touch = true; +#endif + #endif if (!has_touch) @@ -72,7 +78,7 @@ namespace Tango.PPC.UI gridMain.Height = 1280; viewBox.Child = gridMain; LockAspectRatio(); - this.SizeChanged += (x, y) => + this.SizeChanged += (x, y) => { LockAspectRatio(); }; @@ -81,6 +87,18 @@ namespace Tango.PPC.UI Closing += MainWindow_Closing; } + private void ForceTouch() + { + WindowStyle = WindowStyle.None; + ResizeMode = ResizeMode.NoResize; + WindowStartupLocation = WindowStartupLocation.Manual; + Topmost = false; // sure? + Left = 0; + Top = 0; + Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width; + Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height; + } + protected override void OnSourceInitialized(EventArgs e) { //var hwndSource = PresentationSource.FromVisual(this) as HwndSource; @@ -98,6 +116,7 @@ namespace Tango.PPC.UI private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { + e.Cancel = true; TangoIOC.Default.GetInstance<IPPCApplicationManager>().ShutDown(); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs index feb7e371f..bbabed225 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs @@ -103,7 +103,7 @@ namespace Tango.PPC.UI.Modules if (moduleAssembly != null) { - foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) + foreach (var moduleType in moduleAssembly.GetLoadableTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) { if (!AllModules.ToList().Exists(x => x.GetType() == moduleType)) { @@ -131,10 +131,14 @@ namespace Tango.PPC.UI.Modules UserModules.Clear(); - if (_authenticationProvider.CurrentUser != null) + if (_authenticationProvider.AuthenticationRequired && _authenticationProvider.CurrentUser != null) { UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection(); } + else if (!_authenticationProvider.AuthenticationRequired) + { + UserModules = AllModules.ToObservableCollection(); + } ModulesLoaded?.Invoke(this, new EventArgs()); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs index fe3cabcc1..d247ab23c 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; @@ -12,6 +13,7 @@ using Tango.Core.Commands; using Tango.PPC.Common; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Notifications; using Tango.PPC.Common.Threading; using Tango.PPC.UI.Views; using Tango.SharedUI.Controls; @@ -24,23 +26,49 @@ namespace Tango.PPC.UI.Navigation /// <seealso cref="Tango.PPC.Common.Navigation.INavigationManager" /> public class DefaultNavigationManager : ExtendedObject, INavigationManager { - private event Action<Object, Object> NavigationCycleCompleted; + //private event Action<Object, Object> NavigationCycleCompleted; + //private event Action<Object, Object> BeforeNavigationCycleCompleted; + private class AwaitingVMResult + { + public PPCViewModel FromVM { get; set; } + public PPCViewModel ToVM { get; set; } + public Action Action { get; set; } + } + private List<AwaitingVMResult> _awaitingVMResults; private IDispatcherProvider _dispatcherProvider; private IPPCModuleLoader _moduleLoader; - private Object _currentVM; + private INotificationProvider _notificationProvider; private String _lastFullPath; private bool _preventHistory; private bool _navigating_back; + public event EventHandler<PPCViewModel> CurrentVMChanged; + private Stack<String> _navigationHistory; + private Object _currentVM; /// <summary> /// Gets the current view model. /// </summary> public PPCViewModel CurrentVM { - get { return _currentVM as PPCViewModel; } + set + { + var previous = _currentVM; + _currentVM = value; + + var vm = _currentVM as PPCViewModel; + + if (_currentVM != previous && vm != null) + { + CurrentVMChanged?.Invoke(this, vm); + } + } + get + { + return _currentVM as PPCViewModel; + } } private IPPCModule _currentModule; @@ -67,10 +95,13 @@ namespace Tango.PPC.UI.Navigation /// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class. /// </summary> /// <param name="moduleLoader">The module loader.</param> - public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider) + public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider) { + IsBackEnabled = true; + _awaitingVMResults = new List<AwaitingVMResult>(); _navigationHistory = new Stack<String>(); _moduleLoader = moduleLoader; + _notificationProvider = notificationProvider; NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x)); NavigateBackCommand = new RelayCommand(async () => await NavigateBack()); @@ -113,7 +144,19 @@ namespace Tango.PPC.UI.Navigation { LogManager.Log($"Navigating to: {view.ToString()}..."); - MainView.Instance.NavigationControl.NavigateTo(view.ToString()); + + var fromView = MainView.Instance.NavigationControl.SelectedElement; + FrameworkElement toView = null; + + toView = MainView.Instance.NavigationControl.NavigateTo(view.ToString(), (Action)(() => + { + CurrentVM = toView.DataContext as PPCViewModel; + NotifyOnNavigated(fromView.DataContext, toView.DataContext); + + })); + + NotifyOnBeforeNavigated(fromView.DataContext, toView.DataContext); + return Task.FromResult(true); } } @@ -173,88 +216,155 @@ namespace Tango.PPC.UI.Navigation /// 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) + public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<PPCViewModel, PPCViewModel> onNavigating = null, Action<PPCViewModel, PPCViewModel> onNavigated = null) { - String[] path = fullPath.Split('.'); - var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); + try + { + IsNavigating = true; - if (path.Length == 1 && path[0] == CurrentModule.Name) return true; + String[] path = fullPath.Split('.'); + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); - LogManager.Log($"Navigating to: {fullPath}..."); + if (module == null) + { + await _notificationProvider.ShowError("The specified module was not loaded."); + IsNavigating = false; + return false; + } - var fromVM = _currentVM; + if (path.Length == 1 && path[0] == CurrentModule.Name) + { + IsNavigating = false; + return true; + } - if (_currentVM != null && _currentVM is INavigationBlocker) - { - if (_navigating_back) + LogManager.Log($"Navigating to: {fullPath}..."); + + var fromVM = CurrentVM; + + if (CurrentVM != null && CurrentVM is INavigationBlocker) { - if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) + if (_navigating_back) { - return false; + if (!await (CurrentVM as INavigationBlocker).OnNavigateBackRequest()) + { + IsNavigating = false; + return false; + } } - } - else - { - if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + else { - return false; + if (!await (CurrentVM as INavigationBlocker).OnNavigateOutRequest()) + { + IsNavigating = false; + return false; + } } } - } - if (pushToHistory && _lastFullPath != null && !_preventHistory) - { - _navigationHistory.Push(_lastFullPath); - RaisePropertyChanged(nameof(CanNavigateBack)); - } - _lastFullPath = fullPath; - MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); - var navigationControl = LayoutView.Instance.NavigationControl; - CurrentModule = module; - var moduleView = navigationControl.NavigateTo(module.Name); + if (pushToHistory && _lastFullPath != null && !_preventHistory) + { + _navigationHistory.Push(_lastFullPath); + RaisePropertyChanged(nameof(CanNavigateBack)); + } - _currentVM = moduleView.DataContext; + _lastFullPath = fullPath; - if (path.Length > 1) - { - var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var navigationControl = LayoutView.Instance.NavigationControl; + CurrentModule = module; + var moduleView = navigationControl.NavigateTo(module.Name); + + CurrentVM = moduleView.DataContext as PPCViewModel; - if (moduleNavigation != null) + if (path.Length > 1) { - moduleNavigation.RegisterForLoadedOrNow(async (x, e) => + var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); + + if (moduleNavigation != null) { - foreach (var view in path.Skip(1)) + moduleNavigation.RegisterForLoadedOrNow(async (x, e) => { - await Task.Delay(100); - var v = moduleNavigation.NavigateTo(view); + var lastView = moduleNavigation.GetElement(path.Last()); + + if (lastView != null) + { + onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel); + } - if (v != null) + foreach (var view in path.Skip(1)) { - _currentVM = v.DataContext; + await Task.Delay(100); + + FrameworkElement v = null; - if (view != path.Last()) + v = moduleNavigation.NavigateTo(view, () => { - moduleNavigation = v.FindChildOffline<NavigationControl>(); + if (v != null) + { + NotifyOnNavigated(fromVM, v.DataContext); + onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + } + }); + + NotifyOnBeforeNavigated(fromVM, v.DataContext); + + if (v != null) + { + CurrentVM = v.DataContext as PPCViewModel; + + if (view != path.Last()) + { + moduleNavigation = v.FindChildOffline<NavigationControl>(); + } + } + else + { + throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); } } - else - { - throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); - } - } + }); + } + else + { + onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + + NotifyOnBeforeNavigated(fromVM, CurrentVM); + + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); + + NotifyOnNavigated(fromVM, CurrentVM); - NavigationCycleCompleted?.Invoke(fromVM, _currentVM); - }); + onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + } } else { - NavigationCycleCompleted?.Invoke(fromVM, _currentVM); + NotifyOnBeforeNavigated(fromVM, CurrentVM); + + onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); + + NotifyOnNavigated(fromVM, CurrentVM); + + onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); } - } - return true; + return true; + } + catch (Exception ex) + { + IsNavigating = false; + LogManager.Log(ex, $"Error navigating to '{fullPath}'."); + await _notificationProvider.ShowError($"Error navigating to '{fullPath}'."); + return false; + } } /// <summary> @@ -267,46 +377,35 @@ namespace Tango.PPC.UI.Navigation /// <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) + public async Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true) where TModule : IPPCModule { TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>(); - var fromVM = _currentVM; - Object toVM = null; - - - Action<Object, Object> handler = null; + var fromVM = CurrentVM; - handler = (from, to) => + await NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (from, to) => { - if (toVM == null) - { - toVM = to; - if (toVM is INavigationResultProvider<TResult, TObject>) - { - (toVM as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj); - } - } - else + _awaitingVMResults.Add(new AwaitingVMResult() { - if (to == fromVM && from == toVM) + FromVM = fromVM as PPCViewModel, + ToVM = to as PPCViewModel, + Action = () => { - if (from is INavigationResultProvider<TResult, TObject>) + if (to is INavigationResultProvider<TResult, TObject>) { - source.SetResult((from as INavigationResultProvider<TResult, TObject>).GetNavigationResult()); + source.SetResult((to as INavigationResultProvider<TResult, TObject>).GetNavigationResult()); } } + }); - NavigationCycleCompleted -= handler; + if (to is INavigationResultProvider<TResult, TObject>) + { + (to as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj); } - }; - - NavigationCycleCompleted += handler; + }); - NavigateTo<TModule>(typeof(TView).Name, pushToHistory); - - return source.Task; + return await source.Task; } /// <summary> @@ -320,25 +419,13 @@ namespace Tango.PPC.UI.Navigation /// <returns></returns> public Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true) where TModule : IPPCModule { - TaskCompletionSource<bool> source = new TaskCompletionSource<bool>(); - - Action<Object, Object> handler = null; - - handler = (from, to) => + return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) => { - if (to is INavigationObjectReceiver<TPass>) + if (toVM is INavigationObjectReceiver<TPass>) { - (to as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj); + (toVM 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) @@ -361,6 +448,30 @@ namespace Tango.PPC.UI.Navigation get { return _navigationHistory.Count > 0; } } + private bool _isBackEnabled; + /// <summary> + /// Gets a value indicating whether the back should be enabled. + /// </summary> + public bool IsBackEnabled + { + get { return _isBackEnabled; } + set { _isBackEnabled = value; RaisePropertyChangedAuto(); } + } + + private bool _isNavigating; + /// <summary> + /// Gets or sets a value indicating whether the navigation system is currently navigating. + /// </summary> + public bool IsNavigating + { + get { return _isNavigating; } + set + { + _isNavigating = value; + RaisePropertyChangedAuto(); + } + } + /// <summary> /// Navigates to the previous view if <see cref="P:Tango.PPC.Common.Navigation.INavigationManager.CanNavigateBack" /> is true. /// </summary> @@ -370,24 +481,34 @@ namespace Tango.PPC.UI.Navigation _navigating_back = true; - String first = _navigationHistory.Pop(); - _preventHistory = true; - - - if (await NavigateTo(first)) + if (_navigationHistory.Count > 0) { - RaisePropertyChanged(nameof(CanNavigateBack)); - _preventHistory = false; - _navigating_back = false; - return 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; + } } else { - _navigationHistory.Push(first); + await NavigateTo(NavigationView.HomeModule); + RaisePropertyChanged(nameof(CanNavigateBack)); _preventHistory = false; _navigating_back = false; - RaisePropertyChanged(nameof(CanNavigateBack)); - return false; + return true; } } @@ -420,5 +541,48 @@ namespace Tango.PPC.UI.Navigation RaisePropertyChanged(nameof(CanNavigateBack)); } + + private void NotifyOnBeforeNavigated(object fromVM, object toVM) + { + if (fromVM == toVM) return; + + if (fromVM is PPCViewModel) + { + (fromVM as PPCViewModel)?.OnBeforeNavigatedFrom(); + } + + if (toVM is PPCViewModel) + { + (toVM as PPCViewModel)?.OnBeforeNavigatedTo(); + } + } + + private void NotifyOnNavigated(object fromVM, object toVM) + { + IsNavigating = false; + + if (fromVM == toVM) return; + + if (fromVM is PPCViewModel) + { + (fromVM as PPCViewModel)?.OnNavigatedFrom(); + } + + if (toVM is PPCViewModel) + { + (toVM as PPCViewModel)?.OnNavigatedTo(); + (toVM as PPCViewModel)?.OnNavigatedTo(fromVM as PPCViewModel); + } + } + + private void NotifyAwaitingVMResults(PPCViewModel fromVM, PPCViewModel toVM) + { + var awaiter = _awaitingVMResults.SingleOrDefault(x => x.FromVM == toVM && x.ToVM == fromVM); + if (awaiter != null) + { + _awaitingVMResults.Remove(awaiter); + awaiter.Action(); + } + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs index 65337a892..e9de2538e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs @@ -17,6 +17,8 @@ using Tango.Touch.Controls; using Tango.SharedUI; using System.Reflection; using Tango.Core.DI; +using System.ComponentModel; +using System.Windows.Data; namespace Tango.PPC.UI.Notifications { @@ -47,6 +49,16 @@ namespace Tango.PPC.UI.Notifications public ObservableCollection<NotificationItem> NotificationItems { get; private set; } /// <summary> + /// Gets the application bar items. + /// </summary> + public ObservableCollection<AppBarItem> AppBarItems { get; private set; } + + /// <summary> + /// Gets the notification items view. + /// </summary> + public ICollectionView NotificationItemsView { get; private set; } + + /// <summary> /// Gets the collection of taskbar items. /// </summary> public ObservableCollection<TaskBarItem> TaskBarItems { get; private set; } @@ -58,6 +70,10 @@ namespace Tango.PPC.UI.Notifications { NotificationsVisible = true; NotificationItems = new ObservableCollection<NotificationItem>(); + + AppBarItems = new ObservableCollection<AppBarItem>(); + CollectionViewSource.GetDefaultView(AppBarItems).SortDescriptions.Add(new SortDescription(nameof(AppBarItem.Priority), ListSortDirection.Ascending)); + TaskBarItems = new ObservableCollection<TaskBarItem>(); _pendingMessageBoxes = new ConcurrentQueue<PendingNotification<MessageBoxVM, bool>>(); _pendingDialogs = new ConcurrentQueue<PendingNotification<DialogAndView, DialogViewVM>>(); @@ -66,6 +82,9 @@ namespace Tango.PPC.UI.Notifications PopNotificationCommand = new RelayCommand<NotificationItem>((x) => PopNotification(x)); NotificationItems.EnableCrossThreadOperations(); + + NotificationItemsView = CollectionViewSource.GetDefaultView(NotificationItems); + NotificationItemsView.SortDescriptions.Add(new SortDescription(nameof(NotificationItem.Priority), ListSortDirection.Descending)); } private MessageBoxVM _currentMessageBox; @@ -322,29 +341,33 @@ namespace Tango.PPC.UI.Notifications /// <returns></returns> public async Task<T> ShowDialog<T>(T datacontext, FrameworkElement view) where T : DialogViewVM { - view.DataContext = datacontext; - - TangoIOC.Default.Inject(datacontext); + TaskCompletionSource<DialogViewVM> source = new TaskCompletionSource<DialogViewVM>(); - view.Loaded += (_, __) => + InvokeUI(() => { view.DataContext = datacontext; - datacontext.OnShow(); - }; - TaskCompletionSource<DialogViewVM> source = new TaskCompletionSource<DialogViewVM>(); + TangoIOC.Default.Inject(datacontext); - datacontext.Accepted += () => { OnDialogClosed(); source.SetResult(datacontext); }; - datacontext.Canceled += () => { OnDialogClosed(); source.SetResult(datacontext); }; + view.Loaded += (_, __) => + { + view.DataContext = datacontext; + datacontext.OnShow(); + }; - if (CurrentDialog == null) - { - CurrentDialog = view; - } - else - { - _pendingDialogs.Enqueue(new PendingNotification<DialogAndView, DialogViewVM>(new DialogAndView(datacontext, view), source)); - } + datacontext.Accepted += () => { OnDialogClosed(); source.SetResult(datacontext); }; + datacontext.Canceled += () => { OnDialogClosed(); source.SetResult(datacontext); }; + + if (CurrentDialog == null) + { + CurrentDialog = view; + } + else + { + _pendingDialogs.Enqueue(new PendingNotification<DialogAndView, DialogViewVM>(new DialogAndView(datacontext, view), source)); + } + + }); var result = await source.Task; return result as T; @@ -376,23 +399,31 @@ namespace Tango.PPC.UI.Notifications /// <returns></returns> public Task<T> ShowDialog<T>(T datacontext) where T : DialogViewVM { - var callingAssembly = datacontext.GetType().Assembly; - String viewName = datacontext.GetType().FullName.Replace("VM", ""); - var viewType = callingAssembly.GetType(viewName); + TaskCompletionSource<T> source = new TaskCompletionSource<T>(); - if (viewType == null) + InvokeUI(async () => { - throw new NullReferenceException("View type for " + datacontext.GetType().Name + " could not be found!"); - } + var callingAssembly = datacontext.GetType().Assembly; + String viewName = datacontext.GetType().FullName.Replace("VM", ""); + var viewType = callingAssembly.GetType(viewName); - var view = Activator.CreateInstance(viewType) as FrameworkElement; + if (viewType == null) + { + throw new NullReferenceException("View type for " + datacontext.GetType().Name + " could not be found!"); + } - if (view == null) - { - throw new NullReferenceException("The view " + viewType.ToString() + " is not of type framework element."); - } + var view = Activator.CreateInstance(viewType) as FrameworkElement; - return ShowDialog<T>(datacontext, view); + if (view == null) + { + throw new NullReferenceException("The view " + viewType.ToString() + " is not of type framework element."); + } + + T result = await ShowDialog<T>(datacontext, view); + source.SetResult(result); + }); + + return source.Task; } /// <summary> @@ -404,7 +435,15 @@ namespace Tango.PPC.UI.Notifications /// <returns></returns> public Task<T> ShowDialog<T>() where T : DialogViewVM { - return ShowDialog<T>(Activator.CreateInstance<T>()); + TaskCompletionSource<T> source = new TaskCompletionSource<T>(); + + InvokeUI(async () => + { + var result = await ShowDialog<T>(Activator.CreateInstance<T>()); + source.SetResult(result); + }); + + return source.Task; } /// <summary> @@ -442,22 +481,12 @@ namespace Tango.PPC.UI.Notifications /// </summary> public bool IsInGlobalBusyState { get; private set; } - private AppBarItem _currentAppBarItem; - /// <summary> - /// Gets the current application bar item. - /// </summary> - public AppBarItem CurrentAppBarItem - { - get { return _currentAppBarItem; } - set { _currentAppBarItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasAppBarItem)); } - } - /// <summary> /// Gets a value indicating whether this instance has application bar item. /// </summary> - public bool HasAppBarItem + public bool HasAppBarItems { - get { return CurrentAppBarItem != null; } + get { return AppBarItems.Count > 0; } } /// <summary> @@ -468,8 +497,9 @@ namespace Tango.PPC.UI.Notifications public AppBarItem PushAppBarItem(AppBarItem appBarItem) { LogManager.Log($"Pushing AppBarItem '{appBarItem.GetType().Name}'."); - CurrentAppBarItem = appBarItem; + AppBarItems.Add(appBarItem); appBarItem.RemoveAction = () => PopAppBarItem(appBarItem); + RaisePropertyChanged(nameof(HasAppBarItems)); return appBarItem; } @@ -478,9 +508,9 @@ namespace Tango.PPC.UI.Notifications /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> - public AppBarItem PushAppBarItem<T>() where T : AppBarItem + public T PushAppBarItem<T>() where T : AppBarItem { - return PushAppBarItem(Activator.CreateInstance<T>()); + return PushAppBarItem(Activator.CreateInstance<T>()) as T; } /// <summary> @@ -489,8 +519,12 @@ namespace Tango.PPC.UI.Notifications /// <param name="appBarItem">The application bar item.</param> public void PopAppBarItem(AppBarItem appBarItem) { - LogManager.Log($"Popping out AppBarItem '{appBarItem.GetType().Name}'."); - CurrentAppBarItem = null; + InvokeUI(() => + { + LogManager.Log($"Popping out AppBarItem '{appBarItem.GetType().Name}'."); + AppBarItems.Remove(appBarItem); + RaisePropertyChanged(nameof(HasAppBarItems)); + }); } /// <summary> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs new file mode 100644 index 000000000..9e336f276 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common.Notifications; + +namespace Tango.PPC.UI.Notifications.NotificationItems +{ + /// <summary> + /// Represents a simple text message notification item which can be inserted into the application notifications panel. + /// </summary> + /// <seealso cref="Tango.PPC.Common.Notifications.NotificationItem" /> + public class UpdateAvailableNotificationItem : NotificationItem + { + /// <summary> + /// Initializes a new instance of the <see cref="UpdateAvailableNotificationItem"/> class. + /// </summary> + public UpdateAvailableNotificationItem() + { + CanClose = true; + } + + private String _version; + /// <summary> + /// Gets or sets the message. + /// </summary> + public String Version + { + get { return _version; } + set { _version = value; RaisePropertyChangedAuto(); } + } + + private bool _isDatabaseUpdate; + /// <summary> + /// Gets or sets a value indicating whether this instance is database update. + /// </summary> + public bool IsDatabaseUpdate + { + get { return _isDatabaseUpdate; } + set { _isDatabaseUpdate = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Gets or sets the view type. + /// </summary> + public override Type ViewType + { + get { return typeof(UpdateAvailableNotificationItemView); } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml new file mode 100644 index 000000000..1d4dd6fc7 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml @@ -0,0 +1,30 @@ +<UserControl x:Class="Tango.PPC.UI.Notifications.NotificationItems.UpdateAvailableNotificationItemView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.Notifications.NotificationItems" + xmlns:common="clr-namespace:Tango.PPC.Common.Converters" + mc:Ignorable="d" + x:Name="MessageNotificationItemControl" + d:DesignHeight="60" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:UpdateAvailableNotificationItem, IsDesignTimeCreatable=False}" MinHeight="90" Height="90" MaxHeight="150" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + + <Grid> + <Border BorderThickness="0 0 0 2" BorderBrush="{StaticResource TangoPrimaryAccentBrush}" Padding="15"> + <DockPanel> + <Image Source="/Images/update_available.png" MaxHeight="50" /> + + <Grid> + <TextBlock Margin="20 0 0 0" VerticalAlignment="Center" Visibility="{Binding IsDatabaseUpdate,Converter={StaticResource BooleanToVisibilityInverseConverter}}"> + <Run>Version</Run> + <Run Foreground="{StaticResource TangoPrimaryAccentBrush}" FontWeight="SemiBold" Text="{Binding Version,FallbackValue='1.0.0.0',TargetNullValue='1.0.0.0'}"></Run> + <Run>is available!</Run> + <Run>Tap to start updating your system.</Run> + </TextBlock> + <TextBlock Margin="20 0 0 0" VerticalAlignment="Center" Text="Database updates are available. Tap to start updating your system." Visibility="{Binding IsDatabaseUpdate,Converter={StaticResource BooleanToVisibilityConverter}}"></TextBlock> + </Grid> + </DockPanel> + </Border> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs new file mode 100644 index 000000000..791d40540 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Notifications.NotificationItems +{ + /// <summary> + /// Represents the <see cref="UpdateAvailableNotificationItemView"/> view. + /// </summary> + /// <seealso cref="System.Windows.Controls.UserControl" /> + /// <seealso cref="System.Windows.Markup.IComponentConnector" /> + public partial class UpdateAvailableNotificationItemView : UserControl + { + public UpdateAvailableNotificationItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index c7351aa4a..83790a56f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -32,6 +32,10 @@ using Tango.PPC.UI.Dialogs; using Tango.Core.Threading; using Tango.PPC.Common.Messages; using Tango.Core.ExtensionMethods; +using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Synchronization; +using Tango.Insights; +using System.Threading; namespace Tango.PPC.UI.PPCApplication { @@ -49,6 +53,7 @@ namespace Tango.PPC.UI.PPCApplication private IEventLogger _eventLogger; private IPPCModuleLoader _moduleLoader; private INotificationProvider _notificationProvider; + private IMachineDataSynchronizer _machineDataSynchronizer; private WatchDogServer _watchdogServer; private ObservablesContext _machineContext; private ActionTimer _screenLockTimer; @@ -59,6 +64,11 @@ namespace Tango.PPC.UI.PPCApplication public event EventHandler SystemRestartRequired; /// <summary> + /// Occurs when the updater utility has failed to perform the last update. + /// </summary> + public event EventHandler UpdaterFailed; + + /// <summary> /// Occurs when the application has started. /// </summary> public event EventHandler ApplicationStarted; @@ -93,10 +103,15 @@ namespace Tango.PPC.UI.PPCApplication /// </summary> public bool IsShuttingDown { get; private set; } + private bool _isInTechnicianMode; /// <summary> /// Gets a value indicating whether the application is in technician mode. /// </summary> - public bool IsInTechnicianMode { get; private set; } + public bool IsInTechnicianMode + { + get { return _isInTechnicianMode; } + set { _isInTechnicianMode = value; RaisePropertyChangedAuto(); } + } /// <summary> /// Gets the application version. @@ -125,6 +140,16 @@ namespace Tango.PPC.UI.PPCApplication /// </summary> public DateTime StartUpDate { get; private set; } + /// <summary> + /// Gets a value indicating whether an update has occurred before the application started. + /// </summary> + public bool IsAfterUpdate { get; private set; } + + /// <summary> + /// Gets a value indicating whether the updater utility has failed to perform the last update. + /// </summary> + public bool IsUpdateFailed { get; private set; } + private bool _isScreenLocked; /// <summary> /// Gets or sets a value indicating whether the screen is currently locked. @@ -136,15 +161,34 @@ namespace Tango.PPC.UI.PPCApplication } /// <summary> + /// Gets the firmware version. + /// </summary> + public Version FirmwareVersion + { + get + { + return Version.Parse(SettingsManager.Default.GetOrCreate<PPCSettings>().FirmwareVersion); + } + } + + /// <summary> + /// Gets or sets the application folder. + /// </summary> + public String StartPath { get; private set; } + + /// <summary> /// Initializes a new instance of the <see cref="DefaultPPCApplicationManager"/> class. /// </summary> - public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider) + public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider, IMachineDataSynchronizer machineDataSynchronizer) { + StartPath = AssemblyHelper.GetCurrentAssemblyFolder(); + _notificationProvider = notificationProvider; _machineProvider = machineProvider; _dispatcher = dispatcherProvider; _eventLogger = eventLogger; _moduleLoader = moduleLoader; + _machineDataSynchronizer = machineDataSynchronizer; if (!DesignMode) { @@ -210,11 +254,15 @@ namespace Tango.PPC.UI.PPCApplication { LogManager.Log("Application started with '-update_ok' startup arguments. The application has been successfully updated."); - if (settings.ApplicationState == ApplicationStates.PreSetup) + if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore) { isAfterSetup = true; LogManager.Log("System restart is required."); } + else + { + IsAfterUpdate = true; + } settings.ApplicationState = ApplicationStates.Ready; settings.Save(); @@ -226,13 +274,27 @@ namespace Tango.PPC.UI.PPCApplication } } + if (App.StartupArgs.Contains("-update_failed")) + { + LogManager.Log("Application started with '-update_failed' startup arguments. The updater utility has failed."); + + IsUpdateFailed = true; + + settings.ApplicationState = ApplicationStates.Ready; + settings.Save(); + UpdaterFailed?.Invoke(this, new EventArgs()); + return; + } + if (settings.ApplicationState == ApplicationStates.Ready) { LogManager.Log("Initializing ObservablesStaticCollections..."); ObservablesStaticCollections.Instance.Initialize(); LogManager.Log("Loading machine from database..."); _machineContext = ObservablesContext.CreateDefault(); - _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithSettings().WithOrganization().WithConfiguration().WithSpools().WithCats().Build(); + _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithOrganization().WithConfiguration().WithSpools().WithCats().Build(); + + } initialized = true; @@ -276,7 +338,6 @@ namespace Tango.PPC.UI.PPCApplication { LogManager.Log($"Raising {nameof(ApplicationStarted)} event..."); - _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!"); ApplicationStarted?.Invoke(this, new EventArgs()); LogManager.Log("Invoking PPC view models OnApplicationStarted methods..."); @@ -290,6 +351,8 @@ namespace Tango.PPC.UI.PPCApplication } } + var internalModules = this.GetType().Assembly.GetTypes().Where(xx => typeof(PPCModuleBase).IsAssignableFrom(xx)).ToList(); + LogManager.Log("Waiting for IPPCModuleLoader instance injection..."); TangoIOC.Default.GetInstanceWhenAvailable<IPPCModuleLoader>((loader) => { @@ -304,12 +367,32 @@ namespace Tango.PPC.UI.PPCApplication { if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType)) { - LogManager.Log("Loading module view " + module.Name + "..."); - FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; - SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); - Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + try + { + LogManager.Log("Loading module view " + module.Name + "..."); + FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; + SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); + Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading module view for module {module.Name}."); + } } } + + //Adding internal modules. + LogManager.Log("Loading internal modules..."); + foreach (var type in internalModules) + { + var module = Activator.CreateInstance(type) as IPPCModule; + LogManager.Log("Loading module view " + module.Name + "..."); + FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; + SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); + Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + _moduleLoader.AllModules.Add(module); + _moduleLoader.UserModules.Add(module); + } }); LogManager.Log($"{loader.UserModules.Count} modules loaded."); @@ -334,6 +417,9 @@ namespace Tango.PPC.UI.PPCApplication LogManager.Log("Initializing Machine Provider..."); _machineProvider.Init(_machine, _machineContext); + LogManager.Log("Starting Machine Data Synchronizer..."); + _machineDataSynchronizer.IsEnabled = true; + LogManager.Log("Applications initialization completed!"); LogManager.Log("Checking for un-notified PPC view models..."); @@ -350,6 +436,7 @@ namespace Tango.PPC.UI.PPCApplication _dispatcher.Invoke(() => { LogManager.Log($"Invoking {nameof(ApplicationReady)} event."); + _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!"); ApplicationReady?.Invoke(this, new EventArgs()); LogManager.Log("Notifying view models about application ready..."); @@ -390,7 +477,7 @@ namespace Tango.PPC.UI.PPCApplication /// <summary> /// Shutdown the application. /// </summary> - public void ShutDown() + public async void ShutDown() { if (IsShuttingDown) return; @@ -408,13 +495,22 @@ namespace Tango.PPC.UI.PPCApplication } catch { } + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + Environment.Exit(0); } /// <summary> /// Restarts the application. /// </summary> - public void Restart() + public async void Restart() { if (IsShuttingDown) return; @@ -422,13 +518,28 @@ namespace Tango.PPC.UI.PPCApplication try { + _dispatcher.Invoke(() => + { + var nav = TangoIOC.Default.GetInstance<INavigationManager>(); + if (nav != null) + { + nav.NavigateTo(NavigationView.RestartingView); + } + }); + LogManager.Log("Restarting the application..."); + await Task.Delay(8000); + _watchdogServer.Dispose(); foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>()) { - vm.OnApplicationShuttingDown(); + try + { + vm.OnApplicationShuttingDown(); + } + catch { } } } catch { } @@ -442,6 +553,15 @@ namespace Tango.PPC.UI.PPCApplication } catch { } + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + Process.Start(Application.ResourceAssembly.Location); Environment.Exit(0); } @@ -449,25 +569,82 @@ namespace Tango.PPC.UI.PPCApplication /// <summary> /// Runs the updater utility and exits the application. /// </summary> - public void UpdateApplication(String updaterPath, String arguments) + public async void UpdateApplication(String updaterPath, String arguments) { if (IsShuttingDown) return; IsShuttingDown = true; + LogManager.Log("Restarting application for update..."); + try { - _watchdogServer.Dispose(); + LogManager.Log("Navigating to restart view..."); + _dispatcher.Invoke(() => + { + var nav = TangoIOC.Default.GetInstance<INavigationManager>(); + if (nav != null) + { + nav.NavigateTo(NavigationView.RestartingView); + } + }); + LogManager.Log("Waiting 2 seconds..."); + await Task.Delay(2000); + + try + { + LogManager.Log("Disposing watch dog..."); + _watchdogServer.Dispose(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disposing watch dog."); + } + + LogManager.Log("Raising OnApplicationShutDown for all view models..."); foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>()) { - vm.OnApplicationShuttingDown(); + try + { + vm.OnApplicationShuttingDown(); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error on {vm.GetType().Name}.OnApplicationShutDown()."); + } } } catch { } + try + { + LogManager.Log("Saving application settings..."); + SettingsManager.Default.GetOrCreate<PPCSettings>().PreviousApplicationVersion = Version.ToString(); + SettingsManager.Default.Save(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving application settings."); + } + + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + LogManager.Log($"Executing '{updaterPath}' with arguments '{arguments}'..."); - Process.Start(updaterPath, arguments); + + Process p = new Process(); + p.StartInfo.FileName = updaterPath; + p.StartInfo.Arguments = arguments; + p.StartInfo.LoadUserProfile = true; + p.StartInfo.UseShellExecute = true; + p.Start(); LogManager.Log("Terminating application..."); Environment.Exit(0); @@ -546,5 +723,48 @@ namespace Tango.PPC.UI.PPCApplication { IsScreenLocked = true; } + + public void SetWindowState(WindowState state) + { + InvokeUI(() => + { + MainWindow.Instance.WindowState = state; + }); + } + + private Task FinalizeApplication() + { + LogManager.Log("Finalizing application..."); + + return LimitedTimeTask.StartNew(() => + { + try + { + LogManager.Log("Flushing machine events..."); + _eventLogger.Log(EventTypes.APPLICATION_TERMINATED, "User Interface Terminated."); + _eventLogger.FlushAll(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error flushing machine events."); + } + + try + { + LogManager.Log("Disposing insights manager (max 40 seconds to complete)..."); + Stopwatch watch = new Stopwatch(); + watch.Start(); + var frame = InsightsFrame.CreateEmpty(DateTime.UtcNow); + InsightsManager.Default.InsertFrame(frame); + InsightsManager.Default.Dispose(); + watch.Stop(); + LogManager.Log($"Insights manager disposed after {(int)watch.Elapsed.TotalSeconds} seconds."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disposing insights manager."); + } + }, TimeSpan.FromSeconds(40)); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs index 56ec2fa7e..1f2895f26 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs @@ -259,7 +259,11 @@ namespace Tango.PPC.UI.Printing { throw new InvalidOperationException("Error starting job. Color is out of range."); } - if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.BrushColorSpace == ColorSpaces.Catalog && x.ColorCatalogsItem == null)) + if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.IsLiquidVolumesOutOfRange)) + { + throw new InvalidOperationException("Error starting job. Total ink volume is out of range."); + } + if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.BrushColorSpace == ColorSpaces.Catalog && x.ColorCatalogsItem == null && !x.IsTransparent && !x.IsWhite)) { throw new InvalidOperationException("Error starting job. Please select a catalog color."); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs index 02099e659..0540cfa9b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -8,4 +8,4 @@ using System.Windows; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Tango PPC Application")] -[assembly: AssemblyVersion("1.0.50.0")] +[assembly: AssemblyVersion("1.2.9.0")] diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs new file mode 100644 index 000000000..1b8780f91 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.Core.Threading; +using Tango.Integration.ExternalBridge; +using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Common.RemoteActions; +using Tango.PPC.Common.Threading; +using Tango.PPC.Shared.RemoteActions; + +namespace Tango.PPC.UI.RemoteActions +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteActionsService : IRemoteActionsService, IExternalBridgeRequestHandler + { + [TangoInject] + private IDispatcherProvider DispatcherProvider { get; set; } + + public DefaultRemoteActionsService(IPPCExternalBridgeService externalBridge) + { + externalBridge.RegisterRequestHandler(this); + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + //Do nothing. + } + + [ExternalBridgeRequestHandlerMethod(typeof(SimulateApplicationExceptionRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnSimulateApplicationExceptionRequest(SimulateApplicationExceptionRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new SimulateApplicationExceptionResponse(), token); + + Thread.Sleep(500); + + DispatcherProvider.Invoke(() => + { + if (request.CrashApplication) + { + App.ExceptionTrapper.Disable(); + throw new OutOfMemoryException("This is a simulated exception to cause the application to crash."); + } + else + { + throw new ApplicationException("This is a simulated exception to cause an unhandled application error."); + } + }); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml index f0e872285..d6cd842d5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml @@ -13,4 +13,6 @@ <SolidColorBrush x:Key="TangoMessageBoxHeaderSuccessBrush" Color="#F1FFF4" /> <SolidColorBrush x:Key="TangoMessageBoxHeaderQuestionBrush" Color="#DCE7FC" /> + <SolidColorBrush x:Key="TangoEmergecyScreenBackgroundBrush" Color="#FFD9E4" /> + </ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index c5045abf3..081d79f3e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -114,12 +114,23 @@ <Compile Include="..\..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="AppBarItems\PowerUpAppBarItem.cs" /> + <Compile Include="AppBarItems\PowerOffAppBarItem.cs" /> + <Compile Include="AppBarItems\PowerUpAppBarItemView.xaml.cs"> + <DependentUpon>PowerUpAppBarItemView.xaml</DependentUpon> + </Compile> + <Compile Include="AppBarItems\PowerOffAppBarItemView.xaml.cs"> + <DependentUpon>PowerOffAppBarItemView.xaml</DependentUpon> + </Compile> <Compile Include="Authentication\DefaultAuthenticationProvider.cs" /> <Compile Include="Connectivity\DefaultConnectivityProvider.cs" /> <Compile Include="Connectivity\WiFiAuthenticationView.xaml.cs"> <DependentUpon>WiFiAuthenticationView.xaml</DependentUpon> </Compile> <Compile Include="Connectivity\WiFiAuthenticationViewVM.cs" /> + <Compile Include="Controls\MachineStatusControl.xaml.cs"> + <DependentUpon>MachineStatusControl.xaml</DependentUpon> + </Compile> <Compile Include="Converters\AppBarItemConverter.cs" /> <Compile Include="Converters\ItemBaseConverter.cs" /> <Compile Include="Dialogs\CartridgeValidationView.xaml.cs"> @@ -129,6 +140,21 @@ <DependentUpon>InsufficientLiquidQuantityView.xaml</DependentUpon> </Compile> <Compile Include="Dialogs\InsufficientLiquidQuantityViewVM.cs" /> + <Compile Include="Dialogs\SafetyLevelOperationsConfirmationView.xaml.cs"> + <DependentUpon>SafetyLevelOperationsConfirmationView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\SafetyLevelOperationsConfirmationViewVM.cs" /> + <Compile Include="Dialogs\ThreadBreakView.xaml.cs"> + <DependentUpon>ThreadBreakView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\ThreadBreakViewVM.cs" /> + <Compile Include="Dialogs\ThreadLoadingView.xaml.cs"> + <DependentUpon>ThreadLoadingView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\PowerUpView.xaml.cs"> + <DependentUpon>PowerUpView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\PowerUpViewVM.cs" /> <Compile Include="Dialogs\ScreenLockView.xaml.cs"> <DependentUpon>ScreenLockView.xaml</DependentUpon> </Compile> @@ -138,21 +164,34 @@ </Compile> <Compile Include="Dialogs\ScreenLockViewVM.cs" /> <Compile Include="Dialogs\TechnicianModeLoginViewVM.cs" /> + <Compile Include="Dialogs\ThreadLoadingViewVM.cs" /> + <Compile Include="Dialogs\FirmwareUpgradeFromFileView.xaml.cs"> + <DependentUpon>FirmwareUpgradeFromFileView.xaml</DependentUpon> + </Compile> <Compile Include="Dialogs\UpdateFromFileView.xaml.cs"> <DependentUpon>UpdateFromFileView.xaml</DependentUpon> </Compile> + <Compile Include="Dialogs\FirmwareUpgradeFromFileViewVM.cs" /> <Compile Include="Dialogs\UpdateFromFileViewVM.cs" /> - <Compile Include="Modules\DefaultStudioModuleLoader.cs" /> + <Compile Include="InternalModule.cs" /> + <Compile Include="Modules\DefaultPPCModuleLoader.cs" /> <Compile Include="Navigation\DefaultNavigationManager.cs" /> <Compile Include="Notifications\DefaultNotificationProvider.cs" /> <Compile Include="Notifications\DialogAndView.cs" /> + <Compile Include="Notifications\NotificationItems\UpdateAvailableNotificationItem.cs" /> + <Compile Include="Notifications\NotificationItems\UpdateAvailableNotificationItemView.xaml.cs"> + <DependentUpon>UpdateAvailableNotificationItemView.xaml</DependentUpon> + </Compile> <Compile Include="Notifications\PendingNotification.cs" /> <Compile Include="PPCApplication\DefaultPPCApplicationManager.cs" /> <Compile Include="Printing\DefaultPrintingManager.cs" /> + <Compile Include="RemoteActions\DefaultRemoteActionsService.cs" /> <Compile Include="Threading\DefaultDispatcherProvider.cs" /> + <Compile Include="ThreadLoading\DefaultThreadLoadingService.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\EmergencyViewVM.cs" /> <Compile Include="ViewModels\ExternalBridgeViewVM.cs" /> + <Compile Include="ViewModels\InternalModuleViewVM.cs" /> <Compile Include="ViewModels\LayoutViewVM.cs" /> <Compile Include="ViewModels\LoadingErrorViewVM.cs" /> <Compile Include="ViewModels\LoadingViewVM.cs" /> @@ -161,13 +200,18 @@ <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModels\MachineUpdateViewVM.cs" /> <Compile Include="ViewModels\NoPermissionsViewVM.cs" /> + <Compile Include="ViewModels\PowerOffViewVM.cs" /> <Compile Include="ViewModels\RestartingSystemViewVM.cs" /> + <Compile Include="ViewModels\RestartingViewVM.cs" /> <Compile Include="ViewsContracts\ILayoutView.cs" /> <Compile Include="ViewsContracts\IMachineSetupView.cs" /> <Compile Include="ViewsContracts\IMachineUpdateView.cs" /> <Compile Include="Views\ExternalBridgeView.xaml.cs"> <DependentUpon>ExternalBridgeView.xaml</DependentUpon> </Compile> + <Compile Include="Views\InternalModuleView.xaml.cs"> + <DependentUpon>InternalModuleView.xaml</DependentUpon> + </Compile> <Compile Include="Views\LayoutView.xaml.cs"> <DependentUpon>LayoutView.xaml</DependentUpon> </Compile> @@ -177,6 +221,12 @@ <Compile Include="Views\LoadingErrorView.xaml.cs"> <DependentUpon>LoadingErrorView.xaml</DependentUpon> </Compile> + <Compile Include="Views\PowerOffView.xaml.cs"> + <DependentUpon>PowerOffView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\RestartingView.xaml.cs"> + <DependentUpon>RestartingView.xaml</DependentUpon> + </Compile> <Compile Include="Views\LoadingView.xaml.cs"> <DependentUpon>LoadingView.xaml</DependentUpon> </Compile> @@ -198,15 +248,43 @@ <Compile Include="Views\RestartingSystemView.xaml.cs"> <DependentUpon>RestartingSystemView.xaml</DependentUpon> </Compile> + <Page Include="AppBarItems\PowerUpAppBarItemView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="AppBarItems\PowerOffAppBarItemView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Connectivity\WiFiAuthenticationView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Controls\MachineStatusControl.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Dialogs\CartridgeValidationView.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> <Page Include="Dialogs\InsufficientLiquidQuantityView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="Dialogs\SafetyLevelOperationsConfirmationView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Dialogs\ThreadBreakView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Dialogs\ThreadLoadingView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="Dialogs\PowerUpView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> @@ -218,6 +296,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Dialogs\FirmwareUpgradeFromFileView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Dialogs\UpdateFromFileView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -234,6 +316,10 @@ <DependentUpon>MainWindow.xaml</DependentUpon> <SubType>Code</SubType> </Compile> + <Page Include="Notifications\NotificationItems\UpdateAvailableNotificationItemView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Resources\Colors.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -250,6 +336,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\InternalModuleView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\LayoutView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -262,6 +352,14 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\PowerOffView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Page Include="Views\RestartingView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> <Page Include="Views\LoadingView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -327,18 +425,59 @@ <Resource Include="Images\GlobalStatus\service_Anim.gif" /> <Resource Include="Images\GlobalStatus\shutdown_icon_Anim.gif" /> <Resource Include="Images\GlobalStatus\standby_Anim.gif" /> - <Resource Include="Images\cartridge_validation.png" /> <Resource Include="Images\bug.png" /> - <Content Include="..\..\Build\ColorLib\Debug\Tango.ColorLib_v1.dll"> - <Link>Tango.ColorLib_v1.dll</Link> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </Content> - <Content Include="..\..\Build\ColorLib\Debug\Tango.ColorLib_v2.dll"> - <Link>Tango.ColorLib_v2.dll</Link> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </Content> + <Resource Include="Images\cartridge_validation.png" /> + <Resource Include="Images\machine-image.png" /> + <Resource Include="Images\Menu\backup.png" /> + <Resource Include="Images\backup-restore.png" /> + <Resource Include="Images\restore.png" /> + <Resource Include="Images\backup-big.png" /> + <Resource Include="Images\GlobalStatus\getting-ready.png" /> + <Resource Include="Images\GlobalStatus\shutting-down.png" /> + <Resource Include="Images\GlobalStatus\error.png" /> + <Resource Include="Images\GlobalStatus\service.png" /> + <Resource Include="Images\update_available.png" /> + <Resource Include="Images\powerup.gif" /> + <Resource Include="Images\power_off.gif" /> + <Resource Include="Images\thread_loading.gif" /> + <Resource Include="Images\thread_loading.png" /> + <Resource Include="Images\firmware.png" /> + <Resource Include="Images\power_off_2.gif" /> + <Resource Include="Images\loading_anim.gif" /> + <Resource Include="Images\thread_loading_preview.png" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\1.JPG" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\2.JPG" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\3.JPG" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\4.JPG" /> + <Resource Include="Images\ThreadLoading\GuidingUnits\1.JPG" /> + <Resource Include="Images\ThreadLoading\TheDryer\1.jpg" /> + <Resource Include="Images\ThreadLoading\TheDryer\2.jpg" /> + <Resource Include="Images\ThreadLoading\TheDryer\3.jpg" /> + <Resource Include="Images\ThreadLoading\TheDryer\4.jpg" /> + <Resource Include="Images\ThreadLoading\TheDryer\5.jpg" /> + <Resource Include="Images\ThreadLoading\DryerClose\1.jpg" /> + <Resource Include="Images\ThreadLoading\DryerClose\2.jpg" /> + <Resource Include="Images\ThreadLoading\DryerClose\3.jpg" /> + <Resource Include="Images\ThreadLoading\DryerClose\4.jpg" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\arc\1.jpg" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\arc\2.jpg" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\arc\3.jpg" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\arc\4.jpg" /> + <Resource Include="Images\ThreadLoading\FeedingUnits\arc\5.jpg" /> + <Resource Include="Images\ThreadLoading\NewThread\TS1800_CloseUp_Feeder_P.jpg" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\1.jpg" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\2.JPG" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\3.JPG" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\4.JPG" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\5.JPG" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\6.JPG" /> + <Resource Include="Images\ThreadLoading\NewThread\ReadyForLoading\arc\7.jpg" /> + <Resource Include="Images\ThreadLoading\NewThread\machine_full.jpg" /> <Content Include="Manifests\release.xml" /> <Content Include="Manifests\debug.xml" /> + <None Include="firmware_package.tfp"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> <None Include="packages.config" /> <None Include="Properties\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> @@ -373,6 +512,10 @@ <Project>{4399af76-db52-4cfb-8020-6f85bdb29fd5}</Project> <Name>Tango.Explorer</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.Insights\Tango.Insights.csproj"> + <Project>{4A55C185-3F8D-41B0-8815-C15F6213A14A}</Project> + <Name>Tango.Insights</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.Integration\Tango.Integration.csproj"> <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project> <Name>Tango.Integration</Name> @@ -421,6 +564,10 @@ <Project>{6aa425c9-ea6a-4b01-aaed-5ff122e8b663}</Project> <Name>Tango.WiFi</Name> </ProjectReference> + <ProjectReference Include="..\Modules\Tango.PPC.BackupRestore\Tango.PPC.BackupRestore.csproj"> + <Project>{bc2753f8-c0f7-48f5-a85c-149ec7a2f8c7}</Project> + <Name>Tango.PPC.BackupRestore</Name> + </ProjectReference> <ProjectReference Include="..\Modules\Tango.PPC.BugReporting\Tango.PPC.BugReporting.csproj"> <Project>{8146fa0a-0725-4a1a-82e6-696c58f33a2b}</Project> <Name>Tango.PPC.BugReporting</Name> @@ -437,6 +584,10 @@ <Project>{91b70e9b-66a7-4873-ae10-400e71cf404f}</Project> <Name>Tango.PPC.MachineSettings</Name> </ProjectReference> + <ProjectReference Include="..\Modules\Tango.PPC.Maintenance\Tango.PPC.Maintenance.csproj"> + <Project>{011470ac-6bd6-4366-b5f2-c82c065d4a84}</Project> + <Name>Tango.PPC.Maintenance</Name> + </ProjectReference> <ProjectReference Include="..\Modules\Tango.PPC.Storage\Tango.PPC.Storage.csproj"> <Project>{04febb02-f782-4b96-b47d-f6902afa43be}</Project> <Name>Tango.PPC.Storage</Name> @@ -449,6 +600,40 @@ <Project>{0be74eee-22cb-4dba-b896-793b9e1a3ac0}</Project> <Name>Tango.PPC.Common</Name> </ProjectReference> + <ProjectReference Include="..\Tango.PPC.Shared\Tango.PPC.Shared.csproj"> + <Project>{208c8bd8-72c6-4e3c-acaa-351091a2acc7}</Project> + <Name>Tango.PPC.Shared</Name> + </ProjectReference> + <!--ColorLib--> + <ProjectReference Include="..\..\ColorLib\Tango.ColorLib_v4\Tango.ColorLib_v4.vcxproj"> + <Project>{E9528353-7D41-4AA8-BBAC-D65B7FE3A0D6}</Project> + <Name>Tango.ColorLib_v4</Name> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </ProjectReference> + <ProjectReference Include="..\..\ColorLib\Tango.ColorLib_v3\Tango.ColorLib_v3.vcxproj"> + <Project>{A3A8ADA0-C150-4E30-A60D-11F291FDBF7A}</Project> + <Name>Tango.ColorLib_v3</Name> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </ProjectReference> + <ProjectReference Include="..\..\ColorLib\Tango.ColorLib_v2\Tango.ColorLib_v2.vcxproj"> + <Project>{1A3FC7FB-403C-4B3D-B705-28FCE11317DD}</Project> + <Name>Tango.ColorLib_v2</Name> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </ProjectReference> + <ProjectReference Include="..\..\ColorLib\Tango.ColorLib_v1\Tango.ColorLib_v1.vcxproj"> + <Project>{CF4C66B0-CD13-4D31-8133-339A01E7E6F2}</Project> + <Name>Tango.ColorLib_v1</Name> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </ProjectReference> + <!--ColorLib--> </ItemGroup> <ItemGroup> <Resource Include="Images\liquid.png" /> @@ -504,6 +689,7 @@ <Resource Include="Images\machine-update.png" /> <Resource Include="Images\home.png" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <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"> @@ -560,6 +746,12 @@ RD /S /Q "$(TargetDir)nb-NO\" RD /S /Q "$(TargetDir)pt-BR\" RD /S /Q "$(TargetDir)roslyn\" +RD /S /Q "$(TargetDir)ProtoCompilers\" +RD /S /Q "$(TargetDir)Packages\ProtoCompilers\" +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)x86\" +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)x64\" + +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)lib\" copy /Y "$(SolutionDir)Referenced Assemblies\mscoree.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\msvcp140d.dll" "$(TargetDir)" @@ -568,12 +760,17 @@ copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\Microsoft.WITDataStore32.dll" "$(TargetDir)" -del "$(TargetDir)firmware_package.tfp" +if $(ConfigurationName) == Release del "$(TargetDir)firmware_package.tfp" + +if $(ConfigurationName) == Release del *.xml + +if $(ConfigurationName) == Release del WebRtc.NET.pdb -if $(ConfigurationName) == Release del *.xml</PostBuildEvent> +if $(ConfigurationName) == Debug copy /Y "$(TargetDir)Packages" "$(TargetDir)"</PostBuildEvent> </PropertyGroup> <PropertyGroup> - <PreBuildEvent>copy /Y "$(ProjectDir)Manifests\$(ConfigurationName).xml" "$(ProjectDir)app.manifest"</PreBuildEvent> + <PreBuildEvent>copy /Y "$(ProjectDir)Manifests\$(ConfigurationName).xml" "$(ProjectDir)app.manifest" +</PreBuildEvent> </PropertyGroup> <ProjectExtensions> <VisualStudio> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs new file mode 100644 index 000000000..a6479da63 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Operation; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.Threading; +using Tango.PPC.Common.ThreadLoading; +using Tango.PPC.UI.Dialogs; + +namespace Tango.PPC.UI.ThreadLoading +{ + public class DefaultThreadLoadingService : IThreadLoadingService + { + private INotificationProvider _notificationsProvider; + private IMachineProvider _machineProvider; + private IDispatcherProvider _dispatcher; + private bool _dialogShown; + + public DefaultThreadLoadingService(INotificationProvider notificationsProvider, IMachineProvider machineProvider, IDispatcherProvider dispatcher) + { + _notificationsProvider = notificationsProvider; + _machineProvider = machineProvider; + _dispatcher = dispatcher; + _machineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, PMR.ThreadLoading.StartThreadLoadingResponse e) + { + if (!_dialogShown && e.State != PMR.ThreadLoading.ThreadLoadingState.None) + { + _dialogShown = true; + _dispatcher.Invoke(async () => + { + await _notificationsProvider.ShowDialog<ThreadLoadingViewVM>(new ThreadLoadingViewVM()); + _dialogShown = false; + }); + } + } + + public async void StartThreadLoadingWizard() + { + _dialogShown = true; + await _notificationsProvider.ShowDialog<ThreadLoadingViewVM>(new ThreadLoadingViewVM(true)); + _dialogShown = false; + } + + public async void StartThreadBreakWizard() + { + if (!_dialogShown) + { + _dialogShown = true; + var vm = await _notificationsProvider.ShowDialog<ThreadBreakViewVM>(); + _dialogShown = false; + + if (vm.Result == ThreadBreakViewVM.ThreadBreakWizardResult.StartThreadLoading) + { + StartThreadLoadingWizard(); + } + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index 67b5dc19b..222d3a1e8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -1,26 +1,41 @@ using System; +using System.Linq; using System.Windows; using Tango.Core.DI; using Tango.Integration.ExternalBridge; using Tango.Logging; using Tango.PPC.Common.Application; using Tango.PPC.Common.Authentication; +using Tango.PPC.Common.BackupRestore; using Tango.PPC.Common.Connection; using Tango.PPC.Common.Connectivity; +using Tango.PPC.Common.Console; +using Tango.PPC.Common.DataStore; using Tango.PPC.Common.Diagnostics; using Tango.PPC.Common.EventLogging; using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Common.FileSystem; using Tango.PPC.Common.HotSpot; +using Tango.PPC.Common.Insights; using Tango.PPC.Common.MachineSetup; using Tango.PPC.Common.MachineUpdate; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; using Tango.PPC.Common.OS; +using Tango.PPC.Common.Performance; using Tango.PPC.Common.Printing; +using Tango.PPC.Common.RemoteActions; using Tango.PPC.Common.RemoteAssistance; +using Tango.PPC.Common.RemoteDesktop; +using Tango.PPC.Common.RemoteJob; +using Tango.PPC.Common.SQL; using Tango.PPC.Common.Storage; +using Tango.PPC.Common.Synchronization; +using Tango.PPC.Common.SystemInfo; using Tango.PPC.Common.Threading; +using Tango.PPC.Common.ThreadLoading; +using Tango.PPC.Common.UpdatePackages; using Tango.PPC.Common.UWF; using Tango.PPC.Common.Web; using Tango.PPC.UI.Authentication; @@ -30,7 +45,9 @@ using Tango.PPC.UI.Navigation; using Tango.PPC.UI.Notifications; using Tango.PPC.UI.PPCApplication; using Tango.PPC.UI.Printing; +using Tango.PPC.UI.RemoteActions; using Tango.PPC.UI.Threading; +using Tango.PPC.UI.ThreadLoading; using Tango.PPC.UI.ViewModels; using Tango.PPC.UI.Views; using Tango.PPC.UI.ViewsContracts; @@ -71,8 +88,30 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister<IUnifiedWriteFilterManager>(); TangoIOC.Default.Unregister<IOperationSystemManager>(); TangoIOC.Default.Unregister<PPCWebClient>(); + TangoIOC.Default.Unregister<IBackupManager>(); + TangoIOC.Default.Unregister<IPackageRunner>(); + TangoIOC.Default.Unregister<IMachineDataSynchronizer>(); + TangoIOC.Default.Unregister<IConsoleEngineService>(); + TangoIOC.Default.Unregister<IRemoteDesktopService>(); + TangoIOC.Default.Unregister<IPerformanceService>(); + TangoIOC.Default.Unregister<ISystemInfoService>(); + TangoIOC.Default.Unregister<IFileSystemService>(); + TangoIOC.Default.Unregister<IRemoteJobService>(); + TangoIOC.Default.Unregister<IRemoteSqlService>(); + TangoIOC.Default.Unregister<IInsightsService>(); + TangoIOC.Default.Unregister<IRemoteActionsService>(); + TangoIOC.Default.Unregister<IThreadLoadingService>(); + TangoIOC.Default.Unregister<IDataStoreService>(); + + if (App.StartupArgs != null && App.StartupArgs.Contains("-webDebug")) + { + TangoIOC.Default.Register<PPCWebClient, PPCWebClient>(new PPCWebClient("http://localhost:1111", null)); + } + else + { + TangoIOC.Default.Register<PPCWebClient, PPCWebClient>(new PPCWebClient()); + } - TangoIOC.Default.Register<PPCWebClient, PPCWebClient>(new PPCWebClient()); TangoIOC.Default.Register<IDispatcherProvider, DefaultDispatcherProvider>(new DefaultDispatcherProvider(Application.Current.Dispatcher)); TangoIOC.Default.Register<INotificationProvider, DefaultNotificationProvider>(); TangoIOC.Default.Register<IAuthenticationProvider, DefaultAuthenticationProvider>(); @@ -80,11 +119,14 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>(); TangoIOC.Default.Register<IMachineProvider, DefaultMachineProvider>(); TangoIOC.Default.Register<IEventLogger, DefaultEventLogger>(); + TangoIOC.Default.Register<IMachineDataSynchronizer, DefaultMachineDataSynchronizer>(); TangoIOC.Default.Register<IPPCApplicationManager, DefaultPPCApplicationManager>(); TangoIOC.Default.Register<ExternalBridgeScanner, ExternalBridgeScanner>(); TangoIOC.Default.Register<IDiagnosticsFrameProvider, DefaultDiagnosticsFrameProvider>(); TangoIOC.Default.Register<IPPCExternalBridgeService, PPCExternalBridgeService>(); + TangoIOC.Default.Register<IConsoleEngineService, DefaultConsoleEngineService>(); TangoIOC.Default.Register<IRemoteAssistanceProvider, DefaultRemoteAssistanceProvider>(); + TangoIOC.Default.Register<IPackageRunner, DefaultPackageRunner>(); TangoIOC.Default.Register<IMachineSetupManager, MachineSetupManager>(); TangoIOC.Default.Register<IMachineUpdateManager, MachineUpdateManager>(); TangoIOC.Default.Register<IPrintingManager, DefaultPrintingManager>(); @@ -93,8 +135,17 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<IStorageProvider, DefaultStorageProvider>(); TangoIOC.Default.Register<IUnifiedWriteFilterManager, AlternativeUnifiedWriteFilterManager>(); TangoIOC.Default.Register<IOperationSystemManager, DefaultOperationSystemManager>(); - - //TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); + TangoIOC.Default.Register<IBackupManager, DefaultBackupManager>(); + TangoIOC.Default.Register<IPerformanceService, DefaultPerformanceService>(); + TangoIOC.Default.Register<ISystemInfoService, DefaultSystemInfoService>(); + TangoIOC.Default.Register<IFileSystemService, DefaultFileSystemService>(); + TangoIOC.Default.Register<IRemoteDesktopService, DefaultRemoteDesktopService>(); + TangoIOC.Default.Register<IRemoteJobService, DefaultRemoteJobService>(); + TangoIOC.Default.Register<IRemoteSqlService, DefaultRemoteSqlService>(); + TangoIOC.Default.Register<IInsightsService, DefaultInsightsService>(); + TangoIOC.Default.Register<IRemoteActionsService, DefaultRemoteActionsService>(); + TangoIOC.Default.Register<IThreadLoadingService, DefaultThreadLoadingService>(); + TangoIOC.Default.Register<IDataStoreService, DefaultDataStoreService>(); TangoIOC.Default.Register<LoadingViewVM>(); TangoIOC.Default.Register<MainViewVM>(); @@ -107,6 +158,9 @@ namespace Tango.PPC.UI TangoIOC.Default.Register<NoPermissionsViewVM>(); TangoIOC.Default.Register<RestartingSystemViewVM>(); TangoIOC.Default.Register<EmergencyViewVM>(); + TangoIOC.Default.Register<RestartingViewVM>(); + TangoIOC.Default.Register<InternalModuleViewVM>(); + TangoIOC.Default.Register<PowerOffViewVM>(); TangoIOC.Default.GetInstance<IPPCApplicationManager>().ContentRendered += (_, __) => @@ -212,5 +266,29 @@ namespace Tango.PPC.UI return TangoIOC.Default.GetInstance<EmergencyViewVM>(); } } + + public static RestartingViewVM RestartingViewVM + { + get + { + return TangoIOC.Default.GetInstance<RestartingViewVM>(); + } + } + + public static InternalModuleViewVM InternalModuleViewVM + { + get + { + return TangoIOC.Default.GetInstance<InternalModuleViewVM>(); + } + } + + public static PowerOffViewVM PowerOffViewVM + { + get + { + return TangoIOC.Default.GetInstance<PowerOffViewVM>(); + } + } } }
\ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs index f1127ebfe..f10e84d05 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs @@ -12,6 +12,7 @@ using Tango.PMR.Integration; using Tango.PPC.Common; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.Navigation; +using Tango.PPC.UI.Dialogs; namespace Tango.PPC.UI.ViewModels { @@ -24,6 +25,8 @@ namespace Tango.PPC.UI.ViewModels { private bool _disconnecting; + private const int KEEP_SAFETY_AUTHENTICATION_MINUTES = 5; + #region Properties private ExternalBridgeClientConnectedEventArgs _connection; @@ -79,7 +82,7 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log("Disconnecting current external bridge session."); _disconnecting = true; InvalidateRelayCommands(); - ExternalBridgeService.DisconnectSession(); + ExternalBridgeService.DisconnectFullControlSession(); } #endregion @@ -103,7 +106,7 @@ namespace Tango.PPC.UI.ViewModels public override void OnApplicationStarted() { ExternalBridgeService.ConnectionRequest += ExternalBridgeService_ConnectionRequest; - ExternalBridgeService.ClientDisconnected += ExternalBridgeService_ClientDisconnected; + ExternalBridgeService.FullControlSessionDisconnected += ExternalBridgeService_FullControlSessionDisconnected; } #endregion @@ -111,11 +114,11 @@ namespace Tango.PPC.UI.ViewModels #region Event Handlers /// <summary> - /// Handles the <see cref="ExternalBridgeService.ClientDisconnected"/> event. + /// Handles the <see cref="ExternalBridgeService.FullControlSessionDisconnected"/> event. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> - private void ExternalBridgeService_ClientDisconnected(object sender, EventArgs e) + private void ExternalBridgeService_FullControlSessionDisconnected(object sender, EventArgs e) { if (IsVisible) { @@ -133,13 +136,14 @@ namespace Tango.PPC.UI.ViewModels /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="ExternalBridgeClientConnectedEventArgs"/> instance containing the event data.</param> - private void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e) + private async void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e) { LogManager.Log($"External bridge connection request received.\n{e.ToJsonString()}"); if (!e.Request.Intent.RequiresPassword() || e.Request.Password == Settings.ExternalBridgePassword) { - e.Confirmed = true; + e.ApplicationInformation.Version = ApplicationManager.Version.ToString(); + e.ApplicationInformation.StartupDate = ApplicationManager.StartUpDate.ToUniversalTime().ToString(); Connection = e; @@ -150,6 +154,41 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log($"External bridge connection user has been identified as {User.Contact.FullName}"); } + if (e.Request.RequireSafetyLevelOperations) + { + DateTime lastAuthenticationTime; + bool bypassSafetyConfirmation = false; + + if (ExternalBridgeReceiver.LastSafetyLevelContactsTimes.TryGetValue(e.Request.UserName, out lastAuthenticationTime)) + { + if (DateTime.Now < lastAuthenticationTime.AddMinutes(KEEP_SAFETY_AUTHENTICATION_MINUTES)) + { + bypassSafetyConfirmation = true; + e.Confirm(); + } + } + + if (!bypassSafetyConfirmation) + { + SafetyLevelOperationsConfirmationViewVM vm = new SafetyLevelOperationsConfirmationViewVM(e); + await NotificationProvider.ShowDialog(vm); + + if (vm.DialogResult) + { + e.Confirm(); + } + else + { + e.Decline("Safety level connection refused by the remote user."); + return; + } + } + } + else + { + e.Confirm(); + } + if (e.Request.Intent == ExternalBridgeLoginIntent.FullControl) { LogManager.Log("Navigating to external bridge view..."); @@ -161,6 +200,7 @@ namespace Tango.PPC.UI.ViewModels } else { + e.Decline("Connection password did not match the machine external bridge password."); LogManager.Log("Connection password did not match the machine external bridge password."); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs new file mode 100644 index 000000000..29e6417f4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; + +namespace Tango.PPC.UI.ViewModels +{ + public class InternalModuleViewVM : PPCViewModel + { + public override void OnApplicationStarted() + { + + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs index 9e8a9fe34..a2baec8b8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs @@ -3,13 +3,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; using System.Windows.Threading; +using Tango.Core; using Tango.Core.Commands; using Tango.Core.DI; using Tango.Integration.Operation; +using Tango.PMR.IFS; using Tango.PPC.Common; +using Tango.PPC.Common.Connection; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; +using Tango.PPC.UI.Views; using Tango.PPC.UI.ViewsContracts; using Tango.SharedUI; @@ -22,6 +28,7 @@ namespace Tango.PPC.UI.ViewModels public class LayoutViewVM : PPCViewModel<ILayoutView> { private JobHandler _jobHandler; + private bool _resettingDevice; /// <summary> /// Gets or sets the module loader. @@ -29,6 +36,86 @@ namespace Tango.PPC.UI.ViewModels [TangoInject] public IPPCModuleLoader ModuleLoader { get; set; } + #region Classes + + public class CartridgeModel : ExtendedObject + { + private IMachineProvider _machineProvider; + + public CartridgeStatus Status { get; set; } + + public bool InProgress + { + get { return Status.State == CartridgeState.Filling || Status.State == CartridgeState.Emptying; } + } + + public String Message + { + get { return Status.Cartridge.Slot == PMR.Diagnostics.CartridgeSlot.Ink ? "Ink filling is in progress..." : "Waste emptying is in progress..."; } + } + + public Brush Brush + { + get + { + if (Status.Cartridge.Slot == PMR.Diagnostics.CartridgeSlot.Ink) + { + try + { + int index = Status.Cartridge.Index; + + var idsPack = _machineProvider.Machine.Configuration.NoneEmptyIdsPacks.FirstOrDefault(x => x.PackIndex == index); + + if (idsPack != null) + { + switch (idsPack.LiquidType.Type) + { + case BL.Enumerations.LiquidTypes.Cyan: + return Application.Current.Resources["TangoCyanInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Magenta: + return Application.Current.Resources["TangoMagentaInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Yellow: + return Application.Current.Resources["TangoYellowInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Black: + return Application.Current.Resources["TangoBlackInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Lubricant: + return Application.Current.Resources["TangoLubricantBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Cleaner: + return Application.Current.Resources["TangoCleanerBrush"] as Brush; + case BL.Enumerations.LiquidTypes.TransparentInk: + return Application.Current.Resources["TangoTransparentInkBrush"] as Brush; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating ink filling brush."); + } + + return Application.Current.Resources["TangoPrimaryAccentBrush"] as Brush; + } + else + { + return Application.Current.Resources["TangoWasteBrush"] as Brush; + } + } + } + + public CartridgeModel(IMachineProvider machineProvider) + { + _machineProvider = machineProvider; + Status = new CartridgeStatus(); + } + + public void Invalidate() + { + RaisePropertyChanged(nameof(InProgress)); + RaisePropertyChanged(nameof(Status)); + } + } + + #endregion + #region Properties private bool _isMenuOpened; @@ -72,6 +159,23 @@ namespace Tango.PPC.UI.ViewModels set { _isPowerOpened = value; RaisePropertyChangedAuto(); } } + private bool _isInkFillingOrWasteEmptying; + /// <summary> + /// Gets or sets a value indicating whether ink filling or waste emptying is active. + /// </summary> + public bool IsInkFillingOrWasteEmptying + { + get { return _isInkFillingOrWasteEmptying; } + set { _isInkFillingOrWasteEmptying = value; RaisePropertyChangedAuto(); } + } + + private List<CartridgeModel> _cartridges; + public List<CartridgeModel> Cartridges + { + get { return _cartridges; } + set { _cartridges = value; RaisePropertyChangedAuto(); } + } + #endregion #region Commands @@ -121,6 +225,21 @@ namespace Tango.PPC.UI.ViewModels /// </summary> public RelayCommand RestartApplicationCommand { get; set; } + /// <summary> + /// Gets or sets the power off command. + /// </summary> + public RelayCommand PowerOffCommand { get; set; } + + /// <summary> + /// Gets or sets the reset command. + /// </summary> + public RelayCommand ResetCommand { get; set; } + + /// <summary> + /// Gets or sets the stand by command. + /// </summary> + public RelayCommand StandByCommand { get; set; } + #endregion #region Constructors @@ -137,15 +256,13 @@ namespace Tango.PPC.UI.ViewModels StopPrintingCommand = new RelayCommand(StopPrinting); SignOutCommand = new RelayCommand(SignOut); - UpdateCommand = new RelayCommand(() => - { - NavigationManager.NavigateTo(NavigationView.MachineUpdateView); - TangoIOC.Default.GetInstance<MachineUpdateViewVM>().CheckForUpdates(); - IsMenuOpened = false; - }); + UpdateCommand = new RelayCommand(UpdateMachine); PowerCommand = new RelayCommand(() => IsPowerOpened = true); RestartApplicationCommand = new RelayCommand(RestartApplication); + PowerOffCommand = new RelayCommand(PowerOffMachine, () => MachineProvider.MachineOperator.Status != MachineStatuses.Disconnected); + ResetCommand = new RelayCommand(ResetMachine, () => MachineProvider.MachineOperator.Status != MachineStatuses.Disconnected); + StandByCommand = new RelayCommand(StandBy, () => MachineProvider.MachineOperator.CanPrint); } #endregion @@ -239,6 +356,83 @@ namespace Tango.PPC.UI.ViewModels } } + /// <summary> + /// Powers off the machine. + /// </summary> + private async void PowerOffMachine() + { + IsMenuOpened = false; + + if (await NotificationProvider.ShowQuestion("Are you sure you wish to turn off the machine?")) + { + try + { + await MachineProvider.MachineOperator.PowerDown(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error triggering power down."); + await NotificationProvider.ShowError(ex.FlattenMessage()); + } + } + } + + /// <summary> + /// Resets the machine. + /// </summary> + private async void ResetMachine() + { + IsMenuOpened = false; + + if (!await NotificationProvider.ShowQuestion("Are you sure you want to reset the machine?")) return; + + try + { + _resettingDevice = true; + ResetCommand.RaiseCanExecuteChanged(); + await MachineProvider.MachineOperator.Reset(); + await NotificationProvider.ShowInfo("Machine was successfully restarted."); + } + catch (Exception ex) + { + await NotificationProvider.ShowError(ex.FlattenMessage()); + } + finally + { + _resettingDevice = false; + ResetCommand.RaiseCanExecuteChanged(); + } + } + + private async void StandBy() + { + IsMenuOpened = false; + + try + { + LogManager.Log("Executing stand-by command."); + await MachineProvider.MachineOperator.StandBy(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error switching to stand-by mode."); + await NotificationProvider.ShowError($"Error switching to stand-by mode.\n{ex.FlattenMessage()}"); + } + } + + private void UpdateMachine() + { + if (MachineProvider.MachineOperator.IsPrinting) + { + NotificationProvider.ShowInfo("Cannot perform a machine update while the machine is dyeing."); + return; + } + + NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + TangoIOC.Default.GetInstance<MachineUpdateViewVM>().CheckForUpdates(); + IsMenuOpened = false; + } + #endregion #region Override Methods @@ -250,6 +444,34 @@ namespace Tango.PPC.UI.ViewModels { base.OnApplicationStarted(); MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted; + MachineProvider.MachineOperator.InkFillingStatusChanged += MachineOperator_InkFillingStatusChanged; + } + + private void MachineOperator_InkFillingStatusChanged(object sender, InkFillingStatusChangedEventArgs e) + { + if (Cartridges == null) + { + Cartridges = MachineProvider.MachineOperator.InkFillingStatus.CartridgesStatuses.Select(x => new CartridgeModel(MachineProvider) { Status = x }).ToList(); + } + else + { + foreach (var cartridgeStatus in e.Status.CartridgesStatuses) + { + var model = Cartridges.SingleOrDefault(x => x.Status == cartridgeStatus); + + if (model != null) + { + model.Status = cartridgeStatus; + } + } + } + + foreach (var cartridgeModel in Cartridges) + { + cartridgeModel.Invalidate(); + } + + IsInkFillingOrWasteEmptying = Cartridges.Any(x => x.Status.State == CartridgeState.Filling || x.Status.State == CartridgeState.Emptying); } /// <summary> @@ -260,6 +482,22 @@ namespace Tango.PPC.UI.ViewModels } + public override void OnApplicationReady() + { + base.OnApplicationReady(); + MachineProvider.MachineOperator.StatusChanged += MachineOperator_StatusChanged; + } + + private void MachineOperator_StatusChanged(object sender, MachineStatuses e) + { + InvokeUI(() => + { + PowerOffCommand.RaiseCanExecuteChanged(); + ResetCommand.RaiseCanExecuteChanged(); + StandByCommand.RaiseCanExecuteChanged(); + }); + } + #endregion #region Public Methods diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs index f926a0f4c..38dd569e1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs @@ -74,37 +74,46 @@ namespace Tango.PPC.UI.ViewModels /// </summary> public async override void OnApplicationStarted() { - using (ObservablesContext db = ObservablesContext.CreateDefault()) - { - var machine = await db.Machines.FirstAsync(); + //We don't use authentication! - if (db.Users.Count() == 1 || machine.AutoLogin) - { - var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); + //using (ObservablesContext db = ObservablesContext.CreateDefault()) + //{ + // var machine = await db.Machines.FirstAsync(); - if (!user.HasRole(Roles.PPCUser)) - { - var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); - user.Roles.Add(role); - db.UsersRoles.Add(new BL.Entities.UsersRole() - { - User = user, - Role = role, - }); - await db.SaveChangesAsync(); - } + // if (db.Users.Count() == 1 || machine.AutoLogin) + // { + // var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); - LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); - await AuthenticationProvider.Login(user.Email, user.Password, false); - IsLoading = false; - } - else - { - LogManager.Log("Application started. Navigating to LoginView..."); - await NavigationManager.NavigateTo(NavigationView.LoginView); - IsLoading = false; - } - } + // if (!user.HasRole(Roles.PPCUser)) + // { + // var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); + // user.Roles.Add(role); + // db.UsersRoles.Add(new BL.Entities.UsersRole() + // { + // User = user, + // Role = role, + // }); + // await db.SaveChangesAsync(); + // } + + // LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); + // await AuthenticationProvider.Login(user.Email, user.Password, false); + // await Task.Delay(1000); + // IsLoading = false; + // } + // else + // { + // LogManager.Log("Application started. Navigating to LoginView..."); + // await NavigationManager.NavigateTo(NavigationView.LoginView); + // await Task.Delay(1000); + // IsLoading = false; + // } + //} + + LogManager.Log($"Application started with no authentication mode..."); + await AuthenticationProvider.Login(); + await Task.Delay(1000); + IsLoading = false; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs index aa9689ef3..ec316989f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs @@ -92,7 +92,13 @@ namespace Tango.PPC.UI.ViewModels await Task.Delay(500); - if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) + if (!AuthenticationProvider.AuthenticationRequired) + { + LogManager.Log("Application is ready! Navigating to home module..."); + await NavigationManager.NavigateTo(NavigationView.HomeModule); + IsLoading = false; + } + else if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) { LogManager.Log("Application is ready! Navigating to home module..."); await NavigationManager.NavigateTo(NavigationView.HomeModule); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs index aca9dbcf7..ae31a64a1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs @@ -347,7 +347,10 @@ namespace Tango.PPC.UI.ViewModels try { - _ppcWebClient.Environment = DeploymentSlot; + if (!App.StartupArgs.Contains("-webDebug")) + { + _ppcWebClient.Environment = DeploymentSlot; + } await _operationSystemManager.ChangeTimeZone(SelectedTimeZone); _setup_result = await MachineSetupManager.Setup(SerialNumber); State = MachineSetupStates.Completed; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs index 01e67d3ce..5fe153ee9 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -1,22 +1,38 @@ using System; using System.Collections.Generic; +using System.Data.Entity; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Tango.BL; +using Tango.Core; using Tango.Core.Commands; +using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; +using Tango.Core.Threading; using Tango.Explorer; +using Tango.Integration.ExternalBridge; +using Tango.PMR.FirmwareUpgrade; using Tango.PPC.Common; +using Tango.PPC.Common.Application; +using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.MachineUpdate; +using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.Publish; using Tango.PPC.Common.Web; +using Tango.PPC.Shared.RemoteUpgrade; using Tango.PPC.UI.Dialogs; +using Tango.PPC.UI.Notifications.NotificationItems; using Tango.PPC.UI.ViewsContracts; +using Tango.Transport; namespace Tango.PPC.UI.ViewModels { - public class MachineUpdateViewVM : PPCViewModel<IMachineUpdateView> + public class MachineUpdateViewVM : PPCViewModel<IMachineUpdateView>, IExternalBridgeRequestHandler { public enum MachineUpdateView { @@ -36,6 +52,7 @@ namespace Tango.PPC.UI.ViewModels private DbCompareResult _db_compare_result; private bool _isChecking; private CheckForUpdateResponse _checkUpdateResponse; + private UpdateAvailableNotificationItem _updateNotificationItem; #region Properties @@ -107,9 +124,10 @@ namespace Tango.PPC.UI.ViewModels #region Constructors - public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager) + public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager, IPPCExternalBridgeService externalBridge, IPPCApplicationManager applicationManager, INavigationManager navigationManager, INotificationProvider notificationProvider) { MachineUpdateManager = machineUpdateManager; + externalBridge.RegisterRequestHandler(this); CompleteCommand = new RelayCommand(CompleteUpdate); UpdateCommand = new RelayCommand(Update); @@ -125,6 +143,13 @@ namespace Tango.PPC.UI.ViewModels NavigationManager.NavigateTo(Common.Navigation.NavigationView.HomeModule); NavigateTo(MachineUpdateView.UpdateCheckView); }); + + machineUpdateManager.UpdateAvailable += MachineUpdateManager_UpdateAvailable; + + NavigationManager = navigationManager; + NotificationProvider = notificationProvider; + ApplicationManager = applicationManager; + ApplicationManager.UpdaterFailed += ApplicationManager_UpdaterFailed; } #endregion @@ -150,7 +175,28 @@ namespace Tango.PPC.UI.ViewModels return; } - var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber); + var response = await MachineUpdateManager.CheckForUpdate(); + + try + { + if (response.UsedNotExistingRmlsGuids.Count > 0) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + var arr = response.UsedNotExistingRmlsGuids.ToArray(); + var jobs = await db.Jobs.Where(x => arr.Contains(x.RmlGuid)).ToListAsync(); + FailedError = $"The following jobs must be removed or change thread type before the system can be updated:\n{String.Join("\n", jobs.Select(x => x.Name))}"; + _isChecking = false; + await NavigateTo(MachineUpdateView.UpdateFailedView); + return; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error on used RML check procedure."); + } + _checkUpdateResponse = response; if (response.IsUpdateAvailable) @@ -158,9 +204,19 @@ namespace Tango.PPC.UI.ViewModels LatestVersion = response.Version; await NavigateTo(MachineUpdateView.UpdateAvailableView); } + else if (response.IsDatabaseUpdateAvailable) + { + IsDbUpdate = true; + _db_compare_result = new DbCompareResult() + { + RequiresUpdate = true, + UpdateDBResponse = response.UpdateDBResponse + }; + await NavigateTo(MachineUpdateView.UpdateAvailableView); + } else { - _db_compare_result = await MachineUpdateManager.UpdateDBCheck(MachineProvider.Machine.SerialNumber); + _db_compare_result = await MachineUpdateManager.UpdateDBCheck(); if (_db_compare_result.RequiresUpdate) { @@ -195,7 +251,7 @@ namespace Tango.PPC.UI.ViewModels try { - _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, _checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); + _update_result = await MachineUpdateManager.Update(_checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); LogManager.Log("Machine update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -213,7 +269,7 @@ namespace Tango.PPC.UI.ViewModels try { - await MachineUpdateManager.UpdateDB(_db_compare_result, MachineProvider.Machine.SerialNumber); + await MachineUpdateManager.UpdateDB(_db_compare_result); LogManager.Log("Database update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -234,15 +290,15 @@ namespace Tango.PPC.UI.ViewModels { LogManager.Log("Completing machine update..."); - if (!IsDbUpdate) + if (IsDbUpdate || !_update_result.RequiresBinariesUpdate) { - String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); - ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); + LogManager.Log("Restarting Application..."); + ApplicationManager.Restart(); } else { - LogManager.Log("Restarting Application..."); - ApplicationManager.Restart(); + String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); + ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); } } @@ -275,15 +331,100 @@ namespace Tango.PPC.UI.ViewModels base.OnApplicationReady(); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Update.Extension, HandleSoftwareUpdatePackageLoaded); + StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Firmware.Extension, HandleFirmwareUpgradeLoaded); + + if (ApplicationManager.IsAfterUpdate) + { + RunPostUpdatePackages(); + } + else + { + MachineUpdateManager.EnableAutoCheckForUpdates = true; + } + } + + /// <summary> + /// Called when the navigation system has navigated to this VM view. + /// </summary> + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (_updateNotificationItem != null) + { + _updateNotificationItem.Close(); + _updateNotificationItem = null; + } + } + + #endregion + + #region Post Update Packages + + private async void RunPostUpdatePackages() + { + await Task.Delay(1000); + + LogManager.Log("Application was loaded after an update. Checking for required post-update packages..."); + + bool required = false; + + try + { + required = await MachineUpdateManager.PostUpdatePackagesRequired(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error checking for post-update packages."); + } + + if (required) + { + LogManager.Log("Post-update packages found and needs to be installed. Navigating to machine update and running post-update packages..."); + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + try + { + var result = await MachineUpdateManager.RunPostUpdatePackages(); + + LogManager.Log("Post-update packages installed successfully."); + + await Task.Delay(2000); + + if (result.RestartRequired) + { + LogManager.Log("Restart required. Restarting..."); + ApplicationManager.Restart(); + } + else + { + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.LayoutView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while running post-update packages."); + } + } + else + { + LogManager.Log("No post-update packages installation required."); + } } #endregion #region Handle USB Update - private async void HandleSoftwareUpdatePackageLoaded(ExplorerFileItem fileItem) + private async void HandleSoftwareUpdatePackageLoaded(List<ExplorerFileItem> fileItems) { - UpdatePackageFile packageFile = null; + var fileItem = fileItems.FirstOrDefault(); + + if (fileItem == null) return; + + PublishInfo packageFile = null; + + LogManager.Log("TUP file loaded from storage..."); try { @@ -291,43 +432,394 @@ namespace Tango.PPC.UI.ViewModels } catch (Exception ex) { - LogManager.Log(ex, $"Error loading update package file from {fileItem.Path}."); + LogManager.Log(ex, $"Error loading publish info from {fileItem.Path}."); await NotificationProvider.ShowError("An error occurred while trying to load the selected software update package. Please make sure the package is valid."); return; } - if (ApplicationManager.Version <= packageFile.Version) + UpdateFromFileViewVM vm = new UpdateFromFileViewVM(); + vm.PublishInfo = packageFile; + + LogManager.Log($"TUP publish info:\n{packageFile.ToJson()}"); + + LogManager.Log("Displaying TUP update dialog..."); + + await NotificationProvider.ShowDialog(vm); + + if (vm.DialogResult) { - await NotificationProvider.ShowError($"The selected update package (v{packageFile.Version.ToString()}) contains an older software version."); + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting machine update from package..."); + + try + { + _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path, MachineProvider.Machine.SetupFirmware, MachineProvider.Machine.SetupFpga); + LogManager.Log("Machine update from package completed."); + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Machine update from package failed."); + FailedError = ex.FlattenMessage(); + await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + } + } + } + + private async void HandleFirmwareUpgradeLoaded(List<ExplorerFileItem> fileItems) + { + var fileItem = fileItems.FirstOrDefault(); + + if (fileItem == null) return; + + LogManager.Log("TFP file loaded from storage..."); + + VersionPackageDescriptor packageInfo; + FirmwareUpgradeFromFileViewVM vm = new FirmwareUpgradeFromFileViewVM(); + + try + { + using (FileStream st = File.OpenRead(fileItem.Path)) + { + packageInfo = await MachineProvider.MachineOperator.GetFirmwarePackageInfo(st); + } + + packageInfo.Validate(); + + vm.Version = packageInfo.GetMcuVersion().ToString(); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading package info from {fileItem.Path}."); + await NotificationProvider.ShowError($"An error occurred while trying to load the selected firmware upgrade package.\n{ex.FlattenMessage()}"); return; } - UpdateFromFileViewVM vm = new UpdateFromFileViewVM(); - vm.Version = packageFile.Version.ToString(); + + LogManager.Log($"TFP publish info:\n{packageInfo.ToJsonString()}"); + + LogManager.Log("Displaying TFP update dialog..."); await NotificationProvider.ShowDialog(vm); if (vm.DialogResult) { await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); - await NavigateTo(MachineUpdateView.UpdateFromPackageView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting firmware upgrade from package..."); + + try + { + await MachineUpdateManager.UpdateFromTFP(fileItem.Path); + LogManager.Log("Firmware upgrade from package completed."); + _update_result = new MachineUpdateResult() + { + RequiresBinariesUpdate = false, + }; + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Firmware upgrade from package failed."); + FailedError = ex.FlattenMessage(); + await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + } + } + } + + #endregion + + #region Auto Check For Update + + private void MachineUpdateManager_UpdateAvailable(object sender, CheckForUpdateResponse e) + { + if (!IsVisible && _updateNotificationItem == null) + { + LogManager.Log($"New {(e.IsDatabaseUpdateAvailable ? "database updates" : "application version")} detected ({e.Version}). Pushing notification..."); + + InvokeUI(() => + { + _updateNotificationItem = new UpdateAvailableNotificationItem(); + _updateNotificationItem.Version = Version.Parse(e.Version).ToString(3); + _updateNotificationItem.IsDatabaseUpdate = e.IsDatabaseUpdateAvailable && !e.IsUpdateAvailable; + _updateNotificationItem.Pressed += (_, __) => + { + if (MachineProvider.MachineOperator.IsPrinting) + { + NotificationProvider.ShowInfo("Cannot perform a machine update while the machine is dyeing."); + return; + } + + _updateNotificationItem = null; + + if (!IsVisible) + { + LogManager.Log("Update available notification pressed. Navigating to update view..."); + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + CheckForUpdates(); + } + }; + _updateNotificationItem.Closed += (_, __) => + { + _updateNotificationItem = null; + }; + NotificationProvider.PushNotification(_updateNotificationItem); + }); + } + } + + #endregion + + #region Updater Failed + + private void ApplicationManager_UpdaterFailed(object sender, EventArgs e) + { + InvokeUI(async () => + { + try + { + await NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + await MachineUpdateManager.RestoreLastDatabaseBackup(); + await Task.Delay(5000); + ApplicationManager.Restart(); + } + catch (Exception ex) + { + await NotificationProvider.ShowError($"Could not restore the application to its previous state.\n{ex.FlattenMessage()}"); + ApplicationManager.Restart(); + } + }); + } + + #endregion + + #region External Bridge Handler + + [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteApplicationUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnStartRemoteApplicationUpgradeRequest(StartRemoteApplicationUpgradeRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse(), token); + + bool stopReporting = false; + + try + { + ThreadFactory.StartNew(async () => + { + while (!stopReporting) + { + if (MachineUpdateManager.Status != null) + { + try + { + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse() + { + Progress = new TangoProgress<double>() + { + Message = MachineUpdateManager.Status.Message, + IsIndeterminate = MachineUpdateManager.Status.IsIntermediate, + Maximum = MachineUpdateManager.Status.Total, + Value = MachineUpdateManager.Status.Progress + }, + }, token, new TransportResponseConfig() { Priority = QueuePriority.Low }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending remote upgrade progress."); + } + } + + Thread.Sleep(500); + } + }); + + InvokeUI(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + NavigateTo(MachineUpdateView.UpdateProgressView); + }); LogManager.Log("Starting machine update from package..."); try { - _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path); + _update_result = await MachineUpdateManager.UpdateFromTUP(request.RemoteTupFilePath, request.SetupFirmware, request.SetupFPGA); LogManager.Log("Machine update from package completed."); - await NavigateTo(MachineUpdateView.UpdateCompletedView); + stopReporting = true; + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateCompletedView); + }); } catch (Exception ex) { LogManager.Log(ex, "Machine update from package failed."); - await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + FailedError = ex.FlattenMessage(); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + }); + + throw ex; + } + + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse() + { + Progress = new TangoProgress<double>("Completed", false, 100, 100), + }, token, new TransportResponseConfig() + { + Completed = true + }); + + try + { + File.Delete(request.RemoteTupFilePath); + } + catch { } + + await Task.Delay(2000); + + CompleteUpdate(); + } + catch (Exception ex) + { + stopReporting = true; + await receiver.SendErrorResponse(ex, token); + } + finally + { + stopReporting = true; + + try + { + File.Delete(request.RemoteTupFilePath); } + catch { } } } + [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteFirmwareUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnStartRemoteFirmwareUpgradeRequest(StartRemoteFirmwareUpgradeRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse(), token); + + bool stopReporting = false; + + try + { + ThreadFactory.StartNew(async () => + { + while (!stopReporting) + { + if (MachineUpdateManager.Status != null) + { + try + { + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse() + { + Progress = new TangoProgress<double>() + { + Message = MachineUpdateManager.Status.Message, + IsIndeterminate = MachineUpdateManager.Status.IsIntermediate, + Maximum = MachineUpdateManager.Status.Total, + Value = MachineUpdateManager.Status.Progress + } + }, token, new TransportResponseConfig() { Priority = QueuePriority.Low }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending remote upgrade progress."); + } + } + + Thread.Sleep(500); + } + }); + + InvokeUI(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + NavigateTo(MachineUpdateView.UpdateProgressView); + }); + + LogManager.Log("Starting firmware upgrade from package..."); + + try + { + await MachineUpdateManager.UpdateFromTFP(request.RemoteTfpFilePath); + stopReporting = true; + LogManager.Log("Firmware upgrade from package completed."); + _update_result = new MachineUpdateResult() + { + RequiresBinariesUpdate = false, + }; + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateCompletedView); + }); + } + catch (Exception ex) + { + stopReporting = true; + + LogManager.Log(ex, "Firmware upgrade from package failed."); + FailedError = ex.FlattenMessage(); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + }); + + throw ex; + } + + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse() + { + Progress = new TangoProgress<double>("Completed", false, 100, 100), + }, token, new TransportResponseConfig() + { + Completed = true + }); + + try + { + File.Delete(request.RemoteTfpFilePath); + } + catch { } + + await Task.Delay(2000); + + CompleteUpdate(); + } + catch (Exception ex) + { + stopReporting = true; + await receiver.SendErrorResponse(ex, token); + } + finally + { + stopReporting = true; + + try + { + File.Delete(request.RemoteTfpFilePath); + } + catch { } + } + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + //Do Nothing. + } + #endregion } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs index 01a47539e..05fb610c8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs @@ -4,6 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Threading; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; using Tango.Core.DI; using Tango.Integration.ExternalBridge; using Tango.Integration.Operation; @@ -17,6 +20,8 @@ using Tango.PPC.Common.Notifications; using Tango.PPC.Common.WatchDog; using Tango.PPC.UI.Dialogs; using Tango.SharedUI; +using System.Data.Entity; +using Tango.PPC.UI.AppBarItems; namespace Tango.PPC.UI.ViewModels { @@ -27,6 +32,10 @@ namespace Tango.PPC.UI.ViewModels public class MainViewVM : PPCViewModel { private DispatcherTimer _date_timer; + private bool _isPowerUpDialogShown; + private bool _isThreadLoadingShown; + private PowerUpAppBarItem _powerUpAppBar; + private bool _started; private DateTime _currentDateTime; /// <summary> @@ -58,8 +67,53 @@ namespace Tango.PPC.UI.ViewModels { base.OnApplicationReady(); MachineProvider.MachineOperator.CartridgeValidationRequestReceived += MachineOperator_CartridgeValidationRequestReceived; + MachineProvider.MachineOperator.FirmwareStarted += MachineOperator_FirmwareStarted; + MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineOperator.ThreadLoadingConfirmationRequired += MachineOperator_ThreadLoadingConfirmationRequired; + + MachineProvider.MachineOperator.PowerUpStarted += MachineOperator_PowerUpStarted; + MachineProvider.MachineOperator.PowerUpProgress += MachineOperator_PowerUpProgress; + MachineProvider.MachineOperator.PowerUpEnded += MachineOperator_PowerUpEnded; + } + + #region Power Up + + private void MachineOperator_PowerUpEnded(object sender, EventArgs e) + { + _started = false; + _powerUpAppBar?.Close(); + _powerUpAppBar = null; + } + + private void MachineOperator_PowerUpProgress(object sender, PMR.Power.StartPowerUpResponse status) + { + if (_powerUpAppBar != null) + { + _powerUpAppBar.Status = status; + } + } + + private void MachineOperator_PowerUpStarted(object sender, PMR.Power.StartPowerUpResponse e) + { + _started = true; + + InvokeUI(() => + { + if (_powerUpAppBar != null) + { + _powerUpAppBar.Close(); + } + + if (_started) + { + _powerUpAppBar = NotificationProvider.PushAppBarItem<PowerUpAppBarItem>(); + _powerUpAppBar.Priority = AppBarPriority.Low; + } + }); } + #endregion + #region Event Handlers /// <summary> @@ -92,6 +146,106 @@ namespace Tango.PPC.UI.ViewModels }); } + private async void MachineOperator_FirmwareStarted(object sender, EventArgs e) + { + if (_isPowerUpDialogShown) + { + LogManager.Log("Power up detected but power up dialog is already shown. Skipping..."); + return; + } + + LogManager.Log("Power up detected, showing power up screen..."); + + if (!Settings.DisplayPowerUpScreen) + { + LogManager.Log("Power up screen disabled. skipping..."); + return; + } + + PowerUpViewVM vm; + + try + { + LogManager.Log("Loading site rmls..."); + + List<Rml> rmls = new List<Rml>(); + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildListAsync(); + } + + var selectedRml = rmls.SingleOrDefault(x => x.Guid == Settings.LoadedRmlGuid); + + vm = new PowerUpViewVM(); + vm.Rmls = rmls; + vm.SelectedRml = selectedRml != null ? selectedRml : rmls.FirstOrDefault(); + vm.IsSelectedRml = selectedRml != null; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error initializing power up screen."); + return; + } + + InvokeUI(async () => + { + _isPowerUpDialogShown = true; + await NotificationProvider.ShowDialog<PowerUpViewVM>(vm); + _isPowerUpDialogShown = false; + + await Task.Factory.StartNew(() => + { + LogManager.Log("Power up screen closed."); + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + List<ProcessParametersTable> processTables = new List<ProcessParametersTable>(); + + if (vm.IsSelectedRml) + { + LogManager.Log($"Selected rml '{vm.SelectedRml.Name}'..."); + processTables = new RmlBuilder(db).Set(vm.SelectedRml.Guid).WithActiveParametersGroup().Build().GetActiveProcessGroup().ProcessParametersTables.ToList(); + } + else + { + LogManager.Log("Selected minimal temperature..."); + var rmlsToAvg = new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).WithActiveParametersGroup().Build(); + processTables = rmlsToAvg.Select(x => x.GetActiveProcessGroup()).SelectMany(x => x.ProcessParametersTables).ToList(); + } + + var processToLoad = processTables.OrderBy(x => x.GetAverageTemperature()).First(); + + LogManager.Log($"Selected process parameters:\nRML: {processToLoad.ProcessParametersTablesGroup.Rml.Name}\nGroup: {processToLoad.ProcessParametersTablesGroup.Name}\nProcess Table: {processToLoad.Name}"); + LogManager.Log("Uploading process parameters..."); + var r = MachineProvider.MachineOperator.UploadProcessParameters(processToLoad).Result; + + Settings.LoadedRmlGuid = vm.IsSelectedRml ? vm.SelectedRml.Guid : null; + Settings.Save(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to get and upload the proper process parameters after power screen closed."); + } + }); + }); + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, PMR.ThreadLoading.StartThreadLoadingResponse e) + { + //if (e.State == PMR.ThreadLoading.ThreadLoadingState.Preparing) + //{ + // DisplayThreadLoading(); + //} + } + + private void MachineOperator_ThreadLoadingConfirmationRequired(object sender, ThreadLoadingConfirmationRequiredEventArgs e) + { +// DisplayThreadLoading(e); + } #endregion } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs new file mode 100644 index 000000000..e3ab7d111 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Integration.Operation; +using Tango.PMR.Power; +using Tango.PPC.Common; +using Tango.PPC.UI.AppBarItems; +using Tango.PPC.UI.Views; + +namespace Tango.PPC.UI.ViewModels +{ + public class PowerOffViewVM : PPCViewModel + { + private PowerDownHandler _handler; + private PowerOffAppBarItem _appBarItem; + private int _abortTries; + + private StartPowerDownResponse _status; + public StartPowerDownResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand AbortCommand { get; set; } + + public PowerOffViewVM() + { + _appBarItem = new PowerOffAppBarItem(); + _appBarItem.Pressed += (x, e) => + { + NavigationManager.NavigateTo<InternalModule>(nameof(PowerOffView)); + }; + AbortCommand = new RelayCommand(AbortPowerOff); + } + + public override void OnApplicationStarted() + { + + } + + public override void OnApplicationReady() + { + base.OnApplicationReady(); + MachineProvider.MachineOperator.PowerDownStarted += MachineOperator_PowerDownStarted; + } + + private void MachineOperator_PowerDownStarted(object sender, PowerDownStartedEventArgs e) + { + _abortTries = 0; + _handler = e.Handler; + + _handler.StatusChanged += OnStatusChanged; + _handler.Failed += OnFailed; + _handler.Completed += OnCompleted; + + InvokeUI(async () => + { + await NavigationManager.NavigateTo<InternalModule>(nameof(PowerOffView)); + NotificationProvider.PushAppBarItem(_appBarItem); + }); + } + + private void OnStatusChanged(object sender, PowerDownStatusChangedEventArgs e) + { + Status = e.Status; + _appBarItem.Status = Status; + } + + private void OnCompleted(object sender, EventArgs e) + { + InvokeUI(async () => + { + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + }); + } + + private void OnFailed(object sender, Exception ex) + { + InvokeUI(async () => + { + await NotificationProvider.ShowError($"An error occurred while powering off the machine.\n{ex.FlattenMessage()}"); + + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + }); + } + + private async void AbortPowerOff() + { + try + { + NotificationProvider.SetGlobalBusyMessage("Aborting machine power off..."); + await _handler.Abort(); + await NavigationManager.NavigateBack(); + NotificationProvider.PopAppBarItem(_appBarItem); + } + catch (Exception ex) + { + _abortTries++; + LogManager.Log(ex, "Power down abort error."); + NotificationProvider.ReleaseGlobalBusyMessage(); + await NotificationProvider.ShowError($"An error occurred while trying to abort the power off sequence.\n{ex.FlattenMessage()}"); + + if (_abortTries > 2) + { + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + } + } + finally + { + NotificationProvider.ReleaseGlobalBusyMessage(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs new file mode 100644 index 000000000..46111031b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; + +namespace Tango.PPC.UI.ViewModels +{ + public class RestartingViewVM : PPCViewModel + { + public override void OnApplicationStarted() + { + + } + + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + } + + public override void OnNavigatedFrom() + { + base.OnNavigatedFrom(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml index dfc70e602..f2b018bfa 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml @@ -9,12 +9,18 @@ xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:EmergencyViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.EmergencyViewVM}"> - <Grid> + <Grid Background="{StaticResource TangoEmergecyScreenBackgroundBrush}"> <DockPanel Margin="20 60 20 20"> - <StackPanel DockPanel.Dock="Top"> - <Image Source="../Images/warning-red.png" Width="300" Stretch="Uniform" HorizontalAlignment="Center"></Image> - <TextBlock HorizontalAlignment="Center" Margin="0 40 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Emergency Switch Activated</TextBlock> - <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoTitleFontSize}">Please release the emergency switch to exit this screen.</TextBlock> + <StackPanel DockPanel.Dock="Top" HorizontalAlignment="Center"> + <touch:TouchIcon Icon="Alert" Width="120" Height="120" Foreground="{StaticResource TangoErrorBrush}" HorizontalAlignment="Center"></touch:TouchIcon> + <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" Foreground="{StaticResource TangoErrorBrush}" FontSize="{StaticResource TangoHeaderFontSize}" FontWeight="SemiBold">EMERGENCY PUSH BUTTON PRESSED</TextBlock> + <TextBlock Margin="0 60 0 0" FontWeight="SemiBold" FontSize="24">How to handle:</TextBlock> + <Rectangle Margin="0 20 240 5" StrokeThickness="1" Stroke="{StaticResource TangoGrayBrush}" /> + <TextBlock Margin="0 8 0 0" FontSize="{StaticResource TangoTitleFontSize}">1. Verify that it is safe to restart the system.</TextBlock> + <TextBlock Margin="0 8 0 0" FontSize="{StaticResource TangoTitleFontSize}">2. Release the emergency button.</TextBlock> + <TextBlock Margin="0 8 0 0" FontSize="{StaticResource TangoTitleFontSize}">3. Press the power button to power up the system.</TextBlock> + + <Image Source="../Images/machine-image.png" Width="500" HorizontalAlignment="Left" Margin="0 150 0 0" /> </StackPanel> </DockPanel> </Grid> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml index d83128007..fddd15fe7 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml @@ -7,18 +7,23 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:localControls="clr-namespace:Tango.PPC.UI.Controls" xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:ExternalBridgeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ExternalBridgeViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> <Grid> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> - <Grid HorizontalAlignment="Center"> - <Image Source="/Images/machine-trans.png" Stretch="None" RenderOptions.BitmapScalingMode="Fant"></Image> - <touch:TouchIcon Icon="Wifi" Foreground="{StaticResource TangoGreenBrush}" Width="30" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 25 30"> + <Grid HorizontalAlignment="Center" VerticalAlignment="Center" > + <Ellipse Stroke="{StaticResource TangoDarkForegroundBrush}" Width="50" Height="50"/> + <localControls:MachineStatusControl Margin="0 0 0 -1" VerticalAlignment="Center" DataContext="{Binding MachineProvider.MachineOperator}" /> + </Grid> + <Grid HorizontalAlignment="Center" Margin="0 20 0 0"> + <Image Source="/Images/machine.png" Stretch="None" RenderOptions.BitmapScalingMode="Fant"></Image> + <touch:TouchIcon Icon="Wifi" Foreground="{StaticResource TangoGreenBrush}" Width="30" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 40 45"> <touch:TouchIcon.Style> <Style TargetType="touch:TouchIcon"> <Style.Triggers> - <DataTrigger Binding="{Binding ExternalBridgeService.IsInSession}" Value="True"> + <DataTrigger Binding="{Binding ExternalBridgeService.HasSessions}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard x:Name="Blink"> <Storyboard> @@ -43,8 +48,8 @@ <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0 50 0 0" FontSize="{StaticResource TangoTitleFontSize}">This machine is currently being controlled by a remote client</TextBlock> <controls:TableGrid Margin="0 30 0 0" HorizontalAlignment="Center" RowHeight="30" Width="280"> - <TextBlock FontWeight="Bold">IP Address:</TextBlock> - <TextBlock Text="{Binding Connection.IpAddress}"></TextBlock> + <TextBlock FontWeight="Bold">Address:</TextBlock> + <TextBlock Text="{Binding Connection.Address}"></TextBlock> <TextBlock FontWeight="Bold">Host Name:</TextBlock> <TextBlock Text="{Binding Connection.Request.HostName}"></TextBlock> @@ -57,7 +62,7 @@ <TextBlock FontWeight="Bold" Text="Transfer Rate:" /> <TextBlock> - <Run Text="{Binding ExternalBridgeService.Adapter.TransferRate,Converter={StaticResource ByteArrayToFileSizeConverter},Mode=OneWay}"></Run> + <Run Text="{Binding ExternalBridgeService.FullControlSessionReceiver.Adapter.TransferRate,Converter={StaticResource ByteArrayToFileSizeConverter},Mode=OneWay}"></Run> <Run Text="/ sec"></Run> </TextBlock> </controls:TableGrid> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml new file mode 100644 index 000000000..88981a9fa --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml @@ -0,0 +1,18 @@ +<UserControl x:Class="Tango.PPC.UI.Views.InternalModuleView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Tango.PPC.UI.Views" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" + xmlns:global="clr-namespace:Tango.PPC.UI" + mc:Ignorable="d" + d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:InternalModuleViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.InternalModuleViewVM}"> + <Grid> + <controls:NavigationControl TransitionType="Zoom" KeepElementsAttached="True"> + <local:PowerOffView/> + </controls:NavigationControl> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml.cs new file mode 100644 index 000000000..f67d16dd9 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Views +{ + /// <summary> + /// Interaction logic for InternalModuleView.xaml + /// </summary> + public partial class InternalModuleView : UserControl + { + public InternalModuleView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml index 890d3863b..3e1f50e41 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml @@ -14,6 +14,7 @@ xmlns:commonControls="clr-namespace:Tango.PPC.Common.Controls;assembly=Tango.PPC.Common" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:components="clr-namespace:Tango.Touch.Components;assembly=Tango.Touch" + xmlns:locaControls="clr-namespace:Tango.PPC.UI.Controls" xmlns:keyboard="clr-namespace:Tango.Touch.Keyboard;assembly=Tango.Touch" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LayoutViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LayoutViewVM}"> @@ -129,6 +130,21 @@ <Border Background="{StaticResource TangoPowerMenuOpenedBackgroundBrush}" Height="350" Padding="20" RenderTransformOrigin="0.5,1" VerticalAlignment="Bottom"> + <Border.Resources> + <Style x:Key="PowerButton" TargetType="touch:TouchButton" BasedOn="{StaticResource TangoLinkButton}"> + <Setter Property="Foreground" Value="{StaticResource TangoPrimaryBackgroundBrush}"></Setter> + <Setter Property="FontSize" Value="{StaticResource TangoTitleFontSize}"></Setter> + <Setter Property="HorizontalAlignment" Value="Left"></Setter> + <Setter Property="VerticalAlignment" Value="Center"></Setter> + <Setter Property="Padding" Value="50 20"></Setter> + <Setter Property="Height" Value="Auto"></Setter> + <Style.Triggers> + <Trigger Property="IsEnabled" Value="False"> + <Setter Property="Foreground" Value="{StaticResource TangoGrayBrush}"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </Border.Resources> <Border.Style> <Style TargetType="Border"> <Setter Property="RenderTransform"> @@ -158,7 +174,7 @@ </Border.Style> <Grid> <Grid.RowDefinitions> - <RowDefinition Height="1*"/> + <RowDefinition Height="1.4*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> @@ -170,9 +186,10 @@ <Image Source="/Images/power-machine.png" Margin="30" /> - <UniformGrid Grid.Column="1" Rows="2"> - <touch:TouchButton HorizontalAlignment="Left" VerticalAlignment="Center" Padding="50 20" Height="Auto" Style="{StaticResource TangoLinkButton}" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoPrimaryBackgroundBrush}">Turn Off</touch:TouchButton> - <touch:TouchButton HorizontalAlignment="Left" VerticalAlignment="Center" Padding="50 20" Height="Auto" Style="{StaticResource TangoLinkButton}" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoPrimaryBackgroundBrush}">Stand By</touch:TouchButton> + <UniformGrid Grid.Column="1" Rows="3"> + <touch:TouchButton Style="{StaticResource PowerButton}" Command="{Binding PowerOffCommand}">Turn Off</touch:TouchButton> + <touch:TouchButton Style="{StaticResource PowerButton}" Command="{Binding StandByCommand}">Stand By</touch:TouchButton> + <touch:TouchButton Style="{StaticResource PowerButton}" Command="{Binding ResetCommand}">Reset</touch:TouchButton> </UniformGrid> </Grid> @@ -185,7 +202,7 @@ </Grid.ColumnDefinitions> <Image Source="/Images/power-tablet.png" Margin="30" /> - <touch:TouchButton Command="{Binding RestartApplicationCommand}" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="50 20" Height="Auto" Style="{StaticResource TangoLinkButton}" Foreground="{StaticResource TangoPrimaryBackgroundBrush}" FontSize="{StaticResource TangoTitleFontSize}">Restart</touch:TouchButton> + <touch:TouchButton Command="{Binding RestartApplicationCommand}" Grid.Column="1" Style="{StaticResource PowerButton}">Restart</touch:TouchButton> </Grid> </Grid> </Border> @@ -232,20 +249,21 @@ <touch:TouchNotificationBar NotificationBarVisibility="{Binding NotificationProvider.NotificationsVisible,Converter={StaticResource BooleanToVisibilityConverter}}" - HasNotifications="{Binding NotificationProvider.HasNotificationItems}" - Notifications="{Binding NotificationProvider.NotificationItems}" - ItemExpandedPropertyPath="IsExpanded"> + HasNotifications="{Binding NotificationProvider.HasNotificationItems}" Notifications="{Binding NotificationProvider.NotificationItems}"> <touch:TouchNotificationBar.NotificationTemplate> <DataTemplate> <components:Ripple Padding="0"> <Grid Background="Transparent"> - <i:Interaction.Triggers> - <i:EventTrigger EventName="PreviewMouseUp"> - <i:InvokeCommandAction Command="{Binding PressedCommand}" /> - </i:EventTrigger> - </i:Interaction.Triggers> - <ContentControl Content="{Binding Converter={StaticResource ItemBaseConverter}}"/> - <touch:TouchIconButton Visibility="{Binding CanClose,Converter={StaticResource BooleanToVisibilityConverter}}" DockPanel.Dock="Right" Background="Transparent" Padding="35" Style="{StaticResource TangoRoundTouchIconButton}" Command="{Binding CloseCommand}" CommandParameter="{Binding}" HorizontalAlignment="Right" MaxHeight="90" Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}" Icon="Close" Foreground="{StaticResource TangoDarkForegroundBrush}" /> + <touch:TouchClickableControl Command="{Binding PressedCommand}"> + <ContentControl Content="{Binding Converter={StaticResource ItemBaseConverter}}"/> + </touch:TouchClickableControl> + <Grid Width="40" HorizontalAlignment="Right" VerticalAlignment="Stretch" Visibility="{Binding CanClose,Converter={StaticResource BooleanToVisibilityConverter}}"> + <Grid Margin="0 0 20 0" HorizontalAlignment="Right" VerticalAlignment="Center" Width="18" Height="18"> + <!--<Ellipse Fill="Black" StrokeThickness="1" Stroke="{StaticResource TangoDarkForegroundBrush}" />--> + <touch:TouchIcon Icon="Close" Foreground="Black" /> + </Grid> + <touch:TouchButton Opacity="0" Background="Red" Style="{StaticResource TangoFlatButton}" Command="{Binding CloseCommand}" CommandParameter="{Binding}" Foreground="{StaticResource TangoPrimaryBackgroundBrush}" Padding="5" /> + </Grid> </Grid> </components:Ripple> </DataTemplate> @@ -254,46 +272,13 @@ <Border BorderThickness="0 0 0 1" BorderBrush="{StaticResource TangoDividerBrush}" DockPanel.Dock="Top"> <DockPanel> <Border BorderThickness="0 0 1 0" BorderBrush="{StaticResource TangoDividerBrush}"> - <touch:TouchHamburgerButton Width="100" Height="100" Padding="15" Command="{Binding MenuOrBackCommand}" EnableDropShadow="False" Foreground="{StaticResource TangoPrimaryAccentBrush}" IsBack="{Binding NavigationManager.CanNavigateBack}"> + <touch:TouchHamburgerButton IsHitTestVisible="{Binding NavigationManager.IsNavigating,Converter={StaticResource BooleanInverseConverter}}" IsEnabled="{Binding NavigationManager.IsBackEnabled}" Width="100" Height="100" Padding="15" Command="{Binding MenuOrBackCommand}" EnableDropShadow="False" Foreground="{StaticResource TangoPrimaryAccentBrush}" IsBack="{Binding NavigationManager.CanNavigateBack}"/> - </touch:TouchHamburgerButton> </Border> <Grid DockPanel.Dock="Right" Margin="0 0 20 0"> <StackPanel Orientation="Horizontal"> <StackPanel x:Name="techPressElement" VerticalAlignment="Center" Background="Transparent"> - <touch:TouchGifAnimation Width="36" HorizontalAlignment="Center" EnableAnimation="True"> - <touch:TouchGifAnimation.Style> - <Style TargetType="touch:TouchGifAnimation"> - <Setter Property="Source" Value="/Images/GlobalStatus/standby.png"></Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Disconnected}"> - <Setter Property="Source" Value="/Images/GlobalStatus/machine_off_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Standby}"> - <Setter Property="Source" Value="/Images/GlobalStatus/standby_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.ReadyToDye}"> - <Setter Property="Source" Value="/Images/GlobalStatus/Ready_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.GettingReady}"> - <Setter Property="Source" Value="/Images/GlobalStatus/getting_ready_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Printing}"> - <Setter Property="Source" Value="/Images/GlobalStatus/dyeing_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.ShuttingDown}"> - <Setter Property="Source" Value="/Images/GlobalStatus/shutdown_icon_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Error}"> - <Setter Property="Source" Value="/Images/GlobalStatus/error_Anim.gif"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Service}"> - <Setter Property="Source" Value="/Images/GlobalStatus/service_Anim.gif"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </touch:TouchGifAnimation.Style> - </touch:TouchGifAnimation> + <locaControls:MachineStatusControl HorizontalAlignment="Center" DataContext="{Binding MachineProvider.MachineOperator}" /> <TextBlock Margin="0 10 0 0" Text="{Binding MachineProvider.MachineOperator.Status,Converter={StaticResource EnumToDescriptionConverter}}"></TextBlock> </StackPanel> @@ -302,8 +287,21 @@ </Grid> <Grid> - <Grid Margin="20 0 60 0" Height="80" Visibility="{Binding NotificationProvider.HasAppBarItem,Converter={StaticResource BooleanToVisibilityConverter}}"> - <ContentControl Content="{Binding NotificationProvider.CurrentAppBarItem,Converter={StaticResource AppBarItemConverter}}"></ContentControl> + <Grid Margin="20 0 60 0" Height="80" Visibility="{Binding NotificationProvider.HasAppBarItems,Converter={StaticResource BooleanToVisibilityConverter}}"> + <ItemsControl ItemsSource="{Binding NotificationProvider.AppBarItems}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <Grid IsItemsHost="True" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Grid Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <ContentControl Content="{Binding Converter={StaticResource AppBarItemConverter}}"></ContentControl> + </Grid> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> </Grid> <!--External Header Content Here--> @@ -330,6 +328,35 @@ </DockPanel> </Border> + <Border Margin="0 0 0 0" DockPanel.Dock="Top" Visibility="{Binding IsInkFillingOrWasteEmptying,Converter={StaticResource BooleanToVisibilityConverter}}"> + <ItemsControl ItemsSource="{Binding Cartridges}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Border Margin="0 5 0 0" Visibility="{Binding InProgress,Converter={StaticResource BooleanToVisibilityConverter}}"> + <StackPanel> + <DockPanel Margin="2 0 0 0"> + <touch:TouchIcon> + <touch:TouchIcon.Style> + <Style TargetType="touch:TouchIcon" BasedOn="{StaticResource {x:Type touch:TouchIcon}}"> + <Setter Property="Icon" Value="Recycle"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Status.Cartridge.Slot}" Value="Ink"> + <Setter Property="Icon" Value="FormatColorFill"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </touch:TouchIcon.Style> + </touch:TouchIcon> + <TextBlock VerticalAlignment="Center" Margin="5 0 0 0" Text="{Binding Message,Mode=OneWay}" FontSize="{StaticResource TangoSmallFontSize}"></TextBlock> + </DockPanel> + <touch:TouchProgressBar Foreground="{Binding Brush,Mode=OneWay}" Background="#DBDBDB" Height="3" Margin="0 2 0 0" Minimum="0" Maximum="100" Value="{Binding Status.ProgressPercentage}" /> + </StackPanel> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + <Grid Background="{StaticResource TangoKeyboardBackground}"> <controls:NavigationControl x:Name="NavigationControl" x:FieldModifier="public" TransitionAlwaysFades="False" TransitionType="Zoom" KeepElementsAttached="False" UseDefferedRendering="True"> <!--MODULES GOES HERE--> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs index 883d3f893..b87f14b89 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs @@ -30,7 +30,7 @@ namespace Tango.PPC.UI.Views { public static LayoutView Instance { get; private set; } private LayoutViewVM _vm; - private DispatcherTimer _timer; + private System.Timers.Timer _timer; public LayoutView() { @@ -39,9 +39,9 @@ namespace Tango.PPC.UI.Views Loaded += (_, __) => _vm = DataContext as LayoutViewVM; techPressElement.RegisterForPreviewMouseOrTouchDown(OnMouseOrTouchDown); techPressElement.RegisterForPreviewMouseOrTouchUp(OnMouseOrTouchUp); - _timer = new DispatcherTimer(); - _timer.Interval = TimeSpan.FromSeconds(10); - _timer.Tick += _timer_Tick; + _timer = new System.Timers.Timer(); + _timer.Interval = TimeSpan.FromSeconds(10).TotalMilliseconds; + _timer.Elapsed += _timer_Elapsed; this.PreviewMouseUp += LayoutView_PreviewMouseUp; } @@ -51,10 +51,14 @@ namespace Tango.PPC.UI.Views _vm.ApplicationManager.ResetScreenLockTimer(); } - private void _timer_Tick(object sender, EventArgs e) + private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { _timer.Stop(); - _vm.ToggleTechnicianMode(); + + Dispatcher.BeginInvoke(new Action(() => + { + _vm.ToggleTechnicianMode(); + })); } private void OnMouseOrTouchDown(object sender, MouseOrTouchEventArgs e) diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml index 79d9cd54b..a917695af 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml @@ -10,9 +10,9 @@ xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" - d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> + d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> <Grid> - <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <StackPanel HorizontalAlignment="Center"> <!--<Image gif:ImageBehavior.EnableAnimation="{Binding IsLoading}" gif:ImageBehavior.AnimatedSource="/Images/Twine_Loading_GIF.gif" Margin="100 100 100 0" RenderTransformOrigin="0.5,0.5" RenderOptions.BitmapScalingMode="Fant" Height="382"> <Image.Style> <Style TargetType="Image"> @@ -47,9 +47,10 @@ </Image.Style> </Image>--> - <Grid Margin="0 100 0 0"> - <Image Source="/Images/machine.png" Stretch="Uniform" Width="250" RenderOptions.BitmapScalingMode="Fant"></Image> - <touch:TouchBusyIndicator Width="350" Height="350" IsIndeterminate="{Binding IsLoading}" /> + <Grid Margin="0 0 0 0"> + <!--<Image Source="/Images/machine.png" Stretch="Uniform" Width="250" RenderOptions.BitmapScalingMode="Fant"></Image> + <touch:TouchBusyIndicator Width="350" Height="350" IsIndeterminate="{Binding IsLoading}" />--> + <touch:TouchGifAnimation Source="/Images/loading_anim.gif" EnableAnimation="{Binding IsLoading}" /> </Grid> <TextBlock Margin="0 40 0 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml index 9437caac9..40b296d1e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml @@ -25,7 +25,7 @@ <Grid DockPanel.Dock="Bottom" Height="200" Background="{StaticResource TangoMidBackgroundBrush}"> <Border BorderThickness="0 1 0 0" BorderBrush="{StaticResource TangoGrayBrush}"> - <TextBox x:Name="txtLog" Foreground="{StaticResource TangoGrayTextBrush}" FontSize="12" SelectionBrush="Transparent" IsReadOnly="True" Padding="5" Background="Transparent" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> + <TextBox x:Name="txtLog" Foreground="{StaticResource TangoGrayTextBrush}" FontSize="12" SelectionBrush="#8BB0B0B0" IsReadOnly="True" Padding="5" Background="Transparent" AcceptsReturn="True" TextWrapping="Wrap" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> </TextBox> </Border> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml index fba8a599d..beb09be0d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml @@ -194,8 +194,9 @@ <touch:TouchButton Padding="20" Width="300" Margin="0 0 0 130" CornerRadius="35" Command="{Binding CloseCommand}">CLOSE</touch:TouchButton> </StackPanel> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0 50 0 0"> - <touch:TouchIcon Icon="AlertOctagon" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" /> - <TextBlock VerticalAlignment="Center" Margin="0 10 0 0" Foreground="{StaticResource TangoErrorBrush}" FontSize="{StaticResource TangoTitleFontSize}">An error occurred while trying to update the machine.</TextBlock> + <touch:TouchIcon Icon="AlertOutline" Foreground="{StaticResource TangoErrorBrush}" Width="70" Height="70" /> + <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="{StaticResource TangoTitleFontSize}">Update Failed</TextBlock> + <TextBlock HorizontalAlignment="Center" Margin="0 5 0 0" Foreground="{StaticResource TangoErrorBrush}" TextAlignment="Center" Text="{Binding FailedError,FallbackValue='Unexpected error'}"></TextBlock> </StackPanel> </DockPanel> </Grid> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs index f63899932..13a605774 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -37,7 +38,10 @@ namespace Tango.PPC.UI.Views navigationControl.NavigateTo(view.ToString(), () => { - source.SetResult(new object()); + if (!source.Task.IsCompleted) + { + source.SetResult(new object()); + } }); return source.Task; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml index 6d6d57526..2e36347a3 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml @@ -7,6 +7,7 @@ xmlns:commonControls="clr-namespace:Tango.PPC.Common.Controls;assembly=Tango.PPC.Common" xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" xmlns:global="clr-namespace:Tango.PPC.UI" + xmlns:operations="clr-namespace:Tango.Integration.Operation;assembly=Tango.Integration" xmlns:local="clr-namespace:Tango.PPC.UI.Views" xmlns:notifications="clr-namespace:Tango.PPC.UI.Notifications" xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" @@ -46,6 +47,21 @@ </touch:TouchIcon.Style> </touch:TouchIcon> + <touch:TouchIcon Margin="10 0 0 0" Width="18" Height="18" VerticalAlignment="Center"> + <touch:TouchIcon.Style> + <Style TargetType="touch:TouchIcon" BasedOn="{StaticResource {x:Type touch:TouchIcon}}"> + <Setter Property="Icon" Value="LanDisconnect"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoGrayBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding ConnectivityProvider.IsLanConnected}" Value="True"> + <Setter Property="Icon" Value="LanConnect"></Setter> + <Setter Property="Foreground" Value="{StaticResource TangoSuccessBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </touch:TouchIcon.Style> + </touch:TouchIcon> + <touch:TouchIcon Margin="10 0 0 0" Width="18" Height="18" VerticalAlignment="Center" Foreground="{StaticResource TangoSuccessBrush}" Icon="AccessPointNetwork" Visibility="{Binding HotSpotProvider.IsEnabled,Converter={StaticResource BooleanToVisibilityConverter}}" /> <touch:TouchIcon Margin="10 0 0 0" Width="18" Height="18" VerticalAlignment="Center" Icon="Bridge" Visibility="{Binding ExternalBridgeService.Enabled,Converter={StaticResource BooleanToVisibilityConverter}}"> @@ -53,7 +69,7 @@ <Style TargetType="touch:TouchIcon"> <Setter Property="Foreground" Value="{StaticResource TangoGrayBrush}"></Setter> <Style.Triggers> - <DataTrigger Binding="{Binding ExternalBridgeService.IsInSession}" Value="True"> + <DataTrigger Binding="{Binding ExternalBridgeService.HasSessions}" Value="True"> <Setter Property="Foreground" Value="{StaticResource TangoSuccessBrush}"></Setter> </DataTrigger> </Style.Triggers> @@ -61,6 +77,8 @@ </touch:TouchIcon.Style> </touch:TouchIcon> + <touch:TouchIcon Margin="10 0 0 0" Width="18" Height="18" VerticalAlignment="Center" Foreground="{StaticResource TangoSuccessBrush}" Icon="RemoteDesktop" Visibility="{Binding RemoteDesktopService.InSession,Converter={StaticResource BooleanToVisibilityConverter}}" /> + <ItemsControl ItemsSource="{Binding NotificationProvider.TaskBarItems}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> @@ -73,6 +91,43 @@ </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> + + <Image Margin="10 0 0 0" Width="18" Height="18" VerticalAlignment="Center" RenderOptions.BitmapScalingMode="Fant"> + <Image.Style> + <Style TargetType="Image"> + <Setter Property="Source" Value="/Images/GlobalStatus/machine-off.png"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Disconnected}"> + <Setter Property="Source" Value="/Images/GlobalStatus/machine-off.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.PowerUp}"> + <Setter Property="Source" Value="/Images/GlobalStatus/getting-ready.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Standby}"> + <Setter Property="Source" Value="/Images/GlobalStatus/standby.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.ReadyToDye}"> + <Setter Property="Source" Value="/Images/GlobalStatus/ready-to-dye.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.GettingReady}"> + <Setter Property="Source" Value="/Images/GlobalStatus/getting-ready.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Printing}"> + <Setter Property="Source" Value="/Images/GlobalStatus/dyeing.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.ShuttingDown}"> + <Setter Property="Source" Value="/Images/GlobalStatus/shutting-down.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Error}"> + <Setter Property="Source" Value="/Images/GlobalStatus/error.png"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding MachineProvider.MachineOperator.Status}" Value="{x:Static operations:MachineStatuses.Service}"> + <Setter Property="Source" Value="/Images/GlobalStatus/service.png"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Image.Style> + </Image> <Grid></Grid> </DockPanel> </Border> @@ -89,6 +144,7 @@ <local:MachineUpdateView></local:MachineUpdateView> <local:RestartingSystemView></local:RestartingSystemView> <local:EmergencyView></local:EmergencyView> + <local:RestartingView></local:RestartingView> </controls:NavigationControl> </touch:TouchPanel> </Grid> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml new file mode 100644 index 000000000..22952a827 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml @@ -0,0 +1,20 @@ +<UserControl x:Class="Tango.PPC.UI.Views.PowerOffView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" + xmlns:global="clr-namespace:Tango.PPC.UI" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.Views" + mc:Ignorable="d" + d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:PowerOffViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.PowerOffViewVM}"> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <touch:TouchGifAnimation Source="/Images/power_off_2.gif" EnableAnimation="{Binding IsVisible}" HorizontalAlignment="Center" /> + <TextBlock HorizontalAlignment="Center" Margin="0 60 0 0" FontSize="{StaticResource TangoHeaderFontSize}">Machine is turning Off</TextBlock> + <TextBlock HorizontalAlignment="Center" Margin="0 20 0 0" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}">Do not unplug machine while turning off</TextBlock> + <touch:TouchButton Command="{Binding AbortCommand}" Style="{StaticResource TangoHollowButton}" Margin="0 100 0 0" HorizontalAlignment="Center" Width="200" Height="50">ABORT</touch:TouchButton> + </StackPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs new file mode 100644 index 000000000..ead34ae12 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Views +{ + /// <summary> + /// Interaction logic for LoadingView.xaml + /// </summary> + public partial class PowerOffView : UserControl + { + public PowerOffView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml index 996b1788d..dd4d2f5d5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml @@ -10,17 +10,37 @@ mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:RestartingSystemViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RestartingSystemViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> <Grid> - <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> - <touch:TouchBusyIndicator Width="350" Height="350" IsIndeterminate="{Binding IsVisible}" Foreground="{StaticResource TangoGrayBrush}" /> - <TextBlock Margin="0 40 0 0" TextAlignment="Center" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> - <Run> - Setup completed. - </Run> - <LineBreak/> - <Run> - Restarting the system for the last time... - </Run> + <Grid Margin="0 100 0 0"> + <Image Source="/Images/machine.png" Stretch="Uniform" Width="250" RenderOptions.BitmapScalingMode="Fant"></Image> + <touch:TouchBusyIndicator Foreground="{StaticResource TangoGrayBrush}" Width="350" Height="350" IsIndeterminate="{Binding IsVisible}" /> + </Grid> + + <TextBlock FontSize="{StaticResource TangoHeaderFontSize}" Margin="0 100 0 0" HorizontalAlignment="Center" Width="250"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="Restarting device"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsVisible}" Value="True"> + <DataTrigger.EnterActions> + <BeginStoryboard x:Name="storyRes"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Text" RepeatBehavior="5x"> + <DiscreteObjectKeyFrame KeyTime="00:00:0.2" Value="Restarting." /> + <DiscreteObjectKeyFrame KeyTime="00:00:0.6" Value="Restarting.." /> + <DiscreteObjectKeyFrame KeyTime="00:00:0.9" Value="Restarting..." /> + <DiscreteObjectKeyFrame KeyTime="00:00:1.4" Value="Restarting..." /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <RemoveStoryboard BeginStoryboardName="storyRes" /> + </DataTrigger.ExitActions> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> </TextBlock> </StackPanel> </Grid> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml new file mode 100644 index 000000000..41017f629 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml @@ -0,0 +1,52 @@ +<UserControl x:Class="Tango.PPC.UI.Views.RestartingView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" + xmlns:fx="clr-namespace:Tango.SharedUI.Effects;assembly=Tango.SharedUI" + xmlns:gif="clr-namespace:Tango.AnimatedGif;assembly=Tango.AnimatedGif" + xmlns:global="clr-namespace:Tango.PPC.UI" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:local="clr-namespace:Tango.PPC.UI.Views" + mc:Ignorable="d" + d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:RestartingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RestartingViewVM}"> + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <Grid Margin="0 100 0 0"> + <Image Source="/Images/machine.png" Stretch="Uniform" Width="250" RenderOptions.BitmapScalingMode="Fant"></Image> + <touch:TouchBusyIndicator Foreground="{StaticResource TangoGrayBrush}" Width="350" Height="350" IsIndeterminate="{Binding IsVisible}" /> + </Grid> + + <TextBlock Margin="0 40 0 0" HorizontalAlignment="Center" FontSize="{StaticResource TangoTitleFontSize}" Foreground="{StaticResource TangoGrayTextBrush}"> + <Run>v</Run><Run Text="{Binding ApplicationManager.Version,Mode=OneWay}"></Run> + </TextBlock> + <TextBlock FontSize="{StaticResource TangoHeaderFontSize}" Margin="0 100 0 0" HorizontalAlignment="Center" Width="170"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="Restarting"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsVisible}" Value="True"> + <DataTrigger.EnterActions> + <BeginStoryboard x:Name="storyRes"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Text" RepeatBehavior="5x"> + <DiscreteObjectKeyFrame KeyTime="00:00:0.2" Value="Restarting." /> + <DiscreteObjectKeyFrame KeyTime="00:00:0.6" Value="Restarting.." /> + <DiscreteObjectKeyFrame KeyTime="00:00:0.9" Value="Restarting..." /> + <DiscreteObjectKeyFrame KeyTime="00:00:1.4" Value="Restarting..." /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <RemoveStoryboard BeginStoryboardName="storyRes" /> + </DataTrigger.ExitActions> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </StackPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs new file mode 100644 index 000000000..fabd7b47b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.PPC.UI.Views +{ + /// <summary> + /// Interaction logic for LoadingView.xaml + /// </summary> + public partial class RestartingView : UserControl + { + public RestartingView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest index efc5f8179..d72e75011 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest @@ -16,7 +16,7 @@ Remove this element if your application requires this virtualization for backwards compatibility. --> - <!--<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />--> + <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp b/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp Binary files differnew file mode 100644 index 000000000..bc33e385a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp |
