⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draghandler.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
// *****************************************************************************
// 
//  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 + -