diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-03-11 03:41:20 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-03-11 03:41:20 +0200 |
| commit | e774f9a90fd812a9de8c3efe966a759bee8be703 (patch) | |
| tree | da7a59af6af40ff810254df9e08f6a0f5a31fe1c /Software/Visual_Studio | |
| parent | eb793f20dc078a304a423a481e5bb0eddce71471 (diff) | |
| download | Tango-e774f9a90fd812a9de8c3efe966a759bee8be703.tar.gz Tango-e774f9a90fd812a9de8c3efe966a759bee8be703.zip | |
Working on FSE/PPC performance provider.
Implemented resolution service.
a lot of work!
Diffstat (limited to 'Software/Visual_Studio')
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 Binary files differnew file mode 100644 index 000000000..e7e6a8377 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Bold.ttf 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 Binary files differnew file mode 100644 index 000000000..278a61c8f --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Fonts/Caveat-Regular.ttf 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 Binary files differnew file mode 100644 index 000000000..23b380931 --- /dev/null +++ b/Software/Visual_Studio/Installers/VS Extensions/PropMan.vsix 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" /> |
