using System;
using System.Linq;
namespace Gwen.Control.Layout
{
///
/// Base class for multi-column tables.
///
public class Table : Base
{
// only children of this control should be TableRow.
private bool m_SizeToContents;
private int m_ColumnCount;
private int m_DefaultRowHeight;
private int m_MaxWidth; // for autosizing, if nonzero - fills last cell up to this size
private readonly int[] m_ColumnWidth;
///
/// Column count (default 1).
///
public int ColumnCount { get { return m_ColumnCount; } set { SetColumnCount(value); Invalidate(); } }
///
/// Row count.
///
public int RowCount { get { return Children.Count; } }
///
/// Gets or sets default height for new table rows.
///
public int DefaultRowHeight { get { return m_DefaultRowHeight; } set { m_DefaultRowHeight = value; } }
///
/// Returns specific row of the table.
///
/// Row index.
/// Row at the specified index.
public TableRow this[int index] { get { return Children[index] as TableRow; } }
///
/// Initializes a new instance of the class.
///
/// Parent control.
public Table(Base parent) : base(parent)
{
m_ColumnCount = 1;
m_DefaultRowHeight = 22;
m_ColumnWidth = new int[TableRow.MaxColumns];
for (int i = 0; i < TableRow.MaxColumns; i++)
{
m_ColumnWidth[i] = 20;
}
m_SizeToContents = false;
}
///
/// Sets the number of columns.
///
/// Number of columns.
public void SetColumnCount(int count)
{
if (m_ColumnCount == count) return;
foreach (TableRow row in Children.OfType())
{
row.ColumnCount = count;
}
m_ColumnCount = count;
}
///
/// Sets the column width (in pixels).
///
/// Column index.
/// Column width.
public void SetColumnWidth(int column, int width)
{
if (m_ColumnWidth[column] == width)
return;
m_ColumnWidth[column] = width;
Invalidate();
}
///
/// Gets the column width (in pixels).
///
/// Column index.
/// Column width.
public int GetColumnWidth(int column)
{
return m_ColumnWidth[column];
}
///
/// Adds a new empty row.
///
/// Newly created row.
public TableRow AddRow()
{
TableRow row = new TableRow(this);
row.ColumnCount = m_ColumnCount;
row.Height = m_DefaultRowHeight;
row.Dock = Pos.Top;
return row;
}
///
/// Adds a new row.
///
/// Row to add.
public void AddRow(TableRow row)
{
row.Parent = this;
row.ColumnCount = m_ColumnCount;
row.Height = m_DefaultRowHeight;
row.Dock = Pos.Top;
}
///
/// Adds a new row with specified text in first column.
///
/// Text to add.
/// New row.
public TableRow AddRow(String text)
{
var row = AddRow();
row.SetCellText(0, text);
return row;
}
///
/// Removes a row by reference.
///
/// Row to remove.
public void RemoveRow(TableRow row)
{
RemoveChild(row, true);
}
///
/// Removes a row by index.
///
/// Row index.
public void RemoveRow(int idx)
{
var row = Children[idx];
RemoveRow(row as TableRow);
}
///
/// Removes all rows.
///
public void RemoveAll()
{
while (RowCount > 0)
RemoveRow(0);
}
///
/// Gets the index of a specified row.
///
/// Row to search for.
/// Row index if found, -1 otherwise.
public int GetRowIndex(TableRow row)
{
return Children.IndexOf(row);
}
///
/// Lays out the control's interior according to alignment, padding, dock etc.
///
/// Skin to use.
protected override void Layout(Skin.Base skin)
{
base.Layout(skin);
bool even = false;
foreach (TableRow row in Children)
{
row.EvenRow = even;
even = !even;
for (int i = 0; i < m_ColumnCount; i++)
{
row.SetColumnWidth(i, m_ColumnWidth[i]);
}
}
}
protected override void PostLayout(Skin.Base skin)
{
base.PostLayout(skin);
if (m_SizeToContents)
{
DoSizeToContents();
m_SizeToContents = false;
}
}
///
/// Sizes to fit contents.
///
public void SizeToContents(int maxWidth)
{
m_MaxWidth = maxWidth;
m_SizeToContents = true;
Invalidate();
}
protected void DoSizeToContents()
{
int height = 0;
int width = 0;
foreach (TableRow row in Children)
{
row.SizeToContents(); // now all columns fit but only in this particular row
for (int i = 0; i < ColumnCount; i++)
{
Base cell = row.GetColumn(i);
if (null != cell)
{
if (i < ColumnCount - 1 || m_MaxWidth == 0)
m_ColumnWidth[i] = Math.Max(m_ColumnWidth[i], cell.Width + cell.Margin.Left + cell.Margin.Right);
else
m_ColumnWidth[i] = m_MaxWidth - width; // last cell - fill
}
}
height += row.Height;
}
// sum all column widths
for (int i = 0; i < ColumnCount; i++)
{
width += m_ColumnWidth[i];
}
SetSize(width, height);
//InvalidateParent();
}
}
}