Grasshopper project system now uses csproj extension
[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                 [Browsable(false)]
99                 [EditorBrowsable(EditorBrowsableState.Never)]
100                 public new event KeyPressEventHandler KeyPress {
101                         add { base.KeyPress += value; }
102                         remove { base.KeyPress -= value; }
103                 }
104
105                 [Browsable(false)]
106                 [EditorBrowsable(EditorBrowsableState.Never)]
107                 public new event KeyEventHandler KeyUp {
108                         add { base.KeyUp += value; }
109                         remove { base.KeyUp -= value; }
110                 }
111
112                 [Browsable(false)]
113                 [EditorBrowsable(EditorBrowsableState.Never)]
114                 public new event EventHandler TabStopChanged {
115                         add { base.TabStopChanged += value; }
116                         remove { base.TabStopChanged -= value; }
117                 }
118
119                 public event EventHandler TextAlignChanged {
120                         add { Events.AddHandler (TextAlignChangedEvent, value); }
121                         remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
122                 }
123                 #endregion
124
125                 public Label ()
126                 {
127                         // Defaults in the Spec
128                         autosize = false;
129                         TabStop = false;
130                         string_format = new StringFormat();
131                         TextAlign = ContentAlignment.TopLeft;
132                         image = null;
133                         UseMnemonic = true;
134                         image_list = null;
135                         image_align = ContentAlignment.MiddleCenter;
136                         SetUseMnemonic (UseMnemonic);
137                         flat_style = FlatStyle.Standard;
138
139                         CalcPreferredHeight ();
140                         CalcPreferredWidth ();
141
142                         SetStyle (ControlStyles.Selectable, false);
143                         SetStyle (ControlStyles.ResizeRedraw | 
144                                 ControlStyles.UserPaint | 
145                                 ControlStyles.AllPaintingInWmPaint |
146                                 ControlStyles.SupportsTransparentBackColor
147 #if NET_2_0
148                                 | ControlStyles.OptimizedDoubleBuffer
149 #else
150                                 | ControlStyles.DoubleBuffer
151 #endif
152                                 , true);
153                         
154                         HandleCreated += new EventHandler (OnHandleCreatedLB);
155                 }
156
157                 #region Public Properties
158                 [DefaultValue(false)]
159                 [Localizable(true)]
160                 [RefreshProperties(RefreshProperties.All)]
161 #if NET_2_0
162                 [Browsable (true)]
163                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
164                 [EditorBrowsable (EditorBrowsableState.Always)]
165 #endif
166                 public new virtual bool AutoSize {
167                         get { return autosize; }
168                         set {
169                                 if (autosize == value)
170                                         return;
171
172                                 autosize = value;
173                                 CalcAutoSize ();
174                                 Refresh ();
175
176                                 OnAutoSizeChanged (EventArgs.Empty);                                    
177                         }
178                 }
179
180                 [Browsable(false)]
181                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
182                 [EditorBrowsable(EditorBrowsableState.Never)]
183                 public override Image BackgroundImage {
184                         get { return base.BackgroundImage; }
185                         set {
186                                 base.BackgroundImage = value;
187                                 Refresh ();
188                         }
189                 }
190
191                 [DefaultValue(BorderStyle.None)]
192                 [DispId(-504)]
193                 public virtual BorderStyle BorderStyle {
194                         get { return InternalBorderStyle; }
195                         set { InternalBorderStyle = value; }
196                 }
197
198                 protected override CreateParams CreateParams {
199                         get { 
200                                 CreateParams create_params = base.CreateParams;
201                                         
202                                 if (BorderStyle != BorderStyle.Fixed3D)
203                                         return create_params;
204                                         
205                                 create_params.ExStyle &= ~(int) WindowExStyles.WS_EX_CLIENTEDGE;
206                                 create_params.ExStyle |= (int)WindowExStyles.WS_EX_STATICEDGE;
207                                         
208                                 return create_params;
209                         }
210                 }
211
212                 protected override ImeMode DefaultImeMode {
213                         get { return ImeMode.Disable;}
214                 }
215
216                 protected override Size DefaultSize {
217                         get {return ThemeEngine.Current.LabelDefaultSize;}
218                 }
219
220                 [DefaultValue(FlatStyle.Standard)]
221                 public FlatStyle FlatStyle {
222                         get { return flat_style; }
223                         set {
224                                 if (!Enum.IsDefined (typeof (FlatStyle), value))
225                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for FlatStyle", value));
226
227                                 if (flat_style == value)
228                                         return;
229
230                                 flat_style = value;
231                                 Refresh ();
232                         }
233                 }
234
235                 [Localizable(true)]
236                 public Image Image {
237                         get {
238                                 if (image != null) {
239                                         return image;
240                                 }
241                                         
242                                 if (image_list != null && ImageIndex >= 0) {
243                                         return image_list.Images[ImageIndex];
244                                 }
245                                         
246                                 return null;
247                         }
248                         set {
249                                 if (image == value)
250                                         return;
251
252                                 image = value;
253                                 Refresh ();
254                         }
255                 }
256
257                 [DefaultValue(ContentAlignment.MiddleCenter)]
258                 [Localizable(true)]
259                 public ContentAlignment ImageAlign {
260                         get { return image_align; }
261                         set {
262                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
263                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
264
265                                 if (image_align == value)
266                                         return;
267
268                                 image_align = value;
269                                 Refresh ();
270                         }
271                 }
272
273                 [DefaultValue (-1)]
274                 [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
275                 [Localizable (true)]
276                 [TypeConverter (typeof (ImageIndexConverter))]
277 #if NET_2_0
278                 [RefreshProperties (RefreshProperties.Repaint)]
279 #endif
280                 public int ImageIndex {
281                         get { 
282                                 if (ImageList == null) {
283                                         return -1;
284                                 }
285                                         
286                                 if (image_index >= image_list.Images.Count) {
287                                         return image_list.Images.Count - 1;
288                                 }
289                                         
290                                 return image_index;
291                         }
292                         set {
293
294                                 if (value < -1)
295                                         throw new ArgumentException ();
296
297                                 if (image_index == value)
298                                         return;
299
300                                 image_index = value;
301
302                                 if (ImageList != null && image_index !=-1)
303                                         Image = null;
304
305                                 Refresh ();
306                         }
307                 }
308
309                 [DefaultValue(null)]
310 #if NET_2_0
311                 [RefreshProperties (RefreshProperties.Repaint)]
312 #endif
313                 public ImageList ImageList {
314                         get { return image_list;}
315                         set {
316                                 if (image_list == value)
317                                         return;
318                                         
319                                 image_list = value;
320
321                                 if (image_list != null && image_index !=-1)
322                                         Image = null;
323
324                                 Refresh ();
325                         }
326                 }
327
328                 [Browsable(false)]
329                 [EditorBrowsable(EditorBrowsableState.Never)]
330                 public new ImeMode ImeMode {
331                         get { return base.ImeMode; }
332                         set { base.ImeMode = value; }
333                 }
334
335                 [Browsable(false)]
336                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
337                 [EditorBrowsable(EditorBrowsableState.Advanced)]
338                 public virtual int PreferredHeight {
339                         get { return preferred_height; }
340                 }
341
342                 [Browsable(false)]
343                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
344                 [EditorBrowsable(EditorBrowsableState.Advanced)]
345                 public virtual int PreferredWidth {
346                         get {return preferred_width; }
347                 }
348
349 #if NET_2_0
350                 [Obsolete ("This property has been deprecated.  Use BackColor instead.")]
351 #endif
352                 protected virtual bool RenderTransparent {
353                         get { return render_transparent; }
354                         set { render_transparent = value;}
355                 }
356                         
357                 [Browsable(false)]
358                 [DefaultValue(false)]
359                 [EditorBrowsable(EditorBrowsableState.Never)]
360                 public new bool TabStop  {
361                         get { return base.TabStop; }
362                         set { base.TabStop = value; }
363                 }
364
365                 [DefaultValue(ContentAlignment.TopLeft)]
366                 [Localizable(true)]
367                 public virtual ContentAlignment TextAlign {
368                         get { return text_align; }
369
370                         set {
371                                 if (!Enum.IsDefined (typeof (ContentAlignment), value))
372                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
373
374                                         if (text_align != value) {
375
376                                                 text_align = value;
377
378                                                 switch (value) {
379
380                                                 case ContentAlignment.BottomLeft:
381                                                         string_format.LineAlignment = StringAlignment.Far;
382                                                         string_format.Alignment = StringAlignment.Near;
383                                                         break;
384                                                 case ContentAlignment.BottomCenter:
385                                                         string_format.LineAlignment = StringAlignment.Far;
386                                                         string_format.Alignment = StringAlignment.Center;
387                                                         break;
388                                                 case ContentAlignment.BottomRight:
389                                                         string_format.LineAlignment = StringAlignment.Far;
390                                                 string_format.Alignment = StringAlignment.Far;
391                                                 break;
392                                         case ContentAlignment.TopLeft:
393                                                 string_format.LineAlignment = StringAlignment.Near;
394                                                 string_format.Alignment = StringAlignment.Near;
395                                                 break;
396                                         case ContentAlignment.TopCenter:
397                                                 string_format.LineAlignment = StringAlignment.Near;
398                                                 string_format.Alignment = StringAlignment.Center;
399                                                 break;
400                                         case ContentAlignment.TopRight:
401                                                 string_format.LineAlignment = StringAlignment.Near;
402                                                 string_format.Alignment = StringAlignment.Far;
403                                                 break;
404                                         case ContentAlignment.MiddleLeft:
405                                                 string_format.LineAlignment = StringAlignment.Center;
406                                                 string_format.Alignment = StringAlignment.Near;
407                                                 break;
408                                                 case ContentAlignment.MiddleRight:
409                                                         string_format.LineAlignment = StringAlignment.Center;
410                                                         string_format.Alignment = StringAlignment.Far;
411                                                         break;
412                                                 case ContentAlignment.MiddleCenter:
413                                                         string_format.LineAlignment = StringAlignment.Center;
414                                                         string_format.Alignment = StringAlignment.Center;
415                                                 break;
416                                         default:
417                                                 break;
418                                         }
419
420                                         OnTextAlignChanged (EventArgs.Empty);
421                                                 Refresh();
422                                 }
423                         }
424                 }
425
426                 [DefaultValue(true)]
427                 public bool UseMnemonic {
428                         get { return use_mnemonic; }
429                         set {
430                                 if (use_mnemonic != value) {
431                                         use_mnemonic = value;
432                                         SetUseMnemonic (use_mnemonic);
433                                         Refresh ();
434                                 }
435                         }
436                 }
437
438                 #endregion
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                 protected override AccessibleObject CreateAccessibilityInstance ()
481                 {
482                         return base.CreateAccessibilityInstance ();
483                 }
484
485                 protected override void Dispose(bool disposing)
486                 {
487                         base.Dispose (disposing);
488
489                         if (disposing)
490                                 string_format.Dispose ();
491                 }
492
493                 protected void DrawImage (Graphics g, Image image, Rectangle area, ContentAlignment img_align)
494                 {
495                         if (image == null || g == null)
496                                 return;
497
498                         Rectangle rcImageClip = CalcImageRenderBounds (image, area, img_align);
499
500                         if (Enabled)
501                                 g.DrawImage (image, rcImageClip.X, rcImageClip.Y, rcImageClip.Width, rcImageClip.Height);
502                         else
503                                 ControlPaint.DrawImageDisabled (g, image, rcImageClip.X, rcImageClip.Y, BackColor);
504                 }
505
506 #if !NET_2_0
507                 protected virtual void OnAutoSizeChanged (EventArgs e)
508                 {
509                         EventHandler eh = (EventHandler)(Events [AutoSizeChangedEvent]);
510                         if (eh != null)
511                                 eh (this, e);
512                 }
513 #endif
514
515                 protected override void OnEnabledChanged (EventArgs e)
516                 {
517                         base.OnEnabledChanged (e);
518                 }
519
520                 protected override void OnFontChanged (EventArgs e)
521                 {
522                         base.OnFontChanged (e);
523                         if (autosize) {
524                                 CalcAutoSize();
525                         } else {
526                                 CalcPreferredHeight ();
527                         }
528                         Refresh ();
529                 }
530
531                 protected override void OnPaint (PaintEventArgs pevent)
532                 {
533                         ThemeEngine.Current.DrawLabel (pevent.Graphics, ClientRectangle, this);
534                         DrawImage (pevent.Graphics, Image, ClientRectangle, image_align);
535                         base.OnPaint(pevent);
536                 }
537
538                 protected override void OnParentChanged (EventArgs e)
539                 {
540                                 base.OnParentChanged (e);
541                 }
542
543                 protected virtual void OnTextAlignChanged (EventArgs e)
544                 {
545                         EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
546                         if (eh != null)
547                                 eh (this, e);
548                 }
549
550                 protected override void OnTextChanged (EventArgs e)
551                 {
552                         base.OnTextChanged (e);                 
553                         if (autosize) {
554                                 CalcAutoSize ();
555                         } else {
556                                 CalcPreferredWidth ();
557                         }
558                         Refresh ();
559                 }
560
561                 protected override void OnVisibleChanged (EventArgs e)
562                 {
563                         base.OnVisibleChanged (e);
564                 }
565
566                 protected override bool ProcessMnemonic (char charCode)
567                 {
568                         if (IsMnemonic(charCode, Text) == true) {
569                                 // Select item next in line in tab order
570                                 if (this.Parent != null) {
571                                         Parent.SelectNextControl(this, true, false, false, false);
572                                 }
573                                 return true;
574                         }
575                         
576                         return base.ProcessMnemonic (charCode);
577                 }
578
579                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
580                 {
581                         base.SetBoundsCore (x, y, width, height, specified);
582                 }
583
584                 public override string ToString()
585                 {
586                         return base.ToString () + ", Text: " + Text;
587                 }
588
589                 protected override void WndProc (ref Message m)
590                 {
591                         switch ((Msg) m.Msg) {
592                                 case Msg.WM_DRAWITEM: {
593                                         m.Result = (IntPtr)1;
594                                 }
595                                         break;
596                                 default:
597                                         base.WndProc (ref m);
598                                         break;
599                         }
600                 }
601
602                 #endregion Public Methods
603
604                 #region Private Methods
605
606                 private void CalcAutoSize ()
607                 {
608                         if (IsHandleCreated == false || AutoSize == false)
609                                 return;
610
611                         CalcPreferredWidth ();
612                         CalcPreferredHeight ();
613
614                         Width =  PreferredWidth;
615                         Height =  PreferredHeight;                              
616                 }
617
618                 private void CalcPreferredHeight ()
619                 {
620                         preferred_height = Font.Height;
621
622 #if NET_2_0
623                         if (!use_compatible_text_rendering)
624                                 return; 
625 #endif
626
627                         switch (border_style) {
628                         case BorderStyle.None:
629                                 preferred_height += 3;
630                                 break;
631                         case BorderStyle.FixedSingle:
632                         case BorderStyle.Fixed3D:
633                                 preferred_height += 6;
634                                 break;
635                         default:
636                                 break;
637                         }
638                 }
639
640                 private void CalcPreferredWidth ()
641                 {
642                         if (Text == string.Empty) {
643                                 preferred_width = 0;
644                         }
645                         else {
646                                 SizeF size;
647                                 size = DeviceContext.MeasureString (Text, Font, req_witdthsize, string_format);
648                                 preferred_width = (int) size.Width + 3;
649                         }
650                 }
651
652                 private void OnHandleCreatedLB (Object o, EventArgs e)
653                 {
654                         if (autosize)
655                                 CalcAutoSize ();
656                 }
657
658                 private void SetUseMnemonic (bool use)
659                 {
660                         if (use)
661                                 string_format.HotkeyPrefix = HotkeyPrefix.Show;
662                         else
663                                 string_format.HotkeyPrefix = HotkeyPrefix.None;
664                 }
665
666                 #endregion Private Methods
667 #if NET_2_0
668                 [DefaultValue (false)]
669                 public bool UseCompatibleTextRendering {
670                         get { return use_compatible_text_rendering; }
671                         set { use_compatible_text_rendering = value; }
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 { return base.Text; }
679                         set { base.Text = value; }
680                 }
681
682                 protected override void OnMouseEnter (EventArgs e)
683                 {
684                         base.OnMouseEnter (e);
685                 }
686
687                 protected override void OnMouseLeave (EventArgs e)
688                 {
689                         base.OnMouseLeave (e);
690                 }
691
692                 protected override void OnHandleDestroyed (EventArgs e)
693                 {
694                         base.OnHandleDestroyed (e);
695                 }
696 #endif
697
698         }
699 }