DockPanel.AutoHideWindow.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:23k
源码类别:

C#编程

开发平台:

C#

  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. namespace WeifenLuo.WinFormsUI.Docking
  6. {
  7.     partial class DockPanel
  8.     {
  9.         private class AutoHideWindowControl : Panel, ISplitterDragSource
  10.         {
  11.             private class SplitterControl : SplitterBase
  12.             {
  13.                 public SplitterControl(AutoHideWindowControl autoHideWindow)
  14.                 {
  15.                     m_autoHideWindow = autoHideWindow;
  16.                 }
  17.                 private AutoHideWindowControl m_autoHideWindow;
  18.                 private AutoHideWindowControl AutoHideWindow
  19.                 {
  20.                     get { return m_autoHideWindow; }
  21.                 }
  22.                 protected override int SplitterSize
  23.                 {
  24.                     get { return Measures.SplitterSize; }
  25.                 }
  26.                 protected override void StartDrag()
  27.                 {
  28.          AutoHideWindow.DockPanel.BeginDrag(AutoHideWindow, AutoHideWindow.RectangleToScreen(Bounds));
  29.                 }
  30.             }
  31.             #region consts
  32.             private const int ANIMATE_TIME = 100; // in mini-seconds
  33.             #endregion
  34.             private Timer m_timerMouseTrack;
  35.             private SplitterControl m_splitter;
  36.             public AutoHideWindowControl(DockPanel dockPanel)
  37.             {
  38.                 m_dockPanel = dockPanel;
  39.                 m_timerMouseTrack = new Timer();
  40.                 m_timerMouseTrack.Tick += new EventHandler(TimerMouseTrack_Tick);
  41.                 Visible = false;
  42.                 m_splitter = new SplitterControl(this);
  43.                 Controls.Add(m_splitter);
  44.             }
  45.             protected override void Dispose(bool disposing)
  46.             {
  47.                 if (disposing)
  48.                 {
  49.                     m_timerMouseTrack.Dispose();
  50.                 }
  51.                 base.Dispose(disposing);
  52.             }
  53.             private DockPanel m_dockPanel = null;
  54.             public DockPanel DockPanel
  55.             {
  56.                 get { return m_dockPanel; }
  57.             }
  58.             private DockPane m_activePane = null;
  59.             public DockPane ActivePane
  60.             {
  61.                 get { return m_activePane; }
  62.             }
  63.             private void SetActivePane()
  64.             {
  65.                 DockPane value = (ActiveContent == null ? null : ActiveContent.DockHandler.Pane);
  66.                 if (value == m_activePane)
  67.                     return;
  68.                 m_activePane = value;
  69.             }
  70.             private IDockContent m_activeContent = null;
  71.             public IDockContent ActiveContent
  72.             {
  73.                 get { return m_activeContent; }
  74.                 set
  75.                 {
  76.                     if (value == m_activeContent)
  77.                         return;
  78.                     if (value != null)
  79.                     {
  80.                         if (!DockHelper.IsDockStateAutoHide(value.DockHandler.DockState) || value.DockHandler.DockPanel != DockPanel)
  81.                             throw (new InvalidOperationException(Strings.DockPanel_ActiveAutoHideContent_InvalidValue));
  82.                     }
  83.                     DockPanel.SuspendLayout();
  84.                     if (m_activeContent != null)
  85.                     {
  86.                         if (m_activeContent.DockHandler.Form.ContainsFocus)
  87.                             DockPanel.ContentFocusManager.GiveUpFocus(m_activeContent);
  88.                         AnimateWindow(false);
  89.                     }
  90.                     m_activeContent = value;
  91.                     SetActivePane();
  92.                     if (ActivePane != null)
  93.                         ActivePane.ActiveContent = m_activeContent;
  94.                     if (m_activeContent != null)
  95.                         AnimateWindow(true);
  96.                     DockPanel.ResumeLayout();
  97.                     DockPanel.RefreshAutoHideStrip();
  98.                     SetTimerMouseTrack();
  99.                 }
  100.             }
  101.             public DockState DockState
  102.             {
  103.                 get { return ActiveContent == null ? DockState.Unknown : ActiveContent.DockHandler.DockState; }
  104.             }
  105.             private bool m_flagAnimate = true;
  106.             private bool FlagAnimate
  107.             {
  108.                 get { return m_flagAnimate; }
  109.                 set { m_flagAnimate = value; }
  110.             }
  111.             private bool m_flagDragging = false;
  112.             internal bool FlagDragging
  113.             {
  114.                 get { return m_flagDragging; }
  115.                 set
  116.                 {
  117.                     if (m_flagDragging == value)
  118.                         return;
  119.                     m_flagDragging = value;
  120.                     SetTimerMouseTrack();
  121.                 }
  122.             }
  123.             private void AnimateWindow(bool show)
  124.             {
  125.                 if (!FlagAnimate && Visible != show)
  126.                 {
  127.                     Visible = show;
  128.                     return;
  129.                 }
  130.                 Parent.SuspendLayout();
  131.                 Rectangle rectSource = GetRectangle(!show);
  132.                 Rectangle rectTarget = GetRectangle(show);
  133.                 int dxLoc, dyLoc;
  134.                 int dWidth, dHeight;
  135.                 dxLoc = dyLoc = dWidth = dHeight = 0;
  136.                 if (DockState == DockState.DockTopAutoHide)
  137.                     dHeight = show ? 1 : -1;
  138.                 else if (DockState == DockState.DockLeftAutoHide)
  139.                     dWidth = show ? 1 : -1;
  140.                 else if (DockState == DockState.DockRightAutoHide)
  141.                 {
  142.                     dxLoc = show ? -1 : 1;
  143.                     dWidth = show ? 1 : -1;
  144.                 }
  145.                 else if (DockState == DockState.DockBottomAutoHide)
  146.                 {
  147.                     dyLoc = (show ? -1 : 1);
  148.                     dHeight = (show ? 1 : -1);
  149.                 }
  150.                 if (show)
  151.                 {
  152.                     Bounds = DockPanel.GetAutoHideWindowBounds(new Rectangle(-rectTarget.Width, -rectTarget.Height, rectTarget.Width, rectTarget.Height));
  153.                     if (Visible == false)
  154.                         Visible = true;
  155.                     PerformLayout();
  156.                 }
  157.                 SuspendLayout();
  158.                 LayoutAnimateWindow(rectSource);
  159.                 if (Visible == false)
  160.                     Visible = true;
  161.                 int speedFactor = 1;
  162.                 int totalPixels = (rectSource.Width != rectTarget.Width) ?
  163.                     Math.Abs(rectSource.Width - rectTarget.Width) :
  164.                     Math.Abs(rectSource.Height - rectTarget.Height);
  165.                 int remainPixels = totalPixels;
  166.                 DateTime startingTime = DateTime.Now;
  167.                 while (rectSource != rectTarget)
  168.                 {
  169.                     DateTime startPerMove = DateTime.Now;
  170.                     rectSource.X += dxLoc * speedFactor;
  171.                     rectSource.Y += dyLoc * speedFactor;
  172.                     rectSource.Width += dWidth * speedFactor;
  173.                     rectSource.Height += dHeight * speedFactor;
  174.                     if (Math.Sign(rectTarget.X - rectSource.X) != Math.Sign(dxLoc))
  175.                         rectSource.X = rectTarget.X;
  176.                     if (Math.Sign(rectTarget.Y - rectSource.Y) != Math.Sign(dyLoc))
  177.                         rectSource.Y = rectTarget.Y;
  178.                     if (Math.Sign(rectTarget.Width - rectSource.Width) != Math.Sign(dWidth))
  179.                         rectSource.Width = rectTarget.Width;
  180.                     if (Math.Sign(rectTarget.Height - rectSource.Height) != Math.Sign(dHeight))
  181.                         rectSource.Height = rectTarget.Height;
  182.                     LayoutAnimateWindow(rectSource);
  183.                     if (Parent != null)
  184.                         Parent.Update();
  185.                     remainPixels -= speedFactor;
  186.                     while (true)
  187.                     {
  188.                         TimeSpan time = new TimeSpan(0, 0, 0, 0, ANIMATE_TIME);
  189.                         TimeSpan elapsedPerMove = DateTime.Now - startPerMove;
  190.                         TimeSpan elapsedTime = DateTime.Now - startingTime;
  191.                         if (((int)((time - elapsedTime).TotalMilliseconds)) <= 0)
  192.                         {
  193.                             speedFactor = remainPixels;
  194.                             break;
  195.                         }
  196.                         else
  197.                             speedFactor = remainPixels * (int)elapsedPerMove.TotalMilliseconds / (int)((time - elapsedTime).TotalMilliseconds);
  198.                         if (speedFactor >= 1)
  199.                             break;
  200.                     }
  201.                 }
  202.                 ResumeLayout();
  203.                 Parent.ResumeLayout();
  204.             }
  205.             private void LayoutAnimateWindow(Rectangle rect)
  206.             {
  207.                 Bounds = DockPanel.GetAutoHideWindowBounds(rect);
  208.                 Rectangle rectClient = ClientRectangle;
  209.                 if (DockState == DockState.DockLeftAutoHide)
  210.                     ActivePane.Location = new Point(rectClient.Right - 2 - Measures.SplitterSize - ActivePane.Width, ActivePane.Location.Y);
  211.                 else if (DockState == DockState.DockTopAutoHide)
  212.                     ActivePane.Location = new Point(ActivePane.Location.X, rectClient.Bottom - 2 - Measures.SplitterSize - ActivePane.Height);
  213.             }
  214.             private Rectangle GetRectangle(bool show)
  215.             {
  216.                 if (DockState == DockState.Unknown)
  217.                     return Rectangle.Empty;
  218.                 Rectangle rect = DockPanel.AutoHideWindowRectangle;
  219.                 if (show)
  220.                     return rect;
  221.                 if (DockState == DockState.DockLeftAutoHide)
  222.                     rect.Width = 0;
  223.                 else if (DockState == DockState.DockRightAutoHide)
  224.                 {
  225.                     rect.X += rect.Width;
  226.                     rect.Width = 0;
  227.                 }
  228.                 else if (DockState == DockState.DockTopAutoHide)
  229.                     rect.Height = 0;
  230.                 else
  231.                 {
  232.                     rect.Y += rect.Height;
  233.                     rect.Height = 0;
  234.                 }
  235.                 return rect;
  236.             }
  237.             private void SetTimerMouseTrack()
  238.             {
  239.                 if (ActivePane == null || ActivePane.IsActivated || FlagDragging)
  240.                 {
  241.                     m_timerMouseTrack.Enabled = false;
  242.                     return;
  243.                 }
  244.                 // start the timer
  245.                 int hovertime = SystemInformation.MouseHoverTime ;
  246.                 // assign a default value 400 in case of setting Timer.Interval invalid value exception
  247.                 if (hovertime <= 0)
  248.                     hovertime = 400;
  249.                 m_timerMouseTrack.Interval = 2 * (int)hovertime;
  250.                 m_timerMouseTrack.Enabled = true;
  251.             }
  252.             protected virtual Rectangle DisplayingRectangle
  253.             {
  254.                 get
  255.                 {
  256.                     Rectangle rect = ClientRectangle;
  257.                     // exclude the border and the splitter
  258.                     if (DockState == DockState.DockBottomAutoHide)
  259.                     {
  260.                         rect.Y += 2 + Measures.SplitterSize;
  261.                         rect.Height -= 2 + Measures.SplitterSize;
  262.                     }
  263.                     else if (DockState == DockState.DockRightAutoHide)
  264.                     {
  265.                         rect.X += 2 + Measures.SplitterSize;
  266.                         rect.Width -= 2 + Measures.SplitterSize;
  267.                     }
  268.                     else if (DockState == DockState.DockTopAutoHide)
  269.                         rect.Height -= 2 + Measures.SplitterSize;
  270.                     else if (DockState == DockState.DockLeftAutoHide)
  271.                         rect.Width -= 2 + Measures.SplitterSize;
  272.                     return rect;
  273.                 }
  274.             }
  275.             protected override void OnLayout(LayoutEventArgs levent)
  276.             {
  277.                 DockPadding.All = 0;
  278.                 if (DockState == DockState.DockLeftAutoHide)
  279.                 {
  280.                     DockPadding.Right = 2;
  281.                     m_splitter.Dock = DockStyle.Right;
  282.                 }
  283.                 else if (DockState == DockState.DockRightAutoHide)
  284.                 {
  285.                     DockPadding.Left = 2;
  286.                     m_splitter.Dock = DockStyle.Left;
  287.                 }
  288.                 else if (DockState == DockState.DockTopAutoHide)
  289.                 {
  290.                     DockPadding.Bottom = 2;
  291.                     m_splitter.Dock = DockStyle.Bottom;
  292.                 }
  293.                 else if (DockState == DockState.DockBottomAutoHide)
  294.                 {
  295.                     DockPadding.Top = 2;
  296.                     m_splitter.Dock = DockStyle.Top;
  297.                 }
  298.                 Rectangle rectDisplaying = DisplayingRectangle;
  299.                 Rectangle rectHidden = new Rectangle(-rectDisplaying.Width, rectDisplaying.Y, rectDisplaying.Width, rectDisplaying.Height);
  300.                 foreach (Control c in Controls)
  301.                 {
  302.                     DockPane pane = c as DockPane;
  303.                     if (pane == null)
  304.                         continue;
  305.                     
  306.                     
  307.                     if (pane == ActivePane)
  308.                         pane.Bounds = rectDisplaying;
  309.                     else
  310.                         pane.Bounds = rectHidden;
  311.                 }
  312.                 base.OnLayout(levent);
  313.             }
  314.             protected override void OnPaint(PaintEventArgs e)
  315.             {
  316.                 // Draw the border
  317.                 Graphics g = e.Graphics;
  318.                 if (DockState == DockState.DockBottomAutoHide)
  319.                     g.DrawLine(SystemPens.ControlLightLight, 0, 1, ClientRectangle.Right, 1);
  320.                 else if (DockState == DockState.DockRightAutoHide)
  321.                     g.DrawLine(SystemPens.ControlLightLight, 1, 0, 1, ClientRectangle.Bottom);
  322.                 else if (DockState == DockState.DockTopAutoHide)
  323.                 {
  324.                     g.DrawLine(SystemPens.ControlDark, 0, ClientRectangle.Height - 2, ClientRectangle.Right, ClientRectangle.Height - 2);
  325.                     g.DrawLine(SystemPens.ControlDarkDark, 0, ClientRectangle.Height - 1, ClientRectangle.Right, ClientRectangle.Height - 1);
  326.                 }
  327.                 else if (DockState == DockState.DockLeftAutoHide)
  328.                 {
  329.                     g.DrawLine(SystemPens.ControlDark, ClientRectangle.Width - 2, 0, ClientRectangle.Width - 2, ClientRectangle.Bottom);
  330.                     g.DrawLine(SystemPens.ControlDarkDark, ClientRectangle.Width - 1, 0, ClientRectangle.Width - 1, ClientRectangle.Bottom);
  331.                 }
  332.                 base.OnPaint(e);
  333.             }
  334.             public void RefreshActiveContent()
  335.             {
  336.                 if (ActiveContent == null)
  337.                     return;
  338.                 if (!DockHelper.IsDockStateAutoHide(ActiveContent.DockHandler.DockState))
  339.                 {
  340.                     FlagAnimate = false;
  341.                     ActiveContent = null;
  342.                     FlagAnimate = true;
  343.                 }
  344.             }
  345.             public void RefreshActivePane()
  346.             {
  347.                 SetTimerMouseTrack();
  348.             }
  349.             private void TimerMouseTrack_Tick(object sender, EventArgs e)
  350.             {
  351.                 if (IsDisposed)
  352.                     return;
  353.                 if (ActivePane == null || ActivePane.IsActivated)
  354.                 {
  355.                     m_timerMouseTrack.Enabled = false;
  356.                     return;
  357.                 }
  358.                 DockPane pane = ActivePane;
  359.                 Point ptMouseInAutoHideWindow = PointToClient(Control.MousePosition);
  360.                 Point ptMouseInDockPanel = DockPanel.PointToClient(Control.MousePosition);
  361.                 Rectangle rectTabStrip = DockPanel.GetTabStripRectangle(pane.DockState);
  362.                 if (!ClientRectangle.Contains(ptMouseInAutoHideWindow) && !rectTabStrip.Contains(ptMouseInDockPanel))
  363.                 {
  364.                     ActiveContent = null;
  365.                     m_timerMouseTrack.Enabled = false;
  366.                 }
  367.             }
  368.             #region ISplitterDragSource Members
  369.             void ISplitterDragSource.BeginDrag(Rectangle rectSplitter)
  370.             {
  371.                 FlagDragging = true;
  372.             }
  373.             void ISplitterDragSource.EndDrag()
  374.             {
  375.                 FlagDragging = false;
  376.             }
  377.             bool ISplitterDragSource.IsVertical
  378.             {
  379.                 get { return (DockState == DockState.DockLeftAutoHide || DockState == DockState.DockRightAutoHide); }
  380.             }
  381.             Rectangle ISplitterDragSource.DragLimitBounds
  382.             {
  383.                 get
  384.                 {
  385.                     Rectangle rectLimit = DockPanel.DockArea;
  386.                     if ((this as ISplitterDragSource).IsVertical)
  387.                     {
  388.                         rectLimit.X += MeasurePane.MinSize;
  389.                         rectLimit.Width -= 2 * MeasurePane.MinSize;
  390.                     }
  391.                     else
  392.                     {
  393.                         rectLimit.Y += MeasurePane.MinSize;
  394.                         rectLimit.Height -= 2 * MeasurePane.MinSize;
  395.                     }
  396.                     return DockPanel.RectangleToScreen(rectLimit);
  397.                 }
  398.             }
  399.             void ISplitterDragSource.MoveSplitter(int offset)
  400.             {
  401.                 Rectangle rectDockArea = DockPanel.DockArea;
  402.                 IDockContent content = ActiveContent;
  403.                 if (DockState == DockState.DockLeftAutoHide && rectDockArea.Width > 0)
  404.                 {
  405.                     if (content.DockHandler.AutoHidePortion < 1)
  406.                         content.DockHandler.AutoHidePortion += ((double)offset) / (double)rectDockArea.Width;
  407.                     else
  408.                         content.DockHandler.AutoHidePortion = Width + offset;
  409.                 }
  410.                 else if (DockState == DockState.DockRightAutoHide && rectDockArea.Width > 0)
  411.                 {
  412.                     if (content.DockHandler.AutoHidePortion < 1)
  413.                         content.DockHandler.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Width;
  414.                     else
  415.                         content.DockHandler.AutoHidePortion = Width - offset;
  416.                 }
  417.                 else if (DockState == DockState.DockBottomAutoHide && rectDockArea.Height > 0)
  418.                 {
  419.                     if (content.DockHandler.AutoHidePortion < 1)
  420.                         content.DockHandler.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Height;
  421.                     else
  422.                         content.DockHandler.AutoHidePortion = Height - offset;
  423.                 }
  424.                 else if (DockState == DockState.DockTopAutoHide && rectDockArea.Height > 0)
  425.                 {
  426.                     if (content.DockHandler.AutoHidePortion < 1)
  427.                         content.DockHandler.AutoHidePortion += ((double)offset) / (double)rectDockArea.Height;
  428.                     else
  429.                         content.DockHandler.AutoHidePortion = Height + offset;
  430.                 }
  431.             }
  432.             #region IDragSource Members
  433.             Control IDragSource.DragControl
  434.             {
  435.                 get { return this; }
  436.             }
  437.             #endregion
  438.             #endregion
  439.         }
  440.         private AutoHideWindowControl AutoHideWindow
  441.         {
  442.             get { return m_autoHideWindow; }
  443.         }
  444.         internal Control AutoHideControl
  445.         {
  446.             get { return m_autoHideWindow; }
  447.         }
  448.         internal void RefreshActiveAutoHideContent()
  449.         {
  450.             AutoHideWindow.RefreshActiveContent();
  451.         }
  452.         internal Rectangle AutoHideWindowRectangle
  453.         {
  454.             get
  455.             {
  456.                 DockState state = AutoHideWindow.DockState;
  457.                 Rectangle rectDockArea = DockArea;
  458.                 if (ActiveAutoHideContent == null)
  459.                     return Rectangle.Empty;
  460.                 if (Parent == null)
  461.                     return Rectangle.Empty;
  462.                 Rectangle rect = Rectangle.Empty;
  463.                 double autoHideSize = ActiveAutoHideContent.DockHandler.AutoHidePortion;
  464.                 if (state == DockState.DockLeftAutoHide)
  465.                 {
  466.                     if (autoHideSize < 1)
  467.                         autoHideSize = rectDockArea.Width * autoHideSize;
  468.                     if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
  469.                         autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
  470.                     rect.X = rectDockArea.X;
  471.                     rect.Y = rectDockArea.Y;
  472.                     rect.Width = (int)autoHideSize;
  473.                     rect.Height = rectDockArea.Height;
  474.                 }
  475.                 else if (state == DockState.DockRightAutoHide)
  476.                 {
  477.                     if (autoHideSize < 1)
  478.                         autoHideSize = rectDockArea.Width * autoHideSize;
  479.                     if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
  480.                         autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
  481.                     rect.X = rectDockArea.X + rectDockArea.Width - (int)autoHideSize;
  482.                     rect.Y = rectDockArea.Y;
  483.                     rect.Width = (int)autoHideSize;
  484.                     rect.Height = rectDockArea.Height;
  485.                 }
  486.                 else if (state == DockState.DockTopAutoHide)
  487.                 {
  488.                     if (autoHideSize < 1)
  489.                         autoHideSize = rectDockArea.Height * autoHideSize;
  490.                     if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
  491.                         autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
  492.                     rect.X = rectDockArea.X;
  493.                     rect.Y = rectDockArea.Y;
  494.                     rect.Width = rectDockArea.Width;
  495.                     rect.Height = (int)autoHideSize;
  496.                 }
  497.                 else if (state == DockState.DockBottomAutoHide)
  498.                 {
  499.                     if (autoHideSize < 1)
  500.                         autoHideSize = rectDockArea.Height * autoHideSize;
  501.                     if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
  502.                         autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
  503.                     rect.X = rectDockArea.X;
  504.                     rect.Y = rectDockArea.Y + rectDockArea.Height - (int)autoHideSize;
  505.                     rect.Width = rectDockArea.Width;
  506.                     rect.Height = (int)autoHideSize;
  507.                 }
  508.                 return rect;
  509.             }
  510.         }
  511.         internal Rectangle GetAutoHideWindowBounds(Rectangle rectAutoHideWindow)
  512.         {
  513.             if (DocumentStyle == DocumentStyle.SystemMdi ||
  514.                 DocumentStyle == DocumentStyle.DockingMdi)
  515.                 return (Parent == null) ? Rectangle.Empty : Parent.RectangleToClient(RectangleToScreen(rectAutoHideWindow));
  516.             else
  517.                 return rectAutoHideWindow;
  518.         }
  519.         internal void RefreshAutoHideStrip()
  520.         {
  521.             AutoHideStripControl.RefreshChanges();
  522.         }
  523.     }
  524. }