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 foreach (ToolStripItem tsi in Items)
724 if (this.overflow_button != null && this.overflow_button.drop_down != null)
725 this.overflow_button.drop_down.Dispose ();
727 ToolStripManager.RemoveToolStrip (this);
728 base.Dispose (disposing);
732 [MonoTODO ("Not called")]
733 protected virtual void OnBeginDrag (EventArgs e)
735 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
740 protected override void OnDockChanged (EventArgs e)
742 base.OnDockChanged (e);
745 [MonoTODO ("Not called")]
746 protected virtual void OnEndDrag (EventArgs e)
748 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
753 protected override bool IsInputChar (char charCode)
755 return base.IsInputChar (charCode);
758 protected override bool IsInputKey (Keys keyData)
760 return base.IsInputKey (keyData);
763 protected override void OnEnabledChanged (EventArgs e)
765 base.OnEnabledChanged (e);
767 foreach (ToolStripItem tsi in this.Items)
768 tsi.OnParentEnabledChanged (EventArgs.Empty);
771 protected override void OnFontChanged (EventArgs e)
773 base.OnFontChanged (e);
776 protected override void OnHandleCreated (EventArgs e)
778 base.OnHandleCreated (e);
781 protected override void OnHandleDestroyed (EventArgs e)
783 base.OnHandleDestroyed (e);
786 protected override void OnInvalidated (InvalidateEventArgs e)
788 base.OnInvalidated (e);
791 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
793 if (e.Item.InternalVisible)
794 e.Item.Available = true;
796 e.Item.SetPlacement (ToolStripItemPlacement.Main);
799 this.PerformLayout ();
801 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
806 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
808 if (this.KeyboardActive)
809 ToolStripManager.SetActiveToolStrip (null, false);
811 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
816 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
818 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
823 protected override void OnLayout (LayoutEventArgs e)
827 this.SetDisplayedItems ();
828 this.OnLayoutCompleted (EventArgs.Empty);
832 protected virtual void OnLayoutCompleted (EventArgs e)
834 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
839 protected virtual void OnLayoutStyleChanged (EventArgs e)
841 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
846 protected override void OnLeave (EventArgs e)
851 protected override void OnLostFocus (EventArgs e)
853 base.OnLostFocus (e);
856 protected override void OnMouseCaptureChanged (EventArgs e)
858 base.OnMouseCaptureChanged (e);
861 protected override void OnMouseDown (MouseEventArgs mea)
863 if (mouse_currently_over != null)
865 ToolStripItem focused = GetCurrentlyFocusedItem ();
867 if (focused != null && focused != mouse_currently_over)
868 this.FocusInternal (true);
870 if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
872 (this as MenuStrip).FireMenuActivate ();
877 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
879 if (this is MenuStrip && !menu_selected) {
880 (this as MenuStrip).FireMenuActivate ();
881 menu_selected = true;
884 if (this is MenuStrip)
885 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
888 if (this is MenuStrip)
889 this.Capture = false;
891 base.OnMouseDown (mea);
894 protected override void OnMouseLeave (EventArgs e)
896 if (mouse_currently_over != null) {
897 MouseLeftItem (mouse_currently_over);
898 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
899 mouse_currently_over = null;
902 base.OnMouseLeave (e);
905 protected override void OnMouseMove (MouseEventArgs mea)
908 // Find the item we are now
909 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
910 tsi = this.overflow_button;
912 tsi = this.GetItemAt (mea.X, mea.Y);
915 // If we were already hovering on this item, just send a mouse move
916 if (tsi == mouse_currently_over)
917 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
919 // If we were over a different item, fire a mouse leave on it
920 if (mouse_currently_over != null) {
922 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
925 // Set the new item we are currently over
926 mouse_currently_over = tsi;
928 // Fire mouse enter and mouse move
929 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
930 MouseEnteredItem (tsi);
931 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
933 // If we're over something with a drop down, show it
934 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
935 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
938 // We're not over anything now, just fire the mouse leave on what we used to be over
939 if (mouse_currently_over != null) {
941 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
942 mouse_currently_over = null;
946 base.OnMouseMove (mea);
949 protected override void OnMouseUp (MouseEventArgs mea)
951 // If we're currently over an item (set in MouseMove)
952 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
953 // Fire our ItemClicked event
954 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
956 // Fire the item's MouseUp event
957 if (mouse_currently_over != null)
958 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
960 // The event handler may have blocked until the mouse moved off of the ToolStripItem
961 if (mouse_currently_over == null)
965 base.OnMouseUp (mea);
968 protected override void OnPaint (PaintEventArgs e)
973 this.OnPaintGrip (e);
975 // Make each item draw itself
976 foreach (ToolStripItem tsi in this.displayed_items) {
978 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
979 tsi.FireEvent (e, ToolStripItemEventType.Paint);
980 e.Graphics.ResetTransform ();
984 // Paint the Overflow button if it's visible
985 if (this.overflow_button != null && this.overflow_button.Visible) {
986 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
987 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
988 e.Graphics.ResetTransform ();
991 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
993 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
994 pevent.InternalConnectedArea = CalculateConnectedArea ();
996 this.Renderer.DrawToolStripBorder (pevent);
999 [EditorBrowsable (EditorBrowsableState.Advanced)]
1000 protected override void OnPaintBackground (PaintEventArgs e)
1002 base.OnPaintBackground (e);
1004 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1005 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1007 this.Renderer.DrawToolStripBackground (tsrea);
1010 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1012 // Never draw a grip with these two layouts
1013 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1016 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1020 if (!(this is MenuStrip)) {
1021 if (this.orientation == Orientation.Horizontal)
1022 e.Graphics.TranslateTransform (2, 0);
1024 e.Graphics.TranslateTransform (0, 2);
1027 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1028 e.Graphics.ResetTransform ();
1031 protected virtual void OnRendererChanged (EventArgs e)
1033 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1038 [EditorBrowsable (EditorBrowsableState.Advanced)]
1039 protected override void OnRightToLeftChanged (EventArgs e)
1041 base.OnRightToLeftChanged (e);
1043 foreach (ToolStripItem tsi in this.Items)
1044 tsi.OnParentRightToLeftChanged (e);
1047 protected override void OnScroll (ScrollEventArgs se)
1052 protected override void OnTabStopChanged (EventArgs e)
1054 base.OnTabStopChanged (e);
1057 protected override void OnVisibleChanged (EventArgs e)
1059 base.OnVisibleChanged (e);
1062 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1064 return base.ProcessCmdKey (ref m, keyData);
1067 protected override bool ProcessDialogKey (Keys keyData)
1069 if (!this.KeyboardActive)
1072 // Give each item a chance to handle the key
1073 foreach (ToolStripItem tsi in this.Items)
1074 if (tsi.ProcessDialogKey (keyData))
1077 // See if I want to handle it
1078 if (this.ProcessArrowKey (keyData))
1081 ToolStrip ts = null;
1085 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1088 case Keys.Control | Keys.Tab:
1089 ts = ToolStripManager.GetNextToolStrip (this, true);
1092 foreach (ToolStripItem tsi in this.Items)
1093 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1095 ToolStripManager.SetActiveToolStrip (ts, true);
1096 ts.SelectNextToolStripItem (null, true);
1100 case Keys.Control | Keys.Shift | Keys.Tab:
1101 ts = ToolStripManager.GetNextToolStrip (this, false);
1104 foreach (ToolStripItem tsi in this.Items)
1105 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1107 ToolStripManager.SetActiveToolStrip (ts, true);
1108 ts.SelectNextToolStripItem (null, true);
1116 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1121 return base.ProcessDialogKey (keyData);
1124 protected override bool ProcessMnemonic (char charCode)
1126 // If any item has an explicit mnemonic, it gets the message
1127 foreach (ToolStripItem tsi in this.Items)
1128 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1129 return tsi.ProcessMnemonic (charCode);
1131 string code = Char.ToUpper (charCode).ToString ();
1133 // If any item's text starts with our letter, it gets the message
1134 if (this is ToolStripDropDownMenu)
1135 foreach (ToolStripItem tsi in this.Items)
1136 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
1137 return tsi.ProcessMnemonic (charCode);
1139 return base.ProcessMnemonic (charCode);
1143 [EditorBrowsable (EditorBrowsableState.Advanced)]
1144 protected virtual void RestoreFocus ()
1149 protected override void Select (bool directed, bool forward)
1151 foreach (ToolStripItem tsi in this.DisplayedItems)
1152 if (tsi.CanSelect) {
1158 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1160 base.SetBoundsCore (x, y, width, height, specified);
1163 protected virtual void SetDisplayedItems ()
1165 this.displayed_items.Clear ();
1167 foreach (ToolStripItem tsi in this.items)
1168 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1169 this.displayed_items.AddNoOwnerOrLayout (tsi);
1172 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1173 tsi.Parent = this.OverflowButton.DropDown;
1175 if (this.OverflowButton != null)
1176 this.OverflowButton.DropDown.SetDisplayedItems ();
1179 protected internal void SetItemLocation (ToolStripItem item, Point location)
1182 throw new ArgumentNullException ("item");
1184 if (item.Owner != this)
1185 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1187 item.SetBounds (new Rectangle (location, item.Size));
1190 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1192 if (item.Owner != null) {
1193 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1195 if (item.Owner is ToolStripOverflow)
1196 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1199 parent.Items.AddNoOwnerOrLayout (item);
1200 item.Parent = parent;
1203 protected override void SetVisibleCore (bool visible)
1205 base.SetVisibleCore (visible);
1208 protected override void WndProc (ref Message m)
1210 base.WndProc (ref m);
1214 #region Public Events
1215 static object BeginDragEvent = new object ();
1216 static object EndDragEvent = new object ();
1217 static object ItemAddedEvent = new object ();
1218 static object ItemClickedEvent = new object ();
1219 static object ItemRemovedEvent = new object ();
1220 static object LayoutCompletedEvent = new object ();
1221 static object LayoutStyleChangedEvent = new object ();
1222 static object PaintGripEvent = new object ();
1223 static object RendererChangedEvent = new object ();
1226 [EditorBrowsable (EditorBrowsableState.Always)]
1227 public new event EventHandler AutoSizeChanged {
1228 add { base.AutoSizeChanged += value; }
1229 remove { base.AutoSizeChanged -= value; }
1233 public event EventHandler BeginDrag {
1234 add { Events.AddHandler (BeginDragEvent, value); }
1235 remove { Events.RemoveHandler (BeginDragEvent, value); }
1239 public new event EventHandler CausesValidationChanged {
1240 add { base.CausesValidationChanged += value; }
1241 remove { base.CausesValidationChanged -= value; }
1245 [EditorBrowsable (EditorBrowsableState.Never)]
1246 public new event ControlEventHandler ControlAdded {
1247 add { base.ControlAdded += value; }
1248 remove { base.ControlAdded -= value; }
1252 [EditorBrowsable (EditorBrowsableState.Never)]
1253 public new event ControlEventHandler ControlRemoved {
1254 add { base.ControlRemoved += value; }
1255 remove { base.ControlRemoved -= value; }
1259 public new event EventHandler CursorChanged {
1260 add { base.CursorChanged += value; }
1261 remove { base.CursorChanged -= value; }
1265 public event EventHandler EndDrag {
1266 add { Events.AddHandler (EndDragEvent, value); }
1267 remove { Events.RemoveHandler (EndDragEvent, value); }
1271 public new event EventHandler ForeColorChanged {
1272 add { base.ForeColorChanged += value; }
1273 remove { base.ForeColorChanged -= value; }
1276 public event ToolStripItemEventHandler ItemAdded {
1277 add { Events.AddHandler (ItemAddedEvent, value); }
1278 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1281 public event ToolStripItemClickedEventHandler ItemClicked {
1282 add { Events.AddHandler (ItemClickedEvent, value); }
1283 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1286 public event ToolStripItemEventHandler ItemRemoved {
1287 add { Events.AddHandler (ItemRemovedEvent, value); }
1288 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1291 public event EventHandler LayoutCompleted {
1292 add { Events.AddHandler (LayoutCompletedEvent, value); }
1293 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1296 public event EventHandler LayoutStyleChanged {
1297 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1298 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1301 public event PaintEventHandler PaintGrip {
1302 add { Events.AddHandler (PaintGripEvent, value); }
1303 remove { Events.RemoveHandler (PaintGripEvent, value); }
1306 public event EventHandler RendererChanged {
1307 add { Events.AddHandler (RendererChangedEvent, value); }
1308 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1312 #region Internal Properties
1313 internal virtual bool KeyboardActive
1315 get { return this.keyboard_active; }
1317 if (this.keyboard_active != value) {
1318 this.keyboard_active = value;
1321 Application.KeyboardCapture = this;
1322 else if (Application.KeyboardCapture == this) {
1323 Application.KeyboardCapture = null;
1324 ToolStripManager.ActivatedByKeyboard = false;
1327 // Redraw for mnemonic underlines
1334 #region Private Methods
1335 internal virtual Rectangle CalculateConnectedArea ()
1337 return Rectangle.Empty;
1340 internal void ChangeSelection (ToolStripItem nextItem)
1342 if (Application.KeyboardCapture != this)
1343 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1345 foreach (ToolStripItem tsi in this.Items)
1346 if (tsi != nextItem)
1347 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1349 ToolStripItem current = GetCurrentlySelectedItem ();
1351 if (current != null && !(current is ToolStripControlHost))
1352 this.FocusInternal (true);
1354 if (nextItem is ToolStripControlHost)
1355 (nextItem as ToolStripControlHost).Focus ();
1359 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1360 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1363 internal virtual void Dismiss ()
1365 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1368 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1370 // Release our stranglehold on the keyboard
1371 this.KeyboardActive = false;
1373 // Set our drop down flag to false;
1374 this.menu_selected = false;
1376 // Make sure all of our items are deselected and repainted
1377 foreach (ToolStripItem tsi in this.Items)
1378 tsi.Dismiss (reason);
1380 // We probably need to redraw for mnemonic underlines
1384 internal ToolStripItem GetCurrentlySelectedItem ()
1386 foreach (ToolStripItem tsi in this.DisplayedItems)
1393 internal ToolStripItem GetCurrentlyFocusedItem ()
1395 foreach (ToolStripItem tsi in this.DisplayedItems)
1396 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1402 internal override Size GetPreferredSizeCore (Size proposedSize)
1404 return GetToolStripPreferredSize (proposedSize);
1407 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1409 Size new_size = Size.Empty;
1411 // TODO: This is total duct tape. We really have to call into the correct
1412 // layout engine, do a dry run of the layout, and find out our true
1413 // preferred dimensions.
1414 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1415 Point currentLocation = Point.Empty;
1418 foreach (ToolStripItem tsi in items) {
1419 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1421 currentLocation.Y += tallest;
1424 currentLocation.X = DisplayRectangle.Left;
1427 // Offset the left margin and set the control to our point
1428 currentLocation.Offset (tsi.Margin.Left, 0);
1429 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1431 // Update our location pointer
1432 currentLocation.X += tsi.Width + tsi.Margin.Right;
1435 currentLocation.Y += tallest;
1436 return new Size (currentLocation.X, currentLocation.Y);
1439 if (this.orientation == Orientation.Vertical) {
1440 foreach (ToolStripItem tsi in this.items)
1441 if (tsi.Available) {
1442 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1443 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1445 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1446 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1449 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1451 if (new_size.Width == 0)
1452 new_size.Width = ExplicitBounds.Width;
1456 foreach (ToolStripItem tsi in this.items)
1457 if (tsi.Available) {
1458 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1459 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1461 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1462 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1465 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1467 if (new_size.Height == 0)
1468 new_size.Height = ExplicitBounds.Height;
1470 if (this is StatusStrip)
1471 new_size.Height = Math.Max (new_size.Height, 22);
1477 internal virtual ToolStrip GetTopLevelToolStrip ()
1482 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1484 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1487 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1489 if (this is MenuStrip && release && menu_selected)
1490 (this as MenuStrip).FireMenuDeactivate ();
1493 menu_selected = false;
1495 NotifySelectedChanged (null);
1498 internal void NotifySelectedChanged (ToolStripItem tsi)
1500 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1502 if (tsi2 is ToolStripDropDownItem)
1503 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1505 if (this.OverflowButton != null) {
1506 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1508 foreach (ToolStripItem tsi2 in tsic)
1510 if (tsi2 is ToolStripDropDownItem)
1511 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1513 this.OverflowButton.HideDropDown ();
1516 foreach (ToolStripItem tsi2 in this.Items)
1518 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1521 internal virtual bool OnMenuKey ()
1526 internal virtual bool ProcessArrowKey (Keys keyData)
1532 tsi = this.GetCurrentlySelectedItem ();
1534 if (tsi is ToolStripControlHost)
1537 tsi = this.SelectNextToolStripItem (tsi, true);
1539 if (tsi is ToolStripControlHost)
1540 (tsi as ToolStripControlHost).Focus ();
1544 tsi = this.GetCurrentlySelectedItem ();
1546 tsi = this.SelectNextToolStripItem (tsi, true);
1548 if (tsi is ToolStripControlHost)
1549 (tsi as ToolStripControlHost).Focus ();
1553 tsi = this.GetCurrentlySelectedItem ();
1555 if (tsi is ToolStripControlHost)
1558 tsi = this.SelectNextToolStripItem (tsi, false);
1560 if (tsi is ToolStripControlHost)
1561 (tsi as ToolStripControlHost).Focus ();
1564 case Keys.Shift | Keys.Tab:
1565 tsi = this.GetCurrentlySelectedItem ();
1567 tsi = this.SelectNextToolStripItem (tsi, false);
1569 if (tsi is ToolStripControlHost)
1570 (tsi as ToolStripControlHost).Focus ();
1578 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1580 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1582 if (next_item == null)
1585 this.ChangeSelection (next_item);
1587 if (next_item is ToolStripControlHost)
1588 (next_item as ToolStripControlHost).Focus ();
1593 #region Stuff for ToolTips
1594 private void MouseEnteredItem (ToolStripItem item)
1596 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1597 tooltip_currently_showing = item;
1598 ToolTipTimer.Start ();
1602 private void MouseLeftItem (ToolStripItem item)
1604 ToolTipTimer.Stop ();
1605 ToolTipWindow.Hide (this);
1606 tooltip_currently_showing = null;
1609 private Timer ToolTipTimer {
1611 if (tooltip_timer == null) {
1612 tooltip_timer = new Timer ();
1613 tooltip_timer.Enabled = false;
1614 tooltip_timer.Interval = 500;
1615 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1618 return tooltip_timer;
1622 private ToolTip ToolTipWindow {
1624 if (tooltip_window == null)
1625 tooltip_window = new ToolTip ();
1627 return tooltip_window;
1631 private void ToolTipTimer_Tick (object o, EventArgs args)
1633 string tooltip = tooltip_currently_showing.GetToolTip ();
1635 if (!string.IsNullOrEmpty (tooltip))
1636 ToolTipWindow.Present (this, tooltip);
1638 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1640 ToolTipTimer.Stop ();
1644 #region Stuff for Merging
1645 internal ToolStrip CurrentlyMergedWith {
1646 get { return this.currently_merged_with; }
1647 set { this.currently_merged_with = value; }
1650 internal List<ToolStripItem> HiddenMergedItems {
1652 if (this.hidden_merged_items == null)
1653 this.hidden_merged_items = new List<ToolStripItem> ();
1655 return this.hidden_merged_items;
1659 internal bool IsCurrentlyMerged {
1660 get { return this.is_currently_merged; }
1662 this.is_currently_merged = value;
1664 if (!value && this is MenuStrip)
1665 foreach (ToolStripMenuItem tsmi in this.Items)
1666 tsmi.DropDown.IsCurrentlyMerged = value;
1670 internal void BeginMerge ()
1672 if (!IsCurrentlyMerged) {
1673 IsCurrentlyMerged = true;
1675 if (this.pre_merge_items == null) {
1676 this.pre_merge_items = new List<ToolStripItem> ();
1678 foreach (ToolStripItem tsi in this.Items)
1679 this.pre_merge_items.Add (tsi);
1684 internal void RevertMergeItem (ToolStripItem item)
1688 // Remove it from it's current Parent
1689 if (item.Parent != null && item.Parent != this) {
1690 if (item.Parent is ToolStripOverflow)
1691 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1693 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1695 item.Parent = item.Owner;
1698 // Find where the item was before the merge
1699 index = item.Owner.pre_merge_items.IndexOf (item);
1701 // Find the first pre-merge item that was after this item, that
1702 // is currently in the Items collection. Insert our item before
1704 for (int i = index; i < this.pre_merge_items.Count; i++) {
1705 if (this.Items.Contains (this.pre_merge_items[i])) {
1706 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1711 // There aren't any items that are supposed to be after this item,
1712 // so just append it to the end.
1713 item.Owner.Items.AddNoOwnerOrLayout (item);
1718 #region ToolStripAccessibleObject
1720 public class ToolStripAccessibleObject : ControlAccessibleObject
1722 #region Public Constructor
1723 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1728 #region Public Properties
1729 public override AccessibleRole Role {
1730 get { return AccessibleRole.ToolBar; }
1734 #region Public Methods
1735 public override AccessibleObject GetChild (int index)
1737 return base.GetChild (index);
1740 public override int GetChildCount ()
1742 return (owner as ToolStrip).Items.Count;
1745 public override AccessibleObject HitTest (int x, int y)
1747 return base.HitTest (x, y);