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:
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.
23 // Dennis Hayes dennish@raytek.com
24 // Peter Bartok pbartok@novell.com
29 // $Log: CheckBox.cs,v $
30 // Revision 1.2 2004/08/30 15:44:20 pbartok
31 // - Updated to fix broken build. Not complete yet.
33 // Revision 1.1 2004/07/09 05:21:25 pbartok
43 namespace System.Windows.Forms {
44 public class CheckBox : ButtonBase {
45 private Appearance appearance;
46 private bool auto_check;
47 private ContentAlignment check_alignment;
48 private ContentAlignment text_alignment;
49 private CheckState check_state;
50 private bool three_state;
52 #region Public Constructors
54 appearance = Appearance.Normal;
56 check_alignment = ContentAlignment.MiddleLeft;
58 #endregion // Public Constructors
60 #region Public Instance Properties
61 public Appearance Appearance {
67 if (value != appearance) {
69 if (AppearanceChanged != null) {
70 AppearanceChanged(this, EventArgs.Empty);
76 public bool AutoCheck {
86 public ContentAlignment CheckAlign {
88 return check_alignment;
92 if (value != check_alignment) {
93 check_alignment = value;
100 public bool Checked {
102 if (check_state != CheckState.Unchecked) {
109 if (value && (check_state != CheckState.Checked)) {
110 check_state = CheckState.Checked;
112 OnCheckedChanged(EventArgs.Empty);
113 } else if (!value && (check_state != CheckState.Unchecked)) {
114 check_state = CheckState.Unchecked;
116 OnCheckedChanged(EventArgs.Empty);
121 public CheckState CheckState {
127 if (value != check_state) {
128 bool was_checked = (check_state != CheckState.Unchecked);
132 if (was_checked != (check_state != CheckState.Unchecked)) {
133 OnCheckedChanged(EventArgs.Empty);
136 OnCheckStateChanged(EventArgs.Empty);
142 public override ContentAlignment TextAlign {
144 return text_alignment;
148 if (value != text_alignment) {
149 text_alignment = value;
156 public bool ThreeState {
165 #endregion // Public Instance Properties
167 #region Protected Instance Properties
168 protected override CreateParams CreateParams {
170 return base.CreateParams;
174 protected override Size DefaultSize {
176 return new Size(104, 24);
179 #endregion // Protected Instance Properties
181 #region Public Instance Methods
182 public override string ToString() {
183 if (CheckState == CheckState.Unchecked) {
184 return "CheckBox (unchecked)";
185 } else if (CheckState == CheckState.Checked) {
186 return "CheckBox (checked)";
188 return "CheckBox (state indeterminate)";
191 #endregion // Public Instance Methods
193 #region Protected Instance Methods
194 protected override AccessibleObject CreateAccessibilityInstance() {
195 return base.CreateAccessibilityInstance ();
198 protected virtual void OnAppearanceChanged(EventArgs e) {
199 if (AppearanceChanged != null) {
200 AppearanceChanged(this, e);
204 protected virtual void OnCheckedChanged(EventArgs e) {
205 Console.WriteLine("Checked changed");
206 if (CheckedChanged != null) {
207 CheckedChanged(this, e);
211 protected virtual void OnCheckStateChanged(EventArgs e) {
212 Console.WriteLine("CheckState changed");
213 if (CheckStateChanged != null) {
214 CheckStateChanged(this, e);
218 protected override void OnClick(EventArgs e) {
219 Console.WriteLine("Got click");
223 protected override void OnHandleCreated(EventArgs e) {
224 base.OnHandleCreated (e);
227 protected override void OnMouseUp(MouseEventArgs e) {
231 protected override bool ProcessMnemonic(char charCode) {
232 return base.ProcessMnemonic (charCode);
235 #endregion // Protected Instance Methods
238 public event EventHandler AppearanceChanged;
239 public event EventHandler CheckedChanged;
240 public event EventHandler CheckStateChanged;
245 public class CheckBox : ButtonBase {
248 Appearance appearance;
250 ContentAlignment checkAlign;
252 CheckState checkState;
254 ContentAlignment textAlign;
257 StringFormat textFormat;
258 int checkMarkSize=13; // Keep it configurable for accessability
262 // --- Constructor ---
263 public CheckBox() : base()
266 appearance = Appearance.Normal;
268 checkAlign = ContentAlignment.MiddleLeft;
270 checkState = CheckState.Unchecked;
273 canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
274 canvasDC = Graphics.FromImage(canvasBmp);
276 /* Set defaults for drawing text... */
277 textAlign = ContentAlignment.MiddleLeft;
278 textFormat = new StringFormat();
279 textFormat.Alignment=StringAlignment.Near;
280 textFormat.LineAlignment=StringAlignment.Center;
281 textRect = ClientRectangle;
282 textRect.X+=checkMarkSize;
283 textRect.Width-=checkMarkSize;
285 /* ... and for drawing our checkbox */
286 checkRect.X=ClientRectangle.Left;
287 checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
288 checkRect.Width=checkMarkSize;
289 checkRect.Height=checkMarkSize;
291 SizeChanged+=new System.EventHandler(CheckboxSizeChanged);
292 GotFocus+=new System.EventHandler(CheckboxUpdate);
293 LostFocus+=new System.EventHandler(CheckboxUpdate);
294 TextChanged+=new System.EventHandler(CheckboxUpdate);
296 SubClassWndProc_ = true;
297 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
298 callWinControlProcMask &= ~(CallWinControlProcMask.MOUSE_MESSAGES | CallWinControlProcMask.KEYBOARD_MESSAGES);
301 // --- CheckBox Properties ---
303 public CheckState CheckState {
304 get { return checkState; }
306 if( checkState != value) {
309 bool oldChecked = _checked;
311 if( checkState == CheckState.Unchecked) {
318 if( oldChecked != _checked) {
319 OnCheckedChanged(new EventArgs());
322 OnCheckStateChanged(new EventArgs());
328 protected override CreateParams CreateParams {
330 CreateParams createParams = base.CreateParams;
332 createParams.ClassName = "BUTTON";
334 createParams.Style = (int) (
335 (int)WindowStyles.WS_CHILD |
336 (int)WindowStyles.WS_VISIBLE |
337 (int)ButtonStyles.BS_CHECKBOX |
338 (int)ButtonStyles.BS_NOTIFY |
339 (int)WindowStyles.WS_CLIPSIBLINGS |
340 (int)WindowStyles.WS_CLIPCHILDREN |
341 (int)WindowStyles.WS_TABSTOP |
342 (int)SS_Static_Control_Types.SS_LEFT );
345 createParams.Style |= (int)ButtonStyles.BS_AUTOCHECKBOX;
348 /* We need this, we draw ourselves */
349 createParams.Style |= (int) ButtonStyles.BS_OWNERDRAW;
356 protected override Size DefaultSize {
357 get { return new Size(100,checkMarkSize); }
361 public override ContentAlignment TextAlign {
371 public bool ThreeState {
381 // --- CheckBox methods ---
383 protected override AccessibleObject CreateAccessibilityInstance()
385 throw new NotImplementedException ();
391 protected virtual void OnAppearanceChanged(EventArgs e)
393 if (AppearanceChanged != null) {
394 AppearanceChanged(this, e);
399 protected virtual void OnCheckedChanged(EventArgs e)
402 if(CheckedChanged != null) {
403 CheckedChanged( this, e);
408 protected virtual void OnCheckStateChanged(EventArgs e)
411 if(CheckStateChanged != null) {
412 CheckStateChanged( this, e);
417 protected override void OnClick(EventArgs e)
419 CheckState = (CheckState)Win32.SendMessage(Handle, (int)ButtonMessages.BM_GETCHECK, 0, 0);
424 protected override void OnHandleCreated(EventArgs e)
427 base.OnHandleCreated(e);
428 Win32.SendMessage(Handle, (int)ButtonMessages.BM_SETCHECK, (int)checkState, 0);
431 // protected override void OnMouseDown (MouseEventArgs e)
433 // base.OnMouseDown (e);
437 protected override void OnMouseUp(MouseEventArgs mevent)
440 switch (CheckState) {
441 case CheckState.Unchecked: {
442 CheckState = CheckState.Checked;
446 case CheckState.Indeterminate: {
447 CheckState = CheckState.Unchecked;
451 case CheckState.Checked: {
452 CheckState = CheckState.Indeterminate;
457 Checked = Checked ? false : true;
461 base.OnMouseUp(mevent);
463 // end of [event methods]
467 protected override bool ProcessMnemonic(char charCode)
470 return base.ProcessMnemonic(charCode);
474 //FIXME: do a better tostring
475 public override string ToString()
478 return "CheckBox" + " Checked";
480 return "CheckBox" + " Unchecked";
484 internal override void ButtonPaint (PaintEventArgs e)
486 if (canvasBmp!=null) {
487 e.Graphics.DrawImage(canvasBmp, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
491 /// --- CheckBox events ---
492 public event EventHandler AppearanceChanged;
493 public event EventHandler CheckedChanged;
494 public event EventHandler CheckStateChanged;
496 /// --- public class CheckBox.CheckBoxAccessibleObject : AccessibleObject ---
497 /// the class is only used for .NET framework
499 public class CheckBoxAccessibleObject : AccessibleObject {
502 private void UpdateCheckbox() {
503 /* Calculate the position of text and checkbox rectangle */
504 if (appearance!=Appearance.Button) {
506 case ContentAlignment.BottomCenter: {
507 if (ClientRectangle.Height<checkMarkSize*2) {
508 ClientSize=new Size(ClientRectangle.Width, checkMarkSize*2);
510 checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
511 checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
512 textRect.X=ClientRectangle.X;
513 textRect.Width=ClientRectangle.Width;
517 case ContentAlignment.BottomLeft: {
518 checkRect.X=ClientRectangle.Left;
519 checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
520 textRect.X=ClientRectangle.X+checkMarkSize;
521 textRect.Width=ClientRectangle.Width-checkMarkSize;
525 case ContentAlignment.BottomRight: {
526 checkRect.X=ClientRectangle.Right-checkMarkSize;
527 checkRect.Y=ClientRectangle.Bottom-checkMarkSize;
528 textRect.X=ClientRectangle.X;
529 textRect.Width=ClientRectangle.Width-checkMarkSize;
533 case ContentAlignment.MiddleCenter: {
534 checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
535 checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
536 textRect.X=ClientRectangle.X;
537 textRect.Width=ClientRectangle.Width;
542 case ContentAlignment.MiddleLeft: {
543 checkRect.X=ClientRectangle.Left;
544 checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
545 textRect.X=ClientRectangle.X+checkMarkSize;
546 textRect.Width=ClientRectangle.Width-checkMarkSize;
550 case ContentAlignment.MiddleRight: {
551 checkRect.X=ClientRectangle.Right-checkMarkSize;
552 checkRect.Y=(ClientRectangle.Bottom-ClientRectangle.Top)/2-checkMarkSize/2;
553 textRect.X=ClientRectangle.X;
554 textRect.Width=ClientRectangle.Width-checkMarkSize;
558 case ContentAlignment.TopCenter: {
559 if (ClientRectangle.Height<checkMarkSize*2) {
560 ClientSize=new Size(ClientRectangle.Width, checkMarkSize*2);
562 checkRect.X=(ClientRectangle.Right-ClientRectangle.Left)/2-checkMarkSize/2;
563 checkRect.Y=ClientRectangle.Top;
564 textRect.X=ClientRectangle.X;
565 textRect.Y=checkMarkSize;
566 textRect.Width=ClientRectangle.Width;
567 textRect.Height=ClientRectangle.Height-checkMarkSize;
571 case ContentAlignment.TopLeft: {
572 checkRect.X=ClientRectangle.Left;
573 checkRect.Y=ClientRectangle.Top;
574 textRect.X=ClientRectangle.X+checkMarkSize;
575 textRect.Width=ClientRectangle.Width-checkMarkSize;
579 case ContentAlignment.TopRight: {
580 checkRect.X=ClientRectangle.Right-checkMarkSize;
581 checkRect.Y=ClientRectangle.Top;
582 textRect.X=ClientRectangle.X;
583 textRect.Width=ClientRectangle.Width-checkMarkSize;
588 textRect.X=ClientRectangle.X;
589 textRect.Width=ClientRectangle.Width;
592 /* Set the horizontal alignment of our text */
594 case ContentAlignment.BottomLeft:
595 case ContentAlignment.MiddleLeft:
596 case ContentAlignment.TopLeft: {
597 textFormat.Alignment=StringAlignment.Near;
601 case ContentAlignment.BottomCenter:
602 case ContentAlignment.MiddleCenter:
603 case ContentAlignment.TopCenter: {
604 textFormat.Alignment=StringAlignment.Center;
608 case ContentAlignment.BottomRight:
609 case ContentAlignment.MiddleRight:
610 case ContentAlignment.TopRight: {
611 textFormat.Alignment=StringAlignment.Far;
616 /* Set the vertical alignment of our text */
618 case ContentAlignment.TopLeft:
619 case ContentAlignment.TopCenter:
620 case ContentAlignment.TopRight: {
621 textFormat.LineAlignment=StringAlignment.Near;
625 case ContentAlignment.BottomLeft:
626 case ContentAlignment.BottomCenter:
627 case ContentAlignment.BottomRight: {
628 textFormat.LineAlignment=StringAlignment.Far;
632 case ContentAlignment.MiddleLeft:
633 case ContentAlignment.MiddleCenter:
634 case ContentAlignment.MiddleRight: {
635 textFormat.LineAlignment=StringAlignment.Center;
643 private void CheckboxRedraw() {
646 /* Build the image representing the control */
648 if (canvasDC!=null) {
651 if (canvasBmp!=null) {
655 if (ClientRectangle.Width<1 || ClientRectangle.Height<1) {
658 canvasBmp = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
659 canvasDC = Graphics.FromImage(canvasBmp);
661 sb=new SolidBrush(BackColor);
662 canvasDC.FillRectangle(sb, ClientRectangle);
665 ButtonState state = ButtonState.Normal;
666 if (FlatStyle == FlatStyle.Flat) {
667 state |= ButtonState.Flat;
671 state |= ButtonState.Checked;
674 if (ThreeState && (CheckState == CheckState.Indeterminate)) {
675 state |= ButtonState.Checked;
676 state |= ButtonState.Pushed;
679 if (appearance!=Appearance.Button) {
680 ControlPaint.DrawCheckBox(canvasDC, checkRect, state);
682 ControlPaint.DrawButton(canvasDC, textRect, state);
685 /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
686 sb=new SolidBrush(base.foreColor);
687 canvasDC.DrawString(Text, Font, sb, textRect, textFormat);
691 ControlPaint.DrawFocusRectangle(canvasDC, textRect);
695 private void CheckboxUpdate(object sender, System.EventArgs e) {
696 /* Force recalculation of text & checkbox rectangles */
700 private void CheckboxSizeChanged(object sender, System.EventArgs e)
702 /* Force recalculation of text & checkbox rectangles */
703 textRect.Y=ClientRectangle.Y;
704 textRect.Height=ClientRectangle.Height;