Click here to Skip to main content
15,884,838 members
Articles / Mobile Apps

Windows Mobile Password Safe

Rate me:
Please Sign up or sign in to vote.
4.87/5 (58 votes)
12 Jan 2009CPOL16 min read 159.4K   3.1K   139  
A password safe with a touch screen UI introducing Fluid Controls.
using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using Fluid.Classes;

namespace Fluid.Controls
{
    /// <summary>
    /// Shows only one control sized with it's own size and supports animated navigation from one
    /// control to another.
    /// </summary>
    /// <example>
    /// This control usually contains ListBoxes and/or panels to enable an animted switching to another control.
    /// </example>
    public class TransitionPanel : ControlContainer, INotifyControlAdded
    {
        public FluidControlCollection Controls { get { return controls; } }

        /// <summary>
        /// the control that is currently transitioning.
        /// </summary>
        private FluidControl transitionControl;

        protected override void InitControl()
        {
            base.InitControl();
            BackColor = Color.Empty;
        }

        public override void Dispose()
        {
            if (dbuffer != null) dbuffer.Dispose();
            base.Dispose();
        }

        #region INotifyControlAdded Members

        public void ControlAdded(FluidControl control)
        {
            control.Visible = SelectedControl == control;
            control.Bounds = this.ClientRectangle;
        }

        #endregion

        private int selectedIndex = -1;
        public int SelectedIndex
        {
            get
            {
                return selectedIndex;
            }
            set
            {
                value = EnsureIndexRange(value);
                if (selectedIndex != value)
                {
                    OnSelectedIndexChanging(selectedIndex, value);
                    FluidControl old = SelectedControl;
                    selectedIndex = value;
                    FluidControl c = SelectedControl;
                    BeginInit();
                    if (selectedIndex >= 0) SelectedControl.Bounds = ClientRectangle;
                    if (c != null)
                    {
                        c.Bounds = ClientRectangle;
                        c.Visible = true;
                    }

                    if (old != null)
                    {
                        old.Visible = false;
                    }
                    EndInit();
                    Invalidate();

                }
            }
        }


        private ChangedEventArgs<int> indexChangeEventArgs = new ChangedEventArgs<int>();

        private void OnSelectedIndexChanging(int currentIndex, int newIndex)
        {
            if (SelectedIndexChanging != null)
            {
                indexChangeEventArgs.OldValue = currentIndex;
                indexChangeEventArgs.NewValue = newIndex;
                SelectedIndexChanging(this, indexChangeEventArgs);
            }
        }

        public event EventHandler<ChangedEventArgs<int>> SelectedIndexChanging;

        private DoubleBuffer dbuffer;

        public override void Invalidate(Rectangle bounds)
        {
            if (dbuffer != null) dbuffer.Invalidate(bounds);
            base.Invalidate(bounds);
        }


        /// <summary>
        /// Gets the selected control otherwhise null.
        /// </summary>
        public FluidControl SelectedControl
        {
            get
            {
                return selectedIndex >= 0 ? controls[selectedIndex] : null;
            }
            set
            {
                if (value != null)
                {
                    int index = controls.IndexOf(value);
                    SelectedIndex = index;
                }
                else SelectedIndex = -1;
            }
        }

        private int EnsureIndexRange(int value)
        {
            if (value >= controls.Count) return controls.Count - 1;
            if (value < -1) value = -1;
            return value;
        }

        protected override void OnSizeChanged(System.Drawing.Size oldSize, System.Drawing.Size newSize)
        {
            base.OnSizeChanged(oldSize, newSize);
            if (transitionControl != null) transitionControl.Bounds = ClientRectangle;
            if (selectedIndex >= 0) SelectedControl.Bounds = ClientRectangle;
        }

        protected override void OnPaintBackground(FluidPaintEventArgs e)
        {
            // dont use background painting
        }

        //public override void OnPaint(FluidPaintEventArgs e)
        //{
        //    if (!IsInTransiton)
        //    {
        //        FluidControl c = SelectedControl;
        //        if (c != null) c.OnPaint(e);
        //    }
        //    else base.OnPaint(e);
        //}

        private Animation animation;

        Animation EnsureAnimation()
        {
            if (animation == null)
            {
                animation = new Animation();
                animation.Scene += new EventHandler<AnimationEventArgs>(animation_Scene);
                animation.Started += new EventHandler(animation_Started);
                //animation.Mode = AnimationMode.Log;
                //animation.Acceleration = 0.05f;
                animation.Mode = AnimationMode.Accelerated;
                animation.Acceleration = -3.3f;
                animation.Completed += new EventHandler(animation_Completed);
            }
            return animation;
        }

        /// <summary>
        /// Update after the animation has completed the first scene, to ensure no delay while rendering and caching the new tab 
        /// for the very first time:
        /// </summary>
        void animation_Started(object sender, EventArgs e)
        {
            Update();
        }

        void animation_Completed(object sender, EventArgs e)
        {
            transitionControl.Bounds = ClientRectangle;
            SelectedControl = transitionControl;
            transitionControl = null;
            currentTransition = Transition.None;
            dBufferRequired = false;
            OnTransitionCompleted(sender as Animation);
        }

        private int alpha;

        #region Transitions
        private TranistionFunc transitionFunc;

        delegate void TranistionFunc(int value);

        void Fade(int value)
        {
            alpha = 2 * 255 * value / animation.EndValue;
            Rectangle r1 = ClientRectangle;
            SelectedControl.Bounds = r1;
            transitionControl.Bounds = r1;
            Invalidate();
        }

        void MoveLeft(int value)
        {
            BeginInit();
            Rectangle r1 = ClientRectangle;
            Rectangle r2 = ClientRectangle;

            r2.X = r1.Right - value;
            SelectedControl.Bounds = r1;
            transitionControl.Bounds = r2;
            transitionControl.Visible = true;
            EndInit();
            Invalidate();
        }

        void MoveRight(int value)
        {
            BeginInit();
            Rectangle r1 = ClientRectangle;
            Rectangle r2 = ClientRectangle;

            r2.X = value - r2.Width;
            SelectedControl.Bounds = r1;
            transitionControl.Bounds = r2;
            transitionControl.Visible = true;
            EndInit();
            Invalidate();
        }


        DoubleBuffer ensureDBuffer()
        {
            if (dbuffer == null) dbuffer = new DoubleBuffer();
            return dbuffer;
        }


        /// <summary>
        /// TabPanel uses this flag to switch of double buffering, since TabPanel implements it's own buffering.
        /// </summary>
        internal bool InternalEnableDoubleBuffer = true;

        public override void OnPaint(FluidPaintEventArgs e)
        {
            if (InternalEnableDoubleBuffer && dBufferRequired)
            {
                DoubleBuffer buffer = ensureDBuffer();
                buffer.Paint(e, this, base.OnPaint, alpha);
            }
            else base.OnPaint(e);
        }

        protected override void PaintControls(FluidPaintEventArgs pe)
        {
            FluidControl c = SelectedControl;
            FluidControl tc = transitionControl;

            if (tc == null && (c is PageControl))
            {
                /// build a short cut for performance issues:
                c = ((PageControl)c).Control;
            }
            if (c != null) PaintControl(pe, c);

            if (tc != null) PaintControl(pe, tc);
        }

        private void PaintControl(FluidPaintEventArgs pe, FluidControl c)
        {
            Rectangle controlBounds = pe.ControlBounds;
            Region clip = pe.Region;
            Rectangle bounds = c.Bounds;
            bounds.Offset(controlBounds.X, controlBounds.Y);
            if (clip.IsVisible(bounds))
            {
                PaintControlUnbuffered(pe, c, bounds);
            }
        }

        void ShiftLeft(int value)
        {
            BeginInit();
            Rectangle r1 = ClientRectangle;
            Rectangle r2 = ClientRectangle;

            r1.X -= value;
            r2.X = r1.Right;
            SelectedControl.Bounds = r1;
            if (transitionControl != null)
            {
                transitionControl.Bounds = r2;
                transitionControl.Visible = true;
            }
            EndInit();
            Invalidate();
        }

        void ShiftRight(int value)
        {
            BeginInit();
            Rectangle r1 = ClientRectangle;
            Rectangle r2 = ClientRectangle;

            r1.X += value;
            r2.X = r1.Left - r2.Width;
            SelectedControl.Bounds = r1;
            transitionControl.Bounds = r2;
            transitionControl.Visible = true;
            EndInit();
            Invalidate();
        }

        void None(int value) { }

        TranistionFunc GetTransitionFunc(Transition transition)
        {
            switch (transition)
            {
                case Transition.ShiftLeft: return ShiftLeft;
                case Transition.ShiftRight: return ShiftRight;
                case Transition.MoveLeft: return MoveLeft;
                case Transition.MoveRight: return MoveRight;
                case Transition.Fade: return Fade;

                default: throw new NotSupportedException(transition.ToString());
            }
        }

        public bool RequiresDBuffer(Transition transaction)
        {
            switch (currentTransition)
            {

                case Transition.ShiftRight:
                case Transition.ShiftLeft:
                case Transition.ShiftTop:
                case Transition.ShiftBottom:
                case Transition.None:
                    return false;
                default:
                    return true;
            }
        }

        bool dBufferRequired = false;

        public bool IsInTransiton { get { return transitionControl != null; } }

        private Transition currentTransition = Transition.None;


        void animation_Scene(object sender, AnimationEventArgs e)
        {
            int value = Width * e.Value / e.EndValue;
            transitionFunc(value);
            OnTransitionChange(e);
        }

        protected virtual void OnTransitionChange(AnimationEventArgs e)
        {
            if (TransitionChange != null) TransitionChange(this, e);
        }

        protected virtual void OnTransitionCompleted(Animation a)
        {
            if (TransitionCompleted != null)
            {
                TransitionCompleted(this, a.eventArgs);
            }
        }

        public event EventHandler<AnimationEventArgs> TransitionChange;
        public event EventHandler<AnimationEventArgs> TransitionCompleted;

        public void Switch(int index, Transition transition, int duration)
        {
            alpha = 255;
            if (index != selectedIndex)
            {
                StopTransition();
                currentTransition = transition;
                dBufferRequired = RequiresDBuffer(transition);
                transitionFunc = GetTransitionFunc(transition);
                transitionControl = Controls[index];
                Animation animation = EnsureAnimation();
                animation.BeginValue = 0;
                animation.EndValue = Width;
                animation.Duration = duration;
                OnBeginTransition(index);
                animation.Start();
            }
        }

        private ChangedEventArgs<int> beginTransitionEventArgs = new ChangedEventArgs<int>();

        private void OnBeginTransition(int index)
        {
            if (BeginTransition != null)
            {
                beginTransitionEventArgs.NewValue = index;
                BeginTransition(this, beginTransitionEventArgs);
            }

        }

        public event EventHandler<ChangedEventArgs<int>> BeginTransition;

        private void StopTransition()
        {
            Animation animation = EnsureAnimation();
            animation.Stop();
            currentTransition = Transition.None;
            dBufferRequired = false;
        }

        #endregion

        public override bool IsDoubleBuffered
        {
            get { return IsInTransiton ? false : SelectedControl != null ? SelectedControl.IsDoubleBuffered : false; }
        }


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Germany Germany
MCPD
Enterprise Application Developer 3.5
Windows Developer 3.5
.ASP.NET Developer 3.5
.NET 2.0 Windows Developer
.NET 2.0 Web Developer
.NET 2.0 Enterprise Application Developer


MCTS
.NET 3.5 Windows Forms Applications
.NET 3.5 ASP.NET Applications
.NET 3.5, ADO.NET Application Development
.NET 3.5 WCF
.NET 3.5 WPF
.NET 3.5 WF
Microsoft SQL Server 2008, Database Development
.NET 2.0 Windows Applications
.NET 2.0 Web Applications
.NET 2.0 Distributed Applications
SQL Server 2005
Sharepoint Services 3.0 Application Development
Windows Vista Client Configuration

Comments and Discussions