diff MetroWpf/MetroWpf.Xaml/Transitions/TransitionPresenter.cs @ 24:a8b50a087544

Stocks and FxRates working, new menu introduced. Working nicely so far
author adminsh@apollo
date Tue, 20 Mar 2012 20:18:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MetroWpf/MetroWpf.Xaml/Transitions/TransitionPresenter.cs	Tue Mar 20 20:18:35 2012 +0000
@@ -0,0 +1,249 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Media;
+
+namespace MetroWpf.Xaml.Transitions
+{
+    [System.Windows.Markup.ContentProperty("Content")]
+    public class TransitionPresenter : FrameworkElement
+    {
+        static TransitionPresenter()
+        {
+            ClipToBoundsProperty.OverrideMetadata(typeof(TransitionPresenter), new FrameworkPropertyMetadata(null, CoerceClipToBounds));
+        }
+
+        // Force clip to be true if the active Transition requires it
+        private static object CoerceClipToBounds(object element, object value)
+        {
+            TransitionPresenter transitionElement = (TransitionPresenter)element;
+            bool clip = (bool)value;
+            if (!clip && transitionElement.IsTransitioning)
+            {
+                Transition transition = transitionElement.Transition;
+                if (transition.ClipToBounds)
+                    return true;
+            }
+            return value;
+        }
+
+        public object Content
+        {
+            get { return (object)GetValue(ContentProperty); }
+            set { SetValue(ContentProperty, value); }
+        }
+
+        public static readonly DependencyProperty ContentProperty =
+            DependencyProperty.Register("Content",
+                typeof(object),
+                typeof(TransitionPresenter),
+                new UIPropertyMetadata(null, OnContentChanged, CoerceContent));
+
+        // Don't update content until done transitioning
+        private static object CoerceContent(object element, object value)
+        {
+            TransitionPresenter te = (TransitionPresenter)element;
+            if (te.IsTransitioning)
+                return te.CurrentContentPresenter.Content;
+            return value;
+        }
+
+        private static void OnContentChanged(object element, DependencyPropertyChangedEventArgs e)
+        {
+            TransitionPresenter te = (TransitionPresenter)element;
+            te.BeginTransition();
+        }
+
+        public DataTemplate ContentTemplate
+        {
+            get { return (DataTemplate)GetValue(ContentTemplateProperty); }
+            set { SetValue(ContentTemplateProperty, value); }
+        }
+
+        public static readonly DependencyProperty ContentTemplateProperty =
+            DependencyProperty.Register("ContentTemplate",
+                typeof(DataTemplate),
+                typeof(TransitionPresenter),
+                new UIPropertyMetadata(null, OnContentTemplateChanged));
+
+        private static void OnContentTemplateChanged(object element, DependencyPropertyChangedEventArgs e)
+        {
+            TransitionPresenter te = (TransitionPresenter)element;
+            te.CurrentContentPresenter.ContentTemplate = (DataTemplate)e.NewValue;
+        }
+
+        public DataTemplateSelector ContentTemplateSelector
+        {
+            get { return (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); }
+            set { SetValue(ContentTemplateSelectorProperty, value); }
+        }
+
+        public static readonly DependencyProperty ContentTemplateSelectorProperty =
+            DependencyProperty.Register("ContentTemplateSelector",
+                typeof(DataTemplateSelector),
+                typeof(TransitionPresenter),
+                new UIPropertyMetadata(null, OnContentTemplateSelectorChanged));
+
+        private static void OnContentTemplateSelectorChanged(object element, DependencyPropertyChangedEventArgs e)
+        {
+            TransitionPresenter te = (TransitionPresenter)element;
+            te.CurrentContentPresenter.ContentTemplateSelector = (DataTemplateSelector)e.NewValue;
+        }
+
+        public bool IsTransitioning
+        {
+            get { return (bool)GetValue(IsTransitioningProperty); }
+            private set { SetValue(IsTransitioningPropertyKey, value); }
+        }
+
+        private static readonly DependencyPropertyKey IsTransitioningPropertyKey =
+            DependencyProperty.RegisterReadOnly("IsTransitioning",
+                typeof(bool),
+                typeof(TransitionPresenter),
+                new UIPropertyMetadata(false));
+
+        public static readonly DependencyProperty IsTransitioningProperty =
+            IsTransitioningPropertyKey.DependencyProperty;
+
+        public Transition Transition
+        {
+            get { return (Transition)GetValue(TransitionProperty); }
+            set { SetValue(TransitionProperty, value); }
+        }
+
+        public static readonly DependencyProperty TransitionProperty =
+            DependencyProperty.Register("Transition", typeof(Transition), typeof(TransitionPresenter), new UIPropertyMetadata(null, null, CoerceTransition));
+
+        private static object CoerceTransition(object element, object value)
+        {
+            TransitionPresenter te = (TransitionPresenter)element;
+            if (te.IsTransitioning) return te._activeTransition;
+            return value;
+        }
+
+        public TransitionSelector TransitionSelector
+        {
+            get { return (TransitionSelector)GetValue(TransitionSelectorProperty); }
+            set { SetValue(TransitionSelectorProperty, value); }
+        }
+
+        public static readonly DependencyProperty TransitionSelectorProperty =
+            DependencyProperty.Register("TransitionSelector", typeof(TransitionSelector), typeof(TransitionPresenter), new UIPropertyMetadata(null));
+
+        public TransitionPresenter()
+        {
+            _children = new UIElementCollection(this, null);
+            ContentPresenter currentContent = new ContentPresenter();
+            _currentHost = new AdornerDecorator();
+            _currentHost.Child = currentContent;
+            _children.Add(_currentHost);
+
+            ContentPresenter previousContent = new ContentPresenter();
+            _previousHost = new AdornerDecorator();
+            _previousHost.Child = previousContent;
+        }
+
+        private void BeginTransition()
+        {
+            TransitionSelector selector = TransitionSelector;
+
+            Transition transition = selector != null ?
+                selector.SelectTransition(CurrentContentPresenter.Content, Content) :
+                Transition;
+
+            if (transition != null)
+            {
+                // Swap content presenters
+                AdornerDecorator temp = _previousHost;
+                _previousHost = _currentHost;
+                _currentHost = temp;
+            }
+
+            ContentPresenter currentContent = CurrentContentPresenter;
+            // Set the current content
+            currentContent.Content = Content;
+            currentContent.ContentTemplate = ContentTemplate;
+            currentContent.ContentTemplateSelector = ContentTemplateSelector;
+
+            if (transition != null)
+            {
+                ContentPresenter previousContent = PreviousContentPresenter;
+
+                if (transition.IsNewContentTopmost)
+                    Children.Add(_currentHost);
+                else
+                    Children.Insert(0, _currentHost);
+
+                IsTransitioning = true;
+                _activeTransition = transition;
+                CoerceValue(TransitionProperty);
+                CoerceValue(ClipToBoundsProperty);
+                transition.BeginTransition(this, previousContent, currentContent);
+            }
+        }
+
+        // Clean up after the transition is complete
+        internal void OnTransitionCompleted()
+        {
+            _children.Clear();
+            _children.Add(_currentHost);
+            _currentHost.Visibility = Visibility.Visible;
+            _previousHost.Visibility = Visibility.Visible;
+            ((ContentPresenter)_previousHost.Child).Content = null;
+
+            IsTransitioning = false;
+            _activeTransition = null;
+            CoerceValue(TransitionProperty);
+            CoerceValue(ClipToBoundsProperty);
+            CoerceValue(ContentProperty);
+        }
+
+        protected override Size MeasureOverride(Size availableSize)
+        {
+            _currentHost.Measure(availableSize);
+            return _currentHost.DesiredSize;
+        }
+
+        protected override Size ArrangeOverride(Size finalSize)
+        {
+            foreach (UIElement uie in _children)
+                uie.Arrange(new Rect(finalSize));
+            return finalSize;
+        }
+
+        protected override int VisualChildrenCount
+        {
+            get { return _children.Count; }
+        }
+
+        protected override Visual GetVisualChild(int index)
+        {
+            if (index < 0 || index >= _children.Count)
+                throw new ArgumentOutOfRangeException("index");
+            return _children[index];
+        }
+
+        internal UIElementCollection Children
+        {
+            get { return _children; }
+        }
+
+        private ContentPresenter PreviousContentPresenter
+        {
+            get { return ((ContentPresenter)_previousHost.Child); }
+        }
+
+        private ContentPresenter CurrentContentPresenter
+        {
+            get { return ((ContentPresenter)_currentHost.Child); }
+        }
+
+        private UIElementCollection _children;
+
+        private AdornerDecorator _currentHost;
+        private AdornerDecorator _previousHost;
+
+        private Transition _activeTransition;
+    }
+}