diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-04-08 16:55:37 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-04-08 16:55:37 +0300 |
| commit | 17a77c30765fe8a0d3ca57a9ec60fb43b82432d2 (patch) | |
| tree | 54881e3de14aaef3ad5e699f28d903a11a024b57 /Software/Visual_Studio | |
| parent | b3bc15a29d8fff24edc5bcd4576e18c9141f76a6 (diff) | |
| download | Tango-17a77c30765fe8a0d3ca57a9ec60fb43b82432d2.tar.gz Tango-17a77c30765fe8a0d3ca57a9ec60fb43b82432d2.zip | |
Implemented timeline events !
Diffstat (limited to 'Software/Visual_Studio')
34 files changed, 779 insertions, 231 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Tango.MachineStudio.DataCapture.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Tango.MachineStudio.DataCapture.csproj index efa6d2ad7..384a3fc32 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Tango.MachineStudio.DataCapture.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Tango.MachineStudio.DataCapture.csproj @@ -169,6 +169,10 @@ <Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project> <Name>Tango.MachineStudio.Common</Name> </ProjectReference> + <ProjectReference Include="..\Tango.MachineStudio.Logging\Tango.MachineStudio.Logging.csproj"> + <Project>{1674f726-0e66-414f-b9fd-c6f20d7f07c7}</Project> + <Name>Tango.MachineStudio.Logging</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Resource Include="Images\data-capture.jpg" /> @@ -185,5 +189,8 @@ <ItemGroup> <Resource Include="Images\capture-device.png" /> </ItemGroup> + <ItemGroup> + <Folder Include="Messages\" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs index b3d717263..af65c1430 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs @@ -8,16 +8,21 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Media.Imaging; +using Tango.BL.Entities; +using Tango.BL.Enumerations; using Tango.Core.Commands; +using Tango.Core.Helpers; using Tango.Integration.Diagnostics; using Tango.Integration.Operation; using Tango.Integration.Services; using Tango.MachineStudio.Common.Diagnostics; +using Tango.MachineStudio.Common.EventLogging; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Common.Video; using Tango.MachineStudio.DataCapture.Recording; using Tango.MachineStudio.DataCapture.Views; +using Tango.MachineStudio.Logging.ViewModels; using Tango.PMR.Diagnostics; using Tango.Settings; using Tango.SharedUI; @@ -34,6 +39,7 @@ namespace Tango.MachineStudio.DataCapture.ViewModels private INotificationProvider _notification; private IStudioApplicationManager _applicationManager; private IDiagnosticsFrameProvider _frameProvider; + private IEventLogger _eventLogger; private String _recordingsFolder; private BarItem _recordingBarItem; private BarItem _playerBarItem; @@ -100,6 +106,16 @@ namespace Tango.MachineStudio.DataCapture.ViewModels set { _captureDevices = value; RaisePropertyChangedAuto(); } } + private TimelineViewVM _timelineViewVM; + /// <summary> + /// Gets or sets the timeline view VM. + /// </summary> + public TimelineViewVM TimelineViewVM + { + get { return _timelineViewVM; } + set { _timelineViewVM = value; RaisePropertyChangedAuto(); } + } + #endregion #region Commands @@ -161,15 +177,20 @@ namespace Tango.MachineStudio.DataCapture.ViewModels /// <summary> /// Initializes a new instance of the <see cref="MainViewVM"/> class. /// </summary> - public MainViewVM(IVideoCaptureProvider videoCaptureProvider, INotificationProvider notification, IStudioApplicationManager applicationManager, IDiagnosticsFrameProvider frameProvider) + public MainViewVM(IVideoCaptureProvider videoCaptureProvider, INotificationProvider notification, IStudioApplicationManager applicationManager, IDiagnosticsFrameProvider frameProvider, IEventLogger eventLogger) { _notification = notification; _applicationManager = applicationManager; _frameProvider = frameProvider; + _eventLogger = eventLogger; + + _eventLogger.NewLog += _eventLogger_NewLog; Recorder = new DiagnosticsFileRecorder(); Player = new DiagnosticsFilePlayer(); + TimelineViewVM = new TimelineViewVM(notification) { EnableTimeMarker = true }; + VideoCaptureProvider = videoCaptureProvider; Recordings = new ObservableCollection<DataRecording>(); @@ -204,6 +225,14 @@ namespace Tango.MachineStudio.DataCapture.ViewModels #region Event Handlers + private void _eventLogger_NewLog(object sender, MachinesEvent ev) + { + if (Recorder.IsRecording) + { + Recorder.Write(ev); + } + } + private void ApplicationManager_ConnectedMachineChanged(object sender, IExternalBridgeClient machine) { MachineOperator = machine; @@ -222,7 +251,10 @@ namespace Tango.MachineStudio.DataCapture.ViewModels { CaptureDevices.First().Invoke(() => { - Recorder.Write(CaptureDevices.Where(x => x.VideoSource != null).Select(x => x.VideoSource.GetAsFrozen() as BitmapSource)); + if (Recorder.IsRecording) + { + Recorder.Write(CaptureDevices.Where(x => x.VideoSource != null).Select(x => x.VideoSource.GetAsFrozen() as BitmapSource)); + } }); }); } @@ -240,6 +272,8 @@ namespace Tango.MachineStudio.DataCapture.ViewModels { Recordings.Add(new DataRecording(file, File.GetCreationTime(file))); } + + Recordings = Recordings.OrderByDescending(x => x.Date).ToObservableCollection(); } /// <summary> @@ -248,7 +282,11 @@ namespace Tango.MachineStudio.DataCapture.ViewModels /// <param name="recording">The recording.</param> private void RemoveRecording(DataRecording recording) { - Recordings.Remove(recording); + if (_notification.ShowQuestion("Are you sure you want to remove the specified recording?")) + { + Recordings.Remove(recording); + PathHelper.TryDeleteFile(recording.FilePath); + } } /// <summary> @@ -275,6 +313,8 @@ namespace Tango.MachineStudio.DataCapture.ViewModels { SelectedRecording.Player = new DiagnosticsFilePlayer(); await SelectedRecording.Player.Load(SelectedRecording.FilePath); + TimelineViewVM.Initialize(SelectedRecording.Player.MachineEvents); + TimelineViewVM.TimelineMaxTime = SelectedRecording.Player.TotalTime; } } @@ -327,6 +367,8 @@ namespace Tango.MachineStudio.DataCapture.ViewModels CaptureDevices[i].VideoSource = frame.VideoFrames[i].ToByteArray().ToBitmapSource(); } }); + + TimelineViewVM.CurrentPosition = (sender as DiagnosticsFilePlayer).CurrentTime; } } @@ -335,7 +377,7 @@ namespace Tango.MachineStudio.DataCapture.ViewModels using (_notification.PushTaskItem("Starting Recording...")) { Recorder.Start(); - + _eventLogger.Log(EventTypes.RecordingStarted, "Recording Started..."); _recordingBarItem.Push(); } @@ -350,6 +392,8 @@ namespace Tango.MachineStudio.DataCapture.ViewModels { await Recorder.Stop(); _recordingBarItem.Pop(); + + _eventLogger.Log(EventTypes.RecordingStopped, "Recording Stopped..."); } String recordingName = _notification.ShowTextInput("Enter recording name", "Recording name"); @@ -370,6 +414,7 @@ namespace Tango.MachineStudio.DataCapture.ViewModels else if (Player.IsPlaying) { await Player.Stop(); + TimelineViewVM.CurrentPosition = TimeSpan.Zero; CaptureDevices.ForEach(x => x.EnableSourceUpdate()); _frameProvider.Disable = false; _playerBarItem.Pop(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Views/MainView.xaml index 445d0d216..37f92dea7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/Views/MainView.xaml @@ -8,6 +8,7 @@ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.DataCapture.ViewModels" + xmlns:logging="clr-namespace:Tango.MachineStudio.Logging.Views;assembly=Tango.MachineStudio.Logging" xmlns:video="clr-namespace:Tango.Video.DirectCapture;assembly=Tango.Video" xmlns:global="clr-namespace:Tango.MachineStudio.DataCapture" xmlns:local="clr-namespace:Tango.MachineStudio.DataCapture.Views" @@ -73,7 +74,7 @@ <Grid Grid.Column="1" Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="430"/> - <RowDefinition Height="419*"/> + <RowDefinition Height="1*"/> </Grid.RowDefinitions> <Grid> @@ -179,26 +180,15 @@ </Grid> <Grid Grid.Row="1"> - - <DockPanel HorizontalAlignment="Center" VerticalAlignment="Top" Margin="60" Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityConverter}}" TextElement.FontSize="20"> - <TextBlock DockPanel.Dock="Left"> - <Run FontWeight="SemiBold" FontStyle="Italic">Total Frames:</Run> - <Run FontStyle="Italic" Foreground="#545454" Text="{Binding Recorder.TotalFramesRecorded,StringFormat={}{0:N0},Mode=OneWay,TargetNullValue=0,FallbackValue=0}"></Run> - </TextBlock> - <TextBlock Margin="80 0 0 0" HorizontalAlignment="Right" Width="250"> - <Run FontWeight="SemiBold" FontStyle="Italic">File Size:</Run> - <Run FontStyle="Italic" Foreground="#545454" Text="{Binding Recorder.TotalBytesRecorded,Mode=OneWay,Converter={StaticResource NumberToFileSizeConverter},TargetNullValue=0,FallbackValue=0}"></Run> - </TextBlock> - </DockPanel> - - <StackPanel VerticalAlignment="Bottom" Margin="0 0 0 50"> + <DockPanel> + <StackPanel VerticalAlignment="Bottom" Margin="0 10 0 0" DockPanel.Dock="Bottom"> <Grid Margin="50 0 0 0"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center"> - <Button Command="{Binding MediaSeekBackwardCommand}" Margin="0 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="150" Height="150" Background="Transparent"> - <materialDesign:PackIcon Width="100" Height="100" Kind="Rewind" Foreground="{StaticResource AccentColorBrush}" /> + <Button Command="{Binding MediaSeekBackwardCommand}" Margin="0 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="60" Height="60" Background="Transparent"> + <materialDesign:PackIcon Width="40" Height="40" Kind="Rewind" Foreground="{StaticResource AccentColorBrush}" /> </Button> - <Button Command="{Binding MediaPlayPauseCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="200" Height="200" Background="Transparent"> - <materialDesign:PackIcon Width="100" Height="100" Foreground="{StaticResource AccentColorBrush}"> + <Button Command="{Binding MediaPlayPauseCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="80" Height="80" Background="Transparent"> + <materialDesign:PackIcon Width="60" Height="60" Foreground="{StaticResource AccentColorBrush}"> <materialDesign:PackIcon.Style> <Style TargetType="materialDesign:PackIcon"> <Setter Property="Kind" Value="Play"></Setter> @@ -215,18 +205,18 @@ </materialDesign:PackIcon.Style> </materialDesign:PackIcon> </Button> - <Button Command="{Binding MediaStopCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="150" Height="150" Background="Transparent"> - <materialDesign:PackIcon Width="100" Height="100" Kind="Stop" Foreground="{StaticResource AccentColorBrush}" /> + <Button Command="{Binding MediaStopCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="60" Height="60" Background="Transparent"> + <materialDesign:PackIcon Width="40" Height="40" Kind="Stop" Foreground="{StaticResource AccentColorBrush}" /> </Button> - <Button Command="{Binding MediaSeekForwardCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="150" Height="150" Background="Transparent"> - <materialDesign:PackIcon Width="100" Height="100" Kind="FastForward" Foreground="{StaticResource AccentColorBrush}" /> + <Button Command="{Binding MediaSeekForwardCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="60" Height="60" Background="Transparent"> + <materialDesign:PackIcon Width="40" Height="40" Kind="FastForward" Foreground="{StaticResource AccentColorBrush}" /> </Button> - <Button Command="{Binding MediaRecordingCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Foreground="#FF7A7A" BorderBrush="#FF8585" Padding="0" Width="100" Height="100" Background="Transparent" ToolTip="Start Recording"> - <materialDesign:PackIcon Width="50" Height="50" Kind="Record" /> + <Button Command="{Binding MediaRecordingCommand}" Margin="20 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Foreground="#FF7A7A" BorderBrush="#FF8585" Padding="0" Width="50" Height="50" Background="Transparent" ToolTip="Start Recording"> + <materialDesign:PackIcon Width="30" Height="30" Kind="Record" /> </Button> </StackPanel> <Grid> - <Label Margin="0 0 50 0" VerticalAlignment="Center" HorizontalAlignment="Right" Foreground="#FF8585" FontSize="60" FontFamily="{StaticResource digital-7}"> + <Label Margin="0 0 15 0" VerticalAlignment="Center" HorizontalAlignment="Right" Foreground="#FF8585" FontSize="40" FontFamily="{StaticResource digital-7}"> <Label.Style> <Style TargetType="Label"> <Setter Property="Opacity" Value="1"></Setter> @@ -273,8 +263,19 @@ </Label.Style> </Label> </Grid> + + <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" TextElement.FontSize="16" Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityConverter}}"> + <TextBlock DockPanel.Dock="Left"> + <Run FontWeight="SemiBold" FontStyle="Italic">Total Frames:</Run> + <Run FontStyle="Italic" Foreground="#545454" Text="{Binding Recorder.TotalFramesRecorded,StringFormat={}{0:N0},Mode=OneWay,TargetNullValue=0,FallbackValue=0}"></Run> + </TextBlock> + <TextBlock Margin="80 0 0 0" HorizontalAlignment="Right" Width="250"> + <Run FontWeight="SemiBold" FontStyle="Italic">File Size:</Run> + <Run FontStyle="Italic" Foreground="#545454" Text="{Binding Recorder.TotalBytesRecorded,Mode=OneWay,Converter={StaticResource NumberToFileSizeConverter},TargetNullValue=0,FallbackValue=0}"></Run> + </TextBlock> + </DockPanel> </Grid> - <Slider x:Name="slider" Margin="10 40 50 0" Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityInverseConverter}}" Maximum="{Binding Player.TotalFrames}" Value="{Binding Player.CurrentFrame,Mode=OneWay}"> + <Slider x:Name="slider" Margin="0 10 20 0" Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityInverseConverter}}" Maximum="{Binding Player.TotalFrames}" Value="{Binding Player.CurrentFrame,Mode=OneWay}"> <i:Interaction.Triggers> <i:EventTrigger EventName="PreviewMouseDown"> <i:InvokeCommandAction Command="{Binding MediaSeekHoldCommand}"></i:InvokeCommandAction> @@ -285,6 +286,39 @@ </i:Interaction.Triggers> </Slider> </StackPanel> + + <logging:TimelineView RenderTransformOrigin="0.5,0.5" DataContext="{Binding TimelineViewVM}" Margin="0 0 0 10"> + <FrameworkElement.Style> + <Style TargetType="FrameworkElement"> + <Setter Property="RenderTransform"> + <Setter.Value> + <ScaleTransform ScaleX="0" ScaleY="0" /> + </Setter.Value> + </Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.Player.IsPlaying}" Value="True"> + <DataTrigger.EnterActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1" Duration="00:00:0.2" /> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1" Duration="00:00:0.2" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.EnterActions> + <DataTrigger.ExitActions> + <BeginStoryboard> + <Storyboard> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="0" Duration="00:00:0.2" /> + <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="0" Duration="00:00:0.2" /> + </Storyboard> + </BeginStoryboard> + </DataTrigger.ExitActions> + </DataTrigger> + </Style.Triggers> + </Style> + </FrameworkElement.Style> + </logging:TimelineView> + </DockPanel> </Grid> </Grid> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index f455faa9e..63994f592 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -33,6 +33,7 @@ using System.Windows; using Tango.Core.Helpers; using System.Speech.Synthesis; using System.Media; +using Tango.MachineStudio.Common.EventLogging; namespace Tango.MachineStudio.Developer.ViewModels { @@ -57,6 +58,7 @@ namespace Tango.MachineStudio.Developer.ViewModels private SpeechSynthesizer _speech; private SoundPlayer _soundPlayer; private SoundPlayer _soundPlayerErr; + private IEventLogger _eventLogger; #region Properties @@ -598,7 +600,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// </summary> /// <param name="applicationManager">The application manager.</param> /// <param name="notificationProvider">The notification provider.</param> - public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, IAuthenticationProvider authentication) + public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, IAuthenticationProvider authentication, IEventLogger eventLogger) { SelectedJobs = new ObservableCollection<Job>(); @@ -625,6 +627,7 @@ namespace Tango.MachineStudio.Developer.ViewModels _navigation = navigation; ApplicationManager = applicationManager; VideoCaptureProvider = videoCaptureProvider; + _eventLogger = eventLogger; LogManager.Log("Initializing relay commands..."); @@ -1011,6 +1014,8 @@ namespace Tango.MachineStudio.Developer.ViewModels _jobHandler = MachineOperator.Print(ActiveJob, SelectedProcessParametersTable); + _eventLogger.Log(String.Format("Job '{0}' started...", ActiveJob.Name)); + _jobHandler.StatusReceived += (x, status) => { if (IsJobRunning) @@ -1044,10 +1049,12 @@ namespace Tango.MachineStudio.Developer.ViewModels if (segment.ID != -1) { SpeakInfo(String.Format("Segment {0} Started.", segment.SegmentIndex)); + _eventLogger.Log(String.Format("Segment {0} Started.", segment.SegmentIndex)); } else { SpeakInfo(String.Format("Inter Segment Started.")); + _eventLogger.Log("Inter Segment Started."); } } } @@ -1064,6 +1071,7 @@ namespace Tango.MachineStudio.Developer.ViewModels _jobHandler.Failed += (x, ex) => { LogManager.Log(ex, String.Format("Job {0} has failed.", RunningJob.Name)); + _eventLogger.Log(ex, String.Format("Job {0} has failed.", RunningJob.Name)); SetJobFailed(); InvokeUI(() => @@ -1075,18 +1083,21 @@ namespace Tango.MachineStudio.Developer.ViewModels _jobHandler.Completed += (x, e) => { LogManager.Log(String.Format("Job {0} has completed.", RunningJob.Name)); + _eventLogger.Log(String.Format("Job {0} has completed.", RunningJob.Name)); SetJobCompleted(); }; _jobHandler.Canceled += (x, y) => { LogManager.Log(String.Format("Job {0} has been canceled.", RunningJob.Name)); + _eventLogger.Log(String.Format("Job {0} has been canceled.", RunningJob.Name)); //Finally Canceled.. }; } catch (Exception ex) { LogManager.Log(ex); + _eventLogger.Log(ex, "An error occurred while starting the job."); _notification.ShowError("An error occurred while starting the job. " + Environment.NewLine + ex.Message); SetJobFailed(); } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimelineScrollViewer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimelineScrollViewer.cs new file mode 100644 index 000000000..dd1227a06 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimelineScrollViewer.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Input; + +namespace Tango.MachineStudio.Logging.Controls +{ + public class TimelineScrollViewer : ScrollViewer + { + public event EventHandler<MouseWheelEventArgs> MouseZooming; + + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + if (Keyboard.IsKeyDown(Key.LeftCtrl)) + { + e.Handled = true; + OnMouseZooming(e); + } + else + { + base.OnMouseWheel(e); + } + + e.Handled = false; + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) + { + if (e.Key == Key.Left || e.Key == Key.Right) + e.Handled = true; + return; + } + base.OnKeyDown(e); + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + e.Handled = true; + } + + protected virtual void OnMouseZooming(MouseWheelEventArgs e) + { + if (MouseZooming != null) MouseZooming(this, e); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs index 4c9f5b569..c5f310d52 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs @@ -18,7 +18,7 @@ namespace Tango.MachineStudio.Logging.Converters TimeSpan time = (TimeSpan)values[0]; double scale = (double)values[1]; - return TimelineHelper.ConvertTimeToPixels(time, scale) + 300; + return TimelineHelper.ConvertTimeToPixels(time, scale) + (parameter != null ? System.Convert.ToDouble(parameter) : 0); } return null; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj index 8bcdbe016..4b817a124 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj @@ -81,6 +81,7 @@ <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="Controls\TimelineScrollViewer.cs" /> <Compile Include="Controls\TimeRuler.cs" /> <Compile Include="Converters\DateIsInListToBooleanConverter.cs" /> <Compile Include="Converters\EventsToTimeRulerTicksConverter.cs" /> @@ -92,8 +93,13 @@ <Compile Include="Navigation\LoggingNavigationManager.cs" /> <Compile Include="Navigation\LoggingNavigationView.cs" /> <Compile Include="ViewModelLocator.cs" /> + <Compile Include="ViewModels\EventDetailsViewVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModels\TimelineEventGroup.cs" /> + <Compile Include="ViewModels\TimelineViewVM.cs" /> + <Compile Include="Views\EventDetailsView.xaml.cs"> + <DependentUpon>EventDetailsView.xaml</DependentUpon> + </Compile> <Compile Include="Views\EventsView.xaml.cs"> <DependentUpon>EventsView.xaml</DependentUpon> </Compile> @@ -103,6 +109,9 @@ <Compile Include="Views\TimelineView.xaml.cs"> <DependentUpon>TimelineView.xaml</DependentUpon> </Compile> + <Compile Include="Views\TimelineWrapperView.xaml.cs"> + <DependentUpon>TimelineWrapperView.xaml</DependentUpon> + </Compile> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs"> @@ -175,6 +184,10 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <Page Include="Views\EventDetailsView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\EventsView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -187,6 +200,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\TimelineWrapperView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> </ItemGroup> <ItemGroup> <Resource Include="Images\machine-trans.png" /> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventDetailsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventDetailsViewVM.cs new file mode 100644 index 000000000..0e3d19748 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventDetailsViewVM.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; +using Tango.SharedUI; + +namespace Tango.MachineStudio.Logging.ViewModels +{ + public class EventDetailsViewVM : DialogViewVM + { + public MachinesEvent Event { get; set; } + + public EventDetailsViewVM() + { + + } + + public EventDetailsViewVM(MachinesEvent ev) : this() + { + Event = ev; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs index 81b0a587c..e5121e709 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs @@ -13,6 +13,7 @@ using Tango.MachineStudio.Common.Messages; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Logging.Navigation; +using Tango.MachineStudio.Logging.Views; using Tango.SharedUI; namespace Tango.MachineStudio.Logging.ViewModels @@ -83,32 +84,12 @@ namespace Tango.MachineStudio.Logging.ViewModels set { _isRealTime = value; RaisePropertyChangedAuto(); OnSelectedDateChanged(); } } - private ObservableCollection<TimelineEventGroup> _timelineEventGroups; - public ObservableCollection<TimelineEventGroup> TimelineEventGroups - { - get { return _timelineEventGroups; } - set { _timelineEventGroups = value; RaisePropertyChangedAuto(); } - } - - private TimeSpan _timelineMaxTime; - public TimeSpan TimelineMaxTime - { - get { return _timelineMaxTime; } - set { _timelineMaxTime = value; RaisePropertyChangedAuto(); } - } + private TimelineViewVM _timelineViewVM; - private double _timelineScaleFactor; - public double TimelineScaleFactor + public TimelineViewVM TimelineViewVM { - get { return _timelineScaleFactor; } - set - { - - if (value < 0.1) value = 0.1; - - _timelineScaleFactor = value; - RaisePropertyChangedAuto(); - } + get { return _timelineViewVM; } + set { _timelineViewVM = value; RaisePropertyChangedAuto(); } } public RelayCommand<MachinesEvent> DisplayTimelineCommand { get; set; } @@ -117,6 +98,8 @@ namespace Tango.MachineStudio.Logging.ViewModels public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application, LoggingNavigationManager navigation) { + TimelineViewVM = new TimelineViewVM(notification); + _navigation = navigation; _application = application; _notification = notification; @@ -124,8 +107,6 @@ namespace Tango.MachineStudio.Logging.ViewModels _realTimeEvents = new ObservableCollection<MachinesEvent>(); _eventLogger.NewLog += _eventLogger_NewLog; - TimelineScaleFactor = 10; - RegisterMessage<MachineConnectionChangedMessage>(OnMachineConnectionChanged); DisplayTimelineCommand = new RelayCommand<MachinesEvent>(DisplayTimeline); NavigateToEventsCommand = new RelayCommand(() => _navigation.NavigateTo(LoggingNavigationView.EventsView)); @@ -194,7 +175,7 @@ namespace Tango.MachineStudio.Logging.ViewModels { if (SelectedEvent != null && SelectedEvent.Type != BL.Enumerations.EventTypes.ApplicationStarted) { - _notification.ShowInfo(SelectedEvent.Description); + _notification.ShowModalDialog<EventDetailsViewVM, EventDetailsView>(new EventDetailsViewVM(SelectedEvent), (x) => { }, () => { }); } } @@ -203,21 +184,7 @@ namespace Tango.MachineStudio.Logging.ViewModels var events = Events.OrderBy(x => x.DateTime).SkipWhile(x => x != ev).Skip(1).TakeWhile(x => x.DateTime > ev.DateTime && x.Type != BL.Enumerations.EventTypes.ApplicationStarted).ToObservableCollection(); events.Insert(0, ev); - TimelineEventGroups = new ObservableCollection<TimelineEventGroup>(); - - foreach (var group in events.GroupBy(x => x.Group)) - { - TimelineEventGroup evGroup = new TimelineEventGroup(group.Key.ToString().ToWords()); - - foreach (var e in group) - { - evGroup.Events.Add(e); - } - - TimelineEventGroups.Add(evGroup); - } - - TimelineMaxTime = events.Max(x => x.DateTime) - events.Min(x => x.DateTime); + TimelineViewVM.Initialize(events.ToList()); _navigation.NavigateTo(LoggingNavigationView.TimelineView); } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineViewVM.cs new file mode 100644 index 000000000..edf53bbd2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineViewVM.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Logging.Views; +using Tango.SharedUI; + +namespace Tango.MachineStudio.Logging.ViewModels +{ + public class TimelineViewVM : ViewModel + { + private ObservableCollection<TimelineEventGroup> _timelineEventGroups; + public ObservableCollection<TimelineEventGroup> TimelineEventGroups + { + get { return _timelineEventGroups; } + set { _timelineEventGroups = value; RaisePropertyChangedAuto(); } + } + + private TimeSpan _timelineMaxTime; + public TimeSpan TimelineMaxTime + { + get { return _timelineMaxTime; } + set { _timelineMaxTime = value; RaisePropertyChangedAuto(); } + } + + private double _timelineScaleFactor; + public double TimelineScaleFactor + { + get { return _timelineScaleFactor; } + set + { + + if (value < 0.1) value = 0.1; + + _timelineScaleFactor = value; + RaisePropertyChangedAuto(); + } + } + + private TimeSpan _currentPosition; + + public TimeSpan CurrentPosition + { + get { return _currentPosition; } + set { _currentPosition = value; RaisePropertyChangedAuto(); } + } + + private bool _enableTimeMarker; + + public bool EnableTimeMarker + { + get { return _enableTimeMarker; } + set { _enableTimeMarker = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand<MachinesEvent> EventSelectedCommand { get; set; } + + + public TimelineViewVM(INotificationProvider notification) + { + TimelineScaleFactor = 10; + TimelineEventGroups = new ObservableCollection<TimelineEventGroup>(); + + EventSelectedCommand = new RelayCommand<MachinesEvent>((ev) => + { + notification.ShowModalDialog<EventDetailsViewVM, EventDetailsView>(new EventDetailsViewVM(ev), (x) => { }, () => { }); + }); + } + + public void Initialize(List<MachinesEvent> events) + { + TimelineEventGroups = new ObservableCollection<TimelineEventGroup>(); + + if (events != null && events.Count > 0) + { + foreach (var group in events.GroupBy(x => x.Group)) + { + TimelineEventGroup evGroup = new TimelineEventGroup(group.Key.ToString().ToWords()); + + foreach (var e in group) + { + evGroup.Events.Add(e); + } + + TimelineEventGroups.Add(evGroup); + } + + TimelineMaxTime = events.Max(x => x.DateTime) - events.Min(x => x.DateTime); + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml new file mode 100644 index 000000000..c75ef41ee --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml @@ -0,0 +1,93 @@ +<UserControl x:Class="Tango.MachineStudio.Logging.Views.EventDetailsView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:vm="clr-namespace:Tango.MachineStudio.Logging.ViewModels" + xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" + xmlns:local="clr-namespace:Tango.MachineStudio.Logging.Views" + mc:Ignorable="d" + Height="500" Width="800" Background="White" d:DataContext="{d:DesignInstance Type=vm:EventDetailsViewVM, IsDesignTimeCreatable=False}"> + + <UserControl.Resources> + <converters:DateTimeUTCToStringConverter x:Key="DateTimeUTCToStringConverter" /> + </UserControl.Resources> + + <Grid> + <Grid Grid.RowSpan="2"> + <Grid.RowDefinitions> + <RowDefinition Height="60"/> + <RowDefinition Height="31*"/> + <RowDefinition Height="50"/> + </Grid.RowDefinitions> + + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Width="42" Height="42" VerticalAlignment="Center"> + <materialDesign:PackIcon.Style> + <Style TargetType="materialDesign:PackIcon"> + <Setter Property="Kind" Value="Alert"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Event.Category}" Value="Info"> + <Setter Property="Kind" Value="Information"></Setter> + <Setter Property="Foreground" Value="DimGray"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Event.Category}" Value="Warning"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="#FFA300"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Event.Category}" Value="Error"> + <Setter Property="Kind" Value="AlertOctagon"></Setter> + <Setter Property="Foreground" Value="#FF5C5C"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Event.Category}" Value="Critical"> + <Setter Property="Kind" Value="BellPlus"></Setter> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Event.Type}" Value="ApplicationStarted"> + <Setter Property="Kind" Value="ClockFast"></Setter> + <Setter Property="Foreground" Value="White"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </materialDesign:PackIcon.Style> + </materialDesign:PackIcon> + <TextBlock VerticalAlignment="Center" Text="{Binding Event.EventType.Name}" Margin="10 0 0 0" FontSize="16"></TextBlock> + </StackPanel> + + <Grid Grid.Row="1"> + <DockPanel> + <UniformGrid Columns="2" DockPanel.Dock="Top"> + <controls:TableGrid RowHeight="30"> + <TextBlock Text="Date:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.DateTime,Converter={StaticResource DateTimeUTCToStringConverter},ConverterParameter='MM/dd/yyyy HH:mm:ss.fff'}"></TextBlock> + <TextBlock Text="Host Name:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.HostName}"></TextBlock> + <TextBlock Text="Machine:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.Machine.SerialNumber}"></TextBlock> + <TextBlock Text="User:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.User.Contact.FullName}"></TextBlock> + </controls:TableGrid> + + <controls:TableGrid RowHeight="30"> + <TextBlock Text="Category:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.EventType.EventTypesCategory.Name}"></TextBlock> + <TextBlock Text="Group:" FontWeight="SemiBold" /> + <TextBlock Text="{Binding Event.EventType.EventTypesGroup.Name}"></TextBlock> + </controls:TableGrid> + </UniformGrid> + + <Border Padding="5" BorderThickness="1" BorderBrush="Gainsboro"> + <TextBox BorderThickness="0" Text="{Binding Event.Description}" Style="{x:Null}" TextWrapping="Wrap" IsReadOnly="True" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Background="Transparent" /> + </Border> + </DockPanel> + </Grid> + + <Grid Grid.Row="2"> + <Button HorizontalAlignment="Right" Width="140" Command="{Binding CloseCommand}">CLOSE</Button> + </Grid> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml.cs new file mode 100644 index 000000000..dd447e1b6 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.Logging.Views +{ + /// <summary> + /// Interaction logic for EventDetailsView.xaml + /// </summary> + public partial class EventDetailsView : UserControl + { + public EventDetailsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml index a3b4ae6bf..d92e56ddc 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml @@ -16,6 +16,7 @@ <UserControl.Resources> <autoCompleteMachine:MachinesProvider x:Key="MachinesProvider" /> <converters:DateTimeUTCToShortDateTimeConverter x:Key="DateTimeUTCToShortDateTimeConverter" /> + <converters:DateTimeUTCToStringConverter x:Key="DateTimeUTCToStringConverter" /> <localConverters:DateIsInListToBooleanConverter x:Key="DateIsInListToBooleanConverter" /> <Style x:Key="CustomCalendarDayButtonStyle" TargetType="{x:Type CalendarDayButton}" BasedOn="{StaticResource MaterialDesignCalendarDayButton}"> @@ -191,7 +192,7 @@ </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> - <DataGridTextColumn Header="DATE TIME" Binding="{Binding DateTime,Converter={StaticResource DateTimeUTCToShortDateTimeConverter}}" /> + <DataGridTextColumn Header="DATE TIME" Binding="{Binding DateTime,Converter={StaticResource DateTimeUTCToStringConverter},ConverterParameter='MM/dd/yyyy HH:mm:ss.fff'}" /> <DataGridTextColumn Header="HOST" Binding="{Binding HostName}" /> <DataGridTextColumn Header="USER" Binding="{Binding User.Contact.FullName,Mode=OneTime}" /> <DataGridTextColumn Header="GROUP" Binding="{Binding EventType.EventTypesGroup.Name}" /> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml index 6d841149e..6d5f98b51 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml @@ -22,7 +22,7 @@ <local:EventsView/> </ContentControl> <ContentControl Tag="TimelineView"> - <local:TimelineView/> + <local:TimelineWrapperView /> </ContentControl> </controls:MultiTransitionControl.Controls> </controls:MultiTransitionControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml index e746f67b3..504514cbb 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml @@ -7,17 +7,19 @@ xmlns:global="clr-namespace:Tango.MachineStudio.Logging" xmlns:localConverters="clr-namespace:Tango.MachineStudio.Logging.Converters" xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:vm="clr-namespace:Tango.MachineStudio.Logging.ViewModels" xmlns:localControls="clr-namespace:Tango.MachineStudio.Logging.Controls" xmlns:local="clr-namespace:Tango.MachineStudio.Logging.Views" mc:Ignorable="d" - d:DesignHeight="1080" d:DesignWidth="1920" Background="White" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}" MouseWheel="UserControl_MouseWheel"> + d:DesignHeight="1080" d:DesignWidth="1920" Background="White" d:DataContext="{d:DesignInstance Type=vm:TimelineViewVM, IsDesignTimeCreatable=False}" MouseWheel="UserControl_MouseWheel"> <UserControl.Resources> <localConverters:TimeSpanToXConverter x:Key="TimeSpanToXConverter" /> <localConverters:MachineEventToXConverter x:Key="MachineEventToXConverter" /> <localConverters:SecondsToWidthConverter x:Key="SecondsToWidthConverter" /> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <LinearGradientBrush x:Key="infoBrush" StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Color="White"/> @@ -39,26 +41,14 @@ <GradientStop Color="White" Offset="1"/> </LinearGradientBrush> + <LinearGradientBrush x:Key="hoverBrush" StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Color="#9D9D9D"/> + <GradientStop Color="#F9F9F9" Offset="1"/> + </LinearGradientBrush> </UserControl.Resources> <Grid> <Grid> - <Grid.RowDefinitions> - <RowDefinition Height="70"/> - <RowDefinition Height="1*"/> - </Grid.RowDefinitions> - - <Grid> - <StackPanel Orientation="Horizontal" Margin="10"> - <Button MinWidth="160" Height="50" Style="{StaticResource MaterialDesignFlatButton}" Command="{Binding NavigateToEventsCommand}" HorizontalContentAlignment="Left"> - <StackPanel Orientation="Horizontal" > - <materialDesign:PackIcon Kind="KeyboardBackspace" Width="20" Height="20" /> - <TextBlock Margin="5 0 0 0" FontSize="16">BACK</TextBlock> - </StackPanel> - </Button> - </StackPanel> - </Grid> - <Grid Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="30"/> @@ -77,7 +67,7 @@ </Grid> - <ItemsControl ItemsSource="{Binding TimelineEventGroups}" Grid.Column="0" Grid.Row="1" Margin="0 -3 0 0"> + <ItemsControl ItemsSource="{Binding TimelineEventGroups}" Grid.Column="0" Grid.Row="1" Margin="0 0 0 0" Background="#FCFCFC" Height="{Binding ElementName=scrollViewer,Path=ViewportHeight}" VerticalAlignment="Top"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Columns="1" /> @@ -85,76 +75,112 @@ </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate DataType="{x:Type vm:TimelineEventGroup}"> - <Border BorderThickness="1 1 1 1" BorderBrush="{StaticResource AccentColorBrush}" Margin="2 2 0 2"> + <Border BorderThickness="1 0.5 1 0.5" BorderBrush="{StaticResource AccentColorBrush}" Margin="2 0 0 0" Padding="5"> - <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="28" FontWeight="SemiBold" Foreground="{StaticResource AccentColorBrush}"></TextBlock> + <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" TextWrapping="Wrap" TextAlignment="Center" FontWeight="SemiBold" Foreground="{StaticResource AccentColorBrush}"></TextBlock> </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> - <ScrollViewer x:Name="scrollViewer" Grid.Column="1" Grid.Row="1" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto"> - <ItemsControl ItemsSource="{Binding TimelineEventGroups}" HorizontalAlignment="Left"> - <ItemsControl.Width> - <MultiBinding Converter="{StaticResource TimeSpanToXConverter}"> - <Binding Path="TimelineMaxTime" /> - <Binding Path="TimelineScaleFactor" /> - </MultiBinding> - </ItemsControl.Width> - <ItemsControl.ItemsPanel> - <ItemsPanelTemplate> - <UniformGrid Columns="1" /> - </ItemsPanelTemplate> - </ItemsControl.ItemsPanel> - <ItemsControl.ItemTemplate> - <DataTemplate DataType="{x:Type vm:TimelineEventGroup}"> - <ItemsControl ItemsSource="{Binding Events}"> - <ItemsControl.ItemsPanel> - <ItemsPanelTemplate> - <UniformGrid IsItemsHost="True" Columns="1"></UniformGrid> - </ItemsPanelTemplate> - </ItemsControl.ItemsPanel> - <ItemsControl.ItemTemplate> - <DataTemplate DataType="{x:Type entities:MachinesEvent}"> - <Canvas Margin="10"> - <Grid Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}"> - <Canvas.Left> - <MultiBinding Converter="{StaticResource MachineEventToXConverter}"> - <Binding Path="." /> - <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="DataContext.TimelineEventGroups" /> - <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="DataContext.TimelineScaleFactor" /> - </MultiBinding> - </Canvas.Left> - <Border BorderBrush="#4E4E4E" BorderThickness="1" Padding="10" MinHeight="20" MinWidth="50"> - <Border.Style> - <Style TargetType="Border"> - <Style.Triggers> - <DataTrigger Binding="{Binding Category}" Value="Info"> - <Setter Property="Background" Value="{StaticResource infoBrush}"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Category}" Value="Warning"> - <Setter Property="Background" Value="{StaticResource warningBrush}"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Category}" Value="Error"> - <Setter Property="Background" Value="{StaticResource errorBrush}"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding Category}" Value="Crtitical"> - <Setter Property="Background" Value="{StaticResource criticalBrush}"></Setter> - </DataTrigger> - </Style.Triggers> - </Style> - </Border.Style> - <TextBlock Text="{Binding Description}" Height="17"></TextBlock> - </Border> - </Grid> - </Canvas> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - </ScrollViewer> + <localControls:TimelineScrollViewer x:Name="scrollViewer" Grid.Column="1" Grid.Row="1" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto"> + <Grid HorizontalAlignment="Left"> + <ItemsControl ItemsSource="{Binding TimelineEventGroups}" HorizontalAlignment="Left" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=localControls:TimelineScrollViewer},Path=ActualWidth}"> + <ItemsControl.Width> + <MultiBinding Converter="{StaticResource TimeSpanToXConverter}" ConverterParameter="300"> + <Binding Path="TimelineMaxTime" /> + <Binding Path="TimelineScaleFactor" /> + </MultiBinding> + </ItemsControl.Width> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <UniformGrid Columns="1" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate DataType="{x:Type vm:TimelineEventGroup}"> + <Border BorderThickness="0 0 0 1" BorderBrush="#98DEFF" Margin="0 0 0 0"> + <ItemsControl ItemsSource="{Binding Events}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <UniformGrid IsItemsHost="True" Columns="1"></UniformGrid> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate DataType="{x:Type entities:MachinesEvent}"> + <Canvas Margin="0 5 0 5" MinHeight="20"> + <Grid Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}"> + <Canvas.Left> + <MultiBinding Converter="{StaticResource MachineEventToXConverter}"> + <Binding Path="." /> + <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="DataContext.TimelineEventGroups" /> + <Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="DataContext.TimelineScaleFactor" /> + </MultiBinding> + </Canvas.Left> + <Border BorderBrush="#4E4E4E" BorderThickness="1" Padding="2" MinWidth="50" Cursor="Hand"> + <i:Interaction.Triggers> + <i:EventTrigger EventName="PreviewMouseUp"> + <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.EventSelectedCommand}" CommandParameter="{Binding}" /> + </i:EventTrigger> + </i:Interaction.Triggers> + <Border.Style> + <Style TargetType="Border"> + <Style.Triggers> + <DataTrigger Binding="{Binding Category}" Value="Info"> + <Setter Property="Background" Value="{StaticResource infoBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Warning"> + <Setter Property="Background" Value="{StaticResource warningBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Error"> + <Setter Property="Background" Value="{StaticResource errorBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Category}" Value="Crtitical"> + <Setter Property="Background" Value="{StaticResource criticalBrush}"></Setter> + </DataTrigger> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Opacity" Value="0.7"></Setter> + </Trigger> + </Style.Triggers> + </Style> + </Border.Style> + <StackPanel Orientation="Horizontal"> + <TextBlock FontWeight="SemiBold" Text="{Binding EventType.Name}" Height="14" FontSize="11"></TextBlock> + <TextBlock Margin="10 0 0 0" Text="{Binding Description}" Height="14" FontSize="11"></TextBlock> + </StackPanel> + </Border> + </Grid> + </Canvas> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <Canvas Visibility="{Binding EnableTimeMarker,Converter={StaticResource BooleanToVisibilityConverter}}" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=localControls:TimelineScrollViewer},Path=ActualWidth}" ClipToBounds="False" IsHitTestVisible="False"> + <Grid Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas},Path=ActualHeight}" ClipToBounds="False"> + <Canvas.Left> + <MultiBinding Converter="{StaticResource TimeSpanToXConverter}"> + <Binding Path="CurrentPosition" /> + <Binding Path="TimelineScaleFactor" /> + </MultiBinding> + </Canvas.Left> + + <Rectangle Stroke="DodgerBlue" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Stretch" /> + <Polygon Fill="DodgerBlue" Points="0,0 16,0 8,15 0,0" Margin="-8 -5 0 0" VerticalAlignment="Top" /> + </Grid> + </Canvas> + </Grid> + </localControls:TimelineScrollViewer> + + <Border Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="20" Padding="10" Background="#7ECECECE" CornerRadius="5"> + <Grid> + <materialDesign:PackIcon Kind="MagnifyPlus" Margin="0 -35 0 0" Width="20" Height="20" Foreground="Gray" /> + <Slider Minimum="0.5" Maximum="100" Value="{Binding TimelineScaleFactor}" Orientation="Vertical" Height="120"/> + </Grid> + </Border> </Grid> </Grid> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs index 53e2362dc..e1c09e49f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs @@ -21,12 +21,12 @@ namespace Tango.MachineStudio.Logging.Views /// </summary> public partial class TimelineView : UserControl { - private MainViewVM _vm; + private TimelineViewVM _vm; public TimelineView() { InitializeComponent(); - this.Loaded += (_, __) => _vm = DataContext as MainViewVM; + this.Loaded += (_, __) => _vm = DataContext as TimelineViewVM; } private void UserControl_MouseWheel(object sender, MouseWheelEventArgs e) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml new file mode 100644 index 000000000..abab55264 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml @@ -0,0 +1,33 @@ +<UserControl x:Class="Tango.MachineStudio.Logging.Views.TimelineWrapperView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:global="clr-namespace:Tango.MachineStudio.Logging" + xmlns:vm="clr-namespace:Tango.MachineStudio.Logging.ViewModels" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.MachineStudio.Logging.Views" + mc:Ignorable="d" + d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="70"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + + <Grid> + <StackPanel Orientation="Horizontal" Margin="10"> + <Button MinWidth="160" Height="50" Style="{StaticResource MaterialDesignFlatButton}" Command="{Binding NavigateToEventsCommand}" HorizontalContentAlignment="Left"> + <StackPanel Orientation="Horizontal" > + <materialDesign:PackIcon Kind="KeyboardBackspace" Width="20" Height="20" /> + <TextBlock Margin="5 0 0 0" FontSize="16">BACK</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + + <Grid Grid.Row="1"> + <local:TimelineView DataContext="{Binding TimelineViewVM}" /> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml.cs new file mode 100644 index 000000000..1ca2c30cb --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.Logging.Views +{ + /// <summary> + /// Interaction logic for TimelineWrapperView.xaml + /// </summary> + public partial class TimelineWrapperView : UserControl + { + public TimelineWrapperView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs index 8f1076bb8..63612d420 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/DefaultDiagnosticsFrameProvider.cs @@ -34,25 +34,6 @@ namespace Tango.MachineStudio.Common.Diagnostics set { _disable = value; - - if (!_disable) - { - if (_application.ConnectedMachine != null) - { - MachineEventsStateProvider = _application.ConnectedMachine.MachineEventsStateProvider; - } - else - { - MachineEventsStateProvider = new DefaultMachineEventsStateProvider(); - } - } - else - { - if (_application.ConnectedMachine != null) - { - MachineEventsStateProvider = new DefaultMachineEventsStateProvider(); - } - } } } @@ -61,21 +42,6 @@ namespace Tango.MachineStudio.Common.Diagnostics /// </summary> public event EventHandler<PushDiagnosticsResponse> FrameReceived; - private IMachineEventsStateProvider _machineEventsStateProvider; - /// <summary> - /// Gets or sets the machine events state provider used to get notifications about current machine events and errors. - /// </summary> - public IMachineEventsStateProvider MachineEventsStateProvider - { - get { return _machineEventsStateProvider; } - set - { - _machineEventsStateProvider = value; - RaisePropertyChangedAuto(); - MachineEventsStateProviderChanged?.Invoke(this, _machineEventsStateProvider); - } - } - /// <summary> /// Initializes a new instance of the <see cref="DefaultDiagnosticsFrameProvider"/> class. /// </summary> @@ -83,7 +49,6 @@ namespace Tango.MachineStudio.Common.Diagnostics public DefaultDiagnosticsFrameProvider(IStudioApplicationManager applicationManager) { _application = applicationManager; - MachineEventsStateProvider = new DefaultMachineEventsStateProvider(); applicationManager.ConnectedMachineChanged += ApplicationManager_ConnectedMachineChanged; } @@ -97,11 +62,6 @@ namespace Tango.MachineStudio.Common.Diagnostics if (machine != null) { machine.DiagnosticsDataAvailable += DefaultDiagnosticsFrameProvider_DiagnosticsDataAvailable; - - if (!Disable) - { - MachineEventsStateProvider = machine.MachineEventsStateProvider; - } } } @@ -127,7 +87,6 @@ namespace Tango.MachineStudio.Common.Diagnostics if (Disable) { OnFrameReceived(frame); - MachineEventsStateProvider.ApplyEvents(frame.Events); } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs index ab4780a1f..3294b341d 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Diagnostics/IDiagnosticsFrameProvider.cs @@ -19,16 +19,6 @@ namespace Tango.MachineStudio.Common.Diagnostics event EventHandler<PushDiagnosticsResponse> FrameReceived; /// <summary> - /// Occurs when the machine events state provider has changed. - /// </summary> - event EventHandler<IMachineEventsStateProvider> MachineEventsStateProviderChanged; - - /// <summary> - /// Gets or sets the machine events state provider used to get notifications about current machine events and errors. - /// </summary> - IMachineEventsStateProvider MachineEventsStateProvider { get; } - - /// <summary> /// Disables the frame delivery from the current connected machine and enables the manual push frame method. /// </summary> bool Disable { get; set; } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs index d3fb0897f..91aa049e9 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs @@ -220,6 +220,7 @@ namespace Tango.MachineStudio.Common.EventLogging machineEvent.DateTime = DateTime.UtcNow; machineEvent.Description = message; machineEvent.EventType = _eventTypesGuids[eventType]; + machineEvent.EventTypeGuid = machineEvent.EventType.Guid; Log(machineEvent); } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index 81719287b..c9f4b3441 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -238,8 +238,6 @@ namespace Tango.MachineStudio.UI.ViewModels ApplicationManager = applicationManager; DiagnosticsFrameProvider = frameProvider; - DiagnosticsFrameProvider.MachineEventsStateProviderChanged += FrameProvider_MachineEventsStateProviderChanged; - StartModuleCommand = new RelayCommand<IStudioModule>(StartModule); HomeCommand = new RelayCommand(Home); @@ -253,26 +251,23 @@ namespace Tango.MachineStudio.UI.ViewModels _updateCheckThread = new Thread(UpdateCheckThreadMethod); _updateCheckThread.IsBackground = true; _updateCheckThread.Start(); - } - private void FrameProvider_MachineEventsStateProviderChanged(object sender, Integration.Operation.IMachineEventsStateProvider provider) - { - - if (DiagnosticsFrameProvider.MachineEventsStateProvider.Events.Count == 0) + ApplicationManager.ConnectedMachineChanged += (sender, machine) => { - IsMachineErrorsOpened = false; - } - - provider.NewEvents -= MachineEventsStateProvider_NewEvents; - provider.NewEvents += MachineEventsStateProvider_NewEvents; + if (machine != null) + { + machine.MachineEventsStateProvider.NewEvents -= MachineEventsStateProvider_NewEvents; + machine.MachineEventsStateProvider.NewEvents += MachineEventsStateProvider_NewEvents; - provider.EventsResolved -= MachineEventsStateProvider_EventsResolved; - provider.EventsResolved += MachineEventsStateProvider_EventsResolved; + machine.MachineEventsStateProvider.EventsResolved -= MachineEventsStateProvider_EventsResolved; + machine.MachineEventsStateProvider.EventsResolved += MachineEventsStateProvider_EventsResolved; + } + }; } private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable<MachinesEvent> e) { - if (DiagnosticsFrameProvider.MachineEventsStateProvider.Events.Count == 0) + if (ApplicationManager.ConnectedMachine.MachineEventsStateProvider.Events.Count == 0) { IsMachineErrorsOpened = false; } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index a85e0a850..b7a4cc93f 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -227,11 +227,11 @@ </StackPanel> </Button> - <ToggleButton Visibility="{Binding DiagnosticsFrameProvider.MachineEventsStateProvider.HasEvents,Converter={StaticResource BooleanToVisibilityConverter},FallbackValue=Collapsed,TargetNullValue=Collapsed,Mode=OneWay}" IsChecked="{Binding IsMachineErrorsOpened}" Style="{StaticResource emptyToggleButton}" Margin="0 0 10 0" Cursor="Hand"> + <ToggleButton Visibility="{Binding ApplicationManager.ConnectedMachine.MachineEventsStateProvider.HasEvents,Converter={StaticResource BooleanToVisibilityConverter},FallbackValue=Collapsed,TargetNullValue=Collapsed,Mode=OneWay}" IsChecked="{Binding IsMachineErrorsOpened}" Style="{StaticResource emptyToggleButton}" Margin="0 0 10 0" Cursor="Hand"> <ToggleButton.ToolTip> <TextBlock> <Run>Press to view</Run> - <Run Text="{Binding DiagnosticsFrameProvider.MachineEventsStateProvider.Events.Count,Mode=OneWay}"></Run> + <Run Text="{Binding ApplicationManager.ConnectedMachine.MachineEventsStateProvider.Events.Count,Mode=OneWay}"></Run> <Run>hardware messages</Run> </TextBlock> </ToggleButton.ToolTip> @@ -240,7 +240,7 @@ <Style TargetType="Grid"> <Setter Property="Opacity" Value="1"></Setter> <Style.Triggers> - <DataTrigger Binding="{Binding DiagnosticsFrameProvider.MachineEventsStateProvider.HasEvents}" Value="True"> + <DataTrigger Binding="{Binding ApplicationManager.ConnectedMachine.MachineEventsStateProvider.HasEvents}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> @@ -433,7 +433,7 @@ <DropShadowEffect ShadowDepth="0" BlurRadius="10" /> </Border.Effect> - <ItemsControl ItemsSource="{Binding DiagnosticsFrameProvider.MachineEventsStateProvider.Events}"> + <ItemsControl ItemsSource="{Binding ApplicationManager.ConnectedMachine.MachineEventsStateProvider.Events}"> <ItemsControl.ItemTemplate> <DataTemplate DataType="{x:Type entities:MachinesEvent}"> <Border BorderThickness="0 0 0 1" BorderBrush="#E1E1E1" Padding="5"> diff --git a/Software/Visual_Studio/Tango.BL/EntitiesExtensions/MachineEvent.cs b/Software/Visual_Studio/Tango.BL/EntitiesExtensions/MachineEvent.cs index 7e4b7140b..33dd34d2c 100644 --- a/Software/Visual_Studio/Tango.BL/EntitiesExtensions/MachineEvent.cs +++ b/Software/Visual_Studio/Tango.BL/EntitiesExtensions/MachineEvent.cs @@ -9,6 +9,7 @@ using Tango.PMR.Diagnostics; namespace Tango.BL.Entities { + [Serializable] public partial class MachinesEvent { private static Dictionary<EventTypes, EventType> _eventTypesGuids; diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/EventTypes.cs b/Software/Visual_Studio/Tango.BL/Enumerations/EventTypes.cs index b10ba8848..801d1208f 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/EventTypes.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/EventTypes.cs @@ -225,5 +225,17 @@ namespace Tango.BL.Enumerations [Description("Notifies about application termination")] ApplicationTerminated = 35, + /// <summary> + /// (Occures when a diagnostics recording has been started) + /// </summary> + [Description("Occures when a diagnostics recording has been started")] + RecordingStarted = 36, + + /// <summary> + /// (Occures when a diagnostics recording has been stopped) + /// </summary> + [Description("Occures when a diagnostics recording has been stopped")] + RecordingStopped = 37, + } } diff --git a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs index 9fc0444ea..1073a31ce 100644 --- a/Software/Visual_Studio/Tango.BL/ObservableEntity.cs +++ b/Software/Visual_Studio/Tango.BL/ObservableEntity.cs @@ -31,6 +31,7 @@ namespace Tango.BL /// <typeparam name="T"></typeparam> /// <seealso cref="Tango.Core.ExtendedObject" /> /// <seealso cref="Tango.BL.Entities.IObservableEntity" /> + [Serializable] public abstract class ObservableEntity<T> : ExtendedObject, IObservableEntity where T : class, IObservableEntity { private Regex regExDAL; diff --git a/Software/Visual_Studio/Tango.BrushPicker/Converters/BrushToGradientStopsConverter.cs b/Software/Visual_Studio/Tango.BrushPicker/Converters/BrushToGradientStopsConverter.cs new file mode 100644 index 000000000..077e44562 --- /dev/null +++ b/Software/Visual_Studio/Tango.BrushPicker/Converters/BrushToGradientStopsConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; + +namespace Tango.BrushPicker.Converters +{ + public class BrushToGradientStopsConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + Brush brush = value as LinearGradientBrush; + + if (brush != null) + { + return (brush as LinearGradientBrush).GradientStops; + } + + return null; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/Tango.BrushPicker/Tango.BrushPicker.csproj b/Software/Visual_Studio/Tango.BrushPicker/Tango.BrushPicker.csproj index c007f793d..2c1bae3d9 100644 --- a/Software/Visual_Studio/Tango.BrushPicker/Tango.BrushPicker.csproj +++ b/Software/Visual_Studio/Tango.BrushPicker/Tango.BrushPicker.csproj @@ -60,6 +60,7 @@ <Compile Include="..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="Converters\BrushToGradientStopsConverter.cs" /> <Compile Include="Implementation\AlphaSelector.cs" /> <Compile Include="Implementation\BaseSelector.cs" /> <Compile Include="Implementation\BrushPicker.cs" /> @@ -85,6 +86,7 @@ <SubType>Designer</SubType> </Page> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/Software/Visual_Studio/Tango.BrushPicker/Themes/Generic.xaml b/Software/Visual_Studio/Tango.BrushPicker/Themes/Generic.xaml index 5b1bcbbc3..b496be57b 100644 --- a/Software/Visual_Studio/Tango.BrushPicker/Themes/Generic.xaml +++ b/Software/Visual_Studio/Tango.BrushPicker/Themes/Generic.xaml @@ -11,8 +11,11 @@ <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:converters="clr-namespace:Tango.BrushPicker.Converters" xmlns:local="clr-namespace:Tango.BrushPicker"> + <converters:BrushToGradientStopsConverter x:Key="BrushToGradientStopsConverter" /> + <Geometry x:Key="SkewIcon">M456.021,227.816L545.590,227.816L456.021,362.171L366.452,362.171L456.021,227.816</Geometry> <Geometry x:Key="TranslateIcon">M384,289.828L384,363L457.171,363M384,363L457.171,289.828M480,267L480,310.011L435.711,267L480,267</Geometry> <Geometry x:Key="RotateIcon">F1 M 32.0034,13.0019L 35.0033,16.002L 35.0034,24.0019L 27.0033,24.002L 24.0034,21.0019L 29.5944,21.0014C 28.2209,19.4668 26.2249,18.501 24.0033,18.501C 19.8606,18.501 16.5022,21.8593 16.5022,26.002C 16.5022,28.0734 17.3418,29.9486 18.6992,31.3061L 16.2241,33.7812C 14.2332,31.7903 13.0018,29.0399 13.0018,26.0019C 13.0018,19.926 17.9274,15.0004 24.0033,15.0004C 27.1557,15.0004 29.9984,16.3263 32.0042,18.4508L 32.0034,13.0019 Z</Geometry> @@ -408,7 +411,7 @@ FocusVisualStyle="{x:Null}" ColorBox="{Binding RelativeSource={RelativeSource TemplatedParent}}"> <local:GradientStopAdder.Background> - <LinearGradientBrush GradientStops="{Binding Brush.GradientStops, RelativeSource={RelativeSource TemplatedParent}}" + <LinearGradientBrush GradientStops="{Binding Brush, RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BrushToGradientStopsConverter}}" StartPoint="0,.5" EndPoint="1,.5"/> </local:GradientStopAdder.Background> <Button.Style> diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileEvent.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileEvent.cs new file mode 100644 index 000000000..a6132c6d3 --- /dev/null +++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileEvent.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; + +namespace Tango.Integration.Diagnostics +{ + [Serializable] + public class DiagnosticsFileEvent + { + public DateTime DateTime { get; set; } + + public String EventTypeGuid { get; set; } + + public String HostName { get; set; } + + public String UserGuid { get; set; } + + public String MachineGuid { get; set; } + + public String Description { get; set; } + + public DiagnosticsFileEvent() + { + + } + + public DiagnosticsFileEvent(MachinesEvent ev) : this() + { + DateTime = ev.DateTime; + EventTypeGuid = ev.EventType.Guid; + HostName = ev.HostName; + UserGuid = ev.UserGuid; + MachineGuid = ev.MachineGuid; + Description = ev.Description; + } + + public MachinesEvent ToMachineEvent() + { + MachinesEvent ev = new MachinesEvent(); + ev.DateTime = DateTime; + ev.EventType = ObservablesEntitiesAdapter.Instance.EventTypes.SingleOrDefault(x => x.Guid == EventTypeGuid); + ev.Machine = ObservablesEntitiesAdapter.Instance.Machines.SingleOrDefault(x => x.Guid == MachineGuid); + ev.User = ObservablesEntitiesAdapter.Instance.Users.SingleOrDefault(x => x.Guid == UserGuid); + ev.Description = Description; + ev.HostName = HostName; + + return ev; + } + } +} diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs index 1900e49e1..7b3cf9859 100644 --- a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs +++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Tango.BL.Entities; using Tango.Core; using Tango.Logging; using Tango.PMR.Diagnostics; @@ -113,6 +114,16 @@ namespace Tango.Integration.Diagnostics private set { _totalFrames = value; RaisePropertyChangedAuto(); } } + private List<MachinesEvent> _machineEvents; + /// <summary> + /// Gets or sets the machine events. + /// </summary> + public List<MachinesEvent> MachineEvents + { + get { return _machineEvents; } + set { _machineEvents = value; RaisePropertyChangedAuto(); } + } + #endregion #region Public Methods @@ -149,6 +160,11 @@ namespace Tango.Integration.Diagnostics TotalFrames = _timeCodeChannel.Frames.Count; TotalTime = TimeSpan.FromMilliseconds(_timeCodeChannel.Frames.Last().Milliseconds); + if (_timeCodeChannel.Events != null) + { + MachineEvents = _timeCodeChannel.Events.Select(x => x.ToMachineEvent()).ToList(); + } + IsLoaded = true; } catch (Exception ex) diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs index 5569cc227..f5c420217 100644 --- a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs +++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Media.Imaging; +using Tango.BL.Entities; using Tango.Core; using Tango.Core.Helpers; using Tango.Logging; @@ -31,6 +32,7 @@ namespace Tango.Integration.Diagnostics private FileStream _dataFileStream; //Holds the temporary recording file stream. private TaskCompletionSource<object> _stopCompletionSource; //Holds the "Stop" async method completion source. private DiagnosticsTimeCodeChannel _timeCodeChannel; //Holds the diagnostics time code channel. + private List<DiagnosticsFileEvent> _events; private Stopwatch _stopWatch; //Holds the stop watch for keeping tracks over frames time stamps. private DateTime _lastVideoPush; private List<BitmapSource> _videoFrames; @@ -139,6 +141,7 @@ namespace Tango.Integration.Diagnostics } _tempDataFileName = PathHelper.GetTempFilePath(); _frames = new ConcurrentQueue<DataFileFrame>(); + _events = new List<DiagnosticsFileEvent>(); _timeCodeChannel = new DiagnosticsTimeCodeChannel(); TotalDataBytesRecorded = 0; TotalFramesRecorded = 0; @@ -173,6 +176,15 @@ namespace Tango.Integration.Diagnostics } /// <summary> + /// Writes a machine event to the diagnostics file. + /// </summary> + /// <param name="data">The data.</param> + public void Write(MachinesEvent ev) + { + _events.Add(new DiagnosticsFileEvent(ev)); + } + + /// <summary> /// Writes a diagnostics packet to the recording. /// </summary> /// <param name="data">The data.</param> @@ -247,6 +259,7 @@ namespace Tango.Integration.Diagnostics { BinaryDataSerializer serializer = new BinaryDataSerializer(); + _timeCodeChannel.Events = _events; byte[] timeCodeData = serializer.SerializeToBytes(_timeCodeChannel); using (FileStream fs = new FileStream(fileName, FileMode.Create)) diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsTimeCodeChannel.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsTimeCodeChannel.cs index 4006844ec..242a9709f 100644 --- a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsTimeCodeChannel.cs +++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsTimeCodeChannel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.Integration.Diagnostics { @@ -18,12 +19,15 @@ namespace Tango.Integration.Diagnostics /// </summary> public List<DiagnosticsTimeCodeChannelFrame> Frames { get; set; } + public List<DiagnosticsFileEvent> Events { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="DiagnosticsTimeCodeChannel"/> class. /// </summary> public DiagnosticsTimeCodeChannel() { Frames = new List<DiagnosticsTimeCodeChannelFrame>(); + Events = new List<DiagnosticsFileEvent>(); } } } diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj index 8f4b9fc8e..0f6da30af 100644 --- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj +++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj @@ -76,6 +76,7 @@ <Compile Include="..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="Diagnostics\DiagnosticsFileEvent.cs" /> <Compile Include="Diagnostics\DiagnosticsFilePlayer.cs" /> <Compile Include="Diagnostics\DiagnosticsFileRecorder.cs" /> <Compile Include="Diagnostics\DiagnosticsTimeCodeChannel.cs" /> |
