X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms.Layout%2FDefaultLayout.cs;h=35bb2be338ecade98e65e742028a8c575c10cf6d;hb=0d732b13a081cab85efa3695f158c1164524a48e;hp=77e83ef868005af21764b8ffd6396e06443caebf;hpb=9dc9e58865704baf9d422946d34d1158ceaa5ba4;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.Layout/DefaultLayout.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.Layout/DefaultLayout.cs index 77e83ef8680..35bb2be338e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.Layout/DefaultLayout.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.Layout/DefaultLayout.cs @@ -24,6 +24,7 @@ // // Authors: // Jonathan Pobst (monkey@jpobst.com) +// Stefan Noack (noackstefan@googlemail.com) // using System; @@ -36,52 +37,67 @@ namespace System.Windows.Forms.Layout 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; @@ -100,14 +116,8 @@ namespace System.Windows.Forms.Layout 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) @@ -119,6 +129,7 @@ namespace System.Windows.Forms.Layout // 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) { @@ -131,6 +142,7 @@ namespace System.Windows.Forms.Layout // 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 @@ -140,9 +152,79 @@ namespace System.Windows.Forms.Layout 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) { @@ -152,8 +234,44 @@ namespace System.Windows.Forms.Layout 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); + } } }