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