public override void Layout(ViewLayoutContext context)
{
Debug.Assert(context != null);
// Validate incoming reference
if (context == null) throw new ArgumentNullException("context");
// Cache the right to left setting at layout time
_rightToLeft = context.Control.RightToLeft;
_rightToLeftLayout = CommonHelper.GetRightToLeftLayout(context.Control);
// We take on all the available display area
ClientRectangle = context.DisplayRectangle;
// Available space for positioning starts with entire client area
Rectangle positionRectangle = ClientRectangle;
// Do we have a metric source for additional padding?
if (_paletteMetrics != null)
{
// Get the padding to be applied
Padding outerPadding = _paletteMetrics.GetMetricPadding(State, _metricPadding);
// Reduce space for children by the padding area
positionRectangle = ApplyPadding(positionRectangle, outerPadding);
}
// Do we need to fill any remainder space?
if (FillSpace)
{
// Ensure the extent reflects the maximum size we want, the whole area
if (_extent.Width < positionRectangle.Width)
_extent.Width = positionRectangle.Width;
if (_extent.Height < positionRectangle.Height)
_extent.Height = positionRectangle.Height;
}
// Find the limits allowed for the offset given current extent and display rect
_limit = new Point(Math.Min(positionRectangle.Width - _extent.Width, 0),
Math.Min(positionRectangle.Height - _extent.Height, 0));
// Enforce the offset back to the limits
if (_offset.X < _limit.X) _offset.X = _limit.X;
if (_offset.Y < _limit.Y) _offset.Y = _limit.Y;
// Calculate the offset given the current alignment and counter alignment
Point childOffset;
int childOffsetX;
int childOffsetY;
// Find the final child offset
if (Horizontal)
{
childOffsetX = CalculateAlignedOffset(AlignmentRTL, positionRectangle.X, positionRectangle.Width, _offset.X, _extent.Width, _limit.X);
childOffsetY = CalculateAlignedOffset(CounterAlignmentRTL, positionRectangle.Y, positionRectangle.Height, _offset.Y, _extent.Height, _limit.Y);
}
else
{
childOffsetX = CalculateAlignedOffset(CounterAlignmentRTL, positionRectangle.X, positionRectangle.Width, _offset.X, _extent.Width, _limit.X);
childOffsetY = CalculateAlignedOffset(AlignmentRTL, positionRectangle.Y, positionRectangle.Height, _offset.Y, _extent.Height, _limit.Y);
}
childOffset = new Point(childOffsetX, childOffsetY);
// Ask each child to layout in turn
foreach (ViewBase child in this)
{
// Only layout visible children
if (child.Visible)
{
// Give the child the available positioning size
context.DisplayRectangle = positionRectangle;
// Ask the child how much space they would like
Size childSize = child.GetPreferredSize(context);
// Do we need to fill any remainder space?
if (FillSpace)
{
// Ensure the child reflect the size we want, the whole area
if (childSize.Width < positionRectangle.Width)
childSize.Width = positionRectangle.Width;
if (childSize.Height < positionRectangle.Height)
childSize.Height = positionRectangle.Height;
}
// Give the child all the space it requires
context.DisplayRectangle = new Rectangle(childOffset, childSize);
// Let the child layout using the provided space
child.Layout(context);
}
}
// Put back the original display value now we have finished
context.DisplayRectangle = ClientRectangle;
}