diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-12-18 05:26:29 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-12-18 05:26:29 +0200 |
| commit | 86bbaee1a545f08dc7bfb4efe5f4696d6e4dccdd (patch) | |
| tree | 0b46af20d6bb4568e44148b5e89d31da298c43fc /Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI | |
| parent | d9ee0b8e11f15c2b3bae068767516bc84a5ca4ed (diff) | |
| download | Tango-86bbaee1a545f08dc7bfb4efe5f4696d6e4dccdd.tar.gz Tango-86bbaee1a545f08dc7bfb4efe5f4696d6e4dccdd.zip | |
StubUtils
Diffstat (limited to 'Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI')
8 files changed, 379 insertions, 7 deletions
diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/App.xaml b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/App.xaml index 4db18888a..4b1b7cc93 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/App.xaml +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/App.xaml @@ -62,6 +62,7 @@ <ResourceDictionary Source="/Resources/Converters.xaml" /> <ResourceDictionary Source="/Resources/Colors.xaml" /> <ResourceDictionary Source="/Resources/Fonts.xaml" /> + <ResourceDictionary Source="/Resources/Styles.xaml" /> <ResourceDictionary> <!--OVERRIDE MAHAPPS--> diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Controls/ScrollableFlowDocumentScrollViewer.cs b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Controls/ScrollableFlowDocumentScrollViewer.cs new file mode 100644 index 000000000..5fa00a4ac --- /dev/null +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Controls/ScrollableFlowDocumentScrollViewer.cs @@ -0,0 +1,46 @@ +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.Media; + +namespace Tango.StubsUtils.Service.UI.Controls +{ + public class ScrollableFlowDocumentScrollViewer : FlowDocumentScrollViewer + { + /// <summary> + /// Backing store for the <see cref="ScrollViewer"/> property. + /// </summary> + private ScrollViewer scrollViewer; + + /// <summary> + /// Gets the scroll viewer contained within the FlowDocumentScrollViewer control + /// </summary> + public ScrollViewer ScrollViewer + { + get + { + if (this.scrollViewer == null) + { + DependencyObject obj = this; + + do + { + if (VisualTreeHelper.GetChildrenCount(obj) > 0) + obj = VisualTreeHelper.GetChild(obj as Visual, 0); + else + return null; + } + while (!(obj is ScrollViewer)); + + this.scrollViewer = obj as ScrollViewer; + } + + return this.scrollViewer; + } + } + } +} diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Resources/Styles.xaml b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Resources/Styles.xaml new file mode 100644 index 000000000..e47e4594c --- /dev/null +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Resources/Styles.xaml @@ -0,0 +1,16 @@ +<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.StubsUtils.Service.UI.Resources"> + + <Style x:Key="FSE_RaisedButton_Dark_Hover" TargetType="Button" BasedOn="{StaticResource MaterialDesignRaisedLightButton}"> + <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter> + <Setter Property="Height" Value="Auto"></Setter> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="{StaticResource FSE_PrimaryBackgroundLighterBrush}"></Setter> + </Trigger> + </Style.Triggers> + </Style> + +</ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ServiceUISettings.cs b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ServiceUISettings.cs index 92f7157ca..5e4d8209d 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ServiceUISettings.cs +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ServiceUISettings.cs @@ -9,5 +9,12 @@ namespace Tango.StubsUtils.Service.UI { public class ServiceUISettings : SettingsBase { + public String USBPort { get; set; } + public bool AutoConnect { get; set; } + + public ServiceUISettings() + { + USBPort = "COM1"; + } } } diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Tango.StubsUtils.Service.UI.csproj b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Tango.StubsUtils.Service.UI.csproj index c4cdbab42..a4c59bef2 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Tango.StubsUtils.Service.UI.csproj +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Tango.StubsUtils.Service.UI.csproj @@ -78,6 +78,7 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> + <Compile Include="Controls\ScrollableFlowDocumentScrollViewer.cs" /> <Compile Include="ServiceUISettings.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="Views\MainView.xaml.cs"> @@ -107,6 +108,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Resources\Styles.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\MainView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ViewModels/MainViewVM.cs index 4e8b144e5..21a183d8a 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/ViewModels/MainViewVM.cs @@ -1,17 +1,36 @@ using System; using System.Collections.Generic; +using System.IO.Ports; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.Windows.Documents; +using System.Windows.Input; +using Tango.Core; using Tango.Core.Commands; +using Tango.Logging; +using Tango.Settings; using Tango.SharedUI; +using Tango.SharedUI.Components; using Tango.SharedUI.Helpers; +using Tango.StubsUtils.Service.UI.Views; namespace Tango.StubsUtils.Service.UI.ViewModels { public class MainViewVM : ViewModel { + private ProducerConsumerQueue<String> _logsQueue; + private Thread _logsThread; + + private ServiceUISettings _settings; + public ServiceUISettings Settings + { + get { return _settings; } + set { _settings = value; RaisePropertyChangedAuto(); } + } + private StubsService _service; public StubsService Service { @@ -26,25 +45,131 @@ namespace Tango.StubsUtils.Service.UI.ViewModels set { _isTrayIconVisible = value; RaisePropertyChangedAuto(); } } + private List<String> _availablePorts; + public List<String> AvailablePorts + { + get { return _availablePorts; } + set { _availablePorts = value; RaisePropertyChangedAuto(); } + } + + private String _selectedPort; + public String SelectedPort + { + get { return _selectedPort; } + set { _selectedPort = value; RaisePropertyChangedAuto(); } + } + + private SimpleStringLogger _logger; + public SimpleStringLogger Logger + { + get { return _logger; } + set { _logger = value; RaisePropertyChangedAuto(); } + } public RelayCommand ExitCommand { get; set; } public RelayCommand OpenCommand { get; set; } + public RelayCommand RefreshPortsCommand { get; set; } + public RelayCommand ToggleConnectionCommand { get; set; } + public RelayCommand ClearLogCommand { get; set; } public MainViewVM() { - Init(); ExitCommand = new RelayCommand(ExitApplication); OpenCommand = new RelayCommand(OpenMainWindow); IsTrayIconVisible = true; + AvailablePorts = new List<string>(); + RefreshPortsCommand = new RelayCommand(RefreshPorts); + ToggleConnectionCommand = new RelayCommand(ToggleConnection); + ClearLogCommand = new RelayCommand(ClearLog); + _logsQueue = new ProducerConsumerQueue<string>(); + + _logsThread = new Thread(LogsThreadMethod); + _logsThread.IsBackground = true; + _logsThread.Start(); + + Init(); } public async void Init() { - Service = new StubsService(); - await Service.Start(); + try + { + Logger = new SimpleStringLogger() { Enabled = true }; + Logger.LogReceived += Logger_LogReceived; + + LogManager.RegisterLogger(Logger); + + LogManager.Log("Initializing..."); + Settings = SettingsManager.Default.GetOrCreate<ServiceUISettings>(); + SelectedPort = Settings.USBPort; + + RefreshPorts(); + + Service = new StubsService(); + await Service.Start(); + + if (Settings.AutoConnect) + { + await Task.Delay(2000); + ToggleConnection(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error initializing service."); + } + } + + private void Logger_LogReceived(object sender, LogItemBase e) + { + String message = e.TimeStamp.ToString("HH:mm:ss.ff") + ": " + e.Message; + _logsQueue.BlockEnqueue(message); + } + + private void LogsThreadMethod() + { + while (true) + { + List<String> logs = new List<string>(); + + logs.Add(_logsQueue.BlockDequeue()); + + while (_logsQueue.Count > 0) + { + logs.Add(_logsQueue.BlockDequeue()); + } + + InvokeUINow(() => + { + List<Inline> inlines = new List<Inline>(); - await Task.Delay(10000); - await Service.Connect(); + foreach (var log in logs) + { + inlines.Add(new Run(log)); + inlines.Add(new LineBreak()); + } + + MainView.Instance.paragraphLog.Inlines.AddRange(inlines); + + if (Mouse.LeftButton != MouseButtonState.Pressed) + { + MainView.Instance.scrollViewerLogs.ScrollViewer?.ScrollToEnd(); + } + }); + + Thread.Sleep(200); + } + } + + private void ClearLog() + { + InvokeUI(() => + { + IsFree = false; + UIHelper.DoEvents(); + MainView.Instance.paragraphLog.Inlines.Clear(); + IsFree = true; + }); } private async void OpenMainWindow() @@ -59,10 +184,67 @@ namespace Tango.StubsUtils.Service.UI.ViewModels public async void ExitApplication() { + IsFree = false; + SaveSettings(); IsTrayIconVisible = false; UIHelper.DoEvents(); await Task.Delay(1000); Environment.Exit(0); } + + private void RefreshPorts() + { + AvailablePorts = SerialPort.GetPortNames().ToList(); + + if (!AvailablePorts.Contains(SelectedPort)) + { + SelectedPort = AvailablePorts.FirstOrDefault(); + } + + InvalidateRelayCommands(); + } + + private async void ToggleConnection() + { + try + { + IsFree = false; + + if (!Service.IsConnected) + { + try + { + await Service.Connect(SelectedPort); + SaveSettings(); + //ToastNotificationManager.CreateToastNotifier("MyApplicationId").Show(toast); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error connecting to the specified serial port."); + } + } + else + { + try + { + await Service.Disconnect(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disconnecting from the specified serial port."); + } + } + } + finally + { + IsFree = true; + } + } + + private void SaveSettings() + { + Settings.USBPort = SelectedPort; + Settings.Save(); + } } } diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml index eb2c24e44..7cb2e1413 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml @@ -5,10 +5,11 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.StubsUtils.Service.UI.Controls" xmlns:local="clr-namespace:Tango.StubsUtils.Service.UI.Views" xmlns:vm="clr-namespace:Tango.StubsUtils.Service.UI.ViewModels" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" Background="{StaticResource FSE_PrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:MainViewVM,IsDesignTimeCreatable=False}"> + d:DesignHeight="400" d:DesignWidth="700" Background="{StaticResource FSE_PrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:MainViewVM,IsDesignTimeCreatable=False}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> <UserControl.Resources> <RadialGradientBrush x:Key="FSE_LED_GrayBrush"> @@ -25,7 +26,118 @@ </RadialGradientBrush> </UserControl.Resources> - <Grid> + <Grid IsEnabled="{Binding IsFree}" Background="Transparent"> + <Grid.Style> + <Style TargetType="Grid"> + <Setter Property="Cursor" Value="Arrow"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsFree}" Value="False"> + <Setter Property="Cursor" Value="Wait"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Grid.Style> + + <Grid Margin="10"> + <DockPanel> + <DockPanel DockPanel.Dock="Top"> + <Image VerticalAlignment="Top" Source="/Images/machine_icon_none.png" Stretch="None" /> + + <StackPanel Margin="10 0 0 0" VerticalAlignment="Top"> + <TextBlock FontSize="{StaticResource FSE_LargeFontSize}">Tango Stubs Service</TextBlock> + <DockPanel Margin="0 5 0 0"> + <Ellipse Width="12" Height="12" Stroke="#353535"> + <Ellipse.Style> + <Style TargetType="Ellipse"> + <Setter Property="Fill" Value="{StaticResource FSE_LED_RedBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Service.IsConnected}" Value="True"> + <Setter Property="Fill" Value="{StaticResource FSE_LED_GreenBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Ellipse.Style> + </Ellipse> + <TextBlock Margin="5 0 0 0" FontWeight="SemiBold"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Setter Property="Text" Value="Disconnected"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_RedBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Service.IsConnected}" Value="True"> + <Setter Property="Text" Value="Connected"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_GreenBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DockPanel> + </StackPanel> + </DockPanel> + + <Grid Margin="0 20 0 0"> + <DockPanel> + + <Grid DockPanel.Dock="Top"> + <Border Padding="0 20"> + <DockPanel> + <Button Command="{Binding ToggleConnectionCommand}" Width="150" DockPanel.Dock="Right" Padding="8"> + <Button.Style> + <Style TargetType="Button" BasedOn="{StaticResource FSE_RaisedButton_Dark_Hover}"> + <Setter Property="Content" Value="CONNECT"/> + <Style.Triggers> + <DataTrigger Binding="{Binding Service.IsConnected}" Value="True"> + <Setter Property="Content" Value="DISCONNECT"/> + </DataTrigger> + </Style.Triggers> + </Style> + </Button.Style> + </Button> + <ComboBox DockPanel.Dock="Left" Margin="0 0 20 0" ItemsSource="{Binding AvailablePorts}" SelectedItem="{Binding SelectedPort}" IsEnabled="{Binding Service.IsConnected,Converter={StaticResource BooleanInverseConverter}}"></ComboBox> + </DockPanel> + </Border> + </Grid> + + <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Margin="2 5 0 0"> + <CheckBox IsChecked="{Binding Service.EnableLogs}"> + <TextBlock Margin="0 -3 0 0"> + Enable Communication Logs + </TextBlock> + </CheckBox> + + <CheckBox Margin="10 0 0 0" IsChecked="{Binding Settings.AutoConnect}"> + <TextBlock Margin="0 -3 0 0"> + Auto Connect on Startup + </TextBlock> + </CheckBox> + </StackPanel> + + <DockPanel Margin="0 10 0 0" > + <Border DockPanel.Dock="Top" Padding="4" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" CornerRadius="5 5 0 0"> + <DockPanel> + <Button Style="{StaticResource FSE_RaisedButton_Dark_Hover}" DockPanel.Dock="Right" Command="{Binding ClearLogCommand}" ToolTip="Clear log" Padding="1"> + <material:PackIcon Kind="BinEmpty" /> + </Button> + <TextBlock FontWeight="SemiBold" VerticalAlignment="Center">LOG</TextBlock> + </DockPanel> + </Border> + <Border Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" CornerRadius="0 0 5 5" BorderThickness="1" BorderBrush="{StaticResource FSE_PrimaryBackgroundLightBrush}" Padding="3"> + <!--<TextBox x:Name="txtLogs" Foreground="{StaticResource FSE_GrayBrush}" Style="{x:Null}" BorderThickness="0" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" AcceptsReturn="True" IsReadOnly="True" Background="Transparent" FontSize="{StaticResource FSE_SmallFontSize}" Padding="5" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></TextBox>--> + <controls:ScrollableFlowDocumentScrollViewer x:Name="scrollViewerLogs" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Padding="5"> + <FlowDocument x:Name="documentLogs" FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=FontFamily}" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" PagePadding="0"> + <Paragraph x:Name="paragraphLog"> + + </Paragraph> + </FlowDocument> + </controls:ScrollableFlowDocumentScrollViewer> + </Border> + </DockPanel> + </DockPanel> + </Grid> + </DockPanel> + </Grid> + <tb:TaskbarIcon x:Name="taskIcon" x:FieldModifier="public" Visibility="{Binding IsTrayIconVisible,Converter={StaticResource BooleanToVisibilityConverter}}" ToolTipText="Tango Stubs Service" diff --git a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml.cs index 1c51be6d4..a0dab9f79 100644 --- a/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/StubsUtils/Tango.StubsUtils.Service.UI/Views/MainView.xaml.cs @@ -21,10 +21,13 @@ namespace Tango.StubsUtils.Service.UI.Views /// </summary> public partial class MainView : UserControl { + public static MainView Instance { get; set; } + public MainView() { InitializeComponent(); DataContext = new MainViewVM(); + Instance = this; } } } |
