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)
730 // ToolStripItem.Dispose modifes the collection,
731 // so we iterate it in reverse order
732 for (int i = Items.Count - 1; i >= 0; i--)
733 Items [i].Dispose ();
735 if (this.overflow_button != null && this.overflow_button.drop_down != null)
736 this.overflow_button.drop_down.Dispose ();
738 ToolStripManager.RemoveToolStrip (this);
739 base.Dispose (disposing);
743 [MonoTODO ("Stub, never called")]
744 protected virtual void OnBeginDrag (EventArgs e)
746 EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
751 protected override void OnDockChanged (EventArgs e)
753 base.OnDockChanged (e);
756 [MonoTODO ("Stub, never called")]
757 protected virtual void OnEndDrag (EventArgs e)
759 EventHandler eh = (EventHandler)(Events[EndDragEvent]);
764 protected override bool IsInputChar (char charCode)
766 return base.IsInputChar (charCode);
769 protected override bool IsInputKey (Keys keyData)
771 return base.IsInputKey (keyData);
774 protected override void OnEnabledChanged (EventArgs e)
776 base.OnEnabledChanged (e);
778 foreach (ToolStripItem tsi in this.Items)
779 tsi.OnParentEnabledChanged (EventArgs.Empty);
782 protected override void OnFontChanged (EventArgs e)
784 base.OnFontChanged (e);
787 protected override void OnHandleCreated (EventArgs e)
789 base.OnHandleCreated (e);
792 protected override void OnHandleDestroyed (EventArgs e)
794 base.OnHandleDestroyed (e);
797 protected override void OnInvalidated (InvalidateEventArgs e)
799 base.OnInvalidated (e);
802 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
804 if (e.Item.InternalVisible)
805 e.Item.Available = true;
807 e.Item.SetPlacement (ToolStripItemPlacement.Main);
810 this.PerformLayout ();
812 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
817 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
819 if (this.KeyboardActive)
820 ToolStripManager.SetActiveToolStrip (null, false);
822 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
827 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
829 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
834 protected override void OnLayout (LayoutEventArgs e)
838 this.SetDisplayedItems ();
839 this.OnLayoutCompleted (EventArgs.Empty);
843 protected virtual void OnLayoutCompleted (EventArgs e)
845 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
850 protected virtual void OnLayoutStyleChanged (EventArgs e)
852 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
857 protected override void OnLeave (EventArgs e)
862 protected override void OnLostFocus (EventArgs e)
864 base.OnLostFocus (e);
867 protected override void OnMouseCaptureChanged (EventArgs e)
869 base.OnMouseCaptureChanged (e);
872 protected override void OnMouseDown (MouseEventArgs mea)
874 if (mouse_currently_over != null)
876 ToolStripItem focused = GetCurrentlyFocusedItem ();
878 if (focused != null && focused != mouse_currently_over)
879 this.FocusInternal (true);
881 if (this is MenuStrip && !menu_selected) {
882 (this as MenuStrip).FireMenuActivate ();
883 menu_selected = true;
886 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
888 if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems)
891 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
894 if (this is MenuStrip)
895 this.Capture = false;
897 base.OnMouseDown (mea);
900 protected override void OnMouseLeave (EventArgs e)
902 if (mouse_currently_over != null) {
903 MouseLeftItem (mouse_currently_over);
904 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
905 mouse_currently_over = null;
908 base.OnMouseLeave (e);
911 protected override void OnMouseMove (MouseEventArgs mea)
914 // Find the item we are now
915 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
916 tsi = this.overflow_button;
918 tsi = this.GetItemAt (mea.X, mea.Y);
921 // If we were already hovering on this item, just send a mouse move
922 if (tsi == mouse_currently_over)
923 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
925 // If we were over a different item, fire a mouse leave on it
926 if (mouse_currently_over != null) {
928 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
931 // Set the new item we are currently over
932 mouse_currently_over = tsi;
934 // Fire mouse enter and mouse move
935 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
936 MouseEnteredItem (tsi);
937 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
939 // If we're over something with a drop down, show it
940 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
941 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
944 // We're not over anything now, just fire the mouse leave on what we used to be over
945 if (mouse_currently_over != null) {
947 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
948 mouse_currently_over = null;
952 base.OnMouseMove (mea);
955 protected override void OnMouseUp (MouseEventArgs mea)
957 // If we're currently over an item (set in MouseMove)
958 if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
959 // Fire our ItemClicked event
960 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
962 // Fire the item's MouseUp event
963 if (mouse_currently_over != null)
964 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
966 // The event handler may have blocked until the mouse moved off of the ToolStripItem
967 if (mouse_currently_over == null)
971 base.OnMouseUp (mea);
974 protected override void OnPaint (PaintEventArgs e)
979 this.OnPaintGrip (e);
981 // Make each item draw itself
982 for (int i = 0; i < displayed_items.Count; i++) {
983 ToolStripItem tsi = displayed_items[i];
986 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
987 tsi.FireEvent (e, ToolStripItemEventType.Paint);
988 e.Graphics.ResetTransform ();
992 // Paint the Overflow button if it's visible
993 if (this.overflow_button != null && this.overflow_button.Visible) {
994 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
995 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
996 e.Graphics.ResetTransform ();
999 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1001 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
1002 pevent.InternalConnectedArea = CalculateConnectedArea ();
1004 this.Renderer.DrawToolStripBorder (pevent);
1007 [EditorBrowsable (EditorBrowsableState.Advanced)]
1008 protected override void OnPaintBackground (PaintEventArgs e)
1010 base.OnPaintBackground (e);
1012 Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
1013 ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
1015 this.Renderer.DrawToolStripBackground (tsrea);
1018 protected internal virtual void OnPaintGrip (PaintEventArgs e)
1020 // Never draw a grip with these two layouts
1021 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
1024 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
1028 if (!(this is MenuStrip)) {
1029 if (this.orientation == Orientation.Horizontal)
1030 e.Graphics.TranslateTransform (2, 0);
1032 e.Graphics.TranslateTransform (0, 2);
1035 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
1036 e.Graphics.ResetTransform ();
1039 protected virtual void OnRendererChanged (EventArgs e)
1041 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
1046 [EditorBrowsable (EditorBrowsableState.Advanced)]
1047 protected override void OnRightToLeftChanged (EventArgs e)
1049 base.OnRightToLeftChanged (e);
1051 foreach (ToolStripItem tsi in this.Items)
1052 tsi.OnParentRightToLeftChanged (e);
1055 protected override void OnScroll (ScrollEventArgs se)
1060 protected override void OnTabStopChanged (EventArgs e)
1062 base.OnTabStopChanged (e);
1065 protected override void OnVisibleChanged (EventArgs e)
1068 CloseToolTip (null);
1070 base.OnVisibleChanged (e);
1073 protected override bool ProcessCmdKey (ref Message m, Keys keyData)
1075 return base.ProcessCmdKey (ref m, keyData);
1078 protected override bool ProcessDialogKey (Keys keyData)
1080 if (!this.KeyboardActive)
1083 // Give each item a chance to handle the key
1084 foreach (ToolStripItem tsi in this.Items)
1085 if (tsi.ProcessDialogKey (keyData))
1088 // See if I want to handle it
1089 if (this.ProcessArrowKey (keyData))
1092 ToolStrip ts = null;
1096 this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1099 case Keys.Control | Keys.Tab:
1100 ts = ToolStripManager.GetNextToolStrip (this, true);
1103 foreach (ToolStripItem tsi in this.Items)
1104 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1106 ToolStripManager.SetActiveToolStrip (ts, true);
1107 ts.SelectNextToolStripItem (null, true);
1111 case Keys.Control | Keys.Shift | Keys.Tab:
1112 ts = ToolStripManager.GetNextToolStrip (this, false);
1115 foreach (ToolStripItem tsi in this.Items)
1116 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1118 ToolStripManager.SetActiveToolStrip (ts, true);
1119 ts.SelectNextToolStripItem (null, true);
1127 if (GetCurrentlySelectedItem () is ToolStripControlHost)
1132 return base.ProcessDialogKey (keyData);
1135 protected override bool ProcessMnemonic (char charCode)
1137 // If any item has an explicit mnemonic, it gets the message
1138 foreach (ToolStripItem tsi in this.Items)
1139 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
1140 return tsi.ProcessMnemonic (charCode);
1142 string code = Char.ToUpper (charCode).ToString ();
1144 // If any item's text starts with our letter, it gets the message
1145 if ((Control.ModifierKeys & Keys.Alt) != 0 || this is ToolStripDropDownMenu)
1146 foreach (ToolStripItem tsi in this.Items)
1147 if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
1148 return tsi.ProcessMnemonic (charCode);
1150 return base.ProcessMnemonic (charCode);
1153 [MonoTODO ("Stub, does nothing")]
1154 [EditorBrowsable (EditorBrowsableState.Advanced)]
1155 protected virtual void RestoreFocus ()
1159 protected override void Select (bool directed, bool forward)
1161 foreach (ToolStripItem tsi in this.DisplayedItems)
1162 if (tsi.CanSelect) {
1168 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
1170 base.SetBoundsCore (x, y, width, height, specified);
1173 protected virtual void SetDisplayedItems ()
1175 this.displayed_items.ClearInternal ();
1177 foreach (ToolStripItem tsi in this.items)
1178 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
1179 this.displayed_items.AddNoOwnerOrLayout (tsi);
1182 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
1183 tsi.Parent = this.OverflowButton.DropDown;
1185 if (this.OverflowButton != null)
1186 this.OverflowButton.DropDown.SetDisplayedItems ();
1189 protected internal void SetItemLocation (ToolStripItem item, Point location)
1192 throw new ArgumentNullException ("item");
1194 if (item.Owner != this)
1195 throw new NotSupportedException ("The item is not owned by this ToolStrip");
1197 item.SetBounds (new Rectangle (location, item.Size));
1200 protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
1202 if (item.Owner != null) {
1203 item.Owner.Items.RemoveNoOwnerOrLayout (item);
1205 if (item.Owner is ToolStripOverflow)
1206 (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1209 parent.Items.AddNoOwnerOrLayout (item);
1210 item.Parent = parent;
1213 protected override void SetVisibleCore (bool visible)
1215 base.SetVisibleCore (visible);
1218 protected override void WndProc (ref Message m)
1220 base.WndProc (ref m);
1224 #region Public Events
1225 static object BeginDragEvent = new object ();
1226 static object EndDragEvent = new object ();
1227 static object ItemAddedEvent = new object ();
1228 static object ItemClickedEvent = new object ();
1229 static object ItemRemovedEvent = new object ();
1230 static object LayoutCompletedEvent = new object ();
1231 static object LayoutStyleChangedEvent = new object ();
1232 static object PaintGripEvent = new object ();
1233 static object RendererChangedEvent = new object ();
1236 [EditorBrowsable (EditorBrowsableState.Always)]
1237 public new event EventHandler AutoSizeChanged {
1238 add { base.AutoSizeChanged += value; }
1239 remove { base.AutoSizeChanged -= value; }
1242 [MonoTODO ("Event never raised")]
1243 public event EventHandler BeginDrag {
1244 add { Events.AddHandler (BeginDragEvent, value); }
1245 remove { Events.RemoveHandler (BeginDragEvent, value); }
1249 public new event EventHandler CausesValidationChanged {
1250 add { base.CausesValidationChanged += value; }
1251 remove { base.CausesValidationChanged -= value; }
1255 [EditorBrowsable (EditorBrowsableState.Never)]
1256 public new event ControlEventHandler ControlAdded {
1257 add { base.ControlAdded += value; }
1258 remove { base.ControlAdded -= value; }
1262 [EditorBrowsable (EditorBrowsableState.Never)]
1263 public new event ControlEventHandler ControlRemoved {
1264 add { base.ControlRemoved += value; }
1265 remove { base.ControlRemoved -= value; }
1269 public new event EventHandler CursorChanged {
1270 add { base.CursorChanged += value; }
1271 remove { base.CursorChanged -= value; }
1274 [MonoTODO ("Event never raised")]
1275 public event EventHandler EndDrag {
1276 add { Events.AddHandler (EndDragEvent, value); }
1277 remove { Events.RemoveHandler (EndDragEvent, value); }
1281 public new event EventHandler ForeColorChanged {
1282 add { base.ForeColorChanged += value; }
1283 remove { base.ForeColorChanged -= value; }
1286 public event ToolStripItemEventHandler ItemAdded {
1287 add { Events.AddHandler (ItemAddedEvent, value); }
1288 remove { Events.RemoveHandler (ItemAddedEvent, value); }
1291 public event ToolStripItemClickedEventHandler ItemClicked {
1292 add { Events.AddHandler (ItemClickedEvent, value); }
1293 remove { Events.RemoveHandler (ItemClickedEvent, value); }
1296 public event ToolStripItemEventHandler ItemRemoved {
1297 add { Events.AddHandler (ItemRemovedEvent, value); }
1298 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
1301 public event EventHandler LayoutCompleted {
1302 add { Events.AddHandler (LayoutCompletedEvent, value); }
1303 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
1306 public event EventHandler LayoutStyleChanged {
1307 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
1308 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
1311 public event PaintEventHandler PaintGrip {
1312 add { Events.AddHandler (PaintGripEvent, value); }
1313 remove { Events.RemoveHandler (PaintGripEvent, value); }
1316 public event EventHandler RendererChanged {
1317 add { Events.AddHandler (RendererChangedEvent, value); }
1318 remove { Events.RemoveHandler (RendererChangedEvent, value); }
1322 #region Internal Properties
1323 internal virtual bool KeyboardActive
1325 get { return this.keyboard_active; }
1327 if (this.keyboard_active != value) {
1328 this.keyboard_active = value;
1331 Application.KeyboardCapture = this;
1332 else if (Application.KeyboardCapture == this) {
1333 Application.KeyboardCapture = null;
1334 ToolStripManager.ActivatedByKeyboard = false;
1337 // Redraw for mnemonic underlines
1344 #region Private Methods
1345 internal virtual Rectangle CalculateConnectedArea ()
1347 return Rectangle.Empty;
1350 internal void ChangeSelection (ToolStripItem nextItem)
1352 if (Application.KeyboardCapture != this)
1353 ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
1355 foreach (ToolStripItem tsi in this.Items)
1356 if (tsi != nextItem)
1357 tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1359 ToolStripItem current = GetCurrentlySelectedItem ();
1361 if (current != null && !(current is ToolStripControlHost))
1362 this.FocusInternal (true);
1364 if (nextItem is ToolStripControlHost)
1365 (nextItem as ToolStripControlHost).Focus ();
1369 if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
1370 (nextItem as ToolStripMenuItem).HandleAutoExpansion ();
1373 internal virtual void Dismiss ()
1375 this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
1378 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1380 // Release our stranglehold on the keyboard
1381 this.KeyboardActive = false;
1383 // Set our drop down flag to false;
1384 this.menu_selected = false;
1386 // Make sure all of our items are deselected and repainted
1387 foreach (ToolStripItem tsi in this.Items)
1388 tsi.Dismiss (reason);
1390 // We probably need to redraw for mnemonic underlines
1394 internal ToolStripItem GetCurrentlySelectedItem ()
1396 foreach (ToolStripItem tsi in this.DisplayedItems)
1403 internal ToolStripItem GetCurrentlyFocusedItem ()
1405 foreach (ToolStripItem tsi in this.DisplayedItems)
1406 if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
1412 internal override Size GetPreferredSizeCore (Size proposedSize)
1414 return GetToolStripPreferredSize (proposedSize);
1417 internal virtual Size GetToolStripPreferredSize (Size proposedSize)
1419 Size new_size = Size.Empty;
1421 // TODO: This is total duct tape. We really have to call into the correct
1422 // layout engine, do a dry run of the layout, and find out our true
1423 // preferred dimensions.
1424 if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
1425 Point currentLocation = Point.Empty;
1428 foreach (ToolStripItem tsi in items) {
1429 if ((DisplayRectangle.Width - currentLocation.X) < (tsi.Width + tsi.Margin.Horizontal)) {
1431 currentLocation.Y += tallest;
1434 currentLocation.X = DisplayRectangle.Left;
1437 // Offset the left margin and set the control to our point
1438 currentLocation.Offset (tsi.Margin.Left, 0);
1439 tallest = Math.Max (tallest, tsi.Height + tsi.Margin.Vertical);
1441 // Update our location pointer
1442 currentLocation.X += tsi.Width + tsi.Margin.Right;
1445 currentLocation.Y += tallest;
1446 return new Size (currentLocation.X, currentLocation.Y);
1449 if (this.orientation == Orientation.Vertical) {
1450 foreach (ToolStripItem tsi in this.items)
1451 if (tsi.Available) {
1452 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1453 new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
1455 if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
1456 new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
1459 new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
1461 if (new_size.Width == 0)
1462 new_size.Width = ExplicitBounds.Width;
1466 foreach (ToolStripItem tsi in this.items)
1467 if (tsi.Available) {
1468 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
1469 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
1471 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
1472 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
1475 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
1477 if (new_size.Height == 0)
1478 new_size.Height = ExplicitBounds.Height;
1480 if (this is StatusStrip)
1481 new_size.Height = Math.Max (new_size.Height, 22);
1487 internal virtual ToolStrip GetTopLevelToolStrip ()
1492 internal virtual void HandleItemClick (ToolStripItem dismissingItem)
1494 this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
1497 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
1499 if (this is MenuStrip && release && menu_selected)
1500 (this as MenuStrip).FireMenuDeactivate ();
1503 menu_selected = false;
1505 NotifySelectedChanged (null);
1508 internal void NotifySelectedChanged (ToolStripItem tsi)
1510 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1512 if (tsi2 is ToolStripDropDownItem)
1513 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1515 if (this.OverflowButton != null) {
1516 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1518 foreach (ToolStripItem tsi2 in tsic)
1520 if (tsi2 is ToolStripDropDownItem)
1521 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1523 this.OverflowButton.HideDropDown ();
1526 foreach (ToolStripItem tsi2 in this.Items)
1528 tsi2.Dismiss (ToolStripDropDownCloseReason.Keyboard);
1531 internal virtual bool OnMenuKey ()
1536 internal virtual bool ProcessArrowKey (Keys keyData)
1542 tsi = this.GetCurrentlySelectedItem ();
1544 if (tsi is ToolStripControlHost)
1547 tsi = this.SelectNextToolStripItem (tsi, true);
1549 if (tsi is ToolStripControlHost)
1550 (tsi as ToolStripControlHost).Focus ();
1554 tsi = this.GetCurrentlySelectedItem ();
1556 tsi = this.SelectNextToolStripItem (tsi, true);
1558 if (tsi is ToolStripControlHost)
1559 (tsi as ToolStripControlHost).Focus ();
1563 tsi = this.GetCurrentlySelectedItem ();
1565 if (tsi is ToolStripControlHost)
1568 tsi = this.SelectNextToolStripItem (tsi, false);
1570 if (tsi is ToolStripControlHost)
1571 (tsi as ToolStripControlHost).Focus ();
1574 case Keys.Shift | Keys.Tab:
1575 tsi = this.GetCurrentlySelectedItem ();
1577 tsi = this.SelectNextToolStripItem (tsi, false);
1579 if (tsi is ToolStripControlHost)
1580 (tsi as ToolStripControlHost).Focus ();
1588 internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
1590 ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
1592 if (next_item == null)
1595 this.ChangeSelection (next_item);
1597 if (next_item is ToolStripControlHost)
1598 (next_item as ToolStripControlHost).Focus ();
1603 #region Stuff for ToolTips
1604 private void MouseEnteredItem (ToolStripItem item)
1606 if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
1607 ToolTipTimer.Interval = InitialToolTipDelay;
1608 tooltip_state = ToolTip.TipState.Initial;
1609 tooltip_currently_showing = item;
1610 ToolTipTimer.Start ();
1614 private void CloseToolTip (ToolStripItem item)
1616 ToolTipTimer.Stop ();
1617 ToolTipWindow.Hide (this);
1618 tooltip_currently_showing = null;
1619 tooltip_state = ToolTip.TipState.Down;
1622 private void MouseLeftItem (ToolStripItem item)
1624 CloseToolTip (item);
1627 private Timer ToolTipTimer {
1629 if (tooltip_timer == null) {
1630 tooltip_timer = new Timer ();
1631 tooltip_timer.Enabled = false;
1632 tooltip_timer.Interval = InitialToolTipDelay;
1633 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1636 return tooltip_timer;
1640 private ToolTip ToolTipWindow {
1642 if (tooltip_window == null)
1643 tooltip_window = new ToolTip ();
1645 return tooltip_window;
1649 private void ShowToolTip ()
1651 string tooltip = tooltip_currently_showing.GetToolTip ();
1653 if (!string.IsNullOrEmpty (tooltip)) {
1654 ToolTipWindow.Present (this, tooltip);
1655 ToolTipTimer.Interval = ToolTipDelay;
1656 ToolTipTimer.Start ();
1657 tooltip_state = ToolTip.TipState.Show;
1660 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1663 private void ToolTipTimer_Tick (object o, EventArgs args)
1665 ToolTipTimer.Stop ();
1667 switch (tooltip_state) {
1668 case ToolTip.TipState.Initial:
1671 case ToolTip.TipState.Show:
1672 CloseToolTip (null);
1678 #region Stuff for Merging
1679 internal ToolStrip CurrentlyMergedWith {
1680 get { return this.currently_merged_with; }
1681 set { this.currently_merged_with = value; }
1684 internal List<ToolStripItem> HiddenMergedItems {
1686 if (this.hidden_merged_items == null)
1687 this.hidden_merged_items = new List<ToolStripItem> ();
1689 return this.hidden_merged_items;
1693 internal bool IsCurrentlyMerged {
1694 get { return this.is_currently_merged; }
1696 this.is_currently_merged = value;
1698 if (!value && this is MenuStrip)
1699 foreach (ToolStripMenuItem tsmi in this.Items)
1700 tsmi.DropDown.IsCurrentlyMerged = value;
1704 internal void BeginMerge ()
1706 if (!IsCurrentlyMerged) {
1707 IsCurrentlyMerged = true;
1709 if (this.pre_merge_items == null) {
1710 this.pre_merge_items = new List<ToolStripItem> ();
1712 foreach (ToolStripItem tsi in this.Items)
1713 this.pre_merge_items.Add (tsi);
1718 internal void RevertMergeItem (ToolStripItem item)
1722 // Remove it from it's current Parent
1723 if (item.Parent != null && item.Parent != this) {
1724 if (item.Parent is ToolStripOverflow)
1725 (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
1727 item.Parent.Items.RemoveNoOwnerOrLayout (item);
1729 item.Parent = item.Owner;
1732 // Find where the item was before the merge
1733 index = item.Owner.pre_merge_items.IndexOf (item);
1735 // Find the first pre-merge item that was after this item, that
1736 // is currently in the Items collection. Insert our item before
1738 for (int i = index; i < this.pre_merge_items.Count; i++) {
1739 if (this.Items.Contains (this.pre_merge_items[i])) {
1740 item.Owner.Items.InsertNoOwnerOrLayout (this.Items.IndexOf (this.pre_merge_items[i]), item);
1745 // There aren't any items that are supposed to be after this item,
1746 // so just append it to the end.
1747 item.Owner.Items.AddNoOwnerOrLayout (item);
1752 #region ToolStripAccessibleObject
1754 public class ToolStripAccessibleObject : ControlAccessibleObject
1756 #region Public Constructor
1757 public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
1762 #region Public Properties
1763 public override AccessibleRole Role {
1764 get { return AccessibleRole.ToolBar; }
1768 #region Public Methods
1769 public override AccessibleObject GetChild (int index)
1771 return base.GetChild (index);
1774 public override int GetChildCount ()
1776 return (owner as ToolStrip).Items.Count;
1779 public override AccessibleObject HitTest (int x, int y)
1781 return base.HitTest (x, y);