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(); } } }