aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs
blob: 3850ba7695ccaef28337ef89d83a4d5d18277065 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
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.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Tango.SharedUI.Controls
{
    /// <summary>
    /// Represents a control for holding a list of content controls and creates transition effects between them.
    /// </summary>
    public partial class MultiTransitionControl : UserControl
    {
        private int index;
        private bool freezeAnimation;
        private ContentControl element1 = null;
        private ContentControl element2 = null;
        private ContentControl fromElement;
        private ContentControl toElement;
        private Action navigationCompleteAction;
        private bool _loaded;

        #region Events
        /// <summary>
        /// Occurs when the transition has completed.
        /// </summary>
        public event Action<MultiTransitionControl> TransitionComplete;

        #endregion

        #region Constructors

        /// <summary>
        /// Initialize a new instance of MultiTransitionControl.
        /// </summary>
        public MultiTransitionControl()
        {
            Controls = new List<ContentControl>();

            index = 0;
            InitializeComponent();
            this.Loaded += MultiTransitionControl_Loaded;
        }

        #endregion

        #region Event Handlers

        private void MultiTransitionControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (!_loaded)
            {
                RefreshControls();

                _loaded = true;
            }
        }

        public void RefreshControls()
        {
            mainGrid.Children.Clear();

            foreach (ContentControl control in Controls)
            {
                control.Visibility = System.Windows.Visibility.Hidden;
                mainGrid.Children.Add(control);
            }

            if (Controls.Count > 0)
            {
                Controls[0].Visibility = System.Windows.Visibility.Visible;
                SelectedControl = Controls[0];
                fromElement = SelectedControl;
            }
        }

        private void ani_BackCompleted(object sender, EventArgs e)
        {
            fromElement = toElement;
            toElement = null;
            freezeAnimation = true;
            this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
            Mix = 0;
            index++;
            freezeAnimation = false;
            IsAnimating = false;

            OnTransitionCompleted();
        }

        private void ani_NextCompleted(object sender, EventArgs e)
        {
            fromElement = toElement;
            toElement = null;
            freezeAnimation = true;
            this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
            Mix = 0;
            index++;
            freezeAnimation = false;
            IsAnimating = false;

            OnTransitionCompleted();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the available content controls nested in the MultiTransitionControl.
        /// </summary>
        public List<ContentControl> Controls { get; set; }

        /// <summary>
        /// Gets or sets the transition style.
        /// </summary>
        public TransitionTypeEnum TransitionType
        {
            get { return (TransitionTypeEnum)GetValue(TransitionTypeProperty); }
            set { SetValue(TransitionTypeProperty, value); }
        }
        public static readonly DependencyProperty TransitionTypeProperty =
            DependencyProperty.Register("TransitionType", typeof(TransitionTypeEnum), typeof(MultiTransitionControl), new PropertyMetadata(TransitionTypeEnum.Fade) { PropertyChangedCallback = new PropertyChangedCallback(TransitionTypeChanged) });
        private static void TransitionTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as MultiTransitionControl).ResetTransformation();
        }

        /// <summary>
        /// This is where the actual transition occurs.
        /// </summary>
        private double Mix
        {
            get { return (double)GetValue(MixProperty); }
            set
            {
                SetValue(MixProperty, value);
                if (!freezeAnimation)
                {
                    UpdateMix(value);
                }
            }
        }
        private static readonly DependencyProperty MixProperty =
            DependencyProperty.Register("Mix", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(new PropertyChangedCallback(MixChanged)));
        private static void MixChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MultiTransitionControl tr = d as MultiTransitionControl;
            double value = (double)e.NewValue;
            tr.UpdateMix(value);
        }


        /// <summary>
        /// Gets or sets whether to always include a cross fade transition along with the selected transition style.
        /// </summary>
        public bool AlwaysFade
        {
            get { return (bool)GetValue(AlwaysFadeProperty); }
            set { SetValue(AlwaysFadeProperty, value); }
        }
        public static readonly DependencyProperty AlwaysFadeProperty =
            DependencyProperty.Register("AlwaysFade", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));


        /// <summary>
        /// Gets or sets the interval in milliseconds for the transition to complete.
        /// </summary>
        public int AnimationTime
        {
            get { return (int)GetValue(AnimationTimeProperty); }
            set { SetValue(AnimationTimeProperty, value); }
        }
        public static readonly DependencyProperty AnimationTimeProperty =
            DependencyProperty.Register("AnimationTime", typeof(int), typeof(MultiTransitionControl), new PropertyMetadata(1000));


        /// <summary>
        /// Gets or sets the transition 'ease in' time.
        /// </summary>
        public double AnimationAcceleration
        {
            get { return (double)GetValue(AnimationAccelerationProperty); }
            set { SetValue(AnimationAccelerationProperty, value); }
        }
        public static readonly DependencyProperty AnimationAccelerationProperty =
            DependencyProperty.Register("AnimationAcceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));


        /// <summary>
        /// Gets or sets the transition 'ease out' time.
        /// </summary>
        public double AnimationDeceleration
        {
            get { return (double)GetValue(AnimationDecelerationProperty); }
            set { SetValue(AnimationDecelerationProperty, value); }
        }
        public static readonly DependencyProperty AnimationDecelerationProperty =
            DependencyProperty.Register("AnimationDeceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));


        /// <summary>
        /// Gets or sets whether a transition is taking place at the moment.
        /// </summary>
        public bool IsAnimating
        {
            get { return (bool)GetValue(IsAnimatingProperty); }
            private set { SetValue(IsAnimatingProperty, value); }
        }
        public static readonly DependencyProperty IsAnimatingProperty =
            DependencyProperty.Register("IsAnimating", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));


        /// <summary>
        /// Gets or sets currently visible content control.
        /// </summary>
        public ContentControl SelectedControl
        {
            get { return (ContentControl)GetValue(SelectedControlProperty); }
            set { SetValue(SelectedControlProperty, value); }
        }
        public static readonly DependencyProperty SelectedControlProperty =
            DependencyProperty.Register("SelectedControl", typeof(ContentControl), typeof(MultiTransitionControl), new PropertyMetadata(null));

        #endregion

        #region Methods

        /// <summary>
        /// Updates the mix.
        /// </summary>
        /// <param name="value">The value.</param>
        private void UpdateMix(double value)
        {
            if (freezeAnimation) return;

            if (element1 == null || element2 == null)
            {
                return;
            }

            element1.Visibility = System.Windows.Visibility.Visible;
            element2.Visibility = System.Windows.Visibility.Visible;

            if (TransitionType == TransitionTypeEnum.Fade)
            {
                element1.RenderTransform = null;
                element2.RenderTransform = null;
                element1.Opacity = value;
                element2.Opacity = 1 - value;
                return;
            }
            else if (TransitionType == TransitionTypeEnum.Slide)
            {
                double v = value * 100;
                v = (v * this.ActualWidth) / 100;
                element2.RenderTransform = new TranslateTransform(v, 0);
                element1.RenderTransform = new TranslateTransform(v - this.ActualWidth, 0);
            }
            else if (TransitionType == TransitionTypeEnum.Zoom)
            {
                element1.RenderTransformOrigin = new Point(0.5, 0.5);
                element2.RenderTransformOrigin = new Point(0.5, 0.5);
                element1.RenderTransform = new ScaleTransform(value, value);
                element2.RenderTransform = new ScaleTransform(1 - value, 1 - value);
            }
            else if (TransitionType == TransitionTypeEnum.Spin)
            {
                double v = value * 100;
                v = (v * 360) / 100;

                var group1 = new TransformGroup();
                group1.Children.Add(new RotateTransform(v));
                group1.Children.Add(new ScaleTransform(value, value));

                var group2 = new TransformGroup();
                group2.Children.Add(new RotateTransform(360 - v));
                group2.Children.Add(new ScaleTransform(1 - value, 1 - value));

                element1.RenderTransform = group1;
                element2.RenderTransform = group2;
            }
            else if (TransitionType == TransitionTypeEnum.Carousel)
            {
                double v = value * 100;
                v = (v * this.ActualWidth) / 100;

                var group1 = new TransformGroup();
                group1.Children.Add(new ScaleTransform(value, value));
                group1.Children.Add(new TranslateTransform(v - this.ActualWidth, 0));

                var group2 = new TransformGroup();
                group2.Children.Add(new TranslateTransform(v * 2, 0));
                group2.Children.Add(new ScaleTransform(1 - value, 1 - value));

                element1.RenderTransform = group1;
                element2.RenderTransform = group2;
            }
            else if (TransitionType == TransitionTypeEnum.Skew)
            {
                double v = value * 100;
                v = (v * 180) / 100;
                element2.RenderTransform = new SkewTransform(v, 0);
                element1.RenderTransform = new SkewTransform(v - 180, 0);
            }
            else if (TransitionType == TransitionTypeEnum.Push)
            {
                element1.RenderTransformOrigin = new Point(1, 0.5);
                element2.RenderTransformOrigin = new Point(0, 0.5);
                element1.RenderTransform = new ScaleTransform(value, 1);
                element2.RenderTransform = new ScaleTransform(1 - value, 1);
            }
            if (AlwaysFade)
            {
                element1.Opacity = value;
                element2.Opacity = 1 - value;
            }
        }

        /// <summary>
        /// Resets the transformation.
        /// </summary>
        private void ResetTransformation()
        {
            foreach (ContentControl control in Controls)
            {
                control.RenderTransformOrigin = new Point(0.5, 0.5);
            }
        }

        /// <summary>
        /// Execute a transition between the current selected control and the specified content control tag.
        /// </summary>
        /// <param name="tag">Tag of content control to navigate to.</param>
        /// <param name="dataContext">DataContext to assign to the specified content control.</param>
        /// <param name="navigationComplete">Navigation completed callback delegate.</param>
        public void AutoNavigate(object tag, object dataContext = null, Action navigationComplete = null)
        {
            if (IsAnimating)
            {
                return;
            }

            ContentControl control = Controls.SingleOrDefault(x => x.Tag != null && x.Tag.ToString() == tag.ToString());

            if (control == SelectedControl)
            {
                return;
            }

            if (control == null)
            {
                throw new Exception("Control with tag '" + tag.ToString() + "' not found! (Transition Control)");
            }

            if (dataContext != null)
            {
                control.DataContext = dataContext;
            }

            if (Controls.IndexOf(control) > Controls.IndexOf(fromElement))
            {
                navigationCompleteAction = navigationComplete;
                toElement = control;
                SelectedControl = control;
                Next();
            }
            else if (Controls.IndexOf(control) < Controls.IndexOf(fromElement))
            {
                navigationCompleteAction = navigationComplete;
                toElement = control;
                SelectedControl = control;
                Back();
            }
        }

        private void Next()
        {
            if (IsAnimating)
            {
                return;
            }

            IsAnimating = true;

            if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
            {
                element1 = toElement;
                element2 = fromElement;
            }
            else
            {
                element1 = fromElement;
                element2 = toElement;
            }

            if (element2 == null)
            {
                SelectedControl = Controls[0];
                fromElement = SelectedControl;
                element2 = fromElement;
            }

            freezeAnimation = true;
            this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
            Mix = 0;
            freezeAnimation = false;

            DoubleAnimation ani = new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
            ani.AccelerationRatio = AnimationAcceleration;
            ani.DecelerationRatio = AnimationDeceleration;
            ani.Completed += ani_NextCompleted;
            this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
        }

        private void Back()
        {
            if (IsAnimating) return;

            IsAnimating = true;

            if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
            {
                element1 = toElement;
                element2 = fromElement;
            }
            else
            {
                element1 = fromElement;
                element2 = toElement;
            }

            freezeAnimation = true;
            this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
            Mix = 1;
            freezeAnimation = false;

            DoubleAnimation ani = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
            ani.Completed += ani_BackCompleted;
            ani.AccelerationRatio = AnimationAcceleration;
            ani.DecelerationRatio = AnimationDeceleration;
            this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
        }

        #endregion

        #region Virtuals

        /// <summary>
        /// Called when [transition completed].
        /// </summary>
        protected virtual void OnTransitionCompleted()
        {
            if (TransitionComplete != null) TransitionComplete(this);

            if (SelectedControl != null)
            {
                Panel.SetZIndex(SelectedControl, Controls.Max(x => Panel.GetZIndex(x)) + 1);
            }

            if (navigationCompleteAction != null)
            {
                navigationCompleteAction();
                navigationCompleteAction = null;
            }

            if (SelectedControl != null)
            {
                if (SelectedControl.Content is ITransitionView)
                {
                    (SelectedControl.Content as ITransitionView).OnTransitionCompleted();
                }
            }
        }

        public interface ITransitionView
        {
            void OnTransitionCompleted();
        }

        #endregion
    }
}