You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
508 lines
15 KiB
508 lines
15 KiB
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 WeifenLuo.WinFormsUI.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; |
|
} |
|
|
|
public IDockContent Content |
|
{ |
|
get { return m_content; } |
|
} |
|
|
|
public virtual void Dispose() |
|
{ |
|
} |
|
} |
|
|
|
[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; |
|
} |
|
|
|
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 virtual void Dispose() |
|
{ |
|
} |
|
} |
|
|
|
[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); |
|
} |
|
}
|
|
|