4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
34 using System.Windows.Forms.Layout;
35 using System.Collections.Generic;
36 using System.ComponentModel.Design.Serialization;
38 namespace System.Windows.Forms
41 [ClassInterface (ClassInterfaceType.AutoDispatch)]
42 [DefaultEvent ("ItemClicked")]
43 [DefaultProperty ("Items")]
44 [Designer ("System.Windows.Forms.Design.ToolStripDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 [DesignerSerializer ("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
46 public class ToolStrip : ScrollableControl, IComponent, IDisposable, IToolStripData
48 #region Private Variables
49 private bool allow_item_reorder;
50 private bool allow_merge;
51 private Color back_color;
52 private bool can_overflow;
53 private ToolStrip currently_merged_with;
54 private ToolStripDropDownDirection default_drop_down_direction;
55 internal ToolStripItemCollection displayed_items;
56 private Color fore_color;
57 private Padding grip_margin;
58 private ToolStripGripStyle grip_style;
59 private List<ToolStripItem> hidden_merged_items;
60 private ImageList image_list;
61 private Size image_scaling_size;
62 private bool is_currently_merged;
63 private ToolStripItemCollection items;
64 private bool keyboard_active;
65 private LayoutEngine layout_engine;
66 private LayoutSettings layout_settings;
67 private ToolStripLayoutStyle layout_style;
68 private Orientation orientation;
69 private ToolStripOverflowButton overflow_button;
70 private List<ToolStripItem> pre_merge_items;
71 private ToolStripRenderer renderer;
72 private ToolStripRenderMode render_mode;
73 private ToolStripTextDirection text_direction;
74 private Timer tooltip_timer;
75 private ToolTip tooltip_window;
76 private bool show_item_tool_tips;
79 private ToolStripItem mouse_currently_over;
80 internal bool menu_selected;
81 private ToolStripItem tooltip_currently_showing;
82 private ToolTip.TipState tooltip_state;
84 const int InitialToolTipDelay = 500;
85 const int ToolTipDelay = 5000;
88 #region Public Constructors
89 public ToolStrip () : this (null)
93 public ToolStrip (params ToolStripItem[] items) : base ()
95 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
96 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
97 SetStyle (ControlStyles.Selectable, false);
98 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
100 this.SuspendLayout ();
102 this.items = new ToolStripItemCollection (this, items, true);
103 this.allow_merge = true;
104 base.AutoSize = true;
105 this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
106 this.back_color = Control.DefaultBackColor;
107 this.can_overflow = true;
108 base.CausesValidation = false;
109 this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
110 this.displayed_items = new ToolStripItemCollection (this, null, true);
111 this.Dock = this.DefaultDock;
112 base.Font = new Font ("Tahoma", 8.25f);
113 this.fore_color = Control.DefaultForeColor;
114 this.grip_margin = this.DefaultGripMargin;
115 this.grip_style = ToolStripGripStyle.Visible;
116 this.image_scaling_size = new Size (16, 16);
117 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
118 this.orientation = Orientation.Horizontal;
119 if (!(this is ToolStripDropDown))
120 this.overflow_button = new ToolStripOverflowButton (this);
121 this.renderer = null;
122 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
123 this.show_item_tool_tips = this.DefaultShowItemToolTips;
124 base.TabStop = false;
125 this.text_direction = ToolStripTextDirection.Horizontal;
126 this.ResumeLayout ();
128 // Register with the ToolStripManager
129 ToolStripManager.AddToolStrip (this);
133 #region Public Properties
134 [MonoTODO ("Stub, does nothing")]
135 public override bool AllowDrop {
136 get { return base.AllowDrop; }
137 set { base.AllowDrop = value; }
140 [MonoTODO ("Stub, does nothing")]
141 [DefaultValue (false)]
142 public bool AllowItemReorder {
143 get { return this.allow_item_reorder; }
144 set { this.allow_item_reorder = value; }
147 [DefaultValue (true)]
148 public bool AllowMerge {
149 get { return this.allow_merge; }
150 set { this.allow_merge = value; }
153 public override AnchorStyles Anchor {
154 get { return base.Anchor; }
155 set { base.Anchor = value; }
159 [EditorBrowsable (EditorBrowsableState.Never)]
160 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
161 public override bool AutoScroll {
162 get { return base.AutoScroll; }
163 set { base.AutoScroll = value; }
167 [EditorBrowsable (EditorBrowsableState.Never)]
168 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
169 public new Size AutoScrollMargin {
170 get { return base.AutoScrollMargin; }
171 set { base.AutoScrollMargin = value; }
175 [EditorBrowsable (EditorBrowsableState.Never)]
176 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
177 public new Size AutoScrollMinSize {
178 get { return base.AutoScrollMinSize; }
179 set { base.AutoScrollMinSize = value; }
183 [EditorBrowsable (EditorBrowsableState.Never)]
184 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
185 public new Point AutoScrollPosition {
186 get { return base.AutoScrollPosition; }
187 set { base.AutoScrollPosition = value; }
190 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
192 [EditorBrowsable (EditorBrowsableState.Always)]
193 [DefaultValue (true)]
194 public override bool AutoSize {
195 get { return base.AutoSize; }
196 set { base.AutoSize = value; }
199 new public Color BackColor {
200 get { return this.back_color; }
201 set { this.back_color = value; }
204 public override BindingContext BindingContext {
205 get { return base.BindingContext; }
206 set { base.BindingContext = value; }
209 [DefaultValue (true)]
210 public bool CanOverflow {
211 get { return this.can_overflow; }
212 set { this.can_overflow = value; }
216 [DefaultValue (false)]
217 public new bool CausesValidation {
218 get { return base.CausesValidation; }
219 set { base.CausesValidation = value; }
222 [EditorBrowsable (EditorBrowsableState.Never)]
223 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
224 public new ControlCollection Controls {
225 get { return base.Controls; }
229 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
230 public override Cursor Cursor {
231 get { return base.Cursor; }
232 set { base.Cursor = value; }
236 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
237 get { return this.default_drop_down_direction; }
239 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
240 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
242 this.default_drop_down_direction = value;
246 public override Rectangle DisplayRectangle {
248 if (this.orientation == Orientation.Horizontal)
249 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
250 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
252 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);
254 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
255 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
257 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);
261 [DefaultValue (DockStyle.Top)]
262 public override DockStyle Dock {
263 get { return base.Dock; }
265 if (base.Dock != value) {
270 case DockStyle.Bottom:
272 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
275 case DockStyle.Right:
276 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
283 public override Font Font {
284 get { return base.Font; }
286 if (base.Font != value) {
289 foreach (ToolStripItem tsi in this.Items)
290 tsi.OnOwnerFontChanged (EventArgs.Empty);
296 public new Color ForeColor {
297 get { return this.fore_color; }
299 if (this.fore_color != value) {
300 this.fore_color = value;
301 this.OnForeColorChanged (EventArgs.Empty);
307 public ToolStripGripDisplayStyle GripDisplayStyle {
308 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
311 public Padding GripMargin {
312 get { return this.grip_margin; }
314 if (this.grip_margin != value) {
315 this.grip_margin = value;
316 this.PerformLayout ();
322 public Rectangle GripRectangle {
324 if (this.grip_style == ToolStripGripStyle.Hidden)
325 return Rectangle.Empty;
327 if (this.orientation == Orientation.Horizontal)
328 return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
330 return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
334 [DefaultValue (ToolStripGripStyle.Visible)]
335 public ToolStripGripStyle GripStyle {
336 get { return this.grip_style; }
338 if (this.grip_style != value) {
339 if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
340 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
341 this.grip_style = value;
342 this.PerformLayout (this, "GripStyle");
348 [EditorBrowsable (EditorBrowsableState.Never)]
349 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
350 public new bool HasChildren {
351 get { return base.HasChildren; }
355 [EditorBrowsable (EditorBrowsableState.Never)]
356 public new HScrollProperties HorizontalScroll {
357 get { return base.HorizontalScroll; }
361 [DefaultValue (null)]
362 public ImageList ImageList {
363 get { return this.image_list; }
364 set { this.image_list = value; }
367 [DefaultValue ("{Width=16, Height=16}")]
368 public Size ImageScalingSize {
369 get { return this.image_scaling_size; }
370 set { this.image_scaling_size = value; }
373 [MonoTODO ("Always returns false, dragging not implemented yet.")]
375 [EditorBrowsable (EditorBrowsableState.Advanced)]
376 public bool IsCurrentlyDragging {
377 get { return false; }
381 public bool IsDropDown {
383 if (this is ToolStripDropDown)
390 [MergableProperty (false)]
391 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
392 public virtual ToolStripItemCollection Items {
393 get { return this.items; }
396 public override LayoutEngine LayoutEngine {
398 if (layout_engine == null)
399 this.layout_engine = new ToolStripSplitStackLayout ();
401 return this.layout_engine;
406 [DefaultValue (null)]
407 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
408 public LayoutSettings LayoutSettings {
409 get { return this.layout_settings; }
411 if (this.layout_settings != value) {
412 this.layout_settings = value;
413 PerformLayout (this, "LayoutSettings");
418 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
419 public ToolStripLayoutStyle LayoutStyle {
420 get { return layout_style; }
422 if (this.layout_style != value) {
423 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
424 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
426 this.layout_style = value;
428 if (this.layout_style == ToolStripLayoutStyle.Flow)
429 this.layout_engine = new FlowLayout ();
431 this.layout_engine = new ToolStripSplitStackLayout ();
433 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
434 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
435 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
437 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
440 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
441 this.orientation = Orientation.Horizontal;
442 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
443 this.orientation = Orientation.Vertical;
445 this.layout_settings = this.CreateLayoutSettings (value);
447 this.PerformLayout (this, "LayoutStyle");
448 this.OnLayoutStyleChanged (EventArgs.Empty);
454 public Orientation Orientation {
455 get { return this.orientation; }
459 [EditorBrowsable (EditorBrowsableState.Advanced)]
460 public ToolStripOverflowButton OverflowButton {
461 get { return this.overflow_button; }
465 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
466 public ToolStripRenderer Renderer {
468 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
469 return ToolStripManager.Renderer;
471 return this.renderer;
474 if (this.renderer != value) {
475 this.renderer = value;
476 this.render_mode = ToolStripRenderMode.Custom;
477 this.PerformLayout (this, "Renderer");
478 this.OnRendererChanged (EventArgs.Empty);
483 public ToolStripRenderMode RenderMode {
484 get { return this.render_mode; }
486 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
487 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
489 if (value == ToolStripRenderMode.Custom && this.renderer == null)
490 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
491 else if (value == ToolStripRenderMode.Professional)
492 this.Renderer = new ToolStripProfessionalRenderer ();
493 else if (value == ToolStripRenderMode.System)
494 this.Renderer = new ToolStripSystemRenderer ();
496 this.render_mode = value;
500 [DefaultValue (true)]
501 public bool ShowItemToolTips {
502 get { return this.show_item_tool_tips; }
503 set { this.show_item_tool_tips = value; }
506 [DefaultValue (false)]
507 public bool Stretch {
508 get { return this.stretch; }
509 set { this.stretch = value; }
512 [DefaultValue (false)]
514 public new bool TabStop {
515 get { return base.TabStop; }
517 base.TabStop = value;
518 SetStyle (ControlStyles.Selectable, value);
522 [DefaultValue (ToolStripTextDirection.Horizontal)]
523 public virtual ToolStripTextDirection TextDirection {
524 get { return this.text_direction; }
526 if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
527 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
529 if (this.text_direction != value) {
530 this.text_direction = value;
532 this.PerformLayout (this, "TextDirection");
540 [EditorBrowsable (EditorBrowsableState.Never)]
541 public new VScrollProperties VerticalScroll {
542 get { return base.VerticalScroll; }
546 #region Protected Properties
547 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
548 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
549 protected override Padding DefaultMargin { get { return Padding.Empty; } }
550 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
551 protected virtual bool DefaultShowItemToolTips { get { return true; } }
552 protected override Size DefaultSize { get { return new Size (100, 25); } }
553 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
554 protected internal virtual Size MaxItemSize {
555 get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); }
559 #region Public Methods
560 [EditorBrowsable (EditorBrowsableState.Never)]
561 public new Control GetChildAtPoint (Point point)
563 return base.GetChildAtPoint (point);
566 [EditorBrowsable (EditorBrowsableState.Never)]
567 public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
569 return base.GetChildAtPoint (pt, skipValue);
572 public ToolStripItem GetItemAt (Point point)
574 foreach (ToolStripItem tsi in this.displayed_items)
575 if (tsi.Visible && tsi.Bounds.Contains (point))
581 public ToolStripItem GetItemAt (int x, int y)
583 return GetItemAt (new Point (x, y));
586 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
588 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
589 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
591 ToolStripItem current_best = null;
592 int current_best_point;
595 case ArrowDirection.Right:
596 current_best_point = int.MaxValue;
599 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
600 if (loop_tsi.Left >= start.Right && loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
601 current_best = loop_tsi;
602 current_best_point = loop_tsi.Left;
605 if (current_best == null)
606 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
607 if (loop_tsi.Left < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
608 current_best = loop_tsi;
609 current_best_point = loop_tsi.Left;
613 case ArrowDirection.Up:
614 current_best_point = int.MinValue;
617 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
618 if (loop_tsi.Bottom <= start.Top && loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
619 current_best = loop_tsi;
620 current_best_point = loop_tsi.Top;
623 if (current_best == null)
624 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
625 if (loop_tsi.Top > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
626 current_best = loop_tsi;
627 current_best_point = loop_tsi.Top;
631 case ArrowDirection.Left:
632 current_best_point = int.MinValue;
635 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
636 if (loop_tsi.Right <= start.Left && loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
637 current_best = loop_tsi;
638 current_best_point = loop_tsi.Left;
641 if (current_best == null)
642 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
643 if (loop_tsi.Left > current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
644 current_best = loop_tsi;
645 current_best_point = loop_tsi.Left;
649 case ArrowDirection.Down:
650 current_best_point = int.MaxValue;
653 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
654 if (loop_tsi.Top >= start.Bottom && loop_tsi.Bottom < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
655 current_best = loop_tsi;
656 current_best_point = loop_tsi.Top;
659 if (current_best == null)
660 foreach (ToolStripItem loop_tsi in this.DisplayedItems)
661 if (loop_tsi.Top < current_best_point && loop_tsi.Visible && loop_tsi.CanSelect) {
662 current_best = loop_tsi;
663 current_best_point = loop_tsi.Top;
672 [EditorBrowsable (EditorBrowsableState.Never)]
673 public void ResetMinimumSize ()
675 this.MinimumSize = new Size (-1, -1);
678 [EditorBrowsable (EditorBrowsableState.Never)]
679 public new void SetAutoScrollMargin (int x, int y)
681 base.SetAutoScrollMargin (x, y);
684 public override string ToString ()
686 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
690 #region Protected Methods
691 protected override AccessibleObject CreateAccessibilityInstance ()
693 return new ToolStripAccessibleObject (this);
696 protected override ControlCollection CreateControlsInstance ()
698 return base.CreateControlsInstance ();
701 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
704 return new ToolStripSeparator ();
706 if (this is ToolStripDropDown)
707 return new ToolStripMenuItem (text, image, onClick);
709 return new ToolStripButton (text, image, onClick);
712 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
714 switch (layoutStyle) {
715 case ToolStripLayoutStyle.Flow:
716 return new FlowLayoutSettings (this);
717 case ToolStripLayoutStyle.Table:
718 //return new TableLayoutSettings ();
719 case ToolStripLayoutStyle.StackWithOverflow:
720 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
721 case ToolStripLayoutStyle.VerticalStackWithOverflow:
727 protected override void Dispose (bool disposing)
731 // ToolStripItem.Dispose modifes the collection,
732 // so we iterate it in reverse order
733 for (int i = Items.Count - 1; i >= 0; i--)
734 Items [i].Dispose ();
736 if (this.overflow_button != null && this.overflow_button.drop_down != null)
737 this.overflow_button.drop_down.Dispose ();
739 ToolStripManager.RemoveToolStrip (this);
740 base.Dispose (disposing);
744 [MonoTODO ("Stub, never called")]
745 protected virtual void OnBeginDrag (EventArgs e)
747 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
752 protected override void OnDockChanged (EventArgs e)
754 base.OnDockChanged (e);
757 [MonoTODO ("Stub, never called")]
758 protected virtual void OnEndDrag (EventArgs e)
760 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
765 protected override bool IsInputChar (char charCode)
767 return base.IsInputChar (charCode);
770 protected override bool IsInputKey (Keys keyData)
772 return base.IsInputKey (keyData);
775 protected override void OnEnabledChanged (EventArgs e)
777 base.OnEnabledChanged (e);
779 foreach (ToolStripItem tsi in this.Items)
780 tsi.OnParentEnabledChanged (EventArgs.Empty);
783 protected override void OnFontChanged (EventArgs e)
785 base.OnFontChanged (e);
788 protected override void OnHandleCreated (EventArgs e)
790 base.OnHandleCreated (e);
793 protected override void OnHandleDestroyed (EventArgs e)
795 base.OnHandleDestroyed (e);
798 protected override void OnInvalidated (InvalidateEventArgs e)
800 base.OnInvalidated (e);
803 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
805 if (e.Item.InternalVisible)
806 e.Item.Available = true;
808 e.Item.SetPlacement (ToolStripItemPlacement.Main);
811 this.PerformLayout ();
813 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
818 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
820 if (this.KeyboardActive)
821 ToolStripManager.SetActiveToolStrip (null, false);
823 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
828 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
830 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
835 protected override void OnLayout (LayoutEventArgs e)
839 this.SetDisplayedItems ();
840 this.OnLayoutCompleted (EventArgs.Empty);
844 protected virtual void OnLayoutCompleted (EventArgs e)
846 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
851 protected virtual void OnLayoutStyleChanged (EventArgs e)
853 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
858 protected override void OnLeave (EventArgs e)
863 protected override void OnLostFocus (EventArgs e)
865 base.OnLostFocus (e);
868 protected override void OnMouseCaptureChanged (EventArgs e)
870 base.OnMouseCaptureChanged (e);
873 protected override void OnMouseDown (MouseEventArgs mea)
875 if (mouse_currently_over != null)
877 ToolStripItem focused = GetCurrentlyFocusedItem ();
879 if (focused != null && focused != mouse_currently_over)
880 this.FocusInternal (true);
882 if (this is MenuStrip && !menu_selected) {
883 (this as MenuStrip).FireMenuActivate ();
884 menu_selected = true;
887 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
889 if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems)
892 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
895 if (this is MenuStrip)
896 this.Capture = false;
898 base.OnMouseDown (mea);
901 protected override void OnMouseLeave (EventArgs e)
903 if (mouse_currently_over != null) {
904 MouseLeftItem (mouse_currently_over);
905 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
906 mouse_currently_over = null;
909 base.OnMouseLeave (e);
912 protected override void OnMouseMove (MouseEventArgs mea)
915 // Find the item we are now
916 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
917 tsi = this.overflow_button;
919 tsi = this.GetItemAt (mea.X, mea.Y);
922 // If we were already hovering on this item, just send a mouse move
923 if (tsi == mouse_currently_over)
924 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
926 // If we were over a different item, fire a mouse leave on it
927 if (mouse_currently_over != null) {
929 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
932 // Set the new item we are currently over
933 mouse_currently_over = tsi;
935 // Fire mouse enter and mouse move
936 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
937 MouseEnteredItem (tsi);
938 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
940 // If we're over something with a drop down, show it
941 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
942 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
945 // We're not over anything now, just fire the mouse leave on what we used to be over
946 if (mouse_currently_over != null) {
948 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
949 mouse_currently_over = null;
953 base.OnMouseMove (mea);
956 protected override void OnMouseUp (MouseEventArgs mea)
958 // If we're currently over an item (set in MouseMove)
959 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
960 // Fire our ItemClicked event
961 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
963 // Fire the item's MouseUp event
964 if (mouse_currently_over != null)
965 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
967 // The event handler may have blocked until the mouse moved off of the ToolStripItem
968 if (mouse_currently_over == null)
972 base.OnMouseUp (mea);
975 protected override void OnPaint (PaintEventArgs e)
980 this.OnPaintGrip (e);
982 // Make each item draw itself
983 for (int i = 0; i < displayed_items.Count; i++) {
984 ToolStripItem tsi = displayed_items[i];
987 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
988 tsi.FireEvent (e, ToolStripItemEventType.Paint);
989 e.Graphics.ResetTransform ();
993 // Paint the Overflow button if it's visible
994 if (this.overflow_button != null && this.overflow_button.Visible) {
995 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
996 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
997 e.Graphics.ResetTransform ();
1000 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1002 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
1003 pevent.InternalConnectedArea = CalculateConnectedArea ();
1005 this.Renderer.DrawToolStripBorder (pevent);
1008 [EditorBrowsable (EditorBrowsableState.Advanced)]
1009 protected override void OnPaintBackground (PaintEventArgs e)
1011 base.OnPaintBackground (e);
1013 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1014 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1016 this.Renderer.DrawToolStripBackground (tsrea);
1019 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1021 // Never draw a grip with these two layouts
1022 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1025 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1029 if (!(this is MenuStrip)) {
1030 if (this.orientation == Orientation.Horizontal)
1031 e.Graphics.TranslateTransform (2, 0);
1033 e.Graphics.TranslateTransform (0, 2);
1036 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1037 e.Graphics.ResetTransform ();
1040 protected virtual void OnRendererChanged (EventArgs e)
1042 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1047 [EditorBrowsable (EditorBrowsableState.Advanced)]
1048 protected override void OnRightToLeftChanged (EventArgs e)
1050 base.OnRightToLeftChanged (e);
1052 foreach (ToolStripItem tsi in this.Items)
1053 tsi.OnParentRightToLeftChanged (e);
1056 protected override void OnScroll (ScrollEventArgs se)
1061 protected override void OnTabStopChanged (EventArgs e)
1063 base.OnTabStopChanged (e);
1066 protected override void OnVisibleChanged (EventArgs e)
1069 CloseToolTip (null);
1071 base.OnVisibleChanged (e);
1074 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1076 return base.ProcessCmdKey (ref m, keyData);
1079 protected override bool ProcessDialogKey (Keys keyData)
1081 if (!this.KeyboardActive)
1084 // Give each item a chance to handle the key
1085 foreach (ToolStripItem tsi in this.Items)
1086 if (tsi.ProcessDialogKey (keyData))
1089 // See if I want to handle it
1090 if (this.ProcessArrowKey (keyData))
1093 ToolStrip ts = null;
1097 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1100 case Keys.Control | Keys.Tab:
1101 ts = ToolStripManager.GetNextToolStrip (this, true);
1104 foreach (ToolStripItem tsi in this.Items)
1105 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1107 ToolStripManager.SetActiveToolStrip (ts, true);
1108 ts.SelectNextToolStripItem (null, true);
1112 case Keys.Control | Keys.Shift | Keys.Tab:
1113 ts = ToolStripManager.GetNextToolStrip (this, false);
1116 foreach (ToolStripItem tsi in this.Items)
1117 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1119 ToolStripManager.SetActiveToolStrip (ts, true);
1120 ts.SelectNextToolStripItem (null, true);
1128 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1133 return base.ProcessDialogKey (keyData);
1136 protected override bool ProcessMnemonic (char charCode)
1138 // If any item has an explicit mnemonic, it gets the message
1139 foreach (ToolStripItem tsi in this.Items)
1140 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1141 return tsi.ProcessMnemonic (charCode);
1143 string code = Char.ToUpper (charCode).ToString ();
1145 // If any item's text starts with our letter, it gets the message
1146 if ((Control.ModifierKeys & Keys.Alt) != 0 || this is ToolStripDropDownMenu)
1147 foreach (ToolStripItem tsi in this.Items)
1148 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
1149 return tsi.ProcessMnemonic (charCode);
1151 return base.ProcessMnemonic (charCode);
1154 [MonoTODO ("Stub, does nothing")]
1155 [EditorBrowsable (EditorBrowsableState.Advanced)]
1156 protected virtual void RestoreFocus ()
1160 protected override void Select (bool directed, bool forward)
1162 foreach (ToolStripItem tsi in this.DisplayedItems)
1163 if (tsi.CanSelect) {
1169 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1171 base.SetBoundsCore (x, y, width, height, specified);
1174 protected virtual void SetDisplayedItems ()
1176 this.displayed_items.Clear ();
1178 foreach (ToolStripItem tsi in this.items)
1179 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1180 this.displayed_items.AddNoOwnerOrLayout (tsi);
1183 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1184 tsi.Parent = this.OverflowButton.DropDown;
1186 if (this.OverflowButton != null)
1187 this.OverflowButton.DropDown.SetDisplayedItems ();
1190 protected internal void SetItemLocation (ToolStripItem item, Point location)
1193 throw new ArgumentNullException ("item");
1195 if (item.Owner != this)
1196 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1198 item.SetBounds (new Rectangle (location, item.Size));
1201 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1203 if (item.Owner != null) {
1204 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1206 if (item.Owner is ToolStripOverflow)
1207 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1210 parent.Items.AddNoOwnerOrLayout (item);
1211 item.Parent = parent;
1214 protected override void SetVisibleCore (bool visible)
1216 base.SetVisibleCore (visible);
1219 protected override void WndProc (ref Message m)
1221 base.WndProc (ref m);
1225 #region Public Events
1226 static object BeginDragEvent = new object ();
1227 static object EndDragEvent = new object ();
1228 static object ItemAddedEvent = new object ();
1229 static object ItemClickedEvent = new object ();
1230 static object ItemRemovedEvent = new object ();
1231 static object LayoutCompletedEvent = new object ();
1232 static object LayoutStyleChangedEvent = new object ();
1233 static object PaintGripEvent = new object ();
1234 static object RendererChangedEvent = new object ();
1237 [EditorBrowsable (EditorBrowsableState.Always)]
1238 public new event EventHandler AutoSizeChanged {
1239 add { base.AutoSizeChanged += value; }
1240 remove { base.AutoSizeChanged -= value; }
1243 [MonoTODO ("Event never raised")]
1244 public event EventHandler BeginDrag {
1245 add { Events.AddHandler (BeginDragEvent, value); }
1246 remove { Events.RemoveHandler (BeginDragEvent, value); }
1250 public new event EventHandler CausesValidationChanged {
1251 add { base.CausesValidationChanged += value; }
1252 remove { base.CausesValidationChanged -= value; }
1256 [EditorBrowsable (EditorBrowsableState.Never)]
1257 public new event ControlEventHandler ControlAdded {
1258 add { base.ControlAdded += value; }
1259 remove { base.ControlAdded -= value; }
1263 [EditorBrowsable (EditorBrowsableState.Never)]
1264 public new event ControlEventHandler ControlRemoved {
1265 add { base.ControlRemoved += value; }
1266 remove { base.ControlRemoved -= value; }
1270 public new event EventHandler CursorChanged {
1271 add { base.CursorChanged += value; }
1272 remove { base.CursorChanged -= value; }
1275 [MonoTODO ("Event never raised")]
1276 public event EventHandler EndDrag {
1277 add { Events.AddHandler (EndDragEvent, value); }
1278 remove { Events.RemoveHandler (EndDragEvent, value); }
1282 public new event EventHandler ForeColorChanged {
1283 add { base.ForeColorChanged += value; }
1284 remove { base.ForeColorChanged -= value; }
1287 public event ToolStripItemEventHandler ItemAdded {
1288 add { Events.AddHandler (ItemAddedEvent, value); }
1289 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1292 public event ToolStripItemClickedEventHandler ItemClicked {
1293 add { Events.AddHandler (ItemClickedEvent, value); }
1294 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1297 public event ToolStripItemEventHandler ItemRemoved {
1298 add { Events.AddHandler (ItemRemovedEvent, value); }
1299 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1302 public event EventHandler LayoutCompleted {
1303 add { Events.AddHandler (LayoutCompletedEvent, value); }
1304 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1307 public event EventHandler LayoutStyleChanged {
1308 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1309 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1312 public event PaintEventHandler PaintGrip {
1313 add { Events.AddHandler (PaintGripEvent, value); }
1314 remove { Events.RemoveHandler (PaintGripEvent, value); }
1317 public event EventHandler RendererChanged {
1318 add { Events.AddHandler (RendererChangedEvent, value); }
1319 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1323 #region Internal Properties
1324 internal virtual bool KeyboardActive
1326 get { return this.keyboard_active; }
1328 if (this.keyboard_active != value) {
1329 this.keyboard_active = value;
1332 Application.KeyboardCapture = this;
1333 else if (Application.KeyboardCapture == this) {
1334 Application.KeyboardCapture = null;
1335 ToolStripManager.ActivatedByKeyboard = false;
1338 // Redraw for mnemonic underlines
1345 #region Private Methods
1346 internal virtual Rectangle CalculateConnectedArea ()
1348 return Rectangle.Empty;
1351 internal void ChangeSelection (ToolStripItem nextItem)
1353 if (Application.KeyboardCapture != this)
1354 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1356 foreach (ToolStripItem tsi in this.Items)
1357 if (tsi != nextItem)
1358 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1360 ToolStripItem current = GetCurrentlySelectedItem ();
1362 if (current != null && !(current is ToolStripControlHost))
1363 this.FocusInternal (true);
1365 if (nextItem is ToolStripControlHost)
1366 (nextItem as ToolStripControlHost).Focus ();
1370 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1371 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1374 internal virtual void Dismiss ()
1376 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1379 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1381 // Release our stranglehold on the keyboard
1382 this.KeyboardActive = false;
1384 // Set our drop down flag to false;
1385 this.menu_selected = false;
1387 // Make sure all of our items are deselected and repainted
1388 foreach (ToolStripItem tsi in this.Items)
1389 tsi.Dismiss (reason);
1391 // We probably need to redraw for mnemonic underlines
1395 internal ToolStripItem GetCurrentlySelectedItem ()
1397 foreach (ToolStripItem tsi in this.DisplayedItems)
1404 internal ToolStripItem GetCurrentlyFocusedItem ()
1406 foreach (ToolStripItem tsi in this.DisplayedItems)
1407 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1413 internal override Size GetPreferredSizeCore (Size proposedSize)
1415 return GetToolStripPreferredSize (proposedSize);
1418 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1420 Size new_size = Size.Empty;
1422 // TODO: This is total duct tape. We really have to call into the correct
1423 // layout engine, do a dry run of the layout, and find out our true
1424 // preferred dimensions.
1425 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1426 Point currentLocation = Point.Empty;
1429 foreach (ToolStripItem tsi in items) {
1430 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1432 currentLocation.Y += tallest;
1435 currentLocation.X = DisplayRectangle.Left;
1438 // Offset the left margin and set the control to our point
1439 currentLocation.Offset (tsi.Margin.Left, 0);
1440 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1442 // Update our location pointer
1443 currentLocation.X += tsi.Width + tsi.Margin.Right;
1446 currentLocation.Y += tallest;
1447 return new Size (currentLocation.X, currentLocation.Y);
1450 if (this.orientation == Orientation.Vertical) {
1451 foreach (ToolStripItem tsi in this.items)
1452 if (tsi.Available) {
1453 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1454 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1456 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1457 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1460 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1462 if (new_size.Width == 0)
1463 new_size.Width = ExplicitBounds.Width;
1467 foreach (ToolStripItem tsi in this.items)
1468 if (tsi.Available) {
1469 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1470 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1472 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1473 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1476 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1478 if (new_size.Height == 0)
1479 new_size.Height = ExplicitBounds.Height;
1481 if (this is StatusStrip)
1482 new_size.Height = Math.Max (new_size.Height, 22);
1488 internal virtual ToolStrip GetTopLevelToolStrip ()
1493 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1495 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1498 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1500 if (this is MenuStrip && release && menu_selected)
1501 (this as MenuStrip).FireMenuDeactivate ();
1504 menu_selected = false;
1506 NotifySelectedChanged (null);
1509 internal void NotifySelectedChanged (ToolStripItem tsi)
1511 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1513 if (tsi2 is ToolStripDropDownItem)
1514 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1516 if (this.OverflowButton != null) {
1517 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1519 foreach (ToolStripItem tsi2 in tsic)
1521 if (tsi2 is ToolStripDropDownItem)
1522 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1524 this.OverflowButton.HideDropDown ();
1527 foreach (ToolStripItem tsi2 in this.Items)
1529 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1532 internal virtual bool OnMenuKey ()
1537 internal virtual bool ProcessArrowKey (Keys keyData)
1543 tsi = this.GetCurrentlySelectedItem ();
1545 if (tsi is ToolStripControlHost)
1548 tsi = this.SelectNextToolStripItem (tsi, true);
1550 if (tsi is ToolStripControlHost)
1551 (tsi as ToolStripControlHost).Focus ();
1555 tsi = this.GetCurrentlySelectedItem ();
1557 tsi = this.SelectNextToolStripItem (tsi, true);
1559 if (tsi is ToolStripControlHost)
1560 (tsi as ToolStripControlHost).Focus ();
1564 tsi = this.GetCurrentlySelectedItem ();
1566 if (tsi is ToolStripControlHost)
1569 tsi = this.SelectNextToolStripItem (tsi, false);
1571 if (tsi is ToolStripControlHost)
1572 (tsi as ToolStripControlHost).Focus ();
1575 case Keys.Shift | Keys.Tab:
1576 tsi = this.GetCurrentlySelectedItem ();
1578 tsi = this.SelectNextToolStripItem (tsi, false);
1580 if (tsi is ToolStripControlHost)
1581 (tsi as ToolStripControlHost).Focus ();
1589 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1591 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1593 if (next_item == null)
1596 this.ChangeSelection (next_item);
1598 if (next_item is ToolStripControlHost)
1599 (next_item as ToolStripControlHost).Focus ();
1604 #region Stuff for ToolTips
1605 private void MouseEnteredItem (ToolStripItem item)
1607 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1608 ToolTipTimer.Interval = InitialToolTipDelay;
1609 tooltip_state = ToolTip.TipState.Initial;
1610 tooltip_currently_showing = item;
1611 ToolTipTimer.Start ();
1615 private void CloseToolTip (ToolStripItem item)
1617 ToolTipTimer.Stop ();
1618 ToolTipWindow.Hide (this);
1619 tooltip_currently_showing = null;
1620 tooltip_state = ToolTip.TipState.Down;
1623 private void MouseLeftItem (ToolStripItem item)
1625 CloseToolTip (item);
1628 private Timer ToolTipTimer {
1630 if (tooltip_timer == null) {
1631 tooltip_timer = new Timer ();
1632 tooltip_timer.Enabled = false;
1633 tooltip_timer.Interval = InitialToolTipDelay;
1634 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1637 return tooltip_timer;
1641 private ToolTip ToolTipWindow {
1643 if (tooltip_window == null)
1644 tooltip_window = new ToolTip ();
1646 return tooltip_window;
1650 private void ShowToolTip ()
1652 string tooltip = tooltip_currently_showing.GetToolTip ();
1654 if (!string.IsNullOrEmpty (tooltip)) {
1655 ToolTipWindow.Present (this, tooltip);
1656 ToolTipTimer.Interval = ToolTipDelay;
1657 ToolTipTimer.Start ();
1658 tooltip_state = ToolTip.TipState.Show;
1661 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1664 private void ToolTipTimer_Tick (object o, EventArgs args)
1666 ToolTipTimer.Stop ();
1668 switch (tooltip_state) {
1669 case ToolTip.TipState.Initial:
1672 case ToolTip.TipState.Show:
1673 CloseToolTip (null);
1679 #region Stuff for Merging
1680 internal ToolStrip CurrentlyMergedWith {
1681 get { return this.currently_merged_with; }
1682 set { this.currently_merged_with = value; }
1685 internal List<ToolStripItem> HiddenMergedItems {
1687 if (this.hidden_merged_items == null)
1688 this.hidden_merged_items = new List<ToolStripItem> ();
1690 return this.hidden_merged_items;
1694 internal bool IsCurrentlyMerged {
1695 get { return this.is_currently_merged; }
1697 this.is_currently_merged = value;
1699 if (!value && this is MenuStrip)
1700 foreach (ToolStripMenuItem tsmi in this.Items)
1701 tsmi.DropDown.IsCurrentlyMerged = value;
1705 internal void BeginMerge ()
1707 if (!IsCurrentlyMerged) {
1708 IsCurrentlyMerged = true;
1710 if (this.pre_merge_items == null) {
1711 this.pre_merge_items = new List<ToolStripItem> ();
1713 foreach (ToolStripItem tsi in this.Items)
1714 this.pre_merge_items.Add (tsi);
1719 internal void RevertMergeItem (ToolStripItem item)
1723 // Remove it from it's current Parent
1724 if (item.Parent != null && item.Parent != this) {
1725 if (item.Parent is ToolStripOverflow)
1726 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1728 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1730 item.Parent = item.Owner;
1733 // Find where the item was before the merge
1734 index = item.Owner.pre_merge_items.IndexOf (item);
1736 // Find the first pre-merge item that was after this item, that
1737 // is currently in the Items collection. Insert our item before
1739 for (int i = index; i < this.pre_merge_items.Count; i++) {
1740 if (this.Items.Contains (this.pre_merge_items[i])) {
1741 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1746 // There aren't any items that are supposed to be after this item,
1747 // so just append it to the end.
1748 item.Owner.Items.AddNoOwnerOrLayout (item);
1753 #region ToolStripAccessibleObject
1755 public class ToolStripAccessibleObject : ControlAccessibleObject
1757 #region Public Constructor
1758 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1763 #region Public Properties
1764 public override AccessibleRole Role {
1765 get { return AccessibleRole.ToolBar; }
1769 #region Public Methods
1770 public override AccessibleObject GetChild (int index)
1772 return base.GetChild (index);
1775 public override int GetChildCount ()
1777 return (owner as ToolStrip).Items.Count;
1780 public override AccessibleObject HitTest (int x, int y)
1782 return base.HitTest (x, y);