📄 draghandler.cs
字号:
// *****************************************************************************
//
// Copyright 2004, Weifen Luo
// All rights reserved. The software and associated documentation
// supplied hereunder are the proprietary information of Weifen Luo
// and are supplied subject to licence terms.
//
// WinFormsUI Library Version 1.0
// *****************************************************************************
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WeifenLuo.WinFormsUI
{
internal class DropTarget
{
private Control m_dropTo = null;
private DockStyle m_dock = DockStyle.None;
private int m_contentIndex = -1;
private Control m_oldDropTo = null;
private DockStyle m_oldDock = DockStyle.None;
private int m_oldContentIndex = -1;
public DropTarget()
{
Clear();
}
public Control DropTo
{
get { return m_dropTo; }
}
public DockStyle Dock
{
get { return m_dock; }
}
public int ContentIndex
{
get { return m_contentIndex; }
}
public bool SameAsOldValue
{
get { return (m_dropTo!=null && m_dropTo==m_oldDropTo && m_dock==m_oldDock && m_contentIndex==m_oldContentIndex); }
}
public void Clear()
{
Clear(false);
}
public void Clear(bool saveOldValue)
{
if (saveOldValue)
{
m_oldDropTo = m_dropTo;
m_oldDock = m_dock;
m_oldContentIndex = m_contentIndex;
}
else
{
m_oldDropTo = null;
m_oldDock = DockStyle.None;
m_oldContentIndex = -1;
}
m_dropTo = null;
m_dock = DockStyle.None;
m_contentIndex = -1;
}
public void SetDropTarget(DockPane pane, DockStyle dock)
{
m_dropTo = pane;
m_dock = dock;
m_contentIndex = -1;
}
public void SetDropTarget(DockPane pane, int contentIndex)
{
m_dropTo = pane;
m_dock = DockStyle.Fill;
m_contentIndex = contentIndex;
}
public void SetDropTarget(DockPanel dockPanel, DockStyle dock)
{
m_dropTo = dockPanel;
m_dock = dock;
m_contentIndex = -1;
}
}
internal enum DragSource
{
Content,
Pane,
FloatWindow,
PaneSplitter,
DockWindowSplitter,
AutoHideWindowSplitter
}
/// <summary>
/// Summary description for DragHandler.
/// </summary>
internal sealed class DragHandler : DragHandlerBase
{
private Point m_splitterLocation;
private Point m_mouseOffset = Point.Empty;
public DragHandler(DockPanel dockPanel)
{
m_dockPanel = dockPanel;
m_dropTarget = new DropTarget();
}
private DragSource m_dragSource;
internal DragSource DragSource
{
get { return m_dragSource; }
}
private DockPanel m_dockPanel;
public DockPanel DockPanel
{
get { return m_dockPanel; }
}
private Region m_dragOutline = null;
internal Region DragOutline
{
get { return m_dragOutline; }
set
{
if (m_dragOutline != null)
{
DrawHelper.DrawDragOutline(m_dragOutline);
m_dragOutline.Dispose();
}
m_dragOutline = value;
if (m_dragOutline != null)
DrawHelper.DrawDragOutline(m_dragOutline);
}
}
private DropTarget m_dropTarget;
public DropTarget DropTarget
{
get { return m_dropTarget; }
}
private int OutlineBorderWidth
{
get
{
if (DragSource == DragSource.DockWindowSplitter)
return MeasureDockWindow.SplitterSize;
else if (DragSource == DragSource.AutoHideWindowSplitter)
return MeasureAutoHideWindow.SplitterSize;
else if (DragSource == DragSource.PaneSplitter)
return MeasurePaneSplitter.SplitterSize;
else
return MeasureOutline.Width;
}
}
public void BeginDragContent(DockPane pane, Rectangle rectPane)
{
if (!InitDrag(pane, DragSource.Content))
return;
Content_BeginDrag(rectPane);
}
public void BeginDragPane(DockPane pane, Point captionLocation)
{
if (!InitDrag(pane, DragSource.Pane))
return;
Pane_BeginDrag(captionLocation);
}
public void BeginDragPaneSplitter(DockPaneSplitter splitter)
{
if (!InitDrag(splitter, DragSource.PaneSplitter))
return;
PaneSplitter_BeginDrag(splitter.Location);
}
public void BeginDragAutoHideWindowSplitter(AutoHideWindow autoHideWindow, Point splitterLocation)
{
if (!InitDrag(autoHideWindow, DragSource.AutoHideWindowSplitter))
return;
AutoHideWindowSplitter_BeginDrag(splitterLocation);
}
public void BeginDragDockWindowSplitter(DockWindow dockWindow, Point splitterLocation)
{
if (!InitDrag(dockWindow, DragSource.DockWindowSplitter))
return;
DockWindowSplitter_BeginDrag(splitterLocation);
}
public void BeginDragFloatWindow(FloatWindow floatWindow)
{
if (!InitDrag(floatWindow, DragSource.FloatWindow))
return;
FloatWindow_BeginDrag();
}
private bool InitDrag(Control c, DragSource dragSource)
{
if (!base.BeginDrag(c))
return false;
m_dragSource = dragSource;
DropTarget.Clear();
return true;
}
protected override void OnDragging()
{
DropTarget.Clear(true);
if (m_dragSource == DragSource.Content)
Content_OnDragging();
else if (m_dragSource == DragSource.Pane)
Pane_OnDragging();
else if (m_dragSource == DragSource.PaneSplitter)
PaneSplitter_OnDragging();
else if (m_dragSource == DragSource.DockWindowSplitter)
DockWindowSplitter_OnDragging();
else if (m_dragSource == DragSource.AutoHideWindowSplitter)
AutoHideWindowSplitter_OnDragging();
else if (m_dragSource == DragSource.FloatWindow)
FloatWindow_OnDragging();
}
protected override void OnEndDrag(bool abort)
{
DragOutline = null;
if (m_dragSource == DragSource.Content)
Content_OnEndDrag(abort);
else if (m_dragSource == DragSource.Pane)
Pane_OnEndDrag(abort);
else if (m_dragSource == DragSource.PaneSplitter)
PaneSplitter_OnEndDrag(abort);
else if (m_dragSource == DragSource.DockWindowSplitter)
DockWindowSplitter_OnEndDrag(abort);
else if (m_dragSource == DragSource.AutoHideWindowSplitter)
AutoHideWindowSplitter_OnEndDrag(abort);
else if (m_dragSource == DragSource.FloatWindow)
FloatWindow_OnEndDrag(abort);
}
private void Content_BeginDrag(Rectangle rectPane)
{
DockPane pane = (DockPane)DragControl;
Point pt;
if (pane.DockState == DockState.Document)
pt = new Point(rectPane.Top, rectPane.Left);
else
pt = new Point(rectPane.Left, rectPane.Bottom);
pt = DragControl.PointToScreen(pt);
m_mouseOffset.X = pt.X - StartMousePosition.X;
m_mouseOffset.Y = pt.Y - StartMousePosition.Y;
}
private void Content_OnDragging()
{
Point ptMouse = Control.MousePosition;
DockPane pane = (DockPane)DragControl;
if (!TestDrop(ptMouse))
return;
if (DropTarget.DropTo == null)
{
if (IsDockStateValid(DockState.Float))
{
Size size = FloatWindow.DefaultWindowSize;
Point location;
if (pane.DockState == DockState.Document)
location = new Point(ptMouse.X + m_mouseOffset.X, ptMouse.Y + m_mouseOffset.Y);
else
location = new Point(ptMouse.X + m_mouseOffset.X, ptMouse.Y + m_mouseOffset.Y - size.Height);
if (ptMouse.X > location.X + size.Width)
location.X += ptMouse.X - (location.X + size.Width) + OutlineBorderWidth;
Rectangle rect = new Rectangle(location, size);
DragOutline = DrawHelper.CreateDragOutline(rect, OutlineBorderWidth);
}
else
DragOutline = null;
}
if (DragOutline == null)
User32.SetCursor(Cursors.No.Handle);
else
User32.SetCursor(DragControl.Cursor.Handle);
}
private void Content_OnEndDrag(bool abort)
{
User32.SetCursor(DragControl.Cursor.Handle);
if (abort)
return;
DockContent content = ((DockPane)DragControl).ActiveContent;
if (DropTarget.DropTo is DockPane)
{
DockPane paneTo = DropTarget.DropTo as DockPane;
if (DropTarget.Dock == DockStyle.Fill)
{
bool samePane = (content.Pane == paneTo);
if (!samePane)
content.Pane = paneTo;
if (DropTarget.ContentIndex == -1 || !samePane)
paneTo.SetContentIndex(content, DropTarget.ContentIndex);
else
{
DockContentCollection contents = paneTo.Contents;
int oldIndex = contents.IndexOf(content);
int newIndex = DropTarget.ContentIndex;
if (oldIndex < newIndex)
{
newIndex += 1;
if (newIndex > contents.Count -1)
newIndex = -1;
}
paneTo.SetContentIndex(content, newIndex);
}
content.Activate();
}
else
{
DockPane pane = content.DockPanel.DockPaneFactory.CreateDockPane(content, paneTo.DockState, true);
IDockListContainer container = paneTo.DockListContainer;
if (DropTarget.Dock == DockStyle.Left)
pane.AddToDockList(container, paneTo, DockAlignment.Left, 0.5);
else if (DropTarget.Dock == DockStyle.Right)
pane.AddToDockList(container, paneTo, DockAlignment.Right, 0.5);
else if (DropTarget.Dock == DockStyle.Top)
pane.AddToDockList(container, paneTo, DockAlignment.Top, 0.5);
else if (DropTarget.Dock == DockStyle.Bottom)
pane.AddToDockList(container, paneTo, DockAlignment.Bottom, 0.5);
pane.DockState = paneTo.DockState;
pane.Activate();
}
}
else if (DropTarget.DropTo is DockPanel)
{
DockPane pane;
DockPanel dockPanel = content.DockPanel;
if (DropTarget.Dock == DockStyle.Top)
pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockTop, true);
else if (DropTarget.Dock == DockStyle.Bottom)
pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockBottom, true);
else if (DropTarget.Dock == DockStyle.Left)
pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockLeft, true);
else if (DropTarget.Dock == DockStyle.Right)
pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockRight, true);
else if (DropTarget.Dock == DockStyle.Fill)
pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.Document, true);
else
return;
pane.Activate();
}
else if (IsDockStateValid(DockState.Float))
{
Point ptMouse = Control.MousePosition;
Size size = FloatWindow.DefaultWindowSize;
Point location;
if (content.DockState == DockState.Document)
location = new Point(ptMouse.X + m_mouseOffset.X, ptMouse.Y + m_mouseOffset.Y);
else
location = new Point(ptMouse.X + m_mouseOffset.X, ptMouse.Y + m_mouseOffset.Y - size.Height);
if (ptMouse.X > location.X + size.Width)
location.X += ptMouse.X - (location.X + size.Width) + OutlineBorderWidth;
DockPane pane = content.DockPanel.DockPaneFactory.CreateDockPane(content, new Rectangle(location, size), true);
pane.Activate();
}
}
private void Pane_BeginDrag(Point captionLocation)
{
Point pt = captionLocation;
pt = DragControl.PointToScreen(pt);
m_mouseOffset.X = pt.X - StartMousePosition.X;
m_mouseOffset.Y = pt.Y - StartMousePosition.Y;
}
private void Pane_OnDragging()
{
Point ptMouse = Control.MousePosition;
DockPane pane = (DockPane)DragControl;
if (!TestDrop(ptMouse))
return;
if (DropTarget.DropTo == null)
{
if (IsDockStateValid(DockState.Float))
{
Point location = new Point(ptMouse.X + m_mouseOffset.X, ptMouse.Y + m_mouseOffset.Y);
Size size;
if (pane.FloatWindow == null)
size = FloatWindow.DefaultWindowSize;
else if (pane.FloatWindow.DisplayingList.Count == 1)
size = pane.FloatWindow.Size;
else
size = FloatWindow.DefaultWindowSize;
if (ptMouse.X > location.X + size.Width)
location.X += ptMouse.X - (location.X + size.Width) + OutlineBorderWidth;
Rectangle rect = new Rectangle(location, size);
DragOutline = DrawHelper.CreateDragOutline(rect, OutlineBorderWidth);
}
else
DragOutline = null;
}
if (DragOutline == null)
User32.SetCursor(Cursors.No.Handle);
else
User32.SetCursor(DragControl.Cursor.Handle);
}
private void Pane_OnEndDrag(bool abort)
{
User32.SetCursor(DragControl.Cursor.Handle);
if (abort)
return;
DockPane pane = (DockPane)DragControl;
if (DropTarget.DropTo is DockPane)
{
DockPane paneTo = DropTarget.DropTo as DockPane;
if (DropTarget.Dock == DockStyle.Fill)
{
for (int i=pane.Contents.Count - 1; i>=0; i--)
{
DockContent c = pane.Contents[i];
c.Pane = paneTo;
if (DropTarget.ContentIndex != -1)
paneTo.SetContentIndex(c, DropTarget.ContentIndex);
c.Activate();
}
}
else
{
if (DropTarget.Dock == DockStyle.Left)
pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Left, 0.5);
else if (DropTarget.Dock == DockStyle.Right)
pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Right, 0.5);
else if (DropTarget.Dock == DockStyle.Top)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -