This commit is contained in:
Lluis Sanchez Gual 2011-12-14 13:11:34 +01:00
Родитель 033231d8bd
Коммит ab3c759c7b
8 изменённых файлов: 661 добавлений и 89 удалений

Просмотреть файл

@ -59,6 +59,7 @@ namespace Samples
AddSample (null, "List View", typeof(ListView1));
AddSample (null, "Notebook", typeof(NotebookSample));
// AddSample (null, "Scroll View", typeof(ScrollWindowSample));
AddSample (null, "Tables", typeof(Tables));
AddSample (null, "Text Entry", typeof(TextEntries));
AddSample (null, "Windows", typeof(Windows));

Просмотреть файл

@ -61,6 +61,7 @@
<Compile Include="Samples\TextEntries.cs" />
<Compile Include="Samples\Images.cs" />
<Compile Include="Samples\CanvasWithWidget.cs" />
<Compile Include="Samples\Tables.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Просмотреть файл

@ -55,7 +55,7 @@ namespace Samples
class SimpleBox: Canvas
{
double coreSize;
Size coreSize;
double margin = 1;
public Color Color { get; set; }
@ -63,10 +63,17 @@ namespace Samples
public SimpleBox (double coreSize)
{
Color = new Color (0.5, 0.5, 1);
this.coreSize = coreSize;
this.coreSize = new Size (coreSize, coreSize);
MinSize = new Size (coreSize + margin * 2, coreSize + margin * 2);
}
public SimpleBox (double coreWidth, double coreHeight)
{
Color = new Color (0.5, 0.5, 1);
this.coreSize = new Size (coreWidth, coreHeight);
MinSize = new Size (coreSize.Width + margin * 2, coreSize.Height + margin * 2);
}
protected override void OnDraw (Context ctx)
{
ctx.SetColor (new Color (0.5, 0.5, 0.5));
@ -76,7 +83,7 @@ namespace Samples
ctx.Rectangle (Bounds.Inflate (-margin, -margin));
ctx.Fill ();
ctx.SetColor (Color);
ctx.Rectangle (Bounds.Width / 2 - coreSize / 2, Bounds.Height / 2 - coreSize / 2, coreSize, coreSize);
ctx.Rectangle (Bounds.Width / 2 - coreSize.Width / 2, Bounds.Height / 2 - coreSize.Height / 2, coreSize.Width, coreSize.Height);
ctx.Fill ();
}
}

70
Samples/Samples/Tables.cs Normal file
Просмотреть файл

@ -0,0 +1,70 @@
//
// Tables.cs
//
// Author:
// Lluis Sanchez Gual <lluis@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// 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.
using System;
using Xwt;
namespace Samples
{
public class Tables: VBox
{
public Tables ()
{
Table t = new Table ();
SimpleBox b = new SimpleBox (200, 20);
t.Attach (b, 0, 1, 0, 1);
b = new SimpleBox (10, 20);
t.Attach (b, 1, 2, 0, 1);
b = new SimpleBox (500, 20);
t.Attach (b, 0, 2, 1, 2, AttachOptions.Expand, AttachOptions.Expand);
b = new SimpleBox (600, 20);
t.Attach (b, 1, 3, 2, 3);
b = new SimpleBox (200, 20);
t.Attach (b, 2, 3, 3, 4);
b = new SimpleBox (900, 20);
t.Attach (b, 0, 3, 4, 5);
PackStart (t);
HBox box = new HBox ();
PackStart (box);
t = new Table ();
t.Attach (new Label ("One:"), 0, 1, 0, 1);
t.Attach (new TextEntry (), 1, 2, 0, 1);
t.Attach (new Label ("Two:"), 0, 1, 1, 2);
t.Attach (new TextEntry (), 1, 2, 1, 2);
t.Attach (new Label ("Three:"), 0, 1, 2, 3);
t.Attach (new TextEntry (), 1, 2, 2, 3);
box.PackStart (t);
}
}
}

Просмотреть файл

@ -62,6 +62,7 @@ namespace Xwt.GtkBackend
WidgetRegistry.RegisterBackend (typeof(Xwt.ToggleButton), typeof(ToggleButtonBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.ImageView), typeof(ImageViewBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.Backends.IAlertDialogBackend), typeof(AlertDialogBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.Table), typeof(BoxBackend));
}
public override void RunApplication ()

Просмотреть файл

@ -69,6 +69,7 @@ namespace Xwt.Mac
WidgetRegistry.RegisterBackend (typeof(Xwt.ComboBox), typeof(ComboBoxBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.TextEntry), typeof(TextEntryBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.ImageView), typeof(ImageViewBackend));
WidgetRegistry.RegisterBackend (typeof(Xwt.Table), typeof(BoxBackend));
}
public override void RunApplication ()

Просмотреть файл

@ -234,12 +234,12 @@ namespace Xwt
protected override WidgetSize OnGetPreferredWidth ()
{
return new WidgetSize (minSize.Width, naturalSize.Width);
return new WidgetSize (minSize.Width);
}
protected override WidgetSize OnGetPreferredHeight ()
{
return new WidgetSize (minSize.Height, naturalSize.Width);
return new WidgetSize (minSize.Height);
}
protected override WidgetSize OnGetPreferredHeightForWidth (double width)

Просмотреть файл

@ -25,146 +25,637 @@
// THE SOFTWARE.
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using Xwt.Backends;
using System.Windows.Markup;
namespace Xwt
{
public class Table
public class Table: Widget
{
/* new ITableBackend Backend {
get { return (ITableBackend) base.Backend; }
ChildrenCollection<TablePlacement> children;
double defaultRowSpacing = 6;
double defaultColSpacing = 6;
Dictionary<int,double> rowSpacing;
Dictionary<int,double> colSpacing;
protected new class EventSink: Widget.EventSink, ICollectionEventSink<TablePlacement>, IContainerEventSink<TablePlacement>
{
public void AddedItem (TablePlacement item, int index)
{
((Table)Parent).OnAdd (item.Child, item);
}
public void RemovedItem (TablePlacement item, int index)
{
((Table)Parent).OnRemove (item.Child);
}
public void ChildChanged (TablePlacement child, string hint)
{
((Table)Parent).OnChildChanged (child, hint);
}
public void ChildReplaced (TablePlacement child, Widget oldWidget, Widget newWidget)
{
((Table)Parent).OnReplaceChild (child, oldWidget, newWidget);
}
}
protected override Widget.EventSink CreateEventSink ()
{
return new EventSink ();
}
new IBoxBackend Backend {
get { return (IBoxBackend) base.Backend; }
}
public Table ()
{
children = new ChildrenCollection<TablePlacement> ((EventSink)WidgetEventSink);
}
public void Attach (Widget w, int left, int right, int top, int bottom)
{
TablePlacement p = new TablePlacement (w);
p.LeftAttach = left;
p.RightAttach = right;
p.TopAttach = top;
p.BottomAttach = bottom;
OnAdd (w, p);
[DefaultValue(6)]
public double DefaultRowSpacing {
get { return defaultRowSpacing; }
set { defaultRowSpacing = value; OnPreferredSizeChanged (); }
}
protected override void OnAdd (Widget child, ChildPlacement placement)
[DefaultValue(6)]
public double DefaultColumnSpacing {
get { return defaultColSpacing; }
set { defaultColSpacing = value; OnPreferredSizeChanged (); }
}
public void SetRowSpacing (int row, double spacing)
{
if (placement == null)
placement = new TablePlacement (child);
if (rowSpacing == null)
rowSpacing = new Dictionary<int, double> ();
rowSpacing [row] = spacing;
OnPreferredSizeChanged ();
}
public void SetColumnSpacing (int col, double spacing)
{
if (colSpacing == null)
colSpacing = new Dictionary<int, double> ();
colSpacing [col] = spacing;
OnPreferredSizeChanged ();
}
public ChildrenCollection<TablePlacement> Placements {
get { return children; }
}
public IEnumerable<Widget> Children {
get { return children.Select (c => c.Child); }
}
public void Attach (Widget widget, int left, int right, int top, int bottom)
{
Attach (widget, left, right, top, bottom, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Fill | AttachOptions.Expand);
}
public void Attach (Widget widget, int left, int right, int top, int bottom, AttachOptions xOptions, AttachOptions yOptions)
{
var p = new TablePlacement ((EventSink)WidgetEventSink, widget) {
Left = left,
Right = right,
Top = top,
Bottom = bottom,
XOptions = xOptions,
YOptions = yOptions
};
children.Add (p);
}
public bool Remove (Widget widget)
{
for (int n=0; n<children.Count; n++) {
if (children[n].Child == widget) {
children.RemoveAt (n);
return true;
}
}
return false;
}
/// <summary>
/// Removes all children
/// </summary>
public void Clear ()
{
children.Clear ();
}
void OnAdd (Widget child, TablePlacement placement)
{
RegisterChild (child);
Backend.Add ((IWidgetBackend)GetBackend (child));
OnPreferredSizeChanged ();
}
void OnRemove (Widget child)
{
UnregisterChild (child);
Backend.Remove ((IWidgetBackend)GetBackend (child));
OnPreferredSizeChanged ();
}
void OnChildChanged (TablePlacement placement, object hint)
{
OnPreferredSizeChanged ();
}
internal protected virtual void OnReplaceChild (TablePlacement placement, Widget oldWidget, Widget newWidget)
{
if (oldWidget != null)
OnRemove (oldWidget);
OnAdd (newWidget, placement);
}
protected override void OnReallocate ()
{
var size = Backend.Size;
var mode = ((IWidgetSurface)this).SizeRequestMode;
if (mode == SizeRequestMode.HeightForWidth) {
CalcDefaultSizes (mode, size.Width, false, true);
CalcDefaultSizes (mode, size.Height, true, true);
} else {
CalcDefaultSizes (mode, size.Height, true, true);
CalcDefaultSizes (mode, size.Width, false, true);
}
foreach (var bp in children) {
if (!bp.Child.Visible)
continue;
Backend.SetAllocation ((IWidgetBackend)GetBackend (bp.Child), new Rectangle (bp.NextX, bp.NextY, bp.NextWidth, bp.NextHeight));
((IWidgetSurface)bp.Child).Reallocate ();
}
}
double GetSpacing (int cell, bool isRow)
{
double sp;
if (isRow) {
if (rowSpacing != null && rowSpacing.TryGetValue (cell, out sp))
return sp;
else
return defaultRowSpacing;
} else {
if (colSpacing != null && colSpacing.TryGetValue (cell, out sp))
return sp;
else
return defaultColSpacing;
}
}
void CalcDefaultSizes (SizeRequestMode mode, bool calcHeights, out TablePlacement[] visibleChildren, out Dictionary<int,WidgetSize> fixedSizesByCell, out HashSet<int> cellsWithExpand, out WidgetSize[] sizes, out double spacing)
{
bool useLengthConstraint = mode == SizeRequestMode.HeightForWidth && calcHeights || mode == SizeRequestMode.WidthForHeight && !calcHeights;
visibleChildren = children.Where (b => b.Child.Visible).ToArray ();
int lastCell = 0;
base.OnAdd (child, placement);
Backend.Attach ((IWidgetBackend)GetBackend (child), (TablePlacement) placement);
fixedSizesByCell = new Dictionary<int, WidgetSize> ();
cellsWithExpand = new HashSet<int> ();
HashSet<int> cellsWithWidget = new HashSet<int> ();
sizes = new WidgetSize [visibleChildren.Length];
// Get the size of each widget and store the fixed sizes for widget which don't span more than one cell
for (int n=0; n<visibleChildren.Length; n++) {
var bp = visibleChildren[n];
int start = GetStartAttach (bp, calcHeights);
int end = GetEndAttach (bp, calcHeights);
if (end > lastCell)
lastCell = end;
// Check if the cell is expandable and store the value
AttachOptions ops = calcHeights ? bp.YOptions : bp.XOptions;
for (int i=start; i < end; i++) {
cellsWithWidget.Add (i);
if ((ops & AttachOptions.Expand) != 0)
cellsWithExpand.Add (i);
}
WidgetSize s;
if (useLengthConstraint)
s = GetPreferredLengthForSize (mode, bp.Child, calcHeights ? bp.NextWidth : bp.NextHeight);
else
s = GetPreferredSize (calcHeights, bp.Child);
sizes [n] = s;
if (end == start + 1) {
bool changed = false;
WidgetSize fs;
fixedSizesByCell.TryGetValue (start, out fs);
if (s.MinSize > fs.MinSize) {
fs.MinSize = s.MinSize;
changed = true;
}
if (s.NaturalSize > fs.NaturalSize) {
fs.NaturalSize = s.NaturalSize;
changed = true;
}
if (changed)
fixedSizesByCell [start] = fs;
}
}
// For widgets that span more than one cell, calculate the floating size, that is, the size
// which is not taken by other fixed size widgets
List<TablePlacement> widgetsToAdjust = new List<TablePlacement> ();
Dictionary<TablePlacement,WidgetSize[]> growSizes = new Dictionary<TablePlacement, WidgetSize[]> ();
for (int n=0; n<visibleChildren.Length; n++) {
var bp = visibleChildren[n];
int start = GetStartAttach (bp, calcHeights);
int end = GetEndAttach (bp, calcHeights);
if (end == start + 1)
continue;
widgetsToAdjust.Add (bp);
WidgetSize fixedSize = new WidgetSize (0);
// We are going to calculate the spacing included in the widget's span of cells
// (there is spacing between each cell)
double spanSpacing = 0;
for (int c = start; c < end; c++) {
WidgetSize fs;
fixedSizesByCell.TryGetValue (c, out fs);
fixedSize += fs;
if (c != start && c != end)
spanSpacing += GetSpacing (c, calcHeights);
}
// sizeToGrow is the size that the whole cell span has to grow in order to fit
// this widget. We substract the spacing between cells because that space will
// be used by the widget, so we don't need to allocate more size for it
WidgetSize sizeToGrow = sizes [n] - fixedSize - new WidgetSize (spanSpacing);
WidgetSize sizeToGrowPart = new WidgetSize (sizeToGrow.MinSize / (end - start), sizeToGrow.NaturalSize / (end - start));
WidgetSize[] widgetGrowSizes = new WidgetSize [end - start];
for (int i=0; i<widgetGrowSizes.Length; i++)
widgetGrowSizes [i] = sizeToGrowPart;
growSizes[bp] = widgetGrowSizes;
}
foreach (var n in cellsWithWidget) {
var colCells = widgetsToAdjust.Where (bp => GetStartAttach (bp, calcHeights) <= n && GetEndAttach (bp, calcHeights) > n).ToArray ();
WidgetSize maxv = new WidgetSize (0);
TablePlacement maxtMin = null;
TablePlacement maxtNatural = null;
foreach (var bp in colCells) {
WidgetSize cv = growSizes[bp][n - GetStartAttach (bp, calcHeights)];
if (cv.MinSize > maxv.MinSize) {
maxv.MinSize = cv.MinSize;
maxtMin = bp;
}
if (cv.NaturalSize > maxv.NaturalSize) {
maxv.NaturalSize = cv.NaturalSize;
maxtNatural = bp;
}
}
foreach (var bp in colCells) {
WidgetSize[] widgetGrows = growSizes[bp];
int cellIndex = n - GetStartAttach (bp, calcHeights);
if (bp != maxtMin) {
double cv = widgetGrows[cellIndex].MinSize;
double splitExtraSpace = (maxv.MinSize - cv) / (widgetGrows.Length - 1);
for (int i=0; i<widgetGrows.Length; i++)
widgetGrows[i].MinSize -= splitExtraSpace;
}
if (bp != maxtNatural) {
double cv = widgetGrows[cellIndex].NaturalSize;
double splitExtraSpace = (maxv.NaturalSize - cv) / (widgetGrows.Length - 1);
for (int i=0; i<widgetGrows.Length; i++)
widgetGrows[i].NaturalSize -= splitExtraSpace;
}
}
}
Dictionary<int,WidgetSize> finalGrowTable = new Dictionary<int, WidgetSize> ();
foreach (var bp in widgetsToAdjust) {
int start = GetStartAttach (bp, calcHeights);
int end = GetEndAttach (bp, calcHeights);
WidgetSize[] widgetGrows = growSizes[bp];
for (int n=start; n<end; n++) {
WidgetSize curGrow;
finalGrowTable.TryGetValue (n, out curGrow);
var val = widgetGrows [n - start];
if (val.MinSize > curGrow.MinSize)
curGrow.MinSize = val.MinSize;
if (val.NaturalSize > curGrow.NaturalSize)
curGrow.NaturalSize = val.NaturalSize;
finalGrowTable [n] = curGrow;
}
}
foreach (var it in finalGrowTable) {
WidgetSize ws;
fixedSizesByCell.TryGetValue (it.Key, out ws);
fixedSizesByCell [it.Key] = it.Value + ws;
}
spacing = 0;
for (int n=1; n<lastCell; n++)
spacing += GetSpacing (n, calcHeights);
}
internal protected override void OnChildChanged (ChildPlacement placement, object hint)
void CalcDefaultSizes (SizeRequestMode mode, double totalSize, bool calcHeights, bool calcOffsets)
{
Backend.Update ((IWidgetBackend)GetBackend (placement.Child), (TablePlacement) placement, (TablePlacementChange) hint);
}*/
TablePlacement[] visibleChildren;
Dictionary<int,WidgetSize> fixedSizesByCell;
HashSet<int> cellsWithExpand;
WidgetSize[] sizes;
double spacing;
CalcDefaultSizes (mode, calcHeights, out visibleChildren, out fixedSizesByCell, out cellsWithExpand, out sizes, out spacing);
double naturalSize = 0;
// Get the total natural size
foreach (var ws in fixedSizesByCell.Values)
naturalSize += ws.NaturalSize;
double remaining = totalSize - naturalSize - spacing;
if (remaining < 0) {
// The box is not big enough to fit the widgets using its natural size.
// We have to shrink the cells
// List of cell indexes that we have to shrink
var toShrink = new List<int> (fixedSizesByCell.Keys);
// The total amount we have to shrink
double shrinkSize = -remaining;
while (toShrink.Count > 0 && shrinkSize > 0) {
SizeSplitter sizePart = new SizeSplitter (shrinkSize, toShrink.Count);
shrinkSize = 0;
for (int i=0; i < toShrink.Count; i++) {
int n = toShrink[i];
double reduction = sizePart.NextSizePart ();
WidgetSize size;
fixedSizesByCell.TryGetValue (n, out size);
size.NaturalSize -= reduction;
if (size.NaturalSize < size.MinSize) {
// If the widget can't be shrinked anymore, we remove it from the shrink list
// and increment the remaining shrink size. We'll loop again and this size will be
// substracted from the cells which can still be reduced
shrinkSize += (size.MinSize - size.NaturalSize);
size.NaturalSize = size.MinSize;
toShrink.RemoveAt (i);
i--;
}
fixedSizesByCell [n] = size;
}
}
}
else {
int nexpands = cellsWithExpand.Count;
var expandRemaining = new SizeSplitter (remaining, nexpands);
foreach (var c in cellsWithExpand) {
WidgetSize ws;
fixedSizesByCell.TryGetValue (c, out ws);
ws.NaturalSize += expandRemaining.NextSizePart ();
fixedSizesByCell [c] = ws;
}
}
for (int n=0; n<visibleChildren.Length; n++) {
var bp = visibleChildren[n];
double allocatedSize = 0;
double cellOffset = 0;
AttachOptions ops = calcHeights ? bp.YOptions : bp.XOptions;
int start = GetStartAttach (bp, calcHeights);
int end = GetEndAttach (bp, calcHeights);
for (int i=start; i<end; i++) {
WidgetSize ws;
fixedSizesByCell.TryGetValue (i, out ws);
allocatedSize += ws.NaturalSize;
if (i != start)
allocatedSize += GetSpacing (i, calcHeights);
}
if ((ops & AttachOptions.Fill) == 0) {
double s = sizes[n].NaturalSize;
if (s < allocatedSize) {
cellOffset = (allocatedSize - s) / 2;
allocatedSize = s;
}
}
// cellOffset is the offset of the widget inside the cell. We store it in NextX/Y, and
// will be used below to calculate the total offset of the widget
if (calcHeights) {
bp.NextHeight = allocatedSize;
bp.NextY = cellOffset;
}
else {
bp.NextWidth = allocatedSize;
bp.NextX = cellOffset;
}
}
if (calcOffsets) {
var sortedChildren = visibleChildren.OrderBy (c => GetStartAttach (c, calcHeights)).ToArray();
var cells = fixedSizesByCell.OrderBy (c => c.Key);
double offset = 0;
int n = 0;
foreach (var c in cells) {
if (c.Key > 0)
offset += GetSpacing (c.Key, calcHeights);
while (n < sortedChildren.Length && GetStartAttach (sortedChildren[n], calcHeights) == c.Key) {
// In the loop above we store the offset of the widget inside the cell in the NextX/Y field
// so now we have to add (not just assign) the offset of the cell to NextX/Y
if (calcHeights)
sortedChildren[n].NextY += offset;
else
sortedChildren[n].NextX += offset;
n++;
}
offset += c.Value.NaturalSize;
}
}
}
WidgetSize CalcSize (bool calcHeights)
{
TablePlacement[] visibleChildren;
Dictionary<int,WidgetSize> fixedSizesByCell;
HashSet<int> cellsWithExpand;
WidgetSize[] sizes;
double spacing;
SizeRequestMode mode = calcHeights ? SizeRequestMode.WidthForHeight : SizeRequestMode.HeightForWidth;
CalcDefaultSizes (mode, calcHeights, out visibleChildren, out fixedSizesByCell, out cellsWithExpand, out sizes, out spacing);
WidgetSize size = new WidgetSize (spacing);
foreach (var s in fixedSizesByCell.Values)
size += s;
return size;
}
protected override WidgetSize OnGetPreferredWidth ()
{
return CalcSize (false);
}
protected override WidgetSize OnGetPreferredHeight ()
{
return CalcSize (true);
}
protected override WidgetSize OnGetPreferredHeightForWidth (double width)
{
CalcDefaultSizes (SizeRequestMode.HeightForWidth, width, false, false);
return CalcSize (true);
}
protected override WidgetSize OnGetPreferredWidthForHeight (double height)
{
CalcDefaultSizes (SizeRequestMode.WidthForHeight, height, true, false);
return CalcSize (false);
}
int GetStartAttach (TablePlacement tp, bool calcHeight)
{
if (calcHeight)
return tp.Top;
else
return tp.Left;
}
int GetEndAttach (TablePlacement tp, bool calcHeight)
{
if (calcHeight)
return tp.Bottom;
else
return tp.Right;
}
WidgetSize GetPreferredSize (bool calcHeight, Widget w)
{
if (calcHeight)
return ((IWidgetSurface)w).GetPreferredHeight ();
else
return ((IWidgetSurface)w).GetPreferredWidth ();
}
WidgetSize GetPreferredLengthForSize (SizeRequestMode mode, Widget w, double width)
{
IWidgetSurface surface = w;
if (mode == SizeRequestMode.WidthForHeight)
return surface.GetPreferredWidthForHeight (width);
else
return surface.GetPreferredHeightForWidth (width);
}
}
/* public class TablePlacement: ChildPlacement
[ContentProperty("Child")]
public class TablePlacement
{
int leftAttach;
int rightAttach;
int topAttach;
int bottomAttach;
AttachOptions xOptions = AttachOptions.Fill;
AttachOptions yOptions = AttachOptions.Fill;
int xPadding;
int yPadding;
IContainerEventSink<TablePlacement> parent;
int left, right, top, bottom;
AttachOptions xOptions, yOptions;
Widget child;
internal TablePlacement (Widget child): base (child)
internal TablePlacement (IContainerEventSink<TablePlacement> parent, Widget child)
{
this.parent = parent;
this.child = child;
}
public int LeftAttach {
internal double NextWidth;
internal double NextHeight;
internal double NextX;
internal double NextY;
public int Left {
get {
return this.leftAttach;
return left;
}
set {
leftAttach = value;
NotifyChanged (TablePlacementChange.LeftAttach);
left = value;
parent.ChildChanged (this, "Left");
}
}
public int RightAttach {
public int Right {
get {
return this.rightAttach;
return right;
}
set {
rightAttach = value;
NotifyChanged (TablePlacementChange.RightAttach);
right = value;
parent.ChildChanged (this, "Right");
}
}
public int TopAttach {
public int Top {
get {
return this.topAttach;
return top;
}
set {
topAttach = value;
NotifyChanged (TablePlacementChange.TopAttach);
top = value;
parent.ChildChanged (this, "Top");
}
}
public int BottomAttach {
public int Bottom {
get {
return this.bottomAttach;
return bottom;
}
set {
bottomAttach = value;
NotifyChanged (TablePlacementChange.BottomAttach);
bottom = value;
parent.ChildChanged (this, "Bottom");
}
}
public Widget Child {
get { return child; }
set {
var old = child;
child = value;
parent.ChildReplaced (this, old, value);
}
}
public AttachOptions XOptions {
get {
return this.xOptions;
}
get { return xOptions; }
set {
xOptions = value;
NotifyChanged (TablePlacementChange.XOptions);
xOptions = value;
parent.ChildChanged (this, "XOptions");
}
}
public AttachOptions YOptions {
get {
return this.yOptions;
}
get { return yOptions; }
set {
yOptions = value;
NotifyChanged (TablePlacementChange.YOptions);
}
}
public int XPadding {
get {
return this.xPadding;
}
set {
xPadding = value;
NotifyChanged (TablePlacementChange.XPadding);
}
}
public int YPadding {
get {
return this.yPadding;
}
set {
yPadding = value;
NotifyChanged (TablePlacementChange.YPadding);
yOptions = value;
parent.ChildChanged (this, "YOptions");
}
}
}
[Flags]
public enum AttachOptions
{
Shrink,
Expand,
Fill
}*/
Expand = 1,
Fill = 2,
Shrink = 4
}
}