CheckBox.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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 Novell, Inc.
  21. //
  22. // Authors:
  23. // Dennis Hayes [email protected]
  24. // Peter Bartok [email protected]
  25. //
  26. //
  27. // $Revision: 1.1 $
  28. // $Modtime: $
  29. // $Log: CheckBox.cs,v $
  30. // Revision 1.1 2004/07/09 05:21:25 pbartok
  31. // - Initial check-in
  32. //
  33. //
  34. // NOT COMPLETE
  35. namespace System.Windows.Forms {
  36. public class CreateParams {
  37. #region Public Constructors
  38. #endregion // Public Constructors
  39. #region Public Instance Properties
  40. #endregion // Public Instance Properties
  41. #region Public Instance Methods
  42. #endregion // Public Instance Methods
  43. }
  44. }
  45. //
  46. // System.Windows.Forms.CheckBox.cs
  47. //
  48. // Author:
  49. // stubbed out by Jaak Simm ([email protected])
  50. // Dennis Hayes ([email protected])
  51. //
  52. // (C) Ximian, Inc., 2002
  53. //
  54. using System.Drawing;
  55. namespace System.Windows.Forms {
  56. /// <summary>
  57. /// Represents a Windows check box.
  58. /// </summary>
  59. [MonoTODO]
  60. public class CheckBox : ButtonBase {
  61. // private fields
  62. Appearance appearance;
  63. bool autoCheck;
  64. ContentAlignment checkAlign;
  65. bool _checked;
  66. CheckState checkState;
  67. bool threeState;
  68. ContentAlignment textAlign;
  69. Rectangle textRect;
  70. Rectangle checkRect;
  71. StringFormat textFormat;
  72. int checkMarkSize=13; // Keep it configurable for accessability
  73. Graphics canvasDC;
  74. Bitmap canvasBmp;
  75. // --- Constructor ---
  76. public CheckBox() : base()
  77. {
  78. appearance = Appearance.Normal;
  79. autoCheck = true;
  80. checkAlign = ContentAlignment.MiddleLeft;
  81. _checked = false;
  82. checkState = CheckState.Unchecked;
  83. threeState = false;
  84. canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
  85. canvasDC = Graphics.FromImage(canvasBmp);
  86. /* Set defaults for drawing text... */
  87. textAlign = ContentAlignment.MiddleLeft;
  88. textFormat = new StringFormat();
  89. textFormat.Alignment=StringAlignment.Near;
  90. textFormat.LineAlignment=StringAlignment.Center;
  91. textRect = ClientRectangle;
  92. textRect.X+=checkMarkSize;
  93. textRect.Width-=checkMarkSize;
  94. /* ... and for drawing our checkbox */
  95. checkRect.X=ClientRectangle.Left;
  96. checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
  97. checkRect.Width=checkMarkSize;
  98. checkRect.Height=checkMarkSize;
  99. SizeChanged+=new System.EventHandler(CheckboxSizeChanged);
  100. GotFocus+=new System.EventHandler(CheckboxUpdate);
  101. LostFocus+=new System.EventHandler(CheckboxUpdate);
  102. TextChanged+=new System.EventHandler(CheckboxUpdate);
  103. SubClassWndProc_ = true;
  104. SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
  105. callWinControlProcMask &= ~(CallWinControlProcMask.MOUSE_MESSAGES | CallWinControlProcMask.KEYBOARD_MESSAGES);
  106. }
  107. // --- CheckBox Properties ---
  108. public Appearance Appearance {
  109. get { return appearance; }
  110. set { appearance=value; }
  111. }
  112. public bool AutoCheck {
  113. get { return autoCheck; }
  114. set { autoCheck = value; }
  115. }
  116. public ContentAlignment CheckAlign {
  117. get { return checkAlign; }
  118. set {
  119. checkAlign=value;
  120. UpdateCheckbox();
  121. }
  122. }
  123. public bool Checked {
  124. get { return _checked; }
  125. set {
  126. if( _checked != value) {
  127. CheckState = (value) ? CheckState.Checked : CheckState.Unchecked;
  128. }
  129. }
  130. }
  131. public CheckState CheckState {
  132. get { return checkState; }
  133. set {
  134. if( checkState != value) {
  135. checkState = value;
  136. bool oldChecked = _checked;
  137. if( checkState == CheckState.Unchecked) {
  138. _checked = false;
  139. }
  140. else {
  141. _checked = true;
  142. }
  143. if( oldChecked != _checked) {
  144. OnCheckedChanged(new EventArgs());
  145. }
  146. OnCheckStateChanged(new EventArgs());
  147. }
  148. }
  149. }
  150. [MonoTODO]
  151. protected override CreateParams CreateParams {
  152. get {
  153. CreateParams createParams = base.CreateParams;
  154. createParams.ClassName = "BUTTON";
  155. createParams.Style = (int) (
  156. (int)WindowStyles.WS_CHILD |
  157. (int)WindowStyles.WS_VISIBLE |
  158. (int)ButtonStyles.BS_CHECKBOX |
  159. (int)ButtonStyles.BS_NOTIFY |
  160. (int)WindowStyles.WS_CLIPSIBLINGS |
  161. (int)WindowStyles.WS_CLIPCHILDREN |
  162. (int)WindowStyles.WS_TABSTOP |
  163. (int)SS_Static_Control_Types.SS_LEFT );
  164. if (autoCheck) {
  165. createParams.Style |= (int)ButtonStyles.BS_AUTOCHECKBOX;
  166. }
  167. /* We need this, we draw ourselves */
  168. createParams.Style |= (int) ButtonStyles.BS_OWNERDRAW;
  169. return createParams;
  170. }
  171. }
  172. [MonoTODO]
  173. protected override Size DefaultSize {
  174. get { return new Size(100,checkMarkSize); }
  175. }
  176. [MonoTODO]
  177. public override ContentAlignment TextAlign {
  178. get {
  179. return textAlign;
  180. }
  181. set {
  182. textAlign = value;
  183. UpdateCheckbox();
  184. }
  185. }
  186. public bool ThreeState {
  187. get {
  188. return threeState;
  189. }
  190. set {
  191. threeState = value;
  192. }
  193. }
  194. // --- CheckBox methods ---
  195. protected override AccessibleObject CreateAccessibilityInstance()
  196. {
  197. throw new NotImplementedException ();
  198. }
  199. // [event methods]
  200. [MonoTODO]
  201. protected virtual void OnAppearanceChanged(EventArgs e)
  202. {
  203. if (AppearanceChanged != null) {
  204. AppearanceChanged(this, e);
  205. }
  206. }
  207. [MonoTODO]
  208. protected virtual void OnCheckedChanged(EventArgs e)
  209. {
  210. //FIXME:
  211. if(CheckedChanged != null) {
  212. CheckedChanged( this, e);
  213. }
  214. }
  215. [MonoTODO]
  216. protected virtual void OnCheckStateChanged(EventArgs e)
  217. {
  218. //FIXME:
  219. if(CheckStateChanged != null) {
  220. CheckStateChanged( this, e);
  221. }
  222. }
  223. [MonoTODO]
  224. protected override void OnClick(EventArgs e)
  225. {
  226. CheckState = (CheckState)Win32.SendMessage(Handle, (int)ButtonMessages.BM_GETCHECK, 0, 0);
  227. base.OnClick(e);
  228. }
  229. [MonoTODO]
  230. protected override void OnHandleCreated(EventArgs e)
  231. {
  232. //FIXME:
  233. base.OnHandleCreated(e);
  234. Win32.SendMessage(Handle, (int)ButtonMessages.BM_SETCHECK, (int)checkState, 0);
  235. }
  236. // protected override void OnMouseDown (MouseEventArgs e)
  237. // {
  238. // base.OnMouseDown (e);
  239. // }
  240. [MonoTODO]
  241. protected override void OnMouseUp(MouseEventArgs mevent)
  242. {
  243. if (ThreeState) {
  244. switch (CheckState) {
  245. case CheckState.Unchecked: {
  246. CheckState = CheckState.Checked;
  247. break;
  248. }
  249. case CheckState.Indeterminate: {
  250. CheckState = CheckState.Unchecked;
  251. break;
  252. }
  253. case CheckState.Checked: {
  254. CheckState = CheckState.Indeterminate;
  255. break;
  256. }
  257. }
  258. } else {
  259. Checked = Checked ? false : true;
  260. }
  261. CheckboxRedraw();
  262. Invalidate();
  263. base.OnMouseUp(mevent);
  264. }
  265. // end of [event methods]
  266. [MonoTODO]
  267. protected override bool ProcessMnemonic(char charCode)
  268. {
  269. //FIXME:
  270. return base.ProcessMnemonic(charCode);
  271. }
  272. [MonoTODO]
  273. //FIXME: do a better tostring
  274. public override string ToString()
  275. {
  276. if (Checked) {
  277. return "CheckBox" + " Checked";
  278. } else {
  279. return "CheckBox" + " Unchecked";
  280. }
  281. }
  282. internal override void ButtonPaint (PaintEventArgs e)
  283. {
  284. if (canvasBmp!=null) {
  285. e.Graphics.DrawImage(canvasBmp, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
  286. }
  287. }
  288. /// --- CheckBox events ---
  289. public event EventHandler AppearanceChanged;
  290. public event EventHandler CheckedChanged;
  291. public event EventHandler CheckStateChanged;
  292. /// --- public class CheckBox.CheckBoxAccessibleObject : AccessibleObject ---
  293. /// the class is only used for .NET framework
  294. ///
  295. public class CheckBoxAccessibleObject : AccessibleObject {
  296. }
  297. private void UpdateCheckbox() {
  298. /* Calculate the position of text and checkbox rectangle */
  299. if (appearance!=Appearance.Button) {
  300. switch(checkAlign) {
  301. case ContentAlignment.BottomCenter: {
  302. if (ClientRectangle.Height<checkMarkSize*2) {
  303. ClientSize=new Size(ClientRectangle.Width, checkMarkSize*2);
  304. }
  305. checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
  306. checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
  307. textRect.X=ClientRectangle.X;
  308. textRect.Width=ClientRectangle.Width;
  309. break;
  310. }
  311. case ContentAlignment.BottomLeft: {
  312. checkRect.X=ClientRectangle.Left;
  313. checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
  314. textRect.X=ClientRectangle.X+checkMarkSize;
  315. textRect.Width=ClientRectangle.Width-checkMarkSize;
  316. break;
  317. }
  318. case ContentAlignment.BottomRight: {
  319. checkRect.X=ClientRectangle.Right-checkMarkSize;
  320. checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
  321. textRect.X=ClientRectangle.X;
  322. textRect.Width=ClientRectangle.Width-checkMarkSize;
  323. break;
  324. }
  325. case ContentAlignment.MiddleCenter: {
  326. checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
  327. checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
  328. textRect.X=ClientRectangle.X;
  329. textRect.Width=ClientRectangle.Width;
  330. break;
  331. }
  332. default:
  333. case ContentAlignment.MiddleLeft: {
  334. checkRect.X=ClientRectangle.Left;
  335. checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
  336. textRect.X=ClientRectangle.X+checkMarkSize;
  337. textRect.Width=ClientRectangle.Width-checkMarkSize;
  338. break;
  339. }
  340. case ContentAlignment.MiddleRight: {
  341. checkRect.X=ClientRectangle.Right-checkMarkSize;
  342. checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
  343. textRect.X=ClientRectangle.X;
  344. textRect.Width=ClientRectangle.Width-checkMarkSize;
  345. break;
  346. }
  347. case ContentAlignment.TopCenter: {
  348. if (ClientRectangle.Height<checkMarkSize*2) {
  349. ClientSize=new Size(ClientRectangle.Width, checkMarkSize*2);
  350. }
  351. checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
  352. checkRect.Y=ClientRectangle.Top;
  353. textRect.X=ClientRectangle.X;
  354. textRect.Y=checkMarkSize;
  355. textRect.Width=ClientRectangle.Width;
  356. textRect.Height=ClientRectangle.Height-checkMarkSize;
  357. break;
  358. }
  359. case ContentAlignment.TopLeft: {
  360. checkRect.X=ClientRectangle.Left;
  361. checkRect.Y=ClientRectangle.Top;
  362. textRect.X=ClientRectangle.X+checkMarkSize;
  363. textRect.Width=ClientRectangle.Width-checkMarkSize;
  364. break;
  365. }
  366. case ContentAlignment.TopRight: {
  367. checkRect.X=ClientRectangle.Right-checkMarkSize;
  368. checkRect.Y=ClientRectangle.Top;
  369. textRect.X=ClientRectangle.X;
  370. textRect.Width=ClientRectangle.Width-checkMarkSize;
  371. break;
  372. }
  373. }
  374. } else {
  375. textRect.X=ClientRectangle.X;
  376. textRect.Width=ClientRectangle.Width;
  377. }
  378. /* Set the horizontal alignment of our text */
  379. switch(textAlign) {
  380. case ContentAlignment.BottomLeft:
  381. case ContentAlignment.MiddleLeft:
  382. case ContentAlignment.TopLeft: {
  383. textFormat.Alignment=StringAlignment.Near;
  384. break;
  385. }
  386. case ContentAlignment.BottomCenter:
  387. case ContentAlignment.MiddleCenter:
  388. case ContentAlignment.TopCenter: {
  389. textFormat.Alignment=StringAlignment.Center;
  390. break;
  391. }
  392. case ContentAlignment.BottomRight:
  393. case ContentAlignment.MiddleRight:
  394. case ContentAlignment.TopRight: {
  395. textFormat.Alignment=StringAlignment.Far;
  396. break;
  397. }
  398. }
  399. /* Set the vertical alignment of our text */
  400. switch(textAlign) {
  401. case ContentAlignment.TopLeft:
  402. case ContentAlignment.TopCenter:
  403. case ContentAlignment.TopRight: {
  404. textFormat.LineAlignment=StringAlignment.Near;
  405. break;
  406. }
  407. case ContentAlignment.BottomLeft:
  408. case ContentAlignment.BottomCenter:
  409. case ContentAlignment.BottomRight: {
  410. textFormat.LineAlignment=StringAlignment.Far;
  411. break;
  412. }
  413. case ContentAlignment.MiddleLeft:
  414. case ContentAlignment.MiddleCenter:
  415. case ContentAlignment.MiddleRight: {
  416. textFormat.LineAlignment=StringAlignment.Center;
  417. break;
  418. }
  419. }
  420. CheckboxRedraw();
  421. Invalidate();
  422. }
  423. private void CheckboxRedraw() {
  424. SolidBrush sb;
  425. /* Build the image representing the control */
  426. if (canvasDC!=null) {
  427. canvasDC.Dispose();
  428. }
  429. if (canvasBmp!=null) {
  430. canvasBmp.Dispose();
  431. }
  432. if (ClientRectangle.Width<1 || ClientRectangle.Height<1) {
  433. return;
  434. }
  435. canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
  436. canvasDC = Graphics.FromImage(canvasBmp);
  437. sb=new SolidBrush(BackColor);
  438. canvasDC.FillRectangle(sb, ClientRectangle);
  439. sb.Dispose();
  440. ButtonState state = ButtonState.Normal;
  441. if (FlatStyle == FlatStyle.Flat) {
  442. state |= ButtonState.Flat;
  443. }
  444. if (Checked) {
  445. state |= ButtonState.Checked;
  446. }
  447. if (ThreeState && (CheckState == CheckState.Indeterminate)) {
  448. state |= ButtonState.Checked;
  449. state |= ButtonState.Pushed;
  450. }
  451. if (appearance!=Appearance.Button) {
  452. ControlPaint.DrawCheckBox(canvasDC, checkRect, state);
  453. } else {
  454. ControlPaint.DrawButton(canvasDC, textRect, state);
  455. }
  456. /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
  457. sb=new SolidBrush(base.foreColor);
  458. canvasDC.DrawString(Text, Font, sb, textRect, textFormat);
  459. sb.Dispose();
  460. if (Focused) {
  461. ControlPaint.DrawFocusRectangle(canvasDC, textRect);
  462. }
  463. }
  464. private void CheckboxUpdate(object sender, System.EventArgs e) {
  465. /* Force recalculation of text & checkbox rectangles */
  466. UpdateCheckbox();
  467. }
  468. private void CheckboxSizeChanged(object sender, System.EventArgs e)
  469. {
  470. /* Force recalculation of text & checkbox rectangles */
  471. textRect.Y=ClientRectangle.Y;
  472. textRect.Height=ClientRectangle.Height;
  473. UpdateCheckbox();
  474. }
  475. }
  476. }