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

📄 draghandler.cs

📁 Fireball.CodeEditor is an source code editor control derived from the best compona SyntaxBox Control
💻 CS
📖 第 1 页 / 共 2 页
字号:
#region Fireball License
//    Copyright (C) 2005  Sebastian Faltoni sebastian{at}dotnetfireball{dot}net
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#endregion
#region Original License
// *****************************************************************************
// 
//  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
// *****************************************************************************
#endregion

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Fireball.Docking
{
	/// <summary>
	/// Summary description for DragHandler.
	/// </summary>
	internal sealed class DragHandler : DragHandlerBase
	{
		internal enum DragSource
		{
			Content,
			Pane,
			FloatWindow,
			PaneSplitter,
			DockWindowSplitter,
			AutoHideWindowSplitter
		}

		private Point m_splitterLocation;

		private Point m_mouseOffset = Point.Empty;

		public DragHandler(DockContainer dockPanel)
		{
			m_dockPanel = dockPanel;
		}

		private DragSource m_source;
		internal DragSource Source
		{
			get	{	return m_source;	}
		}

		private DockContainer m_dockPanel;
		public DockContainer DockPanel
		{
			get	{	return m_dockPanel;	}
		}

		private DockOutlineBase m_dockOutline;
		internal DockOutlineBase DockOutline
		{
			get	{	return m_dockOutline;	}
		}

		private SplitterOutline m_splitterOutline;
		private SplitterOutline SplitterOutline
		{
			get	{	return m_splitterOutline;	}
		}

		private DockIndicator m_dockIndicator;
		private DockIndicator DockIndicator
		{
			get	{	return m_dockIndicator;	}
		}

		public void BeginDragContent(IDockableWindow content)
		{
			if (!InitDrag(content as Control, DragSource.Content))
				return;

			Content_BeginDrag(content);
		}

		public void BeginDragPane(DockPane pane)
		{
			if (!InitDrag(pane, DragSource.Pane))
				return;

			Pane_BeginDrag();
		}

		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;

			autoHideWindow.FlagDragging = true;
			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 source)
		{
			if (!base.BeginDrag(c))
				return false;

			m_source = source;
			if (Source == DragSource.Content ||
				Source == DragSource.Pane ||
				Source == DragSource.FloatWindow)
			{
				m_dockOutline = new DockOutline();
				m_dockIndicator = new DockIndicator(this);
				DockIndicator.Show(false);
			}
			else if (Source == DragSource.AutoHideWindowSplitter ||
				Source == DragSource.DockWindowSplitter ||
				Source == DragSource.PaneSplitter)
				m_splitterOutline = new SplitterOutline();
			else
				return false;

			return true;
		}

		protected override void OnDragging()
		{
			if (Source == DragSource.Content ||
				Source == DragSource.Pane ||
				Source == DragSource.FloatWindow)
				TestDrop();
			else if (Source == DragSource.PaneSplitter)
				SplitterOutline.Show(GetPaneSplitterDragRectangle());
			else if (Source == DragSource.DockWindowSplitter)
				SplitterOutline.Show(GetWindowSplitterDragRectangle());
			else if (Source == DragSource.AutoHideWindowSplitter)
				SplitterOutline.Show(GetWindowSplitterDragRectangle());
		}

		protected override void OnEndDrag(bool abort)
		{
			if (Source == DragSource.Content ||
				Source == DragSource.Pane ||
				Source == DragSource.FloatWindow)
			{
				DockOutline.Close();
				DockIndicator.Close();
			}
			else if (Source == DragSource.AutoHideWindowSplitter ||
				Source == DragSource.DockWindowSplitter ||
				Source == DragSource.PaneSplitter)
				SplitterOutline.Close();

			if (Source == DragSource.Content)
				Content_OnEndDrag(abort);
			else if (Source == DragSource.Pane)
				Pane_OnEndDrag(abort);
			else if (Source == DragSource.PaneSplitter)
				PaneSplitter_OnEndDrag(abort);
			else if (Source == DragSource.DockWindowSplitter)
				DockWindowSplitter_OnEndDrag(abort);
			else if (Source == DragSource.AutoHideWindowSplitter)
				AutoHideWindowSplitter_OnEndDrag(abort);
			else if (Source == DragSource.FloatWindow)
				FloatWindow_OnEndDrag(abort);
		}

		private void Content_BeginDrag(IDockableWindow content)
		{
			DockPane pane = content.DockHandler.Pane;
			Rectangle rectPane = pane.ClientRectangle;

			Point pt;
			if (pane.DockState == DockState.Document)
				pt = new Point(rectPane.Left, rectPane.Top);
			else
				pt = new Point(rectPane.Left, rectPane.Bottom);

			pt = pane.PointToScreen(pt);

			m_mouseOffset.X = pt.X - StartMousePosition.X;
			m_mouseOffset.Y = pt.Y - StartMousePosition.Y;
		}

		private void Content_OnEndDrag(bool abort)
		{
			User32.SetCursor(DragControl.Cursor.Handle);

			if (abort)
				return;

			IDockableWindow content = DragControl as IDockableWindow;

			if (!DockOutline.FloatWindowBounds.IsEmpty)
			{
				DockPane pane = content.DockHandler.DockPanel.DockPaneFactory.CreateDockPane(content, DockOutline.FloatWindowBounds, true);
				pane.Activate();
			}
			else if (DockOutline.DockTo is DockPane)
			{
				DockPane paneTo = DockOutline.DockTo as DockPane;

				if (DockOutline.Dock == DockStyle.Fill)
				{
					bool samePane = (content.DockHandler.Pane == paneTo);
					if (!samePane)
						content.DockHandler.Pane = paneTo;

					if (DockOutline.ContentIndex == -1 || !samePane)
						paneTo.SetContentIndex(content, DockOutline.ContentIndex);
					else
					{
						DockContentCollection contents = paneTo.Contents;
						int oldIndex = contents.IndexOf(content);
						int newIndex = DockOutline.ContentIndex;
						if (oldIndex < newIndex)
						{
							newIndex += 1;
							if (newIndex > contents.Count -1)
								newIndex = -1;
						}
						paneTo.SetContentIndex(content, newIndex);
					}

					content.DockHandler.Activate();
				}
				else
				{
					DockPane pane = content.DockHandler.DockPanel.DockPaneFactory.CreateDockPane(content, paneTo.DockState, true);
					IDockListContainer container = paneTo.DockListContainer;
					if (DockOutline.Dock == DockStyle.Left)
						pane.AddToDockList(container, paneTo, DockAlignment.Left, 0.5);
					else if (DockOutline.Dock == DockStyle.Right) 
						pane.AddToDockList(container, paneTo, DockAlignment.Right, 0.5);
					else if (DockOutline.Dock == DockStyle.Top)
						pane.AddToDockList(container, paneTo, DockAlignment.Top, 0.5);
					else if (DockOutline.Dock == DockStyle.Bottom) 
						pane.AddToDockList(container, paneTo, DockAlignment.Bottom, 0.5);

					pane.DockState = paneTo.DockState;
					pane.Activate();
				}
			}
			else if (DockOutline.DockTo is DockContainer)
			{
				DockPane pane;
				DockContainer dockPanel = content.DockHandler.DockPanel;

				SetDockWindow();
				if (DockOutline.Dock == DockStyle.Top)
					pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockTop, true);
				else if (DockOutline.Dock == DockStyle.Bottom)
					pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockBottom, true);
				else if (DockOutline.Dock == DockStyle.Left)
					pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockLeft, true);
				else if (DockOutline.Dock == DockStyle.Right)
					pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.DockRight, true);
				else if (DockOutline.Dock == DockStyle.Fill)
					pane = dockPanel.DockPaneFactory.CreateDockPane(content, DockState.Document, true);
				else
					return;
					
				pane.Activate();
			}
		}

		private void Pane_BeginDrag()
		{
			Point pt = new Point(0, 0);
			pt = DragControl.PointToScreen(pt);

			m_mouseOffset.X = pt.X - StartMousePosition.X;
			m_mouseOffset.Y = pt.Y - StartMousePosition.Y;
		}

		private void Pane_OnEndDrag(bool abort)
		{
			User32.SetCursor(DragControl.Cursor.Handle);

			if (abort)
				return;

			DockPane pane = (DockPane)DragControl;

			if (!DockOutline.FloatWindowBounds.IsEmpty)
			{
				if (pane.FloatWindow == null || pane.FloatWindow.DockList.Count != 1)
					pane.FloatWindow = pane.DockPanel.FloatWindowFactory.CreateFloatWindow(pane.DockPanel, pane, DockOutline.FloatWindowBounds);
				else
					pane.FloatWindow.Bounds = DockOutline.FloatWindowBounds;

				pane.DockState = DockState.Float;
				pane.Activate();
			}
			else if (DockOutline.DockTo is DockPane)
			{
				DockPane paneTo = DockOutline.DockTo as DockPane;

				if (DockOutline.Dock == DockStyle.Fill)
				{
					for (int i=pane.Contents.Count - 1; i>=0; i--)
					{
						IDockableWindow c = pane.Contents[i];
						c.DockHandler.Pane = paneTo;
						if (DockOutline.ContentIndex != -1)
							paneTo.SetContentIndex(c, DockOutline.ContentIndex);
						c.DockHandler.Activate();
					}
				}
				else
				{
					if (DockOutline.Dock == DockStyle.Left)
						pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Left, 0.5);
					else if (DockOutline.Dock == DockStyle.Right) 
						pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Right, 0.5);
					else if (DockOutline.Dock == DockStyle.Top)
						pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Top, 0.5);
					else if (DockOutline.Dock == DockStyle.Bottom) 
						pane.AddToDockList(paneTo.DockListContainer, paneTo, DockAlignment.Bottom, 0.5);

					pane.DockState = paneTo.DockState;
					pane.Activate();
				}
			}
			else if (DockOutline.DockTo is DockContainer)
			{
				SetDockWindow();
				if (DockOutline.Dock == DockStyle.Top)
					pane.DockState = DockState.DockTop;
				else if (DockOutline.Dock == DockStyle.Bottom)
					pane.DockState = DockState.DockBottom;
				else if (DockOutline.Dock == DockStyle.Left)
					pane.DockState = DockState.DockLeft;
				else if (DockOutline.Dock == DockStyle.Right)
					pane.DockState = DockState.DockRight;
				else if (DockOutline.Dock == DockStyle.Fill)
					pane.DockState = DockState.Document;
					
				pane.Activate();
			}
		}

		private void DockWindowSplitter_BeginDrag(Point ptSplitter)
		{
			m_splitterLocation = DragControl.PointToScreen(ptSplitter);
			Point ptMouse = StartMousePosition;

			m_mouseOffset.X = m_splitterLocation.X - ptMouse.X;
			m_mouseOffset.Y = m_splitterLocation.Y - ptMouse.Y;

			Rectangle rect = GetWindowSplitterDragRectangle();
			SplitterOutline.Show(rect);
		}

		private void DockWindowSplitter_OnEndDrag(bool abort)
		{
			if (abort)
				return;

			DockWindow dockWindow = DragControl as DockWindow;
			if (dockWindow == null)
				return;
			DockContainer dockPanel = dockWindow.DockPanel;
			DockState state = dockWindow.DockState;

			if ((Control.ModifierKeys & Keys.Shift) != 0)
				dockWindow.SendToBack();

			Point pt = m_splitterLocation;
			Rectangle rect = GetWindowSplitterDragRectangle();
			Rectangle rectDockArea = dockPanel.DockArea;
			if (state == DockState.DockLeft && rectDockArea.Width > 0)
				dockPanel.DockLeftPortion += ((double)rect.X - (double)pt.X) / (double)rectDockArea.Width;
			else if (state == DockState.DockRight && rectDockArea.Width > 0)
				dockPanel.DockRightPortion += ((double)pt.X - (double)rect.X) / (double)rectDockArea.Width;
			else if (state == DockState.DockBottom && rectDockArea.Height > 0)
				dockPanel.DockBottomPortion += ((double)pt.Y - (double)rect.Y) / (double)rectDockArea.Height;
			else if (state == DockState.DockTop && rectDockArea.Height > 0)
				dockPanel.DockTopPortion += ((double)rect.Y - (double)pt.Y) / (double)rectDockArea.Height;
		}

		private void AutoHideWindowSplitter_BeginDrag(Point ptSplitter)
		{
			m_splitterLocation = DragControl.PointToScreen(ptSplitter);
			Point ptMouse = StartMousePosition;

			m_mouseOffset.X = m_splitterLocation.X - ptMouse.X;
			m_mouseOffset.Y = m_splitterLocation.Y - ptMouse.Y;

			Rectangle rect = GetWindowSplitterDragRectangle();
			SplitterOutline.Show(rect);
		}

		private void AutoHideWindowSplitter_OnEndDrag(bool abort)
		{
			AutoHideWindow autoHideWindow = DragControl as AutoHideWindow;
			if (autoHideWindow == null || abort)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -