private Point OffsetForChildRect(Rectangle rect)
{
// Begin by using the current offset
Point offset = _offset;
// Find how far to over position the viewport
int overs = 0;
// We might not be provided with metrics, so only use if reference provided
if (_paletteMetrics != null)
overs = _paletteMetrics.GetMetricInt(State, _metricOvers) + _scrollOvers;
// Move the required rectangle more than exactly into view in order to make it
// easier for users to see extra pages before and after it for easy selection
if ((Orientation == VisualOrientation.Top) ||
(Orientation == VisualOrientation.Bottom))
{
rect.X -= overs;
rect.Width += overs * 2;
}
else
{
rect.Y -= overs;
rect.Height += overs * 2;
}
//If all the children are completely visible then nothing to do
if ((_limit.X != 0) || (_limit.Y != 0))
{
// Is part of the required rectangle not currently visible
if (!ClientRectangle.Contains(rect))
{
// Correct the alignmnet to take right to left into account
RelativePositionAlign alignment = AlignmentRTL;
// Center alignment needs changing to near or far for scrolling
if (alignment == RelativePositionAlign.Center)
alignment = RelativePositionAlign.Near;
// How to scroll into view depends on the alignmnent of items
switch (alignment)
{
case RelativePositionAlign.Near:
if (rect.Right > ClientRectangle.Right) offset.X += (ClientRectangle.Right - rect.Right);
if (rect.Left < ClientRectangle.Left) offset.X += (ClientRectangle.Left - rect.Left);
if (rect.Bottom > ClientRectangle.Bottom) offset.Y += (ClientRectangle.Bottom - rect.Bottom);
if (rect.Top < ClientRectangle.Top) offset.Y += (ClientRectangle.Top - rect.Top);
break;
case RelativePositionAlign.Far:
if (rect.Right > ClientRectangle.Right) offset.X -= (ClientRectangle.Right - rect.Right);
if (rect.Left < ClientRectangle.Left) offset.X -= (ClientRectangle.Left - rect.Left);
if (rect.Bottom > ClientRectangle.Bottom) offset.Y -= (ClientRectangle.Bottom - rect.Bottom);
if (rect.Top < ClientRectangle.Top) offset.Y -= (ClientRectangle.Top - rect.Top);
break;
}
}
}
// Enforce the offset back to the limits
offset.X = Math.Min(Math.Max(offset.X, _limit.X), 0);
offset.Y = Math.Min(Math.Max(offset.Y, _limit.Y), 0);
return offset;
}