aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-11 03:41:20 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-03-11 03:41:20 +0200
commite774f9a90fd812a9de8c3efe966a759bee8be703 (patch)
treeda7a59af6af40ff810254df9e08f6a0f5a31fe1c /Software
parenteb793f20dc078a304a423a481e5bb0eddce71471 (diff)
downloadTango-e774f9a90fd812a9de8c3efe966a759bee8be703.tar.gz
Tango-e774f9a90fd812a9de8c3efe966a759bee8be703.zip
Working on FSE/PPC performance provider.
Implemented resolution service. a lot of work!
Diffstat (limited to 'Software')
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/ConsoleViewVM.cs29
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs24
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/ConsoleView.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml49
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/RemoteDesktopView.xaml149
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Console/IConsoleService.cs16
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.cs106
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.xaml106
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.cs34
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.xaml32
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs14
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Bold.ttfbin0 -> 335416 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Regular.ttfbin0 -> 330800 bytes
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/IPerformanceProvider.cs13
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/PerformancePackageEventArgs.cs14
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/IResolutionService.cs20
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionHelper.cs227
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionMode.cs15
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml2
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml1
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml64
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj27
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml6
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Console/DefaultConsoleService.cs53
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Performance/DefaultPerformanceProvider.cs46
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Resolution/DefaultResolutionService.cs121
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj8
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs12
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs5
-rw-r--r--Software/Visual_Studio/Installers/VS Extensions/PropMan.vsixbin0 -> 45195 bytes
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Console/DefaultConsoleEngineService.cs22
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/DefaultPerformanceService.cs227
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/IPerformanceService.cs14
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj4
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs3
-rw-r--r--Software/Visual_Studio/Tango.Console/ConsoleExecutionEngine.cs21
-rw-r--r--Software/Visual_Studio/Tango.Console/Network/ConsoleCommandRequest.cs (renamed from Software/Visual_Studio/Tango.Console/ConsoleCommandDTO.cs)4
-rw-r--r--Software/Visual_Studio/Tango.Console/Network/ConsoleCommandResponse.cs20
-rw-r--r--Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryRequest.cs13
-rw-r--r--Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryResponse.cs13
-rw-r--r--Software/Visual_Studio/Tango.Console/Tango.Console.csproj5
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationRequest.cs12
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationResponse.cs12
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/InformationPackage.cs18
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/MachineProperty.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/PerformancePackage.cs25
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesRequest.cs12
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesResponse.cs13
-rw-r--r--Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj9
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventArgs.cs39
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventContainer.cs95
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Binding/BindingProperty.cs38
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs26
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/StringToTitleCaseConverter.cs30
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj4
58 files changed, 1818 insertions, 83 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/ConsoleViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/ConsoleViewVM.cs
index fd1567e0d..3ccab26da 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/ConsoleViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/ConsoleViewVM.cs
@@ -4,7 +4,10 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Console;
+using Tango.Console.Network;
+using Tango.Core.DI;
using Tango.FSE.Common;
+using Tango.FSE.Common.Console;
namespace Tango.FSE.PPCConsole.ViewModels
{
@@ -12,6 +15,9 @@ namespace Tango.FSE.PPCConsole.ViewModels
{
private List<ConsoleSuggestion> _lastSuggestions;
+ [TangoInject]
+ public IConsoleService ConsoleService { get; set; }
+
private ConsoleControlVM _consoleVM;
public ConsoleControlVM ConsoleVM
{
@@ -27,17 +33,34 @@ namespace Tango.FSE.PPCConsole.ViewModels
ConsoleVM.Clear();
}
+ public override void OnApplicationStarted()
+ {
+ ConsoleService.Initialized += ConsoleService_Initialized;
+ }
+
+ private void ConsoleService_Initialized(object sender, EventArgs e)
+ {
+ ConsoleVM.Clear();
+ ConsoleVM.CurrentCommand.WorkingFolder = ConsoleService.CurrentDirectory;
+ }
+
private async void ConsoleVM_CommandExecuting(object sender, ConsoleCommandExecutingEventArgs e)
{
try
{
- var result = await MachineProvider.MachineOperator.SendGenericRequest<ConsoleCommandDTO, ConsoleCommandExecutionResult>(new ConsoleCommandDTO()
+ var response = await ConsoleService.ExecuteCommand(new ConsoleCommandRequest()
{
Command = e.Command.CommandText,
WorkingFolder = e.Command.WorkingFolder,
});
- _lastSuggestions = result.Suggestions;
- e.Complete(result);
+
+ _lastSuggestions = response.Suggestions;
+ e.Complete(new ConsoleCommandExecutionResult()
+ {
+ Output = response.Output,
+ Suggestions = response.Suggestions,
+ WorkingFolder = response.WorkingFolder
+ });
}
catch (Exception ex)
{
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
index cd12bcdd9..8b9c4169a 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs
@@ -13,6 +13,30 @@ namespace Tango.FSE.PPCConsole.ViewModels
{
public class MainViewVM : FSEViewModel
{
+ public enum NavigationView
+ {
+ ConsoleView,
+ RemoteDesktopView,
+ }
+
+ private NavigationView _selectedView;
+ public NavigationView SelectedView
+ {
+ get { return _selectedView; }
+ set
+ {
+ _selectedView = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ public override void OnNavigatedTo()
+ {
+ base.OnNavigatedTo();
+ SelectedView = NavigationView.RemoteDesktopView;
+ }
+
+
public override void OnApplicationReady()
{
base.OnApplicationReady();
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/ConsoleView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/ConsoleView.xaml
index 0a26fc8b4..1aad6fa58 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/ConsoleView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/ConsoleView.xaml
@@ -11,8 +11,8 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:ConsoleViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ConsoleViewVM}">
<Grid>
- <Border Background="#121212" BorderBrush="{StaticResource FSE_BorderBrush}" BorderThickness="1">
- <console:ConsoleControl Background="#121212" Margin="10" BorderBrush="{StaticResource FSE_BorderBrush}" SuggestionsBackground="{StaticResource FSE_PrimaryBackgroundBrush}" SuggestionsBorderBrush="{StaticResource FSE_BorderBrush}" SuggestionsForeground="Silver" DataContext="{Binding ConsoleVM}">
+ <Border Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderBrush="{StaticResource FSE_BorderBrush}" BorderThickness="1" CornerRadius="5">
+ <console:ConsoleControl Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" Margin="10" BorderBrush="{StaticResource FSE_BorderBrush}" SuggestionsBackground="{StaticResource FSE_PrimaryBackgroundBrush}" SuggestionsBorderBrush="{StaticResource FSE_BorderBrush}" SuggestionsForeground="Silver" DataContext="{Binding ConsoleVM}">
<console:ConsoleControl.BusyTemplate>
<DataTemplate>
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}" IsIndeterminate="True" Width="16" Height="16" />
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
index 1f47bf832..1b7a6ceea 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/MainView.xaml
@@ -4,42 +4,41 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:global="clr-namespace:Tango.FSE.PPCConsole"
+ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:vm="clr-namespace:Tango.FSE.PPCConsole.ViewModels"
xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Views"
xmlns:console="clr-namespace:Tango.Console;assembly=Tango.Console"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
<Grid Margin="10">
<Grid>
- <!--<Grid.ColumnDefinitions>
- <ColumnDefinition Width="200" />
- <ColumnDefinition Width="1*" />
- </Grid.ColumnDefinitions>-->
+ <Grid>
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Margin" Value="100 40"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True">
+ <Setter Property="Margin" Value="20"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+ <commonControls:FSETabControl TabsWidth="900" x:Name="tabs" SelectedObject="{Binding SelectedView,Mode=TwoWay}">
+ <local:ConsoleView Tag="COMMAND PROMPT" />
+ <local:RemoteDesktopView Tag="REMOTE DESKTOP" />
+ <ContentControl Tag="FILE SYSTEM" />
+ <ContentControl Tag="MONITORING" />
+ <ContentControl Tag="UPDATES" />
+ </commonControls:FSETabControl>
- <!--<Grid>
- <ListBox x:Name="listMenu" HorizontalContentAlignment="Stretch" Focusable="False">
- <Button Margin="5" HorizontalContentAlignment="Right" IsHitTestVisible="False" Style="{StaticResource FSE_FlatButton_ForegroundAccentHover}">CONSOLE</Button>
- <Button Margin="5" HorizontalContentAlignment="Right" IsHitTestVisible="False" Style="{StaticResource FSE_FlatButton_ForegroundAccentHover}">REMOTE DESKTOP</Button>
- </ListBox>
- </Grid>-->
-
- <TabControl Margin="10 0 0 0" Background="Transparent" BorderThickness="0" Padding="0" Grid.Column="1" SelectedIndex="{Binding ElementName=listMenu,Path=SelectedIndex,Mode=TwoWay}">
- <TabItem Header="REMOTE DESKTOP" Visibility="Collapsed">
- <!--REMOTE DESKTOP-->
- <Grid Grid.Column="1">
- <local:RemoteDesktopView />
- </Grid>
- </TabItem>
- <TabItem Header="CONSOLE" Visibility="Collapsed">
- <!--CONSOLE-->
- <Grid>
- <local:ConsoleView />
- </Grid>
- </TabItem>
- </TabControl>
+ <TextBlock resolution:ResolutionHelper.MinWidth="1500" Margin="10 0 0 0" FontFamily="{StaticResource hand}" FontSize="{StaticResource FSE_ModuleHeaderFontSize}" Foreground="{StaticResource FSE_PrimaryAccentDarkBrush}" VerticalAlignment="Top" HorizontalAlignment="Left" Text="{Binding ElementName=tabs,Path=SelectedElement.Tag,Converter={StaticResource StringToTitleCaseConverter}}"></TextBlock>
+ </Grid>
</Grid>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/RemoteDesktopView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/RemoteDesktopView.xaml
index 110fcbcbd..644bfabba 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/RemoteDesktopView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Views/RemoteDesktopView.xaml
@@ -5,11 +5,13 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:global="clr-namespace:Tango.FSE.PPCConsole"
xmlns:vm="clr-namespace:Tango.FSE.PPCConsole.ViewModels"
+ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common"
xmlns:local="clr-namespace:Tango.FSE.PPCConsole.Views"
+ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
xmlns:console="clr-namespace:Tango.Console;assembly=Tango.Console"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
- d:DesignHeight="800" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:RemoteDesktopViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RemoteDesktopViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
+ d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:RemoteDesktopViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RemoteDesktopViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
<Grid>
<DockPanel>
<Border DockPanel.Dock="Right" CornerRadius="15" BorderBrush="{StaticResource FSE_BorderBrush}" BorderThickness="1">
@@ -39,36 +41,147 @@
</Border>
<Grid IsHitTestVisible="False">
- <material:PackIcon Visibility="{Binding RemoteDesktopProvider.IsWebRtcActive,Converter={StaticResource BooleanToVisibilityConverter}}" Kind="LightningBolt" HorizontalAlignment="Right" VerticalAlignment="Top" Width="16" Height="16" Margin="10" Foreground="{StaticResource FSE_GreenBrush}" />
+ <material:PackIcon Visibility="{Binding RemoteDesktopProvider.IsWebRtcActive,Converter={StaticResource BooleanToVisibilityConverter}}" Kind="LightningBoltCircle" HorizontalAlignment="Right" VerticalAlignment="Top" Width="16" Height="16" Margin="10 8 30 10" Foreground="{StaticResource FSE_GreenBrush}" />
</Grid>
</Grid>
</Border>
<Grid>
- <DockPanel MaxWidth="700" Margin="0 100 0 0">
+ <DockPanel>
+ <DockPanel.Style>
+ <Style TargetType="DockPanel">
+ <Setter Property="Margin" Value="0 100 100 50"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True">
+ <Setter Property="Margin" Value="0 20 100 0"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </DockPanel.Style>
<StackPanel DockPanel.Dock="Top">
<DockPanel>
- <TextBlock VerticalAlignment="Center" FontSize="{StaticResource FSE_ModuleHeaderFontSize}">REMOTE DESKTOP</TextBlock>
- <Grid HorizontalAlignment="Right" Margin="0 0 100 0" Width="150" Height="150">
- <Image Source="{StaticResource FSE_Machine_Full}" VerticalAlignment="Top" HorizontalAlignment="Right" RenderOptions.BitmapScalingMode="Fant" Width="120" Stretch="Uniform" />
- <Image Source="../Images/desktop.png" Stretch="Uniform" Width="90" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
- </Grid>
+ <TextBlock VerticalAlignment="Center" FontStyle="Italic" FontSize="{StaticResource FSE_ModuleHeaderFontSize}">REMOTE DESKTOP</TextBlock>
+ <Viewbox Stretch="Uniform" HorizontalAlignment="Right" Margin="0 0 100 0">
+ <Viewbox.Style>
+ <Style TargetType="Viewbox">
+ <Setter Property="Width" Value="100"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True">
+ <Setter Property="Width" Value="50"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Viewbox.Style>
+ <Grid Width="100" Height="100">
+ <Image Source="{StaticResource FSE_Machine_Full}" VerticalAlignment="Top" HorizontalAlignment="Right" RenderOptions.BitmapScalingMode="Fant" Width="90" Stretch="Uniform" />
+ <Image Source="../Images/desktop.png" Stretch="Uniform" Width="60" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
+ </Grid>
+ </Viewbox>
</DockPanel>
<Rectangle StrokeThickness="1" Stroke="{StaticResource FSE_BorderBrush}" Height="1" StrokeDashArray="4" Margin="0 20 0 0" />
</StackPanel>
<Grid>
-
+ <DockPanel Margin="0 20 0 0">
+ <StackPanel DockPanel.Dock="Top">
+ <TextBlock TextWrapping="Wrap">
+ <Run>Remote desktop allows you to view and control the currently connected machine tablet PC screen.</Run>
+ <LineBreak/>
+ <Run>Press 'start' to start a remote desktop session.</Run>
+ </TextBlock>
+ </StackPanel>
+ <Grid DockPanel.Dock="Bottom">
+
+ <Grid HorizontalAlignment="Left">
+ <Grid.Style>
+ <Style TargetType="Grid">
+ <Setter Property="Margin" Value="0 0 0 0"></Setter>
+ <Setter Property="VerticalAlignment" Value="Bottom"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True">
+ <Setter Property="VerticalAlignment" Value="Top"></Setter>
+ <Setter Property="Margin" Value="0 -40 0 0"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Style>
+
+ <StackPanel Orientation="Horizontal">
+ <material:PackIcon>
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryBackgroundLighterBrush}"></Setter>
+ <Setter Property="Kind" Value="Circle"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RemoteDesktopProvider.InSession}" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RemoteDesktopProvider.IsWebRtcActive}" Value="True">
+ <Setter Property="Kind" Value="LightningBoltCircle"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ <TextBlock Margin="10 0 0 0">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Text" Value="Remote desktop disabled. No active machine connection."></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_BorderBrush}"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="False">
+ <Setter Property="Text" Value="Remote desktop disabled. No active machine connection."></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding MachineProvider.IsConnected}" Value="True">
+ <Setter Property="Text" Value="Remote desktop session is ready to start."></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RemoteDesktopProvider.InSession}" Value="True">
+ <Setter Property="Text" Value="Remote desktop session is active."></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding RemoteDesktopProvider.IsWebRtcActive}" Value="True">
+ <Setter Property="Text" Value="Remote desktop session is active using a fast communication channel."></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ </StackPanel>
+ </Grid>
+
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Height="50">
+ <controls:TextIconButton Icon="Stop" Padding="0 12" Width="200" Command="{Binding StopCommand}" IsEnabled="{Binding RemoteDesktopProvider.InSession}" Grid.Column="1" Style="{StaticResource FSE_TextIconButton_Dark}">STOP</controls:TextIconButton>
+ <controls:TextIconButton Icon="Play" Padding="0 12" Width="200" Command="{Binding StartCommand}" IsEnabled="{Binding RemoteDesktopProvider.CanStartSession}" Grid.Column="2" Margin="10 0 0 0" Height="Auto">START</controls:TextIconButton>
+ </StackPanel>
+ </Grid>
+ <Grid>
+ <StackPanel Margin="0 40 0 0">
+ <TextBlock FontStyle="Italic" Foreground="{StaticResource FSE_PrimaryAccentBrush}" FontSize="{StaticResource FSE_LargeFontSize}">Actions</TextBlock>
+
+ <UniformGrid Margin="0 10 0 0" HorizontalAlignment="Left">
+ <UniformGrid.Style>
+ <Style TargetType="UniformGrid">
+ <Setter Property="Rows" Value="3"></Setter>
+ <Setter Property="Columns" Value="1"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ResolutionService.IsLowResolution}" Value="True">
+ <Setter Property="Columns" Value="2"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </UniformGrid.Style>
+ <Button IsEnabled="{Binding RemoteDesktopProvider.InSession}" Width="250" Margin="5" Style="{StaticResource FSE_Button_Polygon}" Content="Hide PPC and open shell"/>
+
+ <Button IsEnabled="{Binding RemoteDesktopProvider.InSession}" Width="250" Margin="5" Style="{StaticResource FSE_Button_Polygon}" Content="Restart application"/>
+
+ <Button IsEnabled="{Binding RemoteDesktopProvider.InSession}" Width="250" Margin="5" Style="{StaticResource FSE_Button_Polygon}" Content="Something else"/>
+
+ <CheckBox Margin="5" HorizontalAlignment="Center" IsEnabled="{Binding RemoteDesktopProvider.InSession,Converter={StaticResource BooleanInverseConverter}}" IsChecked="{Binding RemoteDesktopProvider.EnableWebRtc}">Enable fast communication channel</CheckBox>
+ </UniformGrid>
+ </StackPanel>
+ </Grid>
+ </DockPanel>
</Grid>
</DockPanel>
- <!--<Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="1*" />
- <ColumnDefinition Width="50*" />
- <ColumnDefinition Width="50*" />
- </Grid.ColumnDefinitions>
- <Button Command="{Binding StopCommand}" IsEnabled="{Binding RemoteDesktopProvider.InSession}" Grid.Column="1" Style="{StaticResource FSE_RaisedButton_Dark_Hover}">STOP</Button>
- <Button Command="{Binding StartCommand}" IsEnabled="{Binding RemoteDesktopProvider.CanStartSession}" Grid.Column="2" Margin="10 0 0 0" Style="{StaticResource FSE_RaisedButton_Dark_Hover}">START</Button>
- </Grid>-->
</Grid>
</DockPanel>
</Grid>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Console/IConsoleService.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Console/IConsoleService.cs
new file mode 100644
index 000000000..dd32b9b93
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Console/IConsoleService.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Console.Network;
+
+namespace Tango.FSE.Common.Console
+{
+ public interface IConsoleService
+ {
+ event EventHandler Initialized;
+ String CurrentDirectory { get; }
+ Task<ConsoleCommandResponse> ExecuteCommand(ConsoleCommandRequest request, TimeSpan? timeout = null);
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.cs
new file mode 100644
index 000000000..44cfd4872
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+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.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Tango.SharedUI;
+using Tango.SharedUI.Controls;
+using static Tango.SharedUI.Controls.NavigationControl;
+
+namespace Tango.FSE.Common.Controls
+{
+ [ContentProperty(nameof(Elements))]
+ public class FSETabControl : Control
+ {
+ private NavigationControl _navigationControl;
+
+ public ObservableCollection<FrameworkElement> Elements
+ {
+ get { return (ObservableCollection<FrameworkElement>)GetValue(ElementsProperty); }
+ set { SetValue(ElementsProperty, value); }
+ }
+ public static readonly DependencyProperty ElementsProperty =
+ DependencyProperty.Register("Elements", typeof(ObservableCollection<FrameworkElement>), typeof(FSETabControl), new PropertyMetadata(null));
+
+ public FrameworkElement SelectedElement
+ {
+ get { return (FrameworkElement)GetValue(SelectedElementProperty); }
+ set { SetValue(SelectedElementProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedElementProperty =
+ DependencyProperty.Register("SelectedElement", typeof(FrameworkElement), typeof(FSETabControl), new PropertyMetadata(null));
+
+ public TransitionTypes TransitionType
+ {
+ get { return (TransitionTypes)GetValue(TransitionTypeProperty); }
+ set { SetValue(TransitionTypeProperty, value); }
+ }
+ public static readonly DependencyProperty TransitionTypeProperty =
+ DependencyProperty.Register("TransitionType", typeof(TransitionTypes), typeof(FSETabControl), new PropertyMetadata(TransitionTypes.Slide));
+
+ public bool TransitionAlwaysFades
+ {
+ get { return (bool)GetValue(TransitionAlwaysFadesProperty); }
+ set { SetValue(TransitionAlwaysFadesProperty, value); }
+ }
+ public static readonly DependencyProperty TransitionAlwaysFadesProperty =
+ DependencyProperty.Register("TransitionAlwaysFades", typeof(bool), typeof(FSETabControl), new PropertyMetadata(false));
+
+ public Duration TransitionDuration
+ {
+ get { return (Duration)GetValue(TransitionDurationProperty); }
+ set { SetValue(TransitionDurationProperty, value); }
+ }
+ public static readonly DependencyProperty TransitionDurationProperty =
+ DependencyProperty.Register("TransitionDuration", typeof(Duration), typeof(FSETabControl), new PropertyMetadata(new Duration(TimeSpan.FromSeconds(0.2))));
+
+ public object SelectedObject
+ {
+ get { return (object)GetValue(SelectedObjectProperty); }
+ set { SetValue(SelectedObjectProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedObjectProperty =
+ DependencyProperty.Register("SelectedObject", typeof(object), typeof(FSETabControl), new PropertyMetadata(null));
+
+ public double TabsWidth
+ {
+ get { return (double)GetValue(TabsWidthProperty); }
+ set { SetValue(TabsWidthProperty, value); }
+ }
+ public static readonly DependencyProperty TabsWidthProperty =
+ DependencyProperty.Register("TabsWidth", typeof(double), typeof(FSETabControl), new PropertyMetadata(double.NaN));
+
+ public FSETabControl()
+ {
+ Elements = new ObservableCollection<FrameworkElement>();
+ }
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+ _navigationControl = GetTemplateChild("navigation") as NavigationControl;
+ _navigationControl.SelectedElementChanged += (x, e) =>
+ {
+ SelectedElement = e;
+ };
+
+ _navigationControl.Elements = Elements;
+ }
+
+ static FSETabControl()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(FSETabControl), new FrameworkPropertyMetadata(typeof(FSETabControl)));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.xaml
new file mode 100644
index 000000000..73aa05931
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/FSETabControl.xaml
@@ -0,0 +1,106 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.FSE.Common.Controls">
+
+ <Style TargetType="{x:Type local:FSETabControl}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type local:FSETabControl}">
+ <Border Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}">
+
+ <DockPanel>
+ <Grid DockPanel.Dock="Top" Height="50">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="1*" />
+ </Grid.ColumnDefinitions>
+ <Rectangle Grid.Column="0" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
+ <ListBox x:Name="listTabs" Grid.Column="1" DisplayMemberPath="Tag" ItemsSource="{Binding ElementName=navigation,Path=Elements}" SelectedItem="{Binding ElementName=navigation,Path=SelectedElement,Mode=TwoWay}" SelectedIndex="0" Width="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TabsWidth}">
+ <ListBox.Style>
+ <Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
+ <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"></Setter>
+ <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"></Setter>
+ <Setter Property="ItemsPanel">
+ <Setter.Value>
+ <ItemsPanelTemplate>
+ <UniformGrid Margin="15 0 0 0" Columns="{Binding RelativeSource={RelativeSource AncestorType=ListBox},Path=Items.Count}" IsItemsHost="True"></UniformGrid>
+ </ItemsPanelTemplate>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="ItemContainerStyle">
+ <Setter.Value>
+ <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
+ <Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
+ <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundBrush}"></Setter>
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ListBoxItem">
+ <Grid x:Name="grid" Margin="-15 0 0 0" Background="Transparent">
+ <Viewbox Stretch="Fill">
+ <Grid>
+ <Polygon Fill="{TemplateBinding Background}" Stretch="Fill" Points="0,30 15,0 85,0 100,30"></Polygon>
+ <Polygon Fill="White" Stretch="Fill" Points="0,30 15,0 85,0 100,30" IsHitTestVisible="False" Opacity="0.1">
+ <Polygon.Style>
+ <Style TargetType="Polygon">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},Path=IsMouseOver}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Polygon.Style>
+ </Polygon>
+ <Polyline Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" Stretch="Fill" Points="0,30 15,0 85,0 100,30" />
+ <Rectangle VerticalAlignment="Bottom" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" StrokeThickness="1" />
+ </Grid>
+ </Viewbox>
+ <ContentPresenter Content="{Binding Tag}" TextElement.Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Grid>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <Trigger Property="IsSelected" Value="True">
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryAccentDarkBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="FontWeight" Value="SemiBold"></Setter>
+ <Setter Property="Panel.ZIndex" Value="200"></Setter>
+ </Trigger>
+ <Trigger Property="IsSelected" Value="False">
+ <Setter Property="Panel.ZIndex" Value="-1"></Setter>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </ListBox.Style>
+ </ListBox>
+ <Rectangle Grid.Column="2" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="{StaticResource FSE_PrimaryAccentDarkBrush}" />
+ </Grid>
+
+ <Border Margin="0 -2 0 0" Padding="10">
+ <controls:NavigationControl x:Name="navigation" SelectedObject="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=SelectedObject,Mode=TwoWay}" TransitionAlwaysFades="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TransitionAlwaysFades}" TransitionType="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TransitionType}" TransitionDuration="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=TransitionDuration}"/>
+ </Border>
+ </DockPanel>
+
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.cs
new file mode 100644
index 000000000..31bcee5cd
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.cs
@@ -0,0 +1,34 @@
+using MaterialDesignThemes.Wpf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.FSE.Common.Controls
+{
+ public class TextIconButton : Button
+ {
+ static TextIconButton()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(TextIconButton), new FrameworkPropertyMetadata(typeof(TextIconButton)));
+ }
+
+ public PackIconKind Icon
+ {
+ get { return (PackIconKind)GetValue(IconProperty); }
+ set { SetValue(IconProperty, value); }
+ }
+ public static readonly DependencyProperty IconProperty =
+ DependencyProperty.Register("Icon", typeof(PackIconKind), typeof(TextIconButton), new PropertyMetadata(PackIconKind.BorderNone));
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.xaml
new file mode 100644
index 000000000..eb8d823f7
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/TextIconButton.xaml
@@ -0,0 +1,32 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.Common.Controls">
+
+ <Style TargetType="{x:Type local:TextIconButton}" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <DockPanel>
+ <material:PackIcon Margin="-5 0 0 0" Width="Auto" Height="Auto" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:TextIconButton},Path=Icon}" VerticalAlignment="Center" />
+ <Label VerticalAlignment="Center" Content="{Binding}"></Label>
+ </DockPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style x:Key="FSE_TextIconButton_Dark" TargetType="{x:Type local:TextIconButton}" BasedOn="{StaticResource FSE_RaisedButton_Dark_Hover}">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <DockPanel>
+ <material:PackIcon Margin="-5 0 0 0" Width="Auto" Height="Auto" Kind="{Binding RelativeSource={RelativeSource AncestorType=local:TextIconButton},Path=Icon}" VerticalAlignment="Center" />
+ <Label VerticalAlignment="Center" Content="{Binding}"></Label>
+ </DockPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
index 91aeb3d64..75d9e593c 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs
@@ -21,7 +21,9 @@ using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Gateway;
using Tango.FSE.Common.Navigation;
using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Performance;
using Tango.FSE.Common.RemoteDesktop;
+using Tango.FSE.Common.Resolution;
using Tango.Settings;
using Tango.SharedUI;
using static Tango.SharedUI.Controls.NavigationControl;
@@ -91,6 +93,18 @@ namespace Tango.FSE.Common
public IRemoteDesktopProvider RemoteDesktopProvider { get; set; }
/// <summary>
+ /// Gets or sets the performance provider.
+ /// </summary>
+ [TangoInject]
+ public IPerformanceProvider PerformanceProvider { get; set; }
+
+ /// <summary>
+ /// Gets or sets the resolution service.
+ /// </summary>
+ [TangoInject]
+ public IResolutionService ResolutionService { get; set; }
+
+ /// <summary>
/// Gets or sets the FSE service.
/// </summary>
[TangoInject]
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Bold.ttf b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Bold.ttf
new file mode 100644
index 000000000..e7e6a8377
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Bold.ttf
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Regular.ttf b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Regular.ttf
new file mode 100644
index 000000000..278a61c8f
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Regular.ttf
Binary files differ
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/IPerformanceProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/IPerformanceProvider.cs
new file mode 100644
index 000000000..c9c4f3a9d
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/IPerformanceProvider.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Performance
+{
+ public interface IPerformanceProvider
+ {
+ event EventHandler<PerformancePackageEventArgs> PerformancePackageAvailable;
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/PerformancePackageEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/PerformancePackageEventArgs.cs
new file mode 100644
index 000000000..669890a29
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Performance/PerformancePackageEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Integration.ExternalBridge.Network.Performance;
+
+namespace Tango.FSE.Common.Performance
+{
+ public class PerformancePackageEventArgs : EventArgs
+ {
+ public PerformancePackage Package { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/IResolutionService.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/IResolutionService.cs
new file mode 100644
index 000000000..9b9f04bbc
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/IResolutionService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.FSE.Common.Resolution
+{
+ public interface IResolutionService
+ {
+ event EventHandler<ResolutionMode> ResolutionModeChanged;
+ event EventHandler<SizeChangedEventArgs> ResolutionChanged;
+ ResolutionMode Resolution { get; }
+ bool IsLowResolution { get; }
+ bool IsHighResolution { get; }
+ double ResolutionWidth { get; }
+ double ResolutionHeight { get; }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionHelper.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionHelper.cs
new file mode 100644
index 000000000..6caee944a
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionHelper.cs
@@ -0,0 +1,227 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core.DI;
+
+namespace Tango.FSE.Common.Resolution
+{
+ public static class ResolutionHelper
+ {
+ private static List<FrameworkElement> _elements;
+ private static IResolutionService _resolutionService;
+
+ static ResolutionHelper()
+ {
+ _elements = new List<FrameworkElement>();
+ var resolutionService = TangoIOC.Default.GetInstance<IResolutionService>();
+ _resolutionService = resolutionService;
+
+ if (resolutionService != null)
+ {
+ resolutionService.ResolutionModeChanged += ResolutionService_ResolutionModeChanged;
+ resolutionService.ResolutionChanged += ResolutionService_ResolutionChanged;
+ }
+ }
+
+ private static void ResolutionService_ResolutionChanged(object sender, SizeChangedEventArgs e)
+ {
+ foreach (var element in _elements)
+ {
+ ApplyElementSetting(element);
+ }
+ }
+
+ private static void ResolutionService_ResolutionModeChanged(object sender, ResolutionMode mode)
+ {
+ foreach (var element in _elements)
+ {
+ ApplyElementSetting(element);
+ }
+ }
+
+ private static void ApplyElementSetting(FrameworkElement element)
+ {
+ if (_resolutionService != null)
+ {
+ var mode = GetMode(element);
+ if (mode != ResolutionMode.None)
+ {
+ if (mode == _resolutionService.Resolution)
+ {
+ element.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ element.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ var width = GetMinWidth(element);
+
+ if (!Double.IsNaN(width))
+ {
+ if (_resolutionService.ResolutionWidth >= width)
+ {
+ element.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ element.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ var height = GetMinHeight(element);
+
+ if (!Double.IsNaN(height))
+ {
+ if (_resolutionService.ResolutionHeight >= height)
+ {
+ element.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ element.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ if (!Double.IsNaN(width) && !Double.IsNaN(height))
+ {
+ if (_resolutionService.ResolutionWidth >= width && _resolutionService.ResolutionHeight >= height)
+ {
+ element.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ element.Visibility = Visibility.Collapsed;
+ }
+ }
+ }
+ }
+
+ #region Mode
+
+ /// <summary>
+ /// Determined the resolution mode for the trigger.
+ /// </summary>
+ public static readonly DependencyProperty ModeProperty =
+ DependencyProperty.RegisterAttached("Mode",
+ typeof(ResolutionMode), typeof(ResolutionHelper),
+ new FrameworkPropertyMetadata(ResolutionMode.None, OnModeChanged));
+
+ private static void OnModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (!_elements.Contains(d as FrameworkElement))
+ {
+ _elements.Add(d as FrameworkElement);
+ ApplyElementSetting(d as FrameworkElement);
+ }
+ }
+
+ /// <summary>
+ /// Sets the Mode attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <param name="value">if set to <c>true</c> [value].</param>
+ public static void SetMode(FrameworkElement element, ResolutionMode value)
+ {
+ element.SetValue(ModeProperty, value);
+ }
+
+ /// <summary>
+ /// Gets the Mode attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <returns></returns>
+ public static ResolutionMode GetMode(FrameworkElement element)
+ {
+ return (ResolutionMode)element.GetValue(ModeProperty);
+ }
+
+ #endregion
+
+ #region MinWidth
+
+ /// <summary>
+ /// Determined the resolution MinWidth for the trigger.
+ /// </summary>
+ public static readonly DependencyProperty MinWidthProperty =
+ DependencyProperty.RegisterAttached("MinWidth",
+ typeof(double), typeof(ResolutionHelper),
+ new FrameworkPropertyMetadata(double.NaN, OnMinWidthChanged));
+
+ private static void OnMinWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (!_elements.Contains(d as FrameworkElement))
+ {
+ _elements.Add(d as FrameworkElement);
+ ApplyElementSetting(d as FrameworkElement);
+ }
+ }
+
+ /// <summary>
+ /// Sets the MinWidth attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <param name="value">if set to <c>true</c> [value].</param>
+ public static void SetMinWidth(FrameworkElement element, double value)
+ {
+ element.SetValue(MinWidthProperty, value);
+ }
+
+ /// <summary>
+ /// Gets the MinWidth attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <returns></returns>
+ public static double GetMinWidth(FrameworkElement element)
+ {
+ return (double)element.GetValue(MinWidthProperty);
+ }
+
+ #endregion
+
+ #region MinHeight
+
+ /// <summary>
+ /// Determined the resolution MinHeight for the trigger.
+ /// </summary>
+ public static readonly DependencyProperty MinHeightProperty =
+ DependencyProperty.RegisterAttached("MinHeight",
+ typeof(double), typeof(ResolutionHelper),
+ new FrameworkPropertyMetadata(double.NaN, OnMinHeightChanged));
+
+ private static void OnMinHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (!_elements.Contains(d as FrameworkElement))
+ {
+ _elements.Add(d as FrameworkElement);
+ ApplyElementSetting(d as FrameworkElement);
+ }
+ }
+
+ /// <summary>
+ /// Sets the MinHeight attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <param name="value">if set to <c>true</c> [value].</param>
+ public static void SetMinHeight(FrameworkElement element, double value)
+ {
+ element.SetValue(MinHeightProperty, value);
+ }
+
+ /// <summary>
+ /// Gets the MinHeight attached property.
+ /// </summary>
+ /// <param name="element">The element.</param>
+ /// <returns></returns>
+ public static double GetMinHeight(FrameworkElement element)
+ {
+ return (double)element.GetValue(MinHeightProperty);
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionMode.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionMode.cs
new file mode 100644
index 000000000..b770bbc71
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resolution/ResolutionMode.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Common.Resolution
+{
+ public enum ResolutionMode
+ {
+ None,
+ High,
+ Low
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml
index b21cd9ac6..27ba83315 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml
@@ -12,6 +12,7 @@
<Color x:Key="FSE_SemiTransparentColor">#76000000</Color>
<Color x:Key="FSE_BorderColor">#707070</Color>
<Color x:Key="FSE_PrimaryAccentColor">#03A9F4</Color>
+ <Color x:Key="FSE_PrimaryAccentDarkColor">#009FE7</Color>
<Color x:Key="FSE_ErrorColor">#FF4C4C</Color>
<Color x:Key="FSE_WarningColor">#FF914C</Color>
@@ -37,6 +38,7 @@
<SolidColorBrush x:Key="FSE_BorderBrush" Color="{StaticResource FSE_BorderColor}"></SolidColorBrush>
<SolidColorBrush x:Key="FSE_GrayBrush" Color="{StaticResource FSE_GrayColor}"></SolidColorBrush>
<SolidColorBrush x:Key="FSE_PrimaryAccentBrush" Color="{StaticResource FSE_PrimaryAccentColor}"></SolidColorBrush>
+ <SolidColorBrush x:Key="FSE_PrimaryAccentDarkBrush" Color="{StaticResource FSE_PrimaryAccentDarkColor}"></SolidColorBrush>
<SolidColorBrush x:Key="FSE_ErrorBrush" Color="{StaticResource FSE_ErrorColor}"></SolidColorBrush>
<SolidColorBrush x:Key="FSE_WarningBrush" Color="{StaticResource FSE_WarningColor}"></SolidColorBrush>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
index b750437c6..bc2425b0e 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml
@@ -4,6 +4,8 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/IconButton.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/TextIconButton.xaml" />
+ <ResourceDictionary Source="pack://application:,,,/Tango.FSE.Common;component/Controls/FSETabControl.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml
index ab98ef01c..61890fe54 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml
@@ -32,4 +32,5 @@
<converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" />
<converters:TimeSpanToMinutesConverter x:Key="TimeSpanToMinutesConverter" />
<converters:TimeSpanToSecondsConverter x:Key="TimeSpanToSecondsConverter" />
+ <converters:StringToTitleCaseConverter x:Key="StringToTitleCaseConverter" />
</ResourceDictionary> \ No newline at end of file
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml
index 6d8c0d272..d7b6e7635 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Fonts.xaml
@@ -5,6 +5,7 @@
<FontFamily x:Key="digital-7">../Fonts/#digital-7</FontFamily>
<FontFamily x:Key="flexo">../Fonts/#flexo</FontFamily>
+ <FontFamily x:Key="hand">../Fonts/#Caveat</FontFamily>
<sys:Double x:Key="FSE_DefaultFontSize">14</sys:Double>
<sys:Double x:Key="FSE_SmallFontSize">12</sys:Double>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
index 997b100e1..0543d501e 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml
@@ -53,6 +53,70 @@
<Setter Property="BorderBrush" Value="{StaticResource FSE_OrangeBrush}"></Setter>
</Style>
+ <Style x:Key="FSE_Button_Polygon" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundLightBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_BorderBrush}"></Setter>
+ <Setter Property="BorderThickness" Value="1"></Setter>
+ <Setter Property="FontSize" Value="{StaticResource FSE_SmallFontSize}"></Setter>
+ <Setter Property="Height" Value="30"></Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter>
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Background" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter>
+ <Setter Property="BorderBrush" Value="{StaticResource FSE_PrimaryAccentBrush}"></Setter>
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter Property="Foreground" Value="{StaticResource FSE_BorderBrush}"></Setter>
+ </Trigger>
+ </ControlTemplate.Triggers>
+ <Grid TextElement.Foreground="{TemplateBinding Foreground}">
+ <Viewbox Stretch="Fill">
+ <Polygon Points="0,15 15,0 285,0 300,15 285,30 15,30" Fill="{TemplateBinding Background}" Height="30" Stroke="{TemplateBinding BorderBrush}"/>
+ </Viewbox>
+ <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
+ <Canvas IsHitTestVisible="False" HorizontalAlignment="Center">
+ <Grid Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}">
+ <Ellipse x:Name="ellipse" Fill="White" RenderTransformOrigin="0.5,0.5">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Opacity" Value="0.2"></Setter>
+ <Setter Property="RenderTransform">
+ <Setter.Value>
+ <ScaleTransform ScaleX="0" ScaleY="0" />
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=IsPressed}" Value="True">
+ <DataTrigger.EnterActions>
+ <BeginStoryboard>
+ <Storyboard>
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" From="0" To="10" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="10" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="0.001" Duration="00:00:0.5" DecelerationRatio="0.8" />
+ </Storyboard>
+ </BeginStoryboard>
+ </DataTrigger.EnterActions>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ </Grid>
+ </Canvas>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
<Style TargetType="editors:AutoCompleteTextBox" >
<Setter Property="Focusable" Value="True" />
<Setter Property="BorderThickness" Value="0 0 0 1"/>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
index cb27cce2d..119ab74d4 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj
@@ -87,10 +87,13 @@
<Compile Include="Connection\IMachineProvider.cs" />
<Compile Include="Connection\MachineConnectedEventArgs.cs" />
<Compile Include="Connection\MachineDisconnectedEventArgs.cs" />
+ <Compile Include="Console\IConsoleService.cs" />
<Compile Include="Controls\ConnectedMachineIcon.xaml.cs">
<DependentUpon>ConnectedMachineIcon.xaml</DependentUpon>
</Compile>
+ <Compile Include="Controls\FSETabControl.cs" />
<Compile Include="Controls\IconButton.cs" />
+ <Compile Include="Controls\TextIconButton.cs" />
<Compile Include="Core\FSEProgress.cs" />
<Compile Include="Diagnostics\DiagnosticsFrame.cs" />
<Compile Include="Diagnostics\DiagnosticsFrameReceivedEventArgs.cs" />
@@ -118,8 +121,13 @@
<Compile Include="Notifications\SnackbarItem.cs" />
<Compile Include="Notifications\TaskItem.cs" />
<Compile Include="FSEModuleBase.cs" />
+ <Compile Include="Performance\IPerformanceProvider.cs" />
+ <Compile Include="Performance\PerformancePackageEventArgs.cs" />
<Compile Include="RemoteDesktop\DesktopFrameReceivedEventArgs.cs" />
<Compile Include="RemoteDesktop\IRemoteDesktopProvider.cs" />
+ <Compile Include="Resolution\IResolutionService.cs" />
+ <Compile Include="Resolution\ResolutionHelper.cs" />
+ <Compile Include="Resolution\ResolutionMode.cs" />
<Compile Include="Threading\IDispatcherProvider.cs" />
<Compile Include="Web\FSEWebClient.cs" />
<Compile Include="Web\FSEWebClientBase.cs" />
@@ -131,10 +139,18 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Controls\FSETabControl.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Controls\IconButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Controls\TextIconButton.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Resources\Colors.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -159,6 +175,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Themes\Generic.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
</ItemGroup>
<ItemGroup>
<Compile Include="FSESettings.cs" />
@@ -207,6 +227,8 @@
<Resource Include="Fonts\Flexo-Regular.otf" />
<Resource Include="Fonts\Flexo-Thin.otf" />
<Resource Include="Fonts\Flexo-ThinIt.otf" />
+ <Resource Include="Fonts\Caveat-Bold.ttf" />
+ <Resource Include="Fonts\Caveat-Regular.ttf" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -222,6 +244,10 @@
<Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
<Name>Tango.BL</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Console\Tango.Console.csproj">
+ <Project>{199E8359-CAD3-433D-9EED-2027652B24A4}</Project>
+ <Name>Tango.Console</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
@@ -285,6 +311,7 @@
<ItemGroup>
<Resource Include="Images\abstract1.png" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>REM nswag run "$(SolutionDir)Web\Tango.MachineService.Gateway\Nswag\GatewayClient.nswag" /variables:assembly="$(SolutionDir)Web\Tango.MachineService.Gateway\bin\Tango.MachineService.Gateway.dll",output="$(ProjectDir)Gateway\GatewayClient.cs"</PreBuildEvent>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml
new file mode 100644
index 000000000..5d4c59fd4
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Themes/Generic.xaml
@@ -0,0 +1,6 @@
+<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.FSE.Common">
+
+</ResourceDictionary>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Console/DefaultConsoleService.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Console/DefaultConsoleService.cs
new file mode 100644
index 000000000..a13adc6d1
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Console/DefaultConsoleService.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Console.Network;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.Console;
+
+namespace Tango.FSE.UI.Console
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultConsoleService : ExtendedObject, IConsoleService
+ {
+ public event EventHandler Initialized;
+
+ public string CurrentDirectory { get; private set; }
+
+ private IMachineProvider MachineProvider { get; set; }
+
+ public DefaultConsoleService(IMachineProvider machineProvider)
+ {
+ MachineProvider = machineProvider;
+ MachineProvider.MachineConnected += MachineProvider_MachineConnected;
+ }
+
+ private async void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
+ {
+ try
+ {
+ CurrentDirectory = (await MachineProvider.MachineOperator.SendGenericRequest<GetCurrentDirectoryRequest, GetCurrentDirectoryResponse>(new GetCurrentDirectoryRequest())).CurrentDirectory;
+ Initialized?.Invoke(this, new EventArgs());
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error getting remote machine current console directory.");
+ }
+ }
+
+ public async Task<ConsoleCommandResponse> ExecuteCommand(ConsoleCommandRequest request, TimeSpan? timeout = null)
+ {
+ var response = await MachineProvider.MachineOperator.SendGenericRequest<ConsoleCommandRequest, ConsoleCommandResponse>(request, new Transport.TransportRequestConfig()
+ {
+ ShouldLog = true,
+ Timeout = timeout
+ });
+
+ return response;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
index 25919916b..aa6413cab 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/MainWindow.xaml
@@ -10,7 +10,9 @@
xmlns:local="clr-namespace:Tango.FSE.UI"
xmlns:commonControls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common"
mc:Ignorable="d"
- Title="Tango FSE" Height="720" Width="1280"
+ Title="Tango FSE"
+ Height="720"
+ Width="1280"
WindowStartupLocation="CenterScreen"
TextElement.Foreground="{StaticResource FSE_PrimaryForegroundBrush}"
Background="{StaticResource FSE_PrimaryBackgroundBrush}"
@@ -18,8 +20,8 @@
TitleCharacterCasing="Normal"
UseNoneWindowStyle="True"
EnableDWMDropShadow="True"
- MinWidth="800"
- MinHeight="600"
+ MinWidth="1280"
+ MinHeight="720"
BorderThickness="1"
BorderBrush="Gray"
FontFamily="{StaticResource flexo}"
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Performance/DefaultPerformanceProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Performance/DefaultPerformanceProvider.cs
new file mode 100644
index 000000000..c9b5d8bbb
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Performance/DefaultPerformanceProvider.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.Performance;
+using Tango.Integration.ExternalBridge.Network.Performance;
+
+namespace Tango.FSE.UI.Performance
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultPerformanceProvider : ExtendedObject, IPerformanceProvider
+ {
+ public event EventHandler<PerformancePackageEventArgs> PerformancePackageAvailable;
+
+ private IMachineProvider MachineProvider { get; set; }
+
+ public DefaultPerformanceProvider(IMachineProvider machineProvider)
+ {
+ MachineProvider = machineProvider;
+ MachineProvider.MachineConnected += MachineProvider_MachineConnected;
+ }
+
+ private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
+ {
+ MachineProvider.MachineOperator.SendGenericContinuousRequest<StartPerformanceUpdatesRequest, StartPerformanceUpdatesResponse>(new StartPerformanceUpdatesRequest()).Subscribe((response) =>
+ {
+ OnPerformancePackageAvailable(response.Package);
+ }, (ex) =>
+ {
+ LogManager.Log(ex, "Error starting performance updates.");
+ }, () =>
+ {
+ //Do nothing.
+ });
+ }
+
+ protected virtual void OnPerformancePackageAvailable(PerformancePackage package)
+ {
+ PerformancePackageAvailable?.Invoke(this, new PerformancePackageEventArgs() { Package = package });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Resolution/DefaultResolutionService.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Resolution/DefaultResolutionService.cs
new file mode 100644
index 000000000..de3d2c356
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Resolution/DefaultResolutionService.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.FSE.Common.Resolution;
+
+namespace Tango.FSE.UI.Resolution
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultResolutionService : ExtendedObject, IResolutionService
+ {
+ public event EventHandler<ResolutionMode> ResolutionModeChanged;
+ public event EventHandler<SizeChangedEventArgs> ResolutionChanged;
+
+ private ResolutionMode resolution;
+ public ResolutionMode Resolution
+ {
+ get
+ {
+ return resolution;
+ }
+ private set
+ {
+ resolution = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private bool isLowResolution;
+ public bool IsLowResolution
+ {
+ get
+ {
+ return isLowResolution;
+ }
+ private set
+ {
+ isLowResolution = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+
+ private bool isHighResolution;
+ public bool IsHighResolution
+ {
+ get
+ {
+ return isHighResolution;
+ }
+ private set
+ {
+ isHighResolution = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private double resolutionWidth;
+ public double ResolutionWidth
+ {
+ get
+ {
+ return resolutionWidth;
+ }
+ private set
+ {
+ resolutionWidth = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private double resolutionHeight;
+ public double ResolutionHeight
+ {
+ get
+ {
+ return resolutionHeight;
+ }
+ private set
+ {
+ resolutionHeight = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ public DefaultResolutionService()
+ {
+ var window = Application.Current.MainWindow;
+ if (window != null)
+ {
+ window.SizeChanged += Window_SizeChanged;
+ }
+ }
+
+ private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ var size = e.NewSize;
+
+ ResolutionWidth = size.Width;
+ ResolutionHeight = size.Height;
+
+ IsHighResolution = ResolutionWidth > 1280 && ResolutionHeight > 800;
+ IsLowResolution = !isHighResolution;
+
+ ResolutionMode previousMode = Resolution;
+
+ Resolution = IsHighResolution ? ResolutionMode.High : ResolutionMode.Low;
+
+ if (Resolution != previousMode)
+ {
+ ResolutionModeChanged?.Invoke(this, Resolution);
+ }
+
+ ResolutionChanged?.Invoke(this, e);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
index 7c6679549..eb59d67d0 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
@@ -109,6 +109,7 @@
</ApplicationDefinition>
<Compile Include="Authentication\DefaultAuthenticationProvider.cs" />
<Compile Include="Connection\DefaultMachineProvider.cs" />
+ <Compile Include="Console\DefaultConsoleService.cs" />
<Compile Include="Contracts\ILayoutView.cs" />
<Compile Include="Diagnostics\DefaultDiagnosticsProvider.cs" />
<Compile Include="Dialogs\MachineConnectionBaseViewVM.cs" />
@@ -149,7 +150,9 @@
<DependentUpon>MachineConnectionPane.xaml</DependentUpon>
</Compile>
<Compile Include="Panes\MachineConnectionPaneVM.cs" />
+ <Compile Include="Performance\DefaultPerformanceProvider.cs" />
<Compile Include="RemoteDesktop\DefaultRemoteDesktopProvider.cs" />
+ <Compile Include="Resolution\DefaultResolutionService.cs" />
<Compile Include="Threading\DefaultDispatcherProvider.cs" />
<Compile Include="ViewModelLocator.cs" />
<Compile Include="ViewModels\AccountViewVM.cs" />
@@ -299,6 +302,10 @@
<Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
<Name>Tango.BL</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Console\Tango.Console.csproj">
+ <Project>{199E8359-CAD3-433D-9EED-2027652B24A4}</Project>
+ <Name>Tango.Console</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
<Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
<Name>Tango.Core</Name>
@@ -425,6 +432,7 @@
<ItemGroup>
<Resource Include="Images\logout.png" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets" Condition="Exists('..\..\packages\MaterialDesignThemes.3.0.1\build\MaterialDesignThemes.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
index 536a42ae6..52be9581c 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs
@@ -8,24 +8,30 @@ using Tango.Core.DI;
using Tango.FSE.BL;
using Tango.FSE.Common.Authentication;
using Tango.FSE.Common.Connection;
+using Tango.FSE.Common.Console;
using Tango.FSE.Common.Diagnostics;
using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Gateway;
using Tango.FSE.Common.Modules;
using Tango.FSE.Common.Navigation;
using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Performance;
using Tango.FSE.Common.RemoteDesktop;
+using Tango.FSE.Common.Resolution;
using Tango.FSE.Common.Threading;
using Tango.FSE.Common.Web;
using Tango.FSE.UI.Authentication;
using Tango.FSE.UI.Connection;
+using Tango.FSE.UI.Console;
using Tango.FSE.UI.Diagnostics;
using Tango.FSE.UI.FSEApplication;
using Tango.FSE.UI.Gateway;
using Tango.FSE.UI.Modules;
using Tango.FSE.UI.Navigation;
using Tango.FSE.UI.Notifications;
+using Tango.FSE.UI.Performance;
using Tango.FSE.UI.RemoteDesktop;
+using Tango.FSE.UI.Resolution;
using Tango.FSE.UI.Threading;
using Tango.FSE.UI.ViewModels;
@@ -46,6 +52,9 @@ namespace Tango.FSE.UI
TangoIOC.Default.Unregister<IFSEApplicationManager>();
TangoIOC.Default.Unregister<IDiagnosticsProvider>();
TangoIOC.Default.Unregister<IRemoteDesktopProvider>();
+ TangoIOC.Default.Unregister<IResolutionService>();
+ TangoIOC.Default.Unregister<IConsoleService>();
+ TangoIOC.Default.Unregister<IPerformanceProvider>();
//TangoIOC.Default.Unregister<ExternalBridgeScanner>();
//TangoIOC.Default.Unregister<IDiagnosticsFrameProvider>();
//TangoIOC.Default.Unregister<IEventLogger>();
@@ -65,6 +74,9 @@ namespace Tango.FSE.UI
TangoIOC.Default.Register<INavigationManager, DefaultNavigationManager>();
TangoIOC.Default.Register<IFSEApplicationManager, DefaultFSEApplicationManager>();
TangoIOC.Default.Register<IRemoteDesktopProvider, DefaultRemoteDesktopProvider>();
+ TangoIOC.Default.Register<IResolutionService, DefaultResolutionService>();
+ TangoIOC.Default.Register<IConsoleService, DefaultConsoleService>();
+ TangoIOC.Default.Register<IPerformanceProvider, DefaultPerformanceProvider>();
TangoIOC.Default.Register<MainWindowVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs
index 6f2693e5a..6517025b6 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoadingViewVM.cs
@@ -46,10 +46,5 @@ namespace Tango.FSE.UI.ViewModels
IsLoading = false;
}
}
-
- public override void OnApplicationReady()
- {
-
- }
}
}
diff --git a/Software/Visual_Studio/Installers/VS Extensions/PropMan.vsix b/Software/Visual_Studio/Installers/VS Extensions/PropMan.vsix
new file mode 100644
index 000000000..23b380931
--- /dev/null
+++ b/Software/Visual_Studio/Installers/VS Extensions/PropMan.vsix
Binary files differ
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Console/DefaultConsoleEngineService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Console/DefaultConsoleEngineService.cs
index 42228614e..02d510a93 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Console/DefaultConsoleEngineService.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Console/DefaultConsoleEngineService.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Console;
+using Tango.Console.Network;
using Tango.Core.DI;
using Tango.Integration.ExternalBridge;
using Tango.PPC.Common.ExternalBridge;
@@ -21,16 +22,27 @@ namespace Tango.PPC.Common.Console
externalBridge.RegisterRequestHandler(this);
}
- [ExternalBridgeRequestHandlerMethod(typeof(ConsoleCommandDTO))]
- public async void OnConsoleCommandReceived(ConsoleCommandDTO command, String token, ITransporter transporter)
+ [ExternalBridgeRequestHandlerMethod(typeof(GetCurrentDirectoryRequest))]
+ public async void OnGetCurrentDirectoryRequest(GetCurrentDirectoryRequest request, String token, ITransporter transporter)
+ {
+ await transporter.SendGenericResponse(new GetCurrentDirectoryResponse() { CurrentDirectory = Environment.CurrentDirectory }, token);
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(ConsoleCommandRequest))]
+ public async void OnConsoleCommandRequest(ConsoleCommandRequest request, String token, ITransporter transporter)
{
if (Enabled)
{
try
{
ConsoleExecutionEngine engine = new ConsoleExecutionEngine();
- var result = await engine.Execute(command);
- await transporter.SendGenericResponse<ConsoleCommandExecutionResult>(result, token, new TransportResponseConfig()
+ var result = await engine.Execute(request);
+ await transporter.SendGenericResponse<ConsoleCommandResponse>(new ConsoleCommandResponse()
+ {
+ Output = result.Output,
+ Suggestions = result.Suggestions,
+ WorkingFolder = result.WorkingFolder
+ }, token, new TransportResponseConfig()
{
Immediate = true,
});
@@ -44,7 +56,7 @@ namespace Tango.PPC.Common.Console
public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
{
-
+
}
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/DefaultPerformanceService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/DefaultPerformanceService.cs
new file mode 100644
index 000000000..700cc0d47
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/DefaultPerformanceService.cs
@@ -0,0 +1,227 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.Integration.ExternalBridge;
+using Tango.Integration.ExternalBridge.Network.Performance;
+using Tango.PPC.Common.ExternalBridge;
+
+namespace Tango.PPC.Common.Performance
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultPerformanceService : ExtendedObject, IPerformanceService
+ {
+ #region Nested Classes
+
+ public static class PerformanceInfo
+ {
+ [DllImport("psapi.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetPerformanceInfo([Out] out PerformanceInformation PerformanceInformation, [In] int Size);
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PerformanceInformation
+ {
+ public int Size;
+ public IntPtr CommitTotal;
+ public IntPtr CommitLimit;
+ public IntPtr CommitPeak;
+ public IntPtr PhysicalTotal;
+ public IntPtr PhysicalAvailable;
+ public IntPtr SystemCache;
+ public IntPtr KernelTotal;
+ public IntPtr KernelPaged;
+ public IntPtr KernelNonPaged;
+ public IntPtr PageSize;
+ public int HandlesCount;
+ public int ProcessCount;
+ public int ThreadCount;
+ }
+
+ public static Int64 GetPhysicalAvailableMemoryInMiB()
+ {
+ PerformanceInformation pi = new PerformanceInformation();
+ if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
+ {
+ return Convert.ToInt64((pi.PhysicalAvailable.ToInt64() * pi.PageSize.ToInt64() / 1048576));
+ }
+ else
+ {
+ return -1;
+ }
+
+ }
+
+ public static Int64 GetTotalMemoryInMiB()
+ {
+ PerformanceInformation pi = new PerformanceInformation();
+ if (GetPerformanceInfo(out pi, Marshal.SizeOf(pi)))
+ {
+ return Convert.ToInt64((pi.PhysicalTotal.ToInt64() * pi.PageSize.ToInt64() / 1048576));
+ }
+ else
+ {
+ return -1;
+ }
+
+ }
+ }
+
+ #endregion
+
+ private class PerformanceClient
+ {
+ public ExternalBridgeReceiver Receiver { get; set; }
+ public String Token { get; set; }
+ }
+
+ private List<PerformanceClient> _clients;
+ private PerformancePackage _package;
+ private bool _isStarted;
+ private Thread _performanceThread;
+
+ public bool Enabled { get; set; } = true;
+
+ public DefaultPerformanceService(IPPCExternalBridgeService externalBridge)
+ {
+ _package = new PerformancePackage();
+ _clients = new List<PerformanceClient>();
+ externalBridge.RegisterRequestHandler(this);
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(StartPerformanceUpdatesRequest))]
+ public async void OnStartPerformanceUpdatesRequest(StartPerformanceUpdatesRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ if (Enabled)
+ {
+ try
+ {
+ if (!_clients.Exists(x => x.Receiver == receiver))
+ {
+ _clients.Add(new PerformanceClient() { Receiver = receiver, Token = token });
+ OnReceiversChanged();
+ }
+
+ await receiver.SendGenericResponse(new StartPerformanceUpdatesResponse() { Package = _package }, token);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending performance package.");
+ }
+ }
+ }
+
+ public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
+ {
+ _clients.RemoveAll(x => x.Receiver == receiver);
+ OnReceiversChanged();
+ }
+
+ private void OnReceiversChanged()
+ {
+ if (_clients.Count > 0 && !_isStarted)
+ {
+ _isStarted = true;
+ _performanceThread = new Thread(PerformanceThreadMethod);
+ _performanceThread.IsBackground = true;
+ _performanceThread.Start();
+ }
+ else if (_clients.Count == 0 && _isStarted)
+ {
+ _isStarted = false;
+ }
+ }
+
+ private async void PerformanceThreadMethod()
+ {
+ while (_isStarted)
+ {
+ try
+ {
+ _package.ApplicationCPU = (int)GetAppCPU();
+ _package.CPU = (int)GetTotalCPU();
+ _package.ApplicationRAM = (int)BytesToMegaBytes(GetAppRam());
+ _package.RAM = (int)PerformanceInfo.GetTotalMemoryInMiB();
+ _package.MaxRAM = (int)PerformanceInfo.GetPhysicalAvailableMemoryInMiB();
+
+ DriveInfo info = new DriveInfo("C");
+ _package.DiskCapacity = (int)BytesToMegaBytes(info.TotalSize);
+ _package.AvailableDiskSpace = (int)BytesToMegaBytes(info.AvailableFreeSpace);
+ _package.DateTime = DateTime.Now;
+
+ foreach (var client in _clients.ToList())
+ {
+ try
+ {
+ await client.Receiver.SendGenericResponse(new StartPerformanceUpdatesResponse() { Package = _package }, client.Token);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending performance package.");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error creating performance package.");
+ }
+
+ Thread.Sleep(2000);
+ }
+ }
+
+ #region Helpers
+
+ private float BytesToMegaBytes(long bytes)
+ {
+ return bytes / 1024f / 1024f;
+ }
+
+ public float GetAppCPU()
+ {
+ PerformanceCounter cpuCounter = new PerformanceCounter();
+ cpuCounter.CategoryName = "Process";
+ cpuCounter.CounterName = "% Processor Time";
+ cpuCounter.InstanceName = Process.GetCurrentProcess().ProcessName;
+
+ // will always start at 0
+ float firstValue = cpuCounter.NextValue();
+ System.Threading.Thread.Sleep(1000);
+ // now matches task manager reading
+ float secondValue = cpuCounter.NextValue();
+
+ return secondValue / Environment.ProcessorCount;
+ }
+
+ public float GetTotalCPU()
+ {
+ PerformanceCounter cpuCounter = new PerformanceCounter();
+ cpuCounter.CategoryName = "Processor";
+ cpuCounter.CounterName = "% Processor Time";
+ cpuCounter.InstanceName = "_Total";
+
+ // will always start at 0
+ float firstValue = cpuCounter.NextValue();
+ System.Threading.Thread.Sleep(1000);
+ // now matches task manager reading
+ float secondValue = cpuCounter.NextValue();
+
+ return secondValue;
+ }
+
+ public long GetAppRam()
+ {
+ Process proc = Process.GetCurrentProcess();
+ return proc.PrivateMemorySize64;
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/IPerformanceService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/IPerformanceService.cs
new file mode 100644
index 000000000..c3bfd1543
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Performance/IPerformanceService.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Integration.ExternalBridge;
+
+namespace Tango.PPC.Common.Performance
+{
+ public interface IPerformanceService : IExternalBridgeRequestHandler
+ {
+ bool Enabled { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
index f7b3f9e4c..df6b881a0 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
@@ -159,6 +159,8 @@
<Compile Include="MachineSetup\MachineSetupManager.cs" />
<Compile Include="MachineSetup\MachineSetupProgress.cs" />
<Compile Include="MachineSetup\MachineSetupResult.cs" />
+ <Compile Include="Performance\DefaultPerformanceService.cs" />
+ <Compile Include="Performance\IPerformanceService.cs" />
<Compile Include="RemoteDesktop\DefaultRemoteDesktopService.cs" />
<Compile Include="RemoteDesktop\IRemoteDesktopService.cs" />
<Compile Include="Synchronization\DefaultMachineDataSynchronizer.cs" />
@@ -437,7 +439,7 @@
</Target>
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
index a8cbcfe2d..da6c630d4 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
@@ -20,6 +20,7 @@ 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.RemoteAssistance;
using Tango.PPC.Common.RemoteDesktop;
@@ -82,6 +83,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Unregister<IMachineDataSynchronizer>();
TangoIOC.Default.Unregister<IConsoleEngineService>();
TangoIOC.Default.Unregister<IRemoteDesktopService>();
+ TangoIOC.Default.Unregister<IPerformanceService>();
if (App.StartupArgs.Contains("-webDebug"))
{
@@ -117,6 +119,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Register<IUnifiedWriteFilterManager, AlternativeUnifiedWriteFilterManager>();
TangoIOC.Default.Register<IOperationSystemManager, DefaultOperationSystemManager>();
TangoIOC.Default.Register<IBackupManager, DefaultBackupManager>();
+ TangoIOC.Default.Register<IPerformanceService, DefaultPerformanceService>();
TangoIOC.Default.Register<LoadingViewVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/Tango.Console/ConsoleExecutionEngine.cs b/Software/Visual_Studio/Tango.Console/ConsoleExecutionEngine.cs
index c4bdee0a8..42bc2ac00 100644
--- a/Software/Visual_Studio/Tango.Console/ConsoleExecutionEngine.cs
+++ b/Software/Visual_Studio/Tango.Console/ConsoleExecutionEngine.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Tango.Console.Network;
namespace Tango.Console
{
@@ -15,19 +16,19 @@ namespace Tango.Console
public String Command { get; set; }
public String Arguments { get; set; }
- public ParsedCommand(ConsoleCommandDTO dto)
+ public ParsedCommand(ConsoleCommandRequest request)
{
- String[] s = dto.Command.Split(' ');
+ String[] s = request.Command.Split(' ');
Command = s.First();
Arguments = String.Join(" ", s.Skip(1));
}
}
- public Task<ConsoleCommandExecutionResult> Execute(ConsoleCommandDTO command)
+ public Task<ConsoleCommandExecutionResult> Execute(ConsoleCommandRequest request)
{
return Task.Factory.StartNew<ConsoleCommandExecutionResult>(() =>
{
- ParsedCommand parsedCommand = new ParsedCommand(command);
+ ParsedCommand parsedCommand = new ParsedCommand(request);
if (parsedCommand.Command.ToLower() == "cd")
{
@@ -35,9 +36,9 @@ namespace Tango.Console
{
return CreateResult(parsedCommand.Arguments, String.Empty);
}
- else if (Directory.Exists(Path.Combine(command.WorkingFolder, parsedCommand.Arguments)))
+ else if (Directory.Exists(Path.Combine(request.WorkingFolder, parsedCommand.Arguments)))
{
- return CreateResult(Path.GetFullPath(Path.Combine(command.WorkingFolder, parsedCommand.Arguments)), String.Empty);
+ return CreateResult(Path.GetFullPath(Path.Combine(request.WorkingFolder, parsedCommand.Arguments)), String.Empty);
}
else
{
@@ -54,16 +55,16 @@ namespace Tango.Console
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
- if (command.WorkingFolder != null)
+ if (request.WorkingFolder != null)
{
- process.StartInfo.WorkingDirectory = command.WorkingFolder;
+ process.StartInfo.WorkingDirectory = request.WorkingFolder;
}
//process.StartInfo.Verb = "runas";
if (ConsoleDictionary.GetKnownCommands().Exists(x => x.Name.ToLower() == parsedCommand.Command))
{
process.StartInfo.FileName = "cmd.exe";
- process.StartInfo.Arguments = "/C " + command.Command;
+ process.StartInfo.Arguments = "/C " + request.Command;
}
else
{
@@ -88,7 +89,7 @@ namespace Tango.Console
error = process.StandardError.ReadToEnd();
}
- return CreateResult(command.WorkingFolder, String.IsNullOrWhiteSpace(error) ? output.Replace(command.WorkingFolder + ">", "") : error);
+ return CreateResult(request.WorkingFolder, String.IsNullOrWhiteSpace(error) ? output.Replace(request.WorkingFolder + ">", "") : error);
});
}
diff --git a/Software/Visual_Studio/Tango.Console/ConsoleCommandDTO.cs b/Software/Visual_Studio/Tango.Console/Network/ConsoleCommandRequest.cs
index 1d96fccc2..d7541506c 100644
--- a/Software/Visual_Studio/Tango.Console/ConsoleCommandDTO.cs
+++ b/Software/Visual_Studio/Tango.Console/Network/ConsoleCommandRequest.cs
@@ -4,9 +4,9 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Tango.Console
+namespace Tango.Console.Network
{
- public class ConsoleCommandDTO
+ public class ConsoleCommandRequest
{
public String WorkingFolder { get; set; }
public String Command { get; set; }
diff --git a/Software/Visual_Studio/Tango.Console/Network/ConsoleCommandResponse.cs b/Software/Visual_Studio/Tango.Console/Network/ConsoleCommandResponse.cs
new file mode 100644
index 000000000..70b72e703
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Console/Network/ConsoleCommandResponse.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Console.Network
+{
+ public class ConsoleCommandResponse
+ {
+ public String WorkingFolder { get; set; }
+ public String Output { get; set; }
+ public List<ConsoleSuggestion> Suggestions { get; set; }
+
+ public ConsoleCommandResponse()
+ {
+ Suggestions = new List<ConsoleSuggestion>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryRequest.cs b/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryRequest.cs
new file mode 100644
index 000000000..f5abfda70
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryRequest.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Console.Network
+{
+ public class GetCurrentDirectoryRequest
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryResponse.cs b/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryResponse.cs
new file mode 100644
index 000000000..30a24e461
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Console/Network/GetCurrentDirectoryResponse.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Console.Network
+{
+ public class GetCurrentDirectoryResponse
+ {
+ public String CurrentDirectory { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Console/Tango.Console.csproj b/Software/Visual_Studio/Tango.Console/Tango.Console.csproj
index 00b2042f8..9c4819389 100644
--- a/Software/Visual_Studio/Tango.Console/Tango.Console.csproj
+++ b/Software/Visual_Studio/Tango.Console/Tango.Console.csproj
@@ -49,7 +49,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ConsoleCommand.cs" />
- <Compile Include="ConsoleCommandDTO.cs" />
<Compile Include="ConsoleCommandExecutingEventArgs.cs" />
<Compile Include="ConsoleCommandExecutionResult.cs" />
<Compile Include="ConsoleControl.xaml.cs">
@@ -63,6 +62,10 @@
<Compile Include="ConsoleSuggestionType.cs" />
<Compile Include="ConsoleTextBox.cs" />
<Compile Include="ConsoleTextBoxMaxWidthConverter.cs" />
+ <Compile Include="Network\ConsoleCommandRequest.cs" />
+ <Compile Include="Network\ConsoleCommandResponse.cs" />
+ <Compile Include="Network\GetCurrentDirectoryRequest.cs" />
+ <Compile Include="Network\GetCurrentDirectoryResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationRequest.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationRequest.cs
new file mode 100644
index 000000000..38c06b024
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Information
+{
+ public class GetMachineInformationRequest
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationResponse.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationResponse.cs
new file mode 100644
index 000000000..d44382b2e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/GetMachineInformationResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Information
+{
+ public class GetMachineInformationResponse
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/InformationPackage.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/InformationPackage.cs
new file mode 100644
index 000000000..3e004d4f5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/InformationPackage.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Information
+{
+ public class InformationPackage
+ {
+ public List<MachineProperty> Properties { get; set; }
+
+ public InformationPackage()
+ {
+ Properties = new List<MachineProperty>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/MachineProperty.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/MachineProperty.cs
new file mode 100644
index 000000000..99232d624
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Information/MachineProperty.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Information
+{
+ public class MachineProperty
+ {
+ public String Name { get; set; }
+ public String Value { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/PerformancePackage.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/PerformancePackage.cs
new file mode 100644
index 000000000..56921e0c5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/PerformancePackage.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Performance
+{
+ public class PerformancePackage
+ {
+ public int CPU { get; set; }
+ public int ApplicationCPU { get; set; }
+
+ public int RAM { get; set; }
+ public int ApplicationRAM { get; set; }
+ public int MaxRAM { get; set; }
+
+ public int Temperature { get; set; }
+
+ public int AvailableDiskSpace { get; set; }
+ public int DiskCapacity { get; set; }
+
+ public DateTime DateTime { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesRequest.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesRequest.cs
new file mode 100644
index 000000000..2c036e937
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Performance
+{
+ public class StartPerformanceUpdatesRequest
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesResponse.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesResponse.cs
new file mode 100644
index 000000000..8eb22bdef
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Network/Performance/StartPerformanceUpdatesResponse.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.ExternalBridge.Network.Performance
+{
+ public class StartPerformanceUpdatesResponse
+ {
+ public PerformancePackage Package { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
index 04b2903ce..b439fc211 100644
--- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
+++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
@@ -106,6 +106,13 @@
<Compile Include="ExternalBridge\IExternalBridgeRequestHandler.cs" />
<Compile Include="ExternalBridge\ExternalBridgeSignalRConfiguration.cs" />
<Compile Include="ExternalBridge\ExternalBridgeSignalRClient.cs" />
+ <Compile Include="ExternalBridge\Network\Information\GetMachineInformationRequest.cs" />
+ <Compile Include="ExternalBridge\Network\Information\GetMachineInformationResponse.cs" />
+ <Compile Include="ExternalBridge\Network\Information\InformationPackage.cs" />
+ <Compile Include="ExternalBridge\Network\Information\MachineProperty.cs" />
+ <Compile Include="ExternalBridge\Network\Performance\PerformancePackage.cs" />
+ <Compile Include="ExternalBridge\Network\Performance\StartPerformanceUpdatesRequest.cs" />
+ <Compile Include="ExternalBridge\Network\Performance\StartPerformanceUpdatesResponse.cs" />
<Compile Include="ExternalBridge\Web\MachineInfo.cs" />
<Compile Include="IntegrationSettings.cs" />
<Compile Include="JobRuns\BasicJobRunsLogger.cs" />
@@ -211,7 +218,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventArgs.cs b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventArgs.cs
new file mode 100644
index 000000000..06ea61019
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventArgs.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Tango.SharedUI
+{
+ /// <summary>
+ /// Represents the <see cref="BindingEventContainer.ValueChanged"/> event arguments.
+ /// </summary>
+ /// <seealso cref="System.EventArgs" />
+ public class BindingEventArgs : EventArgs
+ {
+ internal Action _renewAction;
+
+ /// <summary>
+ /// Gets or sets the element.
+ /// </summary>
+ public DependencyObject DependencyObject { get; set; }
+
+ /// <summary>
+ /// Gets or sets the binding property.
+ /// </summary>
+ public BindingProperty BindingProperty { get; set; }
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public Object Value { get; set; }
+
+ public void Renew()
+ {
+ _renewAction?.Invoke();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventContainer.cs b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventContainer.cs
new file mode 100644
index 000000000..a74a9b085
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingEventContainer.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace Tango.SharedUI
+{
+ /// <summary>
+ /// Represents a binding event container.
+ /// </summary>
+ /// <seealso cref="System.Windows.DependencyObject" />
+ public class BindingEventContainer : DependencyObject
+ {
+ private Action _renewAction;
+
+ /// <summary>
+ /// Occurs when the dependency property value has changed.
+ /// </summary>
+ public event EventHandler<BindingEventArgs> ValueChanged;
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public Object Value
+ {
+ get { return (Object)GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+ public static readonly DependencyProperty ValueProperty =
+ DependencyProperty.Register("Value", typeof(Object), typeof(BindingEventContainer), new PropertyMetadata(null, (d, e) => (d as BindingEventContainer).OnValueChanged()));
+
+ /// <summary>
+ /// Gets or sets the binding property.
+ /// </summary>
+ public BindingProperty BindingProperty { get; set; }
+
+ /// <summary>
+ /// Gets or sets the dependency object.
+ /// </summary>
+ public DependencyObject DependencyObject { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BindingEventContainer"/> class.
+ /// </summary>
+ /// <param name="takeElement">The dependency object.</param>
+ /// <param name="bindingProperty">The binding property.</param>
+ public BindingEventContainer(DependencyObject dependencyObject, BindingProperty bindingProperty)
+ {
+ DependencyObject = dependencyObject;
+ BindingProperty = bindingProperty;
+ }
+
+ /// <summary>
+ /// Called when the value has been changed
+ /// </summary>
+ protected virtual void OnValueChanged()
+ {
+ ValueChanged?.Invoke(this, new BindingEventArgs()
+ {
+ BindingProperty = BindingProperty,
+ DependencyObject = DependencyObject,
+ Value = Value,
+ _renewAction = _renewAction
+ });
+ }
+
+ /// <summary>
+ /// Generates a new <see cref="BindingEventContainer"/> for the specified Take element and binding property.
+ /// </summary>
+ /// <param name="dependencyObject">The take element.</param>
+ /// <param name="dependencyProperty">The binding property.</param>
+ /// <returns></returns>
+ public static BindingEventContainer Generate(DependencyObject dependencyObject, DependencyProperty dependencyProperty)
+ {
+ BindingEventContainer container = new BindingEventContainer(dependencyObject, new BindingProperty(dependencyProperty));
+
+ container._renewAction = () =>
+ {
+ Binding binding = new Binding();
+ binding.Mode = BindingMode.OneWay;
+ binding.Source = dependencyObject;
+ binding.Path = new PropertyPath(dependencyProperty);
+ BindingOperations.SetBinding(container, BindingEventContainer.ValueProperty, binding);
+ };
+
+ container._renewAction.Invoke();
+
+ return container;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Binding/BindingProperty.cs b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingProperty.cs
new file mode 100644
index 000000000..79d4f1c71
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Binding/BindingProperty.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.SharedUI
+{
+ /// <summary>
+ /// Represents a binding property.
+ /// </summary>
+ public class BindingProperty
+ {
+ /// <summary>
+ /// Gets or sets the dependency property.
+ /// </summary>
+ public DependencyProperty DependencyProperty { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BindingProperty"/> class.
+ /// </summary>
+ public BindingProperty()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BindingProperty"/> class.
+ /// </summary>
+ /// <param name="dp">The dependency property.</param>
+ /// <param name="mode">The mode.</param>
+ public BindingProperty(DependencyProperty dp) : this()
+ {
+ DependencyProperty = dp;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs
index 15d15decb..ce1fca7ac 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/NavigationControl.cs
@@ -22,7 +22,9 @@ namespace Tango.SharedUI.Controls
public class NavigationControl : UserControl
{
private event Action NavigationCompleted;
+ public event EventHandler<FrameworkElement> SelectedElementChanged;
private Thread _navigationThread;
+ private bool _preventSelectedObjectNavigation;
private ProducerConsumerQueue<NavigationQueueItem> _navigationQueue;
private class NavigationQueueItem
@@ -191,14 +193,12 @@ namespace Tango.SharedUI.Controls
get { return (object)GetValue(SelectedObjectProperty); }
set { SetValue(SelectedObjectProperty, value); }
}
-
- // Using a DependencyProperty as the backing store for SelectedObject. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedObjectProperty =
- DependencyProperty.Register("SelectedObject", typeof(object), typeof(NavigationControl), new PropertyMetadata(null, (d, e) => (d as NavigationControl).OnSelectedObjectChanged()));
+ DependencyProperty.Register("SelectedObject", typeof(object), typeof(NavigationControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => (d as NavigationControl).OnSelectedObjectChanged()));
private void OnSelectedObjectChanged()
{
- if (SelectedObject != null)
+ if (SelectedObject != null && !_preventSelectedObjectNavigation)
{
NavigateTo(SelectedObject);
}
@@ -218,7 +218,7 @@ namespace Tango.SharedUI.Controls
set { SetValue(SelectedElementProperty, value); }
}
public static readonly DependencyProperty SelectedElementProperty =
- DependencyProperty.Register("SelectedElement", typeof(FrameworkElement), typeof(NavigationControl), new PropertyMetadata(null, (d, e) => (d as NavigationControl).OnSelectedElementChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement)));
+ DependencyProperty.Register("SelectedElement", typeof(FrameworkElement), typeof(NavigationControl), new FrameworkPropertyMetadata(null, (d, e) => (d as NavigationControl).OnSelectedElementChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement)));
public TransitionTypes TransitionType
{
@@ -310,7 +310,9 @@ namespace Tango.SharedUI.Controls
/// <returns></returns>
public static String GetNavigationName(FrameworkElement element)
{
- return element.GetValue(NavigationName).ToStringSafe();
+ var name = element.GetValue(NavigationName).ToStringSafe();
+ if (String.IsNullOrEmpty(name)) name = element.GetType().Name;
+ return name;
}
#endregion
@@ -383,6 +385,8 @@ namespace Tango.SharedUI.Controls
}
else
{
+ Elements.ToList().ForEach(x => x.FocusVisualStyle = null);
+
var toRemove = _grid.Children.OfType<NavigationElement>().ToList().Where(x => !Elements.Contains(x.Element)).ToList();
var toAdd = Elements.Where(x => !_grid.Children.OfType<NavigationElement>().Select(y => y.Element).ToList().Contains(x)).ToList();
@@ -622,6 +626,14 @@ namespace Tango.SharedUI.Controls
protected virtual void OnSelectedElementChanged(FrameworkElement fromElement, FrameworkElement toElement)
{
Navigate(GetElementContainer(fromElement), GetElementContainer(toElement));
+ SelectedElementChanged?.Invoke(this, toElement);
+
+ if (toElement != null)
+ {
+ _preventSelectedObjectNavigation = true;
+ SelectedObject = GetNavigationName(toElement);
+ _preventSelectedObjectNavigation = false;
+ }
}
#endregion
@@ -696,7 +708,7 @@ namespace Tango.SharedUI.Controls
FrameworkElement view = null;
- view = NavigateTo(navigationName, () =>
+ view = NavigateTo(navigationName, () =>
{
source.SetResult(view);
});
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/StringToTitleCaseConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToTitleCaseConverter.cs
new file mode 100644
index 000000000..6bafd1fd0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToTitleCaseConverter.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ public class StringToTitleCaseConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value != null)
+ {
+ return value.ToString().ToTitleCase();
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
index 2170b6d58..834e9e1fe 100644
--- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
+++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
@@ -64,6 +64,9 @@
<Compile Include="..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
+ <Compile Include="Binding\BindingEventArgs.cs" />
+ <Compile Include="Binding\BindingEventContainer.cs" />
+ <Compile Include="Binding\BindingProperty.cs" />
<Compile Include="Components\SelectedObject.cs" />
<Compile Include="Components\SelectedObjectCollection.cs" />
<Compile Include="Components\TextController.cs" />
@@ -133,6 +136,7 @@
<Compile Include="Converters\StringNullOrEmptyToBooleanConverter.cs" />
<Compile Include="Converters\StringToLinesConverter.cs" />
<Compile Include="Converters\StringToOneLineConverter.cs" />
+ <Compile Include="Converters\StringToTitleCaseConverter.cs" />
<Compile Include="Converters\StringToWordsConverter.cs" />
<Compile Include="Converters\TimeSpanToMinutesConverter.cs" />
<Compile Include="Converters\TimeSpanToSecondsConverter.cs" />