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