1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Jackson Harper (jackson@ximian.com)
30 using System.Runtime.InteropServices;
33 namespace System.Windows.Forms {
35 internal abstract class InternalWindowManager {
36 private Size MinTitleBarSize = new Size (115, 25);
37 private TitleButtons title_buttons;
43 protected Point clicked_point;
44 private FormPos sizing_edge;
45 internal Rectangle virtual_position;
47 private Rectangle normal_bounds;
48 private Rectangle iconic_bounds;
69 TopRight = Top | Right,
71 BottomLeft = Bottom | Left,
72 BottomRight = Bottom | Right,
74 AnyEdge = Top | Left | Right | Bottom,
77 public InternalWindowManager (Form form)
81 form.SizeChanged += new EventHandler (FormSizeChangedHandler);
83 title_buttons = new TitleButtons (form);
84 ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
91 public int IconWidth {
92 get { return TitleBarHeight - 5; }
95 public TitleButtons TitleButtons {
100 internal Rectangle NormalBounds {
102 return normal_bounds;
105 normal_bounds = value;
108 internal Size IconicSize {
110 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
111 return new Size (152 + bw * 2, TitleBarHeight + bw * 2);
115 internal Rectangle IconicBounds {
117 if (iconic_bounds == Rectangle.Empty)
118 return Rectangle.Empty;
119 Rectangle result = iconic_bounds;
120 result.Y = Form.Parent.ClientRectangle.Bottom - iconic_bounds.Y;
124 iconic_bounds = value;
125 iconic_bounds.Y = Form.Parent.ClientRectangle.Bottom - iconic_bounds.Y;
129 internal virtual Rectangle MaximizedBounds {
131 return Form.Parent.ClientRectangle;
135 public virtual void UpdateWindowState (FormWindowState old_window_state, FormWindowState new_window_state, bool force)
137 if (old_window_state == FormWindowState.Normal) {
138 NormalBounds = form.Bounds;
139 } else if (old_window_state == FormWindowState.Minimized) {
140 IconicBounds = form.Bounds;
143 switch (new_window_state) {
144 case FormWindowState.Minimized:
145 if (IconicBounds == Rectangle.Empty) {
146 Size size = IconicSize;
147 Point location = new Point (0, Form.Parent.ClientSize.Height - size.Height);
148 IconicBounds = new Rectangle (location, size);
150 form.Bounds = IconicBounds;
152 case FormWindowState.Maximized:
153 form.Bounds = MaximizedBounds;
155 case FormWindowState.Normal:
156 form.Bounds = NormalBounds;
160 UpdateWindowDecorations (new_window_state);
164 public virtual void UpdateWindowDecorations (FormWindowState window_state)
166 ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
167 XplatUI.RequestNCRecalc (form.Handle);
170 public virtual bool WndProc (ref Message m)
173 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 ());
176 switch ((Msg)m.Msg) {
179 // The mouse handling messages are actually
180 // not WM_NC* messages except for the first button and NCMOVEs
181 // down because we capture on the form
183 case Msg.WM_MOUSEMOVE:
184 return HandleMouseMove (form, ref m);
186 case Msg.WM_LBUTTONUP:
187 HandleLButtonUp (ref m);
190 case Msg.WM_RBUTTONDOWN:
191 return HandleRButtonDown (ref m);
193 case Msg.WM_LBUTTONDOWN:
194 return HandleLButtonDown (ref m);
196 case Msg.WM_LBUTTONDBLCLK:
197 return HandleLButtonDblClick (ref m);
199 case Msg.WM_PARENTNOTIFY:
200 if (Control.LowOrder(m.WParam.ToInt32()) == (int) Msg.WM_LBUTTONDOWN)
204 case Msg.WM_NCHITTEST:
205 return HandleNCHitTest (ref m);
207 // Return true from these guys, otherwise win32 will mess up z-order
208 case Msg.WM_NCLBUTTONUP:
209 HandleNCLButtonUp (ref m);
212 case Msg.WM_NCLBUTTONDOWN:
213 HandleNCLButtonDown (ref m);
216 case Msg.WM_NCMOUSEMOVE:
217 HandleNCMouseMove (ref m);
220 case Msg.WM_NCLBUTTONDBLCLK:
221 HandleNCLButtonDblClick (ref m);
224 case Msg.WM_NCMOUSELEAVE:
225 HandleNCMouseLeave (ref m);
228 case Msg.WM_MOUSE_LEAVE:
229 HandleMouseLeave (ref m);
232 case Msg.WM_NCCALCSIZE:
233 HandleNCCalcSize (ref m);
237 return HandleNCPaint ();
243 protected virtual bool HandleNCPaint ()
245 PaintEventArgs pe = XplatUI.PaintEventStart (form.Handle, false);
248 // clip region is not correct on win32.
249 // if (m.WParam.ToInt32 () > 1) {
250 // Region r = Region.FromHrgn (m.WParam);
251 // RectangleF rf = r.GetBounds (pe.Graphics);
252 // clip = new Rectangle ((int) rf.X, (int) rf.Y, (int) rf.Width, (int) rf.Height);
254 clip = new Rectangle (0, 0, form.Width, form.Height);
257 ThemeEngine.Current.DrawManagedWindowDecorations (pe.Graphics, clip, this);
258 XplatUI.PaintEventEnd (form.Handle, false);
262 protected virtual void HandleNCCalcSize (ref Message m)
264 XplatUIWin32.NCCALCSIZE_PARAMS ncp;
266 if (m.WParam == (IntPtr)1) {
267 ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (m.LParam,
268 typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
270 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
273 ncp.rgrc1.top += TitleBarHeight + bw;
274 ncp.rgrc1.bottom -= bw;
275 ncp.rgrc1.left += bw;
276 ncp.rgrc1.right -= bw;
279 // This is necessary for Linux, can't handle <= 0-sized
280 // client areas correctly.
281 if (ncp.rgrc1.right <= ncp.rgrc1.left) {
282 ncp.rgrc1.right += ncp.rgrc1.left - ncp.rgrc1.right + 1;
284 if (ncp.rgrc1.top >= ncp.rgrc1.bottom) {
285 ncp.rgrc1.bottom += ncp.rgrc1.top - ncp.rgrc1.bottom + 1;
288 Marshal.StructureToPtr (ncp, m.LParam, true);
292 protected virtual bool HandleNCHitTest (ref Message m)
295 int x = Control.LowOrder ((int)m.LParam.ToInt32 ());
296 int y = Control.HighOrder ((int)m.LParam.ToInt32 ());
298 NCPointToClient (ref x, ref y);
300 FormPos pos = FormPosForCoords (x, y);
302 if (pos == FormPos.TitleBar) {
303 m.Result = new IntPtr ((int)HitTest.HTCAPTION);
312 m.Result = new IntPtr ((int)HitTest.HTTOP);
315 m.Result = new IntPtr ((int)HitTest.HTLEFT);
318 m.Result = new IntPtr ((int)HitTest.HTRIGHT);
321 m.Result = new IntPtr ((int)HitTest.HTBOTTOM);
323 case FormPos.TopLeft:
324 m.Result = new IntPtr ((int)HitTest.HTTOPLEFT);
326 case FormPos.TopRight:
327 m.Result = new IntPtr ((int)HitTest.HTTOPRIGHT);
329 case FormPos.BottomLeft:
330 m.Result = new IntPtr ((int)HitTest.HTBOTTOMLEFT);
332 case FormPos.BottomRight:
333 m.Result = new IntPtr ((int)HitTest.HTBOTTOMRIGHT);
336 // We return false so that DefWndProc handles things
342 public virtual void UpdateBorderStyle (FormBorderStyle border_style)
344 XplatUI.SetBorderStyle (form.Handle, border_style);
346 if (ShouldRemoveWindowManager (border_style)) {
347 form.RemoveWindowManager ();
351 ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
356 public virtual void SetWindowState (FormWindowState old_state, FormWindowState window_state)
358 UpdateWindowState (old_state, window_state, false);
361 public virtual FormWindowState GetWindowState ()
363 return form.window_state;
366 public virtual void PointToClient (ref int x, ref int y)
368 // toolwindows stay in screencoords we just have to make sure
369 // they obey the working area
370 Rectangle working = SystemInformation.WorkingArea;
372 if (x > working.Right)
374 if (x < working.Left)
379 if (y > working.Bottom)
383 public virtual void PointToScreen (ref int x, ref int y)
385 XplatUI.ClientToScreen (form.Handle, ref x, ref y);
388 protected virtual bool ShouldRemoveWindowManager (FormBorderStyle style)
390 return style != FormBorderStyle.FixedToolWindow && style != FormBorderStyle.SizableToolWindow;
393 public bool IconRectangleContains (int x, int y)
395 if (form.Icon == null)
398 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
399 Rectangle icon = new Rectangle (bw + 3, bw + 2, IconWidth, IconWidth);
400 return icon.Contains (x, y);
403 protected virtual void Activate ()
408 public virtual bool IsActive {
415 private void FormSizeChangedHandler (object sender, EventArgs e)
417 ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
418 XplatUI.InvalidateNC (form.Handle);
421 protected virtual bool HandleRButtonDown (ref Message m)
427 protected virtual bool HandleLButtonDown (ref Message m)
433 protected virtual bool HandleLButtonDblClick(ref Message m)
438 protected virtual bool HandleNCMouseLeave (ref Message m)
440 int x = Control.LowOrder ((int)m.LParam.ToInt32 ());
441 int y = Control.HighOrder ((int)m.LParam.ToInt32 ());
443 NCPointToClient (ref x, ref y);
444 FormPos pos = FormPosForCoords (x, y);
446 if (pos != FormPos.TitleBar) {
447 HandleTitleBarLeave (x, y);
454 protected virtual bool HandleNCMouseMove (ref Message m)
456 int x = Control.LowOrder((int)m.LParam.ToInt32( ));
457 int y = Control.HighOrder((int)m.LParam.ToInt32( ));
459 NCPointToClient (ref x, ref y);
460 FormPos pos = FormPosForCoords (x, y);
462 if (pos == FormPos.TitleBar) {
463 HandleTitleBarMouseMove (x, y);
471 protected virtual bool HandleNCLButtonDown (ref Message m)
475 start = Cursor.Position;
476 virtual_position = form.Bounds;
478 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
479 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
481 // Need to adjust because we are in NC land
482 NCPointToClient (ref x, ref y);
483 FormPos pos = FormPosForCoords (x, y);
485 if (pos == FormPos.TitleBar) {
486 HandleTitleBarDown (x, y);
491 if ((pos & FormPos.AnyEdge) == 0)
494 virtual_position = form.Bounds;
495 state = State.Sizing;
504 protected virtual void HandleNCLButtonDblClick (ref Message m)
506 int x = Control.LowOrder ((int)m.LParam.ToInt32 ());
507 int y = Control.HighOrder ((int)m.LParam.ToInt32 ());
509 // Need to adjust because we are in NC land
510 NCPointToClient (ref x, ref y);
512 FormPos pos = FormPosForCoords (x, y);
513 if (pos == FormPos.TitleBar || pos == FormPos.Top)
514 HandleTitleBarDoubleClick (x, y);
518 protected virtual void HandleTitleBarDoubleClick (int x, int y)
523 protected virtual void HandleTitleBarLeave (int x, int y)
525 title_buttons.MouseLeave (x, y);
528 protected virtual void HandleTitleBarMouseMove (int x, int y)
530 bool any_change = false;
532 any_change = title_buttons.MouseMove (x, y);
535 if (IsMaximized && form.IsMdiChild)
536 XplatUI.InvalidateNC (form.MdiParent.Handle);
538 XplatUI.InvalidateNC (form.Handle);
542 protected virtual void HandleTitleBarUp (int x, int y)
544 title_buttons.MouseUp (x, y);
549 protected virtual void HandleTitleBarDown (int x, int y)
551 title_buttons.MouseDown (x, y);
553 if (!TitleButtons.AnyPushedTitleButtons && !IsMaximized) {
554 state = State.Moving;
555 clicked_point = new Point (x, y);
556 if (form.Parent != null) {
557 form.CaptureWithConfine (form.Parent);
563 XplatUI.InvalidateNC (form.Handle);
566 private bool HandleMouseMove (Form form, ref Message m)
570 HandleWindowMove (m);
580 private void HandleMouseLeave (ref Message m)
585 protected virtual void HandleWindowMove (Message m)
587 Point move = MouseMove (m);
589 UpdateVP (virtual_position.X + move.X, virtual_position.Y + move.Y,
590 virtual_position.Width, virtual_position.Height);
593 private void HandleSizing (Message m)
595 Rectangle pos = virtual_position;
596 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
597 int mw = MinTitleBarSize.Width + (bw * 2);
598 int mh = MinTitleBarSize.Height + (bw * 2);
599 int x = Cursor.Position.X;
600 int y = Cursor.Position.Y;
602 PointToClient (ref x, ref y);
604 if ((sizing_edge & FormPos.Top) != 0) {
605 if (pos.Bottom - y < mh)
607 pos.Height = pos.Bottom - y;
609 } else if ((sizing_edge & FormPos.Bottom) != 0) {
610 int height = y - pos.Top;
616 if ((sizing_edge & FormPos.Left) != 0) {
617 if (pos.Right - x < mw)
619 pos.Width = pos.Right - x;
621 } else if ((sizing_edge & FormPos.Right) != 0) {
622 int width = x - form.Left;
631 public bool IsMaximized {
632 get { return GetWindowState () == FormWindowState.Maximized; }
635 public bool IsMinimized {
636 get { return GetWindowState () == FormWindowState.Minimized; }
639 public bool IsSizable {
641 switch (form.FormBorderStyle) {
642 case FormBorderStyle.Sizable:
643 case FormBorderStyle.SizableToolWindow:
644 return (form.window_state != FormWindowState.Minimized);
651 public bool HasBorders {
653 return form.FormBorderStyle != FormBorderStyle.None;
657 public bool IsToolWindow {
659 if (form.FormBorderStyle == FormBorderStyle.SizableToolWindow ||
660 form.FormBorderStyle == FormBorderStyle.FixedToolWindow)
666 public int TitleBarHeight {
668 return ThemeEngine.Current.ManagedWindowTitleBarHeight (this);
672 protected void UpdateVP (Rectangle r)
674 UpdateVP (r.X, r.Y, r.Width, r.Height);
677 protected void UpdateVP (Point loc, int w, int h)
679 UpdateVP (loc.X, loc.Y, w, h);
682 protected void UpdateVP (int x, int y, int w, int h)
684 virtual_position.X = x;
685 virtual_position.Y = y;
686 virtual_position.Width = w;
687 virtual_position.Height = h;
689 DrawVirtualPosition (virtual_position);
692 protected virtual void HandleLButtonUp (ref Message m)
694 if (state == State.Idle)
697 ClearVirtualPosition ();
699 form.Capture = false;
700 if (state == State.Moving && form.Location != virtual_position.Location)
701 form.Location = virtual_position.Location;
702 else if (state == State.Sizing && form.Bounds != virtual_position)
703 form.Bounds = virtual_position;
706 OnWindowFinishedMoving ();
709 private bool HandleNCLButtonUp (ref Message m)
712 ClearVirtualPosition ();
714 form.Capture = false;
716 if (form.MdiContainer != null)
717 form.MdiContainer.SizeScrollBars();
720 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
721 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
723 NCPointToClient (ref x, ref y);
724 FormPos pos = FormPosForCoords (x, y);
726 if (pos == FormPos.TitleBar) {
727 HandleTitleBarUp (x, y);
734 protected void DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip)
736 if (!button.Rectangle.IntersectsWith (clip))
739 dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
740 ControlPaint.DrawCaptionButton (dc, button.Rectangle,
741 button.Caption, button.State);
744 public virtual void DrawMaximizedButtons (object sender, PaintEventArgs pe)
748 protected Point MouseMove (Message m)
750 Point cp = Cursor.Position;
751 return new Point (cp.X - start.X, cp.Y - start.Y);
754 protected virtual void DrawVirtualPosition (Rectangle virtual_position)
756 form.Bounds = virtual_position;
757 start = Cursor.Position;
760 protected virtual void ClearVirtualPosition ()
765 protected virtual void OnWindowFinishedMoving ()
769 protected virtual void NCPointToClient(ref int x, ref int y) {
770 form.PointToClient(ref x, ref y);
771 NCClientToNC (ref x, ref y);
774 protected virtual void NCClientToNC (ref int x, ref int y) {
776 y += ThemeEngine.Current.ManagedWindowBorderWidth (this);
779 protected FormPos FormPosForCoords (int x, int y)
781 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
782 if (y < TitleBarHeight + bw) {
783 // Console.WriteLine ("A");
784 if (y > bw && x > bw &&
786 return FormPos.TitleBar;
788 if (x < bw || (x < 20 && y < bw))
789 return FormPos.TopLeft;
791 if (x > form.Width - bw ||
792 (x > form.Width - 20 && y < bw))
793 return FormPos.TopRight;
798 } else if (y > form.Height - 20) {
799 // Console.WriteLine ("B");
801 (x < 20 && y > form.Height - bw))
802 return FormPos.BottomLeft;
804 if (x > form.Width - (bw * 2) ||
805 (x > form.Width - 20 &&
806 y > form.Height - bw))
807 return FormPos.BottomRight;
809 if (y > form.Height - (bw * 2))
810 return FormPos.Bottom;
814 // Console.WriteLine ("C");
816 } else if (x > form.Width - (bw * 2)) {
817 // Console.WriteLine ("D");
818 return FormPos.Right;
820 // Console.WriteLine ("E {0}", form.Width - bw);
826 internal class TitleButton
828 public Rectangle Rectangle;
829 public ButtonState State;
830 public CaptionButton Caption;
831 private EventHandler Clicked;
834 public TitleButton (CaptionButton caption, EventHandler clicked)
840 public void OnClick ()
842 if (Clicked != null) {
843 Clicked (this, EventArgs.Empty);
848 internal class TitleButtons : System.Collections.IEnumerable
850 public TitleButton MinimizeButton;
851 public TitleButton MaximizeButton;
852 public TitleButton RestoreButton;
853 public TitleButton CloseButton;
854 public TitleButton HelpButton;
856 public TitleButton [] AllButtons;
859 private ToolTip.ToolTipWindow tooltip;
860 private Timer tooltip_timer;
861 private TitleButton tooltip_hovered_button;
862 private TitleButton tooltip_hidden_button;
863 private const int tooltip_hide_interval = 3000;
864 private const int tooltip_show_interval = 1000;
867 public TitleButtons (Form frm)
872 MinimizeButton = new TitleButton (CaptionButton.Minimize, new EventHandler (ClickHandler));
873 MaximizeButton = new TitleButton (CaptionButton.Maximize, new EventHandler (ClickHandler));
874 RestoreButton = new TitleButton (CaptionButton.Restore, new EventHandler (ClickHandler));
875 CloseButton = new TitleButton (CaptionButton.Close, new EventHandler (ClickHandler));
876 HelpButton = new TitleButton (CaptionButton.Help, new EventHandler (ClickHandler));
878 AllButtons = new TitleButton [] { MinimizeButton, MaximizeButton, RestoreButton, CloseButton, HelpButton };
881 private void ClickHandler (object sender, EventArgs e)
887 TitleButton button = (TitleButton) sender;
889 switch (button.Caption) {
890 case CaptionButton.Close:
893 case CaptionButton.Help:
894 Console.WriteLine ("Help not implemented.");
896 case CaptionButton.Maximize:
897 form.WindowState = FormWindowState.Maximized;
899 case CaptionButton.Minimize:
900 form.WindowState = FormWindowState.Minimized;
902 case CaptionButton.Restore:
903 form.WindowState = FormWindowState.Normal;
908 public TitleButton FindButton (int x, int y)
914 foreach (TitleButton button in AllButtons) {
915 if (button.Visible && button.Rectangle.Contains (x, y)) {
922 public bool AnyPushedTitleButtons {
928 foreach (TitleButton button in AllButtons) {
929 if (button.Visible && button.State == ButtonState.Pushed) {
937 #region IEnumerable Members
939 public System.Collections.IEnumerator GetEnumerator ()
941 return AllButtons.GetEnumerator ();
945 #region ToolTip helpers
946 // Called from MouseMove if mouse is over a button
947 public void ToolTipStart (TitleButton button)
949 tooltip_hovered_button = button;
951 if (tooltip_hovered_button == tooltip_hidden_button)
953 tooltip_hidden_button = null;
955 if (tooltip != null && tooltip.Visible)
958 if (tooltip_timer == null) {
960 tooltip_timer = new Timer ();
961 tooltip_timer.Tick += new EventHandler (ToolTipTimerTick);
964 tooltip_timer.Interval = tooltip_show_interval;
965 tooltip_timer.Start ();
966 tooltip_hovered_button = button;
969 public void ToolTipTimerTick (object sender, EventArgs e)
971 if (tooltip_timer.Interval == tooltip_hide_interval) {
972 tooltip_hidden_button = tooltip_hovered_button;
978 // Called from timer (with only_refresh = false)
979 // Called from ToolTipStart if tooltip is already shown (with only_refresh = true)
980 public void ToolTipShow (bool only_refresh)
982 string text = Locale.GetText (tooltip_hovered_button.Caption.ToString ());
984 tooltip_timer.Interval = tooltip_hide_interval;
985 tooltip_timer.Enabled = true;
987 if (only_refresh && (tooltip == null || !tooltip.Visible)) {
992 tooltip = new ToolTip.ToolTipWindow ();
993 else if (tooltip.Text == text && tooltip.Visible)
995 else if (tooltip.Visible)
996 tooltip.Visible = false;
998 if (form.WindowState == FormWindowState.Maximized && form.MdiParent != null)
999 tooltip.Present (form.MdiParent, text);
1001 tooltip.Present (form, text);
1005 // Called from MouseLeave (with reset_hidden_button = true)
1006 // Called from MouseDown (with reset_hidden_button = false)
1007 // Called from MouseMove if mouse isn't over any button (with reset_hidden_button = false)
1008 // Called from Timer if hiding (with reset_hidden_button = false)
1009 public void ToolTipHide (bool reset_hidden_button)
1011 if (tooltip_timer != null)
1012 tooltip_timer.Enabled = false;
1013 if (tooltip != null && tooltip.Visible)
1014 tooltip.Visible = false;
1015 if (reset_hidden_button)
1016 tooltip_hidden_button = null;
1020 public bool MouseMove (int x, int y)
1026 bool any_change = false;
1027 bool any_pushed_buttons = AnyPushedTitleButtons;
1028 bool any_tooltip = false;
1029 TitleButton over_button = FindButton (x, y);
1031 foreach (TitleButton button in this) {
1035 if (button == over_button) {
1036 if (any_pushed_buttons) {
1037 any_change |= button.State != ButtonState.Pushed;
1038 button.State = ButtonState.Pushed;
1040 ToolTipStart (button);
1043 if (any_pushed_buttons) {
1044 any_change |= button.State != ButtonState.Normal;
1045 button.State = ButtonState.Normal;
1051 ToolTipHide (false);
1056 public void MouseDown (int x, int y)
1062 ToolTipHide (false);
1064 foreach (TitleButton button in this) {
1065 if (button != null) {
1066 button.State = ButtonState.Normal;
1069 TitleButton clicked_button = FindButton (x, y);
1070 if (clicked_button != null) {
1071 clicked_button.State = ButtonState.Pushed;
1075 public void MouseUp (int x, int y)
1081 TitleButton clicked_button = FindButton (x, y);
1082 if (clicked_button != null) {
1083 clicked_button.OnClick ();
1086 foreach (TitleButton button in this) {
1090 button.State = ButtonState.Normal;
1094 internal void MouseLeave (int x, int y)
1100 foreach (TitleButton button in this) {
1104 button.State = ButtonState.Normal;