aboutsummaryrefslogtreecommitdiff
path: root/source/ShiftUI/Internal/MdiClient.cs
diff options
context:
space:
mode:
authorMichael VanOverbeek <[email protected]>2016-07-25 12:57:52 -0400
committerGitHub <[email protected]>2016-07-25 12:57:52 -0400
commit46c1c31302f111a1f3ec23a70e6f3986a9aa2a27 (patch)
treef00af7ea3f6ad2641fb26fa1d310fd8b7179b39c /source/ShiftUI/Internal/MdiClient.cs
parentaf48e774189596b8d7a058c564a7d6d75205ca03 (diff)
parent6fa16209519896de09949a27425dff00ebf2970a (diff)
downloadshiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.tar.gz
shiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.tar.bz2
shiftos-c--46c1c31302f111a1f3ec23a70e6f3986a9aa2a27.zip
Merge pull request #17 from MichaelTheShifter/shiftui_integration
Shiftui integration
Diffstat (limited to 'source/ShiftUI/Internal/MdiClient.cs')
-rw-r--r--source/ShiftUI/Internal/MdiClient.cs1003
1 files changed, 1003 insertions, 0 deletions
diff --git a/source/ShiftUI/Internal/MdiClient.cs b/source/ShiftUI/Internal/MdiClient.cs
new file mode 100644
index 0000000..8c2cf8c
--- /dev/null
+++ b/source/ShiftUI/Internal/MdiClient.cs
@@ -0,0 +1,1003 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+//
+// Authors:
+// Peter Bartok [email protected]
+//
+//
+
+// NOT COMPLETE
+
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System;
+
+namespace ShiftUI {
+ [ComVisible (true)]
+ [ClassInterface(ClassInterfaceType.AutoDispatch)]
+ [DesignTimeVisible(false)]
+ [ToolboxItem(false)]
+ public sealed class MdiClient : Widget {
+ #region Local Variables
+ private int mdi_created;
+ private ImplicitHScrollBar hbar;
+ private ImplicitVScrollBar vbar;
+ private SizeGrip sizegrip;
+ private int hbar_value;
+ private int vbar_value;
+ private bool lock_sizing;
+ private bool initializing_scrollbars;
+ private int prev_bottom;
+ private bool setting_windowstates = false;
+ internal ArrayList mdi_child_list;
+ private string form_text;
+ private bool setting_form_text;
+ private Form active_child;
+
+ #endregion // Local Variables
+
+ #region Public Classes
+ [ComVisible (false)]
+ public new class WidgetCollection : Widget.WidgetCollection {
+
+ private MdiClient owner;
+
+ public WidgetCollection(MdiClient owner) : base(owner) {
+ this.owner = owner;
+ }
+
+ public override void Add(Widget value) {
+ if ((value is Form) == false || !(((Form)value).IsMdiChild)) {
+ throw new ArgumentException("Form must be MdiChild");
+ }
+ owner.mdi_child_list.Add (value);
+ base.Add (value);
+
+ // newest member is the active one
+ Form form = (Form) value;
+ owner.ActiveMdiChild = form;
+ }
+
+ public override void Remove(Widget value)
+ {
+ Form form = value as Form;
+ if (form != null) {
+ MdiWindowManager wm = form.WindowManager as MdiWindowManager;
+ if (wm != null) {
+ form.Closed -= wm.form_closed_handler;
+ }
+ }
+
+ owner.mdi_child_list.Remove (value);
+ base.Remove (value);
+ }
+ }
+ #endregion // Public Classes
+
+ #region Public Constructors
+ public MdiClient()
+ {
+ mdi_child_list = new ArrayList ();
+ BackColor = SystemColors.AppWorkspace;
+ Dock = DockStyle.Fill;
+ SetStyle (Widgetstyles.Selectable, false);
+ }
+ #endregion // Public Constructors
+
+ internal void SendFocusToActiveChild ()
+ {
+ Form active = this.ActiveMdiChild;
+ if (active == null) {
+ ParentForm.SendWidgetFocus (this);
+ } else {
+ active.SendWidgetFocus (active);
+ ParentForm.ActiveWidget = active;
+ }
+ }
+
+ internal bool HorizontalScrollbarVisible {
+ get { return hbar != null && hbar.Visible; }
+ }
+ internal bool VerticalScrollbarVisible {
+ get { return vbar != null && vbar.Visible; }
+ }
+
+ internal void SetParentText(bool text_changed)
+ {
+ if (setting_form_text)
+ return;
+
+ setting_form_text = true;
+
+ if (text_changed)
+ form_text = ParentForm.Text;
+
+ if (ParentForm.ActiveMaximizedMdiChild == null) {
+ ParentForm.Text = form_text;
+ } else {
+ string childText = ParentForm.ActiveMaximizedMdiChild.form.Text;
+ if (childText.Length > 0) {
+ ParentForm.Text = form_text + " - [" + ParentForm.ActiveMaximizedMdiChild.form.Text + "]";
+ } else {
+ ParentForm.Text = form_text;
+ }
+ }
+
+ setting_form_text = false;
+ }
+
+ internal override void OnPaintBackgroundInternal (PaintEventArgs pe)
+ {
+ if (BackgroundImage != null)
+ return;
+
+ if (Parent == null || Parent.BackgroundImage == null)
+ return;
+ Parent.PaintWidgetBackground (pe);
+ }
+
+ internal Form ParentForm {
+ get { return (Form) Parent; }
+ }
+
+ protected override Widget.WidgetCollection CreateWidgetsInstance ()
+ {
+ return new MdiClient.WidgetCollection (this);
+ }
+
+ protected override void WndProc(ref Message m) {
+ switch ((Msg)m.Msg) {
+ case Msg.WM_NCPAINT:
+ PaintEventArgs pe = XplatUI.PaintEventStart (ref m, Handle, false);
+
+ Rectangle clip;
+ clip = new Rectangle (0, 0, Width, Height);
+
+ WidgetPaint.DrawBorder3D (pe.Graphics, clip, Border3DStyle.Sunken);
+ XplatUI.PaintEventEnd (ref m, Handle, false);
+ m.Result = IntPtr.Zero;
+ return ;
+ }
+
+ base.WndProc (ref m);
+ }
+
+ protected override void OnResize (EventArgs e)
+ {
+ base.OnResize (e);
+
+ if (Parent != null && Parent.IsHandleCreated)
+ XplatUI.InvalidateNC (Parent.Handle);
+ // Should probably make this into one loop
+ SizeScrollBars ();
+ ArrangeWindows ();
+ }
+
+ protected override void ScaleWidget (SizeF factor, BoundsSpecified specified)
+ {
+ // Never change the MdiClient's location
+ specified &= ~BoundsSpecified.Location;
+
+ base.ScaleWidget (factor, specified);
+ }
+
+ [System.ComponentModel.EditorBrowsable (EditorBrowsableState.Never)]
+ protected override void ScaleCore (float dx, float dy)
+ {
+ base.ScaleCore (dx, dy);
+ }
+
+ protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
+ {
+ base.SetBoundsCore (x, y, width, height, specified);
+ }
+
+ #region Public Instance Properties
+ [Localizable(true)]
+ public override System.Drawing.Image BackgroundImage {
+ get {
+ return base.BackgroundImage;
+ }
+ set {
+ base.BackgroundImage = value;
+ }
+ }
+
+ //[EditorBrowsable (EditorBrowsableState.Never)]
+ [Browsable (false)]
+ public override ImageLayout BackgroundImageLayout {
+ get {
+ return base.BackgroundImageLayout;
+ }
+ set {
+ base.BackgroundImageLayout = value;
+ }
+ }
+
+ public Form [] MdiChildren {
+ get {
+ if (mdi_child_list == null)
+ return new Form [0];
+ return (Form []) mdi_child_list.ToArray (typeof (Form));
+ }
+ }
+ #endregion // Public Instance Properties
+
+#region Protected Instance Properties
+ protected override CreateParams CreateParams {
+ get {
+ CreateParams result = base.CreateParams;
+ result.ExStyle |= (int) WindowExStyles.WS_EX_CLIENTEDGE;
+ return result;
+ }
+ }
+ #endregion // Protected Instance Properties
+
+ #region Public Instance Methods
+ public void LayoutMdi (MdiLayout value) {
+
+ // Don't forget to always call ArrangeIconicWindows
+ ArrangeIconicWindows (true);
+
+ switch (value) {
+ case MdiLayout.Cascade: {
+ int i = 0;
+ for (int c = Widgets.Count - 1; c >= 0; c--) {
+ Form form = (Form) Widgets [c];
+
+ 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 > ClientSize.Width || t + form.Height > ClientSize.Height)) {
+ i = 0;
+ l = 22 * i;
+ t = 22 * i;
+ }
+
+ form.Left = l;
+ form.Top = t;
+
+ i++;
+ }
+ 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 < Widgets.Count; i++) {
+ Form form = Widgets [i] as Form;
+
+ if (form == null)
+ continue;
+
+ if (!form.Visible)
+ continue;
+
+ 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++;
+ }
+ if (total <= 0)
+ return;
+
+ // Calculate desired height and width
+ Size newSize;
+ Size offset;
+
+ if (value == MdiLayout.TileHorizontal) {
+ newSize = new Size(ClientSize.Width, clientHeight / total);
+ offset = new Size (0, newSize.Height);
+ } else {
+ newSize = new Size(ClientSize.Width / total, clientHeight);
+ offset = new Size (newSize.Width, 0);
+ }
+
+ // Loop again and set the size and location.
+ Point nextLocation = Point.Empty;
+
+ for (int i = 0; i < Widgets.Count; i++) {
+ Form form = Widgets [i] as Form;
+
+ if (form == null)
+ continue;
+
+ if (!form.Visible)
+ continue;
+
+ if (form.WindowState == FormWindowState.Minimized)
+ continue;
+
+ form.Size = newSize;
+ form.Location = nextLocation;
+ nextLocation += offset;
+ }
+
+ break;
+ }
+ }
+ }
+ #endregion // Public Instance Methods
+
+ #region Protected Instance Methods
+ #endregion // Protected Instance Methods
+
+ internal void SizeScrollBars ()
+ {
+ if (lock_sizing)
+ return;
+
+ if (!IsHandleCreated)
+ return;
+
+ if (Widgets.Count == 0 || ((Form) Widgets [0]).WindowState == FormWindowState.Maximized) {
+ if (hbar != null)
+ hbar.Visible = false;
+ if (vbar != null)
+ vbar.Visible = false;
+ if (sizegrip != null)
+ sizegrip.Visible = false;
+ return;
+ }
+
+ int right = 0;
+ int left = 0;
+ int top = 0;
+ int bottom = 0;
+
+ foreach (Form child in Widgets) {
+ if (!child.Visible)
+ continue;
+ if (child.Right > right)
+ right = child.Right;
+ if (child.Left < left) {
+ left = child.Left;
+ }
+
+ if (child.Bottom > bottom)
+ bottom = child.Bottom;
+ if (child.Top < 0) {
+ top = child.Top;
+ }
+ }
+
+ int available_width = ClientSize.Width;
+ int available_height = ClientSize.Height;
+
+ bool need_hbar = false;
+ bool need_vbar = false;
+
+ if (right - left > available_width || left < 0) {
+ need_hbar = true;
+ available_height -= SystemInformation.HorizontalScrollBarHeight;
+ }
+ if (bottom - top > available_height || top < 0) {
+ need_vbar = true;
+ available_width -= SystemInformation.VerticalScrollBarWidth;
+
+ if (!need_hbar && (right - left > available_width || left < 0)) {
+ need_hbar = true;
+ available_height -= SystemInformation.HorizontalScrollBarHeight;
+ }
+ }
+
+ if (need_hbar) {
+ if (hbar == null) {
+ hbar = new ImplicitHScrollBar ();
+ Widgets.AddImplicit (hbar);
+ }
+ hbar.Visible = true;
+ CalcHBar (left, right, need_vbar);
+ } else if (hbar != null)
+ hbar.Visible = false;
+
+ if (need_vbar) {
+ if (vbar == null) {
+ vbar = new ImplicitVScrollBar ();
+ Widgets.AddImplicit (vbar);
+ }
+ vbar.Visible = true;
+ CalcVBar (top, bottom, need_hbar);
+ } else if (vbar != null)
+ vbar.Visible = false;
+
+ if (need_hbar && need_vbar) {
+ if (sizegrip == null) {
+ sizegrip = new SizeGrip (this.ParentForm);
+ Widgets.AddImplicit (sizegrip);
+ }
+ sizegrip.Location = new Point (hbar.Right, vbar.Bottom);
+ sizegrip.Visible = true;
+ XplatUI.SetZOrder (sizegrip.Handle, vbar.Handle, false, false);
+ } else if (sizegrip != null) {
+ sizegrip.Visible = false;
+ }
+
+ XplatUI.InvalidateNC (Handle);
+ }
+
+ private void CalcHBar (int left, int right, bool vert_vis)
+ {
+ initializing_scrollbars = true;
+
+ hbar.Left = 0;
+ hbar.Top = ClientRectangle.Bottom - hbar.Height;
+ hbar.Width = ClientRectangle.Width - (vert_vis ? SystemInformation.VerticalScrollBarWidth : 0);
+ hbar.LargeChange = 50;
+ hbar.Minimum = Math.Min (left, 0);
+ hbar.Maximum = Math.Max (right - ClientSize.Width + 51 + (vert_vis ? SystemInformation.VerticalScrollBarWidth : 0), 0);
+ hbar.Value = 0;
+ hbar_value = 0;
+ hbar.ValueChanged += new EventHandler (HBarValueChanged);
+ XplatUI.SetZOrder (hbar.Handle, IntPtr.Zero, true, false);
+
+ initializing_scrollbars = false;
+ }
+
+ private void CalcVBar (int top, int bottom, bool horz_vis)
+ {
+ initializing_scrollbars = true;
+
+ vbar.Top = 0;
+ vbar.Left = ClientRectangle.Right - vbar.Width;
+ vbar.Height = ClientRectangle.Height - (horz_vis ? SystemInformation.HorizontalScrollBarHeight : 0);
+ vbar.LargeChange = 50;
+ vbar.Minimum = Math.Min (top, 0);
+ vbar.Maximum = Math.Max (bottom - ClientSize.Height + 51 + (horz_vis ? SystemInformation.HorizontalScrollBarHeight : 0), 0);
+ vbar.Value = 0;
+ vbar_value = 0;
+ vbar.ValueChanged += new EventHandler (VBarValueChanged);
+ XplatUI.SetZOrder (vbar.Handle, IntPtr.Zero, true, false);
+
+ initializing_scrollbars = false;
+ }
+
+ private void HBarValueChanged (object sender, EventArgs e)
+ {
+ if (initializing_scrollbars)
+ return;
+
+ if (hbar.Value == hbar_value)
+ return;
+
+ lock_sizing = true;
+
+ try {
+ int diff = hbar_value - hbar.Value;
+ foreach (Form child in Widgets) {
+ child.Left += diff;
+ }
+ } finally {
+ lock_sizing = false;
+ }
+
+ hbar_value = hbar.Value;
+ }
+
+ private void VBarValueChanged (object sender, EventArgs e)
+ {
+ if (initializing_scrollbars)
+ return;
+
+ if (vbar.Value == vbar_value)
+ return;
+
+ lock_sizing = true;
+
+ try {
+ int diff = vbar_value - vbar.Value;
+ foreach (Form child in Widgets) {
+ child.Top += diff;
+ }
+ } finally {
+ lock_sizing = false;
+ }
+
+ vbar_value = vbar.Value;
+ }
+
+ private void ArrangeWindows ()
+ {
+ if (!IsHandleCreated)
+ return;
+
+ int change = 0;
+ if (prev_bottom != -1)
+ change = Bottom - prev_bottom;
+
+ foreach (Widget c in Widgets) {
+ Form child = c as Form;
+
+ if (c == null || !child.Visible)
+ continue;
+
+ MdiWindowManager wm = child.WindowManager as MdiWindowManager;
+ if (wm.GetWindowState () == FormWindowState.Maximized)
+ child.Bounds = wm.MaximizedBounds;
+
+ if (wm.GetWindowState () == FormWindowState.Minimized) {
+ child.Top += change;
+ }
+
+ }
+
+ prev_bottom = Bottom;
+ }
+
+ internal void ArrangeIconicWindows (bool rearrange_all)
+ {
+ Rectangle rect = Rectangle.Empty;
+
+ lock_sizing = true;
+ foreach (Form form in Widgets) {
+ if (form.WindowState != FormWindowState.Minimized)
+ continue;
+
+ MdiWindowManager wm = (MdiWindowManager) form.WindowManager;
+
+ if (wm.IconicBounds != Rectangle.Empty && !rearrange_all) {
+ if (form.Bounds != wm.IconicBounds)
+ form.Bounds = wm.IconicBounds;
+ continue;
+ }
+
+ bool success = true;
+ int startx, starty, currentx, currenty;
+
+ rect.Size = wm.IconicSize;
+
+ startx = 0;
+ starty = ClientSize.Height - rect.Height;
+ currentx = startx;
+ currenty = starty;
+
+ do {
+ rect.X = currentx;
+ rect.Y = currenty;
+ success = true;
+ foreach (Form form2 in Widgets) {
+ if (form2 == form || form2.window_state != FormWindowState.Minimized)
+ continue;
+
+ if (form2.Bounds.IntersectsWith(rect)) {
+ success = false;
+ break;
+ }
+ }
+ if (!success) {
+ currentx += rect.Width;
+ if (currentx + rect.Width > Right) {
+ currentx = startx;
+ currenty -= rect.Height;
+ }
+ }
+ } while (!success);
+ wm.IconicBounds = rect;
+ form.Bounds = wm.IconicBounds;
+ }
+ lock_sizing = false;
+ }
+
+ internal void ChildFormClosed (Form form)
+ {
+ FormWindowState closed_form_windowstate = form.WindowState;
+
+ form.Visible = false;
+ Widgets.Remove (form);
+
+ if (Widgets.Count == 0) {
+ ((MdiWindowManager) form.window_manager).RaiseDeactivate ();
+ } else if (closed_form_windowstate == FormWindowState.Maximized) {
+ Form current = (Form) Widgets [0];
+ current.WindowState = FormWindowState.Maximized;
+ ActivateChild(current);
+ }
+
+ if (Widgets.Count == 0) {
+ XplatUI.RequestNCRecalc (Parent.Handle);
+ ParentForm.PerformLayout ();
+
+ // 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.
+ MenuStrip parent_menu = form.MdiParent.MainMenuStrip;
+
+ if (parent_menu != null)
+ if (parent_menu.IsCurrentlyMerged)
+ ToolStripManager.RevertMerge (parent_menu);
+ }
+ SizeScrollBars ();
+ SetParentText (false);
+ form.Dispose();
+ }
+
+ internal void ActivateNextChild ()
+ {
+ if (Widgets.Count < 1)
+ return;
+ if (Widgets.Count == 1 && Widgets[0] == ActiveMdiChild)
+ return;
+
+ Form front = (Form) Widgets [0];
+ Form form = (Form) Widgets [1];
+
+ ActivateChild (form);
+ front.SendToBack ();
+ }
+
+ internal void ActivatePreviousChild ()
+ {
+ if (Widgets.Count <= 1)
+ return;
+
+ Form back = (Form) Widgets [Widgets.Count - 1];
+
+ ActivateChild (back);
+ }
+
+ internal void ActivateChild (Form form)
+ {
+ if (Widgets.Count < 1)
+ return;
+
+ if (ParentForm.is_changing_visible_state > 0)
+ return;
+
+ Form current = (Form) Widgets [0];
+ bool raise_deactivate = ParentForm.ActiveWidget == current;
+
+ // We want to resize the new active form before it is
+ // made active to avoid flickering. Can't do it in the
+ // normal way (form.WindowState = Maximized) since it's not
+ // active yet and everything would just return to before.
+ // We also won't suspend layout, this way the layout will
+ // happen before the form is made active (and in many cases
+ // before it is visible, which avoids flickering as well).
+ MdiWindowManager wm = (MdiWindowManager)form.WindowManager;
+
+ if (current.WindowState == FormWindowState.Maximized && form.WindowState != FormWindowState.Maximized && form.Visible) {
+ FormWindowState old_state = form.window_state;
+ SetWindowState (form, old_state, FormWindowState.Maximized, true);
+ wm.was_minimized = form.window_state == FormWindowState.Minimized;
+ form.window_state = FormWindowState.Maximized;
+ SetParentText (false);
+ }
+
+ form.BringToFront ();
+ form.SendWidgetFocus (form);
+ SetWindowStates (wm);
+ if (current != form) {
+ form.has_focus = false;
+ if (current.IsHandleCreated)
+ XplatUI.InvalidateNC (current.Handle);
+ if (form.IsHandleCreated)
+ XplatUI.InvalidateNC (form.Handle);
+ if (raise_deactivate) {
+ MdiWindowManager current_wm = (MdiWindowManager) current.window_manager;
+ current_wm.RaiseDeactivate ();
+
+ }
+ }
+ active_child = (Form) Widgets [0];
+
+ if (active_child.Visible) {
+ bool raise_activated = ParentForm.ActiveWidget != active_child;
+ ParentForm.ActiveWidget = active_child;
+ if (raise_activated) {
+ MdiWindowManager active_wm = (MdiWindowManager) active_child.window_manager;
+ active_wm.RaiseActivated ();
+ }
+ }
+ }
+
+ internal override IntPtr AfterTopMostWidget ()
+ {
+ // order of scrollbars:
+ // top = vertical
+ // sizegrid
+ // bottom = horizontal
+ if (hbar != null && hbar.Visible)
+ return hbar.Handle;
+ // no need to check for sizegrip since it will only
+ // be visible if hbar is visible.
+ if (vbar != null && vbar.Visible)
+ return vbar.Handle;
+
+ return base.AfterTopMostWidget ();
+ }
+
+ internal bool SetWindowStates (MdiWindowManager wm)
+ {
+ /*
+ MDI WindowState behaviour:
+ - If the active window is maximized, all other maximized windows are normalized.
+ - If a normal window gets focus and the original active window was maximized,
+ the normal window gets maximized and the original window gets normalized.
+ - If a minimized window gets focus and the original window was maximized,
+ the minimzed window gets maximized and the original window gets normalized.
+ If the ex-minimized window gets deactivated, it will be normalized.
+ */
+ Form form = wm.form;
+
+ if (setting_windowstates) {
+ return false;
+ }
+
+ if (!form.Visible)
+ return false;
+
+ bool is_active = wm.IsActive;
+ bool maximize_this = false;
+
+ if (!is_active){
+ return false;
+ }
+
+ ArrayList minimize_these = new ArrayList ();
+ ArrayList normalize_these = new ArrayList ();
+
+ setting_windowstates = true;
+ foreach (Form frm in mdi_child_list) {
+ if (frm == form) {
+ continue;
+ } else if (!frm.Visible){
+ continue;
+ }
+ if (frm.WindowState == FormWindowState.Maximized && is_active) {
+ maximize_this = true;
+ if (((MdiWindowManager) frm.window_manager).was_minimized) {
+ minimize_these.Add (frm);
+ } else {
+ normalize_these.Add (frm);
+ }
+ }
+ }
+
+ if (maximize_this && form.WindowState != FormWindowState.Maximized) {
+ wm.was_minimized = form.window_state == FormWindowState.Minimized;
+ form.WindowState = FormWindowState.Maximized;
+ }
+
+ foreach (Form frm in minimize_these)
+ frm.WindowState = FormWindowState.Minimized;
+
+ foreach (Form frm in normalize_these)
+ frm.WindowState = FormWindowState.Normal;
+
+
+ SetParentText (false);
+
+ XplatUI.RequestNCRecalc (ParentForm.Handle);
+ XplatUI.RequestNCRecalc (Handle);
+
+ SizeScrollBars ();
+
+ setting_windowstates = false;
+
+ if (form.MdiParent.MainMenuStrip != null)
+ form.MdiParent.MainMenuStrip.RefreshMdiItems ();
+
+ // Implicit menu strip merging
+ // - When child is activated
+ // - Parent form must have a MainMenuStrip
+ // - Find the first menustrip on the child
+ // - Merge
+ MenuStrip parent_menu = form.MdiParent.MainMenuStrip;
+
+ if (parent_menu != null) {
+ if (parent_menu.IsCurrentlyMerged)
+ ToolStripManager.RevertMerge (parent_menu);
+
+ MenuStrip child_menu = LookForChildMenu (form);
+
+ if (form.WindowState != FormWindowState.Maximized)
+ RemoveControlMenuItems (wm);
+
+ if (form.WindowState == FormWindowState.Maximized) {
+ bool found = false;
+
+ foreach (ToolStripItem tsi in parent_menu.Items) {
+ if (tsi is MdiWidgetStrip.SystemMenuItem) {
+ (tsi as MdiWidgetStrip.SystemMenuItem).MdiForm = form;
+ found = true;
+ } else if (tsi is MdiWidgetStrip.WidgetBoxMenuItem) {
+ (tsi as MdiWidgetStrip.WidgetBoxMenuItem).MdiForm = form;
+ found = true;
+ }
+ }
+
+ if (!found) {
+ parent_menu.SuspendLayout ();
+ parent_menu.Items.Insert (0, new MdiWidgetStrip.SystemMenuItem (form));
+ parent_menu.Items.Add (new MdiWidgetStrip.WidgetBoxMenuItem (form, MdiWidgetStrip.ControlBoxType.Close));
+ parent_menu.Items.Add (new MdiWidgetStrip.WidgetBoxMenuItem (form, MdiWidgetStrip.ControlBoxType.Max));
+ parent_menu.Items.Add (new MdiWidgetStrip.WidgetBoxMenuItem (form, MdiWidgetStrip.ControlBoxType.Min));
+ parent_menu.ResumeLayout ();
+ }
+ }
+
+ if (child_menu != null)
+ ToolStripManager.Merge (child_menu, parent_menu);
+ }
+
+ return maximize_this;
+ }
+
+ private MenuStrip LookForChildMenu (Widget parent)
+ {
+ foreach (Widget c in parent.Widgets) {
+ 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;
+
+ // 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 MdiWidgetStrip.SystemMenuItem) {
+ if ((parent_menu.Items[i] as MdiWidgetStrip.SystemMenuItem).MdiForm == form)
+ parent_menu.Items.RemoveAt (i);
+ } else if (parent_menu.Items[i] is MdiWidgetStrip.WidgetBoxMenuItem) {
+ if ((parent_menu.Items[i] as MdiWidgetStrip.WidgetBoxMenuItem).MdiForm == form)
+ parent_menu.Items.RemoveAt (i);
+ }
+ }
+
+ parent_menu.ResumeLayout ();
+ }
+ }
+
+ internal void SetWindowState (Form form, FormWindowState old_window_state, FormWindowState new_window_state, bool is_activating_child)
+ {
+ bool mdiclient_layout;
+
+ MdiWindowManager wm = (MdiWindowManager) form.window_manager;
+
+ if (!is_activating_child && new_window_state == FormWindowState.Maximized && !wm.IsActive) {
+ 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;
+
+ mdiclient_layout = old_window_state == FormWindowState.Maximized || new_window_state == FormWindowState.Maximized;
+
+ switch (new_window_state) {
+ case FormWindowState.Minimized:
+ ArrangeIconicWindows (false);
+ break;
+ case FormWindowState.Maximized:
+ form.Bounds = wm.MaximizedBounds;
+ break;
+ case FormWindowState.Normal:
+ form.Bounds = wm.NormalBounds;
+ break;
+ }
+
+ wm.UpdateWindowDecorations (new_window_state);
+
+ form.ResetCursor ();
+
+ if (mdiclient_layout)
+ Parent.PerformLayout ();
+
+ XplatUI.RequestNCRecalc (Parent.Handle);
+ XplatUI.RequestNCRecalc (form.Handle);
+ if (!setting_windowstates)
+ SizeScrollBars ();
+ }
+ internal int ChildrenCreated {
+ get { return mdi_created; }
+ set { mdi_created = value; }
+ }
+
+ internal Form ActiveMdiChild {
+ get {
+ if (ParentForm != null && !ParentForm.Visible)
+ return null;
+
+ if (Widgets.Count < 1)
+ return null;
+
+ if (!ParentForm.IsHandleCreated)
+ return null;
+
+ if (!ParentForm.has_been_visible)
+ return null;
+
+ if (!ParentForm.Visible)
+ return active_child;
+
+ active_child = null;
+ for (int i = 0; i < Widgets.Count; i++) {
+ if (Widgets [i].Visible) {
+ active_child = (Form) Widgets [i];
+ break;
+ }
+ }
+ return active_child;
+ }
+ set {
+ ActivateChild (value);
+ }
+ }
+
+ internal void ActivateActiveMdiChild ()
+ {
+ if (ParentForm.is_changing_visible_state > 0)
+ return;
+
+ for (int i = 0; i < Widgets.Count; i++) {
+ if (Widgets [i].Visible) {
+ ActivateChild ((Form) Widgets [i]);
+ return;
+ }
+ }
+ }
+ }
+}
+