Click here to Skip to main content
15,896,201 members
Articles / Containers / Docker

SVG Artiste - An SVG Editor

Rate me:
Please Sign up or sign in to vote.
4.69/5 (23 votes)
3 Aug 2010CPOL14 min read 96.3K   15.4K   93  
A Vector based tool to create and edit SVG images
/***************************************************************************
 *   CopyRight (C) 2009 by Cristinel Mazarine                              *
 *   Author:   Cristinel Mazarine                                          *
 *   Contact:  cristinel@osec.ro                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the Crom Free License as published by           *
 *   the SC Crom-Osec SRL; version 1 of the License                        *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   Crom Free License for more details.                                   *
 *                                                                         *
 *   You should have received a copy of the Crom Free License along with   *
 *   this program; if not, write to the contact@osec.ro                    *
 ***************************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

using Crom.Controls.TabbedDocument;

namespace Crom.Controls.Docking
{
   /// <summary>
   /// Forms docker
   /// </summary>
   internal class FormsDocker : Disposable
   {
      #region Fields

      private FormWrapper              _host                            = null;

      private DockGuider               _guider                          = null;
      private DockLayout               _layout                          = null;
      private Autohide                 _autohide                        = null;

      private Timer                    _animationTimer                  = new Timer();
      private Command                  _animationCommand                = new Command();

      private List<DockableFormInfo>   _dockableForms                   = new List<DockableFormInfo>();
      private DockableFormInfo         _selectedForm                    = null;

      private FormsSelector            _switchSelector                  = null;

      private FocusFilter              _focusDetector                   = new FocusFilter();

      private Color                    _titleBarGradientColor1          = SystemColors.Control;
      private Color                    _titleBarGradientColor2          = Color.White;
      private Color                    _titleBarGradientSelectedColor1  = Color.DarkGray;
      private Color                    _titleBarGradientSelectedColor2  = Color.White;
      private Color                    _titleBarTextColor               = Color.Black;

      #endregion Fields

      #region Instance

      /// <summary>
      /// Constructor
      /// </summary>
      /// <param name="host">host window</param>
      public FormsDocker(IWin32Window host)
      {
         _host      = new FormWrapper(host, 14, 4);
         _guider    = new DockGuider (_host);
         _layout    = new DockLayout (_host);
         _autohide  = new Autohide   (_host, 9, _animationCommand);

         _layout.BeginMoveByMouse        += OnPositionerBeginMoveByMouse;
         _layout.MoveByMouse             += OnPositionerMoveByMouse;
         _layout.EndMoveByMouse          += OnPositionerEndMoveByMouse;
         _layout.DestroyFormsTabbedView  += OnDestroyFormsTabbedView;
         _layout.ShowFloatingWindows     += OnShowFloatingWindows;

         _autohide.SetHostContainerDock  += OnSetHostContainerDock;

         _guider.ApplyDock     += OnApplyDock;
         _animationTimer.Tick  += OnTimedAnimation;

         _animationTimer.Interval = 50;
         _animationTimer.Enabled  = true;

         _focusDetector.ControlGotFocus += OnControlGotFocus;
         _focusDetector.MessageFiltered += OnMessageFiltered;
         Application.AddMessageFilter(_focusDetector);
      }

      #endregion Instance

      #region Public section

      /// <summary>
      /// Occurs when show context menu is requested
      /// </summary>
      public event EventHandler<FormContextMenuEventArgs> ShowContextMenu;

      /// <summary>
      /// Occurs when a form is about to be closed
      /// </summary>
      public event EventHandler<DockableFormClosingEventArgs> FormClosing;

      /// <summary>
      /// Occurs after a form was closed
      /// </summary>
      public event EventHandler<FormEventArgs> FormClosed;


      /// <summary>
      /// Accessor of the color 1
      /// </summary>
      public Color TitleBarGradientColor1
      {
         get { return _titleBarGradientColor1; }
         set
         {
            if (_titleBarGradientColor1 != value)
            {
               _titleBarGradientColor1 = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view   = HierarchyUtility.GetTabbedView(info.DockableForm);
                  view.PagesPanel.Color1 = value;
               }
            }
         }
      }

      /// <summary>
      /// Accessor of the color 2
      /// </summary>
      public Color TitleBarGradientColor2
      {
         get { return _titleBarGradientColor2; }
         set
         {
            if (_titleBarGradientColor2 != value)
            {
               _titleBarGradientColor2 = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view   = HierarchyUtility.GetTabbedView(info.DockableForm);
                  view.PagesPanel.Color2 = value;
               }
            }
         }
      }

      /// <summary>
      /// Accessor of the color 1
      /// </summary>
      public Color TitleBarGradientSelectedColor1
      {
         get { return _titleBarGradientSelectedColor1; }
         set
         {
            if (_titleBarGradientSelectedColor1 != value)
            {
               _titleBarGradientSelectedColor1 = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
                  view.PagesPanel.SelectedColor1 = value;
               }
            }
         }
      }

      /// <summary>
      /// Accessor of the color 2
      /// </summary>
      public Color TitleBarGradientSelectedColor2
      {
         get { return _titleBarGradientSelectedColor2; }
         set
         {
            if (_titleBarGradientSelectedColor2 != value)
            {
               _titleBarGradientSelectedColor2 = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
                  view.PagesPanel.SelectedColor2 = value;
               }
            }
         }
      }

      /// <summary>
      /// Accessor of the text color
      /// </summary>
      public Color TitleBarTextColor
      {
         get { return _titleBarTextColor; }
         set
         {
            if (_titleBarTextColor != value)
            {
               _titleBarTextColor = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
                  view.PagesPanel.TextColor = value;
               }
            }
         }
      }



      /// <summary>
      /// Flag indicating if the filled forms can be moved by mouse
      /// </summary>
      public bool CanMoveByMouseFilledForms
      {
         get { return _layout.CanMoveByMouseFilledForms; }
         set 
         {
            if (_layout.CanMoveByMouseFilledForms != value)
            {
               _layout.CanMoveByMouseFilledForms = value;

               foreach (DockableFormInfo info in _dockableForms)
               {
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
                  if (view.HostContainerDock == DockStyle.Fill)
                  {
                     view.CanMoveByMouse = value;
                  }
               }
            }
         }
      }

      /// <summary>
      /// Accessor of the switch selector
      /// </summary>
      public FormsSelector SwitchSelector
      {
         get { return _switchSelector; }
         set { _switchSelector = value; }
      }

      /// <summary>
      /// Accessor of the preview renderer
      /// </summary>
      public PreviewRenderer PreviewRenderer
      {
         get { return _autohide.PreviewRenderer; }
         set { _autohide.PreviewRenderer = value; }
      }

      /// <summary>
      /// Accessor of the dockable forms count
      /// </summary>
      public int Count
      {
         get
         {
            ValidateNotDisposed();

            return _dockableForms.Count;
         }
      }

      /// <summary>
      /// Add form to guider
      /// </summary>
      /// <param name="form">form to guide</param>
      /// <param name="allowedDock">allowed dock</param>
      /// <param name="formIdentifier">identifier of the form added</param>
      /// <returns>object that encapsulates relevant information for the guided form</returns>
      public DockableFormInfo Add(Form form, zAllowedDock allowedDock, Guid formIdentifier)
      {
         if (GetFormInfo(form) != null)
         {
            throw new ArgumentException("Err");
         }

         // Should set the border as None to prevent Microsoft bug in TextBox:
         // TextBox on Form with TopLevel = False and FormBorderStyle != None doesn't process Click event
         form.FormBorderStyle = FormBorderStyle.None;

         Rectangle bounds = form.Bounds;

         DockableFormInfo info = new DockableFormInfo(form, allowedDock, formIdentifier);
         info.ExplicitDisposing  += OnInfoDisposing;
         info.SelectedChanged    += OnFormSelectedChanged;
         info.ShowAutoPanel      += OnShowFormAutoPanel;

         _dockableForms.Add(info);

         FormsTabbedView view  = CreateFormsTabbedView(bounds.Size, null);
         view.Add(info);

         _layout.CreateFloatingContainer(view, bounds);

         return info;
      }

      /// <summary>
      /// Gets the info of the form at given index
      /// </summary>
      /// <param name="index">zero based index of the form</param>
      /// <returns>info of specified form</returns>
      public DockableFormInfo GetFormInfoAt(int index)
      {
         ValidateNotDisposed();

         return _dockableForms[index];
      }

      /// <summary>
      /// Get form info
      /// </summary>
      /// <param name="form">form</param>
      /// <returns>info</returns>
      public DockableFormInfo GetFormInfo(Form form)
      {
         ValidateNotDisposed();

         for (int index = 0; index < _dockableForms.Count; index++)
         {
            if (_dockableForms[index].DockableForm == form)
            {
               return _dockableForms[index];
            }
         }

         return null;
      }

      /// <summary>
      /// Get form info based on identifier
      /// </summary>
      /// <param name="identifier">identifier</param>
      /// <returns>form info</returns>
      public DockableFormInfo GetFormInfo(Guid identifier)
      {
         ValidateNotDisposed();

         for (int index = 0; index < _dockableForms.Count; index++)
         {
            if (_dockableForms[index].Id == identifier)
            {
               return _dockableForms[index];
            }
         }

         return null;
      }

      /// <summary>
      /// Dock a form previously added to guider
      /// </summary>
      /// <param name="info">info about the form to dock</param>
      /// <param name="dock">how to dock</param>
      /// <param name="mode">were to dock</param>
      public void Dock(DockableFormInfo info, DockStyle dock, zDockMode mode)
      {
         DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);
         _layout.DockControl(container, null, dock, mode);
      }

      /// <summary>
      /// Dock a form previously added to guider over another form previously added to guider
      /// </summary>
      /// <param name="info">info about the form to dock</param>
      /// <param name="infoOver">info about form over which to dock</param>
      /// <param name="dock">how to dock</param>
      /// <param name="mode">were to dock</param>
      public void DockOver(DockableFormInfo info, DockableFormInfo infoOver, DockStyle dock, zDockMode mode)
      {
         DockableContainer containerToDock      = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);
         DockableContainer containerWhereToDock = null;

         if (infoOver != null)
         {
            containerWhereToDock = HierarchyUtility.GetClosestDockableContainer(infoOver.DockableForm);
         }

         _layout.DockControl(containerToDock, containerWhereToDock, dock, mode);
      }

      /// <summary>
      /// Undock form
      /// </summary>
      /// <param name="info">info about form to undock</param>
      /// <param name="hintBounds">hint bounds</param>
      public void Undock(DockableFormInfo info, Rectangle hintBounds)
      {
         Undock(info.DockableForm, hintBounds);
      }

      /// <summary>
      /// Remove the form
      /// </summary>
      /// <param name="info">info about form to remove</param>
      public void Remove(DockableFormInfo info)
      {
         if (info == null)
         {
            return;
         }

         FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);

         if (view != null)
         {
            if (view.Count == 1 && view.IsDocked)
            {
               _layout.Undock(view);
            }

            if (view.Count == 1)
            {
               _host.Remove(view.Parent);

               DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);
               container.SetModeEmpty();

               view.Remove(info);
            }
            else
            {
               if (view.Remove(info) == false)
               {
                  if (SelectedFormInfo == info)
                  {
                     SelectedFormInfo = null;
                  }

                  return;
               }
            }
         }

         if (SelectedFormInfo == info)
         {
            SelectedFormInfo = null;
         }

         _dockableForms.Remove(info);
         info.SelectedChanged    -= OnFormSelectedChanged;
         info.ShowAutoPanel      -= OnShowFormAutoPanel;
         info.ExplicitDisposing  -= OnInfoDisposing;

         if (info.IsAutoHideMode)
         {
            _autohide.ArrangeAutoButtonsPanels();
         }

         info.Dispose();
      }

      /// <summary>
      /// Clear
      /// </summary>
      public void Clear()
      {
         for (int index = Count - 1; index >= 0; index--)
         {
            Remove(_dockableForms[index]);
         }
      }

      /// <summary>
      /// Show switch preview
      /// </summary>
      public void ShowSwitchPreview()
      {
         if (SwitchSelector != null)
         {
            SwitchSelector.Show(PreviewRenderer, _host.ScreenClientRectangle, _dockableForms.ToArray());
         }
      }

      /// <summary>
      /// Accessor of the selected form
      /// </summary>
      public Form SelectedForm
      {
         get
         {
            ValidateNotDisposed();

            if (SelectedFormInfo != null)
            {
               return SelectedFormInfo.DockableForm;
            }

            return null;
         }
         set
         {
            ValidateNotDisposed();

            DockableFormInfo info = GetFormInfo(value);
            info.IsSelected = true;
         }
      }

      /// <summary>
      /// Set auto-hide mode
      /// </summary>
      /// <param name="info">info of the form to set</param>
      /// <param name="autoHide">flag indicating if should set auto-hide (true) or unset it</param>
      public void SetAutoHide(DockableFormInfo info, bool autoHide)
      {
         if (autoHide && info.IsAutoHideMode == false)
         {
            _autohide.SetAutoHideMode(HierarchyUtility.GetTabbedView(info.DockableForm));
         }
         else if (autoHide == false && info.IsAutoHideMode)
         {
            _autohide.UnsetAutoHideMode(HierarchyUtility.GetTabbedView(info.DockableForm));
         }
      }

      /// <summary>
      /// Set the width of a form docked: left or right or fill
      /// </summary>
      /// <param name="info">info identifing the form</param>
      /// <param name="newWidth">new width value</param>
      public void SetWidth(DockableFormInfo info, int newWidth)
      {
         int delta = newWidth - info.DockableForm.Width;
         if (delta == 0)
         {
            return;
         }

         DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);

         List<DockableContainer> hierarchy = new List<DockableContainer>();
         List<int> modifiers = new List<int>();
         hierarchy.Add(container);
         modifiers.Add(delta);

         DockableContainer containerParent = container.Parent as DockableContainer;
         while (containerParent != null)
         {
            hierarchy.Add(containerParent);
            modifiers.Add(containerParent.Width - container.Width + delta);

            container       = containerParent;
            containerParent = containerParent.Parent as DockableContainer;
         }

         for (int index = hierarchy.Count - 1; index >= 0; index--)
         {
            hierarchy[index].Width += modifiers[index];
         }
      }

      /// <summary>
      /// Set the height of a form docked: top or bottom or fill
      /// </summary>
      /// <param name="info">info identifing the form</param>
      /// <param name="newHeight">new height value</param>
      public void SetHeight(DockableFormInfo info, int newHeight)
      {
         int delta = newHeight - info.DockableForm.Height;
         if (delta == 0)
         {
            return;
         }

         DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);

         List<DockableContainer> hierarchy = new List<DockableContainer>();
         List<int> modifiers = new List<int>();
         hierarchy.Add(container);
         modifiers.Add(delta);

         DockableContainer containerParent = container.Parent as DockableContainer;
         while (containerParent != null)
         {
            hierarchy.Add(containerParent);
            modifiers.Add(containerParent.Height - container.Height + delta);

            container       = containerParent;
            containerParent = containerParent.Parent as DockableContainer;
         }

         for (int index = hierarchy.Count - 1; index >= 0; index--)
         {
            hierarchy[index].Height += modifiers[index];
         }
      }

      #endregion Public section

      #region Protected section

      /// <summary>
      /// Dispose the current instance
      /// </summary>
      /// <param name="fromIDisposableDispose">dispose was called from IDisposable.Dispose</param>
      protected override void Dispose(bool fromIDisposableDispose)
      {
         if (fromIDisposableDispose)
         {
            if (_animationTimer != null)
            {
               _animationTimer.Tick -= OnTimedAnimation;
               _animationTimer.Dispose();
               _animationTimer = null;
            }
         }
      }

      #endregion Protected section

      #region Private section
      #region Received events

      /// <summary>
      /// Occurs when focus message was filtered
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnMessageFiltered(object sender, TemplateEventArgs<Message> e)
      {
         CheckSwitcherFocus();
      }

      /// <summary>
      /// Occurs when control got focus
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnControlGotFocus(object sender, TemplateEventArgs<IntPtr> e)
      {
         Control control = Control.FromHandle(e.Data);
         while (control != null)
         {
            if (control as Form != null)
            {
               break;
            }

            if (control as FormsTabbedView != null)
            {
               control = ((FormsTabbedView)control).SelectedForm;
               break;
            }

            control = control.Parent;
         }

         Form focusedForm = control as Form;

         if (focusedForm != null)
         {
            foreach (DockableFormInfo info in _dockableForms)
            {
               if (info.DockableForm == focusedForm)
               {
                  SelectedFormInfo = info;
                  break;
               }
            }
         }

         return;
      }


      /// <summary>
      /// On show floating windows
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnShowFloatingWindows(object sender, EventArgs e)
      {
         ShowFloatingWindows();
      }

      /// <summary>
      /// On destroy forms tabbed view
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnDestroyFormsTabbedView(object sender, ControlEventArgs e)
      {
         DestroyFormsTabbedView((FormsTabbedView)e.Control);
      }

      /// <summary>
      /// On begin move a positioner using the mouse
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnPositionerBeginMoveByMouse(object sender, ControlEventArgs e)
      {
         DockableContainer container = (DockableContainer)e.Control;
         if (container.SingleChild == null)
         {
            return;
         }

         _guider.BeginWindowMovement(container, container.SingleChild.AllowedDock);
      }

      /// <summary>
      /// On moving a positioner using the mouse
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnPositionerMoveByMouse(object sender, EventArgs e)
      {
         _guider.MoveWindowByMouse();
      }

      /// <summary>
      /// On end moving a positioner using the mouse
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnPositionerEndMoveByMouse(object sender, EventArgs e)
      {
         _guider.EndWindowMovement();
      }


      /// <summary>
      /// On set logical dock
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnSetHostContainerDock(object sender, DockControlEventArgs e)
      {
         FormsTabbedView view = (FormsTabbedView)e.Control;

         _layout.SetViewDock(view, e.Dock, view.CurrentDock, view.CurrentDockMode);
      }


      /// <summary>
      /// On apply dock
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnApplyDock(object sender, DockControlEventArgs e)
      {
         Point screenPoint = Control.MousePosition;

         DockableContainer containerToDock      = (DockableContainer)e.Control;
         DockableContainer containerWhereToDock = null;

         if (e.DockMode == zDockMode.Inner)
         {
            containerWhereToDock = _guider.GetLeafDockedContainerFromPoint(screenPoint, e.Control);
         }

         _layout.DockControl(containerToDock, containerWhereToDock, e.Dock, e.DockMode);
      }



      /// <summary>
      /// Occurs when a dockable form was closed
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnFormClosed(object sender, FormEventArgs e)
      {
         Remove(GetFormInfo(e.Form));

         EventHandler<FormEventArgs> handler = FormClosed;
         if (handler != null)
         {
            handler(this, e);
         }
      }

      /// <summary>
      /// Occurs when a dockable form is closing
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnFormClosing(object sender, DockableFormClosingEventArgs e)
      {
         EventHandler<DockableFormClosingEventArgs> closingHandler = FormClosing;
         if (closingHandler != null)
         {
            closingHandler(this, e);
         }
      }

      /// <summary>
      /// Occurs when pages autohide button was clicked
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnViewAutoHideClick(object sender, EventArgs e)
      {
         FormsTabbedView view = (FormsTabbedView)sender;
         if (view.PagesPanel.AutoHidden)
         {
            _autohide.UnsetAutoHideMode(view);
         }
         else
         {
            _autohide.SetAutoHideMode(view);
         }
      }

      /// <summary>
      /// Occurs when pages context menu button was clicked
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event arguments</param>
      private void OnViewContextMenuClick(object sender, FormEventArgs e)
      {
         EventHandler<FormContextMenuEventArgs> handler = ShowContextMenu;
         if (handler != null)
         {
            Point menuLocation = Control.MousePosition;
            menuLocation       = e.Form.PointToClient(menuLocation);
            menuLocation.Y     = 0;
            FormContextMenuEventArgs args = new FormContextMenuEventArgs(menuLocation, e.Form, e.FormId);
            handler(this, args);
         }
      }

      /// <summary>
      /// Occurs when undock form from view is raised
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnUndockFormFromView(object sender, FormEventArgs e)
      {
         Point position = _host.PointToClient(Control.MousePosition);
         Undock(e.Form, new Rectangle(position.X - 150, position.Y - 4, 300, 300));
      }



      /// <summary>
      /// On autohide check
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnTimedAnimation(object sender, EventArgs e)
      {
         CheckSwitcherFocus();

         if (_animationCommand.Handler != null)
         {
            _animationCommand.Handler();
         }
         else
         {
            _animationCommand.Handler = _autohide.HideAutoPaneWhenMouseExits;
         }
      }


      /// <summary>
      /// Occurs when IsSelected property of a form is changed
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnFormSelectedChanged(object sender, EventArgs e)
      {
         DockableFormInfo info = (DockableFormInfo)sender;
         
         if (info.IsSelected)
         {
            SelectedFormInfo = info;
         }

         FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
         if (view != null)
         {
            if (view.SelectedForm != null)
            {
               DockableFormInfo topFormInfo = GetFormInfo(view.SelectedForm);

               view.PagesPanel.ShowCloseButton        = topFormInfo.ShowCloseButton;
               view.PagesPanel.ShowContextMenuButton  = topFormInfo.ShowContextMenuButton;
            }
         }         
      }

      /// <summary>
      /// Occurs when ShowAuto property of a form is changed
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnShowFormAutoPanel(object sender, EventArgs e)
      {
         if (SelectedFormInfo != null)
         {
            if (SelectedFormInfo.IsAutoHideMode)
            {
               _autohide.ShowAutoForm(SelectedFormInfo.DockableForm);
            }
         }
      }

      /// <summary>
      /// Occurs when form info is disposing
      /// </summary>
      /// <param name="sender">sender of the event</param>
      /// <param name="e">event argument</param>
      private void OnInfoDisposing(object sender, EventArgs e)
      {
         Remove((DockableFormInfo)sender);
      }

      #endregion Received events

      /// <summary>
      /// Create forms tabbed view
      /// </summary>
      /// <param name="size">initial size of decorator</param>
      /// <param name="positioner">positioner for control</param>
      /// <returns>forms tabbed view</returns>
      private FormsTabbedView CreateFormsTabbedView(Size size, ControlPositioner positioner)
      {
         FormsTabbedView view = new FormsTabbedView();

         view.ShowOneTabButton      = false;
         view.Size                  = size;
         view.PagesPanel.Positioner = positioner;
         view.PagesPanel.Size       = size;
         view.PagesPanel.BackColor  = SystemColors.Control;
         view.PagesPanel.TextColor  = TitleBarTextColor;
         view.PagesPanel.Color1     = TitleBarGradientColor1;
         view.PagesPanel.Color2     = TitleBarGradientColor2;
         view.PagesPanel.SelectedColor1 = TitleBarGradientSelectedColor1;
         view.PagesPanel.SelectedColor2 = TitleBarGradientSelectedColor2;

         view.UndockForm         += OnUndockFormFromView;
         view.ContextMenuClick   += OnViewContextMenuClick;
         view.AutohideClick      += OnViewAutoHideClick;
         view.FormClosing        += OnFormClosing;
         view.FormClosed         += OnFormClosed;

         return view;
      }

      /// <summary>
      /// Destroy forms tabbed view
      /// </summary>
      /// <param name="formTabbedView">form tabbed view</param>
      private void DestroyFormsTabbedView(FormsTabbedView formTabbedView)
      {
         formTabbedView.UndockForm        -= OnUndockFormFromView;
         formTabbedView.ContextMenuClick  -= OnViewContextMenuClick;
         formTabbedView.AutohideClick     -= OnViewAutoHideClick;
         formTabbedView.FormClosing       -= OnFormClosing;
         formTabbedView.FormClosed        -= OnFormClosed;

         formTabbedView.Dispose();
      }
      
      /// <summary>
      /// Show the floating windows
      /// </summary>
      private void ShowFloatingWindows()
      {
         List<DockableContainer> containersToBringInFront = new List<DockableContainer>();

         AddSortedFloatingContainers(containersToBringInFront);
         AddSortedFillContainers(containersToBringInFront);

         for (int index = containersToBringInFront.Count - 1; index >= 0; index--)
         {
            _host.MoveFirst(containersToBringInFront[index]);
         }
      }

      /// <summary>
      /// Add sorted fill containers to the list
      /// </summary>
      /// <param name="containers">containers</param>
      private void AddSortedFillContainers(List<DockableContainer> containers)
      {
         List<DockableContainer> containersToBringInFront = new List<DockableContainer>();

         foreach (DockableFormInfo info in _dockableForms)
         {
            FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
            if (view.HostContainerDock != DockStyle.Fill)
            {
               continue;
            }

            DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);
            while (true)
            {
               if (container.Parent as DockableContainer != null)
               {
                  container = (DockableContainer)container.Parent;
               }
               else
               {
                  break;
               }
            }

            Debug.Assert(_host.Contains(container), "Floating form views must have their parent in form");

            if (containersToBringInFront.Contains(container) == false)
            {
               containersToBringInFront.Add(container);
            }
         }

         SortContainersBasedOnTheirZOrder(containersToBringInFront);

         containers.AddRange(containersToBringInFront);
      }

      /// <summary>
      /// Add sorted floating containers to the list
      /// </summary>
      /// <param name="containers">containers</param>
      private void AddSortedFloatingContainers(List<DockableContainer> containers)
      {
         List<DockableContainer> containersToBringInFront = new List<DockableContainer>();

         foreach (DockableFormInfo info in _dockableForms)
         {
            FormsTabbedView view = HierarchyUtility.GetTabbedView(info.DockableForm);
            if (view.IsDocked)
            {
               continue;
            }

            DockableContainer container = HierarchyUtility.GetClosestDockableContainer(info.DockableForm);
            if (_host.Contains(container) == false)
            {
               continue;
            }

            if (containersToBringInFront.Contains(container) == false)
            {
               containersToBringInFront.Add(container);
            }
         }

         SortContainersBasedOnTheirZOrder(containersToBringInFront);

         containers.AddRange(containersToBringInFront);
      }

      /// <summary>
      /// Sort the containers from the list, based on their z-order
      /// </summary>
      /// <param name="containers">containers to sort</param>
      private void SortContainersBasedOnTheirZOrder(List<DockableContainer> containers)
      {
         Comparison<DockableContainer> containersSorterHandler = delegate(DockableContainer container1, DockableContainer container2)
         {
            if (container1 == container2)
            {
               return 0;
            }

            int indexView1 = _host.GetZOrderIndex(container1);
            int indexView2 = _host.GetZOrderIndex(container2);

            return Math.Sign(indexView2 - indexView1);
         };

         containers.Sort(containersSorterHandler);
      }

      /// <summary>
      /// Accessor of selected form info
      /// </summary>
      private DockableFormInfo SelectedFormInfo
      {
         get { return _selectedForm; }
         set 
         {
            if (_selectedForm != value)
            {
               if (_selectedForm != null)
               {
                  _selectedForm.IsSelected = false;
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(_selectedForm.DockableForm);
                  if (view != null)
                  {
                     view.IsFocused = false;
                  }
               }

               _selectedForm = value;

               if (_selectedForm != null)
               {
                  _selectedForm.IsSelected = true;
                  FormsTabbedView view = HierarchyUtility.GetTabbedView(_selectedForm.DockableForm);
                  if (view != null)
                  {
                     view.IsFocused     = false;
                     view.SelectedIndex = view.GetPageIndex(_selectedForm.DockableForm);
                     view.IsFocused     = true;
                  }
               }
            }
         }
      }

      /// <summary>
      /// Check switcher focus
      /// </summary>
      private void CheckSwitcherFocus()
      {
         if (SwitchSelector != null)
         {
            if (SwitchSelector.HasFocus == false)
            {
               SwitchSelector.Cancel();
            }
         }
      }

      /// <summary>
      /// Undock view
      /// </summary>
      /// <param name="view">view to undock</param>
      /// <param name="hintBounds">hint bounds</param>
      private void Undock(Form formToUndock, Rectangle hintBounds)
      {
         FormsTabbedView view = HierarchyUtility.GetTabbedView(formToUndock);
         if (view.Count == 1)
         {
            _layout.Undock(view, hintBounds);
         }
         else
         {
            DockableFormInfo info = GetFormInfo(formToUndock);

            FormsTabbedView newView = CreateFormsTabbedView(info.DockableForm.Size, null);
            newView.Add(info);

            _layout.CreateFloatingContainer(newView, hintBounds);
         }
      }

      #endregion Private section
   }
}

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
Engineer
Singapore Singapore
He is a Microsoft technology enthusiast, who wish to create applications which others find useful.He loves making small tools and getting involved in architecting bigger systems.

He is currently working as a professional developer in a software development firm in .Net technologies.

He likes reading technical blogs, contributing to opensource and most importantly, enjoying life.

His ambition is to be an impressive software maker.

Comments and Discussions