4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
34 using System.Windows.Forms.Layout;
36 namespace System.Windows.Forms
39 [ClassInterface (ClassInterfaceType.AutoDispatch)]
40 [DefaultEvent ("ItemClicked")]
41 [DefaultProperty ("Items")]
42 public class ToolStrip : ScrollableControl, IComponent, IDisposable
44 #region Private Variables
45 private Color back_color;
46 private bool can_overflow;
47 private ToolStripDropDownDirection default_drop_down_direction;
48 internal ToolStripItemCollection displayed_items;
49 private Color fore_color;
50 private Padding grip_margin;
51 private ToolStripGripStyle grip_style;
52 private ImageList image_list;
53 private Size image_scaling_size;
54 private ToolStripItemCollection items;
55 private LayoutEngine layout_engine;
56 private LayoutSettings layout_settings;
57 private ToolStripLayoutStyle layout_style;
58 private Orientation orientation;
59 private ToolStripOverflowButton overflow_button;
60 private ToolStripRenderer renderer;
61 private ToolStripRenderMode render_mode;
62 private Timer tooltip_timer;
63 private ToolTip.ToolTipWindow tooltip_window;
64 private bool show_item_tool_tips;
67 private ToolStripItem mouse_currently_over;
68 private bool menu_selected;
69 private ToolStripItem tooltip_currently_showing;
72 #region Public Constructors
73 public ToolStrip () : this (null)
77 public ToolStrip (params ToolStripItem[] items) : base ()
79 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
80 SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
81 SetStyle (ControlStyles.Selectable, false);
82 SetStyle (ControlStyles.SupportsTransparentBackColor, true);
84 this.SuspendLayout ();
85 this.items = new ToolStripItemCollection (this, items);
87 this.back_color = Control.DefaultBackColor;
88 this.can_overflow = true;
89 base.CausesValidation = false;
90 this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
91 this.displayed_items = new ToolStripItemCollection (this, null);
92 this.Dock = this.DefaultDock;
93 base.Font = new Font ("Tahoma", 8.25f);
94 this.fore_color = Control.DefaultForeColor;
95 this.grip_margin = this.DefaultGripMargin;
96 this.grip_style = ToolStripGripStyle.Visible;
97 this.image_scaling_size = new Size (16, 16);
98 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
99 this.orientation = Orientation.Horizontal;
100 if (!(this is ToolStripDropDown))
101 this.overflow_button = new ToolStripOverflowButton (this);
102 this.Padding = this.DefaultPadding;
103 this.renderer = null;
104 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
105 this.show_item_tool_tips = this.DefaultShowItemToolTips;
106 base.TabStop = false;
107 this.ResumeLayout ();
110 // Register with the ToolStripManager
111 ToolStripManager.AddToolStrip (this);
115 #region Public Properties
116 public override AnchorStyles Anchor {
117 get { return base.Anchor; }
118 set { base.Anchor = value; }
121 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
123 [EditorBrowsable (EditorBrowsableState.Always)]
124 [DefaultValue (true)]
125 public override bool AutoSize {
126 get { return base.AutoSize; }
127 set { base.AutoSize = value; }
130 new public Color BackColor {
131 get { return this.back_color; }
132 set { this.back_color = value; }
135 [DefaultValue (true)]
136 public bool CanOverflow {
137 get { return this.can_overflow; }
138 set { this.can_overflow = value; }
142 [DefaultValue (false)]
143 public new bool CausesValidation {
144 get { return base.CausesValidation; }
145 set { base.CausesValidation = value; }
148 [EditorBrowsable (EditorBrowsableState.Never)]
149 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
150 public new ControlCollection Controls {
151 get { return base.Controls; }
155 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
156 public override Cursor Cursor {
157 get { return base.Cursor; }
158 set { base.Cursor = value; }
162 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
163 get { return this.default_drop_down_direction; }
165 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
166 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
168 this.default_drop_down_direction = value;
172 public override Rectangle DisplayRectangle {
174 if (this.orientation == Orientation.Horizontal)
175 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
176 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
178 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);
180 if (this.grip_style == ToolStripGripStyle.Hidden || this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
181 return new Rectangle (this.Padding.Left, this.Padding.Top, this.Width - this.Padding.Horizontal, this.Height - this.Padding.Vertical);
183 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);
187 [DefaultValue (DockStyle.Top)]
188 public override DockStyle Dock {
189 get { return base.Dock; }
191 if (base.Dock != value) {
196 case DockStyle.Bottom:
198 this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
201 case DockStyle.Right:
202 this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
209 public override Font Font {
210 get { return base.Font; }
212 if (base.Font != value) {
215 foreach (ToolStripItem tsi in this.Items)
216 tsi.OnOwnerFontChanged (EventArgs.Empty);
222 public new Color ForeColor {
223 get { return this.fore_color; }
225 if (this.fore_color != value) {
226 this.fore_color = value;
227 this.OnForeColorChanged (EventArgs.Empty);
233 public ToolStripGripDisplayStyle GripDisplayStyle {
234 get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
237 public Padding GripMargin {
238 get { return this.grip_margin; }
240 if (this.grip_margin != value) {
241 this.grip_margin = value;
242 this.PerformLayout ();
248 public Rectangle GripRectangle {
250 if (this.grip_style == ToolStripGripStyle.Hidden)
251 return Rectangle.Empty;
253 if (this.orientation == Orientation.Horizontal)
254 return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
256 return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
260 [DefaultValue (ToolStripGripStyle.Visible)]
261 public ToolStripGripStyle GripStyle {
262 get { return this.grip_style; }
264 if (this.grip_style != value) {
265 if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
266 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
267 this.grip_style = value;
268 this.PerformLayout ();
274 [EditorBrowsable (EditorBrowsableState.Never)]
275 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
276 public new bool HasChildren {
277 get { return base.HasChildren; }
281 [DefaultValue (null)]
282 public ImageList ImageList {
283 get { return this.image_list; }
284 set { this.image_list = value; }
287 [DefaultValue ("{Width=16, Height=16}")]
288 public Size ImageScalingSize {
289 get { return this.image_scaling_size; }
290 set { this.image_scaling_size = value; }
293 [MonoTODO ("Always returns false, dragging not implemented yet.")]
295 [EditorBrowsable (EditorBrowsableState.Advanced)]
296 public bool IsCurrentlyDragging {
297 get { return false; }
301 public bool IsDropDown {
303 if (this is ToolStripDropDown)
310 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
311 public virtual ToolStripItemCollection Items {
312 get { return this.items; }
315 public override LayoutEngine LayoutEngine {
317 if (layout_engine == null)
318 this.layout_engine = new ToolStripSplitStackLayout ();
320 return this.layout_engine;
325 [DefaultValue (null)]
326 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
327 public LayoutSettings LayoutSettings {
328 get { return this.layout_settings; }
329 set { this.layout_settings = value; }
332 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
333 public ToolStripLayoutStyle LayoutStyle {
334 get { return layout_style; }
336 if (this.layout_style != value) {
337 if (!Enum.IsDefined (typeof (ToolStripLayoutStyle), value))
338 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripLayoutStyle", value));
340 this.layout_style = value;
342 if (this.layout_style == ToolStripLayoutStyle.Flow)
343 this.layout_engine = new FlowLayout ();
345 this.layout_engine = new ToolStripSplitStackLayout ();
347 if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
348 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
349 this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
351 this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
354 if (this.layout_style == ToolStripLayoutStyle.HorizontalStackWithOverflow)
355 this.orientation = Orientation.Horizontal;
356 else if (this.layout_style == ToolStripLayoutStyle.VerticalStackWithOverflow)
357 this.orientation = Orientation.Vertical;
359 this.layout_settings = this.CreateLayoutSettings (value);
361 this.PerformLayout ();
362 this.OnLayoutStyleChanged (EventArgs.Empty);
368 public Orientation Orientation {
369 get { return this.orientation; }
373 [EditorBrowsable (EditorBrowsableState.Advanced)]
374 public ToolStripOverflowButton OverflowButton {
375 get { return this.overflow_button; }
379 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
380 public ToolStripRenderer Renderer {
382 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
383 return ToolStripManager.Renderer;
385 return this.renderer;
388 if (this.renderer != value) {
389 this.renderer = value;
390 this.render_mode = ToolStripRenderMode.Custom;
391 this.PerformLayout ();
392 this.OnRendererChanged (EventArgs.Empty);
397 public ToolStripRenderMode RenderMode {
398 get { return this.render_mode; }
400 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
401 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
403 if (value == ToolStripRenderMode.Custom && this.renderer == null)
404 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
405 if (value == ToolStripRenderMode.Professional || value == ToolStripRenderMode.System)
406 this.Renderer = new ToolStripProfessionalRenderer ();
408 this.render_mode = value;
412 [DefaultValue (true)]
413 public bool ShowItemToolTips {
414 get { return this.show_item_tool_tips; }
415 set { this.show_item_tool_tips = value; }
418 [DefaultValue (false)]
419 public bool Stretch {
420 get { return this.stretch; }
421 set { this.stretch = value; }
424 [DefaultValue (false)]
426 public new bool TabStop {
427 get { return base.TabStop; }
428 set { base.TabStop = value; }
432 #region Protected Properties
433 protected virtual DockStyle DefaultDock { get { return DockStyle.Top; } }
434 protected virtual Padding DefaultGripMargin { get { return new Padding (2); } }
435 protected override Padding DefaultMargin { get { return Padding.Empty; } }
436 protected override Padding DefaultPadding { get { return new Padding (0, 0, 1, 0); } }
437 protected virtual bool DefaultShowItemToolTips { get { return true; } }
438 protected override Size DefaultSize { get { return new Size (100, 25); } }
439 protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
442 #region Public Methods
444 public new Control GetChildAtPoint (Point point)
446 return base.GetChildAtPoint (point);
449 public ToolStripItem GetItemAt (Point point)
451 foreach (ToolStripItem tsi in this.displayed_items)
452 if (tsi.Visible && tsi.Bounds.Contains (point))
458 public ToolStripItem GetItemAt (int x, int y)
460 return GetItemAt (new Point (x, y));
463 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
465 if (!Enum.IsDefined (typeof (ArrowDirection), direction))
466 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
468 int index = this.items.IndexOf (start);
471 case ArrowDirection.Left:
472 case ArrowDirection.Up:
474 return this.items[index - 1];
476 return this.items[this.items.Count - 1];
477 case ArrowDirection.Right:
478 case ArrowDirection.Down:
479 if (index + 1 >= this.items.Count)
480 return this.items[0];
482 return this.items[index + 1];
488 public override string ToString ()
490 return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
494 #region Protected Methods
495 protected override AccessibleObject CreateAccessibilityInstance ()
497 AccessibleObject ao = new AccessibleObject (this);
499 ao.role = AccessibleRole.ToolBar;
504 protected override ControlCollection CreateControlsInstance ()
506 return base.CreateControlsInstance ();
509 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
512 return new ToolStripSeparator ();
514 if (this is ToolStripDropDown)
515 return new ToolStripMenuItem (text, image, onClick);
517 return new ToolStripButton (text, image, onClick);
520 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
522 switch (layoutStyle) {
523 case ToolStripLayoutStyle.Flow:
524 return new FlowLayoutSettings ();
525 case ToolStripLayoutStyle.Table:
526 //return new TableLayoutSettings ();
527 case ToolStripLayoutStyle.StackWithOverflow:
528 case ToolStripLayoutStyle.HorizontalStackWithOverflow:
529 case ToolStripLayoutStyle.VerticalStackWithOverflow:
535 protected override void Dispose (bool disposing)
538 ToolStripManager.RemoveToolStrip (this);
539 base.Dispose (disposing);
543 protected override void OnDockChanged (EventArgs e)
545 base.OnDockChanged (e);
548 protected override void OnEnabledChanged (EventArgs e)
550 base.OnEnabledChanged (e);
552 foreach (ToolStripItem tsi in this.Items)
553 tsi.OnParentEnabledChanged (EventArgs.Empty);
556 protected override void OnFontChanged (EventArgs e)
558 base.OnFontChanged (e);
561 protected override void OnHandleCreated (EventArgs e)
563 base.OnHandleCreated (e);
566 protected override void OnHandleDestroyed (EventArgs e)
568 base.OnHandleDestroyed (e);
571 protected override void OnInvalidated (InvalidateEventArgs e)
573 base.OnInvalidated (e);
576 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
578 e.Item.Available = true;
579 e.Item.SetPlacement (ToolStripItemPlacement.Main);
581 this.PerformLayout ();
583 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
588 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
590 ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
595 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
597 ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
602 protected override void OnLayout (LayoutEventArgs e)
607 this.SetDisplayedItems ();
608 this.OnLayoutCompleted (EventArgs.Empty);
612 protected virtual void OnLayoutCompleted (EventArgs e)
614 EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
619 protected virtual void OnLayoutStyleChanged (EventArgs e)
621 EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
626 protected override void OnLeave (EventArgs e)
631 protected override void OnLostFocus (EventArgs e)
633 base.OnLostFocus (e);
636 protected override void OnMouseDown (MouseEventArgs mea)
638 if (mouse_currently_over != null)
640 if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
642 (this as MenuStrip).FireMenuActivate ();
647 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
649 if (this is MenuStrip && !menu_selected) {
650 (this as MenuStrip).FireMenuActivate ();
651 menu_selected = true;
654 if (this is MenuStrip)
655 this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
658 if (this is MenuStrip)
659 this.Capture = false;
661 base.OnMouseDown (mea);
664 protected override void OnMouseLeave (EventArgs e)
666 if (mouse_currently_over != null) {
667 MouseLeftItem (mouse_currently_over);
668 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
669 mouse_currently_over = null;
672 base.OnMouseLeave (e);
675 protected override void OnMouseMove (MouseEventArgs mea)
678 // Find the item we are now
679 if (this.overflow_button != null && this.overflow_button.Visible && this.overflow_button.Bounds.Contains (mea.Location))
680 tsi = this.overflow_button;
682 tsi = this.GetItemAt (mea.X, mea.Y);
685 // If we were already hovering on this item, just send a mouse move
686 if (tsi == mouse_currently_over)
687 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
689 // If we were over a different item, fire a mouse leave on it
690 if (mouse_currently_over != null) {
692 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
695 // Set the new item we are currently over
696 mouse_currently_over = tsi;
698 // Fire mouse enter and mouse move
699 tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
700 MouseEnteredItem (tsi);
701 tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
703 // If we're over something with a drop down, show it
704 if (menu_selected && mouse_currently_over.Enabled && mouse_currently_over is ToolStripDropDownItem && (mouse_currently_over as ToolStripDropDownItem).HasDropDownItems)
705 (mouse_currently_over as ToolStripDropDownItem).ShowDropDown ();
708 // We're not over anything now, just fire the mouse leave on what we used to be over
709 if (mouse_currently_over != null) {
711 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
712 mouse_currently_over = null;
716 base.OnMouseMove (mea);
719 protected override void OnMouseUp (MouseEventArgs mea)
721 // If we're currently over an item (set in MouseMove)
722 if (mouse_currently_over != null) {
723 // Fire the item's MouseUp event
724 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
726 // The event handler may have blocked until the mouse moved off of the ToolStripItem
727 if (mouse_currently_over == null)
730 // Fire our ItemClicked event
731 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
734 base.OnMouseUp (mea);
737 protected override void OnPaint (PaintEventArgs e)
742 this.OnPaintGrip (e);
744 // Make each item draw itself
745 foreach (ToolStripItem tsi in this.displayed_items) {
746 e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
747 tsi.FireEvent (e, ToolStripItemEventType.Paint);
748 e.Graphics.ResetTransform ();
751 // Paint the Overflow button if it's visible
752 if (this.overflow_button != null && this.overflow_button.Visible) {
753 e.Graphics.TranslateTransform (this.overflow_button.Bounds.Left, this.overflow_button.Bounds.Top);
754 this.overflow_button.FireEvent (e, ToolStripItemEventType.Paint);
755 e.Graphics.ResetTransform ();
758 Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
759 Rectangle connected_area = Rectangle.Empty;
761 if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
762 connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
764 ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
765 pevent.InternalConnectedArea = connected_area;
767 this.Renderer.DrawToolStripBorder (pevent);
770 [EditorBrowsable (EditorBrowsableState.Advanced)]
771 protected override void OnPaintBackground (PaintEventArgs pevent)
773 base.OnPaintBackground (pevent);
775 Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
776 Rectangle connected_area = Rectangle.Empty;
778 if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
779 connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
781 ToolStripRenderEventArgs e = new ToolStripRenderEventArgs (pevent.Graphics, this, affected_bounds, Color.Empty);
782 e.InternalConnectedArea = connected_area;
784 this.Renderer.DrawToolStripBackground (e);
787 protected internal virtual void OnPaintGrip (PaintEventArgs e)
789 // Never draw a grip with these two layouts
790 if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
793 PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
797 if (!(this is MenuStrip)) {
798 if (this.orientation == Orientation.Horizontal)
799 e.Graphics.TranslateTransform (2, 0);
801 e.Graphics.TranslateTransform (0, 2);
804 this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
805 e.Graphics.ResetTransform ();
808 protected virtual void OnRendererChanged (EventArgs e)
810 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
815 [EditorBrowsable (EditorBrowsableState.Advanced)]
816 protected override void OnRightToLeftChanged (EventArgs e)
818 base.OnRightToLeftChanged (e);
821 protected override void OnTabStopChanged (EventArgs e)
823 base.OnTabStopChanged (e);
826 protected override void OnVisibleChanged (EventArgs e)
828 base.OnVisibleChanged (e);
831 protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
833 return base.ProcessCmdKey (ref msg, keyData);
836 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
838 base.SetBoundsCore (x, y, width, height, specified);
841 protected virtual void SetDisplayedItems ()
843 this.displayed_items.Clear ();
845 foreach (ToolStripItem tsi in this.items)
846 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
847 this.displayed_items.AddNoOwnerOrLayout (tsi);
850 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
851 tsi.Parent = this.OverflowButton.DropDown;
853 if (this.OverflowButton != null)
854 this.OverflowButton.DropDown.SetDisplayedItems ();
857 protected internal void SetItemLocation (ToolStripItem item, Point location)
860 throw new ArgumentNullException ("item");
862 if (item.Owner != this)
863 throw new NotSupportedException ("The item is not owned by this ToolStrip");
865 item.SetBounds (new Rectangle (location, item.Size));
868 protected static void SetItemParent (ToolStripItem item, ToolStrip parent)
870 item.Parent = parent;
873 protected override void SetVisibleCore (bool value)
875 base.SetVisibleCore (value);
878 protected override void WndProc (ref Message m)
880 base.WndProc (ref m);
884 #region Public Events
885 static object ItemAddedEvent = new object ();
886 static object ItemClickedEvent = new object ();
887 static object ItemRemovedEvent = new object ();
888 static object LayoutCompletedEvent = new object ();
889 static object LayoutStyleChangedEvent = new object ();
890 static object PaintGripEvent = new object ();
891 static object RendererChangedEvent = new object ();
894 [EditorBrowsable (EditorBrowsableState.Always)]
895 public new event EventHandler AutoSizeChanged {
896 add { base.AutoSizeChanged += value; }
897 remove { base.AutoSizeChanged -= value; }
901 public new event EventHandler CausesValidationChanged {
902 add { base.CausesValidationChanged += value; }
903 remove { base.CausesValidationChanged -= value; }
907 public new event EventHandler CursorChanged {
908 add { base.CursorChanged += value; }
909 remove { base.CursorChanged -= value; }
913 public new event EventHandler ForeColorChanged {
914 add { base.ForeColorChanged += value; }
915 remove { base.ForeColorChanged -= value; }
918 public event ToolStripItemEventHandler ItemAdded {
919 add { Events.AddHandler (ItemAddedEvent, value); }
920 remove { Events.RemoveHandler (ItemAddedEvent, value); }
923 public event ToolStripItemClickedEventHandler ItemClicked {
924 add { Events.AddHandler (ItemClickedEvent, value); }
925 remove { Events.RemoveHandler (ItemClickedEvent, value); }
928 public event ToolStripItemEventHandler ItemRemoved {
929 add { Events.AddHandler (ItemRemovedEvent, value); }
930 remove { Events.RemoveHandler (ItemRemovedEvent, value); }
933 public event EventHandler LayoutCompleted {
934 add { Events.AddHandler (LayoutCompletedEvent, value); }
935 remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
938 public event EventHandler LayoutStyleChanged {
939 add { Events.AddHandler (LayoutStyleChangedEvent, value); }
940 remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
943 public event PaintEventHandler PaintGrip {
944 add { Events.AddHandler (PaintGripEvent, value); }
945 remove { Events.RemoveHandler (PaintGripEvent, value); }
948 public event EventHandler RendererChanged {
949 add { Events.AddHandler (RendererChangedEvent, value); }
950 remove { Events.RemoveHandler (RendererChangedEvent, value); }
954 #region Private Methods
955 private void DoAutoSize ()
957 if (this.AutoSize == true && this.Dock == DockStyle.None)
958 this.Size = GetPreferredSize (Size.Empty);
960 if (this.AutoSize == true && this.Orientation == Orientation.Horizontal && (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom))
961 this.Height = GetPreferredSize (Size.Empty).Height;
964 public override Size GetPreferredSize (Size proposedSize)
966 Size new_size = new Size (0, this.Height);
968 if (this.orientation == Orientation.Vertical) {
969 foreach (ToolStripItem tsi in this.items)
970 if (tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom > new_size.Height)
971 new_size.Height = tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom;
973 new_size.Height += this.Padding.Top + this.Padding.Bottom;
974 new_size.Width = this.Width;
976 foreach (ToolStripItem tsi in this.items)
978 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
979 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
981 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height))
982 new_size.Height = (this.Padding.Vertical + tsi_preferred.Height);
986 new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
990 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
992 if (this is MenuStrip && release && menu_selected)
993 (this as MenuStrip).FireMenuDeactivate ();
996 menu_selected = false;
998 NotifySelectedChanged (null);
1001 internal void NotifySelectedChanged (ToolStripItem tsi)
1003 foreach (ToolStripItem tsi2 in this.DisplayedItems)
1005 if (tsi2 is ToolStripDropDownItem)
1006 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1008 if (this.OverflowButton != null) {
1009 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1011 foreach (ToolStripItem tsi2 in tsic)
1013 if (tsi2 is ToolStripDropDownItem)
1014 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1016 this.OverflowButton.HideDropDown ();
1020 private void MouseEnteredItem (ToolStripItem item)
1022 if (this.show_item_tool_tips) {
1023 tooltip_currently_showing = item;
1024 ToolTipTimer.Start ();
1028 private void MouseLeftItem (ToolStripItem item)
1030 ToolTipTimer.Stop ();
1031 ToolTipWindow.Hide ();
1032 tooltip_currently_showing = null;
1035 private Timer ToolTipTimer {
1037 if (tooltip_timer == null) {
1038 tooltip_timer = new Timer ();
1039 tooltip_timer.Enabled = false;
1040 tooltip_timer.Interval = 500;
1041 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
1044 return tooltip_timer;
1048 private ToolTip.ToolTipWindow ToolTipWindow {
1050 if (tooltip_window == null)
1051 tooltip_window = new ToolTip.ToolTipWindow ();
1053 return tooltip_window;
1057 private void ToolTipTimer_Tick (object o, EventArgs args)
1059 string tooltip = tooltip_currently_showing.GetToolTip ();
1061 if (!string.IsNullOrEmpty (tooltip))
1062 ToolTipWindow.Present (this, tooltip);
1064 tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1066 ToolTipTimer.Stop ();