X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FInternalWindowManager.cs;h=ea58417925e84ceedb6e206a1c7e674b14f49e53;hb=2f9c820c7ee1063d9fabcb2410b57843c17cb926;hp=2cd02e793e2e2971364df295a27c366a59295872;hpb=40967aa9d98e641cc93041c4fc03271c071b7be3;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/InternalWindowManager.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/InternalWindowManager.cs index 2cd02e793e2..ea58417925e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/InternalWindowManager.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/InternalWindowManager.cs @@ -32,42 +32,20 @@ using System.Runtime.InteropServices; namespace System.Windows.Forms { - internal class InternalWindowManager { - private Size MinTitleBarSize = new Size (115, 25); - + internal abstract class InternalWindowManager { + private TitleButtons title_buttons; internal Form form; - internal TitleButton close_button; - internal TitleButton maximize_button; - internal TitleButton minimize_button; - - private ToolTip.ToolTipWindow tooltip; - private Timer tooltip_timer; - private TitleButton tooltip_hovered_button; - private TitleButton tooltip_hidden_button; - private const int tooltip_hide_interval = 3000; - private const int tooltip_show_interval = 1000; - private TitleButton [] title_buttons = new TitleButton [3]; - // moving windows internal Point start; internal State state; protected Point clicked_point; private FormPos sizing_edge; internal Rectangle virtual_position; - - public class TitleButton { - public Rectangle Rectangle; - public ButtonState State; - public CaptionButton Caption; - public EventHandler Clicked; - public TitleButton (CaptionButton caption, EventHandler clicked) - { - Caption = caption; - Clicked = clicked; - } - } + private Rectangle normal_bounds; + private Rectangle iconic_bounds; + public enum State { Idle, @@ -101,27 +79,99 @@ namespace System.Windows.Forms { form.SizeChanged += new EventHandler (FormSizeChangedHandler); - CreateButtons (); + title_buttons = new TitleButtons (form); + ThemeEngine.Current.ManagedWindowSetButtonLocations (this); } public Form Form { get { return form; } } + + public int IconWidth { + get { return TitleBarHeight - 5; } + } - public bool AnyPushedTitleButtons { + public TitleButtons TitleButtons { + get { + return title_buttons; + } + } + internal Rectangle NormalBounds { get { - return (minimize_button != null && minimize_button.State == ButtonState.Pushed) || - (maximize_button != null && maximize_button.State == ButtonState.Pushed) || - (close_button != null && close_button.State == ButtonState.Pushed); + return normal_bounds; + } + set { + normal_bounds = value; + } + } + internal Size IconicSize { + get { + return SystemInformation.MinimizedWindowSize; } } - public int IconWidth { - get { return TitleBarHeight - 5; } + internal Rectangle IconicBounds { + get { + if (iconic_bounds == Rectangle.Empty) + return Rectangle.Empty; + Rectangle result = iconic_bounds; + result.Y = Form.Parent.ClientRectangle.Bottom - iconic_bounds.Y; + return result; + } + set { + iconic_bounds = value; + iconic_bounds.Y = Form.Parent.ClientRectangle.Bottom - iconic_bounds.Y; + } + } + + internal virtual Rectangle MaximizedBounds { + get { + return Form.Parent.ClientRectangle; + } } + + public virtual void UpdateWindowState (FormWindowState old_window_state, FormWindowState new_window_state, bool force) + { + if (old_window_state == FormWindowState.Normal) { + NormalBounds = form.Bounds; + } else if (old_window_state == FormWindowState.Minimized) { + IconicBounds = form.Bounds; + } + + switch (new_window_state) { + case FormWindowState.Minimized: + if (IconicBounds == Rectangle.Empty) { + Size size = IconicSize; + Point location = new Point (0, Form.Parent.ClientSize.Height - size.Height); + IconicBounds = new Rectangle (location, size); + } + form.Bounds = IconicBounds; + break; + case FormWindowState.Maximized: + form.Bounds = MaximizedBounds; + break; + case FormWindowState.Normal: + form.Bounds = NormalBounds; + break; + } - public virtual bool HandleMessage (ref Message m) + UpdateWindowDecorations (new_window_state); + form.ResetCursor (); + } + + public virtual void UpdateWindowDecorations (FormWindowState window_state) + { + ThemeEngine.Current.ManagedWindowSetButtonLocations (this); + if (form.IsHandleCreated) + XplatUI.RequestNCRecalc (form.Handle); + } + + public virtual bool WndProc (ref Message m) { +#if debug + Console.WriteLine(DateTime.Now.ToLongTimeString () + " " + this.GetType () .Name + " (Handle={0},Text={1}) received message {2}", form.IsHandleCreated ? form.Handle : IntPtr.Zero, form.Text, m.ToString ()); +#endif + switch ((Msg)m.Msg) { @@ -174,59 +224,97 @@ namespace System.Windows.Forms { HandleNCMouseLeave (ref m); break; - case Msg.WM_MOUSE_LEAVE: + case Msg.WM_MOUSELEAVE: HandleMouseLeave (ref m); break; case Msg.WM_NCCALCSIZE: - HandleNCCalcSize (ref m); - break; + return HandleNCCalcSize (ref m); case Msg.WM_NCPAINT: - return HandleNCPaint (); + return HandleNCPaint (ref m); } return false; } - protected virtual bool HandleNCPaint () + protected virtual bool HandleNCPaint (ref Message m) { - PaintEventArgs pe = XplatUI.PaintEventStart (form.Handle, false); + PaintEventArgs pe = XplatUI.PaintEventStart (ref m, form.Handle, false); Rectangle clip; - // clip region is not correct on win32. - // if (m.WParam.ToInt32 () > 1) { - // Region r = Region.FromHrgn (m.WParam); - // RectangleF rf = r.GetBounds (pe.Graphics); - // clip = new Rectangle ((int) rf.X, (int) rf.Y, (int) rf.Width, (int) rf.Height); - //} else { - clip = new Rectangle (0, 0, form.Width, form.Height); - //} - - ThemeEngine.Current.DrawManagedWindowDecorations (pe.Graphics, clip, this); - XplatUI.PaintEventEnd (form.Handle, false); + + if (form.ActiveMenu != null) { + Point pnt; + + pnt = GetMenuOrigin (); + + // The entire menu has to be in the clip rectangle because the + // control buttons are right-aligned and otherwise they would + // stay painted when the window gets resized. + clip = new Rectangle (pnt.X, pnt.Y, form.ClientSize.Width, 0); + clip = Rectangle.Union (clip, pe.ClipRectangle); + pe.SetClip (clip); + pe.Graphics.SetClip (clip); + + form.ActiveMenu.Draw (pe, new Rectangle (pnt.X, pnt.Y, form.ClientSize.Width, 0)); + } + if (HasBorders || IsMinimized && !(Form.IsMdiChild && IsMaximized)) { + // clip region is not correct on win32. + // use the entire form's area. + clip = new Rectangle (0, 0, form.Width, form.Height); + ThemeEngine.Current.DrawManagedWindowDecorations (pe.Graphics, clip, this); + } + XplatUI.PaintEventEnd (ref m, form.Handle, false); return true; } - protected virtual void HandleNCCalcSize (ref Message m) + protected virtual bool HandleNCCalcSize (ref Message m) { XplatUIWin32.NCCALCSIZE_PARAMS ncp; + XplatUIWin32.RECT rect; if (m.WParam == (IntPtr)1) { ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (m.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS)); + + ncp.rgrc1 = NCCalcSize (ncp.rgrc1); - int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); + Marshal.StructureToPtr (ncp, m.LParam, true); + } else { + rect = (XplatUIWin32.RECT) Marshal.PtrToStructure (m.LParam, typeof (XplatUIWin32.RECT)); + + rect = NCCalcSize (rect); + + Marshal.StructureToPtr (rect, m.LParam, true); + } + + return true; + } - if (HasBorders) { - ncp.rgrc1.top += TitleBarHeight + bw; - ncp.rgrc1.bottom -= bw; - ncp.rgrc1.left += bw; - ncp.rgrc1.right -= bw; - } + protected virtual XplatUIWin32.RECT NCCalcSize (XplatUIWin32.RECT proposed_window_rect) + { + int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); - Marshal.StructureToPtr (ncp, m.LParam, true); + if (HasBorders) { + proposed_window_rect.top += TitleBarHeight + bw; + proposed_window_rect.bottom -= bw; + proposed_window_rect.left += bw; + proposed_window_rect.right -= bw; } + + if (XplatUI.RequiresPositiveClientAreaSize) { + // This is necessary for Linux, can't handle <= 0-sized + // client areas correctly. + if (proposed_window_rect.right <= proposed_window_rect.left) { + proposed_window_rect.right += proposed_window_rect.left - proposed_window_rect.right + 1; + } + if (proposed_window_rect.top >= proposed_window_rect.bottom) { + proposed_window_rect.bottom += proposed_window_rect.top - proposed_window_rect.bottom + 1; + } + } + + return proposed_window_rect; } protected virtual bool HandleNCHitTest (ref Message m) @@ -281,93 +369,23 @@ namespace System.Windows.Forms { public virtual void UpdateBorderStyle (FormBorderStyle border_style) { - XplatUI.SetBorderStyle (form.Handle, border_style); + if (form.IsHandleCreated) { + XplatUI.SetBorderStyle (form.Handle, border_style); + } if (ShouldRemoveWindowManager (border_style)) { form.RemoveWindowManager (); return; } - CreateButtons (); - } - - #region ToolTip helpers - // Called from MouseMove if mouse is over a button - private void ToolTipStart (TitleButton button) - { - tooltip_hovered_button = button; - - if (tooltip_hovered_button == tooltip_hidden_button) - return; - tooltip_hidden_button = null; - - if (tooltip != null && tooltip.Visible) - ToolTipShow (true); - - if (tooltip_timer == null) { - - tooltip_timer = new Timer (); - tooltip_timer.Tick += new EventHandler (ToolTipTimerTick); - } - - tooltip_timer.Interval = tooltip_show_interval; - tooltip_timer.Start (); - tooltip_hovered_button = button; - } - - private void ToolTipTimerTick (object sender, EventArgs e) - { - if (tooltip_timer.Interval == tooltip_hide_interval) { - tooltip_hidden_button = tooltip_hovered_button; - ToolTipHide (false); - } else { - ToolTipShow (false); - } + ThemeEngine.Current.ManagedWindowSetButtonLocations (this); } - // Called from timer (with only_refresh = false) - // Called from ToolTipStart if tooltip is already shown (with only_refresh = true) - private void ToolTipShow (bool only_refresh) - { - string text = Locale.GetText (tooltip_hovered_button.Caption.ToString ()); - - tooltip_timer.Interval = tooltip_hide_interval; - tooltip_timer.Enabled = true; - - if (only_refresh && (tooltip == null || !tooltip.Visible )) { - return; - } - - if (tooltip == null) - tooltip = new ToolTip.ToolTipWindow (); - else if (tooltip.Text == text && tooltip.Visible) - return; - else if (tooltip.Visible) - tooltip.Visible = false; - if (form.WindowState == FormWindowState.Maximized) - tooltip.Present (form.MdiParent, text); - else - tooltip.Present (form, text); - - } - // Called from MouseLeave (with reset_hidden_button = true) - // Called from MouseDown (with reset_hidden_button = false) - // Called from MouseMove if mouse isn't over any button (with reset_hidden_button = false) - // Called from Timer if hiding (with reset_hidden_button = false) - private void ToolTipHide (bool reset_hidden_button) - { - if (tooltip_timer != null) - tooltip_timer.Enabled = false; - if (tooltip != null && tooltip.Visible) - tooltip.Visible = false; - if (reset_hidden_button) - tooltip_hidden_button = null; - } - #endregion public virtual void SetWindowState (FormWindowState old_state, FormWindowState window_state) { + UpdateWindowState (old_state, window_state, false); } public virtual FormWindowState GetWindowState () @@ -402,54 +420,48 @@ namespace System.Windows.Forms { return style != FormBorderStyle.FixedToolWindow && style != FormBorderStyle.SizableToolWindow; } - protected virtual void Activate () + public bool IconRectangleContains (int x, int y) { - form.Refresh (); - } + if (!ShowIcon) + return false; - public virtual bool IsActive () - { - return true; + Rectangle icon = ThemeEngine.Current.ManagedWindowGetTitleBarIconArea (this); + return icon.Contains (x, y); } + public bool ShowIcon { + get { + if (!Form.ShowIcon) + return false; + if (!HasBorders) + return false; + if (IsMinimized) + return true; + if (IsToolWindow || Form.FormBorderStyle == FormBorderStyle.FixedDialog) + return false; + return true; + } + } - private void FormSizeChangedHandler (object sender, EventArgs e) + protected virtual void Activate () { - ThemeEngine.Current.ManagedWindowSetButtonLocations (this); - XplatUI.InvalidateNC (form.Handle); + form.Invalidate (true); + form.Update (); } - protected void CreateButtons () - { - switch (form.FormBorderStyle) { - case FormBorderStyle.None: - close_button = null; - minimize_button = null; - maximize_button = null; - if (IsMaximized || IsMinimized) - goto case FormBorderStyle.Sizable; - break; - case FormBorderStyle.FixedToolWindow: - case FormBorderStyle.SizableToolWindow: - close_button = new TitleButton (CaptionButton.Close, new EventHandler (CloseClicked)); - if (IsMaximized || IsMinimized) - goto case FormBorderStyle.Sizable; - break; - case FormBorderStyle.FixedSingle: - case FormBorderStyle.Fixed3D: - case FormBorderStyle.FixedDialog: - case FormBorderStyle.Sizable: - close_button = new TitleButton (CaptionButton.Close, new EventHandler (CloseClicked)); - minimize_button = new TitleButton (CaptionButton.Minimize, new EventHandler (MinimizeClicked)); - maximize_button = new TitleButton (CaptionButton.Maximize, new EventHandler (MaximizeClicked)); - break; + public virtual bool IsActive { + get { + return true; } + } - title_buttons [0] = close_button; - title_buttons [1] = minimize_button; - title_buttons [2] = maximize_button; - ThemeEngine.Current.ManagedWindowSetButtonLocations (this); + private void FormSizeChangedHandler (object sender, EventArgs e) + { + if (form.IsHandleCreated) { + ThemeEngine.Current.ManagedWindowSetButtonLocations (this); + XplatUI.InvalidateNC (form.Handle); + } } protected virtual bool HandleRButtonDown (ref Message m) @@ -498,6 +510,11 @@ namespace System.Windows.Forms { return true; } + if (form.ActiveMenu != null && XplatUI.IsEnabled (form.Handle)) { + MouseEventArgs mea = new MouseEventArgs (Form.FromParamToMouseButtons (m.WParam.ToInt32 ()), form.mouse_clicks, x, y, 0); + form.ActiveMenu.OnMouseMove (form, mea); + } + return true; } @@ -516,6 +533,11 @@ namespace System.Windows.Forms { NCPointToClient (ref x, ref y); FormPos pos = FormPosForCoords (x, y); + if (form.ActiveMenu != null && XplatUI.IsEnabled (form.Handle)) { + MouseEventArgs mea = new MouseEventArgs (Form.FromParamToMouseButtons (m.WParam.ToInt32 ()), form.mouse_clicks, x, y - TitleBarHeight, 0); + form.ActiveMenu.OnMouseDown (form, mea); + } + if (pos == FormPos.TitleBar) { HandleTitleBarDown (x, y); return true; @@ -556,82 +578,30 @@ namespace System.Windows.Forms { protected virtual void HandleTitleBarLeave (int x, int y) { - foreach (TitleButton button in title_buttons) { - if (button != null) { - button.State = ButtonState.Normal; - } - } - ToolTipHide (true); - return; + title_buttons.MouseLeave (x, y); } protected virtual void HandleTitleBarMouseMove (int x, int y) { - bool any_change = false; - bool any_tooltip = false; - bool any_pushed_buttons = AnyPushedTitleButtons; - - foreach (TitleButton button in title_buttons) { - if (button == null) - continue; - - if (button.Rectangle.Contains (x, y)) { - if (any_pushed_buttons) { - any_change |= button.State != ButtonState.Pushed; - button.State = ButtonState.Pushed; - } - ToolTipStart (button); - any_tooltip = true; - } else { - if (any_pushed_buttons) { - any_change |= button.State != ButtonState.Normal; - button.State = ButtonState.Normal; - } - } - } - if (any_change) { - if (IsMaximized && form.IsMdiChild) - XplatUI.InvalidateNC (form.MdiParent.Handle); - else - XplatUI.InvalidateNC (form.Handle); - } - if (!any_tooltip) - ToolTipHide (false); + if (title_buttons.MouseMove (x, y)) + XplatUI.InvalidateNC (form.Handle); } protected virtual void HandleTitleBarUp (int x, int y) { - foreach (TitleButton button in title_buttons) { - if (button == null) - continue; - - button.State = ButtonState.Normal; - if (button.Rectangle.Contains (x, y)) { - button.Clicked (this, EventArgs.Empty); - } - } + title_buttons.MouseUp (x, y); return; } protected virtual void HandleTitleBarDown (int x, int y) { - ToolTipHide (false); - - foreach (TitleButton button in title_buttons) { - if (button != null) { - if (button.Rectangle.Contains (x, y)) { - button.State = ButtonState.Pushed; - } else { - button.State = ButtonState.Normal; - } - } - } - - if (!AnyPushedTitleButtons && !IsMaximized){ + title_buttons.MouseDown (x, y); + + if (!TitleButtons.AnyPushedTitleButtons && !IsMaximized) { state = State.Moving; clicked_point = new Point (x, y); - if (form.IsMdiChild) { + if (form.Parent != null) { form.CaptureWithConfine (form.Parent); } else { form.Capture = true; @@ -662,7 +632,7 @@ namespace System.Windows.Forms { protected virtual void HandleWindowMove (Message m) { - Point move = MouseMove (m); + Point move = MouseMove (Cursor.Position); UpdateVP (virtual_position.X + move.X, virtual_position.Y + move.Y, virtual_position.Width, virtual_position.Height); @@ -671,9 +641,17 @@ namespace System.Windows.Forms { private void HandleSizing (Message m) { Rectangle pos = virtual_position; - int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); - int mw = MinTitleBarSize.Width + (bw * 2); - int mh = MinTitleBarSize.Height + (bw * 2); + int mw; + int mh; + if (IsToolWindow) { + int border_width = BorderWidth; + mw = 2 * (border_width + Theme.ManagedWindowSpacingAfterLastTitleButton) + ThemeEngine.Current.ManagedWindowButtonSize (this).Width; + mh = 2 * border_width + TitleBarHeight; + } else { + Size minimum_size = SystemInformation.MinWindowTrackSize; + mw = minimum_size.Width; + mh = minimum_size.Height; + } int x = Cursor.Position.X; int y = Cursor.Position.Y; @@ -735,7 +713,8 @@ namespace System.Windows.Forms { public bool IsToolWindow { get { if (form.FormBorderStyle == FormBorderStyle.SizableToolWindow || - form.FormBorderStyle == FormBorderStyle.FixedToolWindow) + form.FormBorderStyle == FormBorderStyle.FixedToolWindow || + form.GetCreateParams().IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) return true; return false; } @@ -747,6 +726,18 @@ namespace System.Windows.Forms { } } + public int BorderWidth { + get { + return ThemeEngine.Current.ManagedWindowBorderWidth (this); + } + } + + public virtual int MenuHeight { + get { + return (form.Menu != null ? ThemeEngine.Current.MenuHeight : 0); + } + } + protected void UpdateVP (Rectangle r) { UpdateVP (r.X, r.Y, r.Width, r.Height); @@ -775,7 +766,10 @@ namespace System.Windows.Forms { ClearVirtualPosition (); form.Capture = false; - form.Bounds = virtual_position; + if (state == State.Moving && form.Location != virtual_position.Location) + form.Location = virtual_position.Location; + else if (state == State.Sizing && form.Bounds != virtual_position) + form.Bounds = virtual_position; state = State.Idle; OnWindowFinishedMoving (); @@ -811,42 +805,16 @@ namespace System.Windows.Forms { if (!button.Rectangle.IntersectsWith (clip)) return; - dc.FillRectangle (SystemBrushes.Control, button.Rectangle); - ControlPaint.DrawCaptionButton (dc, button.Rectangle, - button.Caption, button.State); + ThemeEngine.Current.ManagedWindowDrawMenuButton (dc, button, clip, this); } public virtual void DrawMaximizedButtons (object sender, PaintEventArgs pe) { } - protected virtual void CloseClicked (object sender, EventArgs e) - { - form.Close (); - } - - private void MinimizeClicked (object sender, EventArgs e) - { - if (GetWindowState () != FormWindowState.Minimized) { - form.WindowState = FormWindowState.Minimized; - } else { - form.WindowState = FormWindowState.Normal; - } - } - - private void MaximizeClicked (object sender, EventArgs e) - { - if (GetWindowState () != FormWindowState.Maximized) { - form.WindowState = FormWindowState.Maximized; - } else { - form.WindowState = FormWindowState.Normal; - } - } - - protected Point MouseMove (Message m) + protected Point MouseMove (Point pos) { - Point cp = Cursor.Position; - return new Point (cp.X - start.X, cp.Y - start.Y); + return new Point (pos.X - start.X, pos.Y - start.Y); } protected virtual void DrawVirtualPosition (Rectangle virtual_position) @@ -871,12 +839,18 @@ namespace System.Windows.Forms { protected virtual void NCClientToNC (ref int x, ref int y) { y += TitleBarHeight; - y += ThemeEngine.Current.ManagedWindowBorderWidth (this); + y += BorderWidth; + y += MenuHeight; + } + + internal Point GetMenuOrigin () + { + return new Point (BorderWidth, BorderWidth + TitleBarHeight); } protected FormPos FormPosForCoords (int x, int y) { - int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); + int bw = BorderWidth; if (y < TitleBarHeight + bw) { // Console.WriteLine ("A"); if (y > bw && x > bw && @@ -921,6 +895,317 @@ namespace System.Windows.Forms { return FormPos.None; } } + internal class TitleButton + { + public Rectangle Rectangle; + public ButtonState State; + public CaptionButton Caption; + private EventHandler Clicked; + public bool Visible; + bool entered; + + public TitleButton (CaptionButton caption, EventHandler clicked) + { + Caption = caption; + Clicked = clicked; + } + + public void OnClick () + { + if (Clicked != null) { + Clicked (this, EventArgs.Empty); + } + } + + public bool Entered { + get { return entered; } + set { entered = value; } + } + } + + internal class TitleButtons : System.Collections.IEnumerable + { + public TitleButton MinimizeButton; + public TitleButton MaximizeButton; + public TitleButton RestoreButton; + public TitleButton CloseButton; + public TitleButton HelpButton; + + public TitleButton [] AllButtons; + public bool Visible; + + private ToolTip.ToolTipWindow tooltip; + private Timer tooltip_timer; + private TitleButton tooltip_hovered_button; + private TitleButton tooltip_hidden_button; + private const int tooltip_hide_interval = 3000; + private const int tooltip_show_interval = 1000; + private Form form; + + public TitleButtons (Form frm) + { + this.form = frm; + this.Visible = true; + + MinimizeButton = new TitleButton (CaptionButton.Minimize, new EventHandler (ClickHandler)); + MaximizeButton = new TitleButton (CaptionButton.Maximize, new EventHandler (ClickHandler)); + RestoreButton = new TitleButton (CaptionButton.Restore, new EventHandler (ClickHandler)); + CloseButton = new TitleButton (CaptionButton.Close, new EventHandler (ClickHandler)); + HelpButton = new TitleButton (CaptionButton.Help, new EventHandler (ClickHandler)); + + AllButtons = new TitleButton [] { MinimizeButton, MaximizeButton, RestoreButton, CloseButton, HelpButton }; + } + + private void ClickHandler (object sender, EventArgs e) + { + if (!Visible) { + return; + } + + TitleButton button = (TitleButton) sender; + + switch (button.Caption) { + case CaptionButton.Close: + form.Close (); + break; + case CaptionButton.Help: + Console.WriteLine ("Help not implemented."); + break; + case CaptionButton.Maximize: + form.WindowState = FormWindowState.Maximized; + break; + case CaptionButton.Minimize: + form.WindowState = FormWindowState.Minimized; + break; + case CaptionButton.Restore: + form.WindowState = FormWindowState.Normal; + break; + } + } + + public TitleButton FindButton (int x, int y) + { + if (!Visible) { + return null; + } + + foreach (TitleButton button in AllButtons) { + if (button.Visible && button.Rectangle.Contains (x, y)) { + return button; + } + } + return null; + } + + public bool AnyPushedTitleButtons { + get { + if (!Visible) { + return false; + } + + foreach (TitleButton button in AllButtons) { + if (button.Visible && button.State == ButtonState.Pushed) { + return true; + } + } + return false; + } + } + + #region IEnumerable Members + + public System.Collections.IEnumerator GetEnumerator () + { + return AllButtons.GetEnumerator (); + } + #endregion + + #region ToolTip helpers + // Called from MouseMove if mouse is over a button + public void ToolTipStart (TitleButton button) + { + tooltip_hovered_button = button; + + if (tooltip_hovered_button == tooltip_hidden_button) + return; + tooltip_hidden_button = null; + + if (tooltip != null && tooltip.Visible) + ToolTipShow (true); + + if (tooltip_timer == null) { + + tooltip_timer = new Timer (); + tooltip_timer.Tick += new EventHandler (ToolTipTimerTick); + } + + tooltip_timer.Interval = tooltip_show_interval; + tooltip_timer.Start (); + tooltip_hovered_button = button; + } + + public void ToolTipTimerTick (object sender, EventArgs e) + { + if (tooltip_timer.Interval == tooltip_hide_interval) { + tooltip_hidden_button = tooltip_hovered_button; + ToolTipHide (false); + } else { + ToolTipShow (false); + } + } + // Called from timer (with only_refresh = false) + // Called from ToolTipStart if tooltip is already shown (with only_refresh = true) + public void ToolTipShow (bool only_refresh) + { + if (!form.Visible) + return; + + string text = Locale.GetText (tooltip_hovered_button.Caption.ToString ()); + + tooltip_timer.Interval = tooltip_hide_interval; + tooltip_timer.Enabled = true; + + if (only_refresh && (tooltip == null || !tooltip.Visible)) { + return; + } + + if (tooltip == null) + tooltip = new ToolTip.ToolTipWindow (); + else if (tooltip.Text == text && tooltip.Visible) + return; + else if (tooltip.Visible) + tooltip.Visible = false; + + if (form.WindowState == FormWindowState.Maximized && form.MdiParent != null) + tooltip.Present (form.MdiParent, text); + else + tooltip.Present (form, text); + + } + + // Called from MouseLeave (with reset_hidden_button = true) + // Called from MouseDown (with reset_hidden_button = false) + // Called from MouseMove if mouse isn't over any button (with reset_hidden_button = false) + // Called from Timer if hiding (with reset_hidden_button = false) + public void ToolTipHide (bool reset_hidden_button) + { + if (tooltip_timer != null) + tooltip_timer.Enabled = false; + if (tooltip != null && tooltip.Visible) + tooltip.Visible = false; + if (reset_hidden_button) + tooltip_hidden_button = null; + } + #endregion + + public bool MouseMove (int x, int y) + { + if (!Visible) { + return false; + } + + bool any_change = false; + bool any_pushed_buttons = AnyPushedTitleButtons; + bool any_tooltip = false; + TitleButton over_button = FindButton (x, y); + + foreach (TitleButton button in this) { + if (button == null) + continue; + + if (button.State == ButtonState.Inactive) + continue; + + if (button == over_button) { + if (any_pushed_buttons) { + any_change |= button.State != ButtonState.Pushed; + button.State = ButtonState.Pushed; + } + ToolTipStart (button); + any_tooltip = true; + if (!button.Entered) { + button.Entered = true; + if (ThemeEngine.Current.ManagedWindowTitleButtonHasHotElementStyle (button, form)) + any_change = true; + } + } else { + if (any_pushed_buttons) { + any_change |= button.State != ButtonState.Normal; + button.State = ButtonState.Normal; + } + if (button.Entered) { + button.Entered = false; + if (ThemeEngine.Current.ManagedWindowTitleButtonHasHotElementStyle (button, form)) + any_change = true; + } + } + } + + if (!any_tooltip) + ToolTipHide (false); + + return any_change; + } + + public void MouseDown (int x, int y) + { + if (!Visible) { + return; + } + + ToolTipHide (false); + + foreach (TitleButton button in this) { + if (button != null && button.State != ButtonState.Inactive) { + button.State = ButtonState.Normal; + } + } + TitleButton clicked_button = FindButton (x, y); + if (clicked_button != null && clicked_button.State != ButtonState.Inactive) { + clicked_button.State = ButtonState.Pushed; + } + } + + public void MouseUp (int x, int y) + { + if (!Visible) { + return; + } + + TitleButton clicked_button = FindButton (x, y); + if (clicked_button != null && clicked_button.State != ButtonState.Inactive) { + clicked_button.OnClick (); + } + + foreach (TitleButton button in this) { + if (button == null || button.State == ButtonState.Inactive) + continue; + + button.State = ButtonState.Normal; + } + + if (clicked_button == CloseButton && !form.closing) + XplatUI.InvalidateNC (form.Handle); + + ToolTipHide (true); + } + + internal void MouseLeave (int x, int y) + { + if (!Visible) { + return; + } + + foreach (TitleButton button in this) { + if (button == null || button.State == ButtonState.Inactive) + continue; + + button.State = ButtonState.Normal; + } + + ToolTipHide (true); + } + } }