New test.
[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 ToolStripItemAlignment alignment;
46                 private bool auto_size;
47                 private bool auto_tool_tip;
48                 private bool available;
49                 private Color back_color;
50                 private Rectangle bounds;
51                 private bool can_select;
52                 private ToolStripItemDisplayStyle display_style;
53                 private DockStyle dock;
54                 private bool double_click_enabled;
55                 private bool enabled;
56                 private Font font;
57                 private Color fore_color;
58                 private Image image;
59                 private ContentAlignment image_align;
60                 private int image_index;
61                 private ToolStripItemImageScaling image_scaling;
62                 protected bool is_pressed;
63                 private bool is_selected;
64                 private Padding margin;
65                 private string name;
66                 private ToolStrip owner;
67                 internal ToolStripItem owner_item;
68                 private Padding padding;
69                 private Object tag;
70                 private string text;
71                 private ContentAlignment text_align;
72                 private TextImageRelation text_image_relation;
73                 private string tool_tip_text;
74                 private bool visible;
75
76                 private ToolStrip parent;
77                 internal Size text_size;
78                 #endregion
79
80                 #region Public Constructors
81                 protected ToolStripItem ()
82                         : this (String.Empty, null, null, String.Empty)
83                 {
84                 }
85
86                 protected ToolStripItem (string text, Image image, EventHandler onClick)
87                         : this (text, image, onClick, String.Empty)
88                 {
89                 }
90
91                 protected ToolStripItem (string text, Image image, EventHandler onClick, string name)
92                 {
93                         this.alignment = ToolStripItemAlignment.Left;
94                         this.auto_size = true;
95                         this.auto_tool_tip = this.DefaultAutoToolTip;
96                         this.available = true;
97                         this.back_color = Control.DefaultBackColor;
98                         this.display_style = this.DefaultDisplayStyle;
99                         this.dock = DockStyle.None;
100                         this.enabled = true;
101                         this.font = new Font ("Tahoma", 8.25f);
102                         this.fore_color = Control.DefaultForeColor;
103                         this.image = image;
104                         this.image_align = ContentAlignment.MiddleCenter;
105                         this.image_index = -1;
106                         this.image_scaling = ToolStripItemImageScaling.SizeToFit;
107                         this.margin = this.DefaultMargin;
108                         this.name = name;
109                         this.padding = this.DefaultPadding;
110                         this.bounds.Size = this.DefaultSize;
111                         this.text = text;
112                         this.text_align = ContentAlignment.MiddleCenter;
113                         this.text_image_relation = TextImageRelation.ImageBeforeText;
114                         this.visible = true;
115
116                         this.Click = onClick;
117                         this.can_select = this is ToolStripMenuItem ? true : false;
118                         OnLayout (new LayoutEventArgs (null, ""));
119                 }
120                 #endregion
121
122                 #region Public Properties
123                 public AccessibleObject AccessibilityObject {
124                         get { 
125                                 if (this.accessibility_object == null)
126                                         this.accessibility_object = CreateAccessibilityInstance ();
127                                         
128                                 return this.accessibility_object;
129                         }
130                 }
131                 
132                 public string AccessibleDefaultActionDescription {
133                         get {
134                                 if (this.accessibility_object == null)
135                                         return null;
136                                 
137                                 return this.accessible_default_action_description;
138                         }
139                         set { this.accessible_default_action_description = value; }
140                 }
141
142                 [Localizable (true)]
143                 public string AccessibleDescription {
144                         get {
145                                 if (this.accessibility_object == null)
146                                         return null;
147                                 
148                                 return this.AccessibilityObject.Description;
149                         }
150                         set { this.AccessibilityObject.description = value; }
151                 }
152
153                 [Localizable (true)]
154                 public string AccessibleName {
155                         get { 
156                                 if (this.accessibility_object == null)
157                                         return null;
158                                         
159                                 return this.AccessibilityObject.Name; 
160                         }
161                         set { this.AccessibilityObject.Name = value; }
162                 }
163                 
164                 public AccessibleRole AccessibleRole {
165                         get
166                         {
167                                 if (this.accessibility_object == null)
168                                         return AccessibleRole.Default;
169                                 
170                                 return this.AccessibilityObject.Role;
171                         }
172                         set { this.AccessibilityObject.role = value; }
173                 }
174                 
175                 [MonoTODO]
176                 [DefaultValue (ToolStripItemAlignment.Left)]
177                 public ToolStripItemAlignment Alignment {
178                         get { return this.alignment; }
179                         set {
180                                 if (!Enum.IsDefined (typeof (ToolStripItemAlignment), value))
181                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripItemAlignment", value));
182
183                                 this.alignment = value;
184                         }
185                 }
186
187                 [Localizable (true)]
188                 [DefaultValue (true)]
189                 public bool AutoSize {
190                         get { return this.auto_size; }
191                         set { 
192                                 this.auto_size = value; 
193                                 this.CalculateAutoSize (); 
194                         }
195                 }
196
197                 [MonoTODO ("Need 2.0 ToolTip to implement tool tips.")]
198                 [DefaultValue (false)]
199                 public bool AutoToolTip {
200                         get { return this.auto_tool_tip; }
201                         set { this.auto_tool_tip = value; }
202                 }
203
204                 [Browsable (false)]
205                 public bool Available {
206                         get { return this.visible; }
207                         set {
208                                 if (this.visible != value) {
209                                         visible = value; 
210                                         
211                                         if (this.owner != null) 
212                                                 owner.PerformLayout (); 
213                                                 
214                                         OnAvailableChanged (EventArgs.Empty); 
215                                 }
216                         }
217                 }
218
219                 public virtual Color BackColor {
220                         get { return this.back_color; }
221                         set {
222                                 if (this.back_color != value) {
223                                         back_color = value;
224                                         OnBackColorChanged (EventArgs.Empty);
225                                         this.Invalidate ();
226                                 }
227                         }
228                 }
229
230                 [Browsable (false)]
231                 public virtual Rectangle Bounds {
232                         get { return this.bounds; }
233                 }
234
235                 [Browsable (false)]
236                 public virtual bool CanSelect {
237                         get { return this.can_select; }
238                 }
239
240                 [Browsable (false)]
241                 public Rectangle ContentRectangle {
242                         get {
243                                 // ToolStripLabels don't have a border
244                                 if (this is ToolStripLabel)
245                                         return new Rectangle (0, 0, this.bounds.Width, this.bounds.Height);
246
247                                 return new Rectangle (2, 2, this.bounds.Width - 4, this.bounds.Height - 4);
248                         }
249                 }
250
251                 public virtual ToolStripItemDisplayStyle DisplayStyle {
252                         get { return this.display_style; }
253                         set {
254                                 if (this.display_style != value) {
255                                         this.display_style = value; 
256                                         this.CalculateAutoSize (); 
257                                         OnDisplayStyleChanged (EventArgs.Empty); 
258                                         this.Invalidate ();
259                                 }
260                         }
261                 }
262
263                 [Browsable (false)]
264                 [DefaultValue (DockStyle.None)]
265                 public DockStyle Dock {
266                         get { return this.dock; }
267                         set {
268                                 if (this.dock != value) {
269                                         if (!Enum.IsDefined (typeof (DockStyle), value))
270                                                 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for DockStyle", value));
271
272                                         this.dock = value;
273                                         this.CalculateAutoSize ();
274                                 }
275                         }
276                 }
277
278                 [DefaultValue (false)]
279                 public bool DoubleClickEnabled {
280                         get { return this.double_click_enabled; }
281                         set { this.double_click_enabled = value; }
282                 }
283
284                 [Localizable (true)]
285                 [DefaultValue (true)]
286                 public virtual bool Enabled {
287                         get { return enabled; }
288                         set { 
289                                 if (this.enabled != value) {
290                                         this.enabled = value; 
291                                         OnEnabledChanged (EventArgs.Empty); 
292                                         this.Invalidate ();
293                                 }
294                         }
295                 }
296
297                 [Localizable (true)]
298                 public virtual Font Font
299                 {
300                         get { return this.font; }
301                         set { 
302                                 if (this.font != value) {
303                                         this.font = value; 
304                                         this.CalculateAutoSize (); 
305                                         this.OnFontChanged (EventArgs.Empty); 
306                                         this.Invalidate ();
307                                 }
308                         }
309                 }
310
311                 public virtual Color ForeColor {
312                         get { return this.fore_color; }
313                         set { 
314                                 if (this.fore_color != value) {
315                                         this.fore_color = value; 
316                                         this.OnForeColorChanged (EventArgs.Empty); 
317                                         this.Invalidate ();
318                                 }
319                         }
320                 }
321
322                 [Browsable (false)]
323                 public int Height {
324                         get { return this.bounds.Height; }
325                         set { 
326                                 this.bounds.Height = value; 
327                                 this.CalculateAutoSize ();
328                                 this.OnBoundsChanged ();
329                                 this.Invalidate (); 
330                         }
331                 }
332
333                 [Localizable (true)]
334                 public virtual Image Image {
335                         get { return this.image; }
336                         set {
337                                 this.image = value; 
338                                 this.CalculateAutoSize (); 
339                                 this.Invalidate ();
340                         }
341                 }
342
343                 [Localizable (true)]
344                 [DefaultValue (ContentAlignment.MiddleCenter)]
345                 public ContentAlignment ImageAlign {
346                         get { return this.image_align; }
347                         set {
348                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
349                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
350
351                                 this.image_align = value;
352                                 this.Invalidate ();
353                         }
354                 }
355
356                 [Localizable (true)]
357                 public int ImageIndex {
358                         get { return this.image_index; }
359                         set {
360                                 if (value < -1)
361                                         throw new ArgumentException ("ImageIndex cannot be less than -1");
362
363                                 this.image_index = value;
364                                 this.CalculateAutoSize ();
365                                 this.Invalidate ();
366                         }
367                 }
368
369                 [Localizable (true)]
370                 [DefaultValue (ToolStripItemImageScaling.SizeToFit)]
371                 public ToolStripItemImageScaling ImageScaling {
372                         get { return this.image_scaling; }
373                         set { 
374                                 this.image_scaling = value; 
375                                 this.CalculateAutoSize (); 
376                                 this.Invalidate (); 
377                         }
378                 }
379
380                 [Browsable (false)]
381                 public bool IsOnDropDown {
382                         get {
383                                 if (this.owner != null && this.owner is ToolStripDropDown)
384                                         return true;
385
386                                 return false;
387                         }
388                 }
389
390                 public Padding Margin {
391                         get { return this.margin; }
392                         set {
393                                 this.margin = value; 
394                                 this.CalculateAutoSize ();
395                         }
396                 }
397
398                 [DefaultValue (null)]
399                 public string Name {
400                         get { return this.name; }
401                         set { this.name = value; }
402                 }
403
404                 [Browsable (false)]
405                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
406                 public ToolStrip Owner {
407                         get { return this.owner; }
408                         set { 
409                                 if (this.owner != value) {
410                                         this.owner = value; 
411                                         this.CalculateAutoSize (); 
412                                         OnOwnerChanged (EventArgs.Empty);
413                                 }
414                         }
415                 }
416
417                 [Browsable (false)]
418                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
419                 public ToolStripItem OwnerItem {
420                         get { return this.owner_item; }
421                 }
422
423                 public virtual Padding Padding {
424                         get { return this.padding; }
425                         set { 
426                                 this.padding = value; 
427                                 this.CalculateAutoSize (); 
428                                 this.Invalidate (); 
429                         }
430                 }
431
432                 [Browsable (false)]
433                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
434                 public virtual bool Pressed { get { return this.is_pressed; } }
435
436                 [Browsable (false)]
437                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
438                 public virtual bool Selected { get { return this.is_selected; } }
439
440                 [Localizable (true)]
441                 public virtual Size Size {
442                         get { return this.bounds.Size; }
443                         set { 
444                                 this.bounds.Size = value; 
445                                 this.CalculateAutoSize ();
446                                 OnBoundsChanged ();
447                         }
448                 }
449
450                 [Localizable (false)]
451                 [Bindable (true)]
452                 [DefaultValue (null)]
453                 public Object Tag {
454                         get { return this.tag; }
455                         set { this.tag = value; }
456                 }
457
458                 [Localizable (true)]
459                 [DefaultValue ("")]
460                 public virtual string Text
461                 {
462                         get { return this.text; }
463                         set { 
464                                 if (this.text != value) { 
465                                         this.text = value; 
466                                         this.CalculateAutoSize (); 
467                                         this.OnTextChanged (EventArgs.Empty); 
468                                         this.Invalidate (); 
469                                 } 
470                         }
471                 }
472
473                 [Localizable (true)]
474                 [DefaultValue (ContentAlignment.MiddleCenter)]
475                 public virtual ContentAlignment TextAlign {
476                         get { return this.text_align; }
477                         set {
478                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
479                                         throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ContentAlignment", value));
480                                 this.text_align = value;
481                                 this.Invalidate ();
482                         }
483                 }
484
485                 [Localizable (true)]
486                 [DefaultValue (TextImageRelation.ImageBeforeText)]
487                 public TextImageRelation TextImageRelation {
488                         get { return this.text_image_relation; }
489                         set { 
490                                 this.text_image_relation = value; 
491                                 this.CalculateAutoSize (); 
492                                 this.Invalidate (); 
493                         }
494                 }
495
496                 [Localizable (true)]
497                 public string ToolTipText {
498                         get { return this.tool_tip_text; }
499                         set { this.tool_tip_text = value; }
500                 }
501
502                 [Localizable (true)]
503                 public bool Visible {
504                         get { 
505                                 if (this.parent == null)
506                                         return false;
507                         
508                                 return this.visible && this.parent.Visible; 
509                         }
510                         set { 
511                                 if (this.visible != value) {
512                                         this.visible = value; 
513                                         this.OnVisibleChanged (EventArgs.Empty); 
514                                         this.Invalidate ();
515                                 }
516                         }
517                 }
518
519                 [Browsable (false)]
520                 public int Width {
521                         get { return this.bounds.Width; }
522                         set { 
523                                 this.bounds.Width = value; 
524                                 this.CalculateAutoSize (); 
525                                 this.OnBoundsChanged();
526                         }
527                 }
528                 #endregion
529
530                 #region Protected Properties
531                 protected virtual bool DefaultAutoToolTip { get { return false; } }
532                 protected virtual ToolStripItemDisplayStyle DefaultDisplayStyle { get { return ToolStripItemDisplayStyle.ImageAndText; } }
533                 protected internal virtual Padding DefaultMargin { get { return new Padding (0, 1, 0, 2); } }
534                 protected virtual Padding DefaultPadding { get { return new Padding (); } }
535                 protected virtual Size DefaultSize { get { return new Size (23, 23); } }
536                 protected internal virtual bool DismissWhenClicked { get { return false; } }
537                 [Browsable (false)]
538                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
539                 protected internal ToolStrip Parent {
540                         get { return this.parent; }
541                         set { 
542                                 ToolStrip old_parent = this.parent;
543                                 this.parent = value; 
544                                 OnParentChanged(old_parent, this.parent);
545                         }
546                 }
547                 protected internal virtual bool ShowKeyboardCues { get { return true; } }
548                 #endregion
549
550                 #region Public Methods
551                 public ToolStrip GetCurrentParent ()
552                 { 
553                         return this.parent; 
554                 }
555
556                 public virtual Size GetPreferredSize (Size constrainingSize)
557                 {
558                         return this.CalculatePreferredSize (constrainingSize);
559                 }
560
561                 public void Invalidate ()
562                 {
563                         if (owner != null)
564                                 owner.Invalidate (this.bounds);
565                 }
566
567                 public void Invalidate (Rectangle r)
568                 {
569                         if (owner != null)
570                                 owner.Invalidate (r);
571                 }
572
573                 public void PerformClick ()
574                 { 
575                         this.OnClick (EventArgs.Empty); 
576                 }
577
578                 [EditorBrowsable (EditorBrowsableState.Never)]
579                 public virtual void ResetBackColor () { this.BackColor = Control.DefaultBackColor; }
580
581                 [EditorBrowsable (EditorBrowsableState.Never)]
582                 public virtual void ResetDisplayStyle () { this.display_style = this.DefaultDisplayStyle; }
583
584                 [EditorBrowsable (EditorBrowsableState.Never)]
585                 public virtual void ResetFont () { this.font = new Font ("Tahoma", 8.25f); }
586
587                 [EditorBrowsable (EditorBrowsableState.Never)]
588                 public virtual void ResetForeColor () { this.ForeColor = Control.DefaultForeColor; }
589
590                 [EditorBrowsable (EditorBrowsableState.Never)]
591                 public virtual void ResetImage () { this.image = null; }
592
593                 [EditorBrowsable (EditorBrowsableState.Never)]
594                 public void ResetMargin () { this.margin = this.DefaultMargin; }
595
596                 [EditorBrowsable (EditorBrowsableState.Never)]
597                 public void ResetPadding () { this.padding = this.DefaultPadding; }
598
599                 public void Select ()
600                 {
601                         if (this.CanSelect) {
602                                 this.is_selected = true;
603                                 this.Invalidate ();
604                         }
605                 }
606
607                 public override string ToString ()
608                 {
609                         return this.text;
610                 }
611                 #endregion
612
613                 #region Protected Methods
614                 protected virtual AccessibleObject CreateAccessibilityInstance ()
615                 {
616                         return new ToolStripItemAccessibleObject (this);
617                 }
618                 
619                 protected virtual void OnAvailableChanged (EventArgs e)
620                 {
621                         if (AvailableChanged != null) AvailableChanged (this, e);
622                 }
623
624                 protected virtual void OnBackColorChanged (EventArgs e)
625                 {
626                         if (BackColorChanged != null) BackColorChanged (this, e);
627                 }
628
629                 protected virtual void OnBoundsChanged ()
630                 {
631                         OnLayout (new LayoutEventArgs(null, ""));
632                 }
633
634                 protected virtual void OnClick (EventArgs e)
635                 {
636                         if (Click != null) Click (this, e);
637                 }
638
639                 protected virtual void OnDisplayStyleChanged (EventArgs e)
640                 {
641                         if (DisplayStyleChanged != null) DisplayStyleChanged (this, e);
642                 }
643
644                 protected virtual void OnDoubleClick (EventArgs e)
645                 {
646                         if (DoubleClick != null) DoubleClick (this, e);
647
648                         if (!double_click_enabled)
649                                 OnClick (e);
650                 }
651
652                 protected virtual void OnEnabledChanged (EventArgs e)
653                 {
654                         if (EnabledChanged != null) EnabledChanged (this, e);
655                 }
656
657                 protected virtual void OnFontChanged (EventArgs e)
658                 {
659                 }
660
661                 protected virtual void OnForeColorChanged (EventArgs e)
662                 {
663                         if (ForeColorChanged != null) ForeColorChanged (this, e);
664                 }
665
666                 protected virtual void OnLayout (LayoutEventArgs e)
667                 {
668                 }
669
670                 protected virtual void OnLocationChanged (EventArgs e)
671                 {
672                         if (LocationChanged != null) LocationChanged (this, e);
673                 }
674
675                 protected virtual void OnMouseDown (MouseEventArgs e)
676                 {
677                         if (this.Enabled) {
678                                 if (MouseDown != null) MouseDown (this, e);
679                                 this.is_pressed = true;
680                                 this.Invalidate ();
681                         }
682                 }
683
684                 protected virtual void OnMouseEnter (EventArgs e)
685                 {
686                         if (MouseEnter != null) MouseEnter (this, e);
687                         
688                         if (this.CanSelect) {
689                                 this.is_selected = true;
690                                 this.Invalidate ();
691                         }
692                 }
693
694                 protected virtual void OnMouseHover (EventArgs e)
695                 {
696                         if (this.Enabled)
697                                 if (MouseHover != null) MouseHover (this, e);
698                 }
699
700                 protected virtual void OnMouseLeave (EventArgs e)
701                 {
702                         if (MouseLeave != null) MouseLeave (this, e);
703                         
704                         if (this.CanSelect) {
705                                 this.is_selected = false;
706                                 this.is_pressed = false;
707                                 this.Invalidate ();
708                         }
709                 }
710
711                 protected virtual void OnMouseMove (MouseEventArgs e)
712                 {
713                         if (this.Enabled)
714                                 if (MouseMove != null) MouseMove (this, e);
715                 }
716
717                 protected virtual void OnMouseUp (MouseEventArgs e)
718                 {
719                         if (this.Enabled) {
720                                 if (MouseUp != null) MouseUp (this, e);
721                                 this.is_pressed = false;
722                                 this.Invalidate ();
723                         }
724                 }
725
726                 protected virtual void OnOwnerChanged (EventArgs e)
727                 {
728                         if (OwnerChanged != null) OwnerChanged (this, e);
729                 }
730
731                 protected virtual void OnPaint (PaintEventArgs e)
732                 {
733                         if (Paint != null) Paint (this, e);
734                 }
735
736                 protected virtual void OnParentChanged (ToolStrip oldParent, ToolStrip newParent)
737                 {
738                 }
739                 
740                 protected virtual void OnTextChanged (EventArgs e)
741                 {
742                         if (TextChanged != null) TextChanged (this, e);
743                 }
744
745                 protected virtual void OnVisibleChanged (EventArgs e)
746                 {
747                         if (VisibleChanged != null) VisibleChanged (this, e);
748                 }
749
750                 protected internal virtual void SetBounds (Rectangle bounds)
751                 {
752                         if (this.bounds != bounds) {
753                                 this.bounds = bounds;
754                                 OnBoundsChanged ();
755                         }
756                 }
757                 #endregion
758
759                 #region Public Events
760                 [Browsable (false)]
761                 public event EventHandler AvailableChanged;
762                 public event EventHandler BackColorChanged;
763                 public event EventHandler Click;
764                 public event EventHandler DisplayStyleChanged;
765                 public event EventHandler DoubleClick;
766                 public event EventHandler EnabledChanged;
767                 public event EventHandler ForeColorChanged;
768                 public event EventHandler LocationChanged;
769                 public event MouseEventHandler MouseDown;
770                 public event EventHandler MouseEnter;
771                 public event EventHandler MouseHover;
772                 public event EventHandler MouseLeave;
773                 public event MouseEventHandler MouseMove;
774                 public event MouseEventHandler MouseUp;
775                 public event EventHandler OwnerChanged;
776                 public event PaintEventHandler Paint;
777                 public event EventHandler TextChanged;
778                 public event EventHandler VisibleChanged;
779                 #endregion
780
781                 #region Internal Methods
782                 internal Rectangle AlignInRectangle (Rectangle outer, Size inner, ContentAlignment align)
783                 {
784                         int x = 0;
785                         int y = 0;
786
787                         if (align == ContentAlignment.BottomLeft || align == ContentAlignment.MiddleLeft || align == ContentAlignment.TopLeft)
788                                 x = outer.X;
789                         else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.MiddleCenter || align == ContentAlignment.TopCenter)
790                                 x = Math.Max (outer.X + ((outer.Width - inner.Width) / 2), outer.Left);
791                         else if (align == ContentAlignment.BottomRight || align == ContentAlignment.MiddleRight || align == ContentAlignment.TopRight)
792                                 x = outer.Right - inner.Width;
793                         if (align == ContentAlignment.TopCenter || align == ContentAlignment.TopLeft || align == ContentAlignment.TopRight)
794                                 y = outer.Y;
795                         else if (align == ContentAlignment.MiddleCenter || align == ContentAlignment.MiddleLeft || align == ContentAlignment.MiddleRight)
796                                 y = outer.Y + (outer.Height - inner.Height) / 2;
797                         else if (align == ContentAlignment.BottomCenter || align == ContentAlignment.BottomRight || align == ContentAlignment.BottomLeft)
798                                 y = outer.Bottom - inner.Height;
799
800                         return new Rectangle (x, y, Math.Min (inner.Width, outer.Width), Math.Min (inner.Height, outer.Height));
801                 }
802
803                 internal void CalculateAutoSize ()
804                 {
805                         if (!this.auto_size || this is ToolStripControlHost)
806                                 return;
807
808                         this.text_size = TextRenderer.MeasureText (this.Text, this.Font);
809                         //this.text_size.Width += 6;
810
811                         Size final_size = this.CalculatePreferredSize (Size.Empty);
812
813                         if (final_size != this.Size) {
814                                 this.bounds.Size = final_size;
815                                 if (this.owner != null) 
816                                         this.owner.PerformLayout ();
817                         }
818                 }
819
820                 internal Size CalculatePreferredSize (Size constrainingSize)
821                 {
822                         Size preferred_size = this.DefaultSize;
823
824                         switch (this.display_style) {
825                                 case ToolStripItemDisplayStyle.Text:
826                                         int width = text_size.Width + this.padding.Horizontal;
827                                         int height = text_size.Height + this.padding.Vertical;
828                                         preferred_size = new Size (width, height);
829                                         break;
830                                 case ToolStripItemDisplayStyle.Image:
831                                         if (this.image == null)
832                                                 preferred_size = this.DefaultSize;
833                                         else {
834                                                 switch (this.image_scaling) {
835                                                         case ToolStripItemImageScaling.None:
836                                                                 preferred_size = this.image.Size;
837                                                                 break;
838                                                         case ToolStripItemImageScaling.SizeToFit:
839                                                                 if (this.owner == null)
840                                                                         preferred_size = this.image.Size;
841                                                                 else
842                                                                         preferred_size = this.owner.ImageScalingSize;
843                                                                 break;
844                                                 }
845                                         }
846                                         break;
847                                 case ToolStripItemDisplayStyle.ImageAndText:
848                                         int width2 = text_size.Width + this.padding.Horizontal;
849                                         int height2 = text_size.Height + this.padding.Vertical;
850
851                                         if (this.image != null) {
852                                                 switch (this.text_image_relation) {
853                                                         case TextImageRelation.Overlay:
854                                                                 width2 = Math.Max (width2, this.image.Width);
855                                                                 height2 = Math.Max (height2, this.image.Height);
856                                                                 break;
857                                                         case TextImageRelation.ImageAboveText:
858                                                         case TextImageRelation.TextAboveImage:
859                                                                 width2 = Math.Max (width2, this.image.Width);
860                                                                 height2 += this.image.Height;
861                                                                 break;
862                                                         case TextImageRelation.ImageBeforeText:
863                                                         case TextImageRelation.TextBeforeImage:
864                                                                 height2 = Math.Max (height2, this.image.Height);
865                                                                 width2 += this.image.Width;
866                                                                 break;
867                                                 }
868                                         }
869
870                                         preferred_size = new Size (width2, height2);
871                                         break;
872                         }
873
874                         if (!(this is ToolStripLabel)) {                // Everything but labels have a border
875                                 preferred_size.Height += 4;
876                                 preferred_size.Width += 4;
877                         }
878                         
879                         if (preferred_size.Width < 23)
880                                 preferred_size.Width = 23;              // There seems to be a minimum width of 23
881                         return preferred_size;
882                 }
883
884                 internal void CalculateTextAndImageRectangles (out Rectangle text_rect, out Rectangle image_rect)
885                 {
886                         text_rect = Rectangle.Empty;
887                         image_rect = Rectangle.Empty;
888
889                         switch (this.display_style) {
890                                 case ToolStripItemDisplayStyle.None:
891                                         break;
892                                 case ToolStripItemDisplayStyle.Text:
893                                         if (this.text != string.Empty)
894                                                 text_rect = AlignInRectangle (this.ContentRectangle, this.text_size, this.text_align);
895                                         break;
896                                 case ToolStripItemDisplayStyle.Image:
897                                         if (this.image != null)
898                                                 image_rect = AlignInRectangle (this.ContentRectangle, this.image.Size, this.image_align);
899                                         break;
900                                 case ToolStripItemDisplayStyle.ImageAndText:
901                                         if (this.text != string.Empty && this.image == null)
902                                                 text_rect = AlignInRectangle (this.ContentRectangle, this.text_size, this.text_align);
903                                         else if (this.text == string.Empty && this.image != null)
904                                                 image_rect = AlignInRectangle (this.ContentRectangle, this.image.Size, this.image_align);
905                                         else if (this.text == string.Empty && this.image == null)
906                                                 break;
907                                         else {
908                                                 Rectangle text_area;
909                                                 Rectangle image_area;
910
911                                                 switch (this.text_image_relation) {
912                                                         case TextImageRelation.Overlay:
913                                                                 text_rect = AlignInRectangle (this.ContentRectangle, this.text_size, this.text_align);
914                                                                 image_rect = AlignInRectangle (this.ContentRectangle, this.image.Size, this.image_align);
915                                                                 break;
916                                                         case TextImageRelation.ImageAboveText:
917                                                                 text_area = new Rectangle (this.ContentRectangle.Left, this.ContentRectangle.Bottom - (text_size.Height - 4), this.ContentRectangle.Width, text_size.Height - 4);
918                                                                 image_area = new Rectangle (this.ContentRectangle.Left, this.ContentRectangle.Top, this.ContentRectangle.Width, this.ContentRectangle.Height - text_area.Height);
919
920                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
921                                                                 image_rect = AlignInRectangle (image_area, this.image.Size, this.image_align);
922                                                                 break;
923                                                         case TextImageRelation.TextAboveImage:
924                                                                 text_area = new Rectangle (this.ContentRectangle.Left, this.ContentRectangle.Top, this.ContentRectangle.Width, text_size.Height - 4);
925                                                                 image_area = new Rectangle (this.ContentRectangle.Left, text_area.Bottom, this.ContentRectangle.Width, this.ContentRectangle.Height - text_area.Height);
926
927                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
928                                                                 image_rect = AlignInRectangle (image_area, this.image.Size, this.image_align);
929                                                                 break;
930                                                         case TextImageRelation.ImageBeforeText:
931                                                                 text_area = new Rectangle (this.ContentRectangle.Right - this.text_size.Width, this.ContentRectangle.Top, this.text_size.Width, this.ContentRectangle.Height);
932                                                                 image_area = new Rectangle (this.ContentRectangle.Left, this.ContentRectangle.Top, text_area.Left - this.ContentRectangle.Left, this.ContentRectangle.Height);
933
934                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
935                                                                 image_rect = AlignInRectangle (image_area, this.image.Size, this.image_align);
936                                                                 break;
937                                                         case TextImageRelation.TextBeforeImage:
938                                                                 text_area = new Rectangle (this.ContentRectangle.Left, this.ContentRectangle.Top, this.text_size.Width, this.ContentRectangle.Height);
939                                                                 image_area = new Rectangle (text_area.Right, this.ContentRectangle.Top, this.ContentRectangle.Width - text_area.Width, this.ContentRectangle.Height);
940
941                                                                 text_rect = AlignInRectangle (text_area, this.text_size, this.text_align);
942                                                                 image_rect = AlignInRectangle (image_area, this.image.Size, this.image_align);
943                                                                 break;
944                                                 }
945                                         }
946                                         break;
947                         }
948                 }
949
950                 internal void FireEvent (EventArgs e, ToolStripItemEventType met)
951                 {
952                         switch (met) {
953                                 case ToolStripItemEventType.MouseUp:
954                                         this.OnMouseUp ((MouseEventArgs)e);
955                                         this.OnClick ((MouseEventArgs)e);
956                                         break;
957                                 case ToolStripItemEventType.MouseDown:
958                                         this.OnMouseDown ((MouseEventArgs)e);
959                                         break;
960                                 case ToolStripItemEventType.MouseEnter:
961                                         this.OnMouseEnter (e);
962                                         break;
963                                 case ToolStripItemEventType.MouseHover:
964                                         this.OnMouseHover (e);
965                                         break;
966                                 case ToolStripItemEventType.MouseLeave:
967                                         this.OnMouseLeave (e);
968                                         break;
969                                 case ToolStripItemEventType.MouseMove:
970                                         this.OnMouseMove ((MouseEventArgs)e);
971                                         break;
972                                 case ToolStripItemEventType.Paint:
973                                         this.OnPaint ((PaintEventArgs)e);
974                                         break;
975                         }
976                 }
977                 #endregion
978                 
979                 public class ToolStripItemAccessibleObject : AccessibleObject
980                 {
981                         private ToolStripItem owner;
982                         
983                         public ToolStripItemAccessibleObject (ToolStripItem ownerItem)
984                         {
985                                 if (ownerItem == null)
986                                         throw new ArgumentNullException ("ownerItem");
987                                         
988                                 this.owner = ownerItem;
989                                 base.default_action = string.Empty;
990                                 base.keyboard_shortcut = string.Empty;
991                                 base.name = string.Empty;
992                                 base.value = string.Empty;
993                         }
994
995                         #region Public Properties
996                         public override Rectangle Bounds {
997                                 get {
998                                         return owner.Visible ? owner.Bounds : Rectangle.Empty;
999                                 }
1000                         }
1001
1002                         public override string DefaultAction {
1003                                 get { return base.DefaultAction; }
1004                         }
1005
1006                         public override string Description {
1007                                 get { return base.Description; }
1008                         }
1009
1010                         public override string Help {
1011                                 get { return base.Help; }
1012                         }
1013
1014                         public override string KeyboardShortcut {
1015                                 get { return base.KeyboardShortcut; }
1016                         }
1017
1018                         public override string Name {
1019                                 get {
1020                                         if (base.name == string.Empty)
1021                                                 return owner.Text;
1022                                                 
1023                                         return base.Name;
1024                                 }
1025                                 set { base.Name = value; }
1026                         }
1027
1028                         public override AccessibleObject Parent {
1029                                 get { return base.Parent; }
1030                         }
1031
1032                         public override AccessibleRole Role {
1033                                 get { return base.Role; }
1034                         }
1035
1036                         public override AccessibleStates State {
1037                                 get { return base.State; }
1038                         }
1039                         #endregion
1040
1041                         #region Public Methods
1042                         public void AddState (AccessibleStates state)
1043                         {
1044                                 base.state = state;
1045                         }
1046
1047                         public override void DoDefaultAction ()
1048                         {
1049                                 base.DoDefaultAction ();
1050                         }
1051
1052                         public override int GetHelpTopic (out string FileName)
1053                         {
1054                                 return base.GetHelpTopic (out FileName);
1055                         }
1056
1057                         public override AccessibleObject Navigate (AccessibleNavigation navdir)
1058                         {
1059                                 return base.Navigate (navdir);
1060                         }
1061
1062                         public override string ToString ()
1063                         {
1064                                 return string.Format ("ToolStripItemAccessibleObject: Owner = {0}", owner.ToString());
1065                         }
1066                         #endregion
1067                 }
1068         }
1069 }
1070 #endif