using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using Tango.PMR.Printing; using Tango.Touch.Controls; namespace Tango.PPC.UI.Controls { public class JobOutlineControl : Control { #region Members private Size _sizeControl = new Size(0, 0); ScrollViewer _parentScrollViewer = null; public struct LevelOffset { public const double level_0 = 0.0; public const double level_1 = 10.0; public const double level_2 = 20.0; public const double level_3 = 37.0; public const double level_4 = 50.0; public const double level_5 = 60.0; public const double level_6 = 77.0; public const double level_7 = 90.0; public const double level_8 = 100.0; } private double _verticalOffset = 0; private double _viewportHeight = 0; private const double HEADER_FONT_HEIGHT = 35; private const double TITLE_FONT_HEIGHT = 22; private const double SUB_TITLE_FONT_HEIGHT = 19; private const double NORMAL_FONT_HEIGHT = 17; private const double WIDTH = 330; #endregion members public JobOutlineControl() : base() { DataContextChanged += JobOutlineControl_DataContextChanged; Width = WIDTH; } private void JobOutlineControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { if (DataContext == null) { return; } if (_parentScrollViewer != null) { _parentScrollViewer.ScrollToTop(); } InvalidateVisual(); } #region events private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { if (e.VerticalChange == 0.0) return; _verticalOffset = _parentScrollViewer.VerticalOffset; _viewportHeight = _parentScrollViewer.ViewportHeight; InvalidateVisual(); } #endregion events #region render protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (!(DataContext is JobTicket job)) return; if (_parentScrollViewer == null) { _parentScrollViewer = this.FindAncestor(); _parentScrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged; _parentScrollViewer.ScrollChanged += ScrollViewer_ScrollChanged; } else if (_viewportHeight == 0) { _viewportHeight = _parentScrollViewer.ActualHeight; } _sizeControl = new Size(); _sizeControl.Height += 10; DrawHeaderText(drawingContext, "JOB OUTLINE", 30, LevelOffset.level_0); _sizeControl.Height += HEADER_FONT_HEIGHT; _sizeControl.Height += 20; DrawHeaderText(drawingContext, "BASIC", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; var basicProps = GetNameValueList(job); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Pencil); _sizeControl.Height += NORMAL_FONT_HEIGHT; } //JobTicket.Spool if (job.Spool != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "SPOOL", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; basicProps = GetNameValueList(job.Spool); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Pencil); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } //JobTicket.ProcessParameters if (job.ProcessParameters != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "PROCESS PARAMETERS", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; basicProps = GetNameValueList(job.ProcessParameters); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Settings); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } //JobTicket.ThreadParameters if (job.ThreadParameters != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "THREAD PARAMETERS", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; basicProps = GetNameValueList(job.ThreadParameters); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Settings); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } //JobTicket.HeadCleaningParameters if (job.HeadCleaningParameters != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "HEAD CLEANING PARAMETERS", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; basicProps = GetNameValueList(job.HeadCleaningParameters); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Settings); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } //JobTicket.BtsrParameters if (job.BtsrParameters != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "BTSR PARAMETERS", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 5.0; basicProps = GetNameValueList(job.BtsrParameters); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_1, TouchIconKind.Settings); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } //JobTicket.Segments if (job.Segments != null) { _sizeControl.Height += 20; DrawHeaderText(drawingContext, "SEGMENTS", 17, LevelOffset.level_0); _sizeControl.Height += TITLE_FONT_HEIGHT; _sizeControl.Height += 10.0; int index = 0; foreach (JobSegment seg in job.Segments) { DrawHeaderText(drawingContext, string.Format("#{0} SEGMENT", ++index), 14, LevelOffset.level_1); _sizeControl.Height += SUB_TITLE_FONT_HEIGHT; basicProps = GetNameValueList(seg); foreach (var prop in basicProps) { DrawNameValueText(drawingContext, prop, LevelOffset.level_2, TouchIconKind.Pencil); _sizeControl.Height += NORMAL_FONT_HEIGHT; } //BrushStops DrawHeaderText(drawingContext, "BRUSH STOPS", 12, LevelOffset.level_3); _sizeControl.Height += NORMAL_FONT_HEIGHT; int indexBrush = 0; foreach (JobBrushStop brushstop in seg.BrushStops) { _sizeControl.Height += 5.0; DrawHeaderText(drawingContext, string.Format("#{0} STOP", ++indexBrush), 11, LevelOffset.level_4); _sizeControl.Height += NORMAL_FONT_HEIGHT; var brushStops = GetNameValueList(brushstop); foreach (var brushstopprop in brushStops) { DrawNameValueText(drawingContext, brushstopprop, LevelOffset.level_5, TouchIconKind.Pencil); _sizeControl.Height += NORMAL_FONT_HEIGHT; } DrawHeaderText(drawingContext, "DISPENSERS", 12, LevelOffset.level_6); _sizeControl.Height += NORMAL_FONT_HEIGHT; _sizeControl.Height += 5.0; int indexDispenser = 0; foreach (JobDispenser disp in brushstop.Dispensers) { DrawHeaderText(drawingContext, string.Format("#{0} DISPENSER", ++indexDispenser), 11, LevelOffset.level_6); _sizeControl.Height += NORMAL_FONT_HEIGHT; var dispProperties = GetNameValueList(disp); foreach (var dispprop in dispProperties) { DrawNameValueText(drawingContext, dispprop, LevelOffset.level_7, TouchIconKind.ArrowRightBoldCircle); _sizeControl.Height += NORMAL_FONT_HEIGHT; } } } } } if (Height != _sizeControl.Height) { Height = _sizeControl.Height; } } public IEnumerable> GetNameValueList(object value) { if (value != null) { var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => (!x.PropertyType.IsClass && !typeof(IEnumerable).IsAssignableFrom(x.PropertyType)) || x.PropertyType == typeof(String)).ToList(); return properties.Select(x => new Tuple(x.Name, x.GetValue(value).ToString())); } else { return null; } } #endregion render #region drawing protected void DrawNameValueText(DrawingContext drawingContext, Tuple text, double levelOfOffset, TouchIconKind? icon) { if (IsInViewPort()) { FormattedText formattedName = new FormattedText(text.Item1 + ": ", System.Globalization.CultureInfo.InvariantCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(this.FontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), 12, Foreground); DrawIconTextIfVisible(drawingContext, levelOfOffset, formattedName, icon); double widthOfNameText = formattedName.WidthIncludingTrailingWhitespace + 17 + levelOfOffset;//17 pix for draw icon before text FormattedText formattedValue = new FormattedText(text.Item2, System.Globalization.CultureInfo.InvariantCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(this.FontFamily, FontStyles.Normal, FontWeights.SemiBold, FontStretches.Normal), 12, Foreground); DrawIconTextIfVisible(drawingContext, widthOfNameText, formattedValue); _sizeControl.Width = Math.Max(_sizeControl.Width, (widthOfNameText + formattedValue.WidthIncludingTrailingWhitespace)); } } private bool IsInViewPort() { return (_sizeControl.Height >= _verticalOffset && _sizeControl.Height <= (_verticalOffset + _viewportHeight + 5)); } protected void DrawHeaderText(DrawingContext drawingContext, string text, int fontSize, double levelOfOffset) { if (IsInViewPort()) { FormattedText formattedtext = new FormattedText(text, System.Globalization.CultureInfo.InvariantCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(this.FontFamily, FontStyles.Normal, FontWeights.SemiBold, FontStretches.Normal), fontSize, Foreground); DrawIconTextIfVisible(drawingContext, levelOfOffset, formattedtext); _sizeControl.Width = Math.Max(_sizeControl.Width, (formattedtext.Width + levelOfOffset)); } } private void DrawIconTextIfVisible(DrawingContext drawingContext, double levelOfOffset, FormattedText formattedText, TouchIconKind? icon = null) { if (icon is TouchIconKind) { DrawIcon(drawingContext, (TouchIconKind)icon, new Point(levelOfOffset, _sizeControl.Height)); levelOfOffset += 17; } drawingContext.DrawText(formattedText, new Point(levelOfOffset, _sizeControl.Height)); } private void DrawIcon(DrawingContext drawingContext, TouchIconKind kind, Point point) { GeometryGroup group = GetGeometryByIcon(kind); SetGeometryPosition(group, point); drawingContext.DrawGeometry(Foreground, new Pen(Brushes.White, 1), group); } private GeometryGroup GetGeometryByIcon(TouchIconKind kind) { Geometry geometry = Geometry.Parse(TouchIcon.Icons[kind]); GeometryGroup group = new GeometryGroup(); group.Children.Add(geometry); TransformGroup tg = new TransformGroup(); tg.Children.Add(new ScaleTransform() { ScaleX = 10d / geometry.Bounds.Width, ScaleY = 10d / geometry.Bounds.Height, }); tg.Children.Add(new TranslateTransform() { }); group.Transform = tg; return group; } private void SetGeometryPosition(GeometryGroup group, Point point) { TransformGroup tg = group.Transform as TransformGroup; (tg.Children[1] as TranslateTransform).X = point.X; (tg.Children[1] as TranslateTransform).Y = point.Y + 1; } #endregion drawing } }