You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
531 lines
15 KiB
C#
531 lines
15 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Windows.Forms;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace Mesnac.Docking
|
|
{
|
|
public abstract partial class AutoHideStripBase : Control
|
|
{
|
|
[SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
|
|
protected class Tab : IDisposable
|
|
{
|
|
private IDockContent m_content;
|
|
|
|
protected internal Tab(IDockContent content)
|
|
{
|
|
m_content = content;
|
|
}
|
|
|
|
~Tab()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public IDockContent Content
|
|
{
|
|
get { return m_content; }
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
}
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
|
|
protected sealed class TabCollection : IEnumerable<Tab>
|
|
{
|
|
#region IEnumerable Members
|
|
IEnumerator<Tab> IEnumerable<Tab>.GetEnumerator()
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
yield return this[i];
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
yield return this[i];
|
|
}
|
|
#endregion
|
|
|
|
internal TabCollection(DockPane pane)
|
|
{
|
|
m_dockPane = pane;
|
|
}
|
|
|
|
private DockPane m_dockPane = null;
|
|
public DockPane DockPane
|
|
{
|
|
get { return m_dockPane; }
|
|
}
|
|
|
|
public DockPanel DockPanel
|
|
{
|
|
get { return DockPane.DockPanel; }
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return DockPane.DisplayingContents.Count; }
|
|
}
|
|
|
|
public Tab this[int index]
|
|
{
|
|
get
|
|
{
|
|
IDockContent content = DockPane.DisplayingContents[index];
|
|
if (content == null)
|
|
throw (new ArgumentOutOfRangeException("index"));
|
|
if (content.DockHandler.AutoHideTab == null)
|
|
content.DockHandler.AutoHideTab = (DockPanel.AutoHideStripControl.CreateTab(content));
|
|
return content.DockHandler.AutoHideTab as Tab;
|
|
}
|
|
}
|
|
|
|
public bool Contains(Tab tab)
|
|
{
|
|
return (IndexOf(tab) != -1);
|
|
}
|
|
|
|
public bool Contains(IDockContent content)
|
|
{
|
|
return (IndexOf(content) != -1);
|
|
}
|
|
|
|
public int IndexOf(Tab tab)
|
|
{
|
|
if (tab == null)
|
|
return -1;
|
|
|
|
return IndexOf(tab.Content);
|
|
}
|
|
|
|
public int IndexOf(IDockContent content)
|
|
{
|
|
return DockPane.DisplayingContents.IndexOf(content);
|
|
}
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
|
|
protected class Pane : IDisposable
|
|
{
|
|
private DockPane m_dockPane;
|
|
|
|
protected internal Pane(DockPane dockPane)
|
|
{
|
|
m_dockPane = dockPane;
|
|
}
|
|
|
|
~Pane()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public DockPane DockPane
|
|
{
|
|
get { return m_dockPane; }
|
|
}
|
|
|
|
public TabCollection AutoHideTabs
|
|
{
|
|
get
|
|
{
|
|
if (DockPane.AutoHideTabs == null)
|
|
DockPane.AutoHideTabs = new TabCollection(DockPane);
|
|
return DockPane.AutoHideTabs as TabCollection;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
}
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
|
|
protected sealed class PaneCollection : IEnumerable<Pane>
|
|
{
|
|
private class AutoHideState
|
|
{
|
|
public DockState m_dockState;
|
|
public bool m_selected = false;
|
|
|
|
public AutoHideState(DockState dockState)
|
|
{
|
|
m_dockState = dockState;
|
|
}
|
|
|
|
public DockState DockState
|
|
{
|
|
get { return m_dockState; }
|
|
}
|
|
|
|
public bool Selected
|
|
{
|
|
get { return m_selected; }
|
|
set { m_selected = value; }
|
|
}
|
|
}
|
|
|
|
private class AutoHideStateCollection
|
|
{
|
|
private AutoHideState[] m_states;
|
|
|
|
public AutoHideStateCollection()
|
|
{
|
|
m_states = new AutoHideState[] {
|
|
new AutoHideState(DockState.DockTopAutoHide),
|
|
new AutoHideState(DockState.DockBottomAutoHide),
|
|
new AutoHideState(DockState.DockLeftAutoHide),
|
|
new AutoHideState(DockState.DockRightAutoHide)
|
|
};
|
|
}
|
|
|
|
public AutoHideState this[DockState dockState]
|
|
{
|
|
get
|
|
{
|
|
for (int i = 0; i < m_states.Length; i++)
|
|
{
|
|
if (m_states[i].DockState == dockState)
|
|
return m_states[i];
|
|
}
|
|
throw new ArgumentOutOfRangeException("dockState");
|
|
}
|
|
}
|
|
|
|
public bool ContainsPane(DockPane pane)
|
|
{
|
|
if (pane.IsHidden)
|
|
return false;
|
|
|
|
for (int i = 0; i < m_states.Length; i++)
|
|
{
|
|
if (m_states[i].DockState == pane.DockState && m_states[i].Selected)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal PaneCollection(DockPanel panel, DockState dockState)
|
|
{
|
|
m_dockPanel = panel;
|
|
m_states = new AutoHideStateCollection();
|
|
States[DockState.DockTopAutoHide].Selected = (dockState == DockState.DockTopAutoHide);
|
|
States[DockState.DockBottomAutoHide].Selected = (dockState == DockState.DockBottomAutoHide);
|
|
States[DockState.DockLeftAutoHide].Selected = (dockState == DockState.DockLeftAutoHide);
|
|
States[DockState.DockRightAutoHide].Selected = (dockState == DockState.DockRightAutoHide);
|
|
}
|
|
|
|
private DockPanel m_dockPanel;
|
|
public DockPanel DockPanel
|
|
{
|
|
get { return m_dockPanel; }
|
|
}
|
|
|
|
private AutoHideStateCollection m_states;
|
|
private AutoHideStateCollection States
|
|
{
|
|
get { return m_states; }
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
int count = 0;
|
|
foreach (DockPane pane in DockPanel.Panes)
|
|
{
|
|
if (States.ContainsPane(pane))
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
}
|
|
|
|
public Pane this[int index]
|
|
{
|
|
get
|
|
{
|
|
int count = 0;
|
|
foreach (DockPane pane in DockPanel.Panes)
|
|
{
|
|
if (!States.ContainsPane(pane))
|
|
continue;
|
|
|
|
if (count == index)
|
|
{
|
|
if (pane.AutoHidePane == null)
|
|
pane.AutoHidePane = DockPanel.AutoHideStripControl.CreatePane(pane);
|
|
return pane.AutoHidePane as Pane;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
throw new ArgumentOutOfRangeException("index");
|
|
}
|
|
}
|
|
|
|
public bool Contains(Pane pane)
|
|
{
|
|
return (IndexOf(pane) != -1);
|
|
}
|
|
|
|
public int IndexOf(Pane pane)
|
|
{
|
|
if (pane == null)
|
|
return -1;
|
|
|
|
int index = 0;
|
|
foreach (DockPane dockPane in DockPanel.Panes)
|
|
{
|
|
if (!States.ContainsPane(pane.DockPane))
|
|
continue;
|
|
|
|
if (pane == dockPane.AutoHidePane)
|
|
return index;
|
|
|
|
index++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#region IEnumerable Members
|
|
|
|
IEnumerator<Pane> IEnumerable<Pane>.GetEnumerator()
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
yield return this[i];
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
yield return this[i];
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
protected AutoHideStripBase(DockPanel panel)
|
|
{
|
|
m_dockPanel = panel;
|
|
m_panesTop = new PaneCollection(panel, DockState.DockTopAutoHide);
|
|
m_panesBottom = new PaneCollection(panel, DockState.DockBottomAutoHide);
|
|
m_panesLeft = new PaneCollection(panel, DockState.DockLeftAutoHide);
|
|
m_panesRight = new PaneCollection(panel, DockState.DockRightAutoHide);
|
|
|
|
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
SetStyle(ControlStyles.Selectable, false);
|
|
}
|
|
|
|
private DockPanel m_dockPanel;
|
|
protected DockPanel DockPanel
|
|
{
|
|
get { return m_dockPanel; }
|
|
}
|
|
|
|
private PaneCollection m_panesTop;
|
|
protected PaneCollection PanesTop
|
|
{
|
|
get { return m_panesTop; }
|
|
}
|
|
|
|
private PaneCollection m_panesBottom;
|
|
protected PaneCollection PanesBottom
|
|
{
|
|
get { return m_panesBottom; }
|
|
}
|
|
|
|
private PaneCollection m_panesLeft;
|
|
protected PaneCollection PanesLeft
|
|
{
|
|
get { return m_panesLeft; }
|
|
}
|
|
|
|
private PaneCollection m_panesRight;
|
|
protected PaneCollection PanesRight
|
|
{
|
|
get { return m_panesRight; }
|
|
}
|
|
|
|
protected PaneCollection GetPanes(DockState dockState)
|
|
{
|
|
if (dockState == DockState.DockTopAutoHide)
|
|
return PanesTop;
|
|
else if (dockState == DockState.DockBottomAutoHide)
|
|
return PanesBottom;
|
|
else if (dockState == DockState.DockLeftAutoHide)
|
|
return PanesLeft;
|
|
else if (dockState == DockState.DockRightAutoHide)
|
|
return PanesRight;
|
|
else
|
|
throw new ArgumentOutOfRangeException("dockState");
|
|
}
|
|
|
|
internal int GetNumberOfPanes(DockState dockState)
|
|
{
|
|
return GetPanes(dockState).Count;
|
|
}
|
|
|
|
protected Rectangle RectangleTopLeft
|
|
{
|
|
get
|
|
{
|
|
int height = MeasureHeight();
|
|
return PanesTop.Count > 0 && PanesLeft.Count > 0 ? new Rectangle(0, 0, height, height) : Rectangle.Empty;
|
|
}
|
|
}
|
|
|
|
protected Rectangle RectangleTopRight
|
|
{
|
|
get
|
|
{
|
|
int height = MeasureHeight();
|
|
return PanesTop.Count > 0 && PanesRight.Count > 0 ? new Rectangle(Width - height, 0, height, height) : Rectangle.Empty;
|
|
}
|
|
}
|
|
|
|
protected Rectangle RectangleBottomLeft
|
|
{
|
|
get
|
|
{
|
|
int height = MeasureHeight();
|
|
return PanesBottom.Count > 0 && PanesLeft.Count > 0 ? new Rectangle(0, Height - height, height, height) : Rectangle.Empty;
|
|
}
|
|
}
|
|
|
|
protected Rectangle RectangleBottomRight
|
|
{
|
|
get
|
|
{
|
|
int height = MeasureHeight();
|
|
return PanesBottom.Count > 0 && PanesRight.Count > 0 ? new Rectangle(Width - height, Height - height, height, height) : Rectangle.Empty;
|
|
}
|
|
}
|
|
|
|
protected internal Rectangle GetTabStripRectangle(DockState dockState)
|
|
{
|
|
int height = MeasureHeight();
|
|
if (dockState == DockState.DockTopAutoHide && PanesTop.Count > 0)
|
|
return new Rectangle(RectangleTopLeft.Width, 0, Width - RectangleTopLeft.Width - RectangleTopRight.Width, height);
|
|
else if (dockState == DockState.DockBottomAutoHide && PanesBottom.Count > 0)
|
|
return new Rectangle(RectangleBottomLeft.Width, Height - height, Width - RectangleBottomLeft.Width - RectangleBottomRight.Width, height);
|
|
else if (dockState == DockState.DockLeftAutoHide && PanesLeft.Count > 0)
|
|
return new Rectangle(0, RectangleTopLeft.Width, height, Height - RectangleTopLeft.Height - RectangleBottomLeft.Height);
|
|
else if (dockState == DockState.DockRightAutoHide && PanesRight.Count > 0)
|
|
return new Rectangle(Width - height, RectangleTopRight.Width, height, Height - RectangleTopRight.Height - RectangleBottomRight.Height);
|
|
else
|
|
return Rectangle.Empty;
|
|
}
|
|
|
|
private GraphicsPath m_displayingArea = null;
|
|
private GraphicsPath DisplayingArea
|
|
{
|
|
get
|
|
{
|
|
if (m_displayingArea == null)
|
|
m_displayingArea = new GraphicsPath();
|
|
|
|
return m_displayingArea;
|
|
}
|
|
}
|
|
|
|
private void SetRegion()
|
|
{
|
|
DisplayingArea.Reset();
|
|
DisplayingArea.AddRectangle(RectangleTopLeft);
|
|
DisplayingArea.AddRectangle(RectangleTopRight);
|
|
DisplayingArea.AddRectangle(RectangleBottomLeft);
|
|
DisplayingArea.AddRectangle(RectangleBottomRight);
|
|
DisplayingArea.AddRectangle(GetTabStripRectangle(DockState.DockTopAutoHide));
|
|
DisplayingArea.AddRectangle(GetTabStripRectangle(DockState.DockBottomAutoHide));
|
|
DisplayingArea.AddRectangle(GetTabStripRectangle(DockState.DockLeftAutoHide));
|
|
DisplayingArea.AddRectangle(GetTabStripRectangle(DockState.DockRightAutoHide));
|
|
Region = new Region(DisplayingArea);
|
|
}
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
base.OnMouseDown(e);
|
|
|
|
if (e.Button != MouseButtons.Left)
|
|
return;
|
|
|
|
IDockContent content = HitTest();
|
|
if (content == null)
|
|
return;
|
|
|
|
content.DockHandler.Activate();
|
|
}
|
|
|
|
protected override void OnMouseHover(EventArgs e)
|
|
{
|
|
base.OnMouseHover(e);
|
|
|
|
IDockContent content = HitTest();
|
|
if (content != null && DockPanel.ActiveAutoHideContent != content)
|
|
DockPanel.ActiveAutoHideContent = content;
|
|
|
|
// requires further tracking of mouse hover behavior,
|
|
ResetMouseEventArgs();
|
|
}
|
|
|
|
protected override void OnLayout(LayoutEventArgs levent)
|
|
{
|
|
RefreshChanges();
|
|
base.OnLayout (levent);
|
|
}
|
|
|
|
internal void RefreshChanges()
|
|
{
|
|
if (IsDisposed)
|
|
return;
|
|
|
|
SetRegion();
|
|
OnRefreshChanges();
|
|
}
|
|
|
|
protected virtual void OnRefreshChanges()
|
|
{
|
|
}
|
|
|
|
protected internal abstract int MeasureHeight();
|
|
|
|
private IDockContent HitTest()
|
|
{
|
|
Point ptMouse = PointToClient(Control.MousePosition);
|
|
return HitTest(ptMouse);
|
|
}
|
|
|
|
protected virtual Tab CreateTab(IDockContent content)
|
|
{
|
|
return new Tab(content);
|
|
}
|
|
|
|
protected virtual Pane CreatePane(DockPane dockPane)
|
|
{
|
|
return new Pane(dockPane);
|
|
}
|
|
|
|
protected abstract IDockContent HitTest(Point point);
|
|
}
|
|
}
|