+using System;\r
+using System.ComponentModel;\r
+using System.Windows.Forms;\r
+using System.Drawing;\r
+\r
+namespace AppliStation.Util\r
+{\r
+ public class ToolStripWeb2LikeTextBox : ToolStripTextBox\r
+ {\r
+ public ToolStripWeb2LikeTextBox() : base()\r
+ {\r
+ this.Text = string.Empty;\r
+ }\r
+ \r
+ [Category("Action")]\r
+ public event EventHandler TextChangedTriggerFired;\r
+ \r
+ private int textChangedTriggerInterval = 500;\r
+ \r
+ /// <summary>\r
+ /// Interval time for TextChangedTriggerFired.\r
+ /// </summary>\r
+ [Category("Behavior")]\r
+ [DefaultValue(500)]\r
+ public virtual int TextChangedTriggerInterval {\r
+ get { return textChangedTriggerInterval; }\r
+ set { textChangedTriggerInterval = value; }\r
+ }\r
+ \r
+ \r
+ private string oldText = null;\r
+ public void FireTextChangedTrigger(EventArgs e)\r
+ {\r
+ textChangeTriggerTimerStop();\r
+ \r
+ if (oldText != this.Text) {\r
+ if (TextChangedTriggerFired != null) {\r
+ TextChangedTriggerFired(this, e);\r
+ }\r
+ oldText = this.Text;\r
+ }\r
+ }\r
+ public void FireTextChangedTrigger()\r
+ {\r
+ FireTextChangedTrigger(EventArgs.Empty);\r
+ }\r
+ \r
+ #region TextChange Timers\r
+ \r
+ /// <summary>\r
+ /// Timer for TextChangedTriggerFired.\r
+ /// </summary>\r
+ protected Timer textChangeTriggerTimer = null;\r
+ \r
+ private void onTextUpdate(bool force)\r
+ {\r
+ textChangeTriggerTimerStop();\r
+ \r
+ textChangeTriggerTimer = new Timer();\r
+ textChangeTriggerTimer.Tick += textChangeTriggerTimerTick;\r
+ textChangeTriggerTimer.Interval = TextChangedTriggerInterval;\r
+ textChangeTriggerTimer.Start();\r
+ }\r
+ \r
+ private void textChangeTriggerTimerTick(object sender, EventArgs e)\r
+ {\r
+ FireTextChangedTrigger(e);\r
+ }\r
+ \r
+ private void textChangeTriggerTimerStop()\r
+ {\r
+ if (textChangeTriggerTimer != null) {\r
+ textChangeTriggerTimer.Stop();\r
+ textChangeTriggerTimer = null;\r
+ }\r
+ }\r
+ \r
+ protected override void OnTextChanged(EventArgs e)\r
+ {\r
+ base.OnTextChanged(e);\r
+ \r
+ if (Focused) {\r
+ onTextUpdate(false);\r
+ }\r
+ }\r
+ \r
+ #endregion\r
+ \r
+ protected bool textIsEmpty = true;\r
+ \r
+ public override string Text {\r
+ get { return textIsEmpty? string.Empty : base.Text; }\r
+ set {\r
+ bool changed = false;\r
+ if (string.IsNullOrEmpty(value)) {\r
+ if (! textIsEmpty) {\r
+ changed = true;\r
+ \r
+ textIsEmpty = true;\r
+ base.Text = EmptyText;\r
+ }\r
+ } else if (this.Text != value) {\r
+ changed = true;\r
+ \r
+ textIsEmpty = false;\r
+ base.Text = value;\r
+ }\r
+ \r
+ if (changed) {\r
+ FireTextChangedTrigger(EventArgs.Empty);\r
+ base.OnTextChanged(EventArgs.Empty);\r
+ \r
+ updateForeColorInternal();\r
+ }\r
+ }\r
+ }\r
+ \r
+ private string emptyText = "(none)";\r
+ \r
+ /// <summary>\r
+ /// Gray text when textbox is empty and has not focus\r
+ /// </summary>\r
+ [Category("Appearance")]\r
+ public virtual string EmptyText {\r
+ get { return emptyText; }\r
+ set {\r
+ emptyText = value;\r
+ \r
+ if (textIsEmpty) {\r
+ base.Text = emptyText;\r
+ }\r
+ }\r
+ }\r
+ \r
+ private Color emptyForeColor = SystemColors.GrayText;\r
+ \r
+ /// <summary>\r
+ /// Gray text color when textbox is empty and has not focus\r
+ /// </summary>\r
+ [Category("Appearance")]\r
+ [DefaultValue(typeof(Color), "GrayText")]\r
+ public virtual Color EmptyForeColor {\r
+ get { return emptyForeColor; }\r
+ set {\r
+ emptyForeColor = value;\r
+ updateForeColorInternal();\r
+ }\r
+ }\r
+ \r
+ private Color foreColor = SystemColors.WindowText;\r
+ \r
+ public override Color ForeColor {\r
+ get { return foreColor; }\r
+ set {\r
+ foreColor = value;\r
+ updateForeColorInternal();\r
+ }\r
+ }\r
+ \r
+ protected override void OnEnter(EventArgs e)\r
+ {\r
+ if (textIsEmpty) {\r
+ base.Text = string.Empty;\r
+ textIsEmpty = false;\r
+ updateForeColorInternal();\r
+ }\r
+ \r
+ base.OnEnter(e);\r
+ }\r
+ \r
+ protected override void OnLeave(EventArgs e)\r
+ {\r
+ if (string.IsNullOrEmpty(base.Text)) {\r
+ base.Text = EmptyText;\r
+ textIsEmpty = true;\r
+ updateForeColorInternal();\r
+ }\r
+ \r
+ base.OnLeave(e);\r
+ }\r
+ \r
+ private void updateForeColorInternal()\r
+ {\r
+ base.ForeColor = textIsEmpty? EmptyForeColor : ForeColor;\r
+ }\r
+ }\r
+}\r