From 953fc4deb9d94a63afe07d66ccf78ff42f54c3bb Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Tue, 27 Mar 2018 19:51:29 +0300 Subject: Working on logging module! --- .../Controls/TimeRuler.cs | 227 +++++++++++++++++++ .../Converters/DateIsInListToBooleanConverter.cs | 30 +++ .../Converters/EventsToTimeRulerTicksConverter.cs | 37 ++++ .../Converters/MachineEventToXConverter.cs | 52 +++++ .../Converters/SecondsToWidthConverter.cs | 27 +++ .../Converters/TimeSpanToXConverter.cs | 32 +++ .../Helpers/TimelineHelper.cs | 16 ++ .../Navigation/LoggingNavigationManager.cs | 22 ++ .../Navigation/LoggingNavigationView.cs | 14 ++ .../Tango.MachineStudio.Logging.csproj | 25 ++- .../ViewModelLocator.cs | 4 + .../ViewModels/DateVM.cs | 22 -- .../ViewModels/MainViewVM.cs | 115 ++++++++-- .../ViewModels/TimelineEventGroup.cs | 28 +++ .../Views/EventsView.xaml | 244 +++++++++++++++++++++ .../Views/EventsView.xaml.cs | 28 +++ .../Views/MainView.xaml | 154 +------------ .../Views/MainView.xaml.cs | 3 + .../Views/TimelineView.xaml | 161 ++++++++++++++ .../Views/TimelineView.xaml.cs | 44 ++++ 20 files changed, 1106 insertions(+), 179 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs delete mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs (limited to 'Software/Visual_Studio/MachineStudio') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs new file mode 100644 index 000000000..552f8f416 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Tango.MachineStudio.Logging.Controls +{ + public class TimeRuler : Control + { + private double _smallStep; + private double _bigStep; + + #region Private Methods + + private static T FindVisualParent(DependencyObject child) where T : DependencyObject + { + // get parent item + DependencyObject parentObject = VisualTreeHelper.GetParent(child); + + // we’ve reached the end of the tree + if (parentObject == null) return null; + + // check if the parent matches the type we’re looking for + T parent = parentObject as T; + if (parent != null) + { + return parent; + } + else + { + // use recursion to proceed with next level + return FindVisualParent(parentObject); + } + } + + #endregion + + #region Properties + + public double RenderWidth + { + get { return (double)GetValue(RenderWidthProperty); } + set { SetValue(RenderWidthProperty, value); } + } + public static readonly DependencyProperty RenderWidthProperty = + DependencyProperty.Register("RenderWidth", typeof(double), typeof(TimeRuler), new FrameworkPropertyMetadata(400.0, FrameworkPropertyMetadataOptions.AffectsRender)); + + public double HorizontalOffset + { + get { return (double)GetValue(HorizontalOffsetProperty); } + set { SetValue(HorizontalOffsetProperty, value); } + } + public static readonly DependencyProperty HorizontalOffsetProperty = + DependencyProperty.Register("HorizontalOffset", typeof(double), typeof(TimeRuler), new PropertyMetadata(0.0, HorizontalOffsetChanged)); + + private static void HorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as TimeRuler; + control.Margin = new Thickness(-control.HorizontalOffset, 0, 0, 0); + control.InvalidateVisual(); + } + + + + #region Zoom + /// + /// Gets or sets the zoom factor for the ruler. The default value is 1.0. + /// + public double Zoom + { + get + { + return (double)GetValue(ZoomProperty); + } + set + { + SetValue(ZoomProperty, value); + this.InvalidateVisual(); + } + } + + private void SetSteps(double value) + { + if (value >= 50) + { + _smallStep = 0.25; + _bigStep = 1; + } + else if (value >= 40) + { + _smallStep = 0.25; + _bigStep = 2; + } + else if (value >= 30) + { + _smallStep = 0.5; + _bigStep = 2; + } + else if (value >= 20) + { + _smallStep = 1; + _bigStep = 5; + } + else if (value >= 10) + { + _smallStep = 1; + _bigStep = 10; + } + else if (value >= 5) + { + _smallStep = 2; + _bigStep = 20; + } + else if (value >= 3) + { + _smallStep = 5; + _bigStep = 30; + } + else if (value >= 1) + { + _smallStep = 30; + _bigStep = 300; + } + else if (value >= 0.5) + { + _smallStep = 60; + _bigStep = 600; + } + } + + /// + /// Identifies the Zoom dependency property. + /// + public static readonly DependencyProperty ZoomProperty = + DependencyProperty.Register("Zoom", typeof(double), typeof(TimeRuler), new FrameworkPropertyMetadata((double)1.0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(ZoomChanged))); + + private static void ZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + (d as TimeRuler).SetSteps((double)e.NewValue); + } + + + #endregion + + #endregion + + #region Constructor + + public TimeRuler() + { + _smallStep = 1; + _bigStep = 10; + FontSize = 10; + this.Loaded += TimeRuler_Loaded; + } + + private void TimeRuler_Loaded(object sender, RoutedEventArgs e) + { + this.InvalidateVisual(); + } + + #endregion + + #region Methods + + /// + /// Participates in rendering operations. + /// + /// The drawing instructions for a specific element. This context is provided to the layout system. + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + + double xDest = RenderWidth; + int start = (int)(HorizontalOffset / Zoom); + + drawingContext.DrawRectangle(Background, new Pen(BorderBrush, 0), new Rect(new Point(start * Zoom, 0.0), new Point(xDest + (start * Zoom) + 100, Height))); + drawingContext.DrawLine(new Pen(BorderBrush, 1), new Point(start * Zoom, Height - 1), new Point(xDest + (start * Zoom) + 100, Height)); + + + double l = (start % _smallStep); + while (l != 0) //I don't know why, but this is needed in order to prevent ruler from flickering on some lower scale factors :/ + { + start += 1; + l = (start % _smallStep); + } + + for (double dUnit = start; dUnit < (RenderWidth / Zoom) + (start) + 10; dUnit += _smallStep) + { + double d = dUnit * (this.Zoom); + + double startHeight; + double endHeight; + + startHeight = Height; + endHeight = ((dUnit % _bigStep == 0) ? (this.ActualHeight / 5) * 1.5 : this.ActualHeight / 5); + + drawingContext.DrawLine(new Pen(Foreground, 1), new Point(d, startHeight), new Point(d, (startHeight - endHeight))); + + double uu = (dUnit % _bigStep); + + if ((dUnit != 0.0) && (uu == 0) && (dUnit < (RenderWidth / Zoom) + start + 10)) + { + double u = dUnit; + TimeSpan t = TimeSpan.FromSeconds((u)); + + FormattedText ft = new FormattedText(t.ToString("g"), + CultureInfo.CurrentCulture, + FlowDirection.LeftToRight, + new Typeface(FontFamily.ToString()), + FontSize, + Foreground); + ft.SetFontWeight(FontWeight); + ft.TextAlignment = TextAlignment.Center; + drawingContext.DrawText(ft, new Point(d, (Height / 2) - (ft.Height / 2) - 2)); + } + } + } + + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs new file mode 100644 index 000000000..cd4f60d4c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class DateIsInListToBooleanConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length < 2 || !(values[0] is DateTime) || !(values[1] is IEnumerable)) + return false; + + var date = (DateTime)values[0]; + var dateList = (IEnumerable)values[1]; + + return dateList.ToList().Exists(x => x.ToLocalTime().ToShortDateString() == date.ToLocalTime().ToShortDateString()); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs new file mode 100644 index 000000000..35df1723b --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class EventsToTimeRulerTicksConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + ObservableCollection groups = value as ObservableCollection; + + DateTime maxTime = groups.SelectMany(x => x.Events).Max(x => x.DateTime); + DateTime minTime = groups.SelectMany(x => x.Events).Min(x => x.DateTime); + + List dates = new List(); + + for (DateTime time = minTime; time < maxTime; time = time.AddSeconds(1)) + { + dates.Add(time); + } + + return dates; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs new file mode 100644 index 000000000..193a63ffc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.BL.Entities; +using Tango.MachineStudio.Logging.Helpers; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class MachineEventToXConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 3) + { + MachinesEvent ev = values[0] as MachinesEvent; + + if (ev != null) + { + ObservableCollection groups = values[1] as ObservableCollection; + + if (groups.Count > 0) + { + double scale = (double)values[2]; + + DateTime maxTime = groups.SelectMany(x => x.Events).Max(x => x.DateTime); + DateTime minTime = groups.SelectMany(x => x.Events).Min(x => x.DateTime); + + TimeSpan range = maxTime - minTime; + TimeSpan time = maxTime - ev.DateTime; + + time = range - time; + + return TimelineHelper.ConvertTimeToPixels(time, scale); + } + } + } + + return 0.0; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs new file mode 100644 index 000000000..66e888cc0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.Helpers; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class SecondsToWidthConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + double scale = (double)value; + double seconds = System.Convert.ToDouble(parameter.ToString()); + + return TimelineHelper.ConvertTimeToPixels(TimeSpan.FromSeconds(seconds), scale); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} 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 new file mode 100644 index 000000000..4c9f5b569 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.Helpers; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class TimeSpanToXConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 2) + { + TimeSpan time = (TimeSpan)values[0]; + double scale = (double)values[1]; + + return TimelineHelper.ConvertTimeToPixels(time, scale) + 300; + } + + return null; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs new file mode 100644 index 000000000..6cfe51ba4 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Logging.Helpers +{ + public static class TimelineHelper + { + public static double ConvertTimeToPixels(TimeSpan time, double scaleFactor) + { + return ((double)(0.05f * ((double)(time.TotalSeconds) * 20))) * scaleFactor; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs new file mode 100644 index 000000000..b86df7b0f --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; +using Tango.MachineStudio.Common.Navigation; +using Tango.MachineStudio.Logging.Views; + +namespace Tango.MachineStudio.Logging.Navigation +{ + public class LoggingNavigationManager + { + private LogManager LogManager = LogManager.Default; + + public void NavigateTo(LoggingNavigationView view) + { + LogManager.Log(String.Format("Navigating to view {0}...", view.ToString())); + MainView.Instance.TransitionControl.AutoNavigate(view.ToString()); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs new file mode 100644 index 000000000..6f4fcbceb --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Logging.Navigation +{ + public enum LoggingNavigationView + { + EventsView, + TimelineView, + } +} 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 be3e1ef93..8bcdbe016 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,13 +81,28 @@ GlobalVersionInfo.cs + + + + + + + + + - + + + EventsView.xaml + MainView.xaml + + TimelineView.xaml + @@ -160,10 +175,18 @@ + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs index 76c89000d..ef6923e27 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs @@ -1,6 +1,7 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Ioc; using Microsoft.Practices.ServiceLocation; +using Tango.MachineStudio.Logging.Navigation; using Tango.MachineStudio.Logging.ViewModels; namespace Tango.MachineStudio.Logging @@ -18,6 +19,9 @@ namespace Tango.MachineStudio.Logging { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register(); + + SimpleIoc.Default.Unregister(); + SimpleIoc.Default.Register(() => new LoggingNavigationManager()); } public static MainViewVM MainViewVM diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs deleted file mode 100644 index fd03d6328..000000000 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; - -namespace Tango.MachineStudio.Logging.ViewModels -{ - public class DateVM : ExtendedObject - { - public DateTime Date { get; set; } - - public String Description { get; set; } - - public DateVM(DateTime date) - { - Date = date; - Description = date.ToLocalTime().ToShortDateString(); - } - } -} 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 2b773c1c2..81b0a587c 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 @@ -7,10 +7,12 @@ using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.Entities; +using Tango.Core.Commands; using Tango.MachineStudio.Common.EventLogging; using Tango.MachineStudio.Common.Messages; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; +using Tango.MachineStudio.Logging.Navigation; using Tango.SharedUI; namespace Tango.MachineStudio.Logging.ViewModels @@ -20,9 +22,9 @@ namespace Tango.MachineStudio.Logging.ViewModels private INotificationProvider _notification; private IStudioApplicationManager _application; private IEventLogger _eventLogger; - private DateVM _realTimeDate; private ObservableCollection _realTimeEvents; private Machine _connectedMachine; + private LoggingNavigationManager _navigation; private Machine _selectedMachine; public Machine SelectedMachine @@ -45,30 +47,88 @@ namespace Tango.MachineStudio.Logging.ViewModels set { _selectedEvent = value; RaisePropertyChangedAuto(); OnSelectedEventChanged(); } } - private ObservableCollection _dates; - public ObservableCollection Dates + private ObservableCollection _dates; + public ObservableCollection Dates { get { return _dates; } set { _dates = value; RaisePropertyChangedAuto(); } } - private DateVM _selectedDate; - public DateVM SelectedDate + private DateTime _selectedDate; + public DateTime SelectedDate { get { return _selectedDate; } set { _selectedDate = value; RaisePropertyChangedAuto(); OnSelectedDateChanged(); } } - public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application) + private DateTime _minDate; + public DateTime MinDate { + get { return _minDate; } + set { _minDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _maxDate; + public DateTime MaxDate + { + get { return _maxDate; } + set { _maxDate = value; RaisePropertyChangedAuto(); } + } + + + private bool _isRealTime; + public bool IsRealTime + { + get { return _isRealTime; } + 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 double _timelineScaleFactor; + public double TimelineScaleFactor + { + get { return _timelineScaleFactor; } + set + { + + if (value < 0.1) value = 0.1; + + _timelineScaleFactor = value; + RaisePropertyChangedAuto(); + } + } + + public RelayCommand DisplayTimelineCommand { get; set; } + + public RelayCommand NavigateToEventsCommand { get; set; } + + public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application, LoggingNavigationManager navigation) + { + _navigation = navigation; _application = application; _notification = notification; _eventLogger = eventLogger; - _realTimeDate = new DateVM(DateTime.Now) { Description = "Real Time" }; _realTimeEvents = new ObservableCollection(); _eventLogger.NewLog += _eventLogger_NewLog; + TimelineScaleFactor = 10; + RegisterMessage(OnMachineConnectionChanged); + DisplayTimelineCommand = new RelayCommand(DisplayTimeline); + NavigateToEventsCommand = new RelayCommand(() => _navigation.NavigateTo(LoggingNavigationView.EventsView)); } private void OnMachineConnectionChanged(MachineConnectionChangedMessage msg) @@ -88,7 +148,7 @@ namespace Tango.MachineStudio.Logging.ViewModels { InvokeUI(() => { - _realTimeEvents.Add(machineEvent); + _realTimeEvents.Insert(0, machineEvent); }); } @@ -96,27 +156,30 @@ namespace Tango.MachineStudio.Logging.ViewModels { if (SelectedMachine != null) { - Dates = new ObservableCollection(); + Dates = new ObservableCollection(); if (SelectedMachine == _connectedMachine) { - Dates.Add(_realTimeDate); + IsRealTime = true; } foreach (var day in SelectedMachine.MachinesEvents.GroupBy(x => x.DateTime.DayOfYear).Select(x => x.First().DateTime).OrderByDescending(x => x)) { - Dates.Add(new DateVM(day)); + Dates.Add(day); } + MinDate = Dates.Min(); + MaxDate = Dates.Max(); + SelectedDate = Dates.FirstOrDefault(); } } private void OnSelectedDateChanged() { - if (SelectedDate != null) + if (SelectedDate != null && SelectedMachine != null) { - if (SelectedDate == _realTimeDate) + if (IsRealTime) { Events = _realTimeEvents; } @@ -129,10 +192,34 @@ namespace Tango.MachineStudio.Logging.ViewModels private void OnSelectedEventChanged() { - if (SelectedEvent != null) + if (SelectedEvent != null && SelectedEvent.Type != BL.Enumerations.EventTypes.ApplicationStarted) { _notification.ShowInfo(SelectedEvent.Description); } } + + private void DisplayTimeline(MachinesEvent ev) + { + 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); + + _navigation.NavigateTo(LoggingNavigationView.TimelineView); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs new file mode 100644 index 000000000..978348fd2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs @@ -0,0 +1,28 @@ +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; + +namespace Tango.MachineStudio.Logging.ViewModels +{ + public class TimelineEventGroup : ExtendedObject + { + public String Name { get; set; } + + public ObservableCollection Events { get; set; } + + public TimelineEventGroup() + { + Events = new ObservableCollection(); + } + + public TimelineEventGroup(String name) : this() + { + Name = name; + } + } +} 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 new file mode 100644 index 000000000..a3b4ae6bf --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Real-Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs new file mode 100644 index 000000000..b17eea54c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.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 EventsView.xaml + /// + public partial class EventsView : UserControl + { + public EventsView() + { + InitializeComponent(); + } + } +} 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 3d59ee88e..6d841149e 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 @@ -8,153 +8,23 @@ xmlns:autoCompleteMachine="clr-namespace:Tango.MachineStudio.Common.AutoComplete;assembly=Tango.MachineStudio.Common" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:global="clr-namespace:Tango.MachineStudio.Logging" + xmlns:localConverters="clr-namespace:Tango.MachineStudio.Logging.Converters" 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" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MACHINE EVENTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs index 160767603..c8d232e86 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs @@ -20,9 +20,12 @@ namespace Tango.MachineStudio.Logging.Views /// public partial class MainView : UserControl { + public static MainView Instance { get; private set; } + public MainView() { InitializeComponent(); + Instance = this; } } } 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 new file mode 100644 index 000000000..e746f67b3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..53e2362dc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs @@ -0,0 +1,44 @@ +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; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Views +{ + /// + /// Interaction logic for TimelineView.xaml + /// + public partial class TimelineView : UserControl + { + private MainViewVM _vm; + + public TimelineView() + { + InitializeComponent(); + this.Loaded += (_, __) => _vm = DataContext as MainViewVM; + } + + private void UserControl_MouseWheel(object sender, MouseWheelEventArgs e) + { + if (e.Delta > 0) + { + _vm.TimelineScaleFactor += 0.5; + } + else + { + _vm.TimelineScaleFactor -= 0.5; + } + } + } +} -- cgit v1.3.1