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 string code = Char.ToUpper (charCode).ToString ();
1150 // If any item's text starts with our letter, it gets the message
1151 if ((Control.ModifierKeys & Keys.Alt) != 0 || this is ToolStripDropDownMenu)
1152 foreach (ToolStripItem tsi in this.Items)
1153 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
1154 return tsi.ProcessMnemonic (charCode);
1156 return base.ProcessMnemonic (charCode);
1159 [MonoTODO ("Stub, does nothing")]
1160 [EditorBrowsable (EditorBrowsableState.Advanced)]
1161 protected virtual void RestoreFocus ()
1165 protected override void Select (bool directed, bool forward)
1167 foreach (ToolStripItem tsi in this.DisplayedItems)
1168 if (tsi.CanSelect) {
1174 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1176 base.SetBoundsCore (x, y, width, height, specified);
1179 protected virtual void SetDisplayedItems ()
1181 this.displayed_items.ClearInternal ();
1183 foreach (ToolStripItem tsi in this.items)
1184 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1185 this.displayed_items.AddNoOwnerOrLayout (tsi);
1188 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1189 tsi.Parent = this.OverflowButton.DropDown;
1191 if (this.OverflowButton != null)
1192 this.OverflowButton.DropDown.SetDisplayedItems ();
1195 protected internal void SetItemLocation (ToolStripItem item, Point location)
1198 throw new ArgumentNullException ("item");
1200 if (item.Owner != this)
1201 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1203 item.SetBounds (new Rectangle (location, item.Size));
1206 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1208 if (item.Owner != null) {
1209 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1211 if (item.Owner is ToolStripOverflow)
1212 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1215 parent.Items.AddNoOwnerOrLayout (item);
1216 item.Parent = parent;
1219 protected override void SetVisibleCore (bool visible)
1221 base.SetVisibleCore (visible);
1224 protected override void WndProc (ref Message m)
1226 base.WndProc (ref m);
1230 #region Public Events
1231 static object BeginDragEvent = new object ();
1232 static object EndDragEvent = new object ();
1233 static object ItemAddedEvent = new object ();
1234 static object ItemClickedEvent = new object ();
1235 static object ItemRemovedEvent = new object ();
1236 static object LayoutCompletedEvent = new object ();
1237 static object LayoutStyleChangedEvent = new object ();
1238 static object PaintGripEvent = new object ();
1239 static object RendererChangedEvent = new object ();
1242 [EditorBrowsable (EditorBrowsableState.Always)]
1243 public new event EventHandler AutoSizeChanged {
1244 add { base.AutoSizeChanged += value; }
1245 remove { base.AutoSizeChanged -= value; }
1248 [MonoTODO ("Event never raised")]
1249 public event EventHandler BeginDrag {
1250 add { Events.AddHandler (BeginDragEvent, value); }
1251 remove { Events.RemoveHandler (BeginDragEvent, value); }
1255 public new event EventHandler CausesValidationChanged {
1256 add { base.CausesValidationChanged += value; }
1257 remove { base.CausesValidationChanged -= value; }
1261 [EditorBrowsable (EditorBrowsableState.Never)]
1262 public new event ControlEventHandler ControlAdded {
1263 add { base.ControlAdded += value; }
1264 remove { base.ControlAdded -= value; }
1268 [EditorBrowsable (EditorBrowsableState.Never)]
1269 public new event ControlEventHandler ControlRemoved {
1270 add { base.ControlRemoved += value; }
1271 remove { base.ControlRemoved -= value; }
1275 public new event EventHandler CursorChanged {
1276 add { base.CursorChanged += value; }
1277 remove { base.CursorChanged -= value; }
1280 [MonoTODO ("Event never raised")]
1281 public event EventHandler EndDrag {
1282 add { Events.AddHandler (EndDragEvent, value); }
1283 remove { Events.RemoveHandler (EndDragEvent, value); }
1287 public new event EventHandler ForeColorChanged {
1288 add { base.ForeColorChanged += value; }
1289 remove { base.ForeColorChanged -= value; }
1292 public event ToolStripItemEventHandler ItemAdded {
1293 add { Events.AddHandler (ItemAddedEvent, value); }
1294 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1297 public event ToolStripItemClickedEventHandler ItemClicked {
1298 add { Events.AddHandler (ItemClickedEvent, value); }
1299 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1302 public event ToolStripItemEventHandler ItemRemoved {
1303 add { Events.AddHandler (ItemRemovedEvent, value); }
1304 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1307 public event EventHandler LayoutCompleted {
1308 add { Events.AddHandler (LayoutCompletedEvent, value); }
1309 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1312 public event EventHandler LayoutStyleChanged {
1313 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1314 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1317 public event PaintEventHandler PaintGrip {
1318 add { Events.AddHandler (PaintGripEvent, value); }
1319 remove { Events.RemoveHandler (PaintGripEvent, value); }
1322 public event EventHandler RendererChanged {
1323 add { Events.AddHandler (RendererChangedEvent, value); }
1324 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1328 #region Internal Properties
1329 internal virtual bool KeyboardActive
1331 get { return this.keyboard_active; }
1333 if (this.keyboard_active != value) {
1334 this.keyboard_active = value;
1337 Application.KeyboardCapture = this;
1338 else if (Application.KeyboardCapture == this) {
1339 Application.KeyboardCapture = null;
1340 ToolStripManager.ActivatedByKeyboard = false;
1343 // Redraw for mnemonic underlines
1350 #region Private Methods
1351 internal virtual Rectangle CalculateConnectedArea ()
1353 return Rectangle.Empty;
1356 internal void ChangeSelection (ToolStripItem nextItem)
1358 if (Application.KeyboardCapture != this)
1359 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1361 foreach (ToolStripItem tsi in this.Items)
1362 if (tsi != nextItem)
1363 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1365 ToolStripItem current = GetCurrentlySelectedItem ();
1367 if (current != null && !(current is ToolStripControlHost))
1368 this.FocusInternal (true);
1370 if (nextItem is ToolStripControlHost)
1371 (nextItem as ToolStripControlHost).Focus ();
1375 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1376 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1379 internal virtual void Dismiss ()
1381 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1384 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1386 // Release our stranglehold on the keyboard
1387 this.KeyboardActive = false;
1389 // Set our drop down flag to false;
1390 this.menu_selected = false;
1392 // Make sure all of our items are deselected and repainted
1393 foreach (ToolStripItem tsi in this.Items)
1394 tsi.Dismiss (reason);
1396 // We probably need to redraw for mnemonic underlines
1400 internal ToolStripItem GetCurrentlySelectedItem ()
1402 foreach (ToolStripItem tsi in this.DisplayedItems)
1409 internal ToolStripItem GetCurrentlyFocusedItem ()
1411 foreach (ToolStripItem tsi in this.DisplayedItems)
1412 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1418 internal override Size GetPreferredSizeCore (Size proposedSize)
1420 return GetToolStripPreferredSize (proposedSize);
1423 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1425 Size new_size = Size.Empty;
1427 // TODO: This is total duct tape. We really have to call into the correct
1428 // layout engine, do a dry run of the layout, and find out our true
1429 // preferred dimensions.
1430 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1431 Point currentLocation = Point.Empty;
1434 foreach (ToolStripItem tsi in items)
1435 if (tsi.Available) {
1436 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1438 if ((DisplayRectangle.Width - currentLocation.X) < (tsi_preferred.Width + tsi.Margin.Horizontal)) {
1440 currentLocation.Y += tallest;
1443 currentLocation.X = DisplayRectangle.Left;
1446 // Offset the left margin and set the control to our point
1447 currentLocation.Offset (tsi.Margin.Left, 0);
1448 tallest = Math.Max (tallest, tsi_preferred.Height + tsi.Margin.Vertical);
1450 // Update our location pointer
1451 currentLocation.X += tsi_preferred.Width + tsi.Margin.Right;
1454 currentLocation.Y += tallest;
1455 return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical);
1458 if (this.orientation == Orientation.Vertical) {
1459 foreach (ToolStripItem tsi in this.items)
1460 if (tsi.Available) {
1461 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1462 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1464 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1465 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1468 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1470 if (new_size.Width == 0)
1471 new_size.Width = ExplicitBounds.Width;
1475 foreach (ToolStripItem tsi in this.items)
1476 if (tsi.Available) {
1477 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1478 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1480 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1481 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1484 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1486 if (new_size.Height == 0)
1487 new_size.Height = ExplicitBounds.Height;
1489 if (this is StatusStrip)
1490 new_size.Height = Math.Max (new_size.Height, 22);
1496 internal virtual ToolStrip GetTopLevelToolStrip ()
1501 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1503 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1506 internal void NotifySelectedChanged (ToolStripItem tsi)
1508 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1510 if (tsi2 is ToolStripDropDownItem)
1511 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1513 if (this.OverflowButton != null) {
1514 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1516 foreach (ToolStripItem tsi2 in tsic)
1518 if (tsi2 is ToolStripDropDownItem)
1519 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1521 this.OverflowButton.HideDropDown ();
1524 foreach (ToolStripItem tsi2 in this.Items)
1526 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1529 internal virtual bool OnMenuKey ()
1534 internal virtual bool ProcessArrowKey (Keys keyData)
1540 tsi = this.GetCurrentlySelectedItem ();
1542 if (tsi is ToolStripControlHost)
1545 tsi = this.SelectNextToolStripItem (tsi, true);
1547 if (tsi is ToolStripControlHost)
1548 (tsi as ToolStripControlHost).Focus ();
1552 tsi = this.GetCurrentlySelectedItem ();
1554 tsi = this.SelectNextToolStripItem (tsi, true);
1556 if (tsi is ToolStripControlHost)
1557 (tsi as ToolStripControlHost).Focus ();
1561 tsi = this.GetCurrentlySelectedItem ();
1563 if (tsi is ToolStripControlHost)
1566 tsi = this.SelectNextToolStripItem (tsi, false);
1568 if (tsi is ToolStripControlHost)
1569 (tsi as ToolStripControlHost).Focus ();
1572 case Keys.Shift | Keys.Tab:
1573 tsi = this.GetCurrentlySelectedItem ();
1575 tsi = this.SelectNextToolStripItem (tsi, false);
1577 if (tsi is ToolStripControlHost)
1578 (tsi as ToolStripControlHost).Focus ();
1586 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1588 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1590 if (next_item == null)
1593 this.ChangeSelection (next_item);
1595 if (next_item is ToolStripControlHost)
1596 (next_item as ToolStripControlHost).Focus ();
1601 #region Stuff for ToolTips
1602 private void MouseEnteredItem (ToolStripItem item)
1604 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1605 ToolTipTimer.Interval = InitialToolTipDelay;
1606 tooltip_state = ToolTip.TipState.Initial;
1607 tooltip_currently_showing = item;
1608 ToolTipTimer.Start ();
1612 private void CloseToolTip (ToolStripItem item)
1614 ToolTipTimer.Stop ();
1615 ToolTipWindow.Hide (this);
1616 tooltip_currently_showing = null;
1617 tooltip_state = ToolTip.TipState.Down;
1620 private void MouseLeftItem (ToolStripItem item)
1622 CloseToolTip (item);
1625 private Timer ToolTipTimer {
1627 if (tooltip_timer == null) {
1628 tooltip_timer = new Timer ();
1629 tooltip_timer.Enabled = false;
1630 tooltip_timer.Interval = InitialToolTipDelay;
1631 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1634 return tooltip_timer;
1638 private ToolTip ToolTipWindow {
1640 if (tooltip_window == null)
1641 tooltip_window = new ToolTip ();
1643 return tooltip_window;
1647 private void ShowToolTip ()
1649 string tooltip = tooltip_currently_showing.GetToolTip ();
1651 if (!string.IsNullOrEmpty (tooltip)) {
1652 ToolTipWindow.Present (this, tooltip);
1653 ToolTipTimer.Interval = ToolTipDelay;
1654 ToolTipTimer.Start ();
1655 tooltip_state = ToolTip.TipState.Show;
1658 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1661 private void ToolTipTimer_Tick (object o, EventArgs args)
1663 ToolTipTimer.Stop ();
1665 switch (tooltip_state) {
1666 case ToolTip.TipState.Initial:
1669 case ToolTip.TipState.Show:
1670 CloseToolTip (null);
1676 #region Stuff for Merging
1677 internal ToolStrip CurrentlyMergedWith {
1678 get { return this.currently_merged_with; }
1679 set { this.currently_merged_with = value; }
1682 internal List<ToolStripItem> HiddenMergedItems {
1684 if (this.hidden_merged_items == null)
1685 this.hidden_merged_items = new List<ToolStripItem> ();
1687 return this.hidden_merged_items;
1691 internal bool IsCurrentlyMerged {
1692 get { return this.is_currently_merged; }
1694 this.is_currently_merged = value;
1696 if (!value && this is MenuStrip)
1697 foreach (ToolStripMenuItem tsmi in this.Items)
1698 tsmi.DropDown.IsCurrentlyMerged = value;
1702 internal void BeginMerge ()
1704 if (!IsCurrentlyMerged) {
1705 IsCurrentlyMerged = true;
1707 if (this.pre_merge_items == null) {
1708 this.pre_merge_items = new List<ToolStripItem> ();
1710 foreach (ToolStripItem tsi in this.Items)
1711 this.pre_merge_items.Add (tsi);
1716 internal void RevertMergeItem (ToolStripItem item)
1720 // Remove it from it's current Parent
1721 if (item.Parent != null && item.Parent != this) {
1722 if (item.Parent is ToolStripOverflow)
1723 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1725 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1727 item.Parent = item.Owner;
1730 // Find where the item was before the merge
1731 index = item.Owner.pre_merge_items.IndexOf (item);
1733 // Find the first pre-merge item that was after this item, that
1734 // is currently in the Items collection. Insert our item before
1736 for (int i = index; i < this.pre_merge_items.Count; i++) {
1737 if (this.Items.Contains (this.pre_merge_items[i])) {
1738 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1743 // There aren't any items that are supposed to be after this item,
1744 // so just append it to the end.
1745 item.Owner.Items.AddNoOwnerOrLayout (item);
1750 #region ToolStripAccessibleObject
1752 public class ToolStripAccessibleObject : ControlAccessibleObject
1754 #region Public Constructor
1755 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1760 #region Public Properties
1761 public override AccessibleRole Role {
1762 get { return AccessibleRole.ToolBar; }
1766 #region Public Methods
1767 public override AccessibleObject GetChild (int index)
1769 return base.GetChild (index);
1772 public override int GetChildCount ()
1774 return (owner as ToolStrip).Items.Count;
1777 public override AccessibleObject HitTest (int x, int y)
1779 return base.HitTest (x, y);