aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
diff options
context:
space:
mode:
authorAvi Levkovich <avi@twine-s.com>2018-02-26 16:30:42 +0200
committerAvi Levkovich <avi@twine-s.com>2018-02-26 16:30:42 +0200
commit5942bb7a13e5ad26c720a1b95ae4ea766eeeda25 (patch)
tree2a855ce1065c875e615f5b040f984cb3fb84e518 /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI
parent4c052df707280abd208b03aa88cf904e0eb6b9bf (diff)
parent6549d8672a93893599e921d9f1938af7dcabb8bf (diff)
downloadTango-5942bb7a13e5ad26c720a1b95ae4ea766eeeda25.tar.gz
Tango-5942bb7a13e5ad26c720a1b95ae4ea766eeeda25.zip
MERGE!
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI')
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs2
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs7
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.pngbin0 -> 1932 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.pngbin0 -> 5289 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml3
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs16
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs55
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj58
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs9
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs153
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs30
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs305
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml6
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml116
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs5
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml194
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs42
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml97
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs44
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config6
23 files changed, 1128 insertions, 41 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
index d38c3ed69..1a0e57043 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config
@@ -6,6 +6,8 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
+
+
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
@@ -17,9 +19,7 @@
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
- <remove invariant="System.Data.SQLite" />
- <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
- </DbProviderFactories>
+ <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
</system.data>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
index c15a87980..b6a131d22 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs
@@ -22,6 +22,8 @@ namespace Tango.MachineStudio.UI
protected override void OnStartup(StartupEventArgs e)
{
+ LogManager.Log("Application Started...");
+
base.OnStartup(e);
LogManager.Categories.Clear();
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
index 82aba268d..110e4d148 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Authentication/DefaultAuthenticationProvider.cs
@@ -50,7 +50,12 @@ namespace Tango.MachineStudio.UI.Authentication
if (user == null)
{
- throw new AuthenticationException("Login failed for user " + email);
+ throw new AuthenticationException("Invalid credentials for " + email);
+ }
+
+ if (!user.HasPermission(Permissions.RunMachineStudio))
+ {
+ throw new AuthenticationException("It seems like you do not have sufficient privileges to run Machine Studio. Please contact your administrator.");
}
CurrentUser = user;
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png
new file mode 100644
index 000000000..eab60ef03
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/new-version.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png
new file mode 100644
index 000000000..a82777414
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/update.png
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
index e0f0b1f4f..63b2b3f6a 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml
@@ -31,6 +31,9 @@
<ContentControl Tag="ShutdownView">
<views:ShutdownView></views:ShutdownView>
</ContentControl>
+ <ContentControl Tag="UpdateView">
+ <views:UpdateView></views:UpdateView>
+ </ContentControl>
</sharedControls:MultiTransitionControl.Controls>
</sharedControls:MultiTransitionControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs
index dfbc0eb77..15c8abcde 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/MainWindow.xaml.cs
@@ -15,6 +15,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Tango.Core.Helpers;
+using Tango.Logging;
using Tango.MachineStudio.Common.StudioApplication;
namespace Tango.MachineStudio.UI
@@ -28,11 +29,18 @@ namespace Tango.MachineStudio.UI
public MainWindow()
{
- InitializeComponent();
- Instance = this;
- ThreadsHelper.SetDisptacher(Dispatcher);
+ try
+ {
+ InitializeComponent();
+ Instance = this;
+ ThreadsHelper.SetDisptacher(Dispatcher);
- this.Closing += MainWindow_Closing;
+ this.Closing += MainWindow_Closing;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex);
+ }
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs
index 1ea22c587..4dd17b500 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Notifications/DefaultNotificationProvider.cs
@@ -225,7 +225,7 @@ namespace Tango.MachineStudio.UI.Notifications
/// <param name="message">The message.</param>
public void ShowError(string message)
{
- ShowMessageBox(PackIconKind.Exclamation, Brushes.Red, message, false);
+ ShowMessageBox(PackIconKind.AlertOctagon, Brushes.Red, message, false);
}
/// <summary>
@@ -234,7 +234,7 @@ namespace Tango.MachineStudio.UI.Notifications
/// <param name="message">The message.</param>
public void ShowInfo(string message)
{
- ShowMessageBox(PackIconKind.Information, Brushes.Black, message, false);
+ ShowMessageBox(PackIconKind.CommentAlertOutline, Brushes.Black, message, false);
}
/// <summary>
@@ -253,7 +253,7 @@ namespace Tango.MachineStudio.UI.Notifications
/// <param name="message">The message.</param>
public void ShowWarning(string message)
{
- ShowMessageBox(PackIconKind.Exclamation, Brushes.DarkOrange, message, false);
+ ShowMessageBox(PackIconKind.AlertOutline, Brushes.DarkOrange, message, false);
}
/// <summary>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
index 886985c92..9538c59af 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs
@@ -17,6 +17,7 @@ using Tango.Logging;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common;
using Tango.Settings;
+using System.Windows;
namespace Tango.MachineStudio.UI.StudioApplication
{
@@ -29,6 +30,7 @@ namespace Tango.MachineStudio.UI.StudioApplication
{
private INavigationManager _navigationManager;
private IStudioModuleLoader _moduleLoader;
+ private List<Window> _openedWindows;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultStudioApplicationManager" /> class.
@@ -38,6 +40,7 @@ namespace Tango.MachineStudio.UI.StudioApplication
{
_moduleLoader = moduleLoader;
_navigationManager = navigationManager;
+ _openedWindows = new List<Window>();
}
/// <summary>
@@ -109,6 +112,17 @@ namespace Tango.MachineStudio.UI.StudioApplication
}
/// <summary>
+ /// Gets the machine studio application version.
+ /// </summary>
+ public string Version
+ {
+ get
+ {
+ return typeof(DefaultStudioApplicationManager).Assembly.GetName().Version.ToString();
+ }
+ }
+
+ /// <summary>
/// Shutdown the application.
/// </summary>
public async void ShutDown()
@@ -137,35 +151,45 @@ namespace Tango.MachineStudio.UI.StudioApplication
}
}
+ foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownListener>())
+ {
+ vm.OnShuttingDown();
+ }
+
try
{
- if (ConnectedMachine != null)
- {
- ConnectedMachine.Disconnect().Wait();
- }
+ SettingsManager.SaveDefaultSettings();
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error disconnecting from machine.");
+ LogManager.Log(ex, "Error saving settings.");
}
- foreach (var vm in ServiceLocator.Current.GetAllInstancesByBase<IShutdownListener>())
+ _navigationManager.NavigateTo(NavigationView.ShutdownView);
+
+ Thread.Sleep(1500);
+
+ foreach (var window in _openedWindows)
{
- vm.OnShuttingDown();
+ ThreadsHelper.InvokeUI(() =>
+ {
+ window.Close();
+ });
}
try
{
- SettingsManager.SaveDefaultSettings();
+ if (ConnectedMachine != null)
+ {
+ ConnectedMachine.Disconnect().Wait();
+ }
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error saving settings.");
+ LogManager.Log(ex, "Error disconnecting from machine.");
}
- _navigationManager.NavigateTo(NavigationView.ShutdownView);
-
- Thread.Sleep(3000);
+ Thread.Sleep(1500);
Environment.Exit(0);
@@ -196,5 +220,12 @@ namespace Tango.MachineStudio.UI.StudioApplication
throw new InvalidOperationException("The module was not found or you do not have sufficient privileges.");
}
}
+
+ public void RegisterOpenedWindow(Window window)
+ {
+ _openedWindows.Add(window);
+
+ window.Closed += (x, y) => { _openedWindows.Remove(window); };
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
index f48561e40..4cfa99a9b 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj
@@ -13,6 +13,8 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -46,6 +48,9 @@
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
+ <Reference Include="FluentFTP, Version=19.1.2.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\FluentFTP.19.1.2\lib\net45\FluentFTP.dll</HintPath>
+ </Reference>
<Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL">
<HintPath>..\..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath>
</Reference>
@@ -61,6 +66,9 @@
<Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
+ <Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Ionic.Zip.1.9.1.8\lib\Ionic.Zip.dll</HintPath>
+ </Reference>
<Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL">
<HintPath>..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath>
</Reference>
@@ -80,7 +88,19 @@
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
+ <Reference Include="System.Data.SQLite, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.Core.1.0.106.0\lib\net46\System.Data.SQLite.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Data.SQLite.EF6, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.EF6.1.0.106.0\lib\net46\System.Data.SQLite.EF6.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Data.SQLite.Linq, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.106.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
<Reference Include="System.Drawing" />
+ <Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath>
@@ -97,6 +117,9 @@
<Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
</Reference>
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Web" />
<Reference Include="System.Windows" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -120,12 +143,12 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Compile Include="Modules\DefaultStudioModuleLoader.cs" />
<Compile Include="Notifications\TextInputBoxWindow.xaml.cs">
<DependentUpon>TextInputBoxWindow.xaml</DependentUpon>
</Compile>
<Compile Include="StudioApplication\DefaultStudioApplicationManager.cs" />
<Compile Include="Authentication\DefaultAuthenticationProvider.cs" />
- <Compile Include="Modules\DefaultStudioModuleLoader.cs" />
<Compile Include="Navigation\DefaultNavigationManager.cs" />
<Compile Include="Notifications\DefaultNotificationProvider.cs" />
<Compile Include="Notifications\MessageBoxWindow.xaml.cs">
@@ -138,7 +161,9 @@
<Compile Include="ViewModels\MachineLoginViewVM.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
<Compile Include="ViewModelLocator.cs" />
+ <Compile Include="ViewModels\ModuleWindowVM.cs" />
<Compile Include="ViewModels\ShutdownViewVM.cs" />
+ <Compile Include="ViewModels\UpdateViewVM.cs" />
<Compile Include="Views\LoadingView.xaml.cs">
<DependentUpon>LoadingView.xaml</DependentUpon>
</Compile>
@@ -160,10 +185,16 @@
<Compile Include="Views\ShutdownView.xaml.cs">
<DependentUpon>ShutdownView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\UpdateView.xaml.cs">
+ <DependentUpon>UpdateView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Windows\ExceptionResolutions.cs" />
<Compile Include="Windows\ExceptionWindow.xaml.cs">
<DependentUpon>ExceptionWindow.xaml</DependentUpon>
</Compile>
+ <Compile Include="Windows\ModuleWindow.xaml.cs">
+ <DependentUpon>ModuleWindow.xaml</DependentUpon>
+ </Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -219,10 +250,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\UpdateView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Windows\ExceptionWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Windows\ModuleWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -324,6 +363,10 @@
<Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
<Name>Tango.MachineStudio.Common</Name>
</ProjectReference>
+ <ProjectReference Include="..\Tango.MachineStudio.Updater\Tango.MachineStudio.Updater.csproj">
+ <Project>{844787ce-f409-4f18-bccc-f3809ecb86f3}</Project>
+ <Name>Tango.MachineStudio.Updater</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="Images\design.png" />
@@ -344,6 +387,12 @@
<ItemGroup>
<Resource Include="Images\exception.png" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\update.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\new-version.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>$(TargetDir)linkgen.exe -s "$(TargetPath)" -d "$(TargetDir)Utilities\Machine Studio.lnk"
@@ -393,4 +442,11 @@ RD /S /Q "$(TargetDir)bg\"
RD /S /Q "$(TargetDir)bn-BD\"
RD /S /Q "$(TargetDir)nb-NO\"</PostBuildEvent>
</PropertyGroup>
+ <Import Project="..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets'))" />
+ </Target>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
index 1907074c0..330bcd6eb 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs
@@ -71,6 +71,7 @@ namespace Tango.MachineStudio.UI
SimpleIoc.Default.Register<LoginViewVM>();
SimpleIoc.Default.Register<MachineConnectionViewVM>();
SimpleIoc.Default.Register<MachineLoginViewVM>();
+ SimpleIoc.Default.Register<UpdateViewVM>();
//Register View (Supervising Controller Pattern).
if (!ViewModelBase.IsInDesignModeStatic)
@@ -127,5 +128,13 @@ namespace Tango.MachineStudio.UI
return ServiceLocator.Current.GetInstance<MachineLoginViewVM>();
}
}
+
+ public UpdateViewVM UpdateViewVM
+ {
+ get
+ {
+ return ServiceLocator.Current.GetInstance<UpdateViewVM>();
+ }
+ }
}
} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
index 55a54e8aa..9acf26afd 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs
@@ -6,9 +6,11 @@ using System.Threading;
using System.Threading.Tasks;
using Tango.Core.Helpers;
using Tango.Integration.Observables;
+using Tango.Logging;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Navigation;
using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.StudioApplication;
using Tango.SharedUI;
namespace Tango.MachineStudio.UI.ViewModels
@@ -23,14 +25,17 @@ namespace Tango.MachineStudio.UI.ViewModels
private INavigationManager _navigationManager;
private IStudioModuleLoader _studioModuleLoader;
+ public IStudioApplicationManager ApplicationManager { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="LoadingViewVM"/> class.
/// </summary>
/// <param name="navigationManager">The navigation manager.</param>
/// <param name="studioModuleLoader">The studio module loader.</param>
/// <param name="notificationProvider">The notification provider.</param>
- public LoadingViewVM(INavigationManager navigationManager, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider)
+ public LoadingViewVM(IStudioApplicationManager applicationManager, INavigationManager navigationManager, IStudioModuleLoader studioModuleLoader, INotificationProvider notificationProvider)
{
+ ApplicationManager = applicationManager;
_navigationManager = navigationManager;
_studioModuleLoader = studioModuleLoader;
_notificationProvider = notificationProvider;
@@ -55,6 +60,8 @@ namespace Tango.MachineStudio.UI.ViewModels
}
catch (Exception ex)
{
+ LogManager.Log(ex);
+
InvokeUINow(() =>
{
if (_notificationProvider.ShowQuestion("An error occurred while trying to connect to Twine database." + Environment.NewLine + "Would you like to try again?"))
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
index 679ba5ff3..fb2cd5c82 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs
@@ -6,7 +6,11 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
using Tango.Core.Commands;
using Tango.Integration.Services;
using Tango.Logging;
@@ -16,10 +20,14 @@ using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common.Navigation;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Common.Update;
+using Tango.MachineStudio.UI.StudioApplication;
using Tango.MachineStudio.UI.SupervisingController;
using Tango.MachineStudio.UI.Views;
+using Tango.MachineStudio.UI.Windows;
using Tango.PMR.Stubs;
using Tango.SharedUI;
+using Tango.SharedUI.Helpers;
using Tango.Transport.Adapters;
namespace Tango.MachineStudio.UI.ViewModels
@@ -33,6 +41,7 @@ namespace Tango.MachineStudio.UI.ViewModels
private IStudioModule _currentModule;
private INavigationManager _navigation;
private bool _isDisconnecting;
+ private Thread _updateCheckThread;
/// <summary>
/// Gets or sets the current loaded module.
@@ -69,6 +78,11 @@ namespace Tango.MachineStudio.UI.ViewModels
public RelayCommand<IStudioModule> StartModuleCommand { get; set; }
/// <summary>
+ /// Gets or sets the open module in window command.
+ /// </summary>
+ public RelayCommand<IStudioModule> OpenModuleInWindowCommand { get; set; }
+
+ /// <summary>
/// Gets or sets the home command.
/// </summary>
public RelayCommand HomeCommand { get; set; }
@@ -88,6 +102,16 @@ namespace Tango.MachineStudio.UI.ViewModels
/// </summary>
public RelayCommand SignoutCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the exit command.
+ /// </summary>
+ public RelayCommand ExitCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the update center command.
+ /// </summary>
+ public RelayCommand UpdateCenterCommand { get; set; }
+
private IAuthenticationProvider _authenticationProvider;
/// <summary>
/// Gets or sets the authentication provider.
@@ -128,6 +152,38 @@ namespace Tango.MachineStudio.UI.ViewModels
set { _applicationManager = value; RaisePropertyChangedAuto(); }
}
+ private bool _isUpdateAvailable;
+ /// <summary>
+ /// Gets or sets a value indicating whether a new version update is available.
+ /// </summary>
+ public bool IsUpdateAvailable
+ {
+ get { return _isUpdateAvailable; }
+ set { _isUpdateAvailable = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _latestVersion;
+ /// <summary>
+ /// Gets or sets the latest version.
+ /// </summary>
+ public String LatestVersion
+ {
+ get { return _latestVersion; }
+ set { _latestVersion = value; RaisePropertyChangedAuto(); }
+ }
+
+
+ private bool _disableCheckForUpdates;
+ /// <summary>
+ /// Gets or sets a value indicating whether [disable check for updates].
+ /// </summary>
+ public bool DisableCheckForUpdates
+ {
+ get { return _disableCheckForUpdates; }
+ set { _disableCheckForUpdates = value; RaisePropertyChangedAuto(); }
+ }
+
+
/// <summary>
/// Initializes a new instance of the <see cref="MainViewVM"/> class.
/// </summary>
@@ -157,6 +213,46 @@ namespace Tango.MachineStudio.UI.ViewModels
ConnectCommand = new RelayCommand(ConnectToMachine);
SignoutCommand = new RelayCommand(SignOut);
DisconnectCommand = new RelayCommand(DisconnectFromMachine, (x) => ApplicationManager.IsMachineConnected && !_isDisconnecting);
+ OpenModuleInWindowCommand = new RelayCommand<IStudioModule>(OpenModuleInWindow);
+ ExitCommand = new RelayCommand(ExitApplication);
+ UpdateCenterCommand = new RelayCommand(NavigateToUpdateCenter);
+
+ _updateCheckThread = new Thread(UpdateCheckThreadMethod);
+ _updateCheckThread.IsBackground = true;
+ _updateCheckThread.Start();
+ }
+
+ private void UpdateCheckThreadMethod()
+ {
+ while (!DisableCheckForUpdates)
+ {
+ Thread.Sleep(TimeSpan.FromMinutes(1));
+
+ try
+ {
+ if (_authenticationProvider.CurrentUser != null)
+ {
+ var service = UpdateServiceHelper.GetUpdateServiceChannel();
+ var client = service.CreateChannel();
+
+ CheckForUpdatesResponse response = client.CheckForUpdates(new CheckForUpdatesRequest()
+ {
+ Email = _authenticationProvider.CurrentUser.Email,
+ Password = _authenticationProvider.CurrentUser.Password,
+ Version = _applicationManager.Version,
+ });
+
+ IsUpdateAvailable = response.IsUpdateAvailable;
+ LatestVersion = response.Version;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error in version update periodic check...");
+ }
+
+ Thread.Sleep(TimeSpan.FromMinutes(4));
+ }
}
/// <summary>
@@ -302,5 +398,62 @@ namespace Tango.MachineStudio.UI.ViewModels
{
base.OnViewAttached();
}
+
+ /// <summary>
+ /// Opens the module in a new window.
+ /// </summary>
+ /// <param name="module">The module.</param>
+ private void OpenModuleInWindow(IStudioModule module)
+ {
+ if (module == null) return;
+
+ try
+ {
+ StartModule(null);
+
+ module.InNewWindow = true;
+
+ var parent = (MainView.Self as MainView).TransitionControl.Controls.SingleOrDefault(x => x.Tag.ToString() == module.Name).Content as Grid;
+
+ var view = parent.Children[0] as FrameworkElement;
+ parent.Children.Remove(view);
+
+ ModuleWindowVM vm = new ModuleWindowVM(module, parent);
+ ModuleWindow window = new ModuleWindow(this, vm, view);
+
+ window.Closing += (x, y) =>
+ {
+ window.grid.Children.Remove(view);
+ parent.Children.Add(view);
+ module.InNewWindow = false;
+ };
+
+ window.Owner = MainWindow.Instance;
+ window.Show();
+
+ (_applicationManager as DefaultStudioApplicationManager).RegisterOpenedWindow(window);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error popping out module " + module.Name);
+ _notificationProvider.ShowError("Error popping out module " + module.Name);
+ }
+ }
+
+ /// <summary>
+ /// Navigates to update center.
+ /// </summary>
+ private void NavigateToUpdateCenter()
+ {
+ _navigation.NavigateTo(NavigationView.UpdateView);
+ }
+
+ /// <summary>
+ /// Exits the application.
+ /// </summary>
+ private void ExitApplication()
+ {
+ _applicationManager.ShutDown();
+ }
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs
new file mode 100644
index 000000000..a5b737b59
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/ModuleWindowVM.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using Tango.MachineStudio.Common;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.UI.ViewModels
+{
+ public class ModuleWindowVM : ViewModel
+ {
+ private IStudioModule _module;
+
+ public IStudioModule Module
+ {
+ get { return _module; }
+ set { _module = value; RaisePropertyChangedAuto(); }
+ }
+
+ public Grid Parent { get; set; }
+
+ public ModuleWindowVM(IStudioModule module, Grid parent)
+ {
+ Parent = parent;
+ Module = module;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs
new file mode 100644
index 000000000..6be4ba4ca
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/UpdateViewVM.cs
@@ -0,0 +1,305 @@
+using FluentFTP;
+using Ionic.Zip;
+using Microsoft.Practices.ServiceLocation;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.ServiceModel;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Core.Commands;
+using Tango.Core.Helpers;
+using Tango.Logging;
+using Tango.MachineStudio.Common.Authentication;
+using Tango.MachineStudio.Common.Navigation;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Common.Update;
+using Tango.SharedUI;
+
+namespace Tango.MachineStudio.UI.ViewModels
+{
+ public enum UpdateStatus
+ {
+ None,
+ CheckingForUpdate,
+ UpToDate,
+ UpdateAvailable,
+ Downloading,
+ Updating,
+ UpdateCompleted,
+ Error,
+ }
+
+ public class UpdateViewVM : ViewModel
+ {
+ private String _appPath = AppDomain.CurrentDomain.BaseDirectory;
+
+ private INotificationProvider _notification;
+ private INavigationManager _navigation;
+ private IStudioApplicationManager _application;
+ private IAuthenticationProvider _authentication;
+ private CheckForUpdatesResponse _updateInfo;
+ private String _newPackageTempFolder;
+
+ private UpdateStatus _status;
+ public UpdateStatus Status
+ {
+ get { return _status; }
+ set { _status = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _latestVersion;
+ public String LatestVersion
+ {
+ get { return _latestVersion; }
+ set { _latestVersion = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _downloadProgress;
+
+ public double DownloadProgress
+ {
+ get { return _downloadProgress; }
+ set { _downloadProgress = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _updateProgress;
+
+ public double UpdateProgress
+ {
+ get { return _updateProgress; }
+ set { _updateProgress = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _currentUpdateFile;
+
+ public String CurrentUpdateFile
+ {
+ get { return _currentUpdateFile; }
+ set { _currentUpdateFile = value; RaisePropertyChanged(nameof(CurrentUpdateFile)); }
+ }
+
+ public RelayCommand UpdateCommand { get; set; }
+
+ public RelayCommand BackCommand { get; set; }
+
+ public RelayCommand RestartCommand { get; set; }
+
+ public RelayCommand TryAgainCommand { get; set; }
+
+ public UpdateViewVM(INotificationProvider notification, IAuthenticationProvider authentication, INavigationManager navigation, IStudioApplicationManager application)
+ {
+ _notification = notification;
+ _navigation = navigation;
+ _application = application;
+ _authentication = authentication;
+
+ LatestVersion = "1.0.0.2";
+ Status = UpdateStatus.CheckingForUpdate;
+ UpdateCommand = new RelayCommand(StartUpdate, () => Status == UpdateStatus.UpdateAvailable);
+ BackCommand = new RelayCommand(BackToApplication, () => Status != UpdateStatus.Updating);
+ RestartCommand = new RelayCommand(RestartApplication, () => Status == UpdateStatus.UpdateCompleted);
+ TryAgainCommand = new RelayCommand(TryAgain, () => Status == UpdateStatus.Error);
+ }
+
+ public void OnNavigatedInto()
+ {
+ CheckForUpdates();
+ }
+
+ private void CheckForUpdates()
+ {
+ Status = UpdateStatus.CheckingForUpdate;
+
+ ChannelFactory<IMachineStudioUpdateService> service = null;
+
+ Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ Thread.Sleep(2000);
+
+ service = UpdateServiceHelper.GetUpdateServiceChannel();
+ var client = service.CreateChannel();
+
+ CheckForUpdatesResponse response = client.CheckForUpdates(new CheckForUpdatesRequest()
+ {
+ Email = _authentication.CurrentUser.Email,
+ Password = _authentication.CurrentUser.Password,
+ Version = _application.Version,
+ });
+
+ if (response.IsUpdateAvailable)
+ {
+ _updateInfo = response;
+ Status = UpdateStatus.UpdateAvailable;
+ LatestVersion = response.Version;
+ }
+ else
+ {
+ Status = UpdateStatus.UpToDate;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error while checking for version update!");
+ Status = UpdateStatus.Error;
+ }
+ finally
+ {
+ if (service != null)
+ {
+ service.Close();
+ }
+ }
+ });
+ }
+
+ private void BackToApplication()
+ {
+ if (Status == UpdateStatus.Downloading)
+ {
+ if (!_notification.ShowQuestion("This will abort all update operations. Are you sure?"))
+ {
+ return;
+ }
+ }
+
+ _navigation.NavigateTo(NavigationView.MainView);
+ Status = UpdateStatus.None;
+ }
+
+ private void StartUpdate()
+ {
+ DownloadProgress = 0;
+ UpdateProgress = 0;
+
+ Status = UpdateStatus.Downloading;
+
+ Task.Factory.StartNew(() =>
+ {
+ var tempFile = PathHelper.GetTempFilePath() + ".zip";
+
+ try
+ {
+ LogManager.Log("Creating temporary file " + tempFile);
+
+ int fileSize = 0;
+
+ using (FileStreamWrapper fs = new FileStreamWrapper(tempFile, FileMode.Create, (current) =>
+ {
+ InvokeUINow(() =>
+ {
+ Thread.Sleep(10);
+ DownloadProgress = ((double)current / (double)fileSize) * 100d;
+ });
+ }))
+ {
+ using (FtpClient ftp = new FtpClient(_updateInfo.FtpHost, _updateInfo.UserName, _updateInfo.Password))
+ {
+ LogManager.Log("Connecting to FTP site: " + _updateInfo.FtpHost);
+ ftp.ConnectAsync().Wait();
+ LogManager.Log("Retrieving download size...");
+ fileSize = (int)ftp.GetFileSize(_updateInfo.FilePath);
+ LogManager.Log("Download size: " + fileSize + " bytes.");
+ LogManager.Log("Starting download...");
+ ftp.DownloadAsync(fs, _updateInfo.FilePath).Wait();
+ }
+ }
+
+
+ Status = UpdateStatus.Updating;
+
+ _newPackageTempFolder = PathHelper.GetTempFolderPath();
+
+ using (ZipFile zip = ZipFile.Read(tempFile))
+ {
+ int currentEntry = 0;
+
+ zip.ExtractProgress += (x, args) =>
+ {
+ if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry)
+ {
+ LogManager.Log("Extracting " + Path.GetFileName(args.CurrentEntry.FileName));
+ UpdateProgress = ((double)(currentEntry++) / (double)zip.Entries.Count) * 100d;
+ }
+ };
+
+ foreach (ZipEntry entry in zip)
+ {
+ Thread.Sleep(10);
+
+ string newPath = Path.Combine(_newPackageTempFolder, entry.FileName);
+
+ try
+ {
+ if (entry.IsDirectory)
+ {
+ Directory.CreateDirectory(newPath);
+ }
+ else
+ {
+ CurrentUpdateFile = Path.GetFileName(entry.FileName);
+ entry.Extract(_newPackageTempFolder, ExtractExistingFileAction.OverwriteSilently);
+ }
+ }
+ catch
+ {
+ LogManager.Log("Could not extract file " + entry.FileName);
+ }
+ }
+ }
+
+ ServiceLocator.Current.GetInstance<MainViewVM>().DisableCheckForUpdates = true;
+ Status = UpdateStatus.UpdateCompleted;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error while extracting update package.");
+ Status = UpdateStatus.Error;
+ }
+ finally
+ {
+ PathHelper.TryDeleteFile(tempFile);
+ }
+ });
+ }
+
+ private void TryAgain()
+ {
+ CheckForUpdates();
+ }
+
+ private void RestartApplication()
+ {
+ try
+ {
+ Process p = new Process();
+ p.StartInfo.FileName = _appPath + "\\Tango.MachineStudio.Updater.exe";
+ p.StartInfo.UseShellExecute = true;
+ p.StartInfo.Arguments = _newPackageTempFolder;
+ p.Start();
+ }
+ catch (Exception ex)
+ {
+ if (ex.Message == "The operation was canceled by the user")
+ {
+ _notification.ShowWarning("It seems like you refused to invoke our update utility. This prevents Machine Studio from completing the update process!");
+ return;
+ }
+ }
+ Environment.Exit(0);
+ }
+
+ protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
+ {
+ base.RaisePropertyChangedAuto(caller);
+ InvalidateRelayCommands();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
index 2478c1155..5f65100df 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml
@@ -19,5 +19,11 @@
<TextBlock HorizontalAlignment="Center" FontSize="18" FontStyle="Italic">Loading, please wait...</TextBlock>
</StackPanel>
</Grid>
+
+
+ <TextBlock Foreground="Gray" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="40" FontSize="20" FontWeight="SemiBold" FontStyle="Italic">
+ <Run>v</Run>
+ <Run Text="{Binding ApplicationManager.Version,Mode=OneWay}"></Run>
+ </TextBlock>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
index 479052cc5..f2c9ddba5 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml
@@ -17,6 +17,9 @@
<UserControl.Resources>
<converters:StringEllipsisConverter x:Key="StringEllipsisConverter" />
+ <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" />
+ <converters:NullObjectToBooleanConverter x:Key="NullObjectToBooleanConverter" />
+ <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<Grid>
@@ -44,7 +47,25 @@
<StackPanel Margin="5 0 0 0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<Image Source="/Images/account.png" RenderOptions.BitmapScalingMode="Fant" VerticalAlignment="Center" Width="50" Height="50"></Image>
+ <StackPanel Margin="0 5 0 0">
<TextBlock FontSize="16" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" FontWeight="Bold" Margin="10 0 0 0" VerticalAlignment="Center" Text="{Binding AuthenticationProvider.CurrentUser.Contact.FullName}"></TextBlock>
+ <TextBlock FontSize="12" TextTrimming="CharacterEllipsis" MaxWidth="170" FontStyle="Italic" Margin="10 5 0 0" VerticalAlignment="Center">
+ <Run Text="{Binding AuthenticationProvider.CurrentUser.Organization.Name}"></Run>
+ ,
+ <Run Text="{Binding AuthenticationProvider.CurrentUser.Roles[0]}">
+ <Run.ToolTip>
+ <ItemsControl ItemsSource="{Binding AuthenticationProvider.CurrentUser.Roles}">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Name}"></TextBlock>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Run.ToolTip>
+ </Run>
+ <Run>...</Run>
+ </TextBlock>
+ </StackPanel>
</StackPanel>
</Grid>
<StackPanel Margin="0 16 0 0">
@@ -69,6 +90,7 @@
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
+ <Setter Property="Visibility" Value="{Binding InNewWindow,Converter={StaticResource BooleanToVisibilityInverseConverter}}"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
@@ -118,10 +140,39 @@
x:Name="MenuToggleButton"/>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges" StaysOpen="False">
<StackPanel>
- <Button Content="Machine Connection" Command="{Binding ConnectCommand}" />
- <Button Content="Disconnect Machine" Command="{Binding DisconnectCommand}" />
+ <Button Command="{Binding ConnectCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="LanConnect" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Machine Connection</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button Command="{Binding DisconnectCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="LanDisconnect" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Disconnect Machine</TextBlock>
+ </StackPanel>
+ </Button>
+ <Separator/>
+ <Button IsEnabled="{Binding IsModuleLoaded}" Command="{Binding OpenModuleInWindowCommand}" CommandParameter="{Binding CurrentModule}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="ArrowTopRight" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Open Module In New Window</TextBlock>
+ </StackPanel>
+ </Button>
+ <Separator/>
+ <Button Command="{Binding UpdateCenterCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="Download" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Update Center</TextBlock>
+ </StackPanel>
+ </Button>
<Separator/>
- <Button Content="Exit" />
+ <Button Command="{Binding ExitCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="CloseCircleOutline" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Exit</TextBlock>
+ </StackPanel>
+ </Button>
</StackPanel>
</materialDesign:PopupBox>
<Grid>
@@ -146,14 +197,8 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
-
+
<Button VerticalAlignment="Center" Margin="10 0 0 0" Style="{StaticResource MaterialDesignFlatButton}" FontSize="12" ToolTip="Connect to machine on the local network" BorderThickness="0" Command="{Binding ConnectCommand}">
- <!--<Button.Background>
- <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
- <GradientStop Color="White" Offset="0.4" />
- <GradientStop Color="#75E0FA" Offset="1"/>
- </LinearGradientBrush>
- </Button.Background>-->
<StackPanel Orientation="Horizontal">
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
@@ -176,6 +221,37 @@
</Grid>
</StackPanel>
</Button>
+
+ <Button Style="{StaticResource emptyButton}" Cursor="Hand" Command="{Binding UpdateCenterCommand}" Visibility="{Binding IsUpdateAvailable,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Button.ToolTip>
+ <TextBlock>
+ <Run>Version</Run>
+ <Run Text="{Binding LatestVersion}"></Run>
+ <Run>is available !</Run>
+ </TextBlock>
+ </Button.ToolTip>
+ <Image Source="/Images/update.png" Width="32" RenderTransformOrigin="0.5,0.5" RenderOptions.BitmapScalingMode="Fant">
+ <Image.RenderTransform>
+ <ScaleTransform ScaleX="1" ScaleY="1" />
+ </Image.RenderTransform>
+ <Image.Style>
+ <Style TargetType="Image">
+ <Style.Triggers>
+ <EventTrigger RoutedEvent="Loaded">
+ <EventTrigger.Actions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0.9" To="1.1" Duration="00:00:0.5" RepeatBehavior="Forever" AutoReverse="True"></DoubleAnimation>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0.9" To="1.1" Duration="00:00:0.5" RepeatBehavior="Forever" AutoReverse="True"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </EventTrigger.Actions>
+ </EventTrigger>
+ </Style.Triggers>
+ </Style>
+ </Image.Style>
+ </Image>
+ </Button>
</StackPanel>
</Grid>
</Grid>
@@ -200,8 +276,8 @@
</Grid.RowDefinitions>
<Grid>
<StackPanel Margin="30 20" HorizontalAlignment="Left">
- <TextBlock Style="{StaticResource MaterialDesignDisplay1TextBlock}">Welcome to Machine Studio</TextBlock>
- <TextBlock HorizontalAlignment="Right" Margin="0 5 -130 0" FontStyle="Italic" Style="{StaticResource MaterialDesignSubheadingTextBlock}" Foreground="{StaticResource AccentColorBrush}">Select Your Studio Module...</TextBlock>
+ <TextBlock FontSize="35">Welcome to Machine Studio</TextBlock>
+ <TextBlock HorizontalAlignment="Left" Margin="350 5 0 0" FontStyle="Italic" FontSize="16">The below modules are displayed according to your user roles and permissions.</TextBlock>
</StackPanel>
</Grid>
@@ -216,7 +292,7 @@
<ItemsControl.ItemTemplate>
<DataTemplate>
- <materialDesign:Card Width="300" Margin="10" Height="400">
+ <materialDesign:Card Width="300" Margin="10" Height="400" Visibility="{Binding InNewWindow,Converter={StaticResource BooleanToVisibilityInverseConverter}}">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="180" />
@@ -234,8 +310,18 @@
<StackPanel Grid.Row="2" Margin="8" HorizontalAlignment="Right" Orientation="Horizontal">
<materialDesign:PopupBox Padding="2,0,2,0" Style="{StaticResource MaterialDesignToolPopupBox}">
<StackPanel>
- <Button Content="More" />
- <Button Content="Options" />
+ <Button Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.OpenModuleInWindowCommand}" CommandParameter="{Binding}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="ArrowTopRight" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Start in new window</TextBlock>
+ </StackPanel>
+ </Button>
+ <Button>
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="Settings" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Settings</TextBlock>
+ </StackPanel>
+ </Button>
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs
index e6e1557f3..c40904173 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml.cs
@@ -69,10 +69,13 @@ namespace Tango.MachineStudio.UI.Views
{
ThreadsHelper.InvokeUI(() =>
{
+ Grid grid = new Grid();
+ grid.Children.Add(module.MainView);
+
TransitionControl.Controls.Add(new ContentControl()
{
Tag = module.Name,
- Content = module.MainView
+ Content = grid,
});
_loader.UserModules.Add(module);
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml
new file mode 100644
index 000000000..dabbaab94
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml
@@ -0,0 +1,194 @@
+<UserControl x:Class="Tango.MachineStudio.UI.Views.UpdateView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:vm="clr-namespace:Tango.MachineStudio.UI.ViewModels"
+ xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="1080" d:DesignWidth="1920" DataContext="{Binding UpdateViewVM, Source={StaticResource Locator}}" Background="White" FontSize="20">
+ <Grid>
+ <Grid.Background>
+ <ImageBrush ImageSource="/Images/White-Abstract.png" />
+ </Grid.Background>
+ <Grid MaxWidth="1200" MaxHeight="700">
+ <DockPanel>
+ <Grid DockPanel.Dock="Top" HorizontalAlignment="Center">
+ <Grid.Effect>
+ <DropShadowEffect BlurRadius="200" ShadowDepth="0" Opacity="0.5" />
+ </Grid.Effect>
+ <StackPanel Orientation="Horizontal">
+ <Image Source="/Images/update.png" Width="100" />
+ <TextBlock Margin="10 0 0 0" VerticalAlignment="Center" FontSize="70">Update Center</TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <Grid DockPanel.Dock="Bottom">
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button MinWidth="140" Height="40" Style="{StaticResource MaterialDesignFlatButton}" Command="{Binding BackCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="KeyboardBackspace" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">BACK TO APPLICATION</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+
+ <Grid>
+ <Border Margin="0 10 0 10" BorderThickness="0 0 0 2" BorderBrush="DimGray">
+ <ContentControl>
+ <ContentControl.Style>
+ <Style TargetType="ContentControl">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.CheckingForUpdate}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel VerticalAlignment="Center">
+ <mahApps:ProgressRing Width="120" Height="120" Foreground="DimGray" />
+ <TextBlock HorizontalAlignment="Center" Margin="0 30 0 0">Checking for updates...</TextBlock>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpdateAvailable}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <Image Source="/Images/new-version.png" Width="64"></Image>
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+ <TextBlock VerticalAlignment="Center" Margin="0 20 0 0">
+ <Run>Version</Run>
+ <Run Text="{Binding LatestVersion}" FontWeight="SemiBold" Foreground="{StaticResource AccentColorBrush}"></Run>
+ <Run>is available!</Run>
+ </TextBlock>
+ </StackPanel>
+ <TextBlock FontSize="12" TextAlignment="Center" Padding="20" Margin="0 0 0 40">
+ <Run>A new version of Machine Studio is available for download</Run>
+ <LineBreak/>
+ <Run>Click 'Update' to start the update process.</Run>
+ </TextBlock>
+ <Button MinWidth="140" Height="40" Margin="0 0 0 0" Width="200" Command="{Binding UpdateCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="Download" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">UPDATE</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Downloading}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <TextBlock HorizontalAlignment="Center">
+ <Run>Downloading version</Run>
+ <Run Text="{Binding LatestVersion,FallbackValue='0.0.0.0'}"></Run>
+ <Run>, please wait...</Run>
+ </TextBlock>
+ <ProgressBar Height="10" Foreground="DimGray" Margin="0 20 0 0" Maximum="100" Value="{Binding DownloadProgress}"></ProgressBar>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Updating}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <TextBlock HorizontalAlignment="Center">
+ <Run>Updating Machine Studio, please wait...</Run>
+ </TextBlock>
+ <ProgressBar Height="10" Foreground="DimGray" Margin="0 20 0 0" Maximum="100" Value="{Binding UpdateProgress}"></ProgressBar>
+
+ <TextBlock TextTrimming="CharacterEllipsis" Text="{Binding CurrentUpdateFile}" FontSize="10" Margin="0 10 0 0" TextAlignment="Center" Foreground="DimGray"></TextBlock>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpdateCompleted}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <materialDesign:PackIcon Kind="Check" Width="100" Height="100" Foreground="#1CBB1C" HorizontalAlignment="Center" />
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="0 20 0 0">Your version of Machine Studio is up to date!</TextBlock>
+ </StackPanel>
+
+ <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="12">Please restart Machine Studio in order to apply the changes.</TextBlock>
+
+ <Button MinWidth="140" Height="40" Margin="0 50 0 0" Width="200" Command="{Binding RestartCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="BackupRestore" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">RESTART</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.UpToDate}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <materialDesign:PackIcon Kind="Check" Width="100" Height="100" Foreground="#1CBB1C" HorizontalAlignment="Center" />
+ <StackPanel Orientation="Horizontal">
+ <TextBlock VerticalAlignment="Center" Margin="0 20 0 0">Your version of Machine Studio is up to date!</TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static vm:UpdateStatus.Error}">
+ <Setter Property="Content">
+ <Setter.Value>
+ <Grid>
+ <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
+ <materialDesign:PackIcon Kind="Alert" Width="100" Height="100" Foreground="#FF5F5F" HorizontalAlignment="Center" />
+ <TextBlock VerticalAlignment="Center" Margin="0 20 0 0" HorizontalAlignment="Center">Error updating machine studio</TextBlock>
+ <TextBlock HorizontalAlignment="Center" Margin="0 10 0 0" FontSize="12" TextAlignment="Center">
+ <Run>An error occurred while updating your software.</Run>
+ <LineBreak/>
+ <Run>press 'Try Again' to give it another try.</Run>
+ </TextBlock>
+ <Button MinWidth="140" Height="40" Margin="0 50 0 0" Width="200" Command="{Binding TryAgainCommand}">
+ <StackPanel Orientation="Horizontal">
+ <materialDesign:PackIcon Kind="BackupRestore" Width="24" Height="24" />
+ <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">TRY AGAIN</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Setter.Value>
+ </Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ContentControl.Style>
+ </ContentControl>
+ </Border>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs
new file mode 100644
index 000000000..75b74f65d
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/UpdateView.xaml.cs
@@ -0,0 +1,42 @@
+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;
+using Tango.MachineStudio.UI.ViewModels;
+using static Tango.SharedUI.Controls.MultiTransitionControl;
+
+namespace Tango.MachineStudio.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for UpdateView.xaml
+ /// </summary>
+ public partial class UpdateView : UserControl, ITransitionView
+ {
+ private UpdateViewVM _vm;
+
+ public UpdateView()
+ {
+ InitializeComponent();
+
+ this.Loaded += (x, y) =>
+ {
+ _vm = DataContext as UpdateViewVM;
+ };
+ }
+
+ public void OnTransitionCompleted()
+ {
+ _vm.OnNavigatedInto();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml
new file mode 100644
index 000000000..8721cfd6a
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml
@@ -0,0 +1,97 @@
+<mahapps:MetroWindow x:Class="Tango.MachineStudio.UI.Windows.ModuleWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows"
+ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:views="clr-namespace:Tango.MachineStudio.UI.Views"
+ xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ mc:Ignorable="d"
+ Title="{Binding RelativeSource={RelativeSource Self},Path=ModuleContext.Module.Name}" Height="800" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}">
+
+ <Window.Resources>
+ <converters:StringEllipsisConverter x:Key="StringEllipsisConverter" />
+ </Window.Resources>
+
+ <Grid>
+ <Grid.Background>
+ <ImageBrush ImageSource="/Images/White-Abstract.png" Stretch="Fill"></ImageBrush>
+ </Grid.Background>
+ <Viewbox Stretch="Fill" UseLayoutRounding="True" SnapsToDevicePixels="True">
+ <Grid Width="1920" Height="1145">
+ <Grid>
+ <DockPanel>
+ <materialDesign:ColorZone Padding="16" materialDesign:ShadowAssist.ShadowDepth="Depth2"
+ Mode="PrimaryMid" DockPanel.Dock="Top">
+ <DockPanel>
+ <Grid>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Height="60" HorizontalAlignment="Center">
+ <Image Source="/Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image>
+ <TextBlock Text="Machine Studio" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36"/>
+ </StackPanel>
+ </Grid>
+ </DockPanel>
+ </materialDesign:ColorZone>
+
+ <Grid>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Grid Grid.Row="1" x:Name="grid">
+
+ </Grid>
+ </Grid>
+
+ <Border HorizontalAlignment="Right" Margin="0 -1 10 0" VerticalAlignment="Top" Width="300" Height="40" Padding="5" CornerRadius="0 0 30 30" BorderThickness="1 0 1 1" BorderBrush="DimGray">
+ <Border.Style>
+ <Style TargetType="Border">
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="1" ScaleY="0"></ScaleTransform>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding NotificationProvider.HasTaskItems}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard HandoffBehavior="Compose">
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" FillBehavior="HoldEnd" To="1" Duration="00:00:0.2"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ <DataTrigger.ExitActions>
+ <BeginStoryboard HandoffBehavior="Compose">
+ <Storyboard>
+ <DoubleAnimation BeginTime="00:00:02" FillBehavior="HoldEnd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" From="1" Duration="00:00:0.5"></DoubleAnimation>
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.ExitActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Border.Style>
+ <Border.Background>
+ <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
+ <GradientStop Color="#03A9F4"/>
+ <GradientStop Color="#0081BB" Offset="1"/>
+ </LinearGradientBrush>
+ </Border.Background>
+
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20 0 0 0">
+ <mahapps:ProgressRing Width="24" Height="24" Foreground="White"></mahapps:ProgressRing>
+ <TextBlock Text="{Binding NotificationProvider.CurrentTaskItem.Message,Converter={StaticResource StringEllipsisConverter},ConverterParameter=35}" Foreground="White" VerticalAlignment="Center" Margin="10 0 0 0" TextWrapping="Wrap"></TextBlock>
+ </StackPanel>
+ </Border>
+ </Grid>
+ </DockPanel>
+ </Grid>
+ </Grid>
+ </Viewbox>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs
new file mode 100644
index 000000000..7ca062645
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs
@@ -0,0 +1,44 @@
+using MahApps.Metro.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+using Tango.MachineStudio.UI.ViewModels;
+
+namespace Tango.MachineStudio.UI.Windows
+{
+ /// <summary>
+ /// Interaction logic for ModuleWindow.xaml
+ /// </summary>
+ public partial class ModuleWindow : MetroWindow
+ {
+ public ModuleWindowVM ModuleContext
+ {
+ get { return (ModuleWindowVM)GetValue(ModuleContextProperty); }
+ set { SetValue(ModuleContextProperty, value); }
+ }
+ public static readonly DependencyProperty ModuleContextProperty =
+ DependencyProperty.Register("ModuleContext", typeof(ModuleWindowVM), typeof(ModuleWindow), new PropertyMetadata(null));
+
+ public ModuleWindow()
+ {
+ InitializeComponent();
+ }
+
+ public ModuleWindow(MainViewVM mainViewVM, ModuleWindowVM moduleVM, FrameworkElement view) : this()
+ {
+ DataContext = mainViewVM;
+ ModuleContext = moduleVM;
+ grid.Children.Add(view);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config
index ae67b1d1c..5dcc330a7 100644
--- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/packages.config
@@ -3,14 +3,20 @@
<package id="CommonServiceLocator" version="1.3" targetFramework="net46" />
<package id="Dragablz" version="0.0.3.197" targetFramework="net46" />
<package id="EntityFramework" version="6.0.0" targetFramework="net46" />
+ <package id="FluentFTP" version="19.1.2" targetFramework="net46" />
<package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" />
<package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
+ <package id="Ionic.Zip" version="1.9.1.8" targetFramework="net46" />
<package id="MahApps.Metro" version="1.5.0" targetFramework="net46" />
<package id="MaterialDesignColors" version="1.1.2" targetFramework="net46" />
<package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net46" />
<package id="MvvmLight" version="5.3.0.0" targetFramework="net46" />
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net46" />
<package id="SimpleValidator" version="0.6.1.0" targetFramework="net46" />
+ <package id="System.Data.SQLite" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.Core" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.EF6" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.Linq" version="1.0.106.0" targetFramework="net46" />
<package id="System.Reactive" version="3.1.1" targetFramework="net46" />
<package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" />
<package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net46" />