view Implab.Fx/AnimationHelpers.cs @ 6:dfa21d507bc5

*refactoring: Promise.Then now returns a new chained promise *fixed bug with animations when multiple events fired simultaneously
author cin
date Mon, 21 Oct 2013 02:34:31 +0400
parents f2559580b481
children 2fad2d1f4b03
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Implab.Fx
{
    public static class AnimationHelpers
    {
        public static Animation<TTarget> AnimateProperty<TTarget, TVal>(this Animation<TTarget> animation, Action<TTarget, TVal> setter, Func<TTarget, TVal> getter, TVal newValue, Func<TVal, TVal, int, int, TVal> fx) where TTarget : class
        {
            if (animation == null)
                throw new ArgumentNullException("animation");

            TVal oldValue = getter(animation.Traget);

            animation.Step += (target, elaped, duration) =>
            {
                var value = fx(oldValue, newValue, elaped, duration);
                setter(target, value);
            };

            return animation;
        }

        public static Animation<T> AnimateTransparency<T>(this T ctl, float newValue) where T : Form
        {
            var anim = new Animation<T>(ctl);

            anim.AnimateProperty(
                (target, value) => target.Opacity = value,
                target => target.Opacity,
                newValue,
                (ov, nv, el, du) => ov + ((float)el / du) * (nv - ov)
            );
            return anim;
        }

        public static Promise<T> CloseFadeOut<T>(this T ctl) where T : Form
        {
            var anim = ctl.AnimateTransparency(0);

            return anim.Play().DispatchToControl(ctl).Then(frm => frm.Close());
        }

        public static Promise<T> OverlayFadeIn<T>(this Form that, T overlay) where T : Form
        {
            if (that == null)
                throw new ArgumentNullException("that");
            if (overlay == null)
                throw new ArgumentNullException("overlay");

            // setup overlay
            overlay.Opacity = 0;
            overlay.FormBorderStyle = FormBorderStyle.None;
            overlay.ShowInTaskbar = false;

            that.AddOwnedForm(overlay);

            EventHandler handler = (object sender, EventArgs args) =>
            {
                overlay.Bounds = that.RectangleToScreen(that.ClientRectangle);
            };

            // attach handlers
            that.Move += handler;
            that.Resize += handler;
            that.Shown += handler;

            // remove handlers to release overlay
            overlay.FormClosed += (sender, args) =>
            {
                that.Move -= handler;
                that.Resize -= handler;
                that.Shown -= handler;
            };

            overlay.Show(that);
            overlay.Bounds = that.RectangleToScreen(that.ClientRectangle);

            return overlay
                .AnimateTransparency(1)
                .Play()
                .DispatchToControl(overlay);
        }
    }
}