diff options
| author | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
|---|---|---|
| committer | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
| commit | d40fed5ce2bc806a91245adb18039634eac13ed0 (patch) | |
| tree | f1d7168aee6db109ac2c738ad18c9db667a6ba69 /source/ShiftUI/Internal/MdiWindowManager.cs | |
| parent | f1856e8ed30ed882229fd3fa2a4038122a5fb441 (diff) | |
| download | shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.gz shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.bz2 shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.zip | |
Move ShiftUI source code to ShiftOS
This'll be a lot easier to work on.
Diffstat (limited to 'source/ShiftUI/Internal/MdiWindowManager.cs')
| -rw-r--r-- | source/ShiftUI/Internal/MdiWindowManager.cs | 624 |
1 files changed, 624 insertions, 0 deletions
diff --git a/source/ShiftUI/Internal/MdiWindowManager.cs b/source/ShiftUI/Internal/MdiWindowManager.cs new file mode 100644 index 0000000..0344f2c --- /dev/null +++ b/source/ShiftUI/Internal/MdiWindowManager.cs @@ -0,0 +1,624 @@ +// 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: +// Jackson Harper ([email protected]) +// +// + + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Runtime.InteropServices; + +namespace ShiftUI { + + internal class MdiWindowManager : InternalWindowManager { + + private MainMenu merged_menu; + private MainMenu maximized_menu; + private MenuItem icon_menu; + internal bool was_minimized; + + private PaintEventHandler draw_maximized_buttons; + internal EventHandler form_closed_handler; + + private MdiClient mdi_container; + private Rectangle prev_virtual_position; + + private Point icon_clicked; + private DateTime icon_clicked_time; + private bool icon_dont_show_popup; + + private TitleButtons maximized_title_buttons; + private bool is_visible_pending; + private byte last_activation_event; // 0 = none, 1 = activated, 2 = deactivated. + + public void RaiseActivated () + { + if (last_activation_event == 1) + return; + + last_activation_event = 1; + form.OnActivatedInternal (); + form.SelectActiveWidget (); + } + + public void RaiseDeactivate () + { + if (last_activation_event != 1) + return; + last_activation_event = 2; + form.OnDeactivateInternal (); + } + + public override int MenuHeight { + get { + // Mdi children don't get menus on the form, they're shown on the main form. + return 0; + } + } + + internal bool IsVisiblePending { + get { + return is_visible_pending; + } + set { + is_visible_pending = value; + } + } + + private TitleButtons MaximizedTitleButtons { + get { + if (maximized_title_buttons == null) { + maximized_title_buttons = new TitleButtons (this.Form); + maximized_title_buttons.CloseButton.Visible = true; + maximized_title_buttons.RestoreButton.Visible = true; + maximized_title_buttons.MinimizeButton.Visible = true; + } + return maximized_title_buttons; + } + } + + internal override Rectangle MaximizedBounds { + get { + Rectangle pb = mdi_container.ClientRectangle; + int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); + int tw = TitleBarHeight; + + Rectangle new_bounds = new Rectangle (pb.Left - bw, + pb.Top - tw - bw, + pb.Width + bw * 2, + pb.Height + tw + bw * 2); + return new_bounds; + } + } + + + + public MdiWindowManager (Form form, MdiClient mdi_container) : base (form) + { + this.mdi_container = mdi_container; + if (form.WindowState == FormWindowState.Normal) { + NormalBounds = form.Bounds; + } + form_closed_handler = new EventHandler (FormClosed); + form.Closed += form_closed_handler; + form.TextChanged += new EventHandler (FormTextChangedHandler); + form.SizeChanged += new EventHandler (FormSizeChangedHandler); + form.LocationChanged += new EventHandler (FormLocationChangedHandler); + form.VisibleChanged += new EventHandler (FormVisibleChangedHandler); + draw_maximized_buttons = new PaintEventHandler (DrawMaximizedButtons); + CreateIconMenus (); + } + + private void FormVisibleChangedHandler (object sender, EventArgs e) + { + if (mdi_container == null) + return; + + if (form.Visible) { + mdi_container.ActivateChild (form); + } else if (mdi_container.Widgets.Count > 1) { + mdi_container.ActivateActiveMdiChild (); + } + } + + private void FormTextChangedHandler (object sender, EventArgs e) + { + mdi_container.SetParentText (false); + + if (form.MdiParent.MainMenuStrip != null) + form.MdiParent.MainMenuStrip.RefreshMdiItems (); + } + + private void FormLocationChangedHandler (object sender, EventArgs e) + { + if (form.window_state == FormWindowState.Minimized) + IconicBounds = form.Bounds; + form.MdiParent.MdiContainer.SizeScrollBars (); + } + + private void FormSizeChangedHandler (object sender, EventArgs e) + { + if (form.window_state == FormWindowState.Maximized && form.Bounds != MaximizedBounds) + form.Bounds = MaximizedBounds; + + form.MdiParent.MdiContainer.SizeScrollBars (); + } + + public MainMenu MergedMenu { + get { + if (merged_menu == null) + merged_menu = CreateMergedMenu (); + return merged_menu; + } + } + + private MainMenu CreateMergedMenu () + { + Form parent = (Form) mdi_container.Parent; + MainMenu clone; + if (parent.Menu != null) + clone = (MainMenu) parent.Menu.CloneMenu (); + else + clone = new MainMenu (); + + if (form.WindowState == FormWindowState.Maximized) { + + } + clone.MergeMenu (form.Menu); + clone.MenuChanged += new EventHandler (MenuChangedHandler); + clone.SetForm (parent); + return clone; + } + + public MainMenu MaximizedMenu { + get { + if (maximized_menu == null) + maximized_menu = CreateMaximizedMenu (); + return maximized_menu; + } + } + + private MainMenu CreateMaximizedMenu () + { + Form parent = (Form) mdi_container.Parent; + + if (form.MainMenuStrip != null || parent.MainMenuStrip != null) + return null; + + MainMenu res = new MainMenu (); + + if (parent.Menu != null) { + MainMenu clone = (MainMenu) parent.Menu.CloneMenu (); + res.MergeMenu (clone); + } + + if (form.Menu != null) { + MainMenu clone = (MainMenu) form.Menu.CloneMenu (); + res.MergeMenu (clone); + } + + if (res.MenuItems.Count == 0) + res.MenuItems.Add (new MenuItem ()); // Dummy item to get the menu height correct + + res.MenuItems.Insert (0, icon_menu); + + res.SetForm (parent); + return res; + } + + private void CreateIconMenus () + { + //TODO: remove this unneeded crap + } + + private void ClickIconMenuItem(object sender, EventArgs e) + { + if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime) { + form.Close (); + return; + } + icon_clicked_time = DateTime.Now; + Point pnt = Point.Empty; + pnt = form.MdiParent.PointToScreen (pnt); + pnt = form.PointToClient (pnt); + ShowPopup (pnt); + } + + internal void ShowPopup (Point pnt) + { + // If we are using MainMenuStrip, display that menu instead + if (form.WindowState == FormWindowState.Maximized && form.MdiParent.MainMenuStrip != null) + if (form.MdiParent.MainMenuStrip.Items.Count > 0) { + ToolStripItem tsi = form.MdiParent.MainMenuStrip.Items[0]; + + if (tsi is MdiWidgetStrip.SystemMenuItem) { + (tsi as MdiWidgetStrip.SystemMenuItem).ShowDropDown (); + return; + } + } + + } + + private void RestoreItemHandler (object sender, EventArgs e) + { + form.WindowState = FormWindowState.Normal; + } + + private void MoveItemHandler (object sender, EventArgs e) + { + int x = 0; + int y = 0; + + PointToScreen (ref x, ref y); + Cursor.Position = new Point (x, y); + form.Cursor = Cursors.Cross; + state = State.Moving; + form.Capture = true; + } + + private void SizeItemHandler (object sender, EventArgs e) + { + int x = 0; + int y = 0; + + PointToScreen (ref x, ref y); + Cursor.Position = new Point (x, y); + form.Cursor = Cursors.Cross; + state = State.Sizing; + form.Capture = true; + } + + private void MinimizeItemHandler (object sender, EventArgs e) + { + form.WindowState = FormWindowState.Minimized; + } + + private void MaximizeItemHandler (object sender, EventArgs e) + { + if (form.WindowState != FormWindowState.Maximized) + form.WindowState = FormWindowState.Maximized; + } + + private void CloseItemHandler (object sender, EventArgs e) + { + form.Close (); + } + + private void NextItemHandler (object sender, EventArgs e) + { + mdi_container.ActivateNextChild (); + } + + private void DrawIconMenuItem (object sender, DrawItemEventArgs de) + { + de.Graphics.DrawIcon (form.Icon, new Rectangle (de.Bounds.X + 2, de.Bounds.Y + 2, + de.Bounds.Height - 4, de.Bounds.Height - 4)); + } + + private void MeasureIconMenuItem (object sender, MeasureItemEventArgs me) + { + int size = SystemInformation.MenuHeight; + me.ItemHeight = size; + me.ItemWidth = size + 2; // some padding + } + + private void MenuChangedHandler (object sender, EventArgs e) + { + CreateMergedMenu (); + } + + public override void PointToClient (ref int x, ref int y) + { + XplatUI.ScreenToClient (mdi_container.Handle, ref x, ref y); + } + + public override void PointToScreen (ref int x, ref int y) + { + XplatUI.ClientToScreen (mdi_container.Handle, ref x, ref y); + } + + public override void UpdateWindowDecorations (FormWindowState window_state) + { + if (MaximizedMenu != null) { + switch (window_state) { + case FormWindowState.Minimized: + case FormWindowState.Normal: + MaximizedMenu.Paint -= draw_maximized_buttons; + MaximizedTitleButtons.Visible = false; + TitleButtons.Visible = true; + break; + case FormWindowState.Maximized: + MaximizedMenu.Paint += draw_maximized_buttons; + MaximizedTitleButtons.Visible = true; + TitleButtons.Visible = false; + break; + } + } + + base.UpdateWindowDecorations (window_state); + } + + public override void SetWindowState (FormWindowState old_state, FormWindowState window_state) + { + mdi_container.SetWindowState (form, old_state, window_state, false); + } + + private void FormClosed (object sender, EventArgs e) + { + mdi_container.ChildFormClosed (form); + + if (form.MdiParent.MainMenuStrip != null) + form.MdiParent.MainMenuStrip.RefreshMdiItems (); + + mdi_container.RemoveControlMenuItems (this); + } + + public override void DrawMaximizedButtons (object sender, PaintEventArgs pe) + { + Size bs = ThemeEngine.Current.ManagedWindowGetMenuButtonSize (this); + Point pnt = XplatUI.GetMenuOrigin (mdi_container.ParentForm.Handle); + int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); + TitleButtons buttons = MaximizedTitleButtons; + + buttons.Visible = true; + TitleButtons.Visible = false; + + buttons.CloseButton.Rectangle = new Rectangle (mdi_container.ParentForm.Size.Width - 1 - bw - bs.Width - 2, + pnt.Y + 2, bs.Width, bs.Height); + + buttons.RestoreButton.Rectangle = new Rectangle (buttons.CloseButton.Rectangle.Left - 2 - bs.Width, + pnt.Y + 2, bs.Width, bs.Height); + + buttons.MinimizeButton.Rectangle = new Rectangle (buttons.RestoreButton.Rectangle.Left - bs.Width, + pnt.Y + 2, bs.Width, bs.Height); + + DrawTitleButton (pe.Graphics, buttons.MinimizeButton, pe.ClipRectangle); + DrawTitleButton (pe.Graphics, buttons.RestoreButton, pe.ClipRectangle); + DrawTitleButton (pe.Graphics, buttons.CloseButton, pe.ClipRectangle); + + buttons.MinimizeButton.Rectangle.Y -= pnt.Y; + buttons.RestoreButton.Rectangle.Y -= pnt.Y; + buttons.CloseButton.Rectangle.Y -= pnt.Y; + } + + public bool HandleMenuMouseDown (MainMenu menu, int x, int y) + { + Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); + + HandleTitleBarDown (pt.X, pt.Y); + return TitleButtons.AnyPushedTitleButtons; + } + + public void HandleMenuMouseUp (MainMenu menu, int x, int y) + { + Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); + + HandleTitleBarUp (pt.X, pt.Y); + } + + public void HandleMenuMouseLeave (MainMenu menu, int x, int y) + { + Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); + HandleTitleBarLeave (pt.X, pt.Y); + + } + + public void HandleMenuMouseMove (MainMenu menu, int x, int y) + { + Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); + + HandleTitleBarMouseMove (pt.X, pt.Y); + + } + + protected override void HandleTitleBarLeave (int x, int y) + { + base.HandleTitleBarLeave (x, y); + + if (maximized_title_buttons != null) { + maximized_title_buttons.MouseLeave (x, y); + } + + if (IsMaximized) + XplatUI.InvalidateNC (form.MdiParent.Handle); + } + + protected override void HandleTitleBarUp (int x, int y) + { + if (IconRectangleContains (x, y)) { + if (!icon_dont_show_popup) { + if (IsMaximized) + ClickIconMenuItem (null, null); + else + ShowPopup (Point.Empty); + } else { + icon_dont_show_popup = false; + } + return; + } + + bool was_maximized = IsMaximized; + base.HandleTitleBarUp (x, y); + if (maximized_title_buttons != null && was_maximized) { + maximized_title_buttons.MouseUp (x, y); + } + + if (IsMaximized) + XplatUI.InvalidateNC (mdi_container.Parent.Handle); + } + + protected override void HandleTitleBarDoubleClick (int x, int y) + { + if (IconRectangleContains (x, y)) { + form.Close (); + } else if (form.MaximizeBox == true) { + form.WindowState = FormWindowState.Maximized; + } + base.HandleTitleBarDoubleClick (x, y); + } + + protected override void HandleTitleBarDown (int x, int y) + { + if (IconRectangleContains (x, y)) { + if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime && icon_clicked.X == x && icon_clicked.Y == y) { + form.Close (); + } else { + icon_clicked_time = DateTime.Now; + icon_clicked.X = x; + icon_clicked.Y = y; + } + + return; + } + + base.HandleTitleBarDown (x, y); + + if (maximized_title_buttons != null) { + maximized_title_buttons.MouseDown (x, y); + } + + if (IsMaximized) { + XplatUI.InvalidateNC (mdi_container.Parent.Handle); + } + } + + protected override void HandleTitleBarMouseMove (int x, int y) + { + base.HandleTitleBarMouseMove (x, y); + + if (maximized_title_buttons != null && maximized_title_buttons.MouseMove (x, y)) + XplatUI.InvalidateNC (form.MdiParent.Handle); + } + + protected override bool HandleLButtonDblClick (ref Message m) + { + + int x = Widget.LowOrder ((int)m.LParam.ToInt32 ()); + int y = Widget.HighOrder ((int)m.LParam.ToInt32 ()); + + // Correct since we are in NC land. + NCClientToNC (ref x, ref y); + + if (IconRectangleContains (x, y)) { + form.Close (); + return true; + } + + return base.HandleLButtonDblClick (ref m); + } + + protected override bool HandleLButtonDown (ref Message m) + { + + int x = Widget.LowOrder ((int)m.LParam.ToInt32 ()); + int y = Widget.HighOrder ((int)m.LParam.ToInt32 ()); + + // Correct y since we are in NC land. + NCClientToNC(ref x, ref y); + + if (IconRectangleContains (x, y)){ + if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime) { + form.Close (); + return true; + } else if (form.Capture) { + icon_dont_show_popup = true; + } + } + return base.HandleLButtonDown (ref m); + } + + protected override bool ShouldRemoveWindowManager (FormBorderStyle style) + { + return false; + } + + protected override void HandleWindowMove (Message m) + { + Point pos = Cursor.Position; + Point move = MouseMove (pos); + + if (move.X == 0 && move.Y == 0) + return; + + int x = virtual_position.X + move.X; + int y = virtual_position.Y + move.Y; + + Rectangle client = mdi_container.ClientRectangle; + if (mdi_container.VerticalScrollbarVisible) + client.Width -= SystemInformation.VerticalScrollBarWidth; + if (mdi_container.HorizontalScrollbarVisible) + client.Height -= SystemInformation.HorizontalScrollBarHeight; + + UpdateVP (x, y, form.Width, form.Height); + + start = pos; + } + + protected override bool HandleNCMouseMove (ref Message m) + { + XplatUI.RequestAdditionalWM_NCMessages (form.Handle, true, true); + return base.HandleNCMouseMove (ref m); + } + + protected override void DrawVirtualPosition (Rectangle virtual_position) + { + ClearVirtualPosition (); + + if (form.Parent != null) + XplatUI.DrawReversibleRectangle (form.Parent.Handle, virtual_position, 2); + prev_virtual_position = virtual_position; + } + + protected override void ClearVirtualPosition () + { + if (prev_virtual_position != Rectangle.Empty && form.Parent != null) + XplatUI.DrawReversibleRectangle (form.Parent.Handle, + prev_virtual_position, 2); + prev_virtual_position = Rectangle.Empty; + } + + protected override void OnWindowFinishedMoving () + { + form.Refresh (); + } + + public override bool IsActive { + get { + if (mdi_container == null) + return false; + return mdi_container.ActiveMdiChild == form; + } + } + + protected override void Activate () + { + if (mdi_container.ActiveMdiChild != form) { + mdi_container.ActivateChild (form); + } + base.Activate (); + } + } +} + |
