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
130 [MonoTODO ("Stub, does nothing")]
131 public override bool AllowDrop {
132 get { return base.AllowDrop; }
133 set { base.AllowDrop = value; }
136 [MonoTODO ("Stub, does nothing")]
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 ("Stub, never 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 ("Stub, never 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 ((Control.ModifierKeys & Keys.Alt) != 0 || 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);
1146 [MonoTODO ("Stub, does nothing")]
1147 [EditorBrowsable (EditorBrowsableState.Advanced)]
1148 protected virtual void RestoreFocus ()
1152 protected override void Select (bool directed, bool forward)
1154 foreach (ToolStripItem tsi in this.DisplayedItems)
1155 if (tsi.CanSelect) {
1161 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1163 base.SetBoundsCore (x, y, width, height, specified);
1166 protected virtual void SetDisplayedItems ()
1168 this.displayed_items.Clear ();
1170 foreach (ToolStripItem tsi in this.items)
1171 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1172 this.displayed_items.AddNoOwnerOrLayout (tsi);
1175 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1176 tsi.Parent = this.OverflowButton.DropDown;
1178 if (this.OverflowButton != null)
1179 this.OverflowButton.DropDown.SetDisplayedItems ();
1182 protected internal void SetItemLocation (ToolStripItem item, Point location)
1185 throw new ArgumentNullException ("item");
1187 if (item.Owner != this)
1188 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1190 item.SetBounds (new Rectangle (location, item.Size));
1193 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1195 if (item.Owner != null) {
1196 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1198 if (item.Owner is ToolStripOverflow)
1199 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1202 parent.Items.AddNoOwnerOrLayout (item);
1203 item.Parent = parent;
1206 protected override void SetVisibleCore (bool visible)
1208 base.SetVisibleCore (visible);
1211 protected override void WndProc (ref Message m)
1213 base.WndProc (ref m);
1217 #region Public Events
1218 static object BeginDragEvent = new object ();
1219 static object EndDragEvent = new object ();
1220 static object ItemAddedEvent = new object ();
1221 static object ItemClickedEvent = new object ();
1222 static object ItemRemovedEvent = new object ();
1223 static object LayoutCompletedEvent = new object ();
1224 static object LayoutStyleChangedEvent = new object ();
1225 static object PaintGripEvent = new object ();
1226 static object RendererChangedEvent = new object ();
1229 [EditorBrowsable (EditorBrowsableState.Always)]
1230 public new event EventHandler AutoSizeChanged {
1231 add { base.AutoSizeChanged += value; }
1232 remove { base.AutoSizeChanged -= value; }
1235 [MonoTODO ("Event never raised")]
1236 public event EventHandler BeginDrag {
1237 add { Events.AddHandler (BeginDragEvent, value); }
1238 remove { Events.RemoveHandler (BeginDragEvent, value); }
1242 public new event EventHandler CausesValidationChanged {
1243 add { base.CausesValidationChanged += value; }
1244 remove { base.CausesValidationChanged -= value; }
1248 [EditorBrowsable (EditorBrowsableState.Never)]
1249 public new event ControlEventHandler ControlAdded {
1250 add { base.ControlAdded += value; }
1251 remove { base.ControlAdded -= value; }
1255 [EditorBrowsable (EditorBrowsableState.Never)]
1256 public new event ControlEventHandler ControlRemoved {
1257 add { base.ControlRemoved += value; }
1258 remove { base.ControlRemoved -= value; }
1262 public new event EventHandler CursorChanged {
1263 add { base.CursorChanged += value; }
1264 remove { base.CursorChanged -= value; }
1267 [MonoTODO ("Event never raised")]
1268 public event EventHandler EndDrag {
1269 add { Events.AddHandler (EndDragEvent, value); }
1270 remove { Events.RemoveHandler (EndDragEvent, value); }
1274 public new event EventHandler ForeColorChanged {
1275 add { base.ForeColorChanged += value; }
1276 remove { base.ForeColorChanged -= value; }
1279 public event ToolStripItemEventHandler ItemAdded {
1280 add { Events.AddHandler (ItemAddedEvent, value); }
1281 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1284 public event ToolStripItemClickedEventHandler ItemClicked {
1285 add { Events.AddHandler (ItemClickedEvent, value); }
1286 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1289 public event ToolStripItemEventHandler ItemRemoved {
1290 add { Events.AddHandler (ItemRemovedEvent, value); }
1291 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1294 public event EventHandler LayoutCompleted {
1295 add { Events.AddHandler (LayoutCompletedEvent, value); }
1296 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1299 public event EventHandler LayoutStyleChanged {
1300 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1301 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1304 public event PaintEventHandler PaintGrip {
1305 add { Events.AddHandler (PaintGripEvent, value); }
1306 remove { Events.RemoveHandler (PaintGripEvent, value); }
1309 public event EventHandler RendererChanged {
1310 add { Events.AddHandler (RendererChangedEvent, value); }
1311 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1315 #region Internal Properties
1316 internal virtual bool KeyboardActive
1318 get { return this.keyboard_active; }
1320 if (this.keyboard_active != value) {
1321 this.keyboard_active = value;
1324 Application.KeyboardCapture = this;
1325 else if (Application.KeyboardCapture == this) {
1326 Application.KeyboardCapture = null;
1327 ToolStripManager.ActivatedByKeyboard = false;
1330 // Redraw for mnemonic underlines
1337 #region Private Methods
1338 internal virtual Rectangle CalculateConnectedArea ()
1340 return Rectangle.Empty;
1343 internal void ChangeSelection (ToolStripItem nextItem)
1345 if (Application.KeyboardCapture != this)
1346 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1348 foreach (ToolStripItem tsi in this.Items)
1349 if (tsi != nextItem)
1350 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1352 ToolStripItem current = GetCurrentlySelectedItem ();
1354 if (current != null && !(current is ToolStripControlHost))
1355 this.FocusInternal (true);
1357 if (nextItem is ToolStripControlHost)
1358 (nextItem as ToolStripControlHost).Focus ();
1362 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1363 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1366 internal virtual void Dismiss ()
1368 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1371 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1373 // Release our stranglehold on the keyboard
1374 this.KeyboardActive = false;
1376 // Set our drop down flag to false;
1377 this.menu_selected = false;
1379 // Make sure all of our items are deselected and repainted
1380 foreach (ToolStripItem tsi in this.Items)
1381 tsi.Dismiss (reason);
1383 // We probably need to redraw for mnemonic underlines
1387 internal ToolStripItem GetCurrentlySelectedItem ()
1389 foreach (ToolStripItem tsi in this.DisplayedItems)
1396 internal ToolStripItem GetCurrentlyFocusedItem ()
1398 foreach (ToolStripItem tsi in this.DisplayedItems)
1399 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1405 internal override Size GetPreferredSizeCore (Size proposedSize)
1407 return GetToolStripPreferredSize (proposedSize);
1410 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1412 Size new_size = Size.Empty;
1414 // TODO: This is total duct tape. We really have to call into the correct
1415 // layout engine, do a dry run of the layout, and find out our true
1416 // preferred dimensions.
1417 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1418 Point currentLocation = Point.Empty;
1421 foreach (ToolStripItem tsi in items) {
1422 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1424 currentLocation.Y += tallest;
1427 currentLocation.X = DisplayRectangle.Left;
1430 // Offset the left margin and set the control to our point
1431 currentLocation.Offset (tsi.Margin.Left, 0);
1432 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1434 // Update our location pointer
1435 currentLocation.X += tsi.Width + tsi.Margin.Right;
1438 currentLocation.Y += tallest;
1439 return new Size (currentLocation.X, currentLocation.Y);
1442 if (this.orientation == Orientation.Vertical) {
1443 foreach (ToolStripItem tsi in this.items)
1444 if (tsi.Available) {
1445 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1446 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1448 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1449 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1452 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1454 if (new_size.Width == 0)
1455 new_size.Width = ExplicitBounds.Width;
1459 foreach (ToolStripItem tsi in this.items)
1460 if (tsi.Available) {
1461 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1462 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1464 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1465 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1468 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1470 if (new_size.Height == 0)
1471 new_size.Height = ExplicitBounds.Height;
1473 if (this is StatusStrip)
1474 new_size.Height = Math.Max (new_size.Height, 22);
1480 internal virtual ToolStrip GetTopLevelToolStrip ()
1485 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1487 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1490 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1492 if (this is MenuStrip && release && menu_selected)
1493 (this as MenuStrip).FireMenuDeactivate ();
1496 menu_selected = false;
1498 NotifySelectedChanged (null);
1501 internal void NotifySelectedChanged (ToolStripItem tsi)
1503 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1505 if (tsi2 is ToolStripDropDownItem)
1506 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1508 if (this.OverflowButton != null) {
1509 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1511 foreach (ToolStripItem tsi2 in tsic)
1513 if (tsi2 is ToolStripDropDownItem)
1514 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1516 this.OverflowButton.HideDropDown ();
1519 foreach (ToolStripItem tsi2 in this.Items)
1521 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1524 internal virtual bool OnMenuKey ()
1529 internal virtual bool ProcessArrowKey (Keys keyData)
1535 tsi = this.GetCurrentlySelectedItem ();
1537 if (tsi is ToolStripControlHost)
1540 tsi = this.SelectNextToolStripItem (tsi, true);
1542 if (tsi is ToolStripControlHost)
1543 (tsi as ToolStripControlHost).Focus ();
1547 tsi = this.GetCurrentlySelectedItem ();
1549 tsi = this.SelectNextToolStripItem (tsi, true);
1551 if (tsi is ToolStripControlHost)
1552 (tsi as ToolStripControlHost).Focus ();
1556 tsi = this.GetCurrentlySelectedItem ();
1558 if (tsi is ToolStripControlHost)
1561 tsi = this.SelectNextToolStripItem (tsi, false);
1563 if (tsi is ToolStripControlHost)
1564 (tsi as ToolStripControlHost).Focus ();
1567 case Keys.Shift | Keys.Tab:
1568 tsi = this.GetCurrentlySelectedItem ();
1570 tsi = this.SelectNextToolStripItem (tsi, false);
1572 if (tsi is ToolStripControlHost)
1573 (tsi as ToolStripControlHost).Focus ();
1581 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1583 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1585 if (next_item == null)
1588 this.ChangeSelection (next_item);
1590 if (next_item is ToolStripControlHost)
1591 (next_item as ToolStripControlHost).Focus ();
1596 #region Stuff for ToolTips
1597 private void MouseEnteredItem (ToolStripItem item)
1599 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1600 tooltip_currently_showing = item;
1601 ToolTipTimer.Start ();
1605 private void MouseLeftItem (ToolStripItem item)
1607 ToolTipTimer.Stop ();
1608 ToolTipWindow.Hide (this);
1609 tooltip_currently_showing = null;
1612 private Timer ToolTipTimer {
1614 if (tooltip_timer == null) {
1615 tooltip_timer = new Timer ();
1616 tooltip_timer.Enabled = false;
1617 tooltip_timer.Interval = 500;
1618 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1621 return tooltip_timer;
1625 private ToolTip ToolTipWindow {
1627 if (tooltip_window == null)
1628 tooltip_window = new ToolTip ();
1630 return tooltip_window;
1634 private void ToolTipTimer_Tick (object o, EventArgs args)
1636 string tooltip = tooltip_currently_showing.GetToolTip ();
1638 if (!string.IsNullOrEmpty (tooltip))
1639 ToolTipWindow.Present (this, tooltip);
1641 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1643 ToolTipTimer.Stop ();
1647 #region Stuff for Merging
1648 internal ToolStrip CurrentlyMergedWith {
1649 get { return this.currently_merged_with; }
1650 set { this.currently_merged_with = value; }
1653 internal List<ToolStripItem> HiddenMergedItems {
1655 if (this.hidden_merged_items == null)
1656 this.hidden_merged_items = new List<ToolStripItem> ();
1658 return this.hidden_merged_items;
1662 internal bool IsCurrentlyMerged {
1663 get { return this.is_currently_merged; }
1665 this.is_currently_merged = value;
1667 if (!value && this is MenuStrip)
1668 foreach (ToolStripMenuItem tsmi in this.Items)
1669 tsmi.DropDown.IsCurrentlyMerged = value;
1673 internal void BeginMerge ()
1675 if (!IsCurrentlyMerged) {
1676 IsCurrentlyMerged = true;
1678 if (this.pre_merge_items == null) {
1679 this.pre_merge_items = new List<ToolStripItem> ();
1681 foreach (ToolStripItem tsi in this.Items)
1682 this.pre_merge_items.Add (tsi);
1687 internal void RevertMergeItem (ToolStripItem item)
1691 // Remove it from it's current Parent
1692 if (item.Parent != null && item.Parent != this) {
1693 if (item.Parent is ToolStripOverflow)
1694 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1696 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1698 item.Parent = item.Owner;
1701 // Find where the item was before the merge
1702 index = item.Owner.pre_merge_items.IndexOf (item);
1704 // Find the first pre-merge item that was after this item, that
1705 // is currently in the Items collection. Insert our item before
1707 for (int i = index; i < this.pre_merge_items.Count; i++) {
1708 if (this.Items.Contains (this.pre_merge_items[i])) {
1709 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1714 // There aren't any items that are supposed to be after this item,
1715 // so just append it to the end.
1716 item.Owner.Items.AddNoOwnerOrLayout (item);
1721 #region ToolStripAccessibleObject
1723 public class ToolStripAccessibleObject : ControlAccessibleObject
1725 #region Public Constructor
1726 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1731 #region Public Properties
1732 public override AccessibleRole Role {
1733 get { return AccessibleRole.ToolBar; }
1737 #region Public Methods
1738 public override AccessibleObject GetChild (int index)
1740 return base.GetChild (index);
1743 public override int GetChildCount ()
1745 return (owner as ToolStrip).Items.Count;
1748 public override AccessibleObject HitTest (int x, int y)
1750 return base.HitTest (x, y);