Refactored, cleaned up
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / MdiClient.cs
index d88f298237caf3a78b49cd8131ac90832cf66366..2a6ef608e7170c5ab4f41b08bbdf39b2f8900673 100644 (file)
@@ -32,10 +32,8 @@ using System.Drawing;
 using System.Runtime.InteropServices;
 
 namespace System.Windows.Forms {
-#if NET_2_0
        [ComVisible (true)]
        [ClassInterface(ClassInterfaceType.AutoDispatch)]
-#endif
        [DesignTimeVisible(false)]
        [ToolboxItem(false)]
        public sealed class MdiClient : Control {
@@ -58,9 +56,7 @@ namespace System.Windows.Forms {
                #endregion      // Local Variables
 
                #region Public Classes
-#if NET_2_0
                [ComVisible (false)]
-#endif
                public new class ControlCollection : Control.ControlCollection {
 
                        private MdiClient owner;
@@ -195,7 +191,7 @@ namespace System.Windows.Forms {
                        SizeScrollBars ();
                        ArrangeWindows ();
                }
-#if NET_2_0
+
                protected override void ScaleControl (SizeF factor, BoundsSpecified specified)
                {
                        // Never change the MdiClient's location
@@ -205,7 +201,6 @@ namespace System.Windows.Forms {
                }
                
                [System.ComponentModel.EditorBrowsable (EditorBrowsableState.Never)]
-#endif
                protected override void ScaleCore (float dx, float dy)
                {
                        base.ScaleCore (dx, dy);
@@ -227,7 +222,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if NET_2_0
                [EditorBrowsable (EditorBrowsableState.Never)]
                [Browsable (false)]
                public override ImageLayout BackgroundImageLayout {
@@ -238,7 +232,6 @@ namespace System.Windows.Forms {
                                base.BackgroundImageLayout = value;
                        }
                }
-#endif
 
                public Form [] MdiChildren {
                        get {
@@ -262,13 +255,8 @@ namespace System.Windows.Forms {
                #region Public Instance Methods
                public void LayoutMdi (MdiLayout value) {
 
-                       int max_width = Int32.MaxValue;
-                       int max_height = Int32.MaxValue;
-
-                       if (Parent != null) {
-                               max_width = Parent.Width;
-                               max_height = Parent.Height;
-                       }
+                       // Don't forget to always call ArrangeIconicWindows 
+                       ArrangeIconicWindows (true);
 
                        switch (value) {
                        case MdiLayout.Cascade: {
@@ -278,11 +266,19 @@ namespace System.Windows.Forms {
 
                                        if (form.WindowState == FormWindowState.Minimized)
                                                continue;
-               
+
+                                       if (form.WindowState == FormWindowState.Maximized)
+                                               form.WindowState = FormWindowState.Normal;
+
+                                       form.Width = System.Convert.ToInt32 (ClientSize.Width * 0.8);
+                                       form.Height = Math.Max (
+                                                               System.Convert.ToInt32 (ClientSize.Height * 0.8),
+                                                               SystemInformation.MinimumWindowSize.Height + 2);
+
                                        int l = 22 * i;
                                        int t = 22 * i;
 
-                                       if (i != 0 && (l + form.Width > max_width || t + form.Height > max_height)) {
+                                       if (i != 0 && (l + form.Width > ClientSize.Width || t + form.Height > ClientSize.Height)) {
                                                i = 0;
                                                l = 22 * i;
                                                t = 22 * i;
@@ -295,13 +291,14 @@ namespace System.Windows.Forms {
                                }
                                break;
                                }
-                       case MdiLayout.ArrangeIcons:
-                               ArrangeIconicWindows (true);
-                               break;
                        case MdiLayout.TileHorizontal:
                        case MdiLayout.TileVertical: {
                                // First count number of windows to tile
                                int total = 0;
+                               
+                               // And space used by iconic windows
+                               int clientHeight = ClientSize.Height;
+                               
                                for (int i = 0; i < Controls.Count; i++) {
                                        Form form = Controls [i] as Form;
                                        
@@ -310,9 +307,14 @@ namespace System.Windows.Forms {
                                        
                                        if (!form.Visible)
                                                continue;
-                                       
-                                       if (form.WindowState == FormWindowState.Minimized)
+
+                                       if (form.WindowState == FormWindowState.Maximized)
+                                               form.WindowState = FormWindowState.Normal;
+                                       else if (form.WindowState == FormWindowState.Minimized) {
+                                               if (form.Bounds.Top < clientHeight)
+                                                       clientHeight = form.Bounds.Top;
                                                continue;
+                                       }
                                                
                                        total++;
                                }
@@ -322,11 +324,12 @@ namespace System.Windows.Forms {
                                // Calculate desired height and width
                                Size newSize;
                                Size offset;
+
                                if (value == MdiLayout.TileHorizontal) {
-                                       newSize = new Size (ClientSize.Width, ClientSize.Height / total);
+                                       newSize = new Size(ClientSize.Width, clientHeight / total);
                                        offset = new Size (0, newSize.Height);
                                } else {
-                                       newSize = new Size (ClientSize.Width / total, ClientSize.Height);
+                                       newSize = new Size(ClientSize.Width / total, clientHeight);
                                        offset = new Size (newSize.Width, 0);
                                }
                                
@@ -449,6 +452,8 @@ namespace System.Windows.Forms {
                        } else if (sizegrip != null) {
                                sizegrip.Visible = false;
                        }
+                       
+                       XplatUI.InvalidateNC (Handle);
                }
 
                private void CalcHBar (int left, int right, bool vert_vis)
@@ -615,25 +620,23 @@ namespace System.Windows.Forms {
 
                internal void ChildFormClosed (Form form)
                {
-                       if (Controls.Count > 1) {
-                               Form next = (Form) Controls [1];
-                               if (form.WindowState == FormWindowState.Maximized)
-                                       next.WindowState = FormWindowState.Maximized;
-                               ActivateChild (next);
-                       }
+                       FormWindowState closed_form_windowstate = form.WindowState;
        
                        form.Visible = false;
                        Controls.Remove (form);
                        
                        if (Controls.Count == 0) {
                                ((MdiWindowManager) form.window_manager).RaiseDeactivate ();
+                       } else if (closed_form_windowstate == FormWindowState.Maximized) {
+                               Form current = (Form) Controls [0];
+                               current.WindowState = FormWindowState.Maximized;
+                               ActivateChild(current);
                        }
 
                        if (Controls.Count == 0) {
                                XplatUI.RequestNCRecalc (Parent.Handle);
                                ParentForm.PerformLayout ();
 
-#if NET_2_0
                                // If we closed the last child, unmerge the menus.
                                // If it's not the last child, the menu will be unmerged
                                // when another child takes focus.
@@ -642,10 +645,10 @@ namespace System.Windows.Forms {
                                if (parent_menu != null)
                                        if (parent_menu.IsCurrentlyMerged)
                                                ToolStripManager.RevertMerge (parent_menu);
-#endif
                        }
                        SizeScrollBars ();
                        SetParentText (false);
+                       form.Dispose();
                }
 
                internal void ActivateNextChild ()
@@ -811,7 +814,6 @@ namespace System.Windows.Forms {
 
                        setting_windowstates = false;
 
-#if NET_2_0
                        if (form.MdiParent.MainMenuStrip != null)
                                form.MdiParent.MainMenuStrip.RefreshMdiItems ();
 
@@ -826,41 +828,80 @@ namespace System.Windows.Forms {
                                if (parent_menu.IsCurrentlyMerged)
                                        ToolStripManager.RevertMerge (parent_menu);
                                        
-                               MenuStrip child_menu = null;
+                               MenuStrip child_menu = LookForChildMenu (form);
 
-                               foreach (Control c in form.Controls)
-                                       if (c is MenuStrip)
-                                               child_menu = (MenuStrip)c;
-
-                               RemoveControlMenuItems (wm);
+                               if (form.WindowState != FormWindowState.Maximized)
+                                       RemoveControlMenuItems (wm);
                                
                                if (form.WindowState == FormWindowState.Maximized) {
-                                       parent_menu.Items.Insert (0, new MdiControlStrip.SystemMenuItem (form));
-                                       parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Close));
-                                       parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Max));
-                                       parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Min));
+                                       bool found = false;
+                                       
+                                       foreach (ToolStripItem tsi in parent_menu.Items) {
+                                               if (tsi is MdiControlStrip.SystemMenuItem) {
+                                                       (tsi as MdiControlStrip.SystemMenuItem).MdiForm = form;
+                                                       found = true;
+                                               } else if (tsi is MdiControlStrip.ControlBoxMenuItem) {
+                                                       (tsi as MdiControlStrip.ControlBoxMenuItem).MdiForm = form;
+                                                       found = true;
+                                               }
+                                       }       
+                                       
+                                       if (!found) {
+                                               parent_menu.SuspendLayout ();
+                                               parent_menu.Items.Insert (0, new MdiControlStrip.SystemMenuItem (form));
+                                               parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Close));
+                                               parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Max));
+                                               parent_menu.Items.Add (new MdiControlStrip.ControlBoxMenuItem (form, MdiControlStrip.ControlBoxType.Min));
+                                               parent_menu.ResumeLayout ();
+                                       }
                                }
                                
                                if (child_menu != null)
                                        ToolStripManager.Merge (child_menu, parent_menu);
                        }
-#endif
 
                        return maximize_this;
                }
 
-#if NET_2_0
+               private MenuStrip LookForChildMenu (Control parent)
+               {
+                       foreach (Control c in parent.Controls) {
+                               if (c is MenuStrip)
+                                       return (MenuStrip)c;
+                                       
+                               if (c is ToolStripContainer || c is ToolStripPanel) {
+                                       MenuStrip ms = LookForChildMenu (c);
+                                       
+                                       if (ms != null)
+                                               return ms;
+                               }
+                       }
+                       
+                       return null;
+               }
+               
                internal void RemoveControlMenuItems (MdiWindowManager wm)
                {
                        Form form = wm.form;
                        MenuStrip parent_menu = form.MdiParent.MainMenuStrip;
-                       
-                       if (parent_menu != null)
-                               for (int i = parent_menu.Items.Count - 1; i >= 0; i--)
-                                       if (parent_menu.Items[i] is MdiControlStrip.SystemMenuItem || parent_menu.Items[i] is MdiControlStrip.ControlBoxMenuItem)
-                                               parent_menu.Items.RemoveAt (i);
+
+                       // Only remove the items if the form requesting still owns the menu items
+                       if (parent_menu != null) {
+                               parent_menu.SuspendLayout ();
+
+                               for (int i = parent_menu.Items.Count - 1; i >= 0; i--) {
+                                       if (parent_menu.Items[i] is MdiControlStrip.SystemMenuItem) {
+                                               if ((parent_menu.Items[i] as MdiControlStrip.SystemMenuItem).MdiForm == form)
+                                                       parent_menu.Items.RemoveAt (i);
+                                       } else if (parent_menu.Items[i] is MdiControlStrip.ControlBoxMenuItem) {
+                                               if ((parent_menu.Items[i] as MdiControlStrip.ControlBoxMenuItem).MdiForm == form)
+                                                       parent_menu.Items.RemoveAt (i);
+                                       }
+                               }
+                               
+                               parent_menu.ResumeLayout ();
+                       }
                }
-#endif
 
                internal void SetWindowState (Form form, FormWindowState old_window_state, FormWindowState new_window_state, bool is_activating_child)
                {
@@ -872,15 +913,15 @@ namespace System.Windows.Forms {
                                ActivateChild (form);
                                return;
                        }
+                               
+                       if (old_window_state == FormWindowState.Normal)
+                               wm.NormalBounds = form.Bounds;
 
                        if (SetWindowStates (wm))
                                return;
 
                        if (old_window_state == new_window_state)
                                return;
-                               
-                       if (old_window_state == FormWindowState.Normal)
-                               wm.NormalBounds = form.Bounds;
 
                        mdiclient_layout = old_window_state == FormWindowState.Maximized || new_window_state == FormWindowState.Maximized;
 
@@ -915,10 +956,9 @@ namespace System.Windows.Forms {
 
                internal Form ActiveMdiChild {
                        get {
-#if NET_2_0
                                if (ParentForm != null && !ParentForm.Visible)
                                        return null;
-#endif
+
                                if (Controls.Count < 1)
                                        return null;