**** Merged from MCS ****
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Label.cs
blobefbe61a0b3cb8eac9f40bdfc8c8e506c7d322f3d
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.
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.
20 // Copyright (c) 2004 Novell, Inc.
22 // Authors:
23 // Jordi Mas i Hernandez, jordi@ximian.com
24 // Peter Bartok, pbartok@novell.com
27 // $Revision: 1.16 $
28 // $Modtime: $
29 // $Log: Label.cs,v $
30 // Revision 1.16 2004/10/05 04:56:11 jackson
31 // Let the base Control handle the buffers, derived classes should not have to CreateBuffers themselves.
33 // Revision 1.15 2004/09/28 18:44:25 pbartok
34 // - Streamlined Theme interfaces:
35 // * Each DrawXXX method for a control now is passed the object for the
36 // control to be drawn in order to allow accessing any state the theme
37 // might require
39 // * ControlPaint methods for the theme now have a CP prefix to avoid
40 // name clashes with the Draw methods for controls
42 // * Every control now retrieves it's DefaultSize from the current theme
44 // Revision 1.14 2004/09/07 09:40:15 jordi
45 // LinkLabel fixes, methods, multiple links
47 // Revision 1.13 2004/09/04 17:10:18 jordi
48 // Refresh when font changed
50 // Revision 1.12 2004/09/01 15:10:10 jordi
51 // fixes method signatures, new methods, events, fixes autosize
53 // Revision 1.11 2004/08/21 22:30:53 pbartok
54 // - Signature fixes
56 // Revision 1.10 2004/08/21 22:21:13 pbartok
57 // - Signature fixes
59 // Revision 1.9 2004/08/11 18:54:11 pbartok
60 // - Forcing redraw on resize
62 // Revision 1.8 2004/08/10 15:24:35 jackson
63 // Let Control handle buffering.
65 // Revision 1.7 2004/08/08 19:47:41 jordi
66 // add cvs header info
69 // INCOMPLETE
71 using System.Drawing;
72 using System.Drawing.Text;
73 using System.Drawing.Imaging;
74 using System.ComponentModel;
76 namespace System.Windows.Forms
78 public class Label : Control
80 private BorderStyle border_style;
81 private bool autosize;
82 private Image image;
83 private bool render_transparent;
84 private FlatStyle flat_style;
85 private int preferred_height;
86 private int preferred_width;
87 private bool use_mnemonic;
88 private int image_index = -1;
89 private ImageList image_list;
90 internal ContentAlignment image_align;
91 internal StringFormat string_format;
92 internal ContentAlignment text_align;
93 static SizeF req_witdthsize = new SizeF (0,0);
95 #region Events
96 public event EventHandler AutoSizeChanged;
97 public new event EventHandler BackgroundImageChanged;
98 public new event EventHandler ImeModeChanged;
99 public new event KeyEventHandler KeyDown;
100 public new event KeyPressEventHandler KeyPress;
101 public new event KeyEventHandler KeyUp;
102 public new event EventHandler TabStopChanged;
103 public event EventHandler TextAlignChanged;
104 #endregion
106 public Label ()
108 // Defaults in the Spec
109 autosize = false;
110 border_style = BorderStyle.None;
111 string_format = new StringFormat();
112 TextAlign = ContentAlignment.TopLeft;
113 image = null;
114 UseMnemonic = true;
115 image_list = null;
116 image_align = ContentAlignment.MiddleCenter;
117 SetUseMnemonic (UseMnemonic);
119 BackColor = ThemeEngine.Current.ColorButtonFace;
120 ForeColor = ThemeEngine.Current.ColorWindowText;
122 CalcPreferredHeight ();
123 CalcPreferredWidth ();
125 AutoSizeChanged = null;
126 TextAlignChanged = null;
128 SetStyle (ControlStyles.ResizeRedraw, true);
130 Resize += new EventHandler (OnResizeLB);
131 HandleCreated += new EventHandler (OnHandleCreatedLB);
134 #region Public Properties
136 public virtual bool AutoSize {
137 get { return autosize; }
138 set {
139 if (autosize == value)
140 return;
142 autosize = value;
143 CalcAutoSize ();
144 Refresh ();
146 if (AutoSizeChanged != null)
147 AutoSizeChanged (this, new EventArgs ());
151 public override Image BackgroundImage {
152 get {
153 return base.BackgroundImage;
155 set {
156 if (base.BackgroundImage == value)
157 return;
159 if (BackgroundImageChanged != null)
160 BackgroundImageChanged (this, EventArgs.Empty);
162 base.BackgroundImage = value;
163 Refresh ();
167 public virtual BorderStyle BorderStyle {
168 get {
169 return border_style;
171 set {
172 if (!Enum.IsDefined (typeof (BorderStyle), value))
173 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
175 if (border_style == value)
176 return;
178 border_style = value;
179 Refresh ();
183 protected override CreateParams CreateParams {
184 get { return base.CreateParams;}
187 protected override ImeMode DefaultImeMode {
188 get { return ImeMode.Disable;}
191 protected override Size DefaultSize {
192 get {return ThemeEngine.Current.LabelDefaultSize;}
195 public FlatStyle FlatStyle {
196 get {
197 return flat_style;
199 set {
200 if (!Enum.IsDefined (typeof (FlatStyle), value))
201 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for FlatStyle", value));
203 if (flat_style == value)
204 return;
206 flat_style = value;
207 Refresh ();
211 public Image Image {
212 get {
213 return image;
215 set {
216 if (image == value)
217 return;
219 image = value;
220 Refresh ();
224 public ContentAlignment ImageAlign {
225 get {
226 return image_align;
228 set {
229 if (!Enum.IsDefined (typeof (ContentAlignment), value))
230 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
232 if (image_align == value)
233 return;
235 image_align = value;
236 Refresh ();
240 public int ImageIndex {
241 get { return image_index;}
242 set {
244 if (value < 0 || value>= image_list.Images.Count)
245 throw new ArgumentException();
247 if (image_index == value)
248 return;
250 image_index = value;
252 if (ImageList != null && image_index !=-1)
253 Image = null;
255 Refresh ();
259 public ImageList ImageList {
260 get { return image_list;}
261 set {
262 if (image_list == value)
263 return;
265 if (ImageList != null && image_index !=-1)
266 Image = null;
268 Refresh ();
272 public new ImeMode ImeMode {
273 get { return base.ImeMode; }
274 set {
275 if (value == ImeMode)
276 return;
277 base.ImeMode = value;
278 if (ImeModeChanged != null)
279 ImeModeChanged (this, EventArgs.Empty);
283 public virtual int PreferredHeight {
284 get { return preferred_height; }
287 public virtual int PreferredWidth {
288 get {return preferred_width; }
291 protected virtual bool RenderTransparent {
292 get { return render_transparent; }
293 set { render_transparent = value;}
296 public new bool TabStop {
297 get { return base.TabStop; }
298 set {
299 if (value == base.TabStop)
300 return;
302 base.TabStop = value;
303 if (TabStopChanged != null)
304 TabStopChanged (this, EventArgs.Empty);
308 public virtual ContentAlignment TextAlign {
309 get { return text_align; }
311 set {
312 if (!Enum.IsDefined (typeof (ContentAlignment), value))
313 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
315 if (text_align != value) {
317 text_align = value;
319 switch (value) {
321 case ContentAlignment.BottomLeft:
322 string_format.LineAlignment = StringAlignment.Far;
323 string_format.Alignment = StringAlignment.Near;
324 break;
325 case ContentAlignment.BottomCenter:
326 string_format.LineAlignment = StringAlignment.Far;
327 string_format.Alignment = StringAlignment.Center;
328 break;
329 case ContentAlignment.BottomRight:
330 string_format.LineAlignment = StringAlignment.Far;
331 string_format.Alignment = StringAlignment.Far;
332 break;
333 case ContentAlignment.TopLeft:
334 string_format.LineAlignment = StringAlignment.Near;
335 string_format.Alignment = StringAlignment.Near;
336 break;
337 case ContentAlignment.TopCenter:
338 string_format.LineAlignment = StringAlignment.Near;
339 string_format.Alignment = StringAlignment.Center;
340 break;
341 case ContentAlignment.TopRight:
342 string_format.LineAlignment = StringAlignment.Near;
343 string_format.Alignment = StringAlignment.Far;
344 break;
345 case ContentAlignment.MiddleLeft:
346 string_format.LineAlignment = StringAlignment.Center;
347 string_format.Alignment = StringAlignment.Near;
348 break;
349 case ContentAlignment.MiddleRight:
350 string_format.LineAlignment = StringAlignment.Center;
351 string_format.Alignment = StringAlignment.Far;
352 break;
353 case ContentAlignment.MiddleCenter:
354 string_format.LineAlignment = StringAlignment.Center;
355 string_format.Alignment = StringAlignment.Center;
356 break;
357 default:
358 break;
361 if (TextAlignChanged != null)
362 TextAlignChanged (this, new EventArgs ());
364 Refresh();
369 public bool UseMnemonic {
370 get { return use_mnemonic; }
371 set {
372 if (use_mnemonic != value) {
373 use_mnemonic = value;
374 SetUseMnemonic (use_mnemonic);
375 Refresh ();
380 #endregion
383 #region Public Methods
385 protected Rectangle CalcImageRenderBounds (Image image, Rectangle area, ContentAlignment img_align)
387 Rectangle rcImageClip = area;
388 rcImageClip.Inflate (-2,-2);
390 int X = area.X;
391 int Y = area.Y;
393 if (img_align == ContentAlignment.TopCenter ||
394 img_align == ContentAlignment.MiddleCenter ||
395 img_align == ContentAlignment.BottomCenter) {
396 X += (area.Width - image.Width) / 2;
398 else if (img_align == ContentAlignment.TopRight ||
399 img_align == ContentAlignment.MiddleRight||
400 img_align == ContentAlignment.BottomRight) {
401 X += (area.Width - image.Width);
404 if( img_align == ContentAlignment.BottomCenter ||
405 img_align == ContentAlignment.BottomLeft ||
406 img_align == ContentAlignment.BottomRight) {
407 Y += area.Height - image.Height;
409 else if(img_align == ContentAlignment.MiddleCenter ||
410 img_align == ContentAlignment.MiddleLeft ||
411 img_align == ContentAlignment.MiddleRight) {
412 Y += (area.Height - image.Height) / 2;
415 rcImageClip.X = X;
416 rcImageClip.Y = Y;
417 rcImageClip.Width = image.Width;
418 rcImageClip.Height = image.Height;
420 return rcImageClip;
424 protected override AccessibleObject CreateAccessibilityInstance ()
426 return base.CreateAccessibilityInstance ();
429 protected override void Dispose(bool disposing)
431 base.Dispose (disposing);
434 protected void DrawImage (Graphics g, Image image, Rectangle area, ContentAlignment img_align)
436 if (image == null || g == null)
437 return;
439 Rectangle rcImageClip = CalcImageRenderBounds (image, area, img_align);
441 if (Enabled)
442 g.DrawImage (image, rcImageClip.X, rcImageClip.Y, rcImageClip.Width, rcImageClip.Height);
443 else
444 ControlPaint.DrawImageDisabled (g, image, rcImageClip.X, rcImageClip.Y, BackColor);
447 protected virtual void OnAutoSizeChanged (EventArgs e)
449 if (AutoSizeChanged != null)
450 AutoSizeChanged (this, e);
453 protected override void OnEnabledChanged (EventArgs e)
455 base.OnEnabledChanged (e);
458 protected override void OnFontChanged (EventArgs e)
460 base.OnFontChanged (e);
461 CalcPreferredHeight ();
462 Refresh ();
466 protected override void OnPaint (PaintEventArgs pevent)
468 if (Width <= 0 || Height <= 0 || Visible == false)
469 return;
471 Draw ();
472 // TODO: Imagelist
473 pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
477 protected override void OnParentChanged (EventArgs e)
479 base.OnParentChanged (e);
482 protected virtual void OnTextAlignChanged (EventArgs e)
484 if (TextAlignChanged != null)
485 TextAlignChanged (this, e);
488 protected override void OnTextChanged (EventArgs e)
490 base.OnTextChanged (e);
491 CalcPreferredWidth ();
492 Refresh ();
495 protected override void OnVisibleChanged (EventArgs e)
497 base.OnVisibleChanged (e);
500 protected override bool ProcessMnemonic (char charCode)
502 return base.ProcessMnemonic (charCode);
505 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
507 base.SetBoundsCore (x, y, width, height, specified);
510 public override string ToString()
512 return base.ToString();
515 protected override void WndProc(ref Message m)
517 switch ((Msg) m.Msg) {
518 case Msg.WM_DRAWITEM: {
519 m.Result = (IntPtr)1;
521 break;
522 default:
523 base.WndProc (ref m);
524 break;
528 #endregion Public Methods
530 #region Private Methods
532 private void CalcAutoSize ()
534 if (IsHandleCreated == false)
535 return;
537 CalcPreferredWidth ();
538 CalcPreferredHeight ();
540 Width = PreferredWidth;
541 Height = PreferredHeight;
543 Invalidate ();
546 private void CalcPreferredHeight ()
548 preferred_height = Font.Height;
550 switch (border_style) {
551 case BorderStyle.None:
552 preferred_height += 3;
553 break;
554 case BorderStyle.FixedSingle:
555 case BorderStyle.Fixed3D:
556 preferred_height += 6;
557 break;
558 default:
559 break;
564 private void CalcPreferredWidth ()
566 SizeF size;
567 size = DeviceContext.MeasureString (Text, Font, req_witdthsize, string_format);
568 preferred_width = (int) size.Width + 3;
571 internal void Draw ()
573 ThemeEngine.Current.DrawLabel(DeviceContext, ClientRectangle, this);
575 DrawImage (DeviceContext, Image, ClientRectangle, image_align);
578 private void OnHandleCreatedLB (Object o, EventArgs e)
580 if (autosize)
581 CalcAutoSize ();
584 private void OnResizeLB (object o, EventArgs e)
586 if (Width <= 0 || Height <= 0)
587 return;
591 private void SetUseMnemonic (bool use)
593 if (use)
594 string_format.HotkeyPrefix = HotkeyPrefix.Show;
595 else
596 string_format.HotkeyPrefix = HotkeyPrefix.None;
599 #endregion Private Methods