------ #### RaUIV4 V4.0.2311.0701 - *.[全新]整合了MyDb、ryControls、MyDb_MySQL等dll文件到RaUI一个项目。 - *.[新增]新增ApkOp类,可以轻松获取APK信息。 - *.[新增]新增JsonExt扩展类,让Json操作更简单。 - *.[新增]新增WebP类,可以支持webp格式的图片。 - *.[改进]ryQuickSQL中的AddField方法改为自动替换已存在的同名值。 - *.[修复]ryQuickSQL中的AddFieldCalc方法无法正常计算的BUG。
566 lines
16 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|