1 /** DGui project file.
2  *
3  * Copyright: Trogu Antonio Davide 2011-2013
4  *
5  * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  *
7  * Authors: Trogu Antonio Davide
8  */
9 module dguihub.core.controls.abstractbutton;
10 
11 public import dguihub.core.dialogs.dialogresult;
12 public import dguihub.core.controls.ownerdrawcontrol;
13 
14 /**
15  * Enum that contain the check state of a *CheckBox* or similar component
16  */
17 enum CheckState : uint {
18    checked = BST_CHECKED, ///Checked State
19    unchecked = BST_UNCHECKED, ///Unchecked State
20    indeterminate = BST_INDETERMINATE, ///Indeterminate State
21 }
22 
23 /**
24  * Abstract class of a *Button* *CheckBox and *RadioButton*
25  */
26 abstract class AbstractButton : OwnerDrawControl {
27    protected DialogResult _dr = DialogResult.none;
28 
29    protected override void createControlParams(ref CreateControlParams ccp) {
30       AbstractButton.setBit(this._cBits, ControlBits.ownClickMsg, true); // Let Button to handle Click Event itself
31 
32       ccp.superclassName = WC_BUTTON;
33       this.setStyle(WS_TABSTOP, true);
34 
35       super.createControlParams(ccp);
36    }
37 
38    protected override void onReflectedMessage(ref Message m) {
39       switch (m.msg) {
40          case WM_COMMAND: {
41                              switch (HIWORD(m.wParam)) {
42                                 case BN_CLICKED: {
43                                                     MouseKeys mk = MouseKeys.none;
44 
45                                                     if (GetAsyncKeyState(MK_LBUTTON)) {
46                                                        mk |= MouseKeys.left;
47                                                     }
48 
49                                                     if (GetAsyncKeyState(MK_MBUTTON)) {
50                                                        mk |= MouseKeys.middle;
51                                                     }
52 
53                                                     if (GetAsyncKeyState(MK_RBUTTON)) {
54                                                        mk |= MouseKeys.right;
55                                                     }
56 
57                                                     Point p = Point(LOWORD(m.lParam), HIWORD(m.lParam));
58                                                     scope MouseEventArgs e = new MouseEventArgs(p, mk);
59                                                     this.onClick(EventArgs.empty);
60 
61                                                     if (this._dr !is DialogResult.none) {
62                                                        Control c = this.topLevelControl;
63 
64                                                        if (c) {
65                                                           c.sendMessage(DGUI_SETDIALOGRESULT, this._dr, 0);
66                                                        }
67                                                     }
68                                                  }
69                                                  break;
70 
71                                 default:
72                                                  break;
73                              }
74                           }
75                           break;
76 
77          default:
78                           break;
79       }
80 
81       super.onReflectedMessage(m);
82    }
83 }
84 
85 /**
86  * Abstract class of a checkable button (_CheckBox, _RadioButton, ...)
87  */
88 abstract class CheckedButton : AbstractButton {
89    public Event!(Control, EventArgs) checkChanged; ///Checked Changed Event of a Checkable _Button
90 
91    private CheckState _checkState = CheckState.unchecked;
92 
93    /**
94     * Returns:
95     * True if the _Button is _checked otherwise False.
96     *
97     * See_Also:
98     * checkState() property below.
99     */
100    @property public bool checked() {
101       return this.checkState is CheckState.checked;
102    }
103 
104    /**
105     * Sets the checked state of a checkable _button
106     *
107     * Params:
108     * True checks the _button, False unchecks it.
109     */
110    @property public void checked(bool b) {
111       this.checkState = b ? CheckState.checked : CheckState.unchecked;
112    }
113 
114    /**
115     * Returns:
116     * A CheckState enum that returns the state of the checkable button (it includes the indeterminate state too)
117     */
118    @property public CheckState checkState() {
119       if (this.created) {
120          return cast(CheckState)this.sendMessage(BM_GETCHECK, 0, 0);
121       }
122 
123       return this._checkState;
124    }
125 
126    /**
127     * Sets the check state of a checkable button
128     */
129    @property public void checkState(CheckState cs) {
130       this._checkState = cs;
131 
132       if (this.created) {
133          this.sendMessage(BM_SETCHECK, cs, 0);
134       }
135    }
136 
137    protected override void onHandleCreated(EventArgs e) {
138       this.sendMessage(BM_SETCHECK, this._checkState, 0);
139       super.onHandleCreated(e);
140    }
141 
142    protected override void onReflectedMessage(ref Message m) {
143       switch (m.msg) {
144          case WM_COMMAND: {
145                              switch (HIWORD(m.wParam)) {
146                                 case BN_CLICKED: {
147                                                     if (this._checkState !is this.checkState) //Is Check State Changed?
148                                                     {
149                                                        this._checkState = this.checkState;
150                                                        this.onCheckChanged(EventArgs.empty);
151                                                     }
152                                                  }
153                                                  break;
154 
155                                 default:
156                                                  break;
157                              }
158                           }
159                           break;
160 
161          default:
162                           break;
163       }
164 
165       super.onReflectedMessage(m);
166    }
167 
168    protected void onCheckChanged(EventArgs e) {
169       this.checkChanged(this, e);
170    }
171 }