2007-05-03 Chris Toshok <toshok@ximian.com>
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStrip.cs
blob848e1999698fb7cb7a029311483d38c514b76b31
1 //
2 // ToolStrip.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
25 // Authors:
26 // Jonathan Pobst (monkey@jpobst.com)
29 #if NET_2_0
30 using System;
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
33 using System.Drawing;
34 using System.Windows.Forms.Layout;
35 using System.Collections.Generic;
36 using System.ComponentModel.Design.Serialization;
38 namespace System.Windows.Forms
40 [ComVisible (true)]
41 [ClassInterface (ClassInterfaceType.AutoDispatch)]
42 [DefaultEvent ("ItemClicked")]
43 [DefaultProperty ("Items")]
44 [Designer ("System.Windows.Forms.Design.ToolStripDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 [DesignerSerializer ("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
46 public class ToolStrip : ScrollableControl, IComponent, IDisposable
48 #region Private Variables
49 private bool allow_merge;
50 private Color back_color;
51 private bool can_overflow;
52 private ToolStrip currently_merged_with;
53 private ToolStripDropDownDirection default_drop_down_direction;
54 internal ToolStripItemCollection displayed_items;
55 private Color fore_color;
56 private Padding grip_margin;
57 private ToolStripGripStyle grip_style;
58 private List<ToolStripItem> hidden_merged_items;
59 private ImageList image_list;
60 private Size image_scaling_size;
61 private bool is_currently_merged;
62 private ToolStripItemCollection items;
63 private bool keyboard_active;
64 private LayoutEngine layout_engine;
65 private LayoutSettings layout_settings;
66 private ToolStripLayoutStyle layout_style;
67 private Orientation orientation;
68 private ToolStripOverflowButton overflow_button;
69 private List<ToolStripItem> pre_merge_items;
70 private ToolStripRenderer renderer;
71 private ToolStripRenderMode render_mode;
72 private Timer tooltip_timer;
73 private ToolTip.ToolTipWindow tooltip_window;
74 private bool show_item_tool_tips;
75 private bool stretch;
77 private ToolStripItem mouse_currently_over;
78 internal bool menu_selected;
79 private ToolStripItem tooltip_currently_showing;
80 #endregion
82 #region Public Constructors
83 public ToolStrip () : this (null)
87 public ToolStrip (params ToolStripItem[] items) : base ()
89 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
90 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
91 SetStyle (ControlStyles.Selectable, false);
92 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
94 this.SuspendLayout ();
95 this.items = new ToolStripItemCollection (this, items);
96 this.allow_merge = true;
97 base.AutoSize = true;
98 this.back_color = Control.DefaultBackColor;
99 this.can_overflow = true;
100 base.CausesValidation = false;
101 this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
102 this.displayed_items = new ToolStripItemCollection (this, null);
103 this.Dock = this.DefaultDock;
104 base.Font = new Font ("Tahoma", 8.25f);
105 this.fore_color = Control.DefaultForeColor;
106 this.grip_margin = this.DefaultGripMargin;
107 this.grip_style = ToolStripGripStyle.Visible;
108 this.image_scaling_size = new Size (16, 16);
109 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
110 this.orientation = Orientation.Horizontal;
111 if (!(this is ToolStripDropDown))
112 this.overflow_button = new ToolStripOverflowButton (this);
113 this.renderer = null;
114 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
115 this.show_item_tool_tips = this.DefaultShowItemToolTips;
116 base.TabStop = false;
117 this.ResumeLayout ();
118 DoAutoSize ();
120 // Register with the ToolStripManager
121 ToolStripManager.AddToolStrip (this);
123 #endregion
125 #region Public Properties
126 [DefaultValue (true)]
127 public bool AllowMerge {
128 get { return this.allow_merge; }
129 set { this.allow_merge = false; }
132 public override AnchorStyles Anchor {
133 get { return base.Anchor; }
134 set { base.Anchor = value; }
137 [Browsable (false)]
138 [EditorBrowsable (EditorBrowsableState.Never)]
139 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
140 public override bool AutoScroll {
141 get { return base.AutoScroll; }
142 set { base.AutoScroll = value; }
145 [Browsable (false)]
146 [EditorBrowsable (EditorBrowsableState.Never)]
147 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
148 public new Size AutoScrollMargin {
149 get { return base.AutoScrollMargin; }
150 set { base.AutoScrollMargin = value; }
153 [Browsable (false)]
154 [EditorBrowsable (EditorBrowsableState.Never)]
155 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
156 public new Size AutoScrollMinSize {
157 get { return base.AutoScrollMinSize; }
158 set { base.AutoScrollMinSize = value; }
161 [Browsable (false)]
162 [EditorBrowsable (EditorBrowsableState.Never)]
163 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
164 public new Point AutoScrollPosition {
165 get { return base.AutoScrollPosition; }
166 set { base.AutoScrollPosition = value; }
169 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
170 [Browsable (true)]
171 [EditorBrowsable (EditorBrowsableState.Always)]
172 [DefaultValue (true)]
173 public override bool AutoSize {
174 get { return base.AutoSize; }
175 set { base.AutoSize = value; }
178 new public Color BackColor {
179 get { return this.back_color; }
180 set { this.back_color = value; }
183 [DefaultValue (true)]
184 public bool CanOverflow {
185 get { return this.can_overflow; }
186 set { this.can_overflow = value; }
189 [Browsable (false)]
190 [DefaultValue (false)]
191 public new bool CausesValidation {
192 get { return base.CausesValidation; }
193 set { base.CausesValidation = value; }
196 [EditorBrowsable (EditorBrowsableState.Never)]
197 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
198 public new ControlCollection Controls {
199 get { return base.Controls; }
202 [Browsable (false)]
203 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
204 public override Cursor Cursor {
205 get { return base.Cursor; }
206 set { base.Cursor = value; }
209 [Browsable (false)]
210 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
211 get { return this.default_drop_down_direction; }
212 set {
213 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
214 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
216 this.default_drop_down_direction = value;
220 public override Rectangle DisplayRectangle {
221 get {
222 if (this.orientation == Orientation.Horizontal)
223 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
224 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
225 else
226 return new Rectangle (this.GripRectangle.Right + this.GripMargin.Right, this.Padding.Top, this.Width - this.Padding.Horizontal - this.GripRectangle.Right - this.GripMargin.Right, this.Height - this.Padding.Vertical);
227 else
228 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
229 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
230 else
231 return new Rectangle (this.Padding.Left, this.GripRectangle.Bottom + this.GripMargin.Bottom + this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical - this.GripRectangle.Bottom - this.GripMargin.Bottom);
235 [DefaultValue (DockStyle.Top)]
236 public override DockStyle Dock {
237 get { return base.Dock; }
238 set {
239 if (base.Dock != value) {
240 base.Dock = value;
242 switch (value) {
243 case DockStyle.Top:
244 case DockStyle.Bottom:
245 case DockStyle.None:
246 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
247 break;
248 case DockStyle.Left:
249 case DockStyle.Right:
250 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
251 break;
257 public override Font Font {
258 get { return base.Font; }
259 set {
260 if (base.Font != value) {
261 base.Font = value;
263 foreach (ToolStripItem tsi in this.Items)
264 tsi.OnOwnerFontChanged (EventArgs.Empty);
269 [Browsable (false)]
270 public new Color ForeColor {
271 get { return this.fore_color; }
272 set {
273 if (this.fore_color != value) {
274 this.fore_color = value;
275 this.OnForeColorChanged (EventArgs.Empty);
280 [Browsable (false)]
281 public ToolStripGripDisplayStyle GripDisplayStyle {
282 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
285 public Padding GripMargin {
286 get { return this.grip_margin; }
287 set {
288 if (this.grip_margin != value) {
289 this.grip_margin = value;
290 this.PerformLayout ();
295 [Browsable (false)]
296 public Rectangle GripRectangle {
297 get {
298 if (this.grip_style == ToolStripGripStyle.Hidden)
299 return Rectangle.Empty;
301 if (this.orientation == Orientation.Horizontal)
302 return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
303 else
304 return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
308 [DefaultValue (ToolStripGripStyle.Visible)]
309 public ToolStripGripStyle GripStyle {
310 get { return this.grip_style; }
311 set {
312 if (this.grip_style != value) {
313 if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
314 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
315 this.grip_style = value;
316 this.PerformLayout ();
321 [Browsable (false)]
322 [EditorBrowsable (EditorBrowsableState.Never)]
323 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
324 public new bool HasChildren {
325 get { return base.HasChildren; }
328 [Browsable (false)]
329 [EditorBrowsable (EditorBrowsableState.Never)]
330 public new HScrollProperties HorizontalScroll {
331 get { return base.HorizontalScroll; }
334 [Browsable (false)]
335 [DefaultValue (null)]
336 public ImageList ImageList {
337 get { return this.image_list; }
338 set { this.image_list = value; }
341 [DefaultValue ("{Width=16, Height=16}")]
342 public Size ImageScalingSize {
343 get { return this.image_scaling_size; }
344 set { this.image_scaling_size = value; }
347 [MonoTODO ("Always returns false, dragging not implemented yet.")]
348 [Browsable (false)]
349 [EditorBrowsable (EditorBrowsableState.Advanced)]
350 public bool IsCurrentlyDragging {
351 get { return false; }
354 [Browsable (false)]
355 public bool IsDropDown {
356 get {
357 if (this is ToolStripDropDown)
358 return true;
360 return false;
364 [MergableProperty (false)]
365 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
366 public virtual ToolStripItemCollection Items {
367 get { return this.items; }
370 public override LayoutEngine LayoutEngine {
371 get {
372 if (layout_engine == null)
373 this.layout_engine = new ToolStripSplitStackLayout ();
375 return this.layout_engine;
379 [Browsable (false)]
380 [DefaultValue (null)]
381 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
382 public LayoutSettings LayoutSettings {
383 get { return this.layout_settings; }
384 set { this.layout_settings = value; }
387 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
388 public ToolStripLayoutStyle LayoutStyle {
389 get { return layout_style; }
390 set {
391 if (this.layout_style != value) {
392 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
393 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
395 this.layout_style = value;
397 if (this.layout_style == ToolStripLayoutStyle.Flow)
398 this.layout_engine = new FlowLayout ();
399 else
400 this.layout_engine = new ToolStripSplitStackLayout ();
402 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
403 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
404 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
405 else
406 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
409 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
410 this.orientation = Orientation.Horizontal;
411 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
412 this.orientation = Orientation.Vertical;
414 this.layout_settings = this.CreateLayoutSettings (value);
416 this.PerformLayout ();
417 this.OnLayoutStyleChanged (EventArgs.Empty);
422 [Browsable (false)]
423 public Orientation Orientation {
424 get { return this.orientation; }
427 [Browsable (false)]
428 [EditorBrowsable (EditorBrowsableState.Advanced)]
429 public ToolStripOverflowButton OverflowButton {
430 get { return this.overflow_button; }
433 [Browsable (false)]
434 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
435 public ToolStripRenderer Renderer {
436 get {
437 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
438 return ToolStripManager.Renderer;
440 return this.renderer;
442 set {
443 if (this.renderer != value) {
444 this.renderer = value;
445 this.render_mode = ToolStripRenderMode.Custom;
446 this.PerformLayout ();
447 this.OnRendererChanged (EventArgs.Empty);
452 public ToolStripRenderMode RenderMode {
453 get { return this.render_mode; }
454 set {
455 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
456 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
458 if (value == ToolStripRenderMode.Custom && this.renderer == null)
459 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
460 if (value == ToolStripRenderMode.Professional || value == ToolStripRenderMode.System)
461 this.Renderer = new ToolStripProfessionalRenderer ();
463 this.render_mode = value;
467 [DefaultValue (true)]
468 public bool ShowItemToolTips {
469 get { return this.show_item_tool_tips; }
470 set { this.show_item_tool_tips = value; }
473 [DefaultValue (false)]
474 public bool Stretch {
475 get { return this.stretch; }
476 set { this.stretch = value; }
479 [DefaultValue (false)]
480 [DispId(-516)]
481 public new bool TabStop {
482 get { return base.TabStop; }
483 set { base.TabStop = value; }
486 [Browsable (false)]
487 [EditorBrowsable (EditorBrowsableState.Never)]
488 public new VScrollProperties VerticalScroll {
489 get { return base.VerticalScroll; }
491 #endregion
493 #region Protected Properties
494 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
495 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
496 protected override Padding DefaultMargin { get { return Padding.Empty; } }
497 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
498 protected virtual bool DefaultShowItemToolTips { get { return true; } }
499 protected override Size DefaultSize { get { return new Size (100, 25); } }
500 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
501 #endregion
503 #region Public Methods
504 [EditorBrowsable (EditorBrowsableState.Never)]
505 public new Control GetChildAtPoint (Point point)
507 return base.GetChildAtPoint (point);
510 //[EditorBrowsable (EditorBrowsableState.Never)]
511 //public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
513 // return base.GetChildAtPoint (pt, skipValue);
516 public ToolStripItem GetItemAt (Point point)
518 foreach (ToolStripItem tsi in this.displayed_items)
519 if (tsi.Visible && tsi.Bounds.Contains (point))
520 return tsi;
522 return null;
525 public ToolStripItem GetItemAt (int x, int y)
527 return GetItemAt (new Point (x, y));
530 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
532 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
533 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
535 ToolStripItem current_best = null;
536 int current_best_point;
538 switch (direction) {
539 case ArrowDirection.Right:
540 current_best_point = int.MaxValue;
542 if (start != null)
543 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
544 if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
545 current_best = loop_tsi;
546 current_best_point = loop_tsi.Left;
549 if (current_best == null)
550 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
551 if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
552 current_best = loop_tsi;
553 current_best_point = loop_tsi.Left;
556 break;
557 case ArrowDirection.Up:
558 current_best_point = int.MinValue;
560 if (start != null)
561 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
562 if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
563 current_best = loop_tsi;
564 current_best_point = loop_tsi.Top;
567 if (current_best == null)
568 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
569 if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
570 current_best = loop_tsi;
571 current_best_point = loop_tsi.Top;
574 break;
575 case ArrowDirection.Left:
576 current_best_point = int.MinValue;
578 if (start != null)
579 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
580 if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
581 current_best = loop_tsi;
582 current_best_point = loop_tsi.Left;
585 if (current_best == null)
586 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
587 if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
588 current_best = loop_tsi;
589 current_best_point = loop_tsi.Left;
592 break;
593 case ArrowDirection.Down:
594 current_best_point = int.MaxValue;
596 if (start != null)
597 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
598 if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
599 current_best = loop_tsi;
600 current_best_point = loop_tsi.Top;
603 if (current_best == null)
604 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
605 if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
606 current_best = loop_tsi;
607 current_best_point = loop_tsi.Top;
610 break;
613 return current_best;
616 [EditorBrowsable (EditorBrowsableState.Never)]
617 public void ResetMinimumSize ()
619 this.MinimumSize = new Size (-1, -1);
622 [EditorBrowsable (EditorBrowsableState.Never)]
623 public new void SetAutoScrollMargin (int x, int y)
625 base.SetAutoScrollMargin (x, y);
628 public override string ToString ()
630 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
632 #endregion
634 #region Protected Methods
635 protected override AccessibleObject CreateAccessibilityInstance ()
637 AccessibleObject ao = new AccessibleObject (this);
639 ao.role = AccessibleRole.ToolBar;
641 return ao;
644 protected override ControlCollection CreateControlsInstance ()
646 return base.CreateControlsInstance ();
649 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
651 if (text == "-")
652 return new ToolStripSeparator ();
654 if (this is ToolStripDropDown)
655 return new ToolStripMenuItem (text, image, onClick);
657 return new ToolStripButton (text, image, onClick);
660 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
662 switch (layoutStyle) {
663 case ToolStripLayoutStyle.Flow:
664 return new FlowLayoutSettings ();
665 case ToolStripLayoutStyle.Table:
666 //return new TableLayoutSettings ();
667 case ToolStripLayoutStyle.StackWithOverflow:
668 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
669 case ToolStripLayoutStyle.VerticalStackWithOverflow:
670 default:
671 return null;
675 protected override void Dispose (bool disposing)
677 if (!IsDisposed) {
678 ToolStripManager.RemoveToolStrip (this);
679 base.Dispose (disposing);
683 protected override void OnDockChanged (EventArgs e)
685 base.OnDockChanged (e);
688 protected override bool IsInputChar (char charCode)
690 return base.IsInputChar (charCode);
693 protected override bool IsInputKey (Keys keyData)
695 return base.IsInputKey (keyData);
698 protected override void OnEnabledChanged (EventArgs e)
700 base.OnEnabledChanged (e);
702 foreach (ToolStripItem tsi in this.Items)
703 tsi.OnParentEnabledChanged (EventArgs.Empty);
706 protected override void OnFontChanged (EventArgs e)
708 base.OnFontChanged (e);
711 protected override void OnHandleCreated (EventArgs e)
713 base.OnHandleCreated (e);
716 protected override void OnHandleDestroyed (EventArgs e)
718 base.OnHandleDestroyed (e);
721 protected override void OnInvalidated (InvalidateEventArgs e)
723 base.OnInvalidated (e);
726 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
728 e.Item.Available = true;
729 e.Item.SetPlacement (ToolStripItemPlacement.Main);
730 this.DoAutoSize ();
731 this.PerformLayout ();
733 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
734 if (eh != null)
735 eh (this, e);
738 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
740 ToolStripManager.SetActiveToolStrip (null);
742 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
743 if (eh != null)
744 eh (this, e);
747 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
749 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
750 if (eh != null)
751 eh (this, e);
754 protected override void OnLayout (LayoutEventArgs e)
756 DoAutoSize ();
757 base.OnLayout (e);
759 this.SetDisplayedItems ();
760 this.OnLayoutCompleted (EventArgs.Empty);
761 this.Invalidate ();
764 protected virtual void OnLayoutCompleted (EventArgs e)
766 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
767 if (eh != null)
768 eh (this, e);
771 protected virtual void OnLayoutStyleChanged (EventArgs e)
773 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
774 if (eh != null)
775 eh (this, e);
778 protected override void OnLeave (EventArgs e)
780 base.OnLeave (e);
783 protected override void OnLostFocus (EventArgs e)
785 base.OnLostFocus (e);
788 protected override void OnMouseCaptureChanged (EventArgs e)
790 base.OnMouseCaptureChanged (e);
793 protected override void OnMouseDown (MouseEventArgs mea)
795 if (mouse_currently_over != null)
797 if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
798 if (!menu_selected)
799 (this as MenuStrip).FireMenuActivate ();
801 return;
804 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
806 if (this is MenuStrip && !menu_selected) {
807 (this as MenuStrip).FireMenuActivate ();
808 menu_selected = true;
810 } else {
811 if (this is MenuStrip)
812 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
815 if (this is MenuStrip)
816 this.Capture = false;
818 base.OnMouseDown (mea);
821 protected override void OnMouseLeave (EventArgs e)
823 if (mouse_currently_over != null) {
824 MouseLeftItem (mouse_currently_over);
825 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
826 mouse_currently_over = null;
829 base.OnMouseLeave (e);
832 protected override void OnMouseMove (MouseEventArgs mea)
834 ToolStripItem tsi;
835 // Find the item we are now
836 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
837 tsi = this.overflow_button;
838 else
839 tsi = this.GetItemAt (mea.X, mea.Y);
841 if (tsi != null) {
842 // If we were already hovering on this item, just send a mouse move
843 if (tsi == mouse_currently_over)
844 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
845 else {
846 // If we were over a different item, fire a mouse leave on it
847 if (mouse_currently_over != null) {
848 MouseLeftItem (tsi);
849 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
852 // Set the new item we are currently over
853 mouse_currently_over = tsi;
855 // Fire mouse enter and mouse move
856 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
857 MouseEnteredItem (tsi);
858 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
860 // If we're over something with a drop down, show it
861 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
862 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
864 } else {
865 // We're not over anything now, just fire the mouse leave on what we used to be over
866 if (mouse_currently_over != null) {
867 MouseLeftItem (tsi);
868 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
869 mouse_currently_over = null;
873 base.OnMouseMove (mea);
876 protected override void OnMouseUp (MouseEventArgs mea)
878 // If we're currently over an item (set in MouseMove)
879 if (mouse_currently_over != null) {
880 // Fire the item's MouseUp event
881 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
883 // The event handler may have blocked until the mouse moved off of the ToolStripItem
884 if (mouse_currently_over == null)
885 return;
887 // Fire our ItemClicked event
888 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
891 base.OnMouseUp (mea);
894 protected override void OnPaint (PaintEventArgs e)
896 base.OnPaint (e);
898 // Draw the grip
899 this.OnPaintGrip (e);
901 // Make each item draw itself
902 foreach (ToolStripItem tsi in this.displayed_items) {
903 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
904 tsi.FireEvent (e, ToolStripItemEventType.Paint);
905 e.Graphics.ResetTransform ();
908 // Paint the Overflow button if it's visible
909 if (this.overflow_button != null && this.overflow_button.Visible) {
910 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
911 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
912 e.Graphics.ResetTransform ();
915 Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
916 Rectangle connected_area = Rectangle.Empty;
918 if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
919 connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
921 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
922 pevent.InternalConnectedArea = connected_area;
924 this.Renderer.DrawToolStripBorder (pevent);
927 [EditorBrowsable (EditorBrowsableState.Advanced)]
928 protected override void OnPaintBackground (PaintEventArgs pevent)
930 base.OnPaintBackground (pevent);
932 Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
933 Rectangle connected_area = Rectangle.Empty;
935 if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
936 connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
938 ToolStripRenderEventArgs e = new ToolStripRenderEventArgs (pevent.Graphics, this, affected_bounds, Color.Empty);
939 e.InternalConnectedArea = connected_area;
941 this.Renderer.DrawToolStripBackground (e);
944 protected internal virtual void OnPaintGrip (PaintEventArgs e)
946 // Never draw a grip with these two layouts
947 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
948 return;
950 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
951 if (eh != null)
952 eh (this, e);
954 if (!(this is MenuStrip)) {
955 if (this.orientation == Orientation.Horizontal)
956 e.Graphics.TranslateTransform (2, 0);
957 else
958 e.Graphics.TranslateTransform (0, 2);
961 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
962 e.Graphics.ResetTransform ();
965 protected virtual void OnRendererChanged (EventArgs e)
967 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
968 if (eh != null)
969 eh (this, e);
972 [EditorBrowsable (EditorBrowsableState.Advanced)]
973 protected override void OnRightToLeftChanged (EventArgs e)
975 base.OnRightToLeftChanged (e);
977 foreach (ToolStripItem tsi in this.Items)
978 tsi.OnParentRightToLeftChanged (e);
981 protected override void OnScroll (ScrollEventArgs se)
983 base.OnScroll (se);
986 protected override void OnTabStopChanged (EventArgs e)
988 base.OnTabStopChanged (e);
991 protected override void OnVisibleChanged (EventArgs e)
993 base.OnVisibleChanged (e);
996 protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
998 return base.ProcessCmdKey (ref msg, keyData);
1001 protected override bool ProcessDialogKey (Keys keyData)
1003 if (!this.KeyboardActive)
1004 return false;
1006 // Give each item a chance to handle the key
1007 foreach (ToolStripItem tsi in this.Items)
1008 if (tsi.ProcessDialogKey (keyData))
1009 return true;
1011 // See if I want to handle it
1012 if (this.ProcessArrowKey (keyData))
1013 return true;
1015 ToolStrip ts = null;
1017 switch (keyData) {
1018 case Keys.Escape:
1019 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1020 return true;
1022 case Keys.Control | Keys.Tab:
1023 ts = ToolStripManager.GetNextToolStrip (this, true);
1025 if (ts != null) {
1026 foreach (ToolStripItem tsi in this.Items)
1027 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1029 ToolStripManager.SetActiveToolStrip (ts);
1030 ts.SelectNextToolStripItem (null, true);
1033 return true;
1034 case Keys.Control | Keys.Shift | Keys.Tab:
1035 ts = ToolStripManager.GetNextToolStrip (this, false);
1037 if (ts != null) {
1038 foreach (ToolStripItem tsi in this.Items)
1039 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1041 ToolStripManager.SetActiveToolStrip (ts);
1042 ts.SelectNextToolStripItem (null, true);
1045 return true;
1046 case Keys.Down:
1047 case Keys.Up:
1048 case Keys.Left:
1049 case Keys.Right:
1050 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1051 return false;
1052 break;
1055 return base.ProcessDialogKey (keyData);
1058 protected override bool ProcessMnemonic (char charCode)
1060 // If any item has an explicit mnemonic, it gets the message
1061 foreach (ToolStripItem tsi in this.Items)
1062 if (tsi.Enabled && tsi.Visible && Control.IsMnemonic (charCode, tsi.Text))
1063 return tsi.ProcessMnemonic (charCode);
1065 string code = Char.ToUpper (charCode).ToString ();
1067 // If any item's text starts with our letter, it gets the message
1068 foreach (ToolStripItem tsi in this.Items)
1069 if (tsi.Enabled && tsi.Visible && tsi.Text.Length > 0 && tsi.Text.ToUpper ().StartsWith (code))
1070 return tsi.ProcessMnemonic (charCode);
1072 return base.ProcessMnemonic (charCode);
1075 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1077 base.SetBoundsCore (x, y, width, height, specified);
1080 protected virtual void SetDisplayedItems ()
1082 this.displayed_items.Clear ();
1084 foreach (ToolStripItem tsi in this.items)
1085 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1086 this.displayed_items.AddNoOwnerOrLayout (tsi);
1087 tsi.Parent = this;
1089 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1090 tsi.Parent = this.OverflowButton.DropDown;
1092 if (this.OverflowButton != null)
1093 this.OverflowButton.DropDown.SetDisplayedItems ();
1096 protected internal void SetItemLocation (ToolStripItem item, Point location)
1098 if (item == null)
1099 throw new ArgumentNullException ("item");
1101 if (item.Owner != this)
1102 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1104 item.SetBounds (new Rectangle (location, item.Size));
1107 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1109 if (item.Parent != null) {
1110 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1112 if (item.Parent is ToolStripOverflow)
1113 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1116 parent.Items.AddNoOwnerOrLayout (item);
1117 item.Parent = parent;
1120 protected override void SetVisibleCore (bool value)
1122 base.SetVisibleCore (value);
1125 protected override void WndProc (ref Message m)
1127 base.WndProc (ref m);
1129 #endregion
1131 #region Public Events
1132 static object ItemAddedEvent = new object ();
1133 static object ItemClickedEvent = new object ();
1134 static object ItemRemovedEvent = new object ();
1135 static object LayoutCompletedEvent = new object ();
1136 static object LayoutStyleChangedEvent = new object ();
1137 static object PaintGripEvent = new object ();
1138 static object RendererChangedEvent = new object ();
1140 [Browsable (true)]
1141 [EditorBrowsable (EditorBrowsableState.Always)]
1142 public new event EventHandler AutoSizeChanged {
1143 add { base.AutoSizeChanged += value; }
1144 remove { base.AutoSizeChanged -= value; }
1147 [Browsable (false)]
1148 public new event EventHandler CausesValidationChanged {
1149 add { base.CausesValidationChanged += value; }
1150 remove { base.CausesValidationChanged -= value; }
1153 [Browsable (false)]
1154 [EditorBrowsable (EditorBrowsableState.Never)]
1155 public new event ControlEventHandler ControlAdded {
1156 add { base.ControlAdded += value; }
1157 remove { base.ControlAdded -= value; }
1160 [Browsable (false)]
1161 [EditorBrowsable (EditorBrowsableState.Never)]
1162 public new event ControlEventHandler ControlRemoved {
1163 add { base.ControlRemoved += value; }
1164 remove { base.ControlRemoved -= value; }
1167 [Browsable (false)]
1168 public new event EventHandler CursorChanged {
1169 add { base.CursorChanged += value; }
1170 remove { base.CursorChanged -= value; }
1173 [Browsable (false)]
1174 public new event EventHandler ForeColorChanged {
1175 add { base.ForeColorChanged += value; }
1176 remove { base.ForeColorChanged -= value; }
1179 public event ToolStripItemEventHandler ItemAdded {
1180 add { Events.AddHandler (ItemAddedEvent, value); }
1181 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1184 public event ToolStripItemClickedEventHandler ItemClicked {
1185 add { Events.AddHandler (ItemClickedEvent, value); }
1186 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1189 public event ToolStripItemEventHandler ItemRemoved {
1190 add { Events.AddHandler (ItemRemovedEvent, value); }
1191 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1194 public event EventHandler LayoutCompleted {
1195 add { Events.AddHandler (LayoutCompletedEvent, value); }
1196 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1199 public event EventHandler LayoutStyleChanged {
1200 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1201 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1204 public event PaintEventHandler PaintGrip {
1205 add { Events.AddHandler (PaintGripEvent, value); }
1206 remove { Events.RemoveHandler (PaintGripEvent, value); }
1209 public event EventHandler RendererChanged {
1210 add { Events.AddHandler (RendererChangedEvent, value); }
1211 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1213 #endregion
1215 #region Internal Properties
1216 internal virtual bool KeyboardActive
1218 get { return this.keyboard_active; }
1219 set {
1220 if (this.keyboard_active != value) {
1221 this.keyboard_active = value;
1223 if (value)
1224 Application.KeyboardCapture = this;
1225 else if (Application.KeyboardCapture == this)
1226 Application.KeyboardCapture = null;
1228 // Redraw for mnemonic underlines
1229 this.Refresh ();
1233 #endregion
1235 #region Private Methods
1236 internal void ChangeSelection (ToolStripItem nextItem)
1238 if (Application.KeyboardCapture != this)
1239 ToolStripManager.SetActiveToolStrip (this);
1241 foreach (ToolStripItem tsi in this.Items)
1242 if (tsi != nextItem)
1243 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1245 nextItem.Select ();
1247 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1248 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1251 internal virtual void Dismiss ()
1253 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1256 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1258 // Release our stranglehold on the keyboard
1259 this.KeyboardActive = false;
1261 // Set our drop down flag to false;
1262 this.menu_selected = false;
1264 // Make sure all of our items are deselected and repainted
1265 foreach (ToolStripItem tsi in this.Items)
1266 tsi.Dismiss (reason);
1269 private void DoAutoSize ()
1271 if (this.AutoSize == true && this.Dock == DockStyle.None)
1272 this.Size = GetPreferredSize (Size.Empty);
1274 if (this.AutoSize == true && this.Orientation == Orientation.Horizontal && (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom))
1275 this.Height = GetPreferredSize (Size.Empty).Height;
1278 internal ToolStripItem GetCurrentlySelectedItem ()
1280 foreach (ToolStripItem tsi in this.DisplayedItems)
1281 if (tsi.Selected)
1282 return tsi;
1284 return null;
1287 public override Size GetPreferredSize (Size proposedSize)
1289 Size new_size = new Size (0, this.Height);
1291 if (this.orientation == Orientation.Vertical) {
1292 foreach (ToolStripItem tsi in this.items)
1293 if (tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom > new_size.Height)
1294 new_size.Height = tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom;
1296 new_size.Height += this.Padding.Top + this.Padding.Bottom;
1297 new_size.Width = this.Width;
1298 } else {
1299 foreach (ToolStripItem tsi in this.items)
1300 if (tsi.Available) {
1301 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1302 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1304 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height))
1305 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height);
1309 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1310 return new_size;
1313 internal virtual ToolStrip GetTopLevelToolStrip ()
1315 return this;
1318 internal void HandleItemClick (ToolStripItem dismissingItem)
1320 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1321 this.OnItemClicked (new ToolStripItemClickedEventArgs (dismissingItem));
1324 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1326 if (this is MenuStrip && release && menu_selected)
1327 (this as MenuStrip).FireMenuDeactivate ();
1329 if (release)
1330 menu_selected = false;
1332 NotifySelectedChanged (null);
1335 internal void NotifySelectedChanged (ToolStripItem tsi)
1337 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1338 if (tsi != tsi2)
1339 if (tsi2 is ToolStripDropDownItem)
1340 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1342 if (this.OverflowButton != null) {
1343 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1345 foreach (ToolStripItem tsi2 in tsic)
1346 if (tsi != tsi2)
1347 if (tsi2 is ToolStripDropDownItem)
1348 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1350 this.OverflowButton.HideDropDown ();
1353 foreach (ToolStripItem tsi2 in this.Items)
1354 if (tsi != tsi2)
1355 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1358 internal virtual bool OnMenuKey ()
1360 return false;
1363 internal virtual bool ProcessArrowKey (Keys keyData)
1365 ToolStripItem tsi;
1367 switch (keyData) {
1368 case Keys.Right:
1369 tsi = this.GetCurrentlySelectedItem ();
1371 if (tsi is ToolStripControlHost)
1372 return false;
1374 tsi = this.SelectNextToolStripItem (tsi, true);
1376 if (tsi is ToolStripControlHost)
1377 (tsi as ToolStripControlHost).Focus ();
1379 return true;
1380 case Keys.Tab:
1381 tsi = this.GetCurrentlySelectedItem ();
1383 tsi = this.SelectNextToolStripItem (tsi, true);
1385 if (tsi is ToolStripControlHost)
1386 (tsi as ToolStripControlHost).Focus ();
1388 return true;
1389 case Keys.Left:
1390 tsi = this.GetCurrentlySelectedItem ();
1392 if (tsi is ToolStripControlHost)
1393 return false;
1395 tsi = this.SelectNextToolStripItem (tsi, false);
1397 if (tsi is ToolStripControlHost)
1398 (tsi as ToolStripControlHost).Focus ();
1400 return true;
1401 case Keys.Shift | Keys.Tab:
1402 tsi = this.GetCurrentlySelectedItem ();
1404 tsi = this.SelectNextToolStripItem (tsi, false);
1406 if (tsi is ToolStripControlHost)
1407 (tsi as ToolStripControlHost).Focus ();
1409 return true;
1412 return false;
1415 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1417 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1419 this.ChangeSelection (next_item);
1421 if (next_item is ToolStripControlHost)
1422 (next_item as ToolStripControlHost).Focus ();
1424 return next_item;
1427 #region Stuff for ToolTips
1428 private void MouseEnteredItem (ToolStripItem item)
1430 if (this.show_item_tool_tips) {
1431 tooltip_currently_showing = item;
1432 ToolTipTimer.Start ();
1436 private void MouseLeftItem (ToolStripItem item)
1438 ToolTipTimer.Stop ();
1439 ToolTipWindow.Hide ();
1440 tooltip_currently_showing = null;
1443 private Timer ToolTipTimer {
1444 get {
1445 if (tooltip_timer == null) {
1446 tooltip_timer = new Timer ();
1447 tooltip_timer.Enabled = false;
1448 tooltip_timer.Interval = 500;
1449 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1452 return tooltip_timer;
1456 private ToolTip.ToolTipWindow ToolTipWindow {
1457 get {
1458 if (tooltip_window == null)
1459 tooltip_window = new ToolTip.ToolTipWindow ();
1461 return tooltip_window;
1465 private void ToolTipTimer_Tick (object o, EventArgs args)
1467 string tooltip = tooltip_currently_showing.GetToolTip ();
1469 if (!string.IsNullOrEmpty (tooltip))
1470 ToolTipWindow.Present (this, tooltip);
1472 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1474 ToolTipTimer.Stop ();
1476 #endregion
1478 #region Stuff for Merging
1479 internal ToolStrip CurrentlyMergedWith {
1480 get { return this.currently_merged_with; }
1481 set { this.currently_merged_with = value; }
1484 internal List<ToolStripItem> HiddenMergedItems {
1485 get {
1486 if (this.hidden_merged_items == null)
1487 this.hidden_merged_items = new List<ToolStripItem> ();
1489 return this.hidden_merged_items;
1493 internal bool IsCurrentlyMerged {
1494 get { return this.is_currently_merged; }
1495 set {
1496 this.is_currently_merged = value;
1498 if (!value && this is MenuStrip)
1499 foreach (ToolStripMenuItem tsmi in this.Items)
1500 tsmi.DropDown.IsCurrentlyMerged = value;
1504 internal void BeginMerge ()
1506 if (!IsCurrentlyMerged) {
1507 IsCurrentlyMerged = true;
1509 if (this.pre_merge_items == null) {
1510 this.pre_merge_items = new List<ToolStripItem> ();
1512 foreach (ToolStripItem tsi in this.Items)
1513 this.pre_merge_items.Add (tsi);
1516 if (this is MenuStrip)
1517 foreach (ToolStripMenuItem tsmi in this.Items)
1518 tsmi.DropDown.BeginMerge ();
1522 internal void RevertMergeItem (ToolStripItem item)
1524 int index = 0;
1526 // Remove it from it's current Parent
1527 if (item.Parent != null && item.Parent != this) {
1528 if (item.Parent is ToolStripOverflow)
1529 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1530 else
1531 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1533 item.Parent = item.Owner;
1536 // Find where the item was before the merge
1537 index = item.Owner.pre_merge_items.IndexOf (item);
1539 // Find the first pre-merge item that was after this item, that
1540 // is currently in the Items collection. Insert our item before
1541 // that one.
1542 for (int i = index; i < this.pre_merge_items.Count; i++) {
1543 if (this.Items.Contains (this.pre_merge_items[i])) {
1544 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1545 return;
1549 // There aren't any items that are supposed to be after this item,
1550 // so just append it to the end.
1551 item.Owner.Items.AddNoOwnerOrLayout (item);
1553 #endregion
1554 #endregion
1557 #endif