dockpane.cs

来自「全功能c#编译器」· CS 代码 · 共 1,899 行 · 第 1/4 页

CS
1,899
字号
		{
			if (IsHidden)
				Show();

			if (DockHelper.IsDockStateAutoHide(DockState) && DockPanel.ActiveContent != ActiveContent)
				DockPanel.ActiveAutoHideContent = ActiveContent;
				
			if (!IsActivated)
				Focus();
		}

		private void AutoHide_Click(object sender, EventArgs e)
		{
			DockState = DockHelper.ToggleAutoHideState(DockState);
			if (!IsAutoHide)
				Activate();
		}

		internal void AddContent(DockContent content)
		{
			if (Contents.Contains(content))
				return;

			Contents.Add(content);
			content.SetParent(this);
			SetDockState();
			if (!content.IsHidden && CountOfVisibleContents == 1)
			{
				ActiveContent = content;
				Refresh();
			}
		}

		private void CalculateTabs()
		{
			if (Appearance == DockPaneAppearance.ToolWindow)
				CalculateTabs_ToolWindow();
			else
				CalculateTabs_Document();
		}

		private void CalculateTabs_ToolWindow()
		{
			if (CountOfVisibleContents <= 1 || IsAutoHide)
				return;

			Rectangle rectTabStrip = GetTabStripRectangle();

			//////////////////////////////////////////////////////////////////////////////
			/// Calculate tab widths
			/// //////////////////////////////////////////////////////////////////////////
			int countOfVisibleContents = CountOfVisibleContents;
			int[] maxWidths = new int[countOfVisibleContents];
			bool[] flags = new bool[countOfVisibleContents];
			for (int i=0; i<countOfVisibleContents; i++)
			{
				maxWidths[i] = GetTabOriginalWidth(i);
				flags[i] = false;
			}

			// Set tab whose max width less than average width
			bool anyWidthWithinAverage = true;
			int totalWidth = rectTabStrip.Width - MeasureToolWindowTab.StripGapLeft - MeasureToolWindowTab.StripGapRight;
			int totalAllocatedWidth = 0;
			int averageWidth = totalWidth / countOfVisibleContents;
			int remainedContents = countOfVisibleContents;
			for (anyWidthWithinAverage=true; anyWidthWithinAverage && remainedContents>0;)
			{
				anyWidthWithinAverage = false;
				for (int i=0; i<countOfVisibleContents; i++)
				{
					if (flags[i])
						continue;

					DockContent content = GetVisibleContent(i);

					if (maxWidths[i] <= averageWidth)
					{
						flags[i] = true;
						content.TabWidth = maxWidths[i];
						totalAllocatedWidth += content.TabWidth;
						anyWidthWithinAverage = true;
						remainedContents--;
					}
				}
				if (remainedContents != 0)
					averageWidth = (totalWidth - totalAllocatedWidth) / remainedContents;
			}

			// If any tab width not set yet, set it to the average width
			if (remainedContents > 0)
			{
				int roundUpWidth = (totalWidth - totalAllocatedWidth) - (averageWidth * remainedContents);
				for (int i=0; i<countOfVisibleContents; i++)
				{
					if (flags[i])
						continue;

					DockContent content = GetVisibleContent(i);

					flags[i] = true;
					if (roundUpWidth > 0)
					{
						content.TabWidth = averageWidth + 1;
						roundUpWidth --;
					}
					else
						content.TabWidth = averageWidth;
				}
			}

			//////////////////////////////////////////////////////////////////////////////
			/// Set the X position of the tabs
			/////////////////////////////////////////////////////////////////////////////
			int x = rectTabStrip.X + MeasureToolWindowTab.StripGapLeft;
			for (int i=0; i<countOfVisibleContents; ++i)
			{
				DockContent content = GetVisibleContent(i);
				content.TabX = x;
				x += content.TabWidth;
			}
		}

		private void CalculateTabs_Document()
		{
			int countOfVisibleContents = CountOfVisibleContents;
			if (countOfVisibleContents == 0)
				return;

			Rectangle rectTabStrip = GetTabStripRectangle();
			int x = rectTabStrip.X + MeasureDocumentTab.TabGapLeft + m_offset;
			for (int i=0; i<countOfVisibleContents; i++)
			{
				DockContent content = GetVisibleContent(i);
				content.TabX = x;
				content.TabWidth = Math.Min(GetTabOriginalWidth(i), MeasureDocumentTab.TabMaxWidth);
				x += content.TabWidth;
			}
		}

		public virtual void Close()
		{
			Dispose();
		}

		protected virtual void CloseActiveContent()
		{
			DockContent content = ActiveContent;

			if (content == null)
				return;

			if (content.HideOnClose)
				content.Hide();
			else
			{
				///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				/// Workaround for .Net Framework bug: removing control from Form may cause form
				/// unclosable.
				///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				Form form = FindForm();
				if (ContainsFocus)
				{
					if (form is FloatWindow)
					{
						((FloatWindow)form).DummyControl.Focus();
						form.ActiveControl = ((FloatWindow)form).DummyControl;
					}
					else if (DockPanel != null)
					{
						DockPanel.DummyControl.Focus();
						if (form != null)
							form.ActiveControl = DockPanel.DummyControl;
					}
				}
				//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				
				content.Close();
			}
		}

		protected virtual void DrawCaption(Graphics g)
		{
			if (Appearance == DockPaneAppearance.Document)
				return;

			Rectangle rectCaption = CaptionRectangle;

			if (rectCaption.IsEmpty)
				return;

			Brush brushBackGround = IsActivated ? SystemBrushes.ActiveCaption : SystemBrushes.Control;

			g.FillRectangle(brushBackGround, rectCaption);

			if (!IsActivated)
			{
				g.DrawLine(SystemPens.GrayText, rectCaption.X + 1, rectCaption.Y, rectCaption.X + rectCaption.Width - 2, rectCaption.Y);
				g.DrawLine(SystemPens.GrayText, rectCaption.X + 1, rectCaption.Y + rectCaption.Height - 1, rectCaption.X + rectCaption.Width - 2, rectCaption.Y + rectCaption.Height - 1);
				g.DrawLine(SystemPens.GrayText, rectCaption.X, rectCaption.Y + 1, rectCaption.X, rectCaption.Y + rectCaption.Height - 2);
				g.DrawLine(SystemPens.GrayText, rectCaption.X + rectCaption.Width - 1, rectCaption.Y + 1, rectCaption.X + rectCaption.Width - 1, rectCaption.Y + rectCaption.Height - 2);
			}

			m_buttonDockWindowClose.BackColor = m_buttonAutoHide.BackColor = (IsActivated ? SystemColors.ActiveCaption : SystemColors.Control);
			m_buttonDockWindowClose.ForeColor = m_buttonAutoHide.ForeColor = (IsActivated ? SystemColors.ActiveCaptionText : SystemColors.ControlText);
			m_buttonDockWindowClose.BorderColor = m_buttonAutoHide.BorderColor = (IsActivated ? SystemColors.ActiveCaptionText : Color.Empty);	

			m_buttonDockWindowClose.Enabled = ActiveContent.CloseButton;

			Rectangle rectCaptionText = rectCaption;
			rectCaptionText.X += MeasureToolWindowCaption.TextGapLeft;
			rectCaptionText.Width = rectCaption.Width - MeasureToolWindowCaption.ButtonGapRight
				- MeasureToolWindowCaption.ButtonGapLeft
				- MeasureToolWindowCaption.ButtonGapBetween - 2 * m_buttonDockWindowClose.Width
				- MeasureToolWindowCaption.TextGapLeft - MeasureToolWindowCaption.TextGapRight;
			rectCaptionText.Y += MeasureToolWindowCaption.TextGapTop;
			rectCaptionText.Height -= MeasureToolWindowCaption.TextGapTop + MeasureToolWindowCaption.TextGapBottom;
			Brush brush = IsActivated ? SystemBrushes.FromSystemColor(SystemColors.ActiveCaptionText)
				: SystemBrushes.FromSystemColor(SystemColors.ControlText);
			g.DrawString(CaptionText, Font, brush, rectCaptionText, StringFormatDockWindowCaption);
		}

		protected virtual void DrawTab(Graphics g, DockContent content, Rectangle rect)
		{
			if (Appearance == DockPaneAppearance.ToolWindow)
				DrawTab_ToolWindow(g, content, rect);
			else
				DrawTab_Document(g, content, rect);
		}

		private void DrawTab_ToolWindow(Graphics g, DockContent content, Rectangle rect)
		{
			Rectangle rectIcon = new Rectangle(
				rect.X + MeasureToolWindowTab.ImageGapLeft,
				rect.Y + rect.Height - 1 - MeasureToolWindowTab.ImageGapBottom - MeasureToolWindowTab.ImageHeight,
				MeasureToolWindowTab.ImageWidth, MeasureToolWindowTab.ImageHeight);
			Rectangle rectText = rectIcon;
			rectText.X += rectIcon.Width + MeasureToolWindowTab.ImageGapRight;
			rectText.Width = rect.Width - rectIcon.Width - MeasureToolWindowTab.ImageGapLeft - 
				MeasureToolWindowTab.ImageGapRight - MeasureToolWindowTab.TextGapRight;

			if (ActiveContent == content)
			{
				g.FillRectangle(SystemBrushes.Control, rect);
				g.DrawLine(SystemPens.ControlText,
					rect.X, rect.Y + rect.Height - 1, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
				g.DrawLine(SystemPens.ControlText,
					rect.X + rect.Width - 1, rect.Y, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
				g.DrawString(content.TabText, Font, SystemBrushes.ControlText, rectText, StringFormatDockWindowTab);
			}
			else
			{
				if (GetIndexOfVisibleContents(ActiveContent) !=
					GetIndexOfVisibleContents(content) + 1)
					g.DrawLine(SystemPens.GrayText,
						rect.X + rect.Width - 1, rect.Y + 3, rect.X + rect.Width - 1, rect.Y + rect.Height - 4);
				g.DrawString(content.TabText, Font, SystemBrushes.FromSystemColor(SystemColors.ControlDarkDark), rectText, StringFormatDockWindowTab);
			}

			if (rect.Contains(rectIcon))
				g.DrawIcon(content.Icon, rectIcon);
		}

		private void DrawTab_Document(Graphics g, DockContent content, Rectangle rect)
		{
			Rectangle rectText = rect;
			rectText.X += MeasureDocumentTab.TextExtraWidth / 2;
			rectText.Width -= MeasureDocumentTab.TextExtraWidth;
			if (ActiveContent == content)
			{
				g.FillRectangle(SystemBrushes.Control, rect);
				g.DrawLine(SystemPens.ControlText,
					rect.X + rect.Width - 1, rect.Y,
					rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
				if (IsActiveDocumentPane)
				{
					using (Font boldFont = new Font(this.Font, FontStyle.Bold))
					{
						g.DrawString(content.Text, boldFont, SystemBrushes.ControlText, rectText,StringFormatDocumentWindowTab);
					}
				}
				else
					g.DrawString(content.Text, Font, SystemBrushes.FromSystemColor(SystemColors.GrayText), rectText, StringFormatDocumentWindowTab);
			}
			else
			{
				if (GetIndexOfVisibleContents(ActiveContent) != GetIndexOfVisibleContents(content) + 1)
					g.DrawLine(SystemPens.GrayText,
						rect.X + rect.Width - 1, rect.Y,
						rect.X + rect.Width - 1, rect.Y + rect.Height - 1 - MeasureDocumentTab.TabGapTop);

				g.DrawString(content.Text, Font, SystemBrushes.FromSystemColor(SystemColors.GrayText), rectText, StringFormatDocumentWindowTab);
			}
		}

		protected virtual void DrawTabStrip(Graphics g)
		{
			if (Appearance == DockPaneAppearance.ToolWindow)
				DrawTabStrip_ToolWindow(g);
			else
				DrawTabStrip_Document(g);
		}

		private void DrawTabStrip_ToolWindow(Graphics g)
		{
			CalculateTabs();

			Rectangle rectTabStrip = GetTabStripRectangle();

			if (rectTabStrip.IsEmpty)
				return;

			// Paint the background
			g.FillRectangle(Brushes.WhiteSmoke, rectTabStrip);
			g.DrawLine(SystemPens.ControlText, rectTabStrip.Left, rectTabStrip.Top,
				rectTabStrip.Right, rectTabStrip.Top);

			for (int i=0; i<CountOfVisibleContents; i++)
				DrawTab(g, GetVisibleContent(i), GetTabRectangle(i));
		}

		private void DrawTabStrip_Document(Graphics g)
		{
			CalculateTabs();

			int countOfVisibleContents = CountOfVisibleContents;
			if (countOfVisibleContents == 0)
				return;

			Rectangle rectTabStrip = GetTabStripRectangle();

			// Paint the background
			g.FillRectangle(Brushes.WhiteSmoke, rectTabStrip);

			// Set position and size of the buttons
			int buttonWidth = ImageDocumentWindowCloseEnabled.Width;
			int buttonHeight = ImageDocumentWindowCloseEnabled.Height;
			int height = rectTabStrip.Height - MeasureDocumentTab.ButtonGapTop - MeasureDocumentTab.ButtonGapBottom;
			if (buttonHeight < height)
			{
				buttonWidth = buttonWidth * (height / buttonHeight);
				buttonHeight = height;
			}
			Size buttonSize = new Size(buttonWidth, buttonHeight);
			m_buttonDocumentWindowClose.Size = m_buttonScrollLeft.Size = m_buttonScrollRight.Size = buttonSize;
			int x = rectTabStrip.X + rectTabStrip.Width - MeasureDocumentTab.TabGapLeft
				- MeasureDocumentTab.ButtonGapRight - buttonWidth;
			int y = rectTabStrip.Y + MeasureDocumentTab.ButtonGapTop;
			m_buttonDocumentWindowClose.Location = new Point(x, y);
			Point point = m_buttonDocumentWindowClose.Location;
			point.Offset(-(MeasureDocumentTab.ButtonGapBetween + buttonWidth), 0);
			m_buttonScrollRight.Location = point;
			point.Offset(-(MeasureDocumentTab.ButtonGapBetween + buttonWidth), 0);
			m_buttonScrollLeft.Location = point;

			m_buttonDocumentWindowClose.BackColor = m_buttonScrollRight.BackColor	= m_buttonScrollLeft.BackColor = Color.WhiteSmoke;
			m_buttonDocumentWindowClose.ForeColor = m_buttonScrollRight.ForeColor	= m_buttonScrollLeft.ForeColor = SystemColors.GrayText;
			m_buttonDocumentWindowClose.BorderColor = m_buttonScrollRight.BorderColor	= m_buttonScrollLeft.BorderColor = SystemColors.GrayText;

			// Draw the tabs
			Rectangle rectTabOnly = GetTabStripRectangle(true);
			Rectangle rectTab = Rectangle.Empty;
			g.SetClip(rectTabOnly, CombineMode.Replace);
			for (int i=0; i<countOfVisibleContents; i++)
			{
				rectTab = GetTabRectangle(i);
				if (rectTab.IntersectsWith(rectTabOnly))
					DrawTab(g, GetVisibleContent(i), rectTab);
			}

			m_buttonScrollLeft.Enabled = (m_offset < 0);
			m_buttonScrollRight.Enabled = rectTab.Right > rectTabOnly.Right;
			m_buttonDocumentWindowClose.Enabled = ActiveContent.CloseButton;
		}

		private void EnsureTabVisible(DockContent content)
		{
			if (Appearance != DockPaneAppearance.Document)
				return;

			CalculateTabs();

			Rectangle rectTabStrip = GetTabStripRectangle(true);
			Rectangle rectTab = GetTabRectangle(GetIndexOfVisibleContents(content));

			if (rectTab.Right > rectTabStrip.Right)
			{
				m_offset -= rectTab.Right - rectTabStrip.Right;
				rectTab.X -= rectTab.Right - rectTabStrip.Right;
			}

			if (rectTab.Left < rectTabStrip.Left)
				m_offset += rectTabStrip.Left - rectTab.Left;

			Invalidate();
		}

		private HitTestResult GetHitTest()
		{
			return GetHitTest(Control.MousePosition);
		}

		protected HitTestResult GetHitTest(Point ptMouse)
		{
			HitTestResult hitTestResult = new HitTestResult(HitTestArea.None, -1);

			ptMouse = PointToClient(ptMouse);

			Rectangle rectCaption = CaptionRectangle;
			if (rectCaption.Contains(ptMouse))
				return new HitTestResult(HitTestArea.Caption, -1);

			Rectangle rectContent = ContentRectangle;
			if (rectContent.Contains(ptMouse))
				return new HitTestResult(HitTestArea.Content, -1);

			Rectangle rectTabStrip = GetTabStripRectangle(true);
			if (rectTabStrip.Contains(ptMouse))
			{
				for (int i=0; i<CountOfVisibleContents; i++)
				{
					Rectangle rectTab = GetTabRectangle(i);
					rectTab.Intersect(rectTabStrip);
					if (rectTab.Contains(ptMouse))
						return new HitTestResult(HitTestArea.TabStrip, i);
				}
				return new HitTestResult(HitTestArea.TabStrip, -1);
			}

			return new HitTestResult(HitTestArea.None, -1);
		}


		internal int GetIndexOfVisibleContents(DockContent content)
		{
			if (content == null)
				return -1;

			if (content.IsHidden)
				return -1;

			int index = -1;
			foreach (DockContent c in Contents)
			{
				if (!c.IsHidden)
					index++;

				if (c == content)
					return index;
			}
			return -1;
		}

		private int GetTabOriginalWidth(int index)
		{
			if (Appearance == DockPaneAppearance.ToolWindow)
				return GetTabOriginalWidth_ToolWindow(index);
			else
				return GetTabOriginalWidth_Document(index);
		}

		private int GetTabOriginalWidth_ToolWindow(int index)
		{
			DockContent content = GetVisibleContent(index);
			using (Graphics g = CreateGraphics())
			{
				SizeF sizeString = g.MeasureString(content.TabText, Font);
				return MeasureToolWindowTab.ImageWidth + (int)sizeString.Width + 1 + MeasureToolWindowTab.ImageGapLeft
					+ MeasureToolWindowTab.ImageGapRight + MeasureToolWindowTab.TextGapRight;
			}
		}

		private int GetTabOriginalWidth_Document(int index)
		{
			DockContent content = GetVisibleContent(index);

⌨️ 快捷键说明

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