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 (this, "GripStyle");
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; }
407 if (this.layout_settings != value) {
408 this.layout_settings = value;
409 PerformLayout (this, "LayoutSettings");
414 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
415 public ToolStripLayoutStyle LayoutStyle {
416 get { return layout_style; }
418 if (this.layout_style != value) {
419 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
420 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
422 this.layout_style = value;
424 if (this.layout_style == ToolStripLayoutStyle.Flow)
425 this.layout_engine = new FlowLayout ();
427 this.layout_engine = new ToolStripSplitStackLayout ();
429 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
430 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
431 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
433 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
436 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
437 this.orientation = Orientation.Horizontal;
438 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
439 this.orientation = Orientation.Vertical;
441 this.layout_settings = this.CreateLayoutSettings (value);
443 this.PerformLayout (this, "LayoutStyle");
444 this.OnLayoutStyleChanged (EventArgs.Empty);
450 public Orientation Orientation {
451 get { return this.orientation; }
455 [EditorBrowsable (EditorBrowsableState.Advanced)]
456 public ToolStripOverflowButton OverflowButton {
457 get { return this.overflow_button; }
461 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
462 public ToolStripRenderer Renderer {
464 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
465 return ToolStripManager.Renderer;
467 return this.renderer;
470 if (this.renderer != value) {
471 this.renderer = value;
472 this.render_mode = ToolStripRenderMode.Custom;
473 this.PerformLayout (this, "Renderer");
474 this.OnRendererChanged (EventArgs.Empty);
479 public ToolStripRenderMode RenderMode {
480 get { return this.render_mode; }
482 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
483 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
485 if (value == ToolStripRenderMode.Custom && this.renderer == null)
486 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
487 else if (value == ToolStripRenderMode.Professional)
488 this.Renderer = new ToolStripProfessionalRenderer ();
489 else if (value == ToolStripRenderMode.System)
490 this.Renderer = new ToolStripSystemRenderer ();
492 this.render_mode = value;
496 [DefaultValue (true)]
497 public bool ShowItemToolTips {
498 get { return this.show_item_tool_tips; }
499 set { this.show_item_tool_tips = value; }
502 [DefaultValue (false)]
503 public bool Stretch {
504 get { return this.stretch; }
505 set { this.stretch = value; }
508 [DefaultValue (false)]
510 public new bool TabStop {
511 get { return base.TabStop; }
513 base.TabStop = value;
514 SetStyle (ControlStyles.Selectable, value);
518 [DefaultValue (ToolStripTextDirection.Horizontal)]
519 public virtual ToolStripTextDirection TextDirection {
520 get { return this.text_direction; }
522 if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
523 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
525 if (this.text_direction != value) {
526 this.text_direction = value;
528 this.PerformLayout (this, "TextDirection");
536 [EditorBrowsable (EditorBrowsableState.Never)]
537 public new VScrollProperties VerticalScroll {
538 get { return base.VerticalScroll; }
542 #region Protected Properties
543 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
544 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
545 protected override Padding DefaultMargin { get { return Padding.Empty; } }
546 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
547 protected virtual bool DefaultShowItemToolTips { get { return true; } }
548 protected override Size DefaultSize { get { return new Size (100, 25); } }
549 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
550 protected internal virtual Size MaxItemSize {
551 get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); }
555 #region Public Methods
556 [EditorBrowsable (EditorBrowsableState.Never)]
557 public new Control GetChildAtPoint (Point point)
559 return base.GetChildAtPoint (point);
562 [EditorBrowsable (EditorBrowsableState.Never)]
563 public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
565 return base.GetChildAtPoint (pt, skipValue);
568 public ToolStripItem GetItemAt (Point point)
570 foreach (ToolStripItem tsi in this.displayed_items)
571 if (tsi.Visible && tsi.Bounds.Contains (point))
577 public ToolStripItem GetItemAt (int x, int y)
579 return GetItemAt (new Point (x, y));
582 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
584 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
585 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
587 ToolStripItem current_best = null;
588 int current_best_point;
591 case ArrowDirection.Right:
592 current_best_point = int.MaxValue;
595 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
596 if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
597 current_best = loop_tsi;
598 current_best_point = loop_tsi.Left;
601 if (current_best == null)
602 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
603 if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
604 current_best = loop_tsi;
605 current_best_point = loop_tsi.Left;
609 case ArrowDirection.Up:
610 current_best_point = int.MinValue;
613 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
614 if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
615 current_best = loop_tsi;
616 current_best_point = loop_tsi.Top;
619 if (current_best == null)
620 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
621 if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
622 current_best = loop_tsi;
623 current_best_point = loop_tsi.Top;
627 case ArrowDirection.Left:
628 current_best_point = int.MinValue;
631 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
632 if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
633 current_best = loop_tsi;
634 current_best_point = loop_tsi.Left;
637 if (current_best == null)
638 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
639 if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
640 current_best = loop_tsi;
641 current_best_point = loop_tsi.Left;
645 case ArrowDirection.Down:
646 current_best_point = int.MaxValue;
649 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
650 if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
651 current_best = loop_tsi;
652 current_best_point = loop_tsi.Top;
655 if (current_best == null)
656 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
657 if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
658 current_best = loop_tsi;
659 current_best_point = loop_tsi.Top;
668 [EditorBrowsable (EditorBrowsableState.Never)]
669 public void ResetMinimumSize ()
671 this.MinimumSize = new Size (-1, -1);
674 [EditorBrowsable (EditorBrowsableState.Never)]
675 public new void SetAutoScrollMargin (int x, int y)
677 base.SetAutoScrollMargin (x, y);
680 public override string ToString ()
682 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
686 #region Protected Methods
687 protected override AccessibleObject CreateAccessibilityInstance ()
689 return new ToolStripAccessibleObject (this);
692 protected override ControlCollection CreateControlsInstance ()
694 return base.CreateControlsInstance ();
697 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
700 return new ToolStripSeparator ();
702 if (this is ToolStripDropDown)
703 return new ToolStripMenuItem (text, image, onClick);
705 return new ToolStripButton (text, image, onClick);
708 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
710 switch (layoutStyle) {
711 case ToolStripLayoutStyle.Flow:
712 return new FlowLayoutSettings (this);
713 case ToolStripLayoutStyle.Table:
714 //return new TableLayoutSettings ();
715 case ToolStripLayoutStyle.StackWithOverflow:
716 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
717 case ToolStripLayoutStyle.VerticalStackWithOverflow:
723 protected override void Dispose (bool disposing)
726 // ToolStripItem.Dispose modifes the collection,
727 // so we iterate it in reverse order
728 for (int i = Items.Count - 1; i >= 0; i--)
729 Items [i].Dispose ();
731 if (this.overflow_button != null && this.overflow_button.drop_down != null)
732 this.overflow_button.drop_down.Dispose ();
734 ToolStripManager.RemoveToolStrip (this);
735 base.Dispose (disposing);
739 [MonoTODO ("Not called")]
740 protected virtual void OnBeginDrag (EventArgs e)
742 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
747 protected override void OnDockChanged (EventArgs e)
749 base.OnDockChanged (e);
752 [MonoTODO ("Not called")]
753 protected virtual void OnEndDrag (EventArgs e)
755 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
760 protected override bool IsInputChar (char charCode)
762 return base.IsInputChar (charCode);
765 protected override bool IsInputKey (Keys keyData)
767 return base.IsInputKey (keyData);
770 protected override void OnEnabledChanged (EventArgs e)
772 base.OnEnabledChanged (e);
774 foreach (ToolStripItem tsi in this.Items)
775 tsi.OnParentEnabledChanged (EventArgs.Empty);
778 protected override void OnFontChanged (EventArgs e)
780 base.OnFontChanged (e);
783 protected override void OnHandleCreated (EventArgs e)
785 base.OnHandleCreated (e);
788 protected override void OnHandleDestroyed (EventArgs e)
790 base.OnHandleDestroyed (e);
793 protected override void OnInvalidated (InvalidateEventArgs e)
795 base.OnInvalidated (e);
798 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
800 if (e.Item.InternalVisible)
801 e.Item.Available = true;
803 e.Item.SetPlacement (ToolStripItemPlacement.Main);
806 this.PerformLayout ();
808 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
813 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
815 if (this.KeyboardActive)
816 ToolStripManager.SetActiveToolStrip (null, false);
818 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
823 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
825 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
830 protected override void OnLayout (LayoutEventArgs e)
834 this.SetDisplayedItems ();
835 this.OnLayoutCompleted (EventArgs.Empty);
839 protected virtual void OnLayoutCompleted (EventArgs e)
841 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
846 protected virtual void OnLayoutStyleChanged (EventArgs e)
848 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
853 protected override void OnLeave (EventArgs e)
858 protected override void OnLostFocus (EventArgs e)
860 base.OnLostFocus (e);
863 protected override void OnMouseCaptureChanged (EventArgs e)
865 base.OnMouseCaptureChanged (e);
868 protected override void OnMouseDown (MouseEventArgs mea)
870 if (mouse_currently_over != null)
872 ToolStripItem focused = GetCurrentlyFocusedItem ();
874 if (focused != null && focused != mouse_currently_over)
875 this.FocusInternal (true);
877 if (this is MenuStrip && !menu_selected) {
878 (this as MenuStrip).FireMenuActivate ();
879 menu_selected = true;
882 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
884 if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems)
887 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
890 if (this is MenuStrip)
891 this.Capture = false;
893 base.OnMouseDown (mea);
896 protected override void OnMouseLeave (EventArgs e)
898 if (mouse_currently_over != null) {
899 MouseLeftItem (mouse_currently_over);
900 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
901 mouse_currently_over = null;
904 base.OnMouseLeave (e);
907 protected override void OnMouseMove (MouseEventArgs mea)
910 // Find the item we are now
911 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
912 tsi = this.overflow_button;
914 tsi = this.GetItemAt (mea.X, mea.Y);
917 // If we were already hovering on this item, just send a mouse move
918 if (tsi == mouse_currently_over)
919 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
921 // If we were over a different item, fire a mouse leave on it
922 if (mouse_currently_over != null) {
924 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
927 // Set the new item we are currently over
928 mouse_currently_over = tsi;
930 // Fire mouse enter and mouse move
931 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
932 MouseEnteredItem (tsi);
933 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
935 // If we're over something with a drop down, show it
936 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
937 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
940 // We're not over anything now, just fire the mouse leave on what we used to be over
941 if (mouse_currently_over != null) {
943 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
944 mouse_currently_over = null;
948 base.OnMouseMove (mea);
951 protected override void OnMouseUp (MouseEventArgs mea)
953 // If we're currently over an item (set in MouseMove)
954 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
955 // Fire our ItemClicked event
956 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
958 // Fire the item's MouseUp event
959 if (mouse_currently_over != null)
960 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
962 // The event handler may have blocked until the mouse moved off of the ToolStripItem
963 if (mouse_currently_over == null)
967 base.OnMouseUp (mea);
970 protected override void OnPaint (PaintEventArgs e)
975 this.OnPaintGrip (e);
977 // Make each item draw itself
978 for (int i = 0; i < displayed_items.Count; i++) {
979 ToolStripItem tsi = displayed_items[i];
982 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
983 tsi.FireEvent (e, ToolStripItemEventType.Paint);
984 e.Graphics.ResetTransform ();
988 // Paint the Overflow button if it's visible
989 if (this.overflow_button != null && this.overflow_button.Visible) {
990 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
991 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
992 e.Graphics.ResetTransform ();
995 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
997 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
998 pevent.InternalConnectedArea = CalculateConnectedArea ();
1000 this.Renderer.DrawToolStripBorder (pevent);
1003 [EditorBrowsable (EditorBrowsableState.Advanced)]
1004 protected override void OnPaintBackground (PaintEventArgs e)
1006 base.OnPaintBackground (e);
1008 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1009 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1011 this.Renderer.DrawToolStripBackground (tsrea);
1014 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1016 // Never draw a grip with these two layouts
1017 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1020 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1024 if (!(this is MenuStrip)) {
1025 if (this.orientation == Orientation.Horizontal)
1026 e.Graphics.TranslateTransform (2, 0);
1028 e.Graphics.TranslateTransform (0, 2);
1031 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1032 e.Graphics.ResetTransform ();
1035 protected virtual void OnRendererChanged (EventArgs e)
1037 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1042 [EditorBrowsable (EditorBrowsableState.Advanced)]
1043 protected override void OnRightToLeftChanged (EventArgs e)
1045 base.OnRightToLeftChanged (e);
1047 foreach (ToolStripItem tsi in this.Items)
1048 tsi.OnParentRightToLeftChanged (e);
1051 protected override void OnScroll (ScrollEventArgs se)
1056 protected override void OnTabStopChanged (EventArgs e)
1058 base.OnTabStopChanged (e);
1061 protected override void OnVisibleChanged (EventArgs e)
1063 base.OnVisibleChanged (e);
1066 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1068 return base.ProcessCmdKey (ref m, keyData);
1071 protected override bool ProcessDialogKey (Keys keyData)
1073 if (!this.KeyboardActive)
1076 // Give each item a chance to handle the key
1077 foreach (ToolStripItem tsi in this.Items)
1078 if (tsi.ProcessDialogKey (keyData))
1081 // See if I want to handle it
1082 if (this.ProcessArrowKey (keyData))
1085 ToolStrip ts = null;
1089 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1092 case Keys.Control | Keys.Tab:
1093 ts = ToolStripManager.GetNextToolStrip (this, true);
1096 foreach (ToolStripItem tsi in this.Items)
1097 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1099 ToolStripManager.SetActiveToolStrip (ts, true);
1100 ts.SelectNextToolStripItem (null, true);
1104 case Keys.Control | Keys.Shift | Keys.Tab:
1105 ts = ToolStripManager.GetNextToolStrip (this, false);
1108 foreach (ToolStripItem tsi in this.Items)
1109 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1111 ToolStripManager.SetActiveToolStrip (ts, true);
1112 ts.SelectNextToolStripItem (null, true);
1120 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1125 return base.ProcessDialogKey (keyData);
1128 protected override bool ProcessMnemonic (char charCode)
1130 // If any item has an explicit mnemonic, it gets the message
1131 foreach (ToolStripItem tsi in this.Items)
1132 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1133 return tsi.ProcessMnemonic (charCode);
1135 string code = Char.ToUpper (charCode).ToString ();
1137 // If any item's text starts with our letter, it gets the message
1138 if (this is ToolStripDropDownMenu)
1139 foreach (ToolStripItem tsi in this.Items)
1140 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
1141 return tsi.ProcessMnemonic (charCode);
1143 return base.ProcessMnemonic (charCode);
1147 [EditorBrowsable (EditorBrowsableState.Advanced)]
1148 protected virtual void RestoreFocus ()
1153 protected override void Select (bool directed, bool forward)
1155 foreach (ToolStripItem tsi in this.DisplayedItems)
1156 if (tsi.CanSelect) {
1162 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1164 base.SetBoundsCore (x, y, width, height, specified);
1167 protected virtual void SetDisplayedItems ()
1169 this.displayed_items.Clear ();
1171 foreach (ToolStripItem tsi in this.items)
1172 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1173 this.displayed_items.AddNoOwnerOrLayout (tsi);
1176 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1177 tsi.Parent = this.OverflowButton.DropDown;
1179 if (this.OverflowButton != null)
1180 this.OverflowButton.DropDown.SetDisplayedItems ();
1183 protected internal void SetItemLocation (ToolStripItem item, Point location)
1186 throw new ArgumentNullException ("item");
1188 if (item.Owner != this)
1189 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1191 item.SetBounds (new Rectangle (location, item.Size));
1194 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1196 if (item.Owner != null) {
1197 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1199 if (item.Owner is ToolStripOverflow)
1200 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1203 parent.Items.AddNoOwnerOrLayout (item);
1204 item.Parent = parent;
1207 protected override void SetVisibleCore (bool visible)
1209 base.SetVisibleCore (visible);
1212 protected override void WndProc (ref Message m)
1214 base.WndProc (ref m);
1218 #region Public Events
1219 static object BeginDragEvent = new object ();
1220 static object EndDragEvent = new object ();
1221 static object ItemAddedEvent = new object ();
1222 static object ItemClickedEvent = new object ();
1223 static object ItemRemovedEvent = new object ();
1224 static object LayoutCompletedEvent = new object ();
1225 static object LayoutStyleChangedEvent = new object ();
1226 static object PaintGripEvent = new object ();
1227 static object RendererChangedEvent = new object ();
1230 [EditorBrowsable (EditorBrowsableState.Always)]
1231 public new event EventHandler AutoSizeChanged {
1232 add { base.AutoSizeChanged += value; }
1233 remove { base.AutoSizeChanged -= value; }
1237 public event EventHandler BeginDrag {
1238 add { Events.AddHandler (BeginDragEvent, value); }
1239 remove { Events.RemoveHandler (BeginDragEvent, value); }
1243 public new event EventHandler CausesValidationChanged {
1244 add { base.CausesValidationChanged += value; }
1245 remove { base.CausesValidationChanged -= value; }
1249 [EditorBrowsable (EditorBrowsableState.Never)]
1250 public new event ControlEventHandler ControlAdded {
1251 add { base.ControlAdded += value; }
1252 remove { base.ControlAdded -= value; }
1256 [EditorBrowsable (EditorBrowsableState.Never)]
1257 public new event ControlEventHandler ControlRemoved {
1258 add { base.ControlRemoved += value; }
1259 remove { base.ControlRemoved -= value; }
1263 public new event EventHandler CursorChanged {
1264 add { base.CursorChanged += value; }
1265 remove { base.CursorChanged -= value; }
1269 public event EventHandler EndDrag {
1270 add { Events.AddHandler (EndDragEvent, value); }
1271 remove { Events.RemoveHandler (EndDragEvent, value); }
1275 public new event EventHandler ForeColorChanged {
1276 add { base.ForeColorChanged += value; }
1277 remove { base.ForeColorChanged -= value; }
1280 public event ToolStripItemEventHandler ItemAdded {
1281 add { Events.AddHandler (ItemAddedEvent, value); }
1282 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1285 public event ToolStripItemClickedEventHandler ItemClicked {
1286 add { Events.AddHandler (ItemClickedEvent, value); }
1287 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1290 public event ToolStripItemEventHandler ItemRemoved {
1291 add { Events.AddHandler (ItemRemovedEvent, value); }
1292 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1295 public event EventHandler LayoutCompleted {
1296 add { Events.AddHandler (LayoutCompletedEvent, value); }
1297 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1300 public event EventHandler LayoutStyleChanged {
1301 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1302 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1305 public event PaintEventHandler PaintGrip {
1306 add { Events.AddHandler (PaintGripEvent, value); }
1307 remove { Events.RemoveHandler (PaintGripEvent, value); }
1310 public event EventHandler RendererChanged {
1311 add { Events.AddHandler (RendererChangedEvent, value); }
1312 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1316 #region Internal Properties
1317 internal virtual bool KeyboardActive
1319 get { return this.keyboard_active; }
1321 if (this.keyboard_active != value) {
1322 this.keyboard_active = value;
1325 Application.KeyboardCapture = this;
1326 else if (Application.KeyboardCapture == this) {
1327 Application.KeyboardCapture = null;
1328 ToolStripManager.ActivatedByKeyboard = false;
1331 // Redraw for mnemonic underlines
1338 #region Private Methods
1339 internal virtual Rectangle CalculateConnectedArea ()
1341 return Rectangle.Empty;
1344 internal void ChangeSelection (ToolStripItem nextItem)
1346 if (Application.KeyboardCapture != this)
1347 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1349 foreach (ToolStripItem tsi in this.Items)
1350 if (tsi != nextItem)
1351 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1353 ToolStripItem current = GetCurrentlySelectedItem ();
1355 if (current != null && !(current is ToolStripControlHost))
1356 this.FocusInternal (true);
1358 if (nextItem is ToolStripControlHost)
1359 (nextItem as ToolStripControlHost).Focus ();
1363 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1364 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1367 internal virtual void Dismiss ()
1369 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1372 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1374 // Release our stranglehold on the keyboard
1375 this.KeyboardActive = false;
1377 // Set our drop down flag to false;
1378 this.menu_selected = false;
1380 // Make sure all of our items are deselected and repainted
1381 foreach (ToolStripItem tsi in this.Items)
1382 tsi.Dismiss (reason);
1384 // We probably need to redraw for mnemonic underlines
1388 internal ToolStripItem GetCurrentlySelectedItem ()
1390 foreach (ToolStripItem tsi in this.DisplayedItems)
1397 internal ToolStripItem GetCurrentlyFocusedItem ()
1399 foreach (ToolStripItem tsi in this.DisplayedItems)
1400 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1406 internal override Size GetPreferredSizeCore (Size proposedSize)
1408 return GetToolStripPreferredSize (proposedSize);
1411 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1413 Size new_size = Size.Empty;
1415 // TODO: This is total duct tape. We really have to call into the correct
1416 // layout engine, do a dry run of the layout, and find out our true
1417 // preferred dimensions.
1418 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1419 Point currentLocation = Point.Empty;
1422 foreach (ToolStripItem tsi in items) {
1423 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1425 currentLocation.Y += tallest;
1428 currentLocation.X = DisplayRectangle.Left;
1431 // Offset the left margin and set the control to our point
1432 currentLocation.Offset (tsi.Margin.Left, 0);
1433 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1435 // Update our location pointer
1436 currentLocation.X += tsi.Width + tsi.Margin.Right;
1439 currentLocation.Y += tallest;
1440 return new Size (currentLocation.X, currentLocation.Y);
1443 if (this.orientation == Orientation.Vertical) {
1444 foreach (ToolStripItem tsi in this.items)
1445 if (tsi.Available) {
1446 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1447 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1449 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1450 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1453 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1455 if (new_size.Width == 0)
1456 new_size.Width = ExplicitBounds.Width;
1460 foreach (ToolStripItem tsi in this.items)
1461 if (tsi.Available) {
1462 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1463 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1465 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1466 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1469 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1471 if (new_size.Height == 0)
1472 new_size.Height = ExplicitBounds.Height;
1474 if (this is StatusStrip)
1475 new_size.Height = Math.Max (new_size.Height, 22);
1481 internal virtual ToolStrip GetTopLevelToolStrip ()
1486 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1488 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1491 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1493 if (this is MenuStrip && release && menu_selected)
1494 (this as MenuStrip).FireMenuDeactivate ();
1497 menu_selected = false;
1499 NotifySelectedChanged (null);
1502 internal void NotifySelectedChanged (ToolStripItem tsi)
1504 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1506 if (tsi2 is ToolStripDropDownItem)
1507 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1509 if (this.OverflowButton != null) {
1510 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1512 foreach (ToolStripItem tsi2 in tsic)
1514 if (tsi2 is ToolStripDropDownItem)
1515 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1517 this.OverflowButton.HideDropDown ();
1520 foreach (ToolStripItem tsi2 in this.Items)
1522 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1525 internal virtual bool OnMenuKey ()
1530 internal virtual bool ProcessArrowKey (Keys keyData)
1536 tsi = this.GetCurrentlySelectedItem ();
1538 if (tsi is ToolStripControlHost)
1541 tsi = this.SelectNextToolStripItem (tsi, true);
1543 if (tsi is ToolStripControlHost)
1544 (tsi as ToolStripControlHost).Focus ();
1548 tsi = this.GetCurrentlySelectedItem ();
1550 tsi = this.SelectNextToolStripItem (tsi, true);
1552 if (tsi is ToolStripControlHost)
1553 (tsi as ToolStripControlHost).Focus ();
1557 tsi = this.GetCurrentlySelectedItem ();
1559 if (tsi is ToolStripControlHost)
1562 tsi = this.SelectNextToolStripItem (tsi, false);
1564 if (tsi is ToolStripControlHost)
1565 (tsi as ToolStripControlHost).Focus ();
1568 case Keys.Shift | Keys.Tab:
1569 tsi = this.GetCurrentlySelectedItem ();
1571 tsi = this.SelectNextToolStripItem (tsi, false);
1573 if (tsi is ToolStripControlHost)
1574 (tsi as ToolStripControlHost).Focus ();
1582 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1584 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1586 if (next_item == null)
1589 this.ChangeSelection (next_item);
1591 if (next_item is ToolStripControlHost)
1592 (next_item as ToolStripControlHost).Focus ();
1597 #region Stuff for ToolTips
1598 private void MouseEnteredItem (ToolStripItem item)
1600 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1601 tooltip_currently_showing = item;
1602 ToolTipTimer.Start ();
1606 private void MouseLeftItem (ToolStripItem item)
1608 ToolTipTimer.Stop ();
1609 ToolTipWindow.Hide (this);
1610 tooltip_currently_showing = null;
1613 private Timer ToolTipTimer {
1615 if (tooltip_timer == null) {
1616 tooltip_timer = new Timer ();
1617 tooltip_timer.Enabled = false;
1618 tooltip_timer.Interval = 500;
1619 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1622 return tooltip_timer;
1626 private ToolTip ToolTipWindow {
1628 if (tooltip_window == null)
1629 tooltip_window = new ToolTip ();
1631 return tooltip_window;
1635 private void ToolTipTimer_Tick (object o, EventArgs args)
1637 string tooltip = tooltip_currently_showing.GetToolTip ();
1639 if (!string.IsNullOrEmpty (tooltip))
1640 ToolTipWindow.Present (this, tooltip);
1642 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1644 ToolTipTimer.Stop ();
1648 #region Stuff for Merging
1649 internal ToolStrip CurrentlyMergedWith {
1650 get { return this.currently_merged_with; }
1651 set { this.currently_merged_with = value; }
1654 internal List<ToolStripItem> HiddenMergedItems {
1656 if (this.hidden_merged_items == null)
1657 this.hidden_merged_items = new List<ToolStripItem> ();
1659 return this.hidden_merged_items;
1663 internal bool IsCurrentlyMerged {
1664 get { return this.is_currently_merged; }
1666 this.is_currently_merged = value;
1668 if (!value && this is MenuStrip)
1669 foreach (ToolStripMenuItem tsmi in this.Items)
1670 tsmi.DropDown.IsCurrentlyMerged = value;
1674 internal void BeginMerge ()
1676 if (!IsCurrentlyMerged) {
1677 IsCurrentlyMerged = true;
1679 if (this.pre_merge_items == null) {
1680 this.pre_merge_items = new List<ToolStripItem> ();
1682 foreach (ToolStripItem tsi in this.Items)
1683 this.pre_merge_items.Add (tsi);
1688 internal void RevertMergeItem (ToolStripItem item)
1692 // Remove it from it's current Parent
1693 if (item.Parent != null && item.Parent != this) {
1694 if (item.Parent is ToolStripOverflow)
1695 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1697 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1699 item.Parent = item.Owner;
1702 // Find where the item was before the merge
1703 index = item.Owner.pre_merge_items.IndexOf (item);
1705 // Find the first pre-merge item that was after this item, that
1706 // is currently in the Items collection. Insert our item before
1708 for (int i = index; i < this.pre_merge_items.Count; i++) {
1709 if (this.Items.Contains (this.pre_merge_items[i])) {
1710 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1715 // There aren't any items that are supposed to be after this item,
1716 // so just append it to the end.
1717 item.Owner.Items.AddNoOwnerOrLayout (item);
1722 #region ToolStripAccessibleObject
1724 public class ToolStripAccessibleObject : ControlAccessibleObject
1726 #region Public Constructor
1727 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1732 #region Public Properties
1733 public override AccessibleRole Role {
1734 get { return AccessibleRole.ToolBar; }
1738 #region Public Methods
1739 public override AccessibleObject GetChild (int index)
1741 return base.GetChild (index);
1744 public override int GetChildCount ()
1746 return (owner as ToolStrip).Items.Count;
1749 public override AccessibleObject HitTest (int x, int y)
1751 return base.HitTest (x, y);