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/ToolTip.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/ToolTip.cs')
| -rw-r--r-- | source/ShiftUI/Internal/ToolTip.cs | 1004 |
1 files changed, 1004 insertions, 0 deletions
diff --git a/source/ShiftUI/Internal/ToolTip.cs b/source/ShiftUI/Internal/ToolTip.cs new file mode 100644 index 0000000..24895fb --- /dev/null +++ b/source/ShiftUI/Internal/ToolTip.cs @@ -0,0 +1,1004 @@ +// 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) 2004 Novell, Inc. (http://www.novell.com) +// +// Authors: +// Peter Bartok [email protected] +// +// + +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Text; +using ShiftUI; +using System; + +namespace ShiftUI { + [DefaultEvent ("Popup")] + [ProvideProperty ("ToolTip", typeof(Widget))] + [ToolboxItemFilter("ShiftUI", ToolboxItemFilterType.Allow)] + public class ToolTip : System.ComponentModel.Component, System.ComponentModel.IExtenderProvider { + #region Local variables + internal bool is_active; + internal int automatic_delay; + internal int autopop_delay; + internal int initial_delay; + internal int re_show_delay; + internal bool show_always; + + internal Color back_color; + internal Color fore_color; + + internal ToolTipWindow tooltip_window; // The actual tooltip window + internal Hashtable tooltip_strings; // List of strings for each Widget, indexed by Widget + internal ArrayList Widgets; + internal Widget active_Widget; // Widget for which the tooltip is currently displayed + internal Widget last_Widget; // last Widget the mouse was in + internal Timer timer; // Used for the various intervals + private Form hooked_form; + + private bool isBalloon; + private bool owner_draw; + private bool stripAmpersands; + private ToolTipIcon tool_tip_icon; + private bool useAnimation; + private bool useFading; + private object tag; + + #endregion // Local variables + + #region ToolTipWindow Class + internal class ToolTipWindow : Widget { + #region ToolTipWindow Class Local Variables + private Widget associated_Widget; + internal Icon icon; + internal string title = String.Empty; + internal Rectangle icon_rect; + internal Rectangle title_rect; + internal Rectangle text_rect; + #endregion // ToolTipWindow Class Local Variables + + #region ToolTipWindow Class Constructor + internal ToolTipWindow() { + Visible = false; + Size = new Size(100, 20); + ForeColor = ThemeEngine.Current.ColorInfoText; + BackColor = ThemeEngine.Current.ColorInfo; + + VisibleChanged += new EventHandler(ToolTipWindow_VisibleChanged); + + // UIA Framework: Used to generate UnPopup + VisibleChanged += new EventHandler (OnUIAToolTip_VisibleChanged); + + SetStyle (Widgetstyles.UserPaint | Widgetstyles.AllPaintingInWmPaint, true); + SetStyle (Widgetstyles.ResizeRedraw, true); + if (ThemeEngine.Current.ToolTipTransparentBackground) { + SetStyle (Widgetstyles.SupportsTransparentBackColor, true); + BackColor = Color.Transparent; + } else + SetStyle (Widgetstyles.Opaque, true); + } + + #endregion // ToolTipWindow Class Constructor + + #region ToolTipWindow Class Protected Instance Methods + protected override void OnCreateWidget() { + base.OnCreateWidget (); + XplatUI.SetTopmost(this.window.Handle, true); + } + + protected override CreateParams CreateParams { + get { + CreateParams cp; + + cp = base.CreateParams; + + cp.Style = (int)WindowStyles.WS_POPUP; + cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS; + + cp.ExStyle = (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST); + + return cp; + } + } + + protected override void OnPaint(PaintEventArgs pevent) { + // We don't do double-buffering on purpose: + // 1) we'd have to meddle with is_visible, it destroys the buffers if !visible + // 2) We don't draw much, no need to double buffer + base.OnPaint(pevent); + + OnDraw (new DrawToolTipEventArgs (pevent.Graphics, associated_Widget, associated_Widget, ClientRectangle, this.Text, this.BackColor, this.ForeColor, this.Font)); + } + + protected override void OnTextChanged (EventArgs args) + { + Invalidate (); + base.OnTextChanged (args); + } + + protected override void WndProc(ref Message m) { + if (m.Msg == (int)Msg.WM_SETFOCUS) { + if (m.WParam != IntPtr.Zero) { + XplatUI.SetFocus(m.WParam); + } + } + base.WndProc (ref m); + } + + + #endregion // ToolTipWindow Class Protected Instance Methods + + #region ToolTipWindow Class Private Methods + internal virtual void OnDraw (DrawToolTipEventArgs e) + { + DrawToolTipEventHandler eh = (DrawToolTipEventHandler)(Events[DrawEvent]); + if (eh != null) + eh (this, e); + else + ThemeEngine.Current.DrawToolTip (e.Graphics, e.Bounds, this); + } + + internal virtual void OnPopup (PopupEventArgs e) + { + PopupEventHandler eh = (PopupEventHandler)(Events[PopupEvent]); + if (eh != null) + eh (this, e); + else + e.ToolTipSize = ThemeEngine.Current.ToolTipSize (this, Text); + } + + private void ToolTipWindow_VisibleChanged(object sender, EventArgs e) { + Widget Widget = (Widget)sender; + + if (Widget.is_visible) { + XplatUI.SetTopmost(Widget.window.Handle, true); + } else { + XplatUI.SetTopmost(Widget.window.Handle, false); + } + } + + // UIA Framework + private void OnUIAToolTip_VisibleChanged (object sender, EventArgs e) + { + if (Visible == false) + OnUnPopup (new PopupEventArgs (associated_Widget, associated_Widget, false, Size.Empty)); + } + + private void OnUnPopup (PopupEventArgs e) + { + PopupEventHandler eh = (PopupEventHandler) (Events [UnPopupEvent]); + if (eh != null) + eh (this, e); + } + + + #endregion // ToolTipWindow Class Protected Instance Methods + + #region Internal Properties + internal override bool ActivateOnShow { get { return false; } } + #endregion + + // This Present is used when we are using the expicit Show methods for 2.0. + // It will not reposition the window. + public void PresentModal (Widget Widget, string text) + { + if (IsDisposed) + return; + + Size display_size; + XplatUI.GetDisplaySize (out display_size); + + associated_Widget = Widget; + + Text = text; + + PopupEventArgs pea = new PopupEventArgs (Widget, Widget, false, Size.Empty); + OnPopup (pea); + + if (pea.Cancel) + return; + + Size = pea.ToolTipSize; + + Visible = true; + } + + public void Present (Widget Widget, string text) + { + if (IsDisposed) + return; + + Size display_size; + XplatUI.GetDisplaySize (out display_size); + + associated_Widget = Widget; + + Text = text; + + PopupEventArgs pea = new PopupEventArgs (Widget, Widget, false, Size.Empty); + OnPopup (pea); + + if (pea.Cancel) + return; + + Size size = pea.ToolTipSize; + + Width = size.Width; + Height = size.Height; + + int cursor_w, cursor_h, hot_x, hot_y; + XplatUI.GetCursorInfo (Widget.Cursor.Handle, out cursor_w, out cursor_h, out hot_x, out hot_y); + Point loc = Widget.MousePosition; + loc.Y += (cursor_h - hot_y); + + if ((loc.X + Width) > display_size.Width) + loc.X = display_size.Width - Width; + + if ((loc.Y + Height) > display_size.Height) + loc.Y = Widget.MousePosition.Y - Height - hot_y; + + Location = loc; + Visible = true; + BringToFront (); + } + + + #region Internal Events + static object DrawEvent = new object (); + static object PopupEvent = new object (); + + // UIA Framework + static object UnPopupEvent = new object (); + + public event DrawToolTipEventHandler Draw { + add { Events.AddHandler (DrawEvent, value); } + remove { Events.RemoveHandler (DrawEvent, value); } + } + + public event PopupEventHandler Popup { + add { Events.AddHandler (PopupEvent, value); } + remove { Events.RemoveHandler (PopupEvent, value); } + } + + internal event PopupEventHandler UnPopup { + add { Events.AddHandler (UnPopupEvent, value); } + remove { Events.RemoveHandler (UnPopupEvent, value); } + } + #endregion + } + #endregion // ToolTipWindow Class + + #region Public Constructors & Destructors + public ToolTip() { + + // Defaults from MS + is_active = true; + automatic_delay = 500; + autopop_delay = 5000; + initial_delay = 500; + re_show_delay = 100; + show_always = false; + back_color = SystemColors.Info; + fore_color = SystemColors.InfoText; + + isBalloon = false; + stripAmpersands = false; + useAnimation = true; + useFading = true; + tooltip_strings = new Hashtable(5); + Widgets = new ArrayList(5); + + tooltip_window = new ToolTipWindow(); + tooltip_window.MouseLeave += new EventHandler(Widget_MouseLeave); + tooltip_window.Draw += new DrawToolTipEventHandler (tooltip_window_Draw); + tooltip_window.Popup += new PopupEventHandler (tooltip_window_Popup); + + // UIA Framework: Static event handlers + tooltip_window.UnPopup += delegate (object sender, PopupEventArgs args) { + OnUnPopup (args); + }; + UnPopup += new PopupEventHandler (OnUIAUnPopup); + + timer = new Timer(); + timer.Enabled = false; + timer.Tick +=new EventHandler(timer_Tick); + + } + + + #region UIA Framework: Events, Delegates and Methods + // NOTE: + // We are using Reflection to add/remove internal events. + // Class ToolTipListener uses the events. + // + // - UIAUnPopup. Event used to generate ChildRemoved in ToolTip + // - UIAToolTipHookUp. Event used to keep track of associated Widgets + // - UIAToolTipUnhookUp. Event used to remove track of associated Widgets + static object UnPopupEvent = new object (); + + internal event PopupEventHandler UnPopup { + add { Events.AddHandler (UnPopupEvent, value); } + remove { Events.RemoveHandler (UnPopupEvent, value); } + } + + internal static event PopupEventHandler UIAUnPopup; + internal static event WidgetEventHandler UIAToolTipHookUp; + internal static event WidgetEventHandler UIAToolTipUnhookUp; + + internal Rectangle UIAToolTipRectangle { + get { return tooltip_window.Bounds; } + } + + internal static void OnUIAUnPopup (object sender, PopupEventArgs args) + { + if (UIAUnPopup != null) + UIAUnPopup (sender, args); + } + + internal static void OnUIAToolTipHookUp (object sender, WidgetEventArgs args) + { + if (UIAToolTipHookUp != null) + UIAToolTipHookUp (sender, args); + } + + internal static void OnUIAToolTipUnhookUp (object sender, WidgetEventArgs args) + { + if (UIAToolTipUnhookUp != null) + UIAToolTipUnhookUp (sender, args); + } + + #endregion + + public ToolTip(System.ComponentModel.IContainer cont) : this() { + cont.Add (this); + } + + ~ToolTip() { + } + #endregion // Public Constructors & Destructors + + #region Public Instance Properties + [DefaultValue (true)] + public bool Active { + get { + return is_active; + } + + set { + if (is_active != value) { + is_active = value; + + if (tooltip_window.Visible) { + tooltip_window.Visible = false; + active_Widget = null; + } + } + } + } + + [DefaultValue (500)] + [RefreshProperties (RefreshProperties.All)] + public int AutomaticDelay { + get { + return automatic_delay; + } + + set { + if (automatic_delay != value) { + automatic_delay = value; + autopop_delay = automatic_delay * 10; + initial_delay = automatic_delay; + re_show_delay = automatic_delay / 5; + } + } + } + + [RefreshProperties (RefreshProperties.All)] + public int AutoPopDelay { + get { + return autopop_delay; + } + + set { + if (autopop_delay != value) { + autopop_delay = value; + } + } + } + + [DefaultValue ("Color [Info]")] + public Color BackColor { + get { return this.back_color; } + set { this.back_color = value; tooltip_window.BackColor = value; } + } + + [DefaultValue ("Color [InfoText]")] + public Color ForeColor + { + get { return this.fore_color; } + set { this.fore_color = value; tooltip_window.ForeColor = value; } + } + + [RefreshProperties (RefreshProperties.All)] + public int InitialDelay { + get { + return initial_delay; + } + + set { + if (initial_delay != value) { + initial_delay = value; + } + } + } + + [DefaultValue (false)] + public bool OwnerDraw { + get { return this.owner_draw; } + set { this.owner_draw = value; } + } + + [RefreshProperties (RefreshProperties.All)] + public int ReshowDelay { + get { + return re_show_delay; + } + + set { + if (re_show_delay != value) { + re_show_delay = value; + } + } + } + + [DefaultValue (false)] + public bool ShowAlways { + get { + return show_always; + } + + set { + if (show_always != value) { + show_always = value; + } + } + } + + + [DefaultValue (false)] + public bool IsBalloon { + get { return isBalloon; } + set { isBalloon = value; } + } + + [Browsable (true)] + [DefaultValue (false)] + public bool StripAmpersands { + get { return stripAmpersands; } + set { stripAmpersands = value; } + } + + [Localizable (false)] + [Bindable (true)] + [TypeConverter (typeof (StringConverter))] + [DefaultValue (null)] + public object Tag { + get { return tag; } + set { tag = value; } + } + + [DefaultValue (ToolTipIcon.None)] + public ToolTipIcon ToolTipIcon { + get { return this.tool_tip_icon; } + set { + switch (value) { + case ToolTipIcon.None: + tooltip_window.icon = null; + break; + case ToolTipIcon.Error: + tooltip_window.icon = SystemIcons.Error; + break; + case ToolTipIcon.Warning: + tooltip_window.icon = SystemIcons.Warning; + break; + case ToolTipIcon.Info: + tooltip_window.icon = SystemIcons.Information; + break; + } + + tool_tip_icon = value; + } + } + + [DefaultValue ("")] + public string ToolTipTitle { + get { return tooltip_window.title; } + set { + if (value == null) + value = String.Empty; + + tooltip_window.title = value; + } + } + + [Browsable (true)] + [DefaultValue (true)] + public bool UseAnimation { + get { return useAnimation; } + set { useAnimation = value; } + } + + [Browsable (true)] + [DefaultValue (true)] + public bool UseFading { + get { return useFading; } + set { useFading = value; } + } + + #endregion // Public Instance Properties + + #region Protected Properties + protected virtual CreateParams CreateParams + { + get + { + CreateParams cp = new CreateParams (); + + cp.Style = 2; + + return cp; + } + } + #endregion + + #region Public Instance Methods + public bool CanExtend(object target) { + return false; + } + + [Localizable (true)] + [DefaultValue ("")] + public string GetToolTip (Widget Widget) + { + string tooltip = (string)tooltip_strings[Widget]; + if (tooltip == null) + return ""; + return tooltip; + } + + public void RemoveAll() { + tooltip_strings.Clear(); + //UIA Framework: ToolTip isn't associated anymore + foreach (Widget Widget in Widgets) + OnUIAToolTipUnhookUp (this, new WidgetEventArgs (Widget)); + + Widgets.Clear(); + } + + public void SetToolTip(Widget Widget, string caption) { + // UIA Framework + OnUIAToolTipHookUp (this, new WidgetEventArgs (Widget)); + tooltip_strings[Widget] = caption; + + // no need for duplicates + if (!Widgets.Contains(Widget)) { + Widget.MouseEnter += new EventHandler(Widget_MouseEnter); + Widget.MouseMove += new MouseEventHandler(Widget_MouseMove); + Widget.MouseLeave += new EventHandler(Widget_MouseLeave); + Widget.MouseDown += new MouseEventHandler (Widget_MouseDown); + Widgets.Add(Widget); + } + + // if SetToolTip is called from a Widget and the mouse is currently over that Widget, + // make sure that tooltip_window.Text gets updated if it's being shown, + // or show the tooltip for it if is not + if (active_Widget == Widget && caption != null && state == TipState.Show) { + Size size = ThemeEngine.Current.ToolTipSize(tooltip_window, caption); + tooltip_window.Width = size.Width; + tooltip_window.Height = size.Height; + tooltip_window.Text = caption; + timer.Stop (); + timer.Start (); + } else if (Widget.IsHandleCreated && MouseInWidget (Widget, false)) + ShowTooltip (Widget); + } + + public override string ToString() { + return base.ToString() + " InitialDelay: " + initial_delay + ", ShowAlways: " + show_always; + } + + public void Show (string text, IWin32Window window) + { + Show (text, window, 0); + } + + public void Show (string text, IWin32Window window, int duration) + { + if (window == null) + throw new ArgumentNullException ("window"); + if (duration < 0) + throw new ArgumentOutOfRangeException ("duration", "duration cannot be less than zero"); + + if (!Active) + return; + + timer.Stop (); + + Widget c = (Widget)window; + + XplatUI.SetOwner (tooltip_window.Handle, c.TopLevelWidget.Handle); + + // If the mouse is in the requested window, use that position + // Else, center in the requested window + if (c.ClientRectangle.Contains (c.PointToClient (Widget.MousePosition))) { + tooltip_window.Location = Widget.MousePosition; + tooltip_strings[c] = text; + HookupWidgetEvents (c); + } + else + tooltip_window.Location = c.PointToScreen (new Point (c.Width / 2, c.Height / 2)); + + // We need to hide our tooltip if the form loses focus, is closed, or is minimized + HookupFormEvents ((Form)c.TopLevelWidget); + + tooltip_window.PresentModal ((Widget)window, text); + + state = TipState.Show; + + if (duration > 0) { + timer.Interval = duration; + timer.Start (); + } + } + + public void Show (string text, IWin32Window window, Point point) + { + Show (text, window, point, 0); + } + + public void Show (string text, IWin32Window window, int x, int y) + { + Show (text, window, new Point (x, y), 0); + } + + public void Show (string text, IWin32Window window, Point point, int duration) + { + if (window == null) + throw new ArgumentNullException ("window"); + if (duration < 0) + throw new ArgumentOutOfRangeException ("duration", "duration cannot be less than zero"); + + if (!Active) + return; + + timer.Stop (); + + Widget c = (Widget)window; + + Point display_point = c.PointToScreen (Point.Empty); + display_point.X += point.X; + display_point.Y += point.Y; + + XplatUI.SetOwner (tooltip_window.Handle, c.TopLevelWidget.Handle); + + // We need to hide our tooltip if the form loses focus, is closed, or is minimized + HookupFormEvents ((Form)c.TopLevelWidget); + + tooltip_window.Location = display_point; + tooltip_window.PresentModal ((Widget)window, text); + + state = TipState.Show; + + if (duration > 0) { + timer.Interval = duration; + timer.Start (); + } + } + + public void Show (string text, IWin32Window window, int x, int y, int duration) + { + Show (text, window, new Point (x, y), duration); + } + + public void Hide (IWin32Window win) + { + timer.Stop (); + state = TipState.Initial; + + UnhookFormEvents (); + tooltip_window.Visible = false; + } + #endregion // Public Instance Methods + + #region Protected Instance Methods + protected override void Dispose(bool disposing) { + // call the base impl first to avoid conflicts with any parent's events + base.Dispose (disposing); + + if (disposing) { + // Mop up the mess; or should we wait for the GC to kick in? + timer.Stop(); + timer.Dispose(); + + // Not sure if we should clean up tooltip_window + tooltip_window.Dispose(); + + tooltip_strings.Clear(); + + //UIA Framework: ToolTip isn't associated anymore + foreach (Widget Widget in Widgets) + OnUIAToolTipUnhookUp (this, new WidgetEventArgs (Widget)); + Widgets.Clear(); + } + } + + protected void StopTimer () + { + timer.Stop (); + } + #endregion // Protected Instance Methods + + internal enum TipState { + Initial, + Show, + Down + } + + TipState state = TipState.Initial; + + #region Private Methods + + private void HookupFormEvents (Form form) + { + hooked_form = form; + + form.Deactivate += new EventHandler (Form_Deactivate); + form.Closed += new EventHandler (Form_Closed); + form.Resize += new EventHandler (Form_Resize); + } + + private void HookupWidgetEvents (Widget widget) + { + if (!Widgets.Contains (widget)) { + widget.MouseEnter += new EventHandler (Widget_MouseEnter); + widget.MouseMove += new MouseEventHandler (Widget_MouseMove); + widget.MouseLeave += new EventHandler (Widget_MouseLeave); + widget.MouseDown += new MouseEventHandler (Widget_MouseDown); + Widgets.Add (widget); + } + } + + private void UnhookWidgetEvents (Widget widget) + { + widget.MouseEnter -= new EventHandler (Widget_MouseEnter); + widget.MouseMove -= new MouseEventHandler (Widget_MouseMove); + widget.MouseLeave -= new EventHandler (Widget_MouseLeave); + widget.MouseDown -= new MouseEventHandler (Widget_MouseDown); + } + private void UnhookFormEvents () + { + if (hooked_form == null) + return; + + hooked_form.Deactivate -= new EventHandler (Form_Deactivate); + hooked_form.Closed -= new EventHandler (Form_Closed); + hooked_form.Resize -= new EventHandler (Form_Resize); + + hooked_form = null; + } + + + private void Form_Resize (object sender, EventArgs e) + { + Form f = (Form)sender; + + if (f.WindowState == FormWindowState.Minimized) + tooltip_window.Visible = false; + } + + private void Form_Closed (object sender, EventArgs e) + { + tooltip_window.Visible = false; + } + + private void Form_Deactivate (object sender, EventArgs e) + { + tooltip_window.Visible = false; + } + + internal void Present (Widget Widget, string text) + { + tooltip_window.Present (Widget, text); + } + + private void Widget_MouseEnter (object sender, EventArgs e) + { + ShowTooltip (sender as Widget); + } + + private void ShowTooltip (Widget Widget) + { + last_Widget = Widget; + + // Whatever we're displaying right now, we don't want it anymore + tooltip_window.Visible = false; + timer.Stop(); + state = TipState.Initial; + + if (!is_active) + return; + + // ShowAlways Widgets whether the Widgets in non-active forms + // can display its tooltips, even if they are not current active Widget. + if (!show_always && Widget.FindForm () != Form.ActiveForm) + return; + + string text = (string)tooltip_strings[Widget]; + if (text != null && text.Length > 0) { + if (active_Widget == null) { + timer.Interval = Math.Max (initial_delay, 1); + } else { + timer.Interval = Math.Max (re_show_delay, 1); + } + + active_Widget = Widget; + timer.Start (); + } + } + + private void timer_Tick(object sender, EventArgs e) { + timer.Stop(); + + switch (state) { + case TipState.Initial: + if (active_Widget == null) + return; + tooltip_window.Present (active_Widget, (string)tooltip_strings[active_Widget]); + state = TipState.Show; + timer.Interval = autopop_delay; + timer.Start(); + break; + + case TipState.Show: + tooltip_window.Visible = false; + state = TipState.Down; + break; + + default: + throw new Exception ("Timer shouldn't be running in state: " + state); + } + } + + private void tooltip_window_Popup (object sender, PopupEventArgs e) + { + e.ToolTipSize = ThemeEngine.Current.ToolTipSize (tooltip_window, tooltip_window.Text); + OnPopup (e); + } + + private void tooltip_window_Draw (object sender, DrawToolTipEventArgs e) + { + if (OwnerDraw) + OnDraw (e); + else + ThemeEngine.Current.DrawToolTip (e.Graphics, e.Bounds, tooltip_window); + } + + private bool MouseInWidget (Widget Widget, bool fuzzy) { + Point m; + Point c; + Size cw; + + if (Widget == null) { + return false; + } + + m = Widget.MousePosition; + c = new Point(Widget.Bounds.X, Widget.Bounds.Y); + if (Widget.Parent != null) { + c = Widget.Parent.PointToScreen(c); + } + cw = Widget.ClientSize; + + + Rectangle rect = new Rectangle (c, cw); + + // + // We won't get mouse move events on all platforms with the exact same + // frequency, so cheat a bit. + if (fuzzy) + rect.Inflate (2, 2); + + return rect.Contains (m); + } + + private void Widget_MouseLeave(object sender, EventArgs e) + { + timer.Stop (); + + active_Widget = null; + tooltip_window.Visible = false; + + if (last_Widget == sender) + last_Widget = null; + } + + + void Widget_MouseDown (object sender, MouseEventArgs e) + { + timer.Stop(); + + active_Widget = null; + tooltip_window.Visible = false; + + if (last_Widget == sender) + last_Widget = null; + } + + private void Widget_MouseMove(object sender, MouseEventArgs e) { + if (state != TipState.Down) { + timer.Stop(); + timer.Start(); + } + } + + internal void OnDraw (DrawToolTipEventArgs e) + { + DrawToolTipEventHandler eh = (DrawToolTipEventHandler)(Events[DrawEvent]); + if (eh != null) + eh (this, e); + } + + internal void OnPopup (PopupEventArgs e) + { + PopupEventHandler eh = (PopupEventHandler) (Events [PopupEvent]); + if (eh != null) + eh (this, e); + } + + internal void OnUnPopup (PopupEventArgs e) + { + PopupEventHandler eh = (PopupEventHandler) (Events [UnPopupEvent]); + if (eh != null) + eh (this, e); + } + + internal bool Visible { + get { return tooltip_window.Visible; } + } + #endregion // Private Methods + + #region Events + static object PopupEvent = new object (); + static object DrawEvent = new object (); + + public event PopupEventHandler Popup { + add { Events.AddHandler (PopupEvent, value); } + remove { Events.RemoveHandler (PopupEvent, value); } + } + + public event DrawToolTipEventHandler Draw { + add { Events.AddHandler (DrawEvent, value); } + remove { Events.RemoveHandler (DrawEvent, value); } + } + #endregion + } +} |
