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:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
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
26 // Jonathan Pobst (monkey@jpobst.com)
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
34 using System.Windows.Forms.Layout;
35 using System.Collections.Generic;
36 using System.ComponentModel.Design.Serialization;
38 namespace System.Windows.Forms
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, IToolStripData
48 #region Private Variables
49 private bool allow_item_reorder;
50 private bool allow_merge;
51 private Color back_color;
52 private bool can_overflow;
53 private ToolStrip currently_merged_with;
54 private ToolStripDropDownDirection default_drop_down_direction;
55 internal ToolStripItemCollection displayed_items;
56 private Color fore_color;
57 private Padding grip_margin;
58 private ToolStripGripStyle grip_style;
59 private List<ToolStripItem> hidden_merged_items;
60 private ImageList image_list;
61 private Size image_scaling_size;
62 private bool is_currently_merged;
63 private ToolStripItemCollection items;
64 private bool keyboard_active;
65 private LayoutEngine layout_engine;
66 private LayoutSettings layout_settings;
67 private ToolStripLayoutStyle layout_style;
68 private Orientation orientation;
69 private ToolStripOverflowButton overflow_button;
70 private List<ToolStripItem> pre_merge_items;
71 private ToolStripRenderer renderer;
72 private ToolStripRenderMode render_mode;
73 private ToolStripTextDirection text_direction;
74 private Timer tooltip_timer;
75 private ToolTip tooltip_window;
76 private bool show_item_tool_tips;
79 private ToolStripItem mouse_currently_over;
80 internal bool menu_selected;
81 private ToolStripItem tooltip_currently_showing;
84 #region Public Constructors
85 public ToolStrip () : this (null)
89 public ToolStrip (params ToolStripItem[] items) : base ()
91 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
92 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
93 SetStyle (ControlStyles.Selectable, false);
94 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
96 this.SuspendLayout ();
98 this.items = new ToolStripItemCollection (this, items, true);
99 this.allow_merge = true;
100 base.AutoSize = true;
101 this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
102 this.back_color = Control.DefaultBackColor;
103 this.can_overflow = true;
104 base.CausesValidation = false;
105 this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
106 this.displayed_items = new ToolStripItemCollection (this, null, true);
107 this.Dock = this.DefaultDock;
108 base.Font = new Font ("Tahoma", 8.25f);
109 this.fore_color = Control.DefaultForeColor;
110 this.grip_margin = this.DefaultGripMargin;
111 this.grip_style = ToolStripGripStyle.Visible;
112 this.image_scaling_size = new Size (16, 16);
113 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
114 this.orientation = Orientation.Horizontal;
115 if (!(this is ToolStripDropDown))
116 this.overflow_button = new ToolStripOverflowButton (this);
117 this.renderer = null;
118 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
119 this.show_item_tool_tips = this.DefaultShowItemToolTips;
120 base.TabStop = false;
121 this.text_direction = ToolStripTextDirection.Horizontal;
122 this.ResumeLayout ();
124 // Register with the ToolStripManager
125 ToolStripManager.AddToolStrip (this);
129 #region Public Properties
131 public override bool AllowDrop {
132 get { return base.AllowDrop; }
133 set { base.AllowDrop = value; }
137 [DefaultValue (false)]
138 public bool AllowItemReorder {
139 get { return this.allow_item_reorder; }
140 set { this.allow_item_reorder = value; }
143 [DefaultValue (true)]
144 public bool AllowMerge {
145 get { return this.allow_merge; }
146 set { this.allow_merge = value; }
149 public override AnchorStyles Anchor {
150 get { return base.Anchor; }
151 set { base.Anchor = value; }
155 [EditorBrowsable (EditorBrowsableState.Never)]
156 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
157 public override bool AutoScroll {
158 get { return base.AutoScroll; }
159 set { base.AutoScroll = value; }
163 [EditorBrowsable (EditorBrowsableState.Never)]
164 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
165 public new Size AutoScrollMargin {
166 get { return base.AutoScrollMargin; }
167 set { base.AutoScrollMargin = value; }
171 [EditorBrowsable (EditorBrowsableState.Never)]
172 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
173 public new Size AutoScrollMinSize {
174 get { return base.AutoScrollMinSize; }
175 set { base.AutoScrollMinSize = value; }
179 [EditorBrowsable (EditorBrowsableState.Never)]
180 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
181 public new Point AutoScrollPosition {
182 get { return base.AutoScrollPosition; }
183 set { base.AutoScrollPosition = value; }
186 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
188 [EditorBrowsable (EditorBrowsableState.Always)]
189 [DefaultValue (true)]
190 public override bool AutoSize {
191 get { return base.AutoSize; }
192 set { base.AutoSize = value; }
195 new public Color BackColor {
196 get { return this.back_color; }
197 set { this.back_color = value; }
200 public override BindingContext BindingContext {
201 get { return base.BindingContext; }
202 set { base.BindingContext = value; }
205 [DefaultValue (true)]
206 public bool CanOverflow {
207 get { return this.can_overflow; }
208 set { this.can_overflow = value; }
212 [DefaultValue (false)]
213 public new bool CausesValidation {
214 get { return base.CausesValidation; }
215 set { base.CausesValidation = value; }
218 [EditorBrowsable (EditorBrowsableState.Never)]
219 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
220 public new ControlCollection Controls {
221 get { return base.Controls; }
225 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
226 public override Cursor Cursor {
227 get { return base.Cursor; }
228 set { base.Cursor = value; }
232 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
233 get { return this.default_drop_down_direction; }
235 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
236 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
238 this.default_drop_down_direction = value;
242 public override Rectangle DisplayRectangle {
244 if (this.orientation == Orientation.Horizontal)
245 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
246 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
248 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);
250 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
251 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
253 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);
257 [DefaultValue (DockStyle.Top)]
258 public override DockStyle Dock {
259 get { return base.Dock; }
261 if (base.Dock != value) {
266 case DockStyle.Bottom:
268 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
271 case DockStyle.Right:
272 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
279 public override Font Font {
280 get { return base.Font; }
282 if (base.Font != value) {
285 foreach (ToolStripItem tsi in this.Items)
286 tsi.OnOwnerFontChanged (EventArgs.Empty);
292 public new Color ForeColor {
293 get { return this.fore_color; }
295 if (this.fore_color != value) {
296 this.fore_color = value;
297 this.OnForeColorChanged (EventArgs.Empty);
303 public ToolStripGripDisplayStyle GripDisplayStyle {
304 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
307 public Padding GripMargin {
308 get { return this.grip_margin; }
310 if (this.grip_margin != value) {
311 this.grip_margin = value;
312 this.PerformLayout ();
318 public Rectangle GripRectangle {
320 if (this.grip_style == ToolStripGripStyle.Hidden)
321 return Rectangle.Empty;
323 if (this.orientation == Orientation.Horizontal)
324 return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
326 return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
330 [DefaultValue (ToolStripGripStyle.Visible)]
331 public ToolStripGripStyle GripStyle {
332 get { return this.grip_style; }
334 if (this.grip_style != value) {
335 if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
336 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
337 this.grip_style = value;
338 this.PerformLayout ();
344 [EditorBrowsable (EditorBrowsableState.Never)]
345 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
346 public new bool HasChildren {
347 get { return base.HasChildren; }
351 [EditorBrowsable (EditorBrowsableState.Never)]
352 public new HScrollProperties HorizontalScroll {
353 get { return base.HorizontalScroll; }
357 [DefaultValue (null)]
358 public ImageList ImageList {
359 get { return this.image_list; }
360 set { this.image_list = value; }
363 [DefaultValue ("{Width=16, Height=16}")]
364 public Size ImageScalingSize {
365 get { return this.image_scaling_size; }
366 set { this.image_scaling_size = value; }
369 [MonoTODO ("Always returns false, dragging not implemented yet.")]
371 [EditorBrowsable (EditorBrowsableState.Advanced)]
372 public bool IsCurrentlyDragging {
373 get { return false; }
377 public bool IsDropDown {
379 if (this is ToolStripDropDown)
386 [MergableProperty (false)]
387 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
388 public virtual ToolStripItemCollection Items {
389 get { return this.items; }
392 public override LayoutEngine LayoutEngine {
394 if (layout_engine == null)
395 this.layout_engine = new ToolStripSplitStackLayout ();
397 return this.layout_engine;
402 [DefaultValue (null)]
403 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
404 public LayoutSettings LayoutSettings {
405 get { return this.layout_settings; }
406 set { this.layout_settings = value; }
409 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
410 public ToolStripLayoutStyle LayoutStyle {
411 get { return layout_style; }
413 if (this.layout_style != value) {
414 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
415 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
417 this.layout_style = value;
419 if (this.layout_style == ToolStripLayoutStyle.Flow)
420 this.layout_engine = new FlowLayout ();
422 this.layout_engine = new ToolStripSplitStackLayout ();
424 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
425 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
426 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
428 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
431 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
432 this.orientation = Orientation.Horizontal;
433 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
434 this.orientation = Orientation.Vertical;
436 this.layout_settings = this.CreateLayoutSettings (value);
438 this.PerformLayout ();
439 this.OnLayoutStyleChanged (EventArgs.Empty);
445 public Orientation Orientation {
446 get { return this.orientation; }
450 [EditorBrowsable (EditorBrowsableState.Advanced)]
451 public ToolStripOverflowButton OverflowButton {
452 get { return this.overflow_button; }
456 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
457 public ToolStripRenderer Renderer {
459 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
460 return ToolStripManager.Renderer;
462 return this.renderer;
465 if (this.renderer != value) {
466 this.renderer = value;
467 this.render_mode = ToolStripRenderMode.Custom;
468 this.PerformLayout ();
469 this.OnRendererChanged (EventArgs.Empty);
474 public ToolStripRenderMode RenderMode {
475 get { return this.render_mode; }
477 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
478 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
480 if (value == ToolStripRenderMode.Custom && this.renderer == null)
481 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
482 else if (value == ToolStripRenderMode.Professional)
483 this.Renderer = new ToolStripProfessionalRenderer ();
484 else if (value == ToolStripRenderMode.System)
485 this.Renderer = new ToolStripSystemRenderer ();
487 this.render_mode = value;
491 [DefaultValue (true)]
492 public bool ShowItemToolTips {
493 get { return this.show_item_tool_tips; }
494 set { this.show_item_tool_tips = value; }
497 [DefaultValue (false)]
498 public bool Stretch {
499 get { return this.stretch; }
500 set { this.stretch = value; }
503 [DefaultValue (false)]
505 public new bool TabStop {
506 get { return base.TabStop; }
508 base.TabStop = value;
509 SetStyle (ControlStyles.Selectable, value);
513 [DefaultValue (ToolStripTextDirection.Horizontal)]
514 public virtual ToolStripTextDirection TextDirection {
515 get { return this.text_direction; }
517 if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
518 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
520 if (this.text_direction != value) {
521 this.text_direction = value;
523 this.PerformLayout (this, "TextDirection");
531 [EditorBrowsable (EditorBrowsableState.Never)]
532 public new VScrollProperties VerticalScroll {
533 get { return base.VerticalScroll; }
537 #region Protected Properties
538 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
539 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
540 protected override Padding DefaultMargin { get { return Padding.Empty; } }
541 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
542 protected virtual bool DefaultShowItemToolTips { get { return true; } }
543 protected override Size DefaultSize { get { return new Size (100, 25); } }
544 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
545 protected internal virtual Size MaxItemSize {
546 get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); }
550 #region Public Methods
551 [EditorBrowsable (EditorBrowsableState.Never)]
552 public new Control GetChildAtPoint (Point point)
554 return base.GetChildAtPoint (point);
557 [EditorBrowsable (EditorBrowsableState.Never)]
558 public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
560 return base.GetChildAtPoint (pt, skipValue);
563 public ToolStripItem GetItemAt (Point point)
565 foreach (ToolStripItem tsi in this.displayed_items)
566 if (tsi.Visible && tsi.Bounds.Contains (point))
572 public ToolStripItem GetItemAt (int x, int y)
574 return GetItemAt (new Point (x, y));
577 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
579 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
580 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
582 ToolStripItem current_best = null;
583 int current_best_point;
586 case ArrowDirection.Right:
587 current_best_point = int.MaxValue;
590 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
591 if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
592 current_best = loop_tsi;
593 current_best_point = loop_tsi.Left;
596 if (current_best == null)
597 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
598 if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
599 current_best = loop_tsi;
600 current_best_point = loop_tsi.Left;
604 case ArrowDirection.Up:
605 current_best_point = int.MinValue;
608 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
609 if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
610 current_best = loop_tsi;
611 current_best_point = loop_tsi.Top;
614 if (current_best == null)
615 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
616 if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
617 current_best = loop_tsi;
618 current_best_point = loop_tsi.Top;
622 case ArrowDirection.Left:
623 current_best_point = int.MinValue;
626 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
627 if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
628 current_best = loop_tsi;
629 current_best_point = loop_tsi.Left;
632 if (current_best == null)
633 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
634 if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
635 current_best = loop_tsi;
636 current_best_point = loop_tsi.Left;
640 case ArrowDirection.Down:
641 current_best_point = int.MaxValue;
644 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
645 if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
646 current_best = loop_tsi;
647 current_best_point = loop_tsi.Top;
650 if (current_best == null)
651 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
652 if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
653 current_best = loop_tsi;
654 current_best_point = loop_tsi.Top;
663 [EditorBrowsable (EditorBrowsableState.Never)]
664 public void ResetMinimumSize ()
666 this.MinimumSize = new Size (-1, -1);
669 [EditorBrowsable (EditorBrowsableState.Never)]
670 public new void SetAutoScrollMargin (int x, int y)
672 base.SetAutoScrollMargin (x, y);
675 public override string ToString ()
677 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
681 #region Protected Methods
682 protected override AccessibleObject CreateAccessibilityInstance ()
684 return new ToolStripAccessibleObject (this);
687 protected override ControlCollection CreateControlsInstance ()
689 return base.CreateControlsInstance ();
692 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
695 return new ToolStripSeparator ();
697 if (this is ToolStripDropDown)
698 return new ToolStripMenuItem (text, image, onClick);
700 return new ToolStripButton (text, image, onClick);
703 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
705 switch (layoutStyle) {
706 case ToolStripLayoutStyle.Flow:
707 return new FlowLayoutSettings ();
708 case ToolStripLayoutStyle.Table:
709 //return new TableLayoutSettings ();
710 case ToolStripLayoutStyle.StackWithOverflow:
711 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
712 case ToolStripLayoutStyle.VerticalStackWithOverflow:
718 protected override void Dispose (bool disposing)
721 ToolStripManager.RemoveToolStrip (this);
722 base.Dispose (disposing);
726 [MonoTODO ("Not called")]
727 protected virtual void OnBeginDrag (EventArgs e)
729 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
734 protected override void OnDockChanged (EventArgs e)
736 base.OnDockChanged (e);
739 [MonoTODO ("Not called")]
740 protected virtual void OnEndDrag (EventArgs e)
742 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
747 protected override bool IsInputChar (char charCode)
749 return base.IsInputChar (charCode);
752 protected override bool IsInputKey (Keys keyData)
754 return base.IsInputKey (keyData);
757 protected override void OnEnabledChanged (EventArgs e)
759 base.OnEnabledChanged (e);
761 foreach (ToolStripItem tsi in this.Items)
762 tsi.OnParentEnabledChanged (EventArgs.Empty);
765 protected override void OnFontChanged (EventArgs e)
767 base.OnFontChanged (e);
770 protected override void OnHandleCreated (EventArgs e)
772 base.OnHandleCreated (e);
775 protected override void OnHandleDestroyed (EventArgs e)
777 base.OnHandleDestroyed (e);
780 protected override void OnInvalidated (InvalidateEventArgs e)
782 base.OnInvalidated (e);
785 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
787 if (e.Item.InternalVisible)
788 e.Item.Available = true;
790 e.Item.SetPlacement (ToolStripItemPlacement.Main);
793 this.PerformLayout ();
795 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
800 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
802 if (this.KeyboardActive)
803 ToolStripManager.SetActiveToolStrip (null, false);
805 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
810 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
812 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
817 protected override void OnLayout (LayoutEventArgs e)
821 this.SetDisplayedItems ();
822 this.OnLayoutCompleted (EventArgs.Empty);
826 protected virtual void OnLayoutCompleted (EventArgs e)
828 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
833 protected virtual void OnLayoutStyleChanged (EventArgs e)
835 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
840 protected override void OnLeave (EventArgs e)
845 protected override void OnLostFocus (EventArgs e)
847 base.OnLostFocus (e);
850 protected override void OnMouseCaptureChanged (EventArgs e)
852 base.OnMouseCaptureChanged (e);
855 protected override void OnMouseDown (MouseEventArgs mea)
857 if (mouse_currently_over != null)
859 ToolStripItem focused = GetCurrentlyFocusedItem ();
861 if (focused != null && focused != mouse_currently_over)
862 this.FocusInternal (true);
864 if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
866 (this as MenuStrip).FireMenuActivate ();
871 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
873 if (this is MenuStrip && !menu_selected) {
874 (this as MenuStrip).FireMenuActivate ();
875 menu_selected = true;
878 if (this is MenuStrip)
879 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
882 if (this is MenuStrip)
883 this.Capture = false;
885 base.OnMouseDown (mea);
888 protected override void OnMouseLeave (EventArgs e)
890 if (mouse_currently_over != null) {
891 MouseLeftItem (mouse_currently_over);
892 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
893 mouse_currently_over = null;
896 base.OnMouseLeave (e);
899 protected override void OnMouseMove (MouseEventArgs mea)
902 // Find the item we are now
903 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
904 tsi = this.overflow_button;
906 tsi = this.GetItemAt (mea.X, mea.Y);
909 // If we were already hovering on this item, just send a mouse move
910 if (tsi == mouse_currently_over)
911 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
913 // If we were over a different item, fire a mouse leave on it
914 if (mouse_currently_over != null) {
916 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
919 // Set the new item we are currently over
920 mouse_currently_over = tsi;
922 // Fire mouse enter and mouse move
923 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
924 MouseEnteredItem (tsi);
925 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
927 // If we're over something with a drop down, show it
928 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
929 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
932 // We're not over anything now, just fire the mouse leave on what we used to be over
933 if (mouse_currently_over != null) {
935 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
936 mouse_currently_over = null;
940 base.OnMouseMove (mea);
943 protected override void OnMouseUp (MouseEventArgs mea)
945 // If we're currently over an item (set in MouseMove)
946 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
947 // Fire our ItemClicked event
948 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
950 // Fire the item's MouseUp event
951 if (mouse_currently_over != null)
952 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
954 // The event handler may have blocked until the mouse moved off of the ToolStripItem
955 if (mouse_currently_over == null)
959 base.OnMouseUp (mea);
962 protected override void OnPaint (PaintEventArgs e)
967 this.OnPaintGrip (e);
969 // Make each item draw itself
970 foreach (ToolStripItem tsi in this.displayed_items) {
972 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
973 tsi.FireEvent (e, ToolStripItemEventType.Paint);
974 e.Graphics.ResetTransform ();
978 // Paint the Overflow button if it's visible
979 if (this.overflow_button != null && this.overflow_button.Visible) {
980 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
981 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
982 e.Graphics.ResetTransform ();
985 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
987 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
988 pevent.InternalConnectedArea = CalculateConnectedArea ();
990 this.Renderer.DrawToolStripBorder (pevent);
993 [EditorBrowsable (EditorBrowsableState.Advanced)]
994 protected override void OnPaintBackground (PaintEventArgs e)
996 base.OnPaintBackground (e);
998 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
999 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1001 this.Renderer.DrawToolStripBackground (tsrea);
1004 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1006 // Never draw a grip with these two layouts
1007 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1010 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1014 if (!(this is MenuStrip)) {
1015 if (this.orientation == Orientation.Horizontal)
1016 e.Graphics.TranslateTransform (2, 0);
1018 e.Graphics.TranslateTransform (0, 2);
1021 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1022 e.Graphics.ResetTransform ();
1025 protected virtual void OnRendererChanged (EventArgs e)
1027 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1032 [EditorBrowsable (EditorBrowsableState.Advanced)]
1033 protected override void OnRightToLeftChanged (EventArgs e)
1035 base.OnRightToLeftChanged (e);
1037 foreach (ToolStripItem tsi in this.Items)
1038 tsi.OnParentRightToLeftChanged (e);
1041 protected override void OnScroll (ScrollEventArgs se)
1046 protected override void OnTabStopChanged (EventArgs e)
1048 base.OnTabStopChanged (e);
1051 protected override void OnVisibleChanged (EventArgs e)
1053 base.OnVisibleChanged (e);
1056 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1058 return base.ProcessCmdKey (ref m, keyData);
1061 protected override bool ProcessDialogKey (Keys keyData)
1063 if (!this.KeyboardActive)
1066 // Give each item a chance to handle the key
1067 foreach (ToolStripItem tsi in this.Items)
1068 if (tsi.ProcessDialogKey (keyData))
1071 // See if I want to handle it
1072 if (this.ProcessArrowKey (keyData))
1075 ToolStrip ts = null;
1079 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1082 case Keys.Control | Keys.Tab:
1083 ts = ToolStripManager.GetNextToolStrip (this, true);
1086 foreach (ToolStripItem tsi in this.Items)
1087 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1089 ToolStripManager.SetActiveToolStrip (ts, true);
1090 ts.SelectNextToolStripItem (null, true);
1094 case Keys.Control | Keys.Shift | Keys.Tab:
1095 ts = ToolStripManager.GetNextToolStrip (this, false);
1098 foreach (ToolStripItem tsi in this.Items)
1099 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1101 ToolStripManager.SetActiveToolStrip (ts, true);
1102 ts.SelectNextToolStripItem (null, true);
1110 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1115 return base.ProcessDialogKey (keyData);
1118 protected override bool ProcessMnemonic (char charCode)
1120 // If any item has an explicit mnemonic, it gets the message
1121 foreach (ToolStripItem tsi in this.Items)
1122 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1123 return tsi.ProcessMnemonic (charCode);
1125 string code = Char.ToUpper (charCode).ToString ();
1127 // If any item's text starts with our letter, it gets the message
1128 if (this is ToolStripDropDownMenu)
1129 foreach (ToolStripItem tsi in this.Items)
1130 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code))
1131 return tsi.ProcessMnemonic (charCode);
1133 return base.ProcessMnemonic (charCode);
1137 [EditorBrowsable (EditorBrowsableState.Advanced)]
1138 protected virtual void RestoreFocus ()
1143 protected override void Select (bool directed, bool forward)
1145 foreach (ToolStripItem tsi in this.DisplayedItems)
1146 if (tsi.CanSelect) {
1152 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1154 base.SetBoundsCore (x, y, width, height, specified);
1157 protected virtual void SetDisplayedItems ()
1159 this.displayed_items.Clear ();
1161 foreach (ToolStripItem tsi in this.items)
1162 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1163 this.displayed_items.AddNoOwnerOrLayout (tsi);
1166 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1167 tsi.Parent = this.OverflowButton.DropDown;
1169 if (this.OverflowButton != null)
1170 this.OverflowButton.DropDown.SetDisplayedItems ();
1173 protected internal void SetItemLocation (ToolStripItem item, Point location)
1176 throw new ArgumentNullException ("item");
1178 if (item.Owner != this)
1179 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1181 item.SetBounds (new Rectangle (location, item.Size));
1184 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1186 if (item.Owner != null) {
1187 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1189 if (item.Owner is ToolStripOverflow)
1190 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1193 parent.Items.AddNoOwnerOrLayout (item);
1194 item.Parent = parent;
1197 protected override void SetVisibleCore (bool visible)
1199 base.SetVisibleCore (visible);
1202 protected override void WndProc (ref Message m)
1204 base.WndProc (ref m);
1208 #region Public Events
1209 static object BeginDragEvent = new object ();
1210 static object EndDragEvent = new object ();
1211 static object ItemAddedEvent = new object ();
1212 static object ItemClickedEvent = new object ();
1213 static object ItemRemovedEvent = new object ();
1214 static object LayoutCompletedEvent = new object ();
1215 static object LayoutStyleChangedEvent = new object ();
1216 static object PaintGripEvent = new object ();
1217 static object RendererChangedEvent = new object ();
1220 [EditorBrowsable (EditorBrowsableState.Always)]
1221 public new event EventHandler AutoSizeChanged {
1222 add { base.AutoSizeChanged += value; }
1223 remove { base.AutoSizeChanged -= value; }
1227 public event EventHandler BeginDrag {
1228 add { Events.AddHandler (BeginDragEvent, value); }
1229 remove { Events.RemoveHandler (BeginDragEvent, value); }
1233 public new event EventHandler CausesValidationChanged {
1234 add { base.CausesValidationChanged += value; }
1235 remove { base.CausesValidationChanged -= value; }
1239 [EditorBrowsable (EditorBrowsableState.Never)]
1240 public new event ControlEventHandler ControlAdded {
1241 add { base.ControlAdded += value; }
1242 remove { base.ControlAdded -= value; }
1246 [EditorBrowsable (EditorBrowsableState.Never)]
1247 public new event ControlEventHandler ControlRemoved {
1248 add { base.ControlRemoved += value; }
1249 remove { base.ControlRemoved -= value; }
1253 public new event EventHandler CursorChanged {
1254 add { base.CursorChanged += value; }
1255 remove { base.CursorChanged -= value; }
1259 public event EventHandler EndDrag {
1260 add { Events.AddHandler (EndDragEvent, value); }
1261 remove { Events.RemoveHandler (EndDragEvent, value); }
1265 public new event EventHandler ForeColorChanged {
1266 add { base.ForeColorChanged += value; }
1267 remove { base.ForeColorChanged -= value; }
1270 public event ToolStripItemEventHandler ItemAdded {
1271 add { Events.AddHandler (ItemAddedEvent, value); }
1272 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1275 public event ToolStripItemClickedEventHandler ItemClicked {
1276 add { Events.AddHandler (ItemClickedEvent, value); }
1277 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1280 public event ToolStripItemEventHandler ItemRemoved {
1281 add { Events.AddHandler (ItemRemovedEvent, value); }
1282 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1285 public event EventHandler LayoutCompleted {
1286 add { Events.AddHandler (LayoutCompletedEvent, value); }
1287 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1290 public event EventHandler LayoutStyleChanged {
1291 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1292 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1295 public event PaintEventHandler PaintGrip {
1296 add { Events.AddHandler (PaintGripEvent, value); }
1297 remove { Events.RemoveHandler (PaintGripEvent, value); }
1300 public event EventHandler RendererChanged {
1301 add { Events.AddHandler (RendererChangedEvent, value); }
1302 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1306 #region Internal Properties
1307 internal virtual bool KeyboardActive
1309 get { return this.keyboard_active; }
1311 if (this.keyboard_active != value) {
1312 this.keyboard_active = value;
1315 Application.KeyboardCapture = this;
1316 else if (Application.KeyboardCapture == this) {
1317 Application.KeyboardCapture = null;
1318 ToolStripManager.ActivatedByKeyboard = false;
1321 // Redraw for mnemonic underlines
1328 #region Private Methods
1329 internal virtual Rectangle CalculateConnectedArea ()
1331 return Rectangle.Empty;
1334 internal void ChangeSelection (ToolStripItem nextItem)
1336 if (Application.KeyboardCapture != this)
1337 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1339 foreach (ToolStripItem tsi in this.Items)
1340 if (tsi != nextItem)
1341 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1343 ToolStripItem current = GetCurrentlySelectedItem ();
1345 if (current != null && !(current is ToolStripControlHost))
1346 this.FocusInternal (true);
1348 if (nextItem is ToolStripControlHost)
1349 (nextItem as ToolStripControlHost).Focus ();
1353 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1354 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1357 internal virtual void Dismiss ()
1359 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1362 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1364 // Release our stranglehold on the keyboard
1365 this.KeyboardActive = false;
1367 // Set our drop down flag to false;
1368 this.menu_selected = false;
1370 // Make sure all of our items are deselected and repainted
1371 foreach (ToolStripItem tsi in this.Items)
1372 tsi.Dismiss (reason);
1374 // We probably need to redraw for mnemonic underlines
1378 internal ToolStripItem GetCurrentlySelectedItem ()
1380 foreach (ToolStripItem tsi in this.DisplayedItems)
1387 internal ToolStripItem GetCurrentlyFocusedItem ()
1389 foreach (ToolStripItem tsi in this.DisplayedItems)
1390 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1396 internal override Size GetPreferredSizeCore (Size proposedSize)
1398 return GetToolStripPreferredSize (proposedSize);
1401 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1403 Size new_size = Size.Empty;
1405 // TODO: This is total duct tape. We really have to call into the correct
1406 // layout engine, do a dry run of the layout, and find out our true
1407 // preferred dimensions.
1408 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1409 Point currentLocation = Point.Empty;
1412 foreach (ToolStripItem tsi in items) {
1413 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1415 currentLocation.Y += tallest;
1418 currentLocation.X = DisplayRectangle.Left;
1421 // Offset the left margin and set the control to our point
1422 currentLocation.Offset (tsi.Margin.Left, 0);
1423 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1425 // Update our location pointer
1426 currentLocation.X += tsi.Width + tsi.Margin.Right;
1429 currentLocation.Y += tallest;
1430 return new Size (currentLocation.X, currentLocation.Y);
1433 if (this.orientation == Orientation.Vertical) {
1434 foreach (ToolStripItem tsi in this.items)
1435 if (tsi.Available) {
1436 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1437 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1439 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1440 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1443 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1445 if (new_size.Width == 0)
1446 new_size.Width = ExplicitBounds.Width;
1450 foreach (ToolStripItem tsi in this.items)
1451 if (tsi.Available) {
1452 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1453 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1455 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1456 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1459 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1461 if (new_size.Height == 0)
1462 new_size.Height = ExplicitBounds.Height;
1464 if (this is StatusStrip)
1465 new_size.Height = Math.Max (new_size.Height, 22);
1471 internal virtual ToolStrip GetTopLevelToolStrip ()
1476 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1478 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1481 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1483 if (this is MenuStrip && release && menu_selected)
1484 (this as MenuStrip).FireMenuDeactivate ();
1487 menu_selected = false;
1489 NotifySelectedChanged (null);
1492 internal void NotifySelectedChanged (ToolStripItem tsi)
1494 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1496 if (tsi2 is ToolStripDropDownItem)
1497 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1499 if (this.OverflowButton != null) {
1500 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1502 foreach (ToolStripItem tsi2 in tsic)
1504 if (tsi2 is ToolStripDropDownItem)
1505 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1507 this.OverflowButton.HideDropDown ();
1510 foreach (ToolStripItem tsi2 in this.Items)
1512 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1515 internal virtual bool OnMenuKey ()
1520 internal virtual bool ProcessArrowKey (Keys keyData)
1526 tsi = this.GetCurrentlySelectedItem ();
1528 if (tsi is ToolStripControlHost)
1531 tsi = this.SelectNextToolStripItem (tsi, true);
1533 if (tsi is ToolStripControlHost)
1534 (tsi as ToolStripControlHost).Focus ();
1538 tsi = this.GetCurrentlySelectedItem ();
1540 tsi = this.SelectNextToolStripItem (tsi, true);
1542 if (tsi is ToolStripControlHost)
1543 (tsi as ToolStripControlHost).Focus ();
1547 tsi = this.GetCurrentlySelectedItem ();
1549 if (tsi is ToolStripControlHost)
1552 tsi = this.SelectNextToolStripItem (tsi, false);
1554 if (tsi is ToolStripControlHost)
1555 (tsi as ToolStripControlHost).Focus ();
1558 case Keys.Shift | Keys.Tab:
1559 tsi = this.GetCurrentlySelectedItem ();
1561 tsi = this.SelectNextToolStripItem (tsi, false);
1563 if (tsi is ToolStripControlHost)
1564 (tsi as ToolStripControlHost).Focus ();
1572 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1574 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1576 this.ChangeSelection (next_item);
1578 if (next_item is ToolStripControlHost)
1579 (next_item as ToolStripControlHost).Focus ();
1584 #region Stuff for ToolTips
1585 private void MouseEnteredItem (ToolStripItem item)
1587 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1588 tooltip_currently_showing = item;
1589 ToolTipTimer.Start ();
1593 private void MouseLeftItem (ToolStripItem item)
1595 ToolTipTimer.Stop ();
1596 ToolTipWindow.Hide (this);
1597 tooltip_currently_showing = null;
1600 private Timer ToolTipTimer {
1602 if (tooltip_timer == null) {
1603 tooltip_timer = new Timer ();
1604 tooltip_timer.Enabled = false;
1605 tooltip_timer.Interval = 500;
1606 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1609 return tooltip_timer;
1613 private ToolTip ToolTipWindow {
1615 if (tooltip_window == null)
1616 tooltip_window = new ToolTip ();
1618 return tooltip_window;
1622 private void ToolTipTimer_Tick (object o, EventArgs args)
1624 string tooltip = tooltip_currently_showing.GetToolTip ();
1626 if (!string.IsNullOrEmpty (tooltip))
1627 ToolTipWindow.Present (this, tooltip);
1629 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1631 ToolTipTimer.Stop ();
1635 #region Stuff for Merging
1636 internal ToolStrip CurrentlyMergedWith {
1637 get { return this.currently_merged_with; }
1638 set { this.currently_merged_with = value; }
1641 internal List<ToolStripItem> HiddenMergedItems {
1643 if (this.hidden_merged_items == null)
1644 this.hidden_merged_items = new List<ToolStripItem> ();
1646 return this.hidden_merged_items;
1650 internal bool IsCurrentlyMerged {
1651 get { return this.is_currently_merged; }
1653 this.is_currently_merged = value;
1655 if (!value && this is MenuStrip)
1656 foreach (ToolStripMenuItem tsmi in this.Items)
1657 tsmi.DropDown.IsCurrentlyMerged = value;
1661 internal void BeginMerge ()
1663 if (!IsCurrentlyMerged) {
1664 IsCurrentlyMerged = true;
1666 if (this.pre_merge_items == null) {
1667 this.pre_merge_items = new List<ToolStripItem> ();
1669 foreach (ToolStripItem tsi in this.Items)
1670 this.pre_merge_items.Add (tsi);
1675 internal void RevertMergeItem (ToolStripItem item)
1679 // Remove it from it's current Parent
1680 if (item.Parent != null && item.Parent != this) {
1681 if (item.Parent is ToolStripOverflow)
1682 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1684 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1686 item.Parent = item.Owner;
1689 // Find where the item was before the merge
1690 index = item.Owner.pre_merge_items.IndexOf (item);
1692 // Find the first pre-merge item that was after this item, that
1693 // is currently in the Items collection. Insert our item before
1695 for (int i = index; i < this.pre_merge_items.Count; i++) {
1696 if (this.Items.Contains (this.pre_merge_items[i])) {
1697 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1702 // There aren't any items that are supposed to be after this item,
1703 // so just append it to the end.
1704 item.Owner.Items.AddNoOwnerOrLayout (item);
1709 #region ToolStripAccessibleObject
1711 public class ToolStripAccessibleObject : ControlAccessibleObject
1713 #region Public Constructor
1714 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1719 #region Public Properties
1720 public override AccessibleRole Role {
1721 get { return AccessibleRole.ToolBar; }
1725 #region Public Methods
1726 public override AccessibleObject GetChild (int index)
1728 return base.GetChild (index);
1731 public override int GetChildCount ()
1733 return (owner as ToolStrip).Items.Count;
1736 public override AccessibleObject HitTest (int x, int y)
1738 return base.HitTest (x, y);