2007-04-26 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStripItem.cs
1 //
2 // ToolStripItem.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 #if NET_2_0
29
30 using System;
31 using System.Drawing;
32 using System.ComponentModel;
33
34 namespace System.Windows.Forms
35 {
36         [DefaultEvent ("Click")]
37         [DefaultProperty ("Text")]
38         [DesignTimeVisible (false)]
39         [ToolboxItem (false)]
40         public abstract class ToolStripItem : Component, IDropTarget, IComponent, IDisposable
41         {
42                 #region Private Variables
43                 private AccessibleObject accessibility_object;
44                 private string accessible_default_action_description;
45                 private bool allow_drop;
46                 private ToolStripItemAlignment alignment;
47                 private AnchorStyles anchor;
48                 private bool available;
49                 private bool auto_size;
50                 private bool auto_tool_tip;
51                 private Color back_color;
52                 private Image background_image;
53                 private ImageLayout background_image_layout;
54                 private Rectangle bounds;
55                 private bool can_select;
56                 private ToolStripItemDisplayStyle display_style;
57                 private DockStyle dock;
58                 private bool double_click_enabled;
59                 private bool enabled;
60                 private Size explicit_size;
61                 private Font font;
62                 private Color fore_color;
63                 private Image image;
64                 private ContentAlignment image_align;
65                 private int image_index;
66                 private string image_key;
67                 private ToolStripItemImageScaling image_scaling;
68                 private Color image_transparent_color;
69                 private bool is_disposed;
70                 internal bool is_pressed;
71                 private bool is_selected;
72                 private Padding margin;
73                 private MergeAction merge_action;
74                 private int merge_index;
75                 private string name;
76                 private ToolStripItemOverflow overflow;
77                 private ToolStrip owner;
78                 internal ToolStripItem owner_item;
79                 private Padding padding;
80                 private ToolStripItemPlacement placement;
81                 private RightToLeft right_to_left;
82                 private bool right_to_left_auto_mirror_image;
83                 private Object tag;
84                 private string text;
85                 private ContentAlignment text_align;
86                 private TextImageRelation text_image_relation;
87                 private string tool_tip_text;
88                 private bool visible;
89
90                 private ToolStrip parent;
91                 private Size text_size;
92                 #endregion
93
94                 #region Public Constructors
95                 protected ToolStripItem ()
96                         : this (String.Empty, null, null, String.Empty)
97                 {
98                 }
99
100                 protected ToolStripItem (string text, Image image, EventHandler onClick)
101                         : this (text, image, onClick, String.Empty)
102                 {
103                 }
104
105                 protected ToolStripItem (string text, Image image, EventHandler onClick, string name)
106                 {
107                         this.alignment = ToolStripItemAlignment.Left;
108                         this.anchor = AnchorStyles.Left | AnchorStyles.Top;
109                         this.auto_size = true;
110                         this.auto_tool_tip = this.DefaultAutoToolTip;
111                         this.available = true;
112                         this.back_color = Control.DefaultBackColor;
113                         this.background_image_layout = ImageLayout.Tile;
114                         this.can_select = true;
115                         this.display_style = this.DefaultDisplayStyle;
116                         this.dock = DockStyle.None;
117                         this.enabled = true;
118                         this.font = new Font ("Tahoma", 8.25f);
119                         this.fore_color = Control.DefaultForeColor;
120                         this.image = image;
121                         this.image_align = ContentAlignment.MiddleCenter;
122                         this.image_index = -1;
123                         this.image_key = string.Empty;
124                         this.image_scaling = ToolStripItemImageScaling.SizeToFit;
125                         this.image_transparent_color = Color.Empty;
126                         this.margin = this.DefaultMargin;
127                         this.merge_action = MergeAction.Append;
128                         this.merge_index = -1;
129                         this.name = name;
130                         this.overflow = ToolStripItemOverflow.AsNeeded;
131                         this.padding = this.DefaultPadding;
132                         this.placement = ToolStripItemPlacement.None;
133                         this.right_to_left = RightToLeft.Inherit;
134                         this.bounds.Size = this.DefaultSize;
135                         this.text = text;
136                         this.text_align = ContentAlignment.MiddleCenter;
137                         this.text_image_relation = TextImageRelation.ImageBeforeText;
138                         this.visible = true;
139
140                         this.Click += onClick;
141                         OnLayout (new LayoutEventArgs (null, string.Empty));
142                 }
143                 #endregion
144
145                 #region Public Properties
146                 [Browsable (false)]
147                 [EditorBrowsable (EditorBrowsableState.Advanced)]
148                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
149                 public AccessibleObject AccessibilityObject {
150                         get { 
151                                 if (this.accessibility_object == null)
152                                         this.accessibility_object = CreateAccessibilityInstance ();
153                                         
154                                 return this.accessibility_object;
155                         }
156                 }
157
158                 [Browsable (false)]
159                 [EditorBrowsable (EditorBrowsableState.Advanced)]
160                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
161                 public string AccessibleDefaultActionDescription {
162                         get {
163                                 if (this.accessibility_object == null)
164                                         return null;
165                                 
166                                 return this.accessible_default_action_description;
167                         }
168                         set { this.accessible_default_action_description = value; }
169                 }
170
171                 [Localizable (true)]
172                 [DefaultValue (null)]
173                 public string AccessibleDescription {
174                         get {
175                                 if (this.accessibility_object == null)
176                                         return null;
177                                 
178                                 return this.AccessibilityObject.Description;
179                         }
180                         set { this.AccessibilityObject.description = value; }
181                 }
182
183                 [Localizable (true)]
184                 [DefaultValue (null)]
185                 public string AccessibleName {
186                         get { 
187                                 if (this.accessibility_object == null)
188                                         return null;
189                                         
190                                 return this.AccessibilityObject.Name; 
191                         }
192                         set { this.AccessibilityObject.Name = value; }
193                 }
194                 
195                 [DefaultValue (AccessibleRole.Default)]
196                 public AccessibleRole AccessibleRole {
197                         get
198                         {
199                                 if (this.accessibility_object == null)
200                                         return AccessibleRole.Default;
201                                 
202                                 return this.AccessibilityObject.Role;
203                         }
204                         set { this.AccessibilityObject.role = value; }
205                 }
206                 
207                 [DefaultValue (ToolStripItemAlignment.Left)]
208                 public ToolStripItemAlignment Alignment {
209                         get { return this.alignment; }
210                         set {
211                                 if (!Enum.IsDefined (typeof (ToolStripItemAlignment), value))
212                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemAlignment", value));
213
214                                 this.alignment = value;
215                         }
216                 }
217
218                 [MonoTODO]
219                 public virtual bool AllowDrop {
220                         get {
221                                 return this.allow_drop;
222                         }
223                         
224                         set {
225                                 this.allow_drop = value;
226                         }
227                 }
228                 
229                 [Browsable (false)]
230                 [DefaultValue (AnchorStyles.Top | AnchorStyles.Left)]
231                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
232                 public AnchorStyles Anchor {
233                         get { return this.anchor; }
234                         set { this.anchor = value; }
235                 }
236                         
237                 [Localizable (true)]
238                 [DefaultValue (true)]
239                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
240                 [RefreshProperties (RefreshProperties.All)]
241                 public bool AutoSize {
242                         get { return this.auto_size; }
243                         set { 
244                                 this.auto_size = value; 
245                                 this.CalculateAutoSize (); 
246                         }
247                 }
248
249                 [DefaultValue (false)]
250                 public bool AutoToolTip {
251                         get { return this.auto_tool_tip; }
252                         set { this.auto_tool_tip = value; }
253                 }
254
255                 [Browsable (false)]
256                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
257                 public bool Available {
258                         get { return this.available; }
259                         set {
260                                 if (this.available != value) {
261                                         available = value;
262                                         visible = value;
263
264                                         if (this.parent != null)
265                                                 parent.PerformLayout (); 
266                                                 
267                                         OnAvailableChanged (EventArgs.Empty); 
268                                         OnVisibleChanged (EventArgs.Empty);
269                                 }
270                         }
271                 }
272
273                 public virtual Color BackColor {
274                         get { return this.back_color; }
275                         set {
276                                 if (this.back_color != value) {
277                                         back_color = value;
278                                         OnBackColorChanged (EventArgs.Empty);
279                                         this.Invalidate ();
280                                 }
281                         }
282                 }
283
284                 [Localizable (true)]
285                 [DefaultValue (null)]
286                 public virtual Image BackgroundImage {
287                         get { return this.background_image; }
288                         set { 
289                                 if (this.background_image != value) {
290                                         this.background_image = value;
291                                         this.Invalidate ();
292                                 }
293                         }
294                 }
295
296                 [Localizable (true)]
297                 [DefaultValue (ImageLayout.Tile)]
298                 public virtual ImageLayout BackgroundImageLayout {
299                         get { return this.background_image_layout; }
300                         set { 
301                                 if (this.background_image_layout != value) {
302                                         this.background_image_layout = value;
303                                         this.Invalidate (); 
304                                 }
305                         }
306                 }
307
308                 [Browsable (false)]
309                 public virtual Rectangle Bounds {
310                         get { return this.bounds; }
311                 }
312
313                 [Browsable (false)]
314                 public virtual bool CanSelect {
315                         get { return this.can_select; }
316                 }
317
318                 [Browsable (false)]
319                 public Rectangle ContentRectangle {
320                         get {
321                                 // ToolStripLabels don't have a border
322                                 if (this is ToolStripLabel || this is ToolStripStatusLabel)
323                                         return new Rectangle (0, 0, this.bounds.Width, this.bounds.Height);
324
325                                 if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow)
326                                         return new Rectangle (2, 2, this.bounds.Width - 13, this.bounds.Height - 4);
327
328                                 return new Rectangle (2, 2, this.bounds.Width - 4, this.bounds.Height - 4);
329                         }
330                 }
331
332                 public virtual ToolStripItemDisplayStyle DisplayStyle {
333                         get { return this.display_style; }
334                         set {
335                                 if (this.display_style != value) {
336                                         this.display_style = value; 
337                                         this.CalculateAutoSize (); 
338                                         OnDisplayStyleChanged (EventArgs.Empty);
339                                         if (this.Parent != null)
340                                                 this.Parent.PerformLayout ();
341                                 }
342                         }
343                 }
344
345                 public bool IsDisposed {
346                         get { return this.is_disposed; }
347                 }
348                 
349                 [Browsable (false)]
350                 [DefaultValue (DockStyle.None)]
351                 public DockStyle Dock {
352                         get { return this.dock; }
353                         set {
354                                 if (this.dock != value) {
355                                         if (!Enum.IsDefined (typeof (DockStyle), value))
356                                                 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value));
357
358                                         this.dock = value;
359                                         this.CalculateAutoSize ();
360                                 }
361                         }
362                 }
363
364                 [DefaultValue (false)]
365                 public bool DoubleClickEnabled {
366                         get { return this.double_click_enabled; }
367                         set { this.double_click_enabled = value; }
368                 }
369
370                 [Localizable (true)]
371                 [DefaultValue (true)]
372                 public virtual bool Enabled {
373                         get { return enabled; }
374                         set { 
375                                 if (this.enabled != value) {
376                                         this.enabled = value; 
377                                         OnEnabledChanged (EventArgs.Empty); 
378                                         this.Invalidate ();
379                                 }
380                         }
381                 }
382
383                 [Localizable (true)]
384                 public virtual Font Font
385                 {
386                         get { return this.font; }
387                         set { 
388                                 if (this.font != value) {
389                                         this.font = value; 
390                                         this.CalculateAutoSize (); 
391                                         this.OnFontChanged (EventArgs.Empty); 
392                                         this.Invalidate ();
393                                 }
394                         }
395                 }
396
397                 public virtual Color ForeColor {
398                         get { return this.fore_color; }
399                         set { 
400                                 if (this.fore_color != value) {
401                                         this.fore_color = value; 
402                                         this.OnForeColorChanged (EventArgs.Empty); 
403                                         this.Invalidate ();
404                                 }
405                         }
406                 }
407
408                 [Browsable (false)]
409                 [EditorBrowsable (EditorBrowsableState.Always)]
410                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
411                 public int Height {
412                         get { return this.Size.Height; }
413                         set { 
414                                 this.bounds.Height = value; 
415                                 this.explicit_size.Height = value;
416                                 
417                                 if (this.Visible) {
418                                         this.CalculateAutoSize ();
419                                         this.OnBoundsChanged ();
420                                         this.Invalidate (); 
421                                 } 
422                         }
423                 }
424
425                 [Localizable (true)]
426                 public virtual Image Image {
427                         get { 
428                                 if (this.image != null)
429                                         return this.image;
430                                         
431                                 if (this.image_index >= 0)
432                                         if (this.owner != null && this.owner.ImageList != null)
433                                                 return this.owner.ImageList.Images[this.image_index];
434
435
436                                 if (!string.IsNullOrEmpty (this.image_key))
437                                         if (this.owner != null && this.owner.ImageList != null)
438                                                 return this.owner.ImageList.Images[this.image_key];
439                                                 
440                                 return null;
441                         }
442                         set {
443                                 if (this.image != value) {
444                                         this.image = value; 
445                                         this.image_index = -1;
446                                         this.image_key = string.Empty;
447                                         this.CalculateAutoSize (); 
448                                         this.Invalidate ();
449                                 }
450                         }
451                 }
452
453                 [Localizable (true)]
454                 [DefaultValue (ContentAlignment.MiddleCenter)]
455                 public ContentAlignment ImageAlign {
456                         get { return this.image_align; }
457                         set {
458                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
459                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
460
461                                 this.image_align = value;
462                                 this.Invalidate ();
463                         }
464                 }
465
466                 [Localizable (true)]
467                 [Browsable (false)]
468                 [RelatedImageList ("Owner.ImageList")]
469                 [RefreshProperties (RefreshProperties.Repaint)]
470                 public int ImageIndex {
471                         get { return this.image_index; }
472                         set {
473                                 if (this.image_index != value) {
474                                         // Lamespec: MSDN says ArgumentException, tests say otherwise
475                                         if (value < -1)
476                                                 throw new ArgumentOutOfRangeException ("ImageIndex cannot be less than -1");
477
478                                         this.image_index = value;
479                                         this.image = null;
480                                         this.image_key = string.Empty;
481                                         this.CalculateAutoSize ();
482                                         this.Invalidate ();
483                                 }
484                         }
485                 }
486
487                 [Localizable (true)]
488                 [Browsable (false)]
489                 [RelatedImageList ("Owner.ImageList")]
490                 [RefreshProperties (RefreshProperties.Repaint)]
491                 public string ImageKey
492                 {
493                         get { return this.image_key; }
494                         set { 
495                                 if (this.image_key != value) {
496                                         this.image = null;
497                                         this.image_index = -1;
498                                         this.image_key = value;
499                                         this.CalculateAutoSize ();
500                                         this.Invalidate ();
501                                 }
502                         }
503                 }
504                 
505                 [Localizable (true)]
506                 [DefaultValue (ToolStripItemImageScaling.SizeToFit)]
507                 public ToolStripItemImageScaling ImageScaling {
508                         get { return this.image_scaling; }
509                         set { 
510                                 this.image_scaling = value; 
511                                 this.CalculateAutoSize (); 
512                                 this.Invalidate (); 
513                         }
514                 }
515
516                 [Localizable (true)]
517                 public Color ImageTransparentColor {
518                         get { return this.image_transparent_color; }
519                         set { this.image_transparent_color = value; }
520                 }
521                 
522                 [Browsable (false)]
523                 public bool IsOnDropDown {
524                         get {
525                                 if (this.parent != null && this.parent is ToolStripDropDown)
526                                         return true;
527
528                                 return false;
529                         }
530                 }
531
532                 [Browsable (false)]
533                 public bool IsOnOverflow {
534                         get { return this.placement == ToolStripItemPlacement.Overflow; }
535                 }
536                 
537                 public Padding Margin {
538                         get { return this.margin; }
539                         set {
540                                 this.margin = value; 
541                                 this.CalculateAutoSize ();
542                         }
543                 }
544
545                 [DefaultValue (MergeAction.Append)]
546                 public MergeAction MergeAction {
547                         get { return this.merge_action; }
548                         set {
549                                 if (!Enum.IsDefined (typeof (MergeAction), value))
550                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for MergeAction", value));
551                                         
552                                 this.merge_action = value;
553                         }
554                 }
555
556                 [DefaultValue (-1)]
557                 public int MergeIndex {
558                         get { return this.merge_index; }
559                         set { this.merge_index = value; }
560                 }
561
562                 [DefaultValue (null)]
563                 [Browsable (false)]
564                 public string Name {
565                         get { return this.name; }
566                         set { this.name = value; }
567                 }
568
569                 [DefaultValue (ToolStripItemOverflow.AsNeeded)]
570                 public ToolStripItemOverflow Overflow {
571                         get { return this.overflow; }
572                         set { 
573                                 if (this.overflow != value) {
574                                         if (!Enum.IsDefined (typeof (ToolStripItemOverflow), value))
575                                                 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemOverflow", value));
576                                 
577                                         this.overflow = value;
578                                         
579                                         if (owner != null)
580                                                 owner.PerformLayout ();
581                                 }
582                         }
583                 }
584                         
585                 [Browsable (false)]
586                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
587                 public ToolStrip Owner {
588                         get { return this.owner; }
589                         set { 
590                                 if (this.owner != value) {
591                                         this.owner = value; 
592                                         this.CalculateAutoSize (); 
593                                         OnOwnerChanged (EventArgs.Empty);
594                                 }
595                         }
596                 }
597
598                 [Browsable (false)]
599                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
600                 public ToolStripItem OwnerItem {
601                         get { return this.owner_item; }
602                 }
603
604                 public virtual Padding Padding {
605                         get { return this.padding; }
606                         set { 
607                                 this.padding = value; 
608                                 this.CalculateAutoSize (); 
609                                 this.Invalidate (); 
610                         }
611                 }
612
613                 [Browsable (false)]
614                 public ToolStripItemPlacement Placement {
615                         get { return this.placement; }
616                 }
617                 
618                 [Browsable (false)]
619                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
620                 public virtual bool Pressed { get { return this.is_pressed; } }
621
622                 [MonoTODO ("Stub, not implemented")]
623                 [Localizable (true)]
624                 public virtual RightToLeft RightToLeft {
625                         get { return this.right_to_left; }
626                         set { 
627                                 if (this.right_to_left != value) {
628                                         this.right_to_left = value;
629                                         this.OnRightToLeftChanged (EventArgs.Empty);
630                                 }
631                         }
632                 }
633                 
634                 [Localizable (true)]
635                 public bool RightToLeftAutoMirrorImage {
636                         get { return this.right_to_left_auto_mirror_image; }
637                         set { 
638                                 if (this.right_to_left_auto_mirror_image != value) {
639                                         this.right_to_left_auto_mirror_image = value;
640                                         this.Invalidate ();
641                                 }
642                         }
643                 }
644                 
645                 [Browsable (false)]
646                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
647                 public virtual bool Selected { get { return this.is_selected; } }
648
649                 [Localizable (true)]
650                 public virtual Size Size {
651                         get { 
652                                 if (!this.AutoSize && this.explicit_size != Size.Empty) 
653                                         return this.explicit_size; 
654                                         
655                                 return this.bounds.Size; 
656                         }
657                         set { 
658                                 this.bounds.Size = value; 
659                                 this.explicit_size = value;
660                                 
661                                 if (this.Visible) {
662                                         this.CalculateAutoSize ();
663                                         this.OnBoundsChanged (); 
664                                 }
665                         }
666                 }
667
668                 [Localizable (false)]
669                 [Bindable (true)]
670                 [DefaultValue (null)]
671                 [TypeConverter (typeof (StringConverter))]
672                 public Object Tag {
673                         get { return this.tag; }
674                         set { this.tag = value; }
675                 }
676
677                 [Localizable (true)]
678                 [DefaultValue ("")]
679                 public virtual string Text
680                 {
681                         get { return this.text; }
682                         set { 
683                                 if (this.text != value) { 
684                                         this.text = value; 
685                                         this.CalculateAutoSize (); 
686                                         this.OnTextChanged (EventArgs.Empty); 
687                                         this.Invalidate (); 
688                                 } 
689                         }
690                 }
691
692                 [Localizable (true)]
693                 [DefaultValue (ContentAlignment.MiddleCenter)]
694                 public virtual ContentAlignment TextAlign {
695                         get { return this.text_align; }
696                         set {
697                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
698                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
699                                 this.text_align = value;
700                                 this.Invalidate ();
701                         }
702                 }
703
704                 [Localizable (true)]
705                 [DefaultValue (TextImageRelation.ImageBeforeText)]
706                 public TextImageRelation TextImageRelation {
707                         get { return this.text_image_relation; }
708                         set { 
709                                 this.text_image_relation = value; 
710                                 this.CalculateAutoSize (); 
711                                 this.Invalidate (); 
712                         }
713                 }
714
715                 [Localizable (true)]
716                 public string ToolTipText {
717                         get { return this.tool_tip_text; }
718                         set { this.tool_tip_text = value; }
719                 }
720
721                 [Localizable (true)]
722                 public bool Visible {
723                         get { 
724                                 if (this.parent == null)
725                                         return false;
726                         
727                                 return this.visible && this.parent.Visible; 
728                         }
729                         set { 
730                                 if (this.visible != value) {
731                                         this.available = value;
732                                         this.SetVisibleCore (value);
733                                 }
734                         }
735                 }
736
737                 [Browsable (false)]
738                 [EditorBrowsable (EditorBrowsableState.Always)]
739                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
740                 public int Width {
741                         get { return this.Size.Width; }
742                         set { 
743                                 this.bounds.Width = value; 
744                                 this.explicit_size.Width = value;
745                                 
746                                 if (this.Visible) {
747                                         this.CalculateAutoSize ();
748                                         this.OnBoundsChanged ();
749                                         this.Invalidate ();
750                                 }
751                         }
752                 }
753                 #endregion
754
755                 #region Protected Properties
756                 protected virtual bool DefaultAutoToolTip { get { return false; } }
757                 protected virtual ToolStripItemDisplayStyle DefaultDisplayStyle { get { return ToolStripItemDisplayStyle.ImageAndText; } }
758                 protected internal virtual Padding DefaultMargin { get { return new Padding (0, 1, 0, 2); } }
759                 protected virtual Padding DefaultPadding { get { return new Padding (); } }
760                 protected virtual Size DefaultSize { get { return new Size (23, 23); } }
761                 protected internal virtual bool DismissWhenClicked { get { return true; } }
762                 [Browsable (false)]
763                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
764                 protected internal ToolStrip Parent {
765                         get { return this.parent; }
766                         set { 
767                                 if (this.parent != value) {
768                                         ToolStrip old_parent = this.parent;
769                                         this.parent = value; 
770                                         OnParentChanged(old_parent, this.parent);
771                                 }
772                         }
773                 }
774                 protected internal virtual bool ShowKeyboardCues { get { return false; } }
775                 #endregion
776
777                 #region Public Methods
778                 public ToolStrip GetCurrentParent ()
779                 { 
780                         return this.parent; 
781                 }
782
783                 public virtual Size GetPreferredSize (Size constrainingSize)
784                 {
785                         return this.CalculatePreferredSize (constrainingSize);
786                 }
787
788                 public void Invalidate ()
789                 {
790                         if (parent != null)
791                                 parent.Invalidate (this.bounds);
792                 }
793
794                 public void Invalidate (Rectangle r)
795                 {
796                         if (parent != null)
797                                 parent.Invalidate (r);
798                 }
799
800                 public void PerformClick ()
801                 { 
802                         this.OnClick (EventArgs.Empty); 
803                 }
804
805                 [EditorBrowsable (EditorBrowsableState.Never)]
806                 public virtual void ResetBackColor () { this.BackColor = Control.DefaultBackColor; }
807
808                 [EditorBrowsable (EditorBrowsableState.Never)]
809                 public virtual void ResetDisplayStyle () { this.display_style = this.DefaultDisplayStyle; }
810
811                 [EditorBrowsable (EditorBrowsableState.Never)]
812                 public virtual void ResetFont () { this.font = new Font ("Tahoma", 8.25f); }
813
814                 [EditorBrowsable (EditorBrowsableState.Never)]
815                 public virtual void ResetForeColor () { this.ForeColor = Control.DefaultForeColor; }
816
817                 [EditorBrowsable (EditorBrowsableState.Never)]
818                 public virtual void ResetImage () { this.image = null; }
819
820                 [EditorBrowsable (EditorBrowsableState.Never)]
821                 public void ResetMargin () { this.margin = this.DefaultMargin; }
822
823                 [EditorBrowsable (EditorBrowsableState.Never)]
824                 public void ResetPadding () { this.padding = this.DefaultPadding; }
825
826                 public void Select ()
827                 {
828                         if (!this.is_selected && this.CanSelect) {
829                                 this.is_selected = true;
830                                 this.Invalidate ();
831                                 this.Parent.NotifySelectedChanged (this);
832                         }
833                 }
834
835                 public override string ToString ()
836                 {
837                         return this.text;
838                 }
839                 #endregion
840
841                 #region Protected Methods
842                 [EditorBrowsable (EditorBrowsableState.Advanced)]
843                 protected virtual AccessibleObject CreateAccessibilityInstance ()
844                 {
845                         return new ToolStripItemAccessibleObject (this);
846                 }
847
848                 protected override void Dispose (bool disposing)
849                 {
850                         if (!is_disposed && disposing)
851                                 is_disposed = true;
852                                 
853                         base.Dispose (disposing);
854                 }
855                 
856                 protected internal virtual bool IsInputChar (char charCode)
857                 {
858                         return false;
859                 }
860                 
861                 protected internal virtual bool IsInputKey (Keys keyData)
862                 {
863                         return false;
864                 }
865                 
866                 protected virtual void OnAvailableChanged (EventArgs e)
867                 {
868                         EventHandler eh = (EventHandler)(Events [AvailableChangedEvent]);
869                         if (eh != null)
870                                 eh (this, e);
871                 }
872
873                 [EditorBrowsable (EditorBrowsableState.Advanced)]
874                 protected virtual void OnBackColorChanged (EventArgs e)
875                 {
876                         EventHandler eh = (EventHandler)(Events [BackColorChangedEvent]);
877                         if (eh != null)
878                                 eh (this, e);
879                 }
880
881                 protected virtual void OnBoundsChanged ()
882                 {
883                         OnLayout (new LayoutEventArgs(null, string.Empty));
884                 }
885
886                 protected virtual void OnClick (EventArgs e)
887                 {
888                         EventHandler eh = (EventHandler)(Events [ClickEvent]);
889                         if (eh != null)
890                                 eh (this, e);
891                 }
892
893                 [EditorBrowsable (EditorBrowsableState.Advanced)]
894                 protected virtual void OnDisplayStyleChanged (EventArgs e)
895                 {
896                         EventHandler eh = (EventHandler)(Events [DisplayStyleChangedEvent]);
897                         if (eh != null)
898                                 eh (this, e);
899                 }
900
901                 protected virtual void OnDoubleClick (EventArgs e)
902                 {
903                         EventHandler eh = (EventHandler)(Events [DoubleClickEvent]);
904                         if (eh != null)
905                                 eh (this, e);
906
907                         if (!double_click_enabled)
908                                 OnClick (e);
909                 }
910
911                 void IDropTarget.OnDragDrop (DragEventArgs e)
912                 {
913                         // XXX
914                 }
915
916                 void IDropTarget.OnDragEnter (DragEventArgs e)
917                 {
918                         // XXX
919                 }
920
921                 void IDropTarget.OnDragLeave (EventArgs e)
922                 {
923                         // XXX
924                 }
925
926                 void IDropTarget.OnDragOver (DragEventArgs e)
927                 {
928                         // XXX
929                 }
930
931                 protected virtual void OnEnabledChanged (EventArgs e)
932                 {
933                         EventHandler eh = (EventHandler)(Events [EnabledChangedEvent]);
934                         if (eh != null)
935                                 eh (this, e);
936                 }
937
938                 [EditorBrowsable (EditorBrowsableState.Advanced)]
939                 protected virtual void OnFontChanged (EventArgs e)
940                 {
941                 }
942
943                 [EditorBrowsable (EditorBrowsableState.Advanced)]
944                 protected virtual void OnForeColorChanged (EventArgs e)
945                 {
946                         EventHandler eh = (EventHandler)(Events [ForeColorChangedEvent]);
947                         if (eh != null)
948                                 eh (this, e);
949                 }
950
951                 protected virtual void OnLayout (LayoutEventArgs e)
952                 {
953                 }
954
955                 protected virtual void OnLocationChanged (EventArgs e)
956                 {
957                         EventHandler eh = (EventHandler)(Events [LocationChangedEvent]);
958                         if (eh != null)
959                                 eh (this, e);
960                 }
961
962                 protected virtual void OnMouseDown (MouseEventArgs e)
963                 {
964                         if (this.Enabled) {
965                                 this.is_pressed = true;
966                                 this.Invalidate ();
967
968                                 MouseEventHandler eh = (MouseEventHandler)(Events [MouseDownEvent]);
969                                 if (eh != null)
970                                         eh (this, e);
971                         }
972                 }
973
974                 protected virtual void OnMouseEnter (EventArgs e)
975                 {
976                         this.Select ();
977
978                         EventHandler eh = (EventHandler)(Events [MouseEnterEvent]);
979                         if (eh != null)
980                                 eh (this, e);
981                 }
982
983                 protected virtual void OnMouseHover (EventArgs e)
984                 {
985                         if (this.Enabled) {
986                                 EventHandler eh = (EventHandler)(Events [MouseHoverEvent]);
987                                 if (eh != null)
988                                         eh (this, e);
989                         }
990                 }
991
992                 protected virtual void OnMouseLeave (EventArgs e)
993                 {
994                         if (this.CanSelect) {
995                                 this.is_selected = false;
996                                 this.is_pressed = false;
997                                 this.Invalidate ();
998                         }
999
1000                         EventHandler eh = (EventHandler)(Events [MouseLeaveEvent]);
1001                         if (eh != null)
1002                                 eh (this, e);
1003                 }
1004
1005                 protected virtual void OnMouseMove (MouseEventArgs e)
1006                 {
1007                         if (this.Enabled) {
1008                                 MouseEventHandler eh = (MouseEventHandler)(Events [MouseMoveEvent]);
1009                                 if (eh != null)
1010                                         eh (this, e);
1011                         }
1012                 }
1013
1014                 protected virtual void OnMouseUp (MouseEventArgs e)
1015                 {
1016                         if (this.Enabled) {
1017                                 this.is_pressed = false;
1018                                 this.Invalidate ();
1019
1020                                 if (this.IsOnDropDown)
1021                                         if (!(this is ToolStripDropDownItem) || !(this as ToolStripDropDownItem).HasDropDownItems || (this as ToolStripDropDownItem).DropDown.Visible == false) {
1022                                                 if ((this.Parent as ToolStripDropDown).OwnerItem != null)
1023                                                         ((this.Parent as ToolStripDropDown).OwnerItem as ToolStripDropDownItem).HideDropDown ();
1024                                                 else
1025                                                         (this.Parent as ToolStripDropDown).Hide ();
1026                                         }
1027                                                 
1028                                 
1029                                 MouseEventHandler eh = (MouseEventHandler)(Events [MouseUpEvent]);
1030                                 if (eh != null)
1031                                         eh (this, e);
1032                         }
1033                 }
1034
1035                 protected virtual void OnOwnerChanged (EventArgs e)
1036                 {
1037                         EventHandler eh = (EventHandler)(Events [OwnerChangedEvent]);
1038                         if (eh != null)
1039                                 eh (this, e);
1040                 }
1041
1042                 protected internal virtual void OnOwnerFontChanged (EventArgs e)
1043                 {
1044                 }
1045                 
1046                 protected virtual void OnPaint (PaintEventArgs e)
1047                 {
1048                         if (this.parent != null)
1049                                 this.parent.Renderer.DrawItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this));
1050                                 
1051                         PaintEventHandler eh = (PaintEventHandler)(Events [PaintEvent]);
1052                         if (eh != null)
1053                                 eh (this, e);
1054                 }
1055
1056                 // This is never called.
1057                 protected virtual void OnParentBackColorChanged (EventArgs e)
1058                 {
1059                 }
1060                 
1061                 protected virtual void OnParentChanged (ToolStrip oldParent, ToolStrip newParent)
1062                 {
1063                         if (oldParent != null)
1064                                 oldParent.PerformLayout ();
1065                                 
1066                         if (newParent != null)
1067                                 newParent.PerformLayout ();
1068                 }
1069
1070                 protected internal virtual void OnParentEnabledChanged (EventArgs e)
1071                 {
1072                         this.OnEnabledChanged (e);
1073                 }
1074
1075                 // This is never called.
1076                 protected virtual void OnParentForeColorChanged (EventArgs e)
1077                 {
1078                 }
1079         
1080                 protected internal virtual void OnParentRightToLeftChanged (EventArgs e)
1081                 {
1082                         this.OnRightToLeftChanged (e);
1083                 }
1084                 
1085                 protected virtual void OnRightToLeftChanged (EventArgs e)
1086                 {
1087                         EventHandler eh = (EventHandler)(Events[RightToLeftChangedEvent]);
1088                         if (eh != null)
1089                                 eh (this, e);
1090                 }
1091                 
1092                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1093                 protected virtual void OnTextChanged (EventArgs e)
1094                 {
1095                         EventHandler eh = (EventHandler)(Events [TextChangedEvent]);
1096                         if (eh != null)
1097                                 eh (this, e);
1098                 }
1099
1100                 protected virtual void OnVisibleChanged (EventArgs e)
1101                 {
1102                         EventHandler eh = (EventHandler)(Events [VisibleChangedEvent]);
1103                         if (eh != null)
1104                                 eh (this, e);
1105                 }
1106
1107                 protected internal virtual bool ProcessCmdKey (ref Message m, Keys keyData)
1108                 {
1109                         return false;
1110                 }
1111                 
1112                 protected internal virtual bool ProcessDialogKey (Keys keyData)
1113                 {
1114                         if (this.Selected && keyData == Keys.Enter) {
1115                                 this.FireEvent (EventArgs.Empty, ToolStripItemEventType.Click);
1116                                 return true;
1117                         }
1118                                 
1119                         return false;
1120                 }
1121                 
1122                 protected internal virtual bool ProcessMnemonic (char charCode)
1123                 {
1124                         return false;
1125                 }
1126                 
1127                 protected internal virtual void SetBounds (Rectangle bounds)
1128                 {
1129                         if (this.bounds != bounds) {
1130                                 this.bounds = bounds;
1131                                 OnBoundsChanged ();
1132                         }
1133                 }
1134                 
1135                 protected virtual void SetVisibleCore (bool visible)
1136                 {
1137                         this.visible = visible;
1138                         this.OnVisibleChanged (EventArgs.Empty);
1139                         this.Invalidate ();
1140                 }
1141                 #endregion
1142
1143                 #region Public Events
1144                 static object AvailableChangedEvent = new object ();
1145                 static object BackColorChangedEvent = new object ();
1146                 static object ClickEvent = new object ();
1147                 static object DisplayStyleChangedEvent = new object ();
1148                 static object DoubleClickEvent = new object ();
1149                 static object EnabledChangedEvent = new object ();
1150                 static object ForeColorChangedEvent = new object ();
1151                 static object LocationChangedEvent = new object ();
1152                 static object MouseDownEvent = new object ();
1153                 static object MouseEnterEvent = new object ();
1154                 static object MouseHoverEvent = new object ();
1155                 static object MouseLeaveEvent = new object ();
1156                 static object MouseMoveEvent = new object ();
1157                 static object MouseUpEvent = new object ();
1158                 static object OwnerChangedEvent = new object ();
1159                 static object PaintEvent = new object ();
1160                 static object RightToLeftChangedEvent = new object ();
1161                 static object TextChangedEvent = new object ();
1162                 static object VisibleChangedEvent = new object ();
1163
1164                 [Browsable (false)]
1165                 public event EventHandler AvailableChanged {
1166                         add { Events.AddHandler (AvailableChangedEvent, value); }
1167                         remove {Events.RemoveHandler (AvailableChangedEvent, value); }
1168                 }
1169
1170                 public event EventHandler BackColorChanged {
1171                         add { Events.AddHandler (BackColorChangedEvent, value); }
1172                         remove {Events.RemoveHandler (BackColorChangedEvent, value); }
1173                 }
1174
1175                 public event EventHandler Click {
1176                         add { Events.AddHandler (ClickEvent, value); }
1177                         remove {Events.RemoveHandler (ClickEvent, value); }
1178                 }
1179
1180                 public event EventHandler DisplayStyleChanged {
1181                         add { Events.AddHandler (DisplayStyleChangedEvent, value); }
1182                         remove {Events.RemoveHandler (DisplayStyleChangedEvent, value); }
1183                 }
1184
1185                 public event EventHandler DoubleClick {
1186                         add { Events.AddHandler (DoubleClickEvent, value); }
1187                         remove {Events.RemoveHandler (DoubleClickEvent, value); }
1188                 }
1189
1190                 public event EventHandler EnabledChanged {
1191                         add { Events.AddHandler (EnabledChangedEvent, value); }
1192                         remove {Events.RemoveHandler (EnabledChangedEvent, value); }
1193                 }
1194
1195                 public event EventHandler ForeColorChanged {
1196                         add { Events.AddHandler (ForeColorChangedEvent, value); }
1197                         remove {Events.RemoveHandler (ForeColorChangedEvent, value); }
1198                 }
1199
1200                 public event EventHandler LocationChanged {
1201                         add { Events.AddHandler (LocationChangedEvent, value); }
1202                         remove {Events.RemoveHandler (LocationChangedEvent, value); }
1203                 }
1204
1205                 public event MouseEventHandler MouseDown {
1206                         add { Events.AddHandler (MouseDownEvent, value); }
1207                         remove {Events.RemoveHandler (MouseDownEvent, value); }
1208                 }
1209
1210                 public event EventHandler MouseEnter {
1211                         add { Events.AddHandler (MouseEnterEvent, value); }
1212                         remove {Events.RemoveHandler (MouseEnterEvent, value); }
1213                 }
1214
1215                 public event EventHandler MouseHover {
1216                         add { Events.AddHandler (MouseHoverEvent, value); }
1217                         remove {Events.RemoveHandler (MouseHoverEvent, value); }
1218                 }
1219
1220                 public event EventHandler MouseLeave {
1221                         add { Events.AddHandler (MouseLeaveEvent, value); }
1222                         remove {Events.RemoveHandler (MouseLeaveEvent, value); }
1223                 }
1224
1225                 public event MouseEventHandler MouseMove {
1226                         add { Events.AddHandler (MouseMoveEvent, value); }
1227                         remove {Events.RemoveHandler (MouseMoveEvent, value); }
1228                 }
1229
1230                 public event MouseEventHandler MouseUp {
1231                         add { Events.AddHandler (MouseUpEvent, value); }
1232                         remove {Events.RemoveHandler (MouseUpEvent, value); }
1233                 }
1234
1235                 public event EventHandler OwnerChanged {
1236                         add { Events.AddHandler (OwnerChangedEvent, value); }
1237                         remove {Events.RemoveHandler (OwnerChangedEvent, value); }
1238                 }
1239
1240                 public event PaintEventHandler Paint {
1241                         add { Events.AddHandler (PaintEvent, value); }
1242                         remove {Events.RemoveHandler (PaintEvent, value); }
1243                 }
1244
1245                 public event EventHandler RightToLeftChanged {
1246                         add { Events.AddHandler (RightToLeftChangedEvent, value); }
1247                         remove { Events.RemoveHandler (RightToLeftChangedEvent, value); }
1248                 }
1249                 
1250                 public event EventHandler TextChanged {
1251                         add { Events.AddHandler (TextChangedEvent, value); }
1252                         remove {Events.RemoveHandler (TextChangedEvent, value); }
1253                 }
1254
1255                 public event EventHandler VisibleChanged {
1256                         add { Events.AddHandler (VisibleChangedEvent, value); }
1257                         remove {Events.RemoveHandler (VisibleChangedEvent, value); }
1258                 }
1259                 #endregion
1260
1261                 #region Internal Methods
1262                 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, ContentAlignment align)
1263                 {
1264                         int x = 0;
1265                         int y = 0;
1266
1267                         if (align == ContentAlignment.BottomLeft || align == ContentAlignment.MiddleLeft || align == ContentAlignment.TopLeft)
1268                                 x = outer.X;
1269                         else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.MiddleCenter || align == ContentAlignment.TopCenter)
1270                                 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
1271                         else if (align == ContentAlignment.BottomRight || align == ContentAlignment.MiddleRight || align == ContentAlignment.TopRight)
1272                                 x = outer.Right - inner.Width;
1273                         if (align == ContentAlignment.TopCenter || align == ContentAlignment.TopLeft || align == ContentAlignment.TopRight)
1274                                 y = outer.Y;
1275                         else if (align == ContentAlignment.MiddleCenter || align == ContentAlignment.MiddleLeft || align == ContentAlignment.MiddleRight)
1276                                 y = outer.Y + (outer.Height - inner.Height) / 2;
1277                         else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.BottomRight || align == ContentAlignment.BottomLeft)
1278                                 y = outer.Bottom - inner.Height;
1279
1280                         return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
1281                 }
1282
1283                 internal void CalculateAutoSize ()
1284                 {
1285                         this.text_size = TextRenderer.MeasureText (this.Text == null ? string.Empty: this.text, this.Font, Size.Empty, TextFormatFlags.HidePrefix);
1286
1287                         if (!this.auto_size || this is ToolStripControlHost)
1288                                 return;
1289                         //this.text_size.Width += 6;
1290
1291                         Size final_size = this.CalculatePreferredSize (Size.Empty);
1292
1293                         if (final_size != this.Size) {
1294                                 this.bounds.Width = final_size.Width;
1295                                 if (this.parent != null)
1296                                         this.parent.PerformLayout ();
1297                         }
1298                 }
1299
1300                 internal virtual Size CalculatePreferredSize (Size constrainingSize)
1301                 {
1302                         if (!this.auto_size)
1303                                 return this.explicit_size;
1304                                 
1305                         Size preferred_size = this.DefaultSize;
1306
1307                         switch (this.display_style) {
1308                                 case ToolStripItemDisplayStyle.Text:
1309                                         int width = text_size.Width + this.padding.Horizontal;
1310                                         int height = text_size.Height + this.padding.Vertical;
1311                                         preferred_size = new Size (width, height);
1312                                         break;
1313                                 case ToolStripItemDisplayStyle.Image:
1314                                         if (this.Image == null)
1315                                                 preferred_size = this.DefaultSize;
1316                                         else {
1317                                                 switch (this.image_scaling) {
1318                                                         case ToolStripItemImageScaling.None:
1319                                                                 preferred_size = this.Image.Size;
1320                                                                 break;
1321                                                         case ToolStripItemImageScaling.SizeToFit:
1322                                                                 if (this.parent == null)
1323                                                                         preferred_size = this.Image.Size;
1324                                                                 else
1325                                                                         preferred_size = this.parent.ImageScalingSize;
1326                                                                 break;
1327                                                 }
1328                                         }
1329                                         break;
1330                                 case ToolStripItemDisplayStyle.ImageAndText:
1331                                         int width2 = text_size.Width + this.padding.Horizontal;
1332                                         int height2 = text_size.Height + this.padding.Vertical;
1333
1334                                         if (this.Image != null) {
1335                                                 switch (this.text_image_relation) {
1336                                                         case TextImageRelation.Overlay:
1337                                                                 width2 = Math.Max (width2, this.Image.Width);
1338                                                                 height2 = Math.Max (height2, this.Image.Height);
1339                                                                 break;
1340                                                         case TextImageRelation.ImageAboveText:
1341                                                         case TextImageRelation.TextAboveImage:
1342                                                                 width2 = Math.Max (width2, this.Image.Width);
1343                                                                 height2 += this.Image.Height;
1344                                                                 break;
1345                                                         case TextImageRelation.ImageBeforeText:
1346                                                         case TextImageRelation.TextBeforeImage:
1347                                                                 height2 = Math.Max (height2, this.Image.Height);
1348                                                                 width2 += this.Image.Width;
1349                                                                 break;
1350                                                 }
1351                                         }
1352
1353                                         preferred_size = new Size (width2, height2);
1354                                         break;
1355                         }
1356
1357                         if (!(this is ToolStripLabel)) {                // Everything but labels have a border
1358                                 preferred_size.Height += 4;
1359                                 preferred_size.Width += 4;
1360                         }
1361                         
1362                         // Account for ToolStripDropDownButton's drop down arrow
1363                         if (this is ToolStripDropDownButton && (this as ToolStripDropDownButton).ShowDropDownArrow)
1364                                 preferred_size.Width += 9;
1365
1366                         return preferred_size;
1367                 }
1368
1369                 internal void CalculateTextAndImageRectangles (out Rectangle text_rect, out Rectangle image_rect)
1370                 {
1371                         this.CalculateTextAndImageRectangles (this.ContentRectangle, out text_rect, out image_rect);
1372                 }
1373                 
1374                 internal void CalculateTextAndImageRectangles (Rectangle contentRectangle, out Rectangle text_rect, out Rectangle image_rect)
1375                 {
1376                         text_rect = Rectangle.Empty;
1377                         image_rect = Rectangle.Empty;
1378                                 
1379                         switch (this.display_style) {
1380                                 case ToolStripItemDisplayStyle.None:
1381                                         break;
1382                                 case ToolStripItemDisplayStyle.Text:
1383                                         if (this.text != string.Empty)
1384                                                 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1385                                         break;
1386                                 case ToolStripItemDisplayStyle.Image:
1387                                         if (this.Image != null)
1388                                                 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1389                                         break;
1390                                 case ToolStripItemDisplayStyle.ImageAndText:
1391                                         if (this.text != string.Empty && this.Image == null)
1392                                                 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1393                                         else if (this.text == string.Empty && this.Image != null)
1394                                                 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1395                                         else if (this.text == string.Empty && this.Image == null)
1396                                                 break;
1397                                         else {
1398                                                 Rectangle text_area;
1399                                                 Rectangle image_area;
1400
1401                                                 switch (this.text_image_relation) {
1402                                                         case TextImageRelation.Overlay:
1403                                                                 text_rect = AlignInRectangle (contentRectangle, this.text_size, this.text_align);
1404                                                                 image_rect = AlignInRectangle (contentRectangle, GetImageSize (), this.image_align);
1405                                                                 break;
1406                                                         case TextImageRelation.ImageAboveText:
1407                                                                 text_area = new Rectangle (contentRectangle.Left, contentRectangle.Bottom - (text_size.Height - 4), contentRectangle.Width, text_size.Height - 4);
1408                                                                 image_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, contentRectangle.Height - text_area.Height);
1409
1410                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
1411                                                                 image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align);
1412                                                                 break;
1413                                                         case TextImageRelation.TextAboveImage:
1414                                                                 text_area = new Rectangle (contentRectangle.Left, contentRectangle.Top, contentRectangle.Width, text_size.Height - 4);
1415                                                                 image_area = new Rectangle (contentRectangle.Left, text_area.Bottom, contentRectangle.Width, contentRectangle.Height - text_area.Height);
1416
1417                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
1418                                                                 image_rect = AlignInRectangle (image_area, GetImageSize (), this.image_align);
1419                                                                 break;
1420                                                         case TextImageRelation.ImageBeforeText:
1421                                                                 LayoutTextBeforeOrAfterImage (contentRectangle, false, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect);
1422                                                                 break;
1423                                                         case TextImageRelation.TextBeforeImage:
1424                                                                 LayoutTextBeforeOrAfterImage (contentRectangle, true, text_size, GetImageSize (), text_align, image_align, out text_rect, out image_rect);
1425                                                                 break;
1426                                                 }
1427                                         }
1428                                         break;
1429                         }
1430                 }
1431
1432                 internal virtual void Dismiss (ToolStripDropDownCloseReason reason)
1433                 {
1434                         if (is_selected) {
1435                                 this.is_selected = false;
1436                                 this.Invalidate ();
1437                         }
1438                 }
1439
1440                 internal virtual ToolStrip GetTopLevelToolStrip ()
1441                 {
1442                         if (this.Parent != null)
1443                                 return this.Parent.GetTopLevelToolStrip ();
1444                                 
1445                         return null;
1446                 }
1447
1448                 private void LayoutTextBeforeOrAfterImage (Rectangle totalArea, bool textFirst, Size textSize, Size imageSize, ContentAlignment textAlign, ContentAlignment imageAlign, out Rectangle textRect, out Rectangle imageRect)
1449                 {
1450                         int element_spacing = 0;        // Spacing between the Text and the Image
1451                         int total_width = textSize.Width + element_spacing + imageSize.Width;
1452                         int excess_width = totalArea.Width - total_width;
1453                         int offset = 0;
1454                         
1455                         Rectangle final_text_rect;
1456                         Rectangle final_image_rect;
1457
1458                         HorizontalAlignment h_text = GetHorizontalAlignment (textAlign);
1459                         HorizontalAlignment h_image = GetHorizontalAlignment (imageAlign);
1460                         
1461                         if (h_image == HorizontalAlignment.Left)
1462                                 offset = 0;
1463                         else if (h_image == HorizontalAlignment.Right && h_text == HorizontalAlignment.Right)
1464                                 offset = excess_width;
1465                         else if (h_image == HorizontalAlignment.Center && (h_text == HorizontalAlignment.Left || h_text == HorizontalAlignment.Center))
1466                                 offset += (int)(excess_width / 3);
1467                         else
1468                                 offset += (int)(2 * (excess_width / 3));
1469                                 
1470                         if (textFirst) {
1471                                 final_text_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
1472                                 final_image_rect = new Rectangle (final_text_rect.Right + element_spacing, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
1473                         } else {
1474                                 final_image_rect = new Rectangle (totalArea.Left + offset, AlignInRectangle (totalArea, imageSize, imageAlign).Top, imageSize.Width, imageSize.Height);
1475                                 final_text_rect = new Rectangle (final_image_rect.Right + element_spacing, AlignInRectangle (totalArea, textSize, textAlign).Top, textSize.Width, textSize.Height);
1476                         }
1477                         
1478                         textRect = final_text_rect;
1479                         imageRect = final_image_rect;
1480                 }
1481                 
1482                 private HorizontalAlignment GetHorizontalAlignment (ContentAlignment align)
1483                 {
1484                         switch (align) {
1485                                 case ContentAlignment.BottomLeft:
1486                                 case ContentAlignment.MiddleLeft:
1487                                 case ContentAlignment.TopLeft:
1488                                         return HorizontalAlignment.Left;
1489                                 case ContentAlignment.BottomCenter:
1490                                 case ContentAlignment.MiddleCenter:
1491                                 case ContentAlignment.TopCenter:
1492                                         return HorizontalAlignment.Center;
1493                                 case ContentAlignment.BottomRight:
1494                                 case ContentAlignment.MiddleRight:
1495                                 case ContentAlignment.TopRight:
1496                                         return HorizontalAlignment.Right;
1497                         }
1498                         
1499                         return HorizontalAlignment.Left;
1500                 }
1501                 
1502                 internal Size GetImageSize ()
1503                 {
1504                         if (this.Image == null)
1505                                 return Size.Empty;
1506                         
1507                         if (this.image_scaling == ToolStripItemImageScaling.None)
1508                                 return this.Image.Size;
1509                                 
1510                         if (this.Parent == null)
1511                                 return Size.Empty;
1512                                 
1513                         return this.Parent.ImageScalingSize;
1514                 }
1515                 
1516                 internal string GetToolTip ()
1517                 {
1518                         if (this.auto_tool_tip && string.IsNullOrEmpty (this.tool_tip_text))
1519                                 return this.text;
1520                                 
1521                         return this.tool_tip_text;
1522                 }
1523                 
1524                 internal void FireEvent (EventArgs e, ToolStripItemEventType met)
1525                 {
1526                         // If we're disabled, don't fire any of these events, except Paint
1527                         if (!this.Enabled && met != ToolStripItemEventType.Paint)
1528                                 return;
1529                                 
1530                         switch (met) {
1531                                 case ToolStripItemEventType.MouseUp:
1532                                         this.OnMouseUp ((MouseEventArgs)e);
1533                                         this.HandleClick (e);
1534                                         break;
1535                                 case ToolStripItemEventType.MouseDown:
1536                                         this.OnMouseDown ((MouseEventArgs)e);
1537                                         break;
1538                                 case ToolStripItemEventType.MouseEnter:
1539                                         this.OnMouseEnter (e);
1540                                         break;
1541                                 case ToolStripItemEventType.MouseHover:
1542                                         this.OnMouseHover (e);
1543                                         break;
1544                                 case ToolStripItemEventType.MouseLeave:
1545                                         this.OnMouseLeave (e);
1546                                         break;
1547                                 case ToolStripItemEventType.MouseMove:
1548                                         this.OnMouseMove ((MouseEventArgs)e);
1549                                         break;
1550                                 case ToolStripItemEventType.Paint:
1551                                         this.OnPaint ((PaintEventArgs)e);
1552                                         break;
1553                                 case ToolStripItemEventType.Click:
1554                                         this.HandleClick (e);
1555                                         break;
1556                         }
1557                 }
1558                 
1559                 internal virtual void HandleClick (EventArgs e)
1560                 {
1561                         this.Parent.HandleItemClick (this);
1562                         this.OnClick (e);
1563                 }
1564                 
1565                 internal virtual void SetPlacement (ToolStripItemPlacement placement)
1566                 {
1567                         this.placement = placement;
1568                 }
1569
1570                 internal bool InternalVisible {
1571                         get { return this.visible; }
1572                         set { this.visible = value; }
1573                 }
1574                 
1575                 internal Point Location {
1576                         get { return this.bounds.Location; }
1577                         set {
1578                                 if (this.bounds.Location != value) {
1579                                         this.bounds.Location = value;
1580                                         this.OnLocationChanged (EventArgs.Empty);
1581                                 }
1582                         }
1583                 }
1584
1585                 internal int Top {
1586                         get { return this.bounds.Y; }
1587                         set {
1588                                 if (this.bounds.Y != value) {
1589                                         this.bounds.Y = value;
1590                                         this.OnLocationChanged (EventArgs.Empty);
1591                                 }
1592                         }
1593                 }
1594
1595                 internal int Left {
1596                         get { return this.bounds.X; }
1597                         set {
1598                                 if (this.bounds.X != value) {
1599                                         this.bounds.X = value;
1600                                         this.OnLocationChanged (EventArgs.Empty);
1601                                 }
1602                         }
1603                 }
1604                 
1605                 internal int Right { get { return this.bounds.Right; } }
1606                 internal int Bottom { get { return this.bounds.Bottom; } }
1607                 #endregion
1608                 
1609                 public class ToolStripItemAccessibleObject : AccessibleObject
1610                 {
1611                         private ToolStripItem owner_item;
1612                         
1613                         public ToolStripItemAccessibleObject (ToolStripItem ownerItem)
1614                         {
1615                                 if (ownerItem == null)
1616                                         throw new ArgumentNullException ("ownerItem");
1617                                         
1618                                 this.owner_item = ownerItem;
1619                                 base.default_action = string.Empty;
1620                                 base.keyboard_shortcut = string.Empty;
1621                                 base.name = string.Empty;
1622                                 base.value = string.Empty;
1623                         }
1624
1625                         #region Public Properties
1626                         public override Rectangle Bounds {
1627                                 get {
1628                                         return owner_item.Visible ? owner_item.Bounds : Rectangle.Empty;
1629                                 }
1630                         }
1631
1632                         public override string DefaultAction {
1633                                 get { return base.DefaultAction; }
1634                         }
1635
1636                         public override string Description {
1637                                 get { return base.Description; }
1638                         }
1639
1640                         public override string Help {
1641                                 get { return base.Help; }
1642                         }
1643
1644                         public override string KeyboardShortcut {
1645                                 get { return base.KeyboardShortcut; }
1646                         }
1647
1648                         public override string Name {
1649                                 get {
1650                                         if (base.name == string.Empty)
1651                                                 return owner_item.Text;
1652                                                 
1653                                         return base.Name;
1654                                 }
1655                                 set { base.Name = value; }
1656                         }
1657
1658                         public override AccessibleObject Parent {
1659                                 get { return base.Parent; }
1660                         }
1661
1662                         public override AccessibleRole Role {
1663                                 get { return base.Role; }
1664                         }
1665
1666                         public override AccessibleStates State {
1667                                 get { return base.State; }
1668                         }
1669                         #endregion
1670
1671                         #region Public Methods
1672                         public void AddState (AccessibleStates state)
1673                         {
1674                                 base.state = state;
1675                         }
1676
1677                         public override void DoDefaultAction ()
1678                         {
1679                                 base.DoDefaultAction ();
1680                         }
1681
1682                         public override int GetHelpTopic (out string FileName)
1683                         {
1684                                 return base.GetHelpTopic (out FileName);
1685                         }
1686
1687                         public override AccessibleObject Navigate (AccessibleNavigation navdir)
1688                         {
1689                                 return base.Navigate (navdir);
1690                         }
1691
1692                         public override string ToString ()
1693                         {
1694                                 return string.Format ("ToolStripItemAccessibleObject: Owner = {0}", owner_item.ToString());
1695                         }
1696                         #endregion
1697                 }
1698         }
1699 }
1700 #endif