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)
30 using System.Runtime.InteropServices;
31 using System.ComponentModel;
33 using System.Windows.Forms.Layout;
34 using System.Collections.Generic;
35 using System.ComponentModel.Design.Serialization;
37 namespace System.Windows.Forms
40 [ClassInterface (ClassInterfaceType.AutoDispatch)]
41 [DefaultEvent ("ItemClicked")]
42 [DefaultProperty ("Items")]
43 [Designer ("System.Windows.Forms.Design.ToolStripDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 [DesignerSerializer ("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
45 public class ToolStrip : ScrollableControl, IComponent, IDisposable, IToolStripData
47 #region Private Variables
48 private bool allow_item_reorder;
49 private bool allow_merge;
50 private Color back_color;
51 private bool can_overflow;
52 private ToolStrip currently_merged_with;
53 private ToolStripDropDownDirection default_drop_down_direction;
54 internal ToolStripItemCollection displayed_items;
55 private Color fore_color;
56 private Padding grip_margin;
57 private ToolStripGripStyle grip_style;
58 private List<ToolStripItem> hidden_merged_items;
59 private ImageList image_list;
60 private Size image_scaling_size;
61 private bool is_currently_merged;
62 private ToolStripItemCollection items;
63 private bool keyboard_active;
64 private LayoutEngine layout_engine;
65 private LayoutSettings layout_settings;
66 private ToolStripLayoutStyle layout_style;
67 private Orientation orientation;
68 private ToolStripOverflowButton overflow_button;
69 private List<ToolStripItem> pre_merge_items;
70 private ToolStripRenderer renderer;
71 private ToolStripRenderMode render_mode;
72 private ToolStripTextDirection text_direction;
73 private Timer tooltip_timer;
74 private ToolTip tooltip_window;
75 private bool show_item_tool_tips;
78 private ToolStripItem mouse_currently_over;
79 internal bool menu_selected;
80 private ToolStripItem tooltip_currently_showing;
81 private ToolTip.TipState tooltip_state;
83 const int InitialToolTipDelay = 500;
84 const int ToolTipDelay = 5000;
87 #region Public Constructors
88 public ToolStrip () : this (null)
92 public ToolStrip (params ToolStripItem[] items) : base ()
94 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
95 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
96 SetStyle (ControlStyles.Selectable, false);
97 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
99 this.SuspendLayout ();
101 this.items = new ToolStripItemCollection (this, items, true);
102 this.allow_merge = true;
103 base.AutoSize = true;
104 this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
105 this.back_color = Control.DefaultBackColor;
106 this.can_overflow = true;
107 base.CausesValidation = false;
108 this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
109 this.displayed_items = new ToolStripItemCollection (this, null, true);
110 this.Dock = this.DefaultDock;
111 base.Font = new Font ("Tahoma", 8.25f);
112 this.fore_color = Control.DefaultForeColor;
113 this.grip_margin = this.DefaultGripMargin;
114 this.grip_style = ToolStripGripStyle.Visible;
115 this.image_scaling_size = new Size (16, 16);
116 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
117 this.orientation = Orientation.Horizontal;
118 if (!(this is ToolStripDropDown))
119 this.overflow_button = new ToolStripOverflowButton (this);
120 this.renderer = null;
121 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
122 this.show_item_tool_tips = this.DefaultShowItemToolTips;
123 base.TabStop = false;
124 this.text_direction = ToolStripTextDirection.Horizontal;
125 this.ResumeLayout ();
127 // Register with the ToolStripManager
128 ToolStripManager.AddToolStrip (this);
132 #region Public Properties
133 [MonoTODO ("Stub, does nothing")]
134 public override bool AllowDrop {
135 get { return base.AllowDrop; }
136 set { base.AllowDrop = value; }
139 [MonoTODO ("Stub, does nothing")]
140 [DefaultValue (false)]
141 public bool AllowItemReorder {
142 get { return this.allow_item_reorder; }
143 set { this.allow_item_reorder = value; }
146 [DefaultValue (true)]
147 public bool AllowMerge {
148 get { return this.allow_merge; }
149 set { this.allow_merge = value; }
152 public override AnchorStyles Anchor {
153 get { return base.Anchor; }
154 set { base.Anchor = value; }
158 [EditorBrowsable (EditorBrowsableState.Never)]
159 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
160 public override bool AutoScroll {
161 get { return base.AutoScroll; }
162 set { base.AutoScroll = value; }
166 [EditorBrowsable (EditorBrowsableState.Never)]
167 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
168 public new Size AutoScrollMargin {
169 get { return base.AutoScrollMargin; }
170 set { base.AutoScrollMargin = value; }
174 [EditorBrowsable (EditorBrowsableState.Never)]
175 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
176 public new Size AutoScrollMinSize {
177 get { return base.AutoScrollMinSize; }
178 set { base.AutoScrollMinSize = value; }
182 [EditorBrowsable (EditorBrowsableState.Never)]
183 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
184 public new Point AutoScrollPosition {
185 get { return base.AutoScrollPosition; }
186 set { base.AutoScrollPosition = value; }
189 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
191 [EditorBrowsable (EditorBrowsableState.Always)]
192 [DefaultValue (true)]
193 public override bool AutoSize {
194 get { return base.AutoSize; }
195 set { base.AutoSize = value; }
198 new public Color BackColor {
199 get { return this.back_color; }
200 set { this.back_color = value; }
203 public override BindingContext BindingContext {
204 get { return base.BindingContext; }
205 set { base.BindingContext = value; }
208 [DefaultValue (true)]
209 public bool CanOverflow {
210 get { return this.can_overflow; }
211 set { this.can_overflow = value; }
215 [DefaultValue (false)]
216 public new bool CausesValidation {
217 get { return base.CausesValidation; }
218 set { base.CausesValidation = value; }
221 [EditorBrowsable (EditorBrowsableState.Never)]
222 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
223 public new ControlCollection Controls {
224 get { return base.Controls; }
228 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
229 public override Cursor Cursor {
230 get { return base.Cursor; }
231 set { base.Cursor = value; }
235 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
236 get { return this.default_drop_down_direction; }
238 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
239 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
241 this.default_drop_down_direction = value;
245 public override Rectangle DisplayRectangle {
247 if (this.orientation == Orientation.Horizontal)
248 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
249 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
251 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);
253 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
254 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
256 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);
260 [DefaultValue (DockStyle.Top)]
261 public override DockStyle Dock {
262 get { return base.Dock; }
264 if (base.Dock != value) {
269 case DockStyle.Bottom:
271 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
274 case DockStyle.Right:
275 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
282 public override Font Font {
283 get { return base.Font; }
285 if (base.Font != value) {
288 foreach (ToolStripItem tsi in this.Items)
289 tsi.OnOwnerFontChanged (EventArgs.Empty);
295 public new Color ForeColor {
296 get { return this.fore_color; }
298 if (this.fore_color != value) {
299 this.fore_color = value;
300 this.OnForeColorChanged (EventArgs.Empty);
306 public ToolStripGripDisplayStyle GripDisplayStyle {
307 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
310 public Padding GripMargin {
311 get { return this.grip_margin; }
313 if (this.grip_margin != value) {
314 this.grip_margin = value;
315 this.PerformLayout ();
321 public Rectangle GripRectangle {
323 if (this.grip_style == ToolStripGripStyle.Hidden)
324 return Rectangle.Empty;
326 if (this.orientation == Orientation.Horizontal)
327 return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
329 return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
333 [DefaultValue (ToolStripGripStyle.Visible)]
334 public ToolStripGripStyle GripStyle {
335 get { return this.grip_style; }
337 if (this.grip_style != value) {
338 if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
339 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
340 this.grip_style = value;
341 this.PerformLayout (this, "GripStyle");
347 [EditorBrowsable (EditorBrowsableState.Never)]
348 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
349 public new bool HasChildren {
350 get { return base.HasChildren; }
354 [EditorBrowsable (EditorBrowsableState.Never)]
355 public new HScrollProperties HorizontalScroll {
356 get { return base.HorizontalScroll; }
360 [DefaultValue (null)]
361 public ImageList ImageList {
362 get { return this.image_list; }
363 set { this.image_list = value; }
366 [DefaultValue ("{Width=16, Height=16}")]
367 public Size ImageScalingSize {
368 get { return this.image_scaling_size; }
369 set { this.image_scaling_size = value; }
372 [MonoTODO ("Always returns false, dragging not implemented yet.")]
374 [EditorBrowsable (EditorBrowsableState.Advanced)]
375 public bool IsCurrentlyDragging {
376 get { return false; }
380 public bool IsDropDown {
382 if (this is ToolStripDropDown)
389 [MergableProperty (false)]
390 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
391 public virtual ToolStripItemCollection Items {
392 get { return this.items; }
395 public override LayoutEngine LayoutEngine {
397 if (layout_engine == null)
398 this.layout_engine = new ToolStripSplitStackLayout ();
400 return this.layout_engine;
405 [DefaultValue (null)]
406 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
407 public LayoutSettings LayoutSettings {
408 get { return this.layout_settings; }
410 if (this.layout_settings != value) {
411 this.layout_settings = value;
412 PerformLayout (this, "LayoutSettings");
417 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
418 public ToolStripLayoutStyle LayoutStyle {
419 get { return layout_style; }
421 if (this.layout_style != value) {
422 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
423 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
425 this.layout_style = value;
427 if (this.layout_style == ToolStripLayoutStyle.Flow)
428 this.layout_engine = new FlowLayout ();
430 this.layout_engine = new ToolStripSplitStackLayout ();
432 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
433 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
434 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
436 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
439 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
440 this.orientation = Orientation.Horizontal;
441 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
442 this.orientation = Orientation.Vertical;
444 this.layout_settings = this.CreateLayoutSettings (value);
446 this.PerformLayout (this, "LayoutStyle");
447 this.OnLayoutStyleChanged (EventArgs.Empty);
453 public Orientation Orientation {
454 get { return this.orientation; }
458 [EditorBrowsable (EditorBrowsableState.Advanced)]
459 public ToolStripOverflowButton OverflowButton {
460 get { return this.overflow_button; }
464 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
465 public ToolStripRenderer Renderer {
467 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
468 return ToolStripManager.Renderer;
470 return this.renderer;
473 if (this.renderer != value) {
474 this.renderer = value;
475 this.render_mode = ToolStripRenderMode.Custom;
476 this.PerformLayout (this, "Renderer");
477 this.OnRendererChanged (EventArgs.Empty);
482 public ToolStripRenderMode RenderMode {
483 get { return this.render_mode; }
485 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
486 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
488 if (value == ToolStripRenderMode.Custom && this.renderer == null)
489 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
490 else if (value == ToolStripRenderMode.Professional)
491 this.Renderer = new ToolStripProfessionalRenderer ();
492 else if (value == ToolStripRenderMode.System)
493 this.Renderer = new ToolStripSystemRenderer ();
495 this.render_mode = value;
499 [DefaultValue (true)]
500 public bool ShowItemToolTips {
501 get { return this.show_item_tool_tips; }
502 set { this.show_item_tool_tips = value; }
505 [DefaultValue (false)]
506 public bool Stretch {
507 get { return this.stretch; }
508 set { this.stretch = value; }
511 [DefaultValue (false)]
513 public new bool TabStop {
514 get { return base.TabStop; }
516 base.TabStop = value;
517 SetStyle (ControlStyles.Selectable, value);
521 [DefaultValue (ToolStripTextDirection.Horizontal)]
522 public virtual ToolStripTextDirection TextDirection {
523 get { return this.text_direction; }
525 if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
526 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
528 if (this.text_direction != value) {
529 this.text_direction = value;
531 this.PerformLayout (this, "TextDirection");
539 [EditorBrowsable (EditorBrowsableState.Never)]
540 public new VScrollProperties VerticalScroll {
541 get { return base.VerticalScroll; }
545 #region Protected Properties
546 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
547 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
548 protected override Padding DefaultMargin { get { return Padding.Empty; } }
549 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
550 protected virtual bool DefaultShowItemToolTips { get { return true; } }
551 protected override Size DefaultSize { get { return new Size (100, 25); } }
552 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
553 protected internal virtual Size MaxItemSize {
554 get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); }
558 #region Public Methods
559 [EditorBrowsable (EditorBrowsableState.Never)]
560 public new Control GetChildAtPoint (Point point)
562 return base.GetChildAtPoint (point);
565 [EditorBrowsable (EditorBrowsableState.Never)]
566 public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
568 return base.GetChildAtPoint (pt, skipValue);
571 public ToolStripItem GetItemAt (Point point)
573 foreach (ToolStripItem tsi in this.displayed_items)
574 if (tsi.Visible && tsi.Bounds.Contains (point))
580 public ToolStripItem GetItemAt (int x, int y)
582 return GetItemAt (new Point (x, y));
585 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
587 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
588 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
590 ToolStripItem current_best = null;
591 int current_best_point;
594 case ArrowDirection.Right:
595 current_best_point = int.MaxValue;
598 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
599 if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
600 current_best = loop_tsi;
601 current_best_point = loop_tsi.Left;
604 if (current_best == null)
605 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
606 if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
607 current_best = loop_tsi;
608 current_best_point = loop_tsi.Left;
612 case ArrowDirection.Up:
613 current_best_point = int.MinValue;
616 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
617 if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
618 current_best = loop_tsi;
619 current_best_point = loop_tsi.Top;
622 if (current_best == null)
623 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
624 if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
625 current_best = loop_tsi;
626 current_best_point = loop_tsi.Top;
630 case ArrowDirection.Left:
631 current_best_point = int.MinValue;
634 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
635 if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
636 current_best = loop_tsi;
637 current_best_point = loop_tsi.Left;
640 if (current_best == null)
641 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
642 if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
643 current_best = loop_tsi;
644 current_best_point = loop_tsi.Left;
648 case ArrowDirection.Down:
649 current_best_point = int.MaxValue;
652 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
653 if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
654 current_best = loop_tsi;
655 current_best_point = loop_tsi.Top;
658 if (current_best == null)
659 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
660 if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
661 current_best = loop_tsi;
662 current_best_point = loop_tsi.Top;
671 [EditorBrowsable (EditorBrowsableState.Never)]
672 public void ResetMinimumSize ()
674 this.MinimumSize = new Size (-1, -1);
677 [EditorBrowsable (EditorBrowsableState.Never)]
678 public new void SetAutoScrollMargin (int x, int y)
680 base.SetAutoScrollMargin (x, y);
683 public override string ToString ()
685 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
689 #region Protected Methods
690 protected override AccessibleObject CreateAccessibilityInstance ()
692 return new ToolStripAccessibleObject (this);
695 protected override ControlCollection CreateControlsInstance ()
697 return base.CreateControlsInstance ();
700 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
703 return new ToolStripSeparator ();
705 if (this is ToolStripDropDown)
706 return new ToolStripMenuItem (text, image, onClick);
708 return new ToolStripButton (text, image, onClick);
711 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
713 switch (layoutStyle) {
714 case ToolStripLayoutStyle.Flow:
715 return new FlowLayoutSettings (this);
716 case ToolStripLayoutStyle.Table:
717 //return new TableLayoutSettings ();
718 case ToolStripLayoutStyle.StackWithOverflow:
719 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
720 case ToolStripLayoutStyle.VerticalStackWithOverflow:
726 protected override void Dispose (bool disposing)
731 // Event Handler must be stopped before disposing Items.
735 // ToolStripItem.Dispose modifes the collection,
736 // so we iterate it in reverse order
737 for (int i = Items.Count - 1; i >= 0; i--)
738 Items [i].Dispose ();
740 if (this.overflow_button != null && this.overflow_button.drop_down != null)
741 this.overflow_button.drop_down.Dispose ();
743 ToolStripManager.RemoveToolStrip (this);
745 base.Dispose (disposing);
749 [MonoTODO ("Stub, never called")]
750 protected virtual void OnBeginDrag (EventArgs e)
752 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
757 protected override void OnDockChanged (EventArgs e)
759 base.OnDockChanged (e);
762 [MonoTODO ("Stub, never called")]
763 protected virtual void OnEndDrag (EventArgs e)
765 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
770 protected override bool IsInputChar (char charCode)
772 return base.IsInputChar (charCode);
775 protected override bool IsInputKey (Keys keyData)
777 return base.IsInputKey (keyData);
780 protected override void OnEnabledChanged (EventArgs e)
782 base.OnEnabledChanged (e);
784 foreach (ToolStripItem tsi in this.Items)
785 tsi.OnParentEnabledChanged (EventArgs.Empty);
788 protected override void OnFontChanged (EventArgs e)
790 base.OnFontChanged (e);
793 protected override void OnHandleCreated (EventArgs e)
795 base.OnHandleCreated (e);
798 protected override void OnHandleDestroyed (EventArgs e)
800 base.OnHandleDestroyed (e);
803 protected override void OnInvalidated (InvalidateEventArgs e)
805 base.OnInvalidated (e);
808 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
810 if (e.Item.InternalVisible)
811 e.Item.Available = true;
813 e.Item.SetPlacement (ToolStripItemPlacement.Main);
816 this.PerformLayout ();
818 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
823 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
825 if (this.KeyboardActive)
826 ToolStripManager.SetActiveToolStrip (null, false);
828 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
833 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
835 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
840 protected override void OnLayout (LayoutEventArgs e)
844 this.SetDisplayedItems ();
845 this.OnLayoutCompleted (EventArgs.Empty);
849 protected virtual void OnLayoutCompleted (EventArgs e)
851 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
856 protected virtual void OnLayoutStyleChanged (EventArgs e)
858 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
863 protected override void OnLeave (EventArgs e)
868 protected override void OnLostFocus (EventArgs e)
870 base.OnLostFocus (e);
873 protected override void OnMouseCaptureChanged (EventArgs e)
875 base.OnMouseCaptureChanged (e);
878 protected override void OnMouseDown (MouseEventArgs mea)
880 if (mouse_currently_over != null)
882 ToolStripItem focused = GetCurrentlyFocusedItem ();
884 if (focused != null && focused != mouse_currently_over)
885 this.FocusInternal (true);
887 if (this is MenuStrip && !menu_selected) {
888 (this as MenuStrip).FireMenuActivate ();
889 menu_selected = true;
892 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
894 if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems)
897 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
900 if (this is MenuStrip)
901 this.Capture = false;
903 base.OnMouseDown (mea);
906 protected override void OnMouseLeave (EventArgs e)
908 if (mouse_currently_over != null) {
909 MouseLeftItem (mouse_currently_over);
910 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
911 mouse_currently_over = null;
914 base.OnMouseLeave (e);
917 protected override void OnMouseMove (MouseEventArgs mea)
920 // Find the item we are now
921 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
922 tsi = this.overflow_button;
924 tsi = this.GetItemAt (mea.X, mea.Y);
927 // If we were already hovering on this item, just send a mouse move
928 if (tsi == mouse_currently_over)
929 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
931 // If we were over a different item, fire a mouse leave on it
932 if (mouse_currently_over != null) {
934 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
937 // Set the new item we are currently over
938 mouse_currently_over = tsi;
940 // Fire mouse enter and mouse move
941 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
942 MouseEnteredItem (tsi);
943 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
945 // If we're over something with a drop down, show it
946 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
947 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
950 // We're not over anything now, just fire the mouse leave on what we used to be over
951 if (mouse_currently_over != null) {
953 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
954 mouse_currently_over = null;
958 base.OnMouseMove (mea);
961 protected override void OnMouseUp (MouseEventArgs mea)
963 // If we're currently over an item (set in MouseMove)
964 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
965 // Fire our ItemClicked event, but only for a left mouse click.
966 if (mea.Button == MouseButtons.Left)
967 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
969 // Fire the item's MouseUp event
970 if (mouse_currently_over != null)
971 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
973 // The event handler may have blocked until the mouse moved off of the ToolStripItem
974 if (mouse_currently_over == null)
978 base.OnMouseUp (mea);
981 protected override void OnPaint (PaintEventArgs e)
986 this.OnPaintGrip (e);
988 // Make each item draw itself
989 for (int i = 0; i < displayed_items.Count; i++) {
990 ToolStripItem tsi = displayed_items[i];
993 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
994 tsi.FireEvent (e, ToolStripItemEventType.Paint);
995 e.Graphics.ResetTransform ();
999 // Paint the Overflow button if it's visible
1000 if (this.overflow_button != null && this.overflow_button.Visible) {
1001 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
1002 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
1003 e.Graphics.ResetTransform ();
1006 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1008 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
1009 pevent.InternalConnectedArea = CalculateConnectedArea ();
1011 this.Renderer.DrawToolStripBorder (pevent);
1014 [EditorBrowsable (EditorBrowsableState.Advanced)]
1015 protected override void OnPaintBackground (PaintEventArgs e)
1017 base.OnPaintBackground (e);
1019 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1020 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1022 this.Renderer.DrawToolStripBackground (tsrea);
1025 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1027 // Never draw a grip with these two layouts
1028 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1031 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1035 if (!(this is MenuStrip)) {
1036 if (this.orientation == Orientation.Horizontal)
1037 e.Graphics.TranslateTransform (2, 0);
1039 e.Graphics.TranslateTransform (0, 2);
1042 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1043 e.Graphics.ResetTransform ();
1046 protected virtual void OnRendererChanged (EventArgs e)
1048 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1053 [EditorBrowsable (EditorBrowsableState.Advanced)]
1054 protected override void OnRightToLeftChanged (EventArgs e)
1056 base.OnRightToLeftChanged (e);
1058 foreach (ToolStripItem tsi in this.Items)
1059 tsi.OnParentRightToLeftChanged (e);
1062 protected override void OnScroll (ScrollEventArgs se)
1067 protected override void OnTabStopChanged (EventArgs e)
1069 base.OnTabStopChanged (e);
1072 protected override void OnVisibleChanged (EventArgs e)
1075 CloseToolTip (null);
1077 base.OnVisibleChanged (e);
1080 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1082 return base.ProcessCmdKey (ref m, keyData);
1085 protected override bool ProcessDialogKey (Keys keyData)
1087 if (!this.KeyboardActive)
1090 // Give each item a chance to handle the key
1091 foreach (ToolStripItem tsi in this.Items)
1092 if (tsi.ProcessDialogKey (keyData))
1095 // See if I want to handle it
1096 if (this.ProcessArrowKey (keyData))
1099 ToolStrip ts = null;
1103 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1106 case Keys.Control | Keys.Tab:
1107 ts = ToolStripManager.GetNextToolStrip (this, true);
1110 foreach (ToolStripItem tsi in this.Items)
1111 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1113 ToolStripManager.SetActiveToolStrip (ts, true);
1114 ts.SelectNextToolStripItem (null, true);
1118 case Keys.Control | Keys.Shift | Keys.Tab:
1119 ts = ToolStripManager.GetNextToolStrip (this, false);
1122 foreach (ToolStripItem tsi in this.Items)
1123 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1125 ToolStripManager.SetActiveToolStrip (ts, true);
1126 ts.SelectNextToolStripItem (null, true);
1134 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1139 return base.ProcessDialogKey (keyData);
1142 protected override bool ProcessMnemonic (char charCode)
1144 // If any item has an explicit mnemonic, it gets the message
1145 foreach (ToolStripItem tsi in this.Items)
1146 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1147 return tsi.ProcessMnemonic (charCode);
1149 // Do not try to match any further here. See Xamarin bug 23532.
1151 return base.ProcessMnemonic (charCode);
1154 [MonoTODO ("Stub, does nothing")]
1155 [EditorBrowsable (EditorBrowsableState.Advanced)]
1156 protected virtual void RestoreFocus ()
1160 protected override void Select (bool directed, bool forward)
1162 foreach (ToolStripItem tsi in this.DisplayedItems)
1163 if (tsi.CanSelect) {
1169 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1171 base.SetBoundsCore (x, y, width, height, specified);
1174 protected virtual void SetDisplayedItems ()
1176 this.displayed_items.ClearInternal ();
1178 foreach (ToolStripItem tsi in this.items)
1179 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1180 this.displayed_items.AddNoOwnerOrLayout (tsi);
1183 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1184 tsi.Parent = this.OverflowButton.DropDown;
1186 if (this.OverflowButton != null)
1187 this.OverflowButton.DropDown.SetDisplayedItems ();
1190 protected internal void SetItemLocation (ToolStripItem item, Point location)
1193 throw new ArgumentNullException ("item");
1195 if (item.Owner != this)
1196 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1198 item.SetBounds (new Rectangle (location, item.Size));
1201 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1203 if (item.Owner != null) {
1204 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1206 if (item.Owner is ToolStripOverflow)
1207 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1210 parent.Items.AddNoOwnerOrLayout (item);
1211 item.Parent = parent;
1214 protected override void SetVisibleCore (bool visible)
1216 base.SetVisibleCore (visible);
1219 protected override void WndProc (ref Message m)
1221 base.WndProc (ref m);
1225 #region Public Events
1226 static object BeginDragEvent = new object ();
1227 static object EndDragEvent = new object ();
1228 static object ItemAddedEvent = new object ();
1229 static object ItemClickedEvent = new object ();
1230 static object ItemRemovedEvent = new object ();
1231 static object LayoutCompletedEvent = new object ();
1232 static object LayoutStyleChangedEvent = new object ();
1233 static object PaintGripEvent = new object ();
1234 static object RendererChangedEvent = new object ();
1237 [EditorBrowsable (EditorBrowsableState.Always)]
1238 public new event EventHandler AutoSizeChanged {
1239 add { base.AutoSizeChanged += value; }
1240 remove { base.AutoSizeChanged -= value; }
1243 [MonoTODO ("Event never raised")]
1244 public event EventHandler BeginDrag {
1245 add { Events.AddHandler (BeginDragEvent, value); }
1246 remove { Events.RemoveHandler (BeginDragEvent, value); }
1250 public new event EventHandler CausesValidationChanged {
1251 add { base.CausesValidationChanged += value; }
1252 remove { base.CausesValidationChanged -= value; }
1256 [EditorBrowsable (EditorBrowsableState.Never)]
1257 public new event ControlEventHandler ControlAdded {
1258 add { base.ControlAdded += value; }
1259 remove { base.ControlAdded -= value; }
1263 [EditorBrowsable (EditorBrowsableState.Never)]
1264 public new event ControlEventHandler ControlRemoved {
1265 add { base.ControlRemoved += value; }
1266 remove { base.ControlRemoved -= value; }
1270 public new event EventHandler CursorChanged {
1271 add { base.CursorChanged += value; }
1272 remove { base.CursorChanged -= value; }
1275 [MonoTODO ("Event never raised")]
1276 public event EventHandler EndDrag {
1277 add { Events.AddHandler (EndDragEvent, value); }
1278 remove { Events.RemoveHandler (EndDragEvent, value); }
1282 public new event EventHandler ForeColorChanged {
1283 add { base.ForeColorChanged += value; }
1284 remove { base.ForeColorChanged -= value; }
1287 public event ToolStripItemEventHandler ItemAdded {
1288 add { Events.AddHandler (ItemAddedEvent, value); }
1289 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1292 public event ToolStripItemClickedEventHandler ItemClicked {
1293 add { Events.AddHandler (ItemClickedEvent, value); }
1294 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1297 public event ToolStripItemEventHandler ItemRemoved {
1298 add { Events.AddHandler (ItemRemovedEvent, value); }
1299 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1302 public event EventHandler LayoutCompleted {
1303 add { Events.AddHandler (LayoutCompletedEvent, value); }
1304 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1307 public event EventHandler LayoutStyleChanged {
1308 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1309 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1312 public event PaintEventHandler PaintGrip {
1313 add { Events.AddHandler (PaintGripEvent, value); }
1314 remove { Events.RemoveHandler (PaintGripEvent, value); }
1317 public event EventHandler RendererChanged {
1318 add { Events.AddHandler (RendererChangedEvent, value); }
1319 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1323 #region Internal Properties
1324 internal virtual bool KeyboardActive
1326 get { return this.keyboard_active; }
1328 if (this.keyboard_active != value) {
1329 this.keyboard_active = value;
1332 Application.KeyboardCapture = this;
1333 else if (Application.KeyboardCapture == this) {
1334 Application.KeyboardCapture = null;
1335 ToolStripManager.ActivatedByKeyboard = false;
1338 // Redraw for mnemonic underlines
1345 #region Private Methods
1346 internal virtual Rectangle CalculateConnectedArea ()
1348 return Rectangle.Empty;
1351 internal void ChangeSelection (ToolStripItem nextItem)
1353 if (Application.KeyboardCapture != this)
1354 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1356 foreach (ToolStripItem tsi in this.Items)
1357 if (tsi != nextItem)
1358 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1360 ToolStripItem current = GetCurrentlySelectedItem ();
1362 if (current != null && !(current is ToolStripControlHost))
1363 this.FocusInternal (true);
1365 if (nextItem is ToolStripControlHost)
1366 (nextItem as ToolStripControlHost).Focus ();
1370 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1371 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1374 internal virtual void Dismiss ()
1376 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1379 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1381 // Release our stranglehold on the keyboard
1382 this.KeyboardActive = false;
1384 // Set our drop down flag to false;
1385 this.menu_selected = false;
1387 // Make sure all of our items are deselected and repainted
1388 foreach (ToolStripItem tsi in this.Items)
1389 tsi.Dismiss (reason);
1391 // We probably need to redraw for mnemonic underlines
1395 internal ToolStripItem GetCurrentlySelectedItem ()
1397 foreach (ToolStripItem tsi in this.DisplayedItems)
1404 internal ToolStripItem GetCurrentlyFocusedItem ()
1406 foreach (ToolStripItem tsi in this.DisplayedItems)
1407 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1413 internal override Size GetPreferredSizeCore (Size proposedSize)
1415 return GetToolStripPreferredSize (proposedSize);
1418 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1420 Size new_size = Size.Empty;
1422 // TODO: This is total duct tape. We really have to call into the correct
1423 // layout engine, do a dry run of the layout, and find out our true
1424 // preferred dimensions.
1425 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1426 Point currentLocation = Point.Empty;
1429 foreach (ToolStripItem tsi in items)
1430 if (tsi.Available) {
1431 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1433 if ((DisplayRectangle.Width - currentLocation.X) < (tsi_preferred.Width + tsi.Margin.Horizontal)) {
1435 currentLocation.Y += tallest;
1438 currentLocation.X = DisplayRectangle.Left;
1441 // Offset the left margin and set the control to our point
1442 currentLocation.Offset (tsi.Margin.Left, 0);
1443 tallest = Math.Max (tallest, tsi_preferred.Height + tsi.Margin.Vertical);
1445 // Update our location pointer
1446 currentLocation.X += tsi_preferred.Width + tsi.Margin.Right;
1449 currentLocation.Y += tallest;
1450 return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical);
1453 if (this.orientation == Orientation.Vertical) {
1454 foreach (ToolStripItem tsi in this.items)
1455 if (tsi.Available) {
1456 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1457 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1459 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1460 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1463 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1465 if (new_size.Width == 0)
1466 new_size.Width = ExplicitBounds.Width;
1470 foreach (ToolStripItem tsi in this.items)
1471 if (tsi.Available) {
1472 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1473 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1475 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1476 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1479 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1481 if (new_size.Height == 0)
1482 new_size.Height = ExplicitBounds.Height;
1484 if (this is StatusStrip)
1485 new_size.Height = Math.Max (new_size.Height, 22);
1491 internal virtual ToolStrip GetTopLevelToolStrip ()
1496 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1498 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
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 ToolTipTimer.Interval = InitialToolTipDelay;
1601 tooltip_state = ToolTip.TipState.Initial;
1602 tooltip_currently_showing = item;
1603 ToolTipTimer.Start ();
1607 private void CloseToolTip (ToolStripItem item)
1609 ToolTipTimer.Stop ();
1610 ToolTipWindow.Hide (this);
1611 tooltip_currently_showing = null;
1612 tooltip_state = ToolTip.TipState.Down;
1615 private void MouseLeftItem (ToolStripItem item)
1617 CloseToolTip (item);
1620 private Timer ToolTipTimer {
1622 if (tooltip_timer == null) {
1623 tooltip_timer = new Timer ();
1624 tooltip_timer.Enabled = false;
1625 tooltip_timer.Interval = InitialToolTipDelay;
1626 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1629 return tooltip_timer;
1633 private ToolTip ToolTipWindow {
1635 if (tooltip_window == null)
1636 tooltip_window = new ToolTip ();
1638 return tooltip_window;
1642 private void ShowToolTip ()
1644 string tooltip = tooltip_currently_showing.GetToolTip ();
1646 if (!string.IsNullOrEmpty (tooltip)) {
1647 ToolTipWindow.Present (this, tooltip);
1648 ToolTipTimer.Interval = ToolTipDelay;
1649 ToolTipTimer.Start ();
1650 tooltip_state = ToolTip.TipState.Show;
1653 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1656 private void ToolTipTimer_Tick (object o, EventArgs args)
1658 ToolTipTimer.Stop ();
1660 switch (tooltip_state) {
1661 case ToolTip.TipState.Initial:
1664 case ToolTip.TipState.Show:
1665 CloseToolTip (null);
1671 #region Stuff for Merging
1672 internal ToolStrip CurrentlyMergedWith {
1673 get { return this.currently_merged_with; }
1674 set { this.currently_merged_with = value; }
1677 internal List<ToolStripItem> HiddenMergedItems {
1679 if (this.hidden_merged_items == null)
1680 this.hidden_merged_items = new List<ToolStripItem> ();
1682 return this.hidden_merged_items;
1686 internal bool IsCurrentlyMerged {
1687 get { return this.is_currently_merged; }
1689 this.is_currently_merged = value;
1691 if (!value && this is MenuStrip)
1692 foreach (ToolStripMenuItem tsmi in this.Items)
1693 tsmi.DropDown.IsCurrentlyMerged = value;
1697 internal void BeginMerge ()
1699 if (!IsCurrentlyMerged) {
1700 IsCurrentlyMerged = true;
1702 if (this.pre_merge_items == null) {
1703 this.pre_merge_items = new List<ToolStripItem> ();
1705 foreach (ToolStripItem tsi in this.Items)
1706 this.pre_merge_items.Add (tsi);
1711 internal void RevertMergeItem (ToolStripItem item)
1715 // Remove it from it's current Parent
1716 if (item.Parent != null && item.Parent != this) {
1717 if (item.Parent is ToolStripOverflow)
1718 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1720 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1722 item.Parent = item.Owner;
1725 // Find where the item was before the merge
1726 index = item.Owner.pre_merge_items.IndexOf (item);
1728 // Find the first pre-merge item that was after this item, that
1729 // is currently in the Items collection. Insert our item before
1731 for (int i = index; i < this.pre_merge_items.Count; i++) {
1732 if (this.Items.Contains (this.pre_merge_items[i])) {
1733 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1738 // There aren't any items that are supposed to be after this item,
1739 // so just append it to the end.
1740 item.Owner.Items.AddNoOwnerOrLayout (item);
1745 #region ToolStripAccessibleObject
1747 public class ToolStripAccessibleObject : ControlAccessibleObject
1749 #region Public Constructor
1750 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1755 #region Public Properties
1756 public override AccessibleRole Role {
1757 get { return AccessibleRole.ToolBar; }
1761 #region Public Methods
1762 public override AccessibleObject GetChild (int index)
1764 return base.GetChild (index);
1767 public override int GetChildCount ()
1769 return (owner as ToolStrip).Items.Count;
1772 public override AccessibleObject HitTest (int x, int y)
1774 return base.HitTest (x, y);