RaUI/Source/ryControls/WeifenLuo.WinFormsUI/Docking/DockPaneStripBase.cs
zilinsoft 3262955f2f ### 2023-11-07更新
------
#### RaUIV4    V4.0.2311.0701
- *.[全新]整合了MyDb、ryControls、MyDb_MySQL等dll文件到RaUI一个项目。
- *.[新增]新增ApkOp类,可以轻松获取APK信息。
- *.[新增]新增JsonExt扩展类,让Json操作更简单。
- *.[新增]新增WebP类,可以支持webp格式的图片。
- *.[改进]ryQuickSQL中的AddField方法改为自动替换已存在的同名值。
- *.[修复]ryQuickSQL中的AddFieldCalc方法无法正常计算的BUG。
2023-11-07 16:37:53 +08:00

566 lines
16 KiB
C#

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Diagnostics.CodeAnalysis;
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
namespace WeifenLuo.WinFormsUI.Docking
{
/// <summary>
///
/// </summary>
public abstract class DockPaneStripBase : Control
{
/// <summary>
///
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
protected internal class Tab : IDisposable
{
private IDockContent m_content;
/// <summary>
///
/// </summary>
/// <param name="content"></param>
public Tab(IDockContent content)
{
m_content = content;
}
/// <summary>
///
/// </summary>
~Tab()
{
Dispose(false);
}
/// <summary>
///
/// </summary>
public IDockContent Content
{
get { return m_content; }
}
/// <summary>
///
/// </summary>
public Form ContentForm
{
get { return m_content as Form; }
}
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
}
private Rectangle? _rect;
private static Rectangle empty = new Rectangle();
/// <summary>
///
/// </summary>
public Rectangle? Rectangle
{
get
{
if (_rect != null)
{
return _rect;
}
return _rect = empty;
}
set
{
_rect = value;
}
}
}
/// <summary>
///
/// </summary>
[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;
/// <summary>
///
/// </summary>
public DockPane DockPane
{
get { return m_dockPane; }
}
/// <summary>
///
/// </summary>
public int Count
{
get { return DockPane.DisplayingContents.Count; }
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Tab this[int index]
{
get
{
IDockContent content = DockPane.DisplayingContents[index];
if (content == null)
throw (new ArgumentOutOfRangeException("index"));
return content.DockHandler.GetTab(DockPane.TabStripControl);
}
}
/// <summary>
///
/// </summary>
/// <param name="tab"></param>
/// <returns></returns>
public bool Contains(Tab tab)
{
return (IndexOf(tab) != -1);
}
/// <summary>
///
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public bool Contains(IDockContent content)
{
return (IndexOf(content) != -1);
}
/// <summary>
///
/// </summary>
/// <param name="tab"></param>
/// <returns></returns>
public int IndexOf(Tab tab)
{
if (tab == null)
return -1;
return DockPane.DisplayingContents.IndexOf(tab.Content);
}
/// <summary>
///
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public int IndexOf(IDockContent content)
{
return DockPane.DisplayingContents.IndexOf(content);
}
}
/// <summary>
///
/// </summary>
/// <param name="pane"></param>
protected DockPaneStripBase(DockPane pane)
{
m_dockPane = pane;
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.Selectable, false);
AllowDrop = true;
}
private DockPane m_dockPane;
/// <summary>
///
/// </summary>
protected DockPane DockPane
{
get { return m_dockPane; }
}
/// <summary>
///
/// </summary>
protected DockPane.AppearanceStyle Appearance
{
get { return DockPane.Appearance; }
}
private TabCollection m_tabs;
/// <summary>
///
/// </summary>
protected TabCollection Tabs
{
get
{
return m_tabs ?? (m_tabs = new TabCollection(DockPane));
}
}
internal void RefreshChanges()
{
if (IsDisposed)
return;
OnRefreshChanges();
}
protected virtual void OnRefreshChanges()
{
}
protected internal abstract int MeasureHeight();
protected internal abstract void EnsureTabVisible(IDockContent content);
protected int HitTest()
{
return HitTest(PointToClient(Control.MousePosition));
}
/// <summary>
///
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
protected internal abstract int HitTest(Point point);
/// <summary>
///
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual bool MouseDownActivateTest(MouseEventArgs e)
{
return true;
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public abstract GraphicsPath GetOutline(int index);
/// <summary>
///
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
protected internal virtual Tab CreateTab(IDockContent content)
{
return new Tab(content);
}
private Rectangle _dragBox = Rectangle.Empty;
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
int index = HitTest();
if (index != -1)
{
if (e.Button == MouseButtons.Middle)
{
// Close the specified content.
TryCloseTab(index);
}
else
{
IDockContent content = Tabs[index].Content;
if (DockPane.ActiveContent != content)
{
// Test if the content should be active
if (MouseDownActivateTest(e))
DockPane.ActiveContent = content;
}
}
}
if (e.Button == MouseButtons.Left)
{
var dragSize = SystemInformation.DragSize;
_dragBox = new Rectangle(new Point(e.X - (dragSize.Width / 2),
e.Y - (dragSize.Height / 2)), dragSize);
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button != MouseButtons.Left || _dragBox.Contains(e.Location))
return;
if (DockPane.ActiveContent == null)
return;
if (DockPane.DockPanel.AllowEndUserDocking && DockPane.AllowDockDragAndDrop && DockPane.ActiveContent.DockHandler.AllowEndUserDocking)
DockPane.DockPanel.BeginDrag(DockPane.ActiveContent.DockHandler);
}
/// <summary>
///
/// </summary>
protected bool HasTabPageContextMenu
{
get { return DockPane.HasTabPageContextMenu; }
}
/// <summary>
///
/// </summary>
/// <param name="position"></param>
protected void ShowTabPageContextMenu(Point position)
{
DockPane.ShowTabPageContextMenu(this, position);
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
protected bool TryCloseTab(int index)
{
if (index >= 0 || index < Tabs.Count)
{
// Close the specified content.
IDockContent content = Tabs[index].Content;
DockPane.CloseContent(content);
return true;
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Right)
ShowTabPageContextMenu(new Point(e.X, e.Y));
}
/// <summary>
///
/// </summary>
/// <param name="m"></param>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)Win32.Msgs.WM_LBUTTONDBLCLK)
{
base.WndProc(ref m);
int index = HitTest();
if (DockPane.DockPanel.AllowEndUserDocking && index != -1)
{
IDockContent content = Tabs[index].Content;
if (content.DockHandler.CheckDockState(!content.DockHandler.IsFloat) != DockState.Unknown)
content.DockHandler.IsFloat = !content.DockHandler.IsFloat;
}
return;
}
base.WndProc(ref m);
return;
}
/// <summary>
///
/// </summary>
/// <param name="drgevent"></param>
protected override void OnDragOver(DragEventArgs drgevent)
{
base.OnDragOver(drgevent);
int index = HitTest();
if (index != -1)
{
IDockContent content = Tabs[index].Content;
if (DockPane.ActiveContent != content)
DockPane.ActiveContent = content;
}
}
/// <summary>
///
/// </summary>
protected void ContentClosed()
{
if (m_tabs.Count == 0)
{
DockPane.ClearLastActiveContent();
}
}
/// <summary>
///
/// </summary>
/// <param name="tab"></param>
/// <returns></returns>
protected abstract Rectangle GetTabBounds(Tab tab);
internal static Rectangle ToScreen(Rectangle rectangle, Control parent)
{
if (parent == null)
return rectangle;
return new Rectangle(parent.PointToScreen(new Point(rectangle.Left, rectangle.Top)), new Size(rectangle.Width, rectangle.Height));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected override AccessibleObject CreateAccessibilityInstance()
{
return new DockPaneStripAccessibleObject(this);
}
/// <summary>
///
/// </summary>
public class DockPaneStripAccessibleObject : Control.ControlAccessibleObject
{
private DockPaneStripBase _strip;
/// <summary>
///
/// </summary>
/// <param name="strip"></param>
public DockPaneStripAccessibleObject(DockPaneStripBase strip)
: base(strip)
{
_strip = strip;
}
/// <summary>
///
/// </summary>
public override AccessibleRole Role
{
get
{
return AccessibleRole.PageTabList;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetChildCount()
{
return _strip.Tabs.Count;
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public override AccessibleObject GetChild(int index)
{
return new DockPaneStripTabAccessibleObject(_strip, _strip.Tabs[index], this);
}
/// <summary>
///
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public override AccessibleObject HitTest(int x, int y)
{
Point point = new Point(x, y);
foreach (Tab tab in _strip.Tabs)
{
Rectangle rectangle = _strip.GetTabBounds(tab);
if (ToScreen(rectangle, _strip).Contains(point))
return new DockPaneStripTabAccessibleObject(_strip, tab, this);
}
return null;
}
}
/// <summary>
///
/// </summary>
protected class DockPaneStripTabAccessibleObject : AccessibleObject
{
private DockPaneStripBase _strip;
private Tab _tab;
private AccessibleObject _parent;
internal DockPaneStripTabAccessibleObject(DockPaneStripBase strip, Tab tab, AccessibleObject parent)
{
_strip = strip;
_tab = tab;
_parent = parent;
}
public override AccessibleObject Parent
{
get
{
return _parent;
}
}
public override AccessibleRole Role
{
get
{
return AccessibleRole.PageTab;
}
}
public override Rectangle Bounds
{
get
{
Rectangle rectangle = _strip.GetTabBounds(_tab);
return ToScreen(rectangle, _strip);
}
}
public override string Name
{
get
{
return _tab.Content.DockHandler.TabText;
}
set
{
//base.Name = value;
}
}
}
}
}