Click here to Skip to main content
15,885,546 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.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using Fluid.Drawing.GdiPlus;
using System.Collections.Specialized;
using System.Diagnostics;

namespace Fluid.Controls
{
    /// <summary>
    /// A control that contains other fluid controls.
    /// </summary>
    public partial class ScrollPanel : ScrollContainer, IMultiControlContainer, ICommandContainer
    {
        public ScrollPanel()
            : base()
        {
            Init();
        }

        public ScrollPanel(int x, int y, int width, int height)
            : base()
        {
            Init();
            Bounds = new Rectangle(x, y, width, height);
        }

        public override void Dispose()
        {
            transparentBrush.Dispose();
            base.Dispose();
        }

        private void Init()
        {
            controls = new FluidControlCollection(this);
            BeginInit();
            Initialize();
            EndInit();
        }


        /// <summary>
        /// Used for derived classes to initialize the control.
        /// </summary>
        protected virtual void Initialize()
        { }


        /// <summary>
        /// dictionary of all cached bitmaps for each control.
        /// </summary>
        private HybridDictionary imageBuffer = new HybridDictionary();

        public override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '\t')
            {
                e.Handled = true;
                SelectNextControl();
            }
        }




        private FluidControlCollection controls;

        /// <summary>
        /// Gets the collection of all TouchControls inside this panel.
        /// </summary>
        /// <value></value>
        public FluidControlCollection Controls { get { return controls; } }

        IEnumerable<FluidControl> IMultiControlContainer.Controls
        {
            get
            {
                return controls;
            }
        }


        public override int DisplayHeight
        {
            get
            {
                return GetVirtualHeight();
            }
        }

        private int GetVirtualHeight()
        {
            int height = 0;
            foreach (FluidControl c in controls)
            {
                height = Math.Max(height, c.Bounds.Bottom);
            }
            return height;
        }




        /// <summary>
        /// Paints this control double buffered.
        /// </summary>
        /// <param name="pe">The  paint event args.</param>
        protected override void PaintContent(FluidPaintEventArgs pe)
        {
            base.PaintContent(pe);
            PaintControls(pe);
        }

        /// <summary>
        /// Paints all  controls.
        /// </summary>
        /// <param name="pe">The PaintEventArgs.</param>
        private void PaintControls(FluidPaintEventArgs pe)
        {
            Rectangle controlBounds = pe.ControlBounds;
            Graphics g = pe.Graphics;
            Region clip = pe.Region;


            foreach (FluidControl c in controls)
            {
                if (!c.Visible) continue;
                Rectangle bounds = c.Bounds;
                bounds.Offset(controlBounds.X, controlBounds.Y);
                if (clip.IsVisible(bounds))
                {
                    if (this.EnableDoubleBuffer && c.AllowDoubleBuffer)
                    {
                        PaintControlDoubleBuffered(pe, c, bounds);
                    }
                    else
                    {
                        PaintControlUnbuffered(pe, c, bounds);
                    }
                }
            }

        }

        private FluidPaintEventArgs paintEventArgs2 = new FluidPaintEventArgs();

        private void PaintControlUnbuffered(FluidPaintEventArgs pe, FluidControl control, Rectangle bounds)
        {
            //bounds.Offset(Left, Top);
            //Region clp = pe.IntersectClip(bounds);
            FluidPaintEventArgs e = paintEventArgs2;
            e.Graphics = pe.Graphics;
            e.ControlBounds = bounds;
            e.Region = pe.Region;
            e.ScaleFactor = pe.ScaleFactor;
            control.OnPaint(e);
            //pe.ResetClip(clp);
        }

        private Color transparentColor = Color.Fuchsia;

        /// <summary>
        /// Gets or sets the color that is used as transparent color when EnableDoubleBuffer is set to true.
        /// see also <seealso cref="EnabledDoubleBuffer"/>.
        /// </summary>
        public Color TransparentColor
        {
            get { return transparentColor; }
            set { transparentColor = value; }
        }

        private FluidPaintEventArgs paintEventArgs = new FluidPaintEventArgs();
        private SolidBrush transparentBrush = new SolidBrush(Color.Transparent);

        private void PaintControlDoubleBuffered(FluidPaintEventArgs pe, FluidControl control, Rectangle bounds)
        {
            Bitmap buffer;
            if (imageBuffer.Contains(control))
            {
                buffer = imageBuffer[control] as Bitmap;
            }
            else
            {
                buffer = new Bitmap(bounds.Width, bounds.Height);
                imageBuffer.Add(control, buffer);
                using (Graphics bg = Graphics.FromImage(buffer))
                {
                    this.transparentBrush.Color = transparentColor;
                    bg.FillRectangle(transparentBrush, 0, 0, buffer.Width, buffer.Height);
                    Rectangle paintRect = control.ClientRectangle;
                    //bg.Clear(transparentColor);

                    FluidPaintEventArgs e = paintEventArgs;
                    e.Graphics = bg;
                    e.ControlBounds = paintRect;
                    e.Region = bg.Clip;
                    e.ScaleFactor = pe.ScaleFactor;
                    control.OnPaint(e);
                }

            }
            ia.SetColorKey(transparentColor, transparentColor);
            pe.Graphics.DrawImage(buffer, bounds, 0, 0, bounds.Width, bounds.Height, GraphicsUnit.Pixel, ia);
        }

        ImageAttributes ia = new ImageAttributes();

        Rectangle IContainer.GetScreenBounds(Rectangle bounds)
        {
            bounds.Offset(Left, Top - ScaledTopOffset);
            return Container.GetScreenBounds(bounds);
        }

        public void Invalidate(Rectangle bounds)
        {
            if (Initializing) return;
            if (Container == null) return;
            if (!bounds.IsEmpty)
            {
                bounds.Offset(Left, Top - ScaledTopOffset);
                //// don't let the child control invalidate anything outside the own bounds:
                ClipRectangle(ref bounds);
                if (!bounds.Size.IsEmpty) Container.Invalidate(bounds);
            }
        }

        public override void Invalidate()
        {
            if (Initializing) return;
            base.Invalidate();
            InvalidateChildren();
        }



        private void InvalidateChildren()
        {
            return; // debug==
            foreach (FluidControl c in controls)
            {
                if (c.IsTransparent) c.Invalidate();
            }
        }

        private FluidControl downControl = null;


        private PointEventArgs TranslatePoint(FluidControl c, PointEventArgs p)
        {
            p.X -= c.Bounds.X;
            p.Y -= c.Bounds.Y;
            //PointEventArgs e = new PointEventArgs(p.Gesture, p.X - c.Bounds.X, p.Y - c.Bounds.Y);
            return p;
        }

        public override void OnGesture(GestureEventArgs e)
        {
            if (downControl != null) downControl.OnGesture(e);
        }

        public override void OnMove(PointEventArgs p)
        {
            base.OnMove(p);
            if (downControl != null) downControl.OnMove(this.TranslatePoint(downControl, p));
        }

        public override void OnRelease(PointEventArgs p)
        {
            base.OnRelease(p);
            if (downControl != null) downControl.OnRelease(this.TranslatePoint(downControl, p));
        }

        private FluidControl selectedControl;

        public override void OnDown(PointEventArgs p)
        {
            base.OnDown(p);
            FluidControl control = ControlFromPoint(p.X, p.Y);
            downControl = control;
            if (control != null)
            {
                PointEventArgs p2 = TranslatePoint(control, p);
                control.OnDown(p2);
            }
            if (control != null && control.Selectable)
            {
                selectedControl = control;
            }
            else if (control == null)
            {
                selectedControl = null;
            }
        }

        public override void OnUp(PointEventArgs p)
        {
            if (downControl != null) downControl.OnUp(TranslatePoint(downControl, p));
            downControl = null;
        }

        public override bool OnClick(PointEventArgs p)
        {
            base.OnClick(p);
            if (downControl != null) downControl.OnClick(TranslatePoint(downControl, p));
            return true;
        }

        private Point checkPoint = new Point();

        /// <summary>
        /// Gets the first control that is under the specified point.
        /// </summary>
        /// <param name="x">The x value of the point.</param>
        /// <param name="y">The y value of the point.</param>
        /// <returns>An ITouchControl, otherwise null.</returns>
        /// <remarks>
        /// The enumeration starts from the last to the first control, because the controls appear in this
        /// order in case they are overlapping.
        /// </remarks>
        public FluidControl ControlFromPoint(int x, int y)
        {
            Point p = checkPoint; 
            p.X = x;
            p.Y = y + TopOffset;
            for (int i = controls.Count - 1; i >= 0; i--)
            {
                FluidControl c = controls[i];
                if (!c.Visible) continue;
                Rectangle r = c.Bounds;
                if (r.Contains(p)) return c;
            }
            return null;
        }

        protected override void BeginMoving()
        {
            base.BeginMoving();
            selectedControl = null;
        }

        public override void OnKeyDown(KeyEventArgs e)
        {          
            StopAutoScroll();
            base.OnKeyDown(e);
        }

        void ControlKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\t')
            {
                e.Handled = true;
                SelectNextControl();
            }
        }

        void ControlKeyDown(object sender, KeyEventArgs e)
        {
            //switch (e.KeyCode)
            //{
            //    case Keys.Escape:
            //        e.Handled = true;
            //        SelectedControl = null;
            //        break;

            //    case Keys.Down:
            //    case Keys.Tab:
            //        e.Handled = true;
            //        SelectNextControl();
            //        break;

            //    case Keys.Up:
            //        e.Handled = true;
            //        SelectPreviousControl();
            //        break;
            //}
        }

        public virtual void SelectNextControl()
        {
            throw new ArgumentException("Not implemententad");
            //int index = SelectedControl != null ? controls.IndexOf(SelectedControl) : -1;
            //int n = controls.Count;
            //for (int i = 1; i <= n; i++)
            //{
            //    int idx = i + index;
            //    if (idx >= n) idx -= n;
            //    FluidControl c = controls[idx];
            //    if (c.Selectable)
            //    {
            //        SelectedControl = c;
            //        return;
            //    }
            //}
        }

        public virtual void SelectPreviousControl()
        {
            throw new ArgumentException("Not implemententad");
            //int index = SelectedControl != null ? controls.IndexOf(SelectedControl) : controls.Count;
            //int n = controls.Count;
            //index = n - index;
            //for (int i = n - 1; i >= 0; i--)
            //{
            //    int idx = i - index;
            //    if (idx < 0) idx += n;
            //    FluidControl c = controls[idx];
            //    if (c.Selectable)
            //    {
            //        SelectedControl = c;
            //        return;
            //    }
            //}
        }


        /// <summary>
        /// Ensure that the specified control is visible, and make it become visible if not.
        /// </summary>
        /// <param name="c">The control that needs to be visible.</param>
        /// <returns>True, if the control was already visible, otherwise false.</returns>
        public bool EnsureVisible(FluidControl c)
        {
            bool result = true;
            Rectangle bounds = c.Bounds;
            bounds.Y -= TopOffset;
            if (!Bounds.Contains(bounds))
            {
                EnsureVisible(bounds);
            }
            return result;
        }

        public IHost Host { get { return this.Container.Host; } }

        public Point PointToHost(int x, int y)
        {
            return Container.PointToHost(x + Left, y + Top);
        }

        #region IControlContainer Members


        #endregion


        protected override void OnSizeChanged(Size oldSize, Size newSize)
        {
            imageBuffer.Clear();
            base.OnSizeChanged(oldSize, newSize);
           // Layout(oldSize, newSize);
        }

        protected override void OnTopOffsetChange(int actualValue, int newValue)
        {
            LeaveDescendant();
            base.OnTopOffsetChange(actualValue, newValue);

        }

        /// <summary>
        /// Removes the focus of the selected control, if this control is a parent of the selected control.
        /// </summary>
        private void LeaveDescendant()
        {
            FluidControl selected = Container.Host.FocusedControl;
            if (selected != null)
            {
                if (selected.IsDescendantOf(this))
                {
                    Container.Host.FocusedControl = this;
                }
            }
        }


        #region ICommandContainer Members

        public virtual void RaiseCommand(CommandEventArgs e)
        {
            if (Command != null)
            {
                Command(this, e);
            }
            if (!e.Handled)
            {
                ICommandContainer container = this.Container as ICommandContainer;
                if (container != null)
                {
                    container.RaiseCommand(e);
                }
            }
        }

        public event EventHandler<CommandEventArgs> Command;

        #endregion
    }
}

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