2007-04-02 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStrip.cs
1 //
2 // ToolStrip.cs
3 //
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:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
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.
22 //
23 // Copyright (c) 2006 Jonathan Pobst
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28
29 #if NET_2_0
30 using System;
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
33 using System.Drawing;
34 using System.Windows.Forms.Layout;
35
36 namespace System.Windows.Forms
37 {
38         [ComVisible (true)]
39         [ClassInterface (ClassInterfaceType.AutoDispatch)]
40         [DefaultEvent ("ItemClicked")]
41         [DefaultProperty ("Items")]
42         public class ToolStrip : ScrollableControl, IComponent, IDisposable
43         {
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;
65                 private bool stretch;
66
67                 private ToolStripItem mouse_currently_over;
68                 private bool menu_selected;
69                 private ToolStripItem tooltip_currently_showing;
70                 #endregion
71
72                 #region Public Constructors
73                 public ToolStrip () : this (null)
74                 {
75                 }
76
77                 public ToolStrip (params ToolStripItem[] items) : base ()
78                 {
79                         SetStyle (ControlStyles.AllPaintingInWmPaint, true);
80                         SetStyle (ControlStyles.OptimizedDoubleBuffer, true);
81                         SetStyle (ControlStyles.Selectable, false);
82                         SetStyle (ControlStyles.SupportsTransparentBackColor, true);
83
84                         this.SuspendLayout ();
85                         this.items = new ToolStripItemCollection (this, items);
86                         base.AutoSize = true;
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 ();
108                         DoAutoSize ();
109                         
110                         // Register with the ToolStripManager
111                         ToolStripManager.AddToolStrip (this);
112                 }
113                 #endregion
114
115                 #region Public Properties
116                 public override AnchorStyles Anchor {
117                         get { return base.Anchor; }
118                         set { base.Anchor = value; }
119                 }
120
121                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
122                 [Browsable (true)]
123                 [EditorBrowsable (EditorBrowsableState.Always)]
124                 [DefaultValue (true)]
125                 public override bool AutoSize {
126                         get { return base.AutoSize; }
127                         set { base.AutoSize = value; }
128                 }
129                 
130                 new public Color BackColor {
131                         get { return this.back_color; }
132                         set { this.back_color = value; }
133                 }
134
135                 [DefaultValue (true)]
136                 public bool CanOverflow {
137                         get { return this.can_overflow; }
138                         set { this.can_overflow = value; }
139                 }
140                 
141                 [Browsable (false)]
142                 [DefaultValue (false)]
143                 public new bool CausesValidation {
144                         get { return base.CausesValidation; }
145                         set { base.CausesValidation = value; }
146                 }
147                 
148                 [EditorBrowsable (EditorBrowsableState.Never)]
149                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
150                 public new ControlCollection Controls {
151                         get { return base.Controls; }
152                 }
153
154                 [Browsable (false)]
155                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
156                 public override Cursor Cursor {
157                         get { return base.Cursor; }
158                         set { base.Cursor = value; }
159                 }
160                 
161                 [Browsable (false)]
162                 public virtual ToolStripDropDownDirection DefaultDropDownDirection {
163                         get { return this.default_drop_down_direction; }
164                         set { 
165                                 if (!Enum.IsDefined (typeof (ToolStripDropDownDirection), value))
166                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripDropDownDirection", value));
167                                         
168                                 this.default_drop_down_direction = value;
169                         }
170                 }
171
172                 public override Rectangle DisplayRectangle {
173                         get {
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);
177                                         else
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);
179                                 else
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);
182                                         else
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);
184                         }
185                 }
186
187                 [DefaultValue (DockStyle.Top)]
188                 public override DockStyle Dock {
189                         get { return base.Dock; }
190                         set {
191                                 if (base.Dock != value) {
192                                         base.Dock = value;
193                                         
194                                         switch (value) {
195                                                 case DockStyle.Top:
196                                                 case DockStyle.Bottom:
197                                                 case DockStyle.None:
198                                                         this.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
199                                                         break;
200                                                 case DockStyle.Left:
201                                                 case DockStyle.Right:
202                                                         this.LayoutStyle = ToolStripLayoutStyle.VerticalStackWithOverflow;
203                                                         break;
204                                         }
205                                 }
206                         }
207                 }
208
209                 public override Font Font {
210                         get { return base.Font; }
211                         set { 
212                                 if (base.Font != value) {
213                                         base.Font = value;
214                                         
215                                         foreach (ToolStripItem tsi in this.Items)
216                                                 tsi.OnOwnerFontChanged (EventArgs.Empty);
217                                 }
218                          }
219                 }
220                 
221                 [Browsable (false)]
222                 public new Color ForeColor {
223                         get { return this.fore_color; }
224                         set { 
225                                 if (this.fore_color != value) {
226                                         this.fore_color = value; 
227                                         this.OnForeColorChanged (EventArgs.Empty); 
228                                 }
229                         }
230                 }
231
232                 [Browsable (false)]
233                 public ToolStripGripDisplayStyle GripDisplayStyle {
234                         get { return this.orientation == Orientation.Vertical ? ToolStripGripDisplayStyle.Horizontal : ToolStripGripDisplayStyle.Vertical; }
235                 }
236
237                 public Padding GripMargin {
238                         get { return this.grip_margin; }
239                         set { 
240                                 if (this.grip_margin != value) {
241                                         this.grip_margin = value; 
242                                         this.PerformLayout (); 
243                                 }
244                         }
245                 }
246
247                 [Browsable (false)]
248                 public Rectangle GripRectangle {
249                         get {
250                                 if (this.grip_style == ToolStripGripStyle.Hidden)
251                                         return Rectangle.Empty;
252
253                                 if (this.orientation == Orientation.Horizontal)
254                                         return new Rectangle (this.grip_margin.Left + this.Padding.Left, this.Padding.Top, 3, this.Height);
255                                 else
256                                         return new Rectangle (this.Padding.Left, this.grip_margin.Top + this.Padding.Top, this.Width, 3);
257                         }
258                 }
259
260                 [DefaultValue (ToolStripGripStyle.Visible)]
261                 public ToolStripGripStyle GripStyle {
262                         get { return this.grip_style; }
263                         set {
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 ();
269                                 }
270                         }
271                 }
272
273                 [Browsable (false)]
274                 [EditorBrowsable (EditorBrowsableState.Never)]
275                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
276                 public new bool HasChildren {
277                         get { return base.HasChildren; }
278                 }
279                 
280                 [Browsable (false)]
281                 [DefaultValue (null)]
282                 public ImageList ImageList {
283                         get { return this.image_list; }
284                         set { this.image_list = value; }
285                 }
286
287                 [DefaultValue ("{Width=16, Height=16}")]
288                 public Size ImageScalingSize {
289                         get { return this.image_scaling_size; }
290                         set { this.image_scaling_size = value; }
291                 }
292
293                 [MonoTODO ("Always returns false, dragging not implemented yet.")]
294                 [Browsable (false)]
295                 [EditorBrowsable (EditorBrowsableState.Advanced)]
296                 public bool IsCurrentlyDragging {
297                         get { return false; }
298                 }
299                 
300                 [Browsable (false)]
301                 public bool IsDropDown {
302                         get {
303                                 if (this is ToolStripDropDown)
304                                         return true;
305
306                                 return false;
307                         }
308                 }
309
310                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
311                 public virtual ToolStripItemCollection Items {
312                         get { return this.items; }
313                 }
314
315                 public override LayoutEngine LayoutEngine {
316                         get { 
317                                  if (layout_engine == null)
318                                         this.layout_engine = new ToolStripSplitStackLayout ();
319                                         
320                                  return this.layout_engine;
321                         }
322                 }
323
324                 [Browsable (false)]
325                 [DefaultValue (null)]
326                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
327                 public LayoutSettings LayoutSettings {
328                         get { return this.layout_settings; }
329                         set { this.layout_settings = value; }
330                 }
331                 
332                 [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
333                 public ToolStripLayoutStyle LayoutStyle {
334                         get { return layout_style; }
335                         set {
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));
339
340                                         this.layout_style = value;
341
342                                         if (this.layout_style == ToolStripLayoutStyle.Flow)
343                                                 this.layout_engine = new FlowLayout ();
344                                         else
345                                                 this.layout_engine = new ToolStripSplitStackLayout ();
346
347                                         if (this.layout_style == ToolStripLayoutStyle.StackWithOverflow) {
348                                                 if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
349                                                         this.layout_style = ToolStripLayoutStyle.VerticalStackWithOverflow;
350                                                 else
351                                                         this.layout_style = ToolStripLayoutStyle.HorizontalStackWithOverflow;
352                                         }
353
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;
358                                                 
359                                         this.layout_settings = this.CreateLayoutSettings (value);
360                                         
361                                         this.PerformLayout ();
362                                         this.OnLayoutStyleChanged (EventArgs.Empty);
363                                 }
364                         }
365                 }
366
367                 [Browsable (false)]
368                 public Orientation Orientation {
369                         get { return this.orientation; }
370                 }
371
372                 [Browsable (false)]
373                 [EditorBrowsable (EditorBrowsableState.Advanced)]
374                 public ToolStripOverflowButton OverflowButton {
375                         get { return this.overflow_button; }
376                 }
377                 
378                 [Browsable (false)]
379                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
380                 public ToolStripRenderer Renderer {
381                         get { 
382                                 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
383                                         return ToolStripManager.Renderer;
384                                         
385                                 return this.renderer; 
386                         }
387                         set { 
388                                 if (this.renderer != value) {
389                                         this.renderer = value; 
390                                         this.render_mode = ToolStripRenderMode.Custom;
391                                         this.PerformLayout ();
392                                         this.OnRendererChanged (EventArgs.Empty);
393                                 }
394                         }
395                 }
396
397                 public ToolStripRenderMode RenderMode {
398                         get { return this.render_mode; }
399                         set {
400                                 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
401                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
402
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 ();
407
408                                 this.render_mode = value;
409                         }
410                 }
411
412                 [DefaultValue (true)]
413                 public bool ShowItemToolTips {
414                         get { return this.show_item_tool_tips; }
415                         set { this.show_item_tool_tips = value; }
416                 }
417                 
418                 [DefaultValue (false)]
419                 public bool Stretch {
420                         get { return this.stretch; }
421                         set { this.stretch = value; }
422                 }
423                 
424                 [DefaultValue (false)]
425                 [DispId(-516)]
426                 public new bool TabStop {
427                         get { return base.TabStop; }
428                         set { base.TabStop = value; }
429                 }
430                 #endregion
431
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; } }
440                 #endregion
441
442                 #region Public Methods
443                 [Browsable (false)]
444                 public new Control GetChildAtPoint (Point point)
445                 {
446                         return base.GetChildAtPoint (point);
447                 }
448                 
449                 public ToolStripItem GetItemAt (Point point)
450                 {
451                         foreach (ToolStripItem tsi in this.displayed_items)
452                                 if (tsi.Visible && tsi.Bounds.Contains (point))
453                                         return tsi;
454
455                         return null;
456                 }
457
458                 public ToolStripItem GetItemAt (int x, int y)
459                 {
460                         return GetItemAt (new Point (x, y));
461                 }
462
463                 public virtual ToolStripItem GetNextItem (ToolStripItem start, ArrowDirection direction)
464                 {
465                         if (!Enum.IsDefined (typeof (ArrowDirection), direction))
466                                 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ArrowDirection", direction));
467
468                         int index = this.items.IndexOf (start);
469
470                         switch (direction) {
471                                 case ArrowDirection.Left:
472                                 case ArrowDirection.Up:
473                                         if (index > 0)
474                                                 return this.items[index - 1];
475         
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];
481
482                                         return this.items[index + 1];
483                         }
484
485                         return null;
486                 }
487
488                 public override string ToString ()
489                 {
490                         return String.Format ("{0}, Name: {1}, Items: {2}", base.ToString(), this.Name, this.items.Count.ToString ());
491                 }
492                 #endregion
493
494                 #region Protected Methods
495                 protected override AccessibleObject CreateAccessibilityInstance ()
496                 {
497                         AccessibleObject ao = new AccessibleObject (this);
498                         
499                         ao.role = AccessibleRole.ToolBar;
500                         
501                         return ao;
502                 }
503                 
504                 protected override ControlCollection CreateControlsInstance ()
505                 {
506                         return base.CreateControlsInstance ();
507                 }
508
509                 protected internal virtual ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick)
510                 {
511                         if (text == "-")
512                                 return new ToolStripSeparator ();
513
514                         if (this is ToolStripDropDown)
515                                 return new ToolStripMenuItem (text, image, onClick);
516                                 
517                         return new ToolStripButton (text, image, onClick);
518                 }
519
520                 protected virtual LayoutSettings CreateLayoutSettings (ToolStripLayoutStyle layoutStyle)
521                 {
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:
530                                 default:
531                                         return null;
532                         }
533                 }
534                 
535                 protected override void Dispose (bool disposing)
536                 {
537                         if (!IsDisposed) {
538                                 ToolStripManager.RemoveToolStrip (this);
539                                 base.Dispose (disposing);
540                         }
541                 }
542                 
543                 protected override void OnDockChanged (EventArgs e)
544                 {
545                         base.OnDockChanged (e);
546                 }
547
548                 protected override void OnEnabledChanged (EventArgs e)
549                 {
550                         base.OnEnabledChanged (e);
551                         
552                         foreach (ToolStripItem tsi in this.Items)
553                                 tsi.OnParentEnabledChanged (EventArgs.Empty);
554                 }
555
556                 protected override void OnFontChanged (EventArgs e)
557                 {
558                         base.OnFontChanged (e);
559                 }
560
561                 protected override void OnHandleCreated (EventArgs e)
562                 {
563                         base.OnHandleCreated (e);
564                 }
565
566                 protected override void OnHandleDestroyed (EventArgs e)
567                 {
568                         base.OnHandleDestroyed (e);
569                 }
570
571                 protected override void OnInvalidated (InvalidateEventArgs e)
572                 {
573                         base.OnInvalidated (e);
574                 }
575
576                 protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
577                 {
578                         e.Item.Available = true;
579                         e.Item.SetPlacement (ToolStripItemPlacement.Main);
580                         this.DoAutoSize ();
581                         this.PerformLayout ();
582                         
583                         ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
584                         if (eh != null)
585                                 eh (this, e);
586                 }
587
588                 protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
589                 {
590                         ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
591                         if (eh != null)
592                                 eh (this, e);
593                 }
594
595                 protected internal virtual void OnItemRemoved (ToolStripItemEventArgs e)
596                 {
597                         ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemRemovedEvent]);
598                         if (eh != null)
599                                 eh (this, e);
600                 }
601
602                 protected override void OnLayout (LayoutEventArgs e)
603                 {
604                         DoAutoSize ();
605                         base.OnLayout (e);
606
607                         this.SetDisplayedItems ();
608                         this.OnLayoutCompleted (EventArgs.Empty);
609                         this.Invalidate ();
610                 }
611
612                 protected virtual void OnLayoutCompleted (EventArgs e)
613                 {
614                         EventHandler eh = (EventHandler)(Events [LayoutCompletedEvent]);
615                         if (eh != null)
616                                 eh (this, e);
617                 }
618
619                 protected virtual void OnLayoutStyleChanged (EventArgs e)
620                 {
621                         EventHandler eh = (EventHandler)(Events[LayoutStyleChangedEvent]);
622                         if (eh != null)
623                                 eh (this, e);
624                 }
625
626                 protected override void OnLeave (EventArgs e)
627                 {
628                         base.OnLeave (e);
629                 }
630
631                 protected override void OnLostFocus (EventArgs e)
632                 {
633                         base.OnLostFocus (e);
634                 }
635
636                 protected override void OnMouseDown (MouseEventArgs mea)
637                 {
638                         if (mouse_currently_over != null)
639                         {
640                                 if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
641                                         if (!menu_selected)
642                                                 (this as MenuStrip).FireMenuActivate ();
643                                         
644                                         return;
645                                 }
646                                         
647                                 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
648                                 
649                                 if (this is MenuStrip && !menu_selected) {
650                                         (this as MenuStrip).FireMenuActivate ();
651                                         menu_selected = true;                           
652                                 }
653                         } else {
654                                 if (this is MenuStrip)
655                                         this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
656                         }
657                         
658                         if (this is MenuStrip)
659                                 this.Capture = false;
660
661                         base.OnMouseDown (mea);
662                 }
663
664                 protected override void OnMouseLeave (EventArgs e)
665                 {
666                         if (mouse_currently_over != null) {
667                                 MouseLeftItem (mouse_currently_over);
668                                 mouse_currently_over.FireEvent (e, ToolStripItemEventType.MouseLeave);
669                                 mouse_currently_over = null;
670                         }
671
672                         base.OnMouseLeave (e);
673                 }
674
675                 protected override void OnMouseMove (MouseEventArgs mea)
676                 {
677                         ToolStripItem tsi;
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;
681                         else
682                                 tsi = this.GetItemAt (mea.X, mea.Y);
683
684                         if (tsi != null) {
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);
688                                 else {
689                                         // If we were over a different item, fire a mouse leave on it
690                                         if (mouse_currently_over != null) {
691                                                 MouseLeftItem (tsi);
692                                                 mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
693                                         }
694                                         
695                                         // Set the new item we are currently over
696                                         mouse_currently_over = tsi;
697                                         
698                                         // Fire mouse enter and mouse move
699                                         tsi.FireEvent (mea, ToolStripItemEventType.MouseEnter);
700                                         MouseEnteredItem (tsi);
701                                         tsi.FireEvent (mea, ToolStripItemEventType.MouseMove);
702
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 ();
706                                 }
707                         } else {
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) {
710                                         MouseLeftItem (tsi);
711                                         mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseLeave);
712                                         mouse_currently_over = null;
713                                 }
714                         }
715                         
716                         base.OnMouseMove (mea);
717                 }
718
719                 protected override void OnMouseUp (MouseEventArgs mea)
720                 {
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);
725
726                                 // The event handler may have blocked until the mouse moved off of the ToolStripItem
727                                 if (mouse_currently_over == null)
728                                         return;
729                                         
730                                 // Fire our ItemClicked event
731                                 OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
732                         }
733
734                         base.OnMouseUp (mea);
735                 }
736
737                 protected override void OnPaint (PaintEventArgs e)
738                 {
739                         base.OnPaint (e);
740
741                         // Draw the grip
742                         this.OnPaintGrip (e);
743
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 ();
749                         }
750
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 ();
756                         }
757
758                         Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
759                         Rectangle connected_area = Rectangle.Empty;
760
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);
763
764                         ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
765                         pevent.InternalConnectedArea = connected_area;
766
767                         this.Renderer.DrawToolStripBorder (pevent);
768                 }
769
770                 [EditorBrowsable (EditorBrowsableState.Advanced)]
771                 protected override void OnPaintBackground (PaintEventArgs pevent)
772                 {
773                         base.OnPaintBackground (pevent);
774
775                         Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
776                         Rectangle connected_area = Rectangle.Empty;
777
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);
780                         
781                         ToolStripRenderEventArgs e = new ToolStripRenderEventArgs (pevent.Graphics, this, affected_bounds, Color.Empty);
782                         e.InternalConnectedArea = connected_area;
783                         
784                         this.Renderer.DrawToolStripBackground (e);
785                 }
786
787                 protected internal virtual void OnPaintGrip (PaintEventArgs e)
788                 {
789                         // Never draw a grip with these two layouts
790                         if (this.layout_style == ToolStripLayoutStyle.Flow || this.layout_style == ToolStripLayoutStyle.Table)
791                                 return;
792                         
793                         PaintEventHandler eh = (PaintEventHandler)(Events [PaintGripEvent]);
794                         if (eh != null)
795                                 eh (this, e);
796
797                         if (!(this is MenuStrip)) {
798                                 if (this.orientation == Orientation.Horizontal)
799                                         e.Graphics.TranslateTransform (2, 0);
800                                 else
801                                         e.Graphics.TranslateTransform (0, 2);
802                         }
803
804                         this.Renderer.DrawGrip (new ToolStripGripRenderEventArgs (e.Graphics, this, this.GripRectangle, this.GripDisplayStyle, this.grip_style));
805                         e.Graphics.ResetTransform ();
806                 }
807
808                 protected virtual void OnRendererChanged (EventArgs e)
809                 {
810                         EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
811                         if (eh != null)
812                                 eh (this, e);
813                 }
814
815                 [EditorBrowsable (EditorBrowsableState.Advanced)]
816                 protected override void OnRightToLeftChanged (EventArgs e)
817                 {
818                         base.OnRightToLeftChanged (e);
819                 }
820
821                 protected override void OnTabStopChanged (EventArgs e)
822                 {
823                         base.OnTabStopChanged (e);
824                 }
825
826                 protected override void OnVisibleChanged (EventArgs e)
827                 {
828                         base.OnVisibleChanged (e);
829                 }
830
831                 protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
832                 {
833                         return base.ProcessCmdKey (ref msg, keyData);
834                 }
835                 
836                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
837                 {
838                         base.SetBoundsCore (x, y, width, height, specified);
839                 }
840
841                 protected virtual void SetDisplayedItems ()
842                 {
843                         this.displayed_items.Clear ();
844                         
845                         foreach (ToolStripItem tsi in this.items)
846                                 if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
847                                         this.displayed_items.AddNoOwnerOrLayout (tsi);
848                                         tsi.Parent = this; 
849                                 }
850                                 else if (tsi.Placement == ToolStripItemPlacement.Overflow)
851                                         tsi.Parent = this.OverflowButton.DropDown; 
852                         
853                         if (this.OverflowButton != null)
854                                 this.OverflowButton.DropDown.SetDisplayedItems ();
855                 }
856
857                 protected internal void SetItemLocation (ToolStripItem item, Point location)
858                 {
859                         if (item == null)
860                                 throw new ArgumentNullException ("item");
861                                 
862                         if (item.Owner != this)
863                                 throw new NotSupportedException ("The item is not owned by this ToolStrip");
864                                 
865                         item.SetBounds (new Rectangle (location, item.Size));
866                 }
867                 
868                 protected static void SetItemParent (ToolStripItem item, ToolStrip parent)
869                 {
870                         item.Parent = parent;
871                 }
872
873                 protected override void SetVisibleCore (bool value)
874                 {
875                         base.SetVisibleCore (value);
876                 }
877
878                 protected override void WndProc (ref Message m)
879                 {
880                         base.WndProc (ref m);
881                 }
882                 #endregion
883
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 ();
892
893                 [Browsable (true)]
894                 [EditorBrowsable (EditorBrowsableState.Always)]
895                 public new event EventHandler AutoSizeChanged {
896                         add { base.AutoSizeChanged += value; }
897                         remove { base.AutoSizeChanged -= value; }
898                 }
899
900                 [Browsable (false)]
901                 public new event EventHandler CausesValidationChanged {
902                         add { base.CausesValidationChanged += value; }
903                         remove { base.CausesValidationChanged -= value; }
904                 }
905
906                 [Browsable (false)]
907                 public new event EventHandler CursorChanged {
908                         add { base.CursorChanged += value; }
909                         remove { base.CursorChanged -= value; }
910                 }
911
912                 [Browsable (false)]
913                 public new event EventHandler ForeColorChanged {
914                         add { base.ForeColorChanged += value; }
915                         remove { base.ForeColorChanged -= value; }
916                 }
917
918                 public event ToolStripItemEventHandler ItemAdded {
919                         add { Events.AddHandler (ItemAddedEvent, value); }
920                         remove { Events.RemoveHandler (ItemAddedEvent, value); }
921                 }
922
923                 public event ToolStripItemClickedEventHandler ItemClicked {
924                         add { Events.AddHandler (ItemClickedEvent, value); }
925                         remove { Events.RemoveHandler (ItemClickedEvent, value); }
926                 }
927
928                 public event ToolStripItemEventHandler ItemRemoved {
929                         add { Events.AddHandler (ItemRemovedEvent, value); }
930                         remove { Events.RemoveHandler (ItemRemovedEvent, value); }
931                 }
932
933                 public event EventHandler LayoutCompleted {
934                         add { Events.AddHandler (LayoutCompletedEvent, value); }
935                         remove { Events.RemoveHandler (LayoutCompletedEvent, value); }
936                 }
937
938                 public event EventHandler LayoutStyleChanged {
939                         add { Events.AddHandler (LayoutStyleChangedEvent, value); }
940                         remove { Events.RemoveHandler (LayoutStyleChangedEvent, value); }
941                 }
942
943                 public event PaintEventHandler PaintGrip {
944                         add { Events.AddHandler (PaintGripEvent, value); }
945                         remove { Events.RemoveHandler (PaintGripEvent, value); }
946                 }
947
948                 public event EventHandler RendererChanged {
949                         add { Events.AddHandler (RendererChangedEvent, value); }
950                         remove { Events.RemoveHandler (RendererChangedEvent, value); }
951                 }
952                 #endregion
953
954                 #region Private Methods
955                 private void DoAutoSize ()
956                 {
957                         if (this.AutoSize == true && this.Dock == DockStyle.None)
958                                 this.Size = GetPreferredSize (Size.Empty);
959                                 
960                         if (this.AutoSize == true && this.Orientation == Orientation.Horizontal && (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom))
961                                 this.Height = GetPreferredSize (Size.Empty).Height;
962                 }
963
964                 public override Size GetPreferredSize (Size proposedSize)
965                 {
966                         Size new_size = new Size (0, this.Height);
967
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;
972
973                                 new_size.Height += this.Padding.Top + this.Padding.Bottom;
974                                 new_size.Width = this.Width;
975                         } else {
976                                 foreach (ToolStripItem tsi in this.items) 
977                                         if (tsi.Available) {
978                                                 Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
979                                                 new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
980                                                 
981                                                 if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height))
982                                                         new_size.Height = (this.Padding.Vertical + tsi_preferred.Height);
983                                         }
984                         }
985
986                         new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
987                         return new_size;
988                 }
989                 
990                 internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
991                 {
992                         if (this is MenuStrip && release && menu_selected)
993                                 (this as MenuStrip).FireMenuDeactivate ();
994                                 
995                         if (release)
996                                 menu_selected = false;
997                                 
998                         NotifySelectedChanged (null);
999                 }
1000
1001                 internal void NotifySelectedChanged (ToolStripItem tsi)
1002                 {
1003                         foreach (ToolStripItem tsi2 in this.DisplayedItems)
1004                                 if (tsi != tsi2)
1005                                         if (tsi2 is ToolStripDropDownItem)
1006                                                 (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1007
1008                         if (this.OverflowButton != null) {
1009                                 ToolStripItemCollection tsic = this.OverflowButton.DropDown.DisplayedItems;
1010                                 
1011                                 foreach (ToolStripItem tsi2 in tsic)
1012                                         if (tsi != tsi2)
1013                                                 if (tsi2 is ToolStripDropDownItem)
1014                                                         (tsi2 as ToolStripDropDownItem).HideDropDown (ToolStripDropDownCloseReason.Keyboard);
1015                         
1016                                 this.OverflowButton.HideDropDown ();
1017                         }
1018                 }
1019                 
1020                 private void MouseEnteredItem (ToolStripItem item)
1021                 {
1022                         if (this.show_item_tool_tips) {
1023                                 tooltip_currently_showing = item;
1024                                 ToolTipTimer.Start ();
1025                         }
1026                 }
1027                 
1028                 private void MouseLeftItem (ToolStripItem item)
1029                 {
1030                         ToolTipTimer.Stop ();
1031                         ToolTipWindow.Hide ();
1032                         tooltip_currently_showing = null;
1033                 }
1034                 
1035                 private Timer ToolTipTimer {
1036                         get {
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);
1042                                 }
1043                                 
1044                                 return tooltip_timer;
1045                         }
1046                 }
1047                 
1048                 private ToolTip.ToolTipWindow ToolTipWindow {
1049                         get {
1050                                 if (tooltip_window == null)
1051                                         tooltip_window = new ToolTip.ToolTipWindow ();
1052                                         
1053                                 return tooltip_window;
1054                         }
1055                 }
1056                 
1057                 private void ToolTipTimer_Tick (object o, EventArgs args)
1058                 {
1059                         string tooltip = tooltip_currently_showing.GetToolTip ();
1060                         
1061                         if (!string.IsNullOrEmpty (tooltip))
1062                                 ToolTipWindow.Present (this, tooltip);
1063
1064                         tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
1065
1066                         ToolTipTimer.Stop ();
1067                 }
1068                 #endregion
1069         }
1070 }
1071 #endif