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