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