//
// Authors:
// Jonathan Pobst (monkey@jpobst.com)
+// Stefan Noack (noackstefan@googlemail.com)
//
using System;
void LayoutDockedChildren (Control parent, Control[] controls)
{
Rectangle space = parent.DisplayRectangle;
-
+ MdiClient mdi = null;
+
// Deal with docking; go through in reverse, MS docs say that lowest Z-order is closest to edge
for (int i = controls.Length - 1; i >= 0; i--) {
Control child = controls[i];
+ Size child_size = child.Size;
+
+ if (child.AutoSize)
+ child_size = GetPreferredControlSize (child);
if (!child.VisibleInternal
|| child.ControlLayoutType == Control.LayoutType.Anchor)
continue;
+ // MdiClient never fills the whole area like other controls, have to do it later
+ if (child is MdiClient) {
+ mdi = (MdiClient)child;
+ continue;
+ }
+
switch (child.Dock) {
case DockStyle.None:
// Do nothing
break;
case DockStyle.Left:
- child.SetImplicitBounds (space.Left, space.Y, child.Width, space.Height);
+ child.SetBoundsInternal (space.Left, space.Y, child_size.Width, space.Height, BoundsSpecified.None);
space.X += child.Width;
space.Width -= child.Width;
break;
case DockStyle.Top:
- child.SetImplicitBounds (space.Left, space.Y, space.Width, child.Height);
+ child.SetBoundsInternal (space.Left, space.Y, space.Width, child_size.Height, BoundsSpecified.None);
space.Y += child.Height;
space.Height -= child.Height;
break;
case DockStyle.Right:
- child.SetImplicitBounds (space.Right - child.Width, space.Y, child.Width, space.Height);
+ child.SetBoundsInternal (space.Right - child_size.Width, space.Y, child_size.Width, space.Height, BoundsSpecified.None);
space.Width -= child.Width;
break;
case DockStyle.Bottom:
- child.SetImplicitBounds (space.Left, space.Bottom - child.Height, space.Width, child.Height);
+ child.SetBoundsInternal (space.Left, space.Bottom - child_size.Height, space.Width, child_size.Height, BoundsSpecified.None);
space.Height -= child.Height;
break;
case DockStyle.Fill:
- child.SetImplicitBounds (space.Left, space.Top, space.Width, space.Height);
+ child.SetBoundsInternal (space.Left, space.Top, space.Width, space.Height, BoundsSpecified.None);
break;
}
}
+
+ // MdiClient gets whatever space is left
+ if (mdi != null)
+ mdi.SetBoundsInternal (space.Left, space.Top, space.Width, space.Height, BoundsSpecified.None);
}
void LayoutAnchoredChildren (Control parent, Control[] controls)
{
- Rectangle space = parent.DisplayRectangle;
+ Rectangle space = parent.ClientRectangle;
for (int i = 0; i < controls.Length; i++) {
int left;
left = child.Left;
top = child.Top;
-#if NET_2_0
- Size preferredsize = child.PreferredSize;
- width = preferredsize.Width;
- height = preferredsize.Height;
-#else
width = child.Width;
height = child.Height;
-#endif
if ((anchor & AnchorStyles.Right) != 0) {
if ((anchor & AnchorStyles.Left) != 0)
// left+=diff_width/2 will introduce rounding errors (diff_width removed from svn after r51780)
// This calculates from scratch every time:
left = left + (space.Width - (left + width + child.dist_right)) / 2;
+ child.dist_right = space.Width - (left + width);
}
if ((anchor & AnchorStyles.Bottom) != 0) {
// top += diff_height/2 will introduce rounding errors (diff_height removed from after r51780)
// This calculates from scratch every time:
top = top + (space.Height - (top + height + child.dist_bottom)) / 2;
+ child.dist_bottom = space.Height - (top + height);
}
// Sanity
if (height < 0)
height = 0;
- child.SetBounds (left, top, width, height);
+ child.SetBoundsInternal (left, top, width, height, BoundsSpecified.None);
}
}
+
+ void LayoutAutoSizedChildren (Control parent, Control[] controls)
+ {
+ for (int i = 0; i < controls.Length; i++) {
+ int left;
+ int top;
+
+ Control child = controls[i];
+ if (!child.VisibleInternal
+ || child.ControlLayoutType == Control.LayoutType.Dock
+ || !child.AutoSize)
+ continue;
+
+ AnchorStyles anchor = child.Anchor;
+ left = child.Left;
+ top = child.Top;
+
+ Size preferredsize = GetPreferredControlSize (child);
+
+ if (((anchor & AnchorStyles.Left) != 0) || ((anchor & AnchorStyles.Right) == 0))
+ child.dist_right += child.Width - preferredsize.Width;
+ if (((anchor & AnchorStyles.Top) != 0) || ((anchor & AnchorStyles.Bottom) == 0))
+ child.dist_bottom += child.Height - preferredsize.Height;
+
+ child.SetBoundsInternal (left, top, preferredsize.Width, preferredsize.Height, BoundsSpecified.None);
+ }
+ }
+
+ void LayoutAutoSizeContainer (Control container)
+ {
+ int left;
+ int top;
+ int width;
+ int height;
+
+ if (!container.VisibleInternal || container.ControlLayoutType == Control.LayoutType.Dock || !container.AutoSize)
+ return;
+
+ left = container.Left;
+ top = container.Top;
+
+ Size preferredsize = container.PreferredSize;
+
+ if (container.GetAutoSizeMode () == AutoSizeMode.GrowAndShrink) {
+ width = preferredsize.Width;
+ height = preferredsize.Height;
+ } else {
+ width = container.ExplicitBounds.Width;
+ height = container.ExplicitBounds.Height;
+ if (preferredsize.Width > width)
+ width = preferredsize.Width;
+ if (preferredsize.Height > height)
+ height = preferredsize.Height;
+ }
+
+ // Sanity
+ if (width < container.MinimumSize.Width)
+ width = container.MinimumSize.Width;
+
+ if (height < container.MinimumSize.Height)
+ height = container.MinimumSize.Height;
+
+ if (container.MaximumSize.Width != 0 && width > container.MaximumSize.Width)
+ width = container.MaximumSize.Width;
+
+ if (container.MaximumSize.Height != 0 && height > container.MaximumSize.Height)
+ height = container.MaximumSize.Height;
+
+ container.SetBoundsInternal (left, top, width, height, BoundsSpecified.None);
+ }
public override bool Layout (object container, LayoutEventArgs args)
{
LayoutDockedChildren (parent, controls);
LayoutAnchoredChildren (parent, controls);
+ LayoutAutoSizedChildren (parent, controls);
+ if (parent is Form) LayoutAutoSizeContainer (parent);
return false;
}
+
+ private Size GetPreferredControlSize (Control child)
+ {
+ int width;
+ int height;
+ Size preferredsize = child.PreferredSize;
+
+ if (child.GetAutoSizeMode () == AutoSizeMode.GrowAndShrink || (child.Dock != DockStyle.None && !(child is Button))) {
+ width = preferredsize.Width;
+ height = preferredsize.Height;
+ } else {
+ width = child.ExplicitBounds.Width;
+ height = child.ExplicitBounds.Height;
+ if (preferredsize.Width > width)
+ width = preferredsize.Width;
+ if (preferredsize.Height > height)
+ height = preferredsize.Height;
+ }
+
+ // Sanity
+ if (width < child.MinimumSize.Width)
+ width = child.MinimumSize.Width;
+
+ if (height < child.MinimumSize.Height)
+ height = child.MinimumSize.Height;
+
+ if (child.MaximumSize.Width != 0 && width > child.MaximumSize.Width)
+ width = child.MaximumSize.Width;
+
+ if (child.MaximumSize.Height != 0 && height > child.MaximumSize.Height)
+ height = child.MaximumSize.Height;
+
+ return new Size (width, height);
+ }
}
}