From 17a77c30765fe8a0d3ca57a9ec60fb43b82432d2 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 8 Apr 2018 16:55:37 +0300 Subject: Implemented timeline events ! --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 1572864 -> 1572864 bytes .../Tango.MachineStudio.DataCapture.csproj | 7 + .../ViewModels/MainViewVM.cs | 53 +++++- .../Views/MainView.xaml | 86 +++++++--- .../ViewModels/MainViewVM.cs | 13 +- .../Controls/TimelineScrollViewer.cs | 51 ++++++ .../Converters/TimeSpanToXConverter.cs | 2 +- .../Tango.MachineStudio.Logging.csproj | 17 ++ .../ViewModels/EventDetailsViewVM.cs | 27 +++ .../ViewModels/MainViewVM.cs | 51 +----- .../ViewModels/TimelineViewVM.cs | 97 +++++++++++ .../Views/EventDetailsView.xaml | 93 ++++++++++ .../Views/EventDetailsView.xaml.cs | 28 +++ .../Views/EventsView.xaml | 3 +- .../Views/MainView.xaml | 2 +- .../Views/TimelineView.xaml | 190 ++++++++++++--------- .../Views/TimelineView.xaml.cs | 4 +- .../Views/TimelineWrapperView.xaml | 33 ++++ .../Views/TimelineWrapperView.xaml.cs | 28 +++ .../Diagnostics/DefaultDiagnosticsFrameProvider.cs | 41 ----- .../Diagnostics/IDiagnosticsFrameProvider.cs | 10 -- .../EventLogging/DefaultEventLogger.cs | 1 + .../ViewModels/MainViewVM.cs | 25 ++- .../Tango.MachineStudio.UI/Views/MainView.xaml | 8 +- .../Tango.BL/EntitiesExtensions/MachineEvent.cs | 1 + .../Tango.BL/Enumerations/EventTypes.cs | 12 ++ .../Visual_Studio/Tango.BL/ObservableEntity.cs | 1 + .../Converters/BrushToGradientStopsConverter.cs | 31 ++++ .../Tango.BrushPicker/Tango.BrushPicker.csproj | 2 + .../Tango.BrushPicker/Themes/Generic.xaml | 5 +- .../Diagnostics/DiagnosticsFileEvent.cs | 54 ++++++ .../Diagnostics/DiagnosticsFilePlayer.cs | 16 ++ .../Diagnostics/DiagnosticsFileRecorder.cs | 13 ++ .../Diagnostics/DiagnosticsTimeCodeChannel.cs | 4 + .../Tango.Integration/Tango.Integration.csproj | 1 + 36 files changed, 779 insertions(+), 231 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimelineScrollViewer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/EventDetailsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventDetailsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineWrapperView.xaml.cs create mode 100644 Software/Visual_Studio/Tango.BrushPicker/Converters/BrushToGradientStopsConverter.cs create mode 100644 Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileEvent.cs diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 7632ba39a..e570d5638 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 690e08a82..1589c0595 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ 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 @@ {cb0b0aa2-bb24-4bca-a720-45e397684e12} Tango.MachineStudio.Common + + {1674f726-0e66-414f-b9fd-c6f20d7f07c7} + Tango.MachineStudio.Logging + @@ -185,5 +189,8 @@ + + + \ 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; + /// + /// Gets or sets the timeline view VM. + /// + public TimelineViewVM TimelineViewVM + { + get { return _timelineViewVM; } + set { _timelineViewVM = value; RaisePropertyChangedAuto(); } + } + #endregion #region Commands @@ -161,15 +177,20 @@ namespace Tango.MachineStudio.DataCapture.ViewModels /// /// Initializes a new instance of the class. /// - 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(); @@ -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(); } /// @@ -248,7 +282,11 @@ namespace Tango.MachineStudio.DataCapture.ViewModels /// The recording. 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); + } } /// @@ -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 @@ - + @@ -179,26 +180,15 @@ - - - - Total Frames: - - - - File Size: - - - - - + + - - /// The application manager. /// The notification provider. - 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(); @@ -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 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 @@ GlobalVersionInfo.cs + @@ -92,8 +93,13 @@ + + + + EventDetailsView.xaml + EventsView.xaml @@ -103,6 +109,9 @@ TimelineView.xaml + + TimelineWrapperView.xaml + @@ -175,6 +184,10 @@ + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -187,6 +200,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + 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 _timelineEventGroups; - public ObservableCollection 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 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(); _eventLogger.NewLog += _eventLogger_NewLog; - TimelineScaleFactor = 10; - RegisterMessage(OnMachineConnectionChanged); DisplayTimelineCommand = new RelayCommand(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(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(); - - 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 _timelineEventGroups; + public ObservableCollection 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 EventSelectedCommand { get; set; } + + + public TimelineViewVM(INotificationProvider notification) + { + TimelineScaleFactor = 10; + TimelineEventGroups = new ObservableCollection(); + + EventSelectedCommand = new RelayCommand((ev) => + { + notification.ShowModalDialog(new EventDetailsViewVM(ev), (x) => { }, () => { }); + }); + } + + public void Initialize(List events) + { + TimelineEventGroups = new ObservableCollection(); + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +{ + /// + /// Interaction logic for EventDetailsView.xaml + /// + 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 @@ + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 /// 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 @@ + + + + + + + + + + + + + + + + + + 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 +{ + /// + /// Interaction logic for TimelineWrapperView.xaml + /// + 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 /// public event EventHandler FrameReceived; - private IMachineEventsStateProvider _machineEventsStateProvider; - /// - /// Gets or sets the machine events state provider used to get notifications about current machine events and errors. - /// - public IMachineEventsStateProvider MachineEventsStateProvider - { - get { return _machineEventsStateProvider; } - set - { - _machineEventsStateProvider = value; - RaisePropertyChangedAuto(); - MachineEventsStateProviderChanged?.Invoke(this, _machineEventsStateProvider); - } - } - /// /// Initializes a new instance of the class. /// @@ -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 @@ -18,16 +18,6 @@ namespace Tango.MachineStudio.Common.Diagnostics /// event EventHandler FrameReceived; - /// - /// Occurs when the machine events state provider has changed. - /// - event EventHandler MachineEventsStateProviderChanged; - - /// - /// Gets or sets the machine events state provider used to get notifications about current machine events and errors. - /// - IMachineEventsStateProvider MachineEventsStateProvider { get; } - /// /// Disables the frame delivery from the current connected machine and enables the manual push frame method. /// 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(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 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 @@ - + Press to view - + hardware messages @@ -240,7 +240,7 @@