Label.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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, [email protected]
  24. // Peter Bartok, [email protected]
  25. //
  26. //
  27. // COMPLETE
  28. using System.ComponentModel;
  29. using System.ComponentModel.Design;
  30. using System.Drawing;
  31. using System.Drawing.Text;
  32. using System.Drawing.Imaging;
  33. using System.Runtime.InteropServices;
  34. namespace System.Windows.Forms
  35. {
  36. [DefaultProperty("Text")]
  37. [Designer ("System.Windows.Forms.Design.LabelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  38. public class Label : Control
  39. {
  40. private bool autosize;
  41. private Image image;
  42. private bool render_transparent;
  43. private FlatStyle flat_style;
  44. private int preferred_height;
  45. private int preferred_width;
  46. private bool use_mnemonic;
  47. private int image_index = -1;
  48. private ImageList image_list;
  49. internal ContentAlignment image_align;
  50. internal StringFormat string_format;
  51. internal ContentAlignment text_align;
  52. static SizeF req_witdthsize = new SizeF (0,0);
  53. #region Events
  54. public event EventHandler AutoSizeChanged;
  55. [Browsable(false)]
  56. [EditorBrowsable(EditorBrowsableState.Never)]
  57. public new event EventHandler BackgroundImageChanged {
  58. add {
  59. base.BackgroundImageChanged += value;
  60. }
  61. remove {
  62. base.BackgroundImageChanged -= value;
  63. }
  64. }
  65. [Browsable(false)]
  66. [EditorBrowsable(EditorBrowsableState.Never)]
  67. public new event EventHandler ImeModeChanged {
  68. add {
  69. base.ImeModeChanged += value;
  70. }
  71. remove {
  72. base.ImeModeChanged -= value;
  73. }
  74. }
  75. [Browsable(false)]
  76. [EditorBrowsable(EditorBrowsableState.Never)]
  77. public new event KeyEventHandler KeyDown {
  78. add {
  79. base.KeyDown += value;
  80. }
  81. remove {
  82. base.KeyDown -= value;
  83. }
  84. }
  85. [Browsable(false)]
  86. [EditorBrowsable(EditorBrowsableState.Never)]
  87. public new event KeyPressEventHandler KeyPress {
  88. add {
  89. base.KeyPress += value;
  90. }
  91. remove {
  92. base.KeyPress -= value;
  93. }
  94. }
  95. [Browsable(false)]
  96. [EditorBrowsable(EditorBrowsableState.Never)]
  97. public new event KeyEventHandler KeyUp {
  98. add {
  99. base.KeyUp += value;
  100. }
  101. remove {
  102. base.KeyUp -= value;
  103. }
  104. }
  105. [Browsable(false)]
  106. [EditorBrowsable(EditorBrowsableState.Never)]
  107. public new event EventHandler TabStopChanged {
  108. add {
  109. base.TabStopChanged += value;
  110. }
  111. remove {
  112. base.TabStopChanged -= value;
  113. }
  114. }
  115. public event EventHandler TextAlignChanged;
  116. #endregion
  117. public Label ()
  118. {
  119. // Defaults in the Spec
  120. autosize = false;
  121. tab_stop = false;
  122. string_format = new StringFormat();
  123. TextAlign = ContentAlignment.TopLeft;
  124. image = null;
  125. UseMnemonic = true;
  126. image_list = null;
  127. image_align = ContentAlignment.MiddleCenter;
  128. SetUseMnemonic (UseMnemonic);
  129. flat_style = FlatStyle.Standard;
  130. CalcPreferredHeight ();
  131. CalcPreferredWidth ();
  132. AutoSizeChanged = null;
  133. TextAlignChanged = null;
  134. SetStyle (ControlStyles.Selectable, false);
  135. SetStyle (ControlStyles.ResizeRedraw |
  136. ControlStyles.UserPaint |
  137. ControlStyles.AllPaintingInWmPaint |
  138. ControlStyles.SupportsTransparentBackColor |
  139. ControlStyles.DoubleBuffer, true);
  140. HandleCreated += new EventHandler (OnHandleCreatedLB);
  141. }
  142. #region Public Properties
  143. [DefaultValue(false)]
  144. [Localizable(true)]
  145. [RefreshProperties(RefreshProperties.All)]
  146. public virtual bool AutoSize {
  147. get { return autosize; }
  148. set {
  149. if (autosize == value)
  150. return;
  151. autosize = value;
  152. CalcAutoSize ();
  153. Refresh ();
  154. OnAutoSizeChanged (EventArgs.Empty);
  155. }
  156. }
  157. [Browsable(false)]
  158. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  159. [EditorBrowsable(EditorBrowsableState.Never)]
  160. public override Image BackgroundImage {
  161. get {
  162. return base.BackgroundImage;
  163. }
  164. set {
  165. base.BackgroundImage = value;
  166. Refresh ();
  167. }
  168. }
  169. [DefaultValue(BorderStyle.None)]
  170. [DispId(-504)]
  171. public virtual BorderStyle BorderStyle {
  172. get { return InternalBorderStyle; }
  173. set { InternalBorderStyle = value; }
  174. }
  175. protected override CreateParams CreateParams {
  176. get { return base.CreateParams;}
  177. }
  178. protected override ImeMode DefaultImeMode {
  179. get { return ImeMode.Disable;}
  180. }
  181. protected override Size DefaultSize {
  182. get {return ThemeEngine.Current.LabelDefaultSize;}
  183. }
  184. [DefaultValue(FlatStyle.Standard)]
  185. public FlatStyle FlatStyle {
  186. get {
  187. return flat_style;
  188. }
  189. set {
  190. if (!Enum.IsDefined (typeof (FlatStyle), value))
  191. throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for FlatStyle", value));
  192. if (flat_style == value)
  193. return;
  194. flat_style = value;
  195. Refresh ();
  196. }
  197. }
  198. [Localizable(true)]
  199. public Image Image {
  200. get {
  201. if (image != null) {
  202. return image;
  203. }
  204. if (image_list != null && ImageIndex >= 0) {
  205. return image_list.Images[ImageIndex];
  206. }
  207. return null;
  208. }
  209. set {
  210. if (image == value)
  211. return;
  212. image = value;
  213. Refresh ();
  214. }
  215. }
  216. [DefaultValue(ContentAlignment.MiddleCenter)]
  217. [Localizable(true)]
  218. public ContentAlignment ImageAlign {
  219. get {
  220. return image_align;
  221. }
  222. set {
  223. if (!Enum.IsDefined (typeof (ContentAlignment), value))
  224. throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
  225. if (image_align == value)
  226. return;
  227. image_align = value;
  228. Refresh ();
  229. }
  230. }
  231. [DefaultValue (-1)]
  232. [Editor ("System.Windows.Forms.Design.ImageIndexEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
  233. [Localizable (true)]
  234. [TypeConverter (typeof (ImageIndexConverter))]
  235. public int ImageIndex {
  236. get {
  237. if (ImageList == null) {
  238. return -1;
  239. }
  240. if (image_index >= image_list.Images.Count) {
  241. return image_list.Images.Count - 1;
  242. }
  243. return image_index;
  244. }
  245. set {
  246. if (value < -1)
  247. throw new ArgumentException ();
  248. if (image_index == value)
  249. return;
  250. image_index = value;
  251. if (ImageList != null && image_index !=-1)
  252. Image = null;
  253. Refresh ();
  254. }
  255. }
  256. [DefaultValue(null)]
  257. public ImageList ImageList {
  258. get { return image_list;}
  259. set {
  260. if (image_list == value)
  261. return;
  262. image_list = value;
  263. if (image_list != null && image_index !=-1)
  264. Image = null;
  265. Refresh ();
  266. }
  267. }
  268. [Browsable(false)]
  269. [EditorBrowsable(EditorBrowsableState.Never)]
  270. public new ImeMode ImeMode {
  271. get { return base.ImeMode; }
  272. set { base.ImeMode = value; }
  273. }
  274. [Browsable(false)]
  275. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  276. [EditorBrowsable(EditorBrowsableState.Advanced)]
  277. public virtual int PreferredHeight {
  278. get { return preferred_height; }
  279. }
  280. [Browsable(false)]
  281. [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
  282. [EditorBrowsable(EditorBrowsableState.Advanced)]
  283. public virtual int PreferredWidth {
  284. get {return preferred_width; }
  285. }
  286. protected virtual bool RenderTransparent {
  287. get { return render_transparent; }
  288. set { render_transparent = value;}
  289. }
  290. [Browsable(false)]
  291. [DefaultValue(false)]
  292. [EditorBrowsable(EditorBrowsableState.Never)]
  293. public new bool TabStop {
  294. get { return base.TabStop; }
  295. set { base.TabStop = value; }
  296. }
  297. [DefaultValue(ContentAlignment.TopLeft)]
  298. [Localizable(true)]
  299. public virtual ContentAlignment TextAlign {
  300. get { return text_align; }
  301. set {
  302. if (!Enum.IsDefined (typeof (ContentAlignment), value))
  303. throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for ContentAlignment", value));
  304. if (text_align != value) {
  305. text_align = value;
  306. switch (value) {
  307. case ContentAlignment.BottomLeft:
  308. string_format.LineAlignment = StringAlignment.Far;
  309. string_format.Alignment = StringAlignment.Near;
  310. break;
  311. case ContentAlignment.BottomCenter:
  312. string_format.LineAlignment = StringAlignment.Far;
  313. string_format.Alignment = StringAlignment.Center;
  314. break;
  315. case ContentAlignment.BottomRight:
  316. string_format.LineAlignment = StringAlignment.Far;
  317. string_format.Alignment = StringAlignment.Far;
  318. break;
  319. case ContentAlignment.TopLeft:
  320. string_format.LineAlignment = StringAlignment.Near;
  321. string_format.Alignment = StringAlignment.Near;
  322. break;
  323. case ContentAlignment.TopCenter:
  324. string_format.LineAlignment = StringAlignment.Near;
  325. string_format.Alignment = StringAlignment.Center;
  326. break;
  327. case ContentAlignment.TopRight:
  328. string_format.LineAlignment = StringAlignment.Near;
  329. string_format.Alignment = StringAlignment.Far;
  330. break;
  331. case ContentAlignment.MiddleLeft:
  332. string_format.LineAlignment = StringAlignment.Center;
  333. string_format.Alignment = StringAlignment.Near;
  334. break;
  335. case ContentAlignment.MiddleRight:
  336. string_format.LineAlignment = StringAlignment.Center;
  337. string_format.Alignment = StringAlignment.Far;
  338. break;
  339. case ContentAlignment.MiddleCenter:
  340. string_format.LineAlignment = StringAlignment.Center;
  341. string_format.Alignment = StringAlignment.Center;
  342. break;
  343. default:
  344. break;
  345. }
  346. OnTextAlignChanged (EventArgs.Empty);
  347. Refresh();
  348. }
  349. }
  350. }
  351. [DefaultValue(true)]
  352. public bool UseMnemonic {
  353. get { return use_mnemonic; }
  354. set {
  355. if (use_mnemonic != value) {
  356. use_mnemonic = value;
  357. SetUseMnemonic (use_mnemonic);
  358. Refresh ();
  359. }
  360. }
  361. }
  362. #endregion
  363. #region Public Methods
  364. protected Rectangle CalcImageRenderBounds (Image image, Rectangle area, ContentAlignment img_align)
  365. {
  366. Rectangle rcImageClip = area;
  367. rcImageClip.Inflate (-2,-2);
  368. int X = area.X;
  369. int Y = area.Y;
  370. if (img_align == ContentAlignment.TopCenter ||
  371. img_align == ContentAlignment.MiddleCenter ||
  372. img_align == ContentAlignment.BottomCenter) {
  373. X += (area.Width - image.Width) / 2;
  374. }
  375. else if (img_align == ContentAlignment.TopRight ||
  376. img_align == ContentAlignment.MiddleRight||
  377. img_align == ContentAlignment.BottomRight) {
  378. X += (area.Width - image.Width);
  379. }
  380. if( img_align == ContentAlignment.BottomCenter ||
  381. img_align == ContentAlignment.BottomLeft ||
  382. img_align == ContentAlignment.BottomRight) {
  383. Y += area.Height - image.Height;
  384. }
  385. else if(img_align == ContentAlignment.MiddleCenter ||
  386. img_align == ContentAlignment.MiddleLeft ||
  387. img_align == ContentAlignment.MiddleRight) {
  388. Y += (area.Height - image.Height) / 2;
  389. }
  390. rcImageClip.X = X;
  391. rcImageClip.Y = Y;
  392. rcImageClip.Width = image.Width;
  393. rcImageClip.Height = image.Height;
  394. return rcImageClip;
  395. }
  396. protected override AccessibleObject CreateAccessibilityInstance ()
  397. {
  398. return base.CreateAccessibilityInstance ();
  399. }
  400. protected override void Dispose(bool disposing)
  401. {
  402. base.Dispose (disposing);
  403. if (disposing)
  404. string_format.Dispose ();
  405. }
  406. protected void DrawImage (Graphics g, Image image, Rectangle area, ContentAlignment img_align)
  407. {
  408. if (image == null || g == null)
  409. return;
  410. Rectangle rcImageClip = CalcImageRenderBounds (image, area, img_align);
  411. if (Enabled)
  412. g.DrawImage (image, rcImageClip.X, rcImageClip.Y, rcImageClip.Width, rcImageClip.Height);
  413. else
  414. ControlPaint.DrawImageDisabled (g, image, rcImageClip.X, rcImageClip.Y, BackColor);
  415. }
  416. protected virtual void OnAutoSizeChanged (EventArgs e)
  417. {
  418. if (AutoSizeChanged != null)
  419. AutoSizeChanged (this, e);
  420. }
  421. protected override void OnEnabledChanged (EventArgs e)
  422. {
  423. base.OnEnabledChanged (e);
  424. }
  425. protected override void OnFontChanged (EventArgs e)
  426. {
  427. base.OnFontChanged (e);
  428. if (autosize) {
  429. CalcAutoSize();
  430. } else {
  431. CalcPreferredHeight ();
  432. }
  433. Refresh ();
  434. }
  435. protected override void OnPaint (PaintEventArgs pevent)
  436. {
  437. ThemeEngine.Current.DrawLabel (pevent.Graphics, ClientRectangle, this);
  438. DrawImage (pevent.Graphics, Image, ClientRectangle, image_align);
  439. base.OnPaint(pevent);
  440. }
  441. protected override void OnParentChanged (EventArgs e)
  442. {
  443. base.OnParentChanged (e);
  444. }
  445. protected virtual void OnTextAlignChanged (EventArgs e)
  446. {
  447. if (TextAlignChanged != null)
  448. TextAlignChanged (this, e);
  449. }
  450. protected override void OnTextChanged (EventArgs e)
  451. {
  452. base.OnTextChanged (e);
  453. if (autosize) {
  454. CalcAutoSize ();
  455. } else {
  456. CalcPreferredWidth ();
  457. }
  458. Refresh ();
  459. }
  460. protected override void OnVisibleChanged (EventArgs e)
  461. {
  462. base.OnVisibleChanged (e);
  463. }
  464. protected override bool ProcessMnemonic (char charCode)
  465. {
  466. if (IsMnemonic(charCode, Text) == true) {
  467. // Select item next in line in tab order
  468. if (this.parent != null) {
  469. parent.SelectNextControl(this, true, false, false, false);
  470. }
  471. return true;
  472. }
  473. return base.ProcessMnemonic (charCode);
  474. }
  475. protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
  476. {
  477. base.SetBoundsCore (x, y, width, height, specified);
  478. }
  479. public override string ToString()
  480. {
  481. return base.ToString () + ", Text: " + Text;
  482. }
  483. protected override void WndProc (ref Message m)
  484. {
  485. switch ((Msg) m.Msg) {
  486. case Msg.WM_DRAWITEM: {
  487. m.Result = (IntPtr)1;
  488. }
  489. break;
  490. default:
  491. base.WndProc (ref m);
  492. break;
  493. }
  494. }
  495. #endregion Public Methods
  496. #region Private Methods
  497. private void CalcAutoSize ()
  498. {
  499. if (IsHandleCreated == false || AutoSize == false)
  500. return;
  501. CalcPreferredWidth ();
  502. CalcPreferredHeight ();
  503. Width = PreferredWidth;
  504. Height = PreferredHeight;
  505. }
  506. private void CalcPreferredHeight ()
  507. {
  508. preferred_height = Font.Height;
  509. switch (border_style) {
  510. case BorderStyle.None:
  511. preferred_height += 3;
  512. break;
  513. case BorderStyle.FixedSingle:
  514. case BorderStyle.Fixed3D:
  515. preferred_height += 6;
  516. break;
  517. default:
  518. break;
  519. }
  520. }
  521. private void CalcPreferredWidth ()
  522. {
  523. SizeF size;
  524. size = DeviceContext.MeasureString (Text, Font, req_witdthsize, string_format);
  525. preferred_width = (int) size.Width + 3;
  526. }
  527. private void OnHandleCreatedLB (Object o, EventArgs e)
  528. {
  529. if (autosize)
  530. CalcAutoSize ();
  531. }
  532. private void SetUseMnemonic (bool use)
  533. {
  534. if (use)
  535. string_format.HotkeyPrefix = HotkeyPrefix.Show;
  536. else
  537. string_format.HotkeyPrefix = HotkeyPrefix.None;
  538. }
  539. #endregion Private Methods
  540. #if NET_2_0
  541. public bool UseCompatibleTextRendering {
  542. get {
  543. return use_compatible_text_rendering;
  544. }
  545. set {
  546. use_compatible_text_rendering = value;
  547. }
  548. }
  549. #endif
  550. }
  551. }