make another pass at corcompare, mostly attributes on classes/properties/events/etc
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Label.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //      Peter Bartok, pbartok@novell.com
25 //
26 //
27
28 // COMPLETE
29
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.Drawing;
33 using System.Drawing.Text;
34 using System.Drawing.Imaging;
35 using System.Runtime.InteropServices;
36
37 namespace System.Windows.Forms
38 {
39         [DefaultProperty ("Text")]
40         [Designer ("System.Windows.Forms.Design.LabelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41 #if NET_2_0
42         [ClassInterface (ClassInterfaceType.AutoDispatch)]
43         [ComVisible (true)]
44         [ToolboxItem (true)]
45         [DefaultBindingProperty ("Text")]
46 #endif
47         public class Label : Control
48         {
49                 private bool autosize;
50                 private Image image;
51                 private bool render_transparent;
52                 private FlatStyle flat_style;
53                 private int preferred_height;
54                 private int preferred_width;
55                 private bool use_mnemonic;
56                 private int image_index = -1;
57                 private ImageList image_list;
58                 internal ContentAlignment image_align;
59                 internal StringFormat string_format;
60                 internal ContentAlignment text_align;
61                 static SizeF req_witdthsize = new SizeF (0,0);
62
63                 #region Events
64                 static object AutoSizeChangedEvent = new object ();
65                 static object TextAlignChangedEvent = new object ();
66
67 #if NET_2_0
68
69                 [Browsable (true)]
70                 [EditorBrowsable (EditorBrowsableState.Always)]
71 #endif
72                 public new event EventHandler AutoSizeChanged {
73                         add { Events.AddHandler (AutoSizeChangedEvent, value); }
74                         remove { Events.RemoveHandler (AutoSizeChangedEvent, value); }
75                 }
76
77                 [Browsable(false)]
78                 [EditorBrowsable(EditorBrowsableState.Never)]
79                 public new event EventHandler BackgroundImageChanged {
80                         add { base.BackgroundImageChanged += value; }
81                         remove { base.BackgroundImageChanged -= value; }
82                 }
83
84                 [Browsable(false)]
85                 [EditorBrowsable(EditorBrowsableState.Never)]
86                 public new event EventHandler ImeModeChanged {
87                         add { base.ImeModeChanged += value; }
88                         remove { base.ImeModeChanged -= value; }
89                 }
90
91                 [Browsable(false)]
92                 [EditorBrowsable(EditorBrowsableState.Never)]
93                 public new event KeyEventHandler KeyDown {
94                         add { base.KeyDown += value; }
95                         remove { base.KeyDown -= value; }
96                 }
97
98
99                 [Browsable(false)]
100                 [EditorBrowsable(EditorBrowsableState.Never)]
101                 public new event KeyPressEventHandler KeyPress {
102                         add { base.KeyPress += value; }
103                         remove { base.KeyPress -= value; }
104                 }
105
106
107                 [Browsable(false)]
108                 [EditorBrowsable(EditorBrowsableState.Never)]
109                 public new event KeyEventHandler KeyUp {
110                         add { base.KeyUp += value; }
111                         remove { base.KeyUp -= value; }
112                 }
113
114
115                 [Browsable(false)]
116                 [EditorBrowsable(EditorBrowsableState.Never)]
117                 public new event EventHandler TabStopChanged {
118                         add { base.TabStopChanged += value; }
119                         remove { base.TabStopChanged -= value; }
120                 }
121
122                 public event EventHandler TextAlignChanged {
123                         add { Events.AddHandler (TextAlignChangedEvent, value); }
124                         remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
125                 }
126                 #endregion
127
128                 public Label ()
129                 {
130                         // Defaults in the Spec
131                         autosize = false;
132                         TabStop = false;
133                         string_format = new StringFormat();
134                         TextAlign = ContentAlignment.TopLeft;
135                         image = null;
136                         UseMnemonic = true;
137                         image_list = null;
138                         image_align = ContentAlignment.MiddleCenter;
139                         SetUseMnemonic (UseMnemonic);
140                         flat_style = FlatStyle.Standard;
141
142                         CalcPreferredHeight ();
143                         CalcPreferredWidth ();
144
145                         SetStyle (ControlStyles.Selectable, false);
146                         SetStyle (ControlStyles.ResizeRedraw | 
147                                 ControlStyles.UserPaint | 
148                                 ControlStyles.AllPaintingInWmPaint |
149                                 ControlStyles.SupportsTransparentBackColor
150 #if NET_2_0
151                                 | ControlStyles.OptimizedDoubleBuffer
152 #else
153                                 | ControlStyles.DoubleBuffer
154 #endif
155                                 , true);
156                         
157                         HandleCreated += new EventHandler (OnHandleCreatedLB);
158                 }
159
160                 #region Public Properties
161                 [DefaultValue(false)]
162                 [Localizable(true)]
163                 [RefreshProperties(RefreshProperties.All)]
164 #if NET_2_0
165                 [Browsable (true)]
166                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
167                 [EditorBrowsable (EditorBrowsableState.Always)]
168 #endif
169                 public new virtual bool AutoSize {
170                         get { return autosize; }
171                         set {
172                                 if (autosize == value)
173                                         return;
174
175                                 autosize = value;
176                                 CalcAutoSize ();
177                                 Refresh ();
178
179                                 OnAutoSizeChanged (EventArgs.Empty);                                    
180                         }
181                 }
182
183                 [Browsable(false)]
184                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
185                 [EditorBrowsable(EditorBrowsableState.Never)]
186                 public override Image BackgroundImage {
187                         get {
188                                 return base.BackgroundImage;
189                         }
190                         set {
191                                 base.BackgroundImage = value;
192                                 Refresh ();
193                         }
194                 }
195
196                 [DefaultValue(BorderStyle.None)]
197                 [DispId(-504)]
198                 public virtual BorderStyle BorderStyle {
199                         get { return InternalBorderStyle; }
200                         set { InternalBorderStyle = value; }
201                 }
202
203                 protected override CreateParams CreateParams {
204                         get { return base.CreateParams;}
205                 }
206
207                 protected override ImeMode DefaultImeMode {
208                         get { return ImeMode.Disable;}
209                 }
210
211                 protected override Size DefaultSize {
212                         get {return ThemeEngine.Current.LabelDefaultSize;}
213                 }
214
215                 [DefaultValue(FlatStyle.Standard)]
216                 public FlatStyle FlatStyle {
217                         get {
218                                 return flat_style;
219                         }
220                         set {
221                                 if (!Enum.IsDefined (typeof (FlatStyle), value))
222                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for FlatStyle", value));
223
224                                 if (flat_style == value)
225                                         return;
226
227                                 flat_style = value;
228                                 Refresh ();
229                         }
230                 }
231
232                 [Localizable(true)]
233                 public Image Image {
234                         get {
235                                 if (image != null) {
236                                         return image;
237                                 }
238                                 
239                                 if (image_list != null && ImageIndex >= 0) {
240                                         return image_list.Images[ImageIndex];
241                                 }
242                                 
243                                 return null;
244                         }
245                         set {
246                                 if (image == value)
247                                         return;
248
249                                 image = value;
250                                 Refresh ();
251                         }
252                 }
253
254                 [DefaultValue(ContentAlignment.MiddleCenter)]
255                 [Localizable(true)]
256                 public ContentAlignment ImageAlign {
257                         get {
258                                 return image_align;
259                         }
260                         set {
261                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
262                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
263
264                                 if (image_align == value)
265                                         return;
266
267                                 image_align = value;
268                                 Refresh ();
269                         }
270                 }
271
272                 [DefaultValue (-1)]
273                 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
274                 [Localizable (true)]
275                 [TypeConverter (typeof (ImageIndexConverter))]
276 #if NET_2_0
277                 [RefreshProperties (RefreshProperties.Repaint)]
278 #endif
279                 public int ImageIndex {
280                         get { 
281                                 if (ImageList == null) {
282                                         return -1;
283                                 }
284                                 
285                                 if (image_index >= image_list.Images.Count) {
286                                         return image_list.Images.Count - 1;
287                                 }
288                                 
289                                 return image_index;
290                         }
291                         set {
292
293                                 if (value < -1)
294                                         throw new ArgumentException ();
295
296                                 if (image_index == value)
297                                         return;
298
299                                 image_index = value;
300
301                                 if (ImageList != null && image_index !=-1)
302                                         Image = null;
303
304                                 Refresh ();
305                         }
306                 }
307
308                 [DefaultValue(null)]
309 #if NET_2_0
310                 [RefreshProperties (RefreshProperties.Repaint)]
311 #endif
312                 public ImageList ImageList {
313                         get { return image_list;}
314                         set {
315                                 if (image_list == value)
316                                         return;
317                                         
318                                 image_list = value;
319
320                                 if (image_list != null && image_index !=-1)
321                                         Image = null;
322
323                                 Refresh ();
324                         }
325                 }
326
327                 [Browsable(false)]
328                 [EditorBrowsable(EditorBrowsableState.Never)]
329                 public new ImeMode ImeMode {
330                         get { return base.ImeMode; }
331                         set { base.ImeMode = value; }
332                 }
333
334                 [Browsable(false)]
335                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
336                 [EditorBrowsable(EditorBrowsableState.Advanced)]
337                 public virtual int PreferredHeight {
338                         get { return preferred_height; }
339                 }
340
341                 [Browsable(false)]
342                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
343                 [EditorBrowsable(EditorBrowsableState.Advanced)]
344                 public virtual int PreferredWidth {
345                         get {return preferred_width; }
346                 }
347
348 #if NET_2_0
349                 [Obsolete ("This property has been deprecated.  Use BackColor instead.")]
350 #endif
351                 protected virtual bool RenderTransparent {
352                         get { return render_transparent; }
353                         set { render_transparent = value;}
354                 }
355                 
356                 [Browsable(false)]
357                 [DefaultValue(false)]
358                 [EditorBrowsable(EditorBrowsableState.Never)]
359                 public new bool TabStop  {
360                         get { return base.TabStop; }
361                         set { base.TabStop = value; }
362                 }
363
364                 [DefaultValue(ContentAlignment.TopLeft)]
365                 [Localizable(true)]
366                 public virtual ContentAlignment TextAlign {
367                         get { return text_align; }
368
369                         set {
370                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
371                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
372
373                                 if (text_align != value) {
374
375                                         text_align = value;
376
377                                         switch (value) {
378
379                                         case ContentAlignment.BottomLeft:
380                                                 string_format.LineAlignment = StringAlignment.Far;
381                                                 string_format.Alignment = StringAlignment.Near;
382                                                 break;
383                                         case ContentAlignment.BottomCenter:
384                                                 string_format.LineAlignment = StringAlignment.Far;
385                                                 string_format.Alignment = StringAlignment.Center;
386                                                 break;
387                                         case ContentAlignment.BottomRight:
388                                                 string_format.LineAlignment = StringAlignment.Far;
389                                                 string_format.Alignment = StringAlignment.Far;
390                                                 break;
391                                         case ContentAlignment.TopLeft:
392                                                 string_format.LineAlignment = StringAlignment.Near;
393                                                 string_format.Alignment = StringAlignment.Near;
394                                                 break;
395                                         case ContentAlignment.TopCenter:
396                                                 string_format.LineAlignment = StringAlignment.Near;
397                                                 string_format.Alignment = StringAlignment.Center;
398                                                 break;
399                                         case ContentAlignment.TopRight:
400                                                 string_format.LineAlignment = StringAlignment.Near;
401                                                 string_format.Alignment = StringAlignment.Far;
402                                                 break;
403                                         case ContentAlignment.MiddleLeft:
404                                                 string_format.LineAlignment = StringAlignment.Center;
405                                                 string_format.Alignment = StringAlignment.Near;
406                                                 break;
407                                         case ContentAlignment.MiddleRight:
408                                                 string_format.LineAlignment = StringAlignment.Center;
409                                                 string_format.Alignment = StringAlignment.Far;
410                                                 break;
411                                         case ContentAlignment.MiddleCenter:
412                                                 string_format.LineAlignment = StringAlignment.Center;
413                                                 string_format.Alignment = StringAlignment.Center;
414                                                 break;
415                                         default:
416                                                 break;
417                                         }
418
419                                         OnTextAlignChanged (EventArgs.Empty);
420                                         Refresh();
421                                 }
422                         }
423                 }
424
425                 [DefaultValue(true)]
426                 public bool UseMnemonic {
427                         get { return use_mnemonic; }
428                         set {
429                                 if (use_mnemonic != value) {
430                                         use_mnemonic = value;
431                                         SetUseMnemonic (use_mnemonic);
432                                         Refresh ();
433                                 }
434                         }
435                 }
436
437                 #endregion
438
439
440                 #region Public Methods
441
442                 protected Rectangle CalcImageRenderBounds (Image image, Rectangle area, ContentAlignment img_align)
443                 {
444                         Rectangle rcImageClip = area;
445                         rcImageClip.Inflate (-2,-2);
446
447                         int X = area.X;
448                         int Y = area.Y;
449
450                         if (img_align == ContentAlignment.TopCenter ||
451                                 img_align == ContentAlignment.MiddleCenter ||
452                                 img_align == ContentAlignment.BottomCenter) {
453                                 X += (area.Width - image.Width) / 2;
454                         }
455                         else if (img_align == ContentAlignment.TopRight ||
456                                 img_align == ContentAlignment.MiddleRight||
457                                 img_align == ContentAlignment.BottomRight) {
458                                 X += (area.Width - image.Width);
459                         }
460
461                         if( img_align == ContentAlignment.BottomCenter ||
462                                 img_align == ContentAlignment.BottomLeft ||
463                                 img_align == ContentAlignment.BottomRight) {
464                                 Y += area.Height - image.Height;
465                         }
466                         else if(img_align == ContentAlignment.MiddleCenter ||
467                                         img_align == ContentAlignment.MiddleLeft ||
468                                         img_align == ContentAlignment.MiddleRight) {
469                                 Y += (area.Height - image.Height) / 2;
470                         }
471
472                         rcImageClip.X = X;
473                         rcImageClip.Y = Y;
474                         rcImageClip.Width = image.Width;
475                         rcImageClip.Height = image.Height;
476
477                         return rcImageClip;
478                 }
479
480                 
481                 protected override AccessibleObject CreateAccessibilityInstance ()
482                 {
483                         return base.CreateAccessibilityInstance ();
484                 }
485
486                 protected override void Dispose(bool disposing)
487                 {
488                         base.Dispose (disposing);
489
490                         if (disposing)
491                                 string_format.Dispose ();
492                 }
493
494                 protected void DrawImage (Graphics g, Image image, Rectangle area, ContentAlignment img_align)
495                 {
496                         if (image == null || g == null)
497                                 return;
498
499                         Rectangle rcImageClip = CalcImageRenderBounds (image, area, img_align);
500
501                         if (Enabled)
502                                 g.DrawImage (image, rcImageClip.X, rcImageClip.Y, rcImageClip.Width, rcImageClip.Height);
503                         else
504                                 ControlPaint.DrawImageDisabled (g, image, rcImageClip.X, rcImageClip.Y, BackColor);
505                 }
506
507                 protected virtual void OnAutoSizeChanged (EventArgs e)
508                 {
509                         EventHandler eh = (EventHandler)(Events [AutoSizeChangedEvent]);
510                         if (eh != null)
511                                 eh (this, e);
512                 }
513
514                 protected override void OnEnabledChanged (EventArgs e)
515                 {
516                         base.OnEnabledChanged (e);
517                 }
518
519                 protected override void OnFontChanged (EventArgs e)
520                 {
521                         base.OnFontChanged (e);
522                         if (autosize) {
523                                 CalcAutoSize();
524                         } else {
525                                 CalcPreferredHeight ();
526                         }
527                         Refresh ();
528                 }
529
530                 protected override void OnPaint (PaintEventArgs pevent)
531                 {
532                         ThemeEngine.Current.DrawLabel (pevent.Graphics, ClientRectangle, this);
533                         DrawImage (pevent.Graphics, Image, ClientRectangle, image_align);
534                         base.OnPaint(pevent);
535                 }
536
537                 protected override void OnParentChanged (EventArgs e)
538                 {
539                         base.OnParentChanged (e);
540                 }
541
542                 protected virtual void OnTextAlignChanged (EventArgs e)
543                 {
544                         EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
545                         if (eh != null)
546                                 eh (this, e);
547                 }
548
549                 protected override void OnTextChanged (EventArgs e)
550                 {
551                         base.OnTextChanged (e);                 
552                         if (autosize) {
553                                 CalcAutoSize ();
554                         } else {
555                                 CalcPreferredWidth ();
556                         }
557                         Refresh ();
558                 }
559
560                 protected override void OnVisibleChanged (EventArgs e)
561                 {
562                         base.OnVisibleChanged (e);
563                 }
564
565                 protected override bool ProcessMnemonic (char charCode)
566                 {
567                         if (IsMnemonic(charCode, Text) == true) {
568                                 // Select item next in line in tab order
569                                 if (this.Parent != null) {
570                                         Parent.SelectNextControl(this, true, false, false, false);
571                                 }
572                                 return true;
573                         }
574                         
575                         return base.ProcessMnemonic (charCode);
576                 }
577
578                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
579                 {
580                         base.SetBoundsCore (x, y, width, height, specified);
581                 }
582
583                 public override string ToString()
584                 {
585                         return base.ToString () + ", Text: " + Text;
586                 }
587
588                 protected override void WndProc (ref Message m)
589                 {
590                         switch ((Msg) m.Msg) {
591                                 case Msg.WM_DRAWITEM: {
592                                         m.Result = (IntPtr)1;
593                                 }
594                                         break;
595                                 default:
596                                         base.WndProc (ref m);
597                                         break;
598                         }
599                 }
600
601                 #endregion Public Methods
602
603                 #region Private Methods
604
605                 private void CalcAutoSize ()
606                 {
607                         if (IsHandleCreated == false || AutoSize == false)
608                                 return;
609
610                         CalcPreferredWidth ();
611                         CalcPreferredHeight ();
612
613                         Width =  PreferredWidth;
614                         Height =  PreferredHeight;                      
615                 }
616
617                 private void CalcPreferredHeight ()
618                 {
619                         preferred_height = Font.Height;
620
621                         switch (border_style) {
622                         case BorderStyle.None:
623                                 preferred_height += 3;
624                                 break;
625                         case BorderStyle.FixedSingle:
626                         case BorderStyle.Fixed3D:
627                                 preferred_height += 6;
628                                 break;
629                         default:
630                                 break;
631                         }
632
633                 }
634
635                 private void CalcPreferredWidth ()
636                 {
637                         if (Text == string.Empty) {
638                                 preferred_width = 0;
639                         }
640                         else {
641                                 SizeF size;
642                                 size = DeviceContext.MeasureString (Text, Font, req_witdthsize, string_format);
643                                 preferred_width = (int) size.Width + 3;
644                         }
645                 }
646
647                 private void OnHandleCreatedLB (Object o, EventArgs e)
648                 {
649                         if (autosize)
650                                 CalcAutoSize ();
651                 }
652
653                 private void SetUseMnemonic (bool use)
654                 {
655                         if (use)
656                                 string_format.HotkeyPrefix = HotkeyPrefix.Show;
657                         else
658                                 string_format.HotkeyPrefix = HotkeyPrefix.None;
659                 }
660
661                 #endregion Private Methods
662 #if NET_2_0
663                 [DefaultValue (false)]
664                 public bool UseCompatibleTextRendering {
665                         get {
666                                 return use_compatible_text_rendering;
667                         }
668
669                         set {
670                                 use_compatible_text_rendering = value;
671                         }
672                 }
673
674                 [SettingsBindable (true)]
675                 [Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design,
676                          typeof (System.Drawing.Design.UITypeEditor))]
677                 public override string Text {
678                         get {
679                                 return base.Text;
680                         }
681
682                         set {
683                                 base.Text = value;
684                         }
685                 }
686
687                 protected override void OnMouseEnter (EventArgs e)
688                 {
689                         base.OnMouseEnter (e);
690                 }
691
692                 protected override void OnMouseLeave (EventArgs e)
693                 {
694                         base.OnMouseLeave (e);
695                 }
696
697                 protected override void OnHandleDestroyed (EventArgs e)
698                 {
699                         base.OnHandleDestroyed (e);
700                 }
701 #endif
702
703         }
704 }