Xamarin Public Jenkins (auto-signing) 19234507ba Imported Upstream version 5.14.0.78
Former-commit-id: 3494343bcc9ddb42b36b82dd9ae7b69e85e0229f
2018-05-10 08:37:03 +00:00

529 lines
16 KiB
C#

//
// TableLayoutPanel.cs
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2006 Jonathan Pobst
//
// Authors:
// Jonathan Pobst (monkey@jpobst.com)
//
using System;
using System.Drawing;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms.Layout;
using System.ComponentModel.Design.Serialization;
namespace System.Windows.Forms
{
[ComVisible (true)]
[ClassInterface (ClassInterfaceType.AutoDispatch)]
[ProvideProperty ("CellPosition", typeof (Control))]
[ProvideProperty ("Column", typeof (Control))]
[ProvideProperty ("ColumnSpan", typeof (Control))]
[ProvideProperty ("Row", typeof (Control))]
[ProvideProperty ("RowSpan", typeof (Control))]
[DefaultProperty ("ColumnCount")]
[Docking (DockingBehavior.Never)]
[Designer ("System.Windows.Forms.Design.TableLayoutPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
[DesignerSerializer ("System.Windows.Forms.Design.TableLayoutPanelCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
public class TableLayoutPanel : Panel, IExtenderProvider
{
private TableLayoutSettings settings;
private TableLayoutPanelCellBorderStyle cell_border_style;
// This is the row/column the Control actually got placed
internal IArrangedElement[,] actual_positions;
// Widths and heights of each column/row
internal int[] column_widths;
internal int[] row_heights;
#region Public Constructor
public TableLayoutPanel ()
{
settings = new TableLayoutSettings(this);
cell_border_style = TableLayoutPanelCellBorderStyle.None;
column_widths = new int[0];
row_heights = new int[0];
CreateDockPadding ();
}
#endregion
#region Public Properties
[Localizable (true)]
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
new public BorderStyle BorderStyle {
get { return base.BorderStyle; }
set { base.BorderStyle = value; }
}
[Localizable (true)]
[DefaultValue (TableLayoutPanelCellBorderStyle.None)]
public TableLayoutPanelCellBorderStyle CellBorderStyle {
get { return this.cell_border_style; }
set {
if (this.cell_border_style != value) {
this.cell_border_style = value;
this.PerformLayout (this, "CellBorderStyle");
this.Invalidate ();
}
}
}
[Localizable (true)]
[DefaultValue (0)]
public int ColumnCount {
get { return settings.ColumnCount; }
set { settings.ColumnCount = value; }
}
[Browsable (false)]
[DisplayName ("Columns")]
[MergableProperty (false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TableLayoutColumnStyleCollection ColumnStyles {
get { return settings.ColumnStyles; }
}
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
new public TableLayoutControlCollection Controls {
get { return (TableLayoutControlCollection) base.Controls; }
}
[DefaultValue (TableLayoutPanelGrowStyle.AddRows)]
public TableLayoutPanelGrowStyle GrowStyle {
get { return settings.GrowStyle; }
set { settings.GrowStyle = value; }
}
public override System.Windows.Forms.Layout.LayoutEngine LayoutEngine {
get { return System.Windows.Forms.Layout.TableLayout.Instance; }
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public TableLayoutSettings LayoutSettings {
get { return this.settings; }
set {
if (value.isSerialized) {
this.settings = new TableLayoutSettings(this, value);
// Serialized version doesn't calculate these.
this.settings.ColumnCount = value.ColumnStyles.Count;
this.settings.RowCount = value.RowStyles.Count;
this.PerformLayout();
} else
throw new NotSupportedException ("LayoutSettings value cannot be set directly.");
}
}
[Localizable (true)]
[DefaultValue (0)]
public int RowCount {
get { return settings.RowCount; }
set { settings.RowCount = value; }
}
[Browsable (false)]
[DisplayName ("Rows")]
[MergableProperty (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
public TableLayoutRowStyleCollection RowStyles {
get { return settings.RowStyles; }
}
#endregion
#region Public Methods
[DefaultValue (-1)]
[DisplayName ("Cell")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public TableLayoutPanelCellPosition GetCellPosition (Control control)
{
return settings.GetCellPosition (control);
}
[DisplayName ("Column")]
[DefaultValue (-1)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public int GetColumn (Control control)
{
return settings.GetColumn (control);
}
[DisplayName ("ColumnSpan")]
[DefaultValue (1)]
public int GetColumnSpan (Control control)
{
return settings.GetColumnSpan (control);
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public int[] GetColumnWidths ()
{
return this.column_widths;
}
public Control GetControlFromPosition (int column, int row)
{
if (column < 0 || row < 0)
throw new ArgumentException ();
TableLayoutPanelCellPosition pos = new TableLayoutPanelCellPosition (column, row);
foreach (Control c in this.Controls)
if (settings.GetCellPosition (c) == pos)
return c;
return null;
}
public TableLayoutPanelCellPosition GetPositionFromControl (Control control)
{
for (int x = 0; x < this.actual_positions.GetLength (0); x++)
for (int y = 0; y < this.actual_positions.GetLength (1); y++)
if (this.actual_positions[x, y] == control)
return new TableLayoutPanelCellPosition (x, y);
return new TableLayoutPanelCellPosition (-1, -1);
}
[DisplayName ("Row")]
[DefaultValue ("-1")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public int GetRow (Control control)
{
return settings.GetRow (control);
}
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
public int[] GetRowHeights ()
{
return this.row_heights;
}
[DisplayName ("RowSpan")]
[DefaultValue (1)]
public int GetRowSpan (Control control)
{
return settings.GetRowSpan (control);
}
public void SetCellPosition (Control control, TableLayoutPanelCellPosition position)
{
settings.SetCellPosition (control, position);
}
public void SetColumn (Control control, int column)
{
settings.SetColumn (control, column);
}
public void SetColumnSpan (Control control, int value)
{
settings.SetColumnSpan (control, value);
}
public void SetRow (Control control, int row)
{
settings.SetRow (control, row);
}
public void SetRowSpan (Control control, int value)
{
settings.SetRowSpan (control, value);
}
#endregion
#region Protected Methods
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected override ControlCollection CreateControlsInstance ()
{
return new TableLayoutControlCollection (this);
}
protected virtual void OnCellPaint (TableLayoutCellPaintEventArgs e)
{
TableLayoutCellPaintEventHandler eh = (TableLayoutCellPaintEventHandler)(Events [CellPaintEvent]);
if (eh != null)
eh (this, e);
}
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected override void OnLayout (LayoutEventArgs levent)
{
base.OnLayout (levent);
Invalidate ();
}
protected override void OnPaintBackground (PaintEventArgs e)
{
base.OnPaintBackground (e);
DrawCellBorders (e);
int border_width = GetCellBorderWidth (CellBorderStyle);
int x = border_width;
int y = border_width;
for (int i = 0; i < column_widths.Length; i++) {
for (int j = 0; j < row_heights.Length; j++) {
this.OnCellPaint (new TableLayoutCellPaintEventArgs (e.Graphics, e.ClipRectangle, new Rectangle (x, y, column_widths[i] + border_width, row_heights[j] + border_width), i, j));
y += row_heights[j] + border_width;
}
x += column_widths[i] + border_width;
y = border_width;
}
}
protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
{
base.ScaleControl (factor, specified);
}
[EditorBrowsable (EditorBrowsableState.Never)]
protected override void ScaleCore (float dx, float dy)
{
base.ScaleCore (dx, dy);
}
#endregion
#region Internal Methods
internal static int GetCellBorderWidth (TableLayoutPanelCellBorderStyle style)
{
switch (style) {
case TableLayoutPanelCellBorderStyle.Single:
return 1;
case TableLayoutPanelCellBorderStyle.Inset:
case TableLayoutPanelCellBorderStyle.Outset:
return 2;
case TableLayoutPanelCellBorderStyle.InsetDouble:
case TableLayoutPanelCellBorderStyle.OutsetPartial:
case TableLayoutPanelCellBorderStyle.OutsetDouble:
return 3;
}
return 0;
}
private void DrawCellBorders (PaintEventArgs e)
{
Rectangle paint_here = new Rectangle (Point.Empty, this.Size);
switch (CellBorderStyle) {
case TableLayoutPanelCellBorderStyle.Single:
DrawSingleBorder (e.Graphics, paint_here);
break;
case TableLayoutPanelCellBorderStyle.Inset:
DrawInsetBorder (e.Graphics, paint_here);
break;
case TableLayoutPanelCellBorderStyle.InsetDouble:
DrawInsetDoubleBorder (e.Graphics, paint_here);
break;
case TableLayoutPanelCellBorderStyle.Outset:
DrawOutsetBorder (e.Graphics, paint_here);
break;
case TableLayoutPanelCellBorderStyle.OutsetDouble:
case TableLayoutPanelCellBorderStyle.OutsetPartial:
DrawOutsetDoubleBorder (e.Graphics, paint_here);
break;
}
}
private void DrawSingleBorder (Graphics g, Rectangle rect)
{
ControlPaint.DrawBorder (g, rect, SystemColors.ControlDark, ButtonBorderStyle.Solid);
int x = DisplayRectangle.X;
int y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 1;
g.DrawLine (SystemPens.ControlDark, new Point (x, 1), new Point (x, Bottom - 2));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 1;
g.DrawLine (SystemPens.ControlDark, new Point (1, y), new Point (Right - 2, y));
}
}
private void DrawInsetBorder (Graphics g, Rectangle rect)
{
ControlPaint.DrawBorder3D (g, rect, Border3DStyle.Etched);
int x = DisplayRectangle.X;
int y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 2;
g.DrawLine (SystemPens.ControlDark, new Point (x, 1), new Point (x, Bottom - 3));
g.DrawLine (Pens.White, new Point (x + 1, 1), new Point (x + 1, Bottom - 3));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 2;
g.DrawLine (SystemPens.ControlDark, new Point (1, y), new Point (Right - 3, y));
g.DrawLine (Pens.White, new Point (1, y + 1), new Point (Right - 3, y + 1));
}
}
private void DrawOutsetBorder (Graphics g, Rectangle rect)
{
g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left + 1, rect.Top + 1, rect.Width - 2, rect.Height - 2));
g.DrawRectangle (Pens.White, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
int x = DisplayRectangle.X;
int y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 2;
g.DrawLine (Pens.White, new Point (x, 1), new Point (x, Bottom - 3));
g.DrawLine (SystemPens.ControlDark, new Point (x + 1, 1), new Point (x + 1, Bottom - 3));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 2;
g.DrawLine (Pens.White, new Point (1, y), new Point (Right - 3, y));
g.DrawLine (SystemPens.ControlDark, new Point (1, y + 1), new Point (Right - 3, y + 1));
}
}
private void DrawOutsetDoubleBorder (Graphics g, Rectangle rect)
{
rect.Width -= 1;
rect.Height -= 1;
g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left + 2, rect.Top + 2, rect.Width - 2, rect.Height - 2));
g.DrawRectangle (Pens.White, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
int x = DisplayRectangle.X;
int y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 3;
g.DrawLine (Pens.White, new Point (x, 3), new Point (x, Bottom - 5));
g.DrawLine (SystemPens.ControlDark, new Point (x + 2, 3), new Point (x + 2, Bottom - 5));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 3;
g.DrawLine (Pens.White, new Point (3, y), new Point (Right - 4, y));
g.DrawLine (SystemPens.ControlDark, new Point (3, y + 2), new Point (Right - 4, y + 2));
}
x = DisplayRectangle.X;
y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 3;
g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (x + 1, 3), new Point (x + 1, Bottom - 5));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 3;
g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (3, y + 1), new Point (Right - 4, y + 1));
}
}
private void DrawInsetDoubleBorder (Graphics g, Rectangle rect)
{
rect.Width -= 1;
rect.Height -= 1;
g.DrawRectangle (Pens.White, new Rectangle (rect.Left + 2, rect.Top + 2, rect.Width - 2, rect.Height - 2));
g.DrawRectangle (SystemPens.ControlDark, new Rectangle (rect.Left, rect.Top, rect.Width - 2, rect.Height - 2));
int x = DisplayRectangle.X;
int y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 3;
g.DrawLine (SystemPens.ControlDark, new Point (x, 3), new Point (x, Bottom - 5));
g.DrawLine (Pens.White, new Point (x + 2, 3), new Point (x + 2, Bottom - 5));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 3;
g.DrawLine (SystemPens.ControlDark, new Point (3, y), new Point (Right - 4, y));
g.DrawLine (Pens.White, new Point (3, y + 2), new Point (Right - 4, y + 2));
}
x = DisplayRectangle.X;
y = DisplayRectangle.Y;
for (int i = 0; i < column_widths.Length - 1; i++) {
x += column_widths[i] + 3;
g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (x + 1, 3), new Point (x + 1, Bottom - 5));
}
for (int j = 0; j < row_heights.Length - 1; j++) {
y += row_heights[j] + 3;
g.DrawLine (ThemeEngine.Current.ResPool.GetPen (BackColor), new Point (3, y + 1), new Point (Right - 4, y + 1));
}
}
#endregion
#region Public Events
static object CellPaintEvent = new object ();
public event TableLayoutCellPaintEventHandler CellPaint {
add { Events.AddHandler (CellPaintEvent, value); }
remove { Events.RemoveHandler (CellPaintEvent, value); }
}
#endregion
#region IExtenderProvider
bool IExtenderProvider.CanExtend (object obj)
{
if (obj is Control)
if ((obj as Control).Parent == this)
return true;
return false;
}
#endregion
}
}