public override void Layout(ViewLayoutContext context)
{
Debug.Assert(context != null);
// We take on all the available display area
ClientRectangle = context.DisplayRectangle;
if (!IgnoreAllBorderAndPadding)
{
// Do we have a metric source for additional padding?
if ((_paletteMetric != null) && (_metricPadding != PaletteMetricPadding.None))
{
// Get the padding to be applied before the canvas drawing
Padding outerPadding = _paletteMetric.GetMetricPadding(State, _metricPadding);
ClientRectangle = CommonHelper.ApplyPadding(Orientation, ClientRectangle, outerPadding);
}
}
// Space available for children begins with our space
Rectangle fillerRect = ClientRectangle;
context.DisplayRectangle = fillerRect;
// By default all the children need to draw all their borders
PaletteDrawBorders leftEdges = PaletteDrawBorders.All;
PaletteDrawBorders rightEdges = PaletteDrawBorders.All;
PaletteDrawBorders topEdges = PaletteDrawBorders.All;
PaletteDrawBorders bottomEdges = PaletteDrawBorders.All;
PaletteDrawBorders fillEdges = PaletteDrawBorders.All;
// Position all except the filler
foreach (ViewBase child in this.Reverse())
{
// Only position visible children
if (child.Visible && (GetDock(child) != ViewDockStyle.Fill))
{
// Prevent children from showing adjacent borders that are not needed
UpdateChildBorders(child, context, ref leftEdges, ref rightEdges,
ref topEdges, ref bottomEdges, ref fillEdges);
// Get the preferred size of the child
Size childSize = child.GetPreferredSize(context);
// Position the child inside the available space
switch (CalculateDock(OrientateDock(GetDock(child)), context.Control))
{
case ViewDockStyle.Top:
context.DisplayRectangle = new Rectangle(fillerRect.X, fillerRect.Y, fillerRect.Width, childSize.Height);
fillerRect.Height -= childSize.Height;
fillerRect.Y += childSize.Height;
break;
case ViewDockStyle.Bottom:
context.DisplayRectangle = new Rectangle(fillerRect.X, fillerRect.Bottom - childSize.Height, fillerRect.Width, childSize.Height);
fillerRect.Height -= childSize.Height;
break;
case ViewDockStyle.Left:
context.DisplayRectangle = new Rectangle(fillerRect.X, fillerRect.Y, childSize.Width, fillerRect.Height);
fillerRect.Width -= childSize.Width;
fillerRect.X += childSize.Width;
break;
case ViewDockStyle.Right:
context.DisplayRectangle = new Rectangle(fillerRect.Right - childSize.Width, fillerRect.Y, childSize.Width, fillerRect.Height);
fillerRect.Width -= childSize.Width;
break;
}
// Layout child in the provided space
child.Layout(context);
}
}
int borderWidth = 0;
Rectangle borderRect = ClientRectangle;
Padding padding = Padding.Empty;
if (!IgnoreAllBorderAndPadding)
{
// Find the actual width of the border as we need to compare this to the calculating border
// padding to work out how far from corners we can ignore the calculated border padding and
// instead use the actual width only.
borderWidth = _paletteBorder.GetBorderWidth(State);
// Update padding to reflect the orientation we are using
padding = context.Renderer.RenderStandardBorder.GetBorderDisplayPadding(_paletteBorder, State, Orientation);
padding = CommonHelper.OrientatePadding(Orientation, padding);
// If docking content extends beyond the border rounding effects then we can adjust
// the padding back so that it lines against the edge and not the rounding edge
padding = AdjustPaddingForDockers(padding, fillerRect, borderWidth);
}
// Apply the padding to the border rectangle
borderRect = new Rectangle(borderRect.X + padding.Left, borderRect.Y + padding.Top,
borderRect.Width - padding.Horizontal, borderRect.Height - padding.Vertical);
// We need to ensure the filler is within the border rectangle
if (fillerRect.X < borderRect.X)
{
fillerRect.Width -= borderRect.X - fillerRect.X;
fillerRect.X = borderRect.X;
}
if (fillerRect.Y < borderRect.Y)
{
fillerRect.Height -= borderRect.Y - fillerRect.Y;
fillerRect.Y = borderRect.Y;
}
if (fillerRect.Right > borderRect.Right)
fillerRect.Width -= fillerRect.Right - borderRect.Right;
if (fillerRect.Bottom > borderRect.Bottom)
fillerRect.Height -= fillerRect.Bottom - borderRect.Bottom;
// Position any filler last
foreach (ViewBase child in this.Reverse())
{
// Only position visible children
if (child.Visible && (GetDock(child) == ViewDockStyle.Fill))
{
// Prevent children from showing adjacent borders that are not needed
UpdateChildBorders(child, context, ref leftEdges, ref rightEdges,
ref topEdges, ref bottomEdges, ref fillEdges);
// Give the filler the remaining space
context.DisplayRectangle = fillerRect;
// Layout child in the provided space
child.Layout(context);
}
}
// Put back the original display value now we have finished
context.DisplayRectangle = ClientRectangle;
// The fill rectangle is the space left over after all children are positioned
_fillRectangle = fillerRect;
}