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
966 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
968 // Fire the item's MouseUp event
969 if (mouse_currently_over != null)
970 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
972 // The event handler may have blocked until the mouse moved off of the ToolStripItem
973 if (mouse_currently_over == null)
977 base.OnMouseUp (mea);
980 protected override void OnPaint (PaintEventArgs e)
985 this.OnPaintGrip (e);
987 // Make each item draw itself
988 for (int i = 0; i < displayed_items.Count; i++) {
989 ToolStripItem tsi = displayed_items[i];
992 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
993 tsi.FireEvent (e, ToolStripItemEventType.Paint);
994 e.Graphics.ResetTransform ();
998 // Paint the Overflow button if it's visible
999 if (this.overflow_button != null && this.overflow_button.Visible) {
1000 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
1001 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
1002 e.Graphics.ResetTransform ();
1005 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1007 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
1008 pevent.InternalConnectedArea = CalculateConnectedArea ();
1010 this.Renderer.DrawToolStripBorder (pevent);
1013 [EditorBrowsable (EditorBrowsableState.Advanced)]
1014 protected override void OnPaintBackground (PaintEventArgs e)
1016 base.OnPaintBackground (e);
1018 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1019 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1021 this.Renderer.DrawToolStripBackground (tsrea);
1024 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1026 // Never draw a grip with these two layouts
1027 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1030 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1034 if (!(this is MenuStrip)) {
1035 if (this.orientation == Orientation.Horizontal)
1036 e.Graphics.TranslateTransform (2, 0);
1038 e.Graphics.TranslateTransform (0, 2);
1041 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1042 e.Graphics.ResetTransform ();
1045 protected virtual void OnRendererChanged (EventArgs e)
1047 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1052 [EditorBrowsable (EditorBrowsableState.Advanced)]
1053 protected override void OnRightToLeftChanged (EventArgs e)
1055 base.OnRightToLeftChanged (e);
1057 foreach (ToolStripItem tsi in this.Items)
1058 tsi.OnParentRightToLeftChanged (e);
1061 protected override void OnScroll (ScrollEventArgs se)
1066 protected override void OnTabStopChanged (EventArgs e)
1068 base.OnTabStopChanged (e);
1071 protected override void OnVisibleChanged (EventArgs e)
1074 CloseToolTip (null);
1076 base.OnVisibleChanged (e);
1079 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1081 return base.ProcessCmdKey (ref m, keyData);
1084 protected override bool ProcessDialogKey (Keys keyData)
1086 if (!this.KeyboardActive)
1089 // Give each item a chance to handle the key
1090 foreach (ToolStripItem tsi in this.Items)
1091 if (tsi.ProcessDialogKey (keyData))
1094 // See if I want to handle it
1095 if (this.ProcessArrowKey (keyData))
1098 ToolStrip ts = null;
1102 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1105 case Keys.Control | Keys.Tab:
1106 ts = ToolStripManager.GetNextToolStrip (this, true);
1109 foreach (ToolStripItem tsi in this.Items)
1110 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1112 ToolStripManager.SetActiveToolStrip (ts, true);
1113 ts.SelectNextToolStripItem (null, true);
1117 case Keys.Control | Keys.Shift | Keys.Tab:
1118 ts = ToolStripManager.GetNextToolStrip (this, false);
1121 foreach (ToolStripItem tsi in this.Items)
1122 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1124 ToolStripManager.SetActiveToolStrip (ts, true);
1125 ts.SelectNextToolStripItem (null, true);
1133 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1138 return base.ProcessDialogKey (keyData);
1141 protected override bool ProcessMnemonic (char charCode)
1143 // If any item has an explicit mnemonic, it gets the message
1144 foreach (ToolStripItem tsi in this.Items)
1145 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1146 return tsi.ProcessMnemonic (charCode);
1148 // Do not try to match any further here. See Xamarin bug 23532.
1150 return base.ProcessMnemonic (charCode);
1153 [MonoTODO ("Stub, does nothing")]
1154 [EditorBrowsable (EditorBrowsableState.Advanced)]
1155 protected virtual void RestoreFocus ()
1159 protected override void Select (bool directed, bool forward)
1161 foreach (ToolStripItem tsi in this.DisplayedItems)
1162 if (tsi.CanSelect) {
1168 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1170 base.SetBoundsCore (x, y, width, height, specified);
1173 protected virtual void SetDisplayedItems ()
1175 this.displayed_items.ClearInternal ();
1177 foreach (ToolStripItem tsi in this.items)
1178 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1179 this.displayed_items.AddNoOwnerOrLayout (tsi);
1182 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1183 tsi.Parent = this.OverflowButton.DropDown;
1185 if (this.OverflowButton != null)
1186 this.OverflowButton.DropDown.SetDisplayedItems ();
1189 protected internal void SetItemLocation (ToolStripItem item, Point location)
1192 throw new ArgumentNullException ("item");
1194 if (item.Owner != this)
1195 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1197 item.SetBounds (new Rectangle (location, item.Size));
1200 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1202 if (item.Owner != null) {
1203 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1205 if (item.Owner is ToolStripOverflow)
1206 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1209 parent.Items.AddNoOwnerOrLayout (item);
1210 item.Parent = parent;
1213 protected override void SetVisibleCore (bool visible)
1215 base.SetVisibleCore (visible);
1218 protected override void WndProc (ref Message m)
1220 base.WndProc (ref m);
1224 #region Public Events
1225 static object BeginDragEvent = new object ();
1226 static object EndDragEvent = new object ();
1227 static object ItemAddedEvent = new object ();
1228 static object ItemClickedEvent = new object ();
1229 static object ItemRemovedEvent = new object ();
1230 static object LayoutCompletedEvent = new object ();
1231 static object LayoutStyleChangedEvent = new object ();
1232 static object PaintGripEvent = new object ();
1233 static object RendererChangedEvent = new object ();
1236 [EditorBrowsable (EditorBrowsableState.Always)]
1237 public new event EventHandler AutoSizeChanged {
1238 add { base.AutoSizeChanged += value; }
1239 remove { base.AutoSizeChanged -= value; }
1242 [MonoTODO ("Event never raised")]
1243 public event EventHandler BeginDrag {
1244 add { Events.AddHandler (BeginDragEvent, value); }
1245 remove { Events.RemoveHandler (BeginDragEvent, value); }
1249 public new event EventHandler CausesValidationChanged {
1250 add { base.CausesValidationChanged += value; }
1251 remove { base.CausesValidationChanged -= value; }
1255 [EditorBrowsable (EditorBrowsableState.Never)]
1256 public new event ControlEventHandler ControlAdded {
1257 add { base.ControlAdded += value; }
1258 remove { base.ControlAdded -= value; }
1262 [EditorBrowsable (EditorBrowsableState.Never)]
1263 public new event ControlEventHandler ControlRemoved {
1264 add { base.ControlRemoved += value; }
1265 remove { base.ControlRemoved -= value; }
1269 public new event EventHandler CursorChanged {
1270 add { base.CursorChanged += value; }
1271 remove { base.CursorChanged -= value; }
1274 [MonoTODO ("Event never raised")]
1275 public event EventHandler EndDrag {
1276 add { Events.AddHandler (EndDragEvent, value); }
1277 remove { Events.RemoveHandler (EndDragEvent, value); }
1281 public new event EventHandler ForeColorChanged {
1282 add { base.ForeColorChanged += value; }
1283 remove { base.ForeColorChanged -= value; }
1286 public event ToolStripItemEventHandler ItemAdded {
1287 add { Events.AddHandler (ItemAddedEvent, value); }
1288 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1291 public event ToolStripItemClickedEventHandler ItemClicked {
1292 add { Events.AddHandler (ItemClickedEvent, value); }
1293 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1296 public event ToolStripItemEventHandler ItemRemoved {
1297 add { Events.AddHandler (ItemRemovedEvent, value); }
1298 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1301 public event EventHandler LayoutCompleted {
1302 add { Events.AddHandler (LayoutCompletedEvent, value); }
1303 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1306 public event EventHandler LayoutStyleChanged {
1307 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1308 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1311 public event PaintEventHandler PaintGrip {
1312 add { Events.AddHandler (PaintGripEvent, value); }
1313 remove { Events.RemoveHandler (PaintGripEvent, value); }
1316 public event EventHandler RendererChanged {
1317 add { Events.AddHandler (RendererChangedEvent, value); }
1318 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1322 #region Internal Properties
1323 internal virtual bool KeyboardActive
1325 get { return this.keyboard_active; }
1327 if (this.keyboard_active != value) {
1328 this.keyboard_active = value;
1331 Application.KeyboardCapture = this;
1332 else if (Application.KeyboardCapture == this) {
1333 Application.KeyboardCapture = null;
1334 ToolStripManager.ActivatedByKeyboard = false;
1337 // Redraw for mnemonic underlines
1344 #region Private Methods
1345 internal virtual Rectangle CalculateConnectedArea ()
1347 return Rectangle.Empty;
1350 internal void ChangeSelection (ToolStripItem nextItem)
1352 if (Application.KeyboardCapture != this)
1353 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1355 foreach (ToolStripItem tsi in this.Items)
1356 if (tsi != nextItem)
1357 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1359 ToolStripItem current = GetCurrentlySelectedItem ();
1361 if (current != null && !(current is ToolStripControlHost))
1362 this.FocusInternal (true);
1364 if (nextItem is ToolStripControlHost)
1365 (nextItem as ToolStripControlHost).Focus ();
1369 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1370 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1373 internal virtual void Dismiss ()
1375 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1378 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1380 // Release our stranglehold on the keyboard
1381 this.KeyboardActive = false;
1383 // Set our drop down flag to false;
1384 this.menu_selected = false;
1386 // Make sure all of our items are deselected and repainted
1387 foreach (ToolStripItem tsi in this.Items)
1388 tsi.Dismiss (reason);
1390 // We probably need to redraw for mnemonic underlines
1394 internal ToolStripItem GetCurrentlySelectedItem ()
1396 foreach (ToolStripItem tsi in this.DisplayedItems)
1403 internal ToolStripItem GetCurrentlyFocusedItem ()
1405 foreach (ToolStripItem tsi in this.DisplayedItems)
1406 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1412 internal override Size GetPreferredSizeCore (Size proposedSize)
1414 return GetToolStripPreferredSize (proposedSize);
1417 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1419 Size new_size = Size.Empty;
1421 // TODO: This is total duct tape. We really have to call into the correct
1422 // layout engine, do a dry run of the layout, and find out our true
1423 // preferred dimensions.
1424 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1425 Point currentLocation = Point.Empty;
1428 foreach (ToolStripItem tsi in items)
1429 if (tsi.Available) {
1430 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1432 if ((DisplayRectangle.Width - currentLocation.X) < (tsi_preferred.Width + tsi.Margin.Horizontal)) {
1434 currentLocation.Y += tallest;
1437 currentLocation.X = DisplayRectangle.Left;
1440 // Offset the left margin and set the control to our point
1441 currentLocation.Offset (tsi.Margin.Left, 0);
1442 tallest = Math.Max (tallest, tsi_preferred.Height + tsi.Margin.Vertical);
1444 // Update our location pointer
1445 currentLocation.X += tsi_preferred.Width + tsi.Margin.Right;
1448 currentLocation.Y += tallest;
1449 return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical);
1452 if (this.orientation == Orientation.Vertical) {
1453 foreach (ToolStripItem tsi in this.items)
1454 if (tsi.Available) {
1455 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1456 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1458 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1459 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1462 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1464 if (new_size.Width == 0)
1465 new_size.Width = ExplicitBounds.Width;
1469 foreach (ToolStripItem tsi in this.items)
1470 if (tsi.Available) {
1471 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1472 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1474 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1475 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1478 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1480 if (new_size.Height == 0)
1481 new_size.Height = ExplicitBounds.Height;
1483 if (this is StatusStrip)
1484 new_size.Height = Math.Max (new_size.Height, 22);
1490 internal virtual ToolStrip GetTopLevelToolStrip ()
1495 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1497 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1500 internal void NotifySelectedChanged (ToolStripItem tsi)
1502 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1504 if (tsi2 is ToolStripDropDownItem)
1505 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1507 if (this.OverflowButton != null) {
1508 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1510 foreach (ToolStripItem tsi2 in tsic)
1512 if (tsi2 is ToolStripDropDownItem)
1513 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1515 this.OverflowButton.HideDropDown ();
1518 foreach (ToolStripItem tsi2 in this.Items)
1520 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1523 internal virtual bool OnMenuKey ()
1528 internal virtual bool ProcessArrowKey (Keys keyData)
1534 tsi = this.GetCurrentlySelectedItem ();
1536 if (tsi is ToolStripControlHost)
1539 tsi = this.SelectNextToolStripItem (tsi, true);
1541 if (tsi is ToolStripControlHost)
1542 (tsi as ToolStripControlHost).Focus ();
1546 tsi = this.GetCurrentlySelectedItem ();
1548 tsi = this.SelectNextToolStripItem (tsi, true);
1550 if (tsi is ToolStripControlHost)
1551 (tsi as ToolStripControlHost).Focus ();
1555 tsi = this.GetCurrentlySelectedItem ();
1557 if (tsi is ToolStripControlHost)
1560 tsi = this.SelectNextToolStripItem (tsi, false);
1562 if (tsi is ToolStripControlHost)
1563 (tsi as ToolStripControlHost).Focus ();
1566 case Keys.Shift | Keys.Tab:
1567 tsi = this.GetCurrentlySelectedItem ();
1569 tsi = this.SelectNextToolStripItem (tsi, false);
1571 if (tsi is ToolStripControlHost)
1572 (tsi as ToolStripControlHost).Focus ();
1580 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1582 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1584 if (next_item == null)
1587 this.ChangeSelection (next_item);
1589 if (next_item is ToolStripControlHost)
1590 (next_item as ToolStripControlHost).Focus ();
1595 #region Stuff for ToolTips
1596 private void MouseEnteredItem (ToolStripItem item)
1598 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1599 ToolTipTimer.Interval = InitialToolTipDelay;
1600 tooltip_state = ToolTip.TipState.Initial;
1601 tooltip_currently_showing = item;
1602 ToolTipTimer.Start ();
1606 private void CloseToolTip (ToolStripItem item)
1608 ToolTipTimer.Stop ();
1609 ToolTipWindow.Hide (this);
1610 tooltip_currently_showing = null;
1611 tooltip_state = ToolTip.TipState.Down;
1614 private void MouseLeftItem (ToolStripItem item)
1616 CloseToolTip (item);
1619 private Timer ToolTipTimer {
1621 if (tooltip_timer == null) {
1622 tooltip_timer = new Timer ();
1623 tooltip_timer.Enabled = false;
1624 tooltip_timer.Interval = InitialToolTipDelay;
1625 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1628 return tooltip_timer;
1632 private ToolTip ToolTipWindow {
1634 if (tooltip_window == null)
1635 tooltip_window = new ToolTip ();
1637 return tooltip_window;
1641 private void ShowToolTip ()
1643 string tooltip = tooltip_currently_showing.GetToolTip ();
1645 if (!string.IsNullOrEmpty (tooltip)) {
1646 ToolTipWindow.Present (this, tooltip);
1647 ToolTipTimer.Interval = ToolTipDelay;
1648 ToolTipTimer.Start ();
1649 tooltip_state = ToolTip.TipState.Show;
1652 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1655 private void ToolTipTimer_Tick (object o, EventArgs args)
1657 ToolTipTimer.Stop ();
1659 switch (tooltip_state) {
1660 case ToolTip.TipState.Initial:
1663 case ToolTip.TipState.Show:
1664 CloseToolTip (null);
1670 #region Stuff for Merging
1671 internal ToolStrip CurrentlyMergedWith {
1672 get { return this.currently_merged_with; }
1673 set { this.currently_merged_with = value; }
1676 internal List<ToolStripItem> HiddenMergedItems {
1678 if (this.hidden_merged_items == null)
1679 this.hidden_merged_items = new List<ToolStripItem> ();
1681 return this.hidden_merged_items;
1685 internal bool IsCurrentlyMerged {
1686 get { return this.is_currently_merged; }
1688 this.is_currently_merged = value;
1690 if (!value && this is MenuStrip)
1691 foreach (ToolStripMenuItem tsmi in this.Items)
1692 tsmi.DropDown.IsCurrentlyMerged = value;
1696 internal void BeginMerge ()
1698 if (!IsCurrentlyMerged) {
1699 IsCurrentlyMerged = true;
1701 if (this.pre_merge_items == null) {
1702 this.pre_merge_items = new List<ToolStripItem> ();
1704 foreach (ToolStripItem tsi in this.Items)
1705 this.pre_merge_items.Add (tsi);
1710 internal void RevertMergeItem (ToolStripItem item)
1714 // Remove it from it's current Parent
1715 if (item.Parent != null && item.Parent != this) {
1716 if (item.Parent is ToolStripOverflow)
1717 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1719 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1721 item.Parent = item.Owner;
1724 // Find where the item was before the merge
1725 index = item.Owner.pre_merge_items.IndexOf (item);
1727 // Find the first pre-merge item that was after this item, that
1728 // is currently in the Items collection. Insert our item before
1730 for (int i = index; i < this.pre_merge_items.Count; i++) {
1731 if (this.Items.Contains (this.pre_merge_items[i])) {
1732 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1737 // There aren't any items that are supposed to be after this item,
1738 // so just append it to the end.
1739 item.Owner.Items.AddNoOwnerOrLayout (item);
1744 #region ToolStripAccessibleObject
1746 public class ToolStripAccessibleObject : ControlAccessibleObject
1748 #region Public Constructor
1749 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1754 #region Public Properties
1755 public override AccessibleRole Role {
1756 get { return AccessibleRole.ToolBar; }
1760 #region Public Methods
1761 public override AccessibleObject GetChild (int index)
1763 return base.GetChild (index);
1766 public override int GetChildCount ()
1768 return (owner as ToolStrip).Items.Count;
1771 public override AccessibleObject HitTest (int x, int y)
1773 return base.HitTest (x, y);