1 /**
2  * Widget module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.widget.checkbutton;
8 
9 /**
10  * Imports.
11  */
12 import std..string;
13 import tkd.element.uielement;
14 import tkd.widget.common.command;
15 import tkd.widget.common.invoke;
16 import tkd.widget.common.value;
17 import tkd.widget.textwidget;
18 
19 /**
20  * A checkbutton widget is used to show or change a setting. It has two states, 
21  * selected and deselected. The state of the checkbutton may be linked to a 
22  * value.
23  *
24  * Example:
25  * ---
26  * auto checkButton = new CheckButton("Text")
27  * 	.setCommand(delegate(CommandArgs arg){ ... })
28  * 	.check()
29  * 	.pack();
30  * ---
31  *
32  * Common_Commands:
33  *     These are injected common commands that can also be used with this widget.
34  *     $(P
35  *         $(LINK2 ./common/command.html, Command) $(BR)
36  *         $(LINK2 ./common/invoke.html, Invoke) $(BR)
37  *         $(LINK2 ./common/value.html, Value) $(BR)
38  *     )
39  *
40  * Additional_Events:
41  *     Additional events that can also be bound to using the $(LINK2 ../element/uielement.html#UiElement.bind, bind) method.
42  *     $(P
43  *         <<Invoke>>,
44  *         <<PrevWindow>>,
45  *         <Alt-Key>,
46  *         <B1-Enter>,
47  *         <B1-Leave>,
48  *         <Button-1>,
49  *         <ButtonRelease-1>,
50  *         <Enter>,
51  *         <Key-F10>,
52  *         <Key-Tab>,
53  *         <Key-space>,
54  *         <Leave>,
55  *     )
56  *
57  * States:
58  *     This widget does not respond to user input if the disabled state is set. 
59  *     The widget sets the selected state whenever the value is set to the 
60  *     widget's on-value, and clears it otherwise. The widget sets the 
61  *     alternate state whenever the value is unset. (The alternate state may be 
62  *     used to indicate a "tri-state" or "indeterminate" selection.)
63  *
64  * Styles:
65  *     Check button widgets support the Toolbutton style in all standard 
66  *     themes, which is useful for creating widgets for toolbars.
67  *
68  * See_Also:
69  *     $(LINK2 ./textwidget.html, tkd.widget.textwidget)
70  */
71 class CheckButton : TextWidget
72 {
73 	/**
74 	 * The name of the variable that contains the widget's value.
75 	 */
76 	private string _valueVariable;
77 
78 	/**
79 	 * The value of the checkbutton if it's checked.
80 	 * The default is '1'.
81 	 */
82 	private string _onValue = "1";
83 
84 	/**
85 	 * The value of the checkbutton if it's unchecked.
86 	 * The default is '1'.
87 	 */
88 	private string _offValue = "0";
89 
90 	/**
91 	 * Construct the widget.
92 	 *
93 	 * Params:
94 	 *     parent = An optional parent of this widget.
95 	 *     text = The text of the checkbutton.
96 	 *
97 	 * See_Also:
98 	 *     $(LINK2 ../element/uielement.html, tkd.element.uielement)
99 	 */
100 	this(UiElement parent, string text = null)
101 	{
102 		super(parent);
103 		this._elementId     = "checkbutton";
104 		this._valueVariable = format("variable-%s", this.generateHash(this.id));
105 
106 		this._tk.eval("ttk::checkbutton %s -textvariable %s -variable %s", this.id, this._textVariable, this._valueVariable);
107 
108 		this.setText(text);
109 		this.unCheck();
110 	}
111 
112 	/**
113 	 * Construct the widget.
114 	 *
115 	 * Params:
116 	 *     text = The text of the checkbutton.
117 	 */
118 	this(string text = null)
119 	{
120 		this(null, text);
121 	}
122 
123 	/**
124 	 * Check the check button.
125 	 *
126 	 * Returns:
127 	 *     This widget to aid method chaining.
128 	 */
129 	public auto check(this T)()
130 	{
131 		this._tk.setVariable(this._valueVariable, this._onValue);
132 
133 		return cast(T) this;
134 	}
135 
136 	/**
137 	 * Uncheck the check button.
138 	 *
139 	 * Returns:
140 	 *     This widget to aid method chaining.
141 	 */
142 	public auto unCheck(this T)()
143 	{
144 		this._tk.setVariable(this._valueVariable, this._offValue);
145 
146 		return cast(T) this;
147 	}
148 
149 	/**
150 	 * Only half check the check button. This is a kind of halfway state.
151 	 *
152 	 * Returns:
153 	 *     This widget to aid method chaining.
154 	 */
155 	public auto halfCheck(this T)()
156 	{
157 		this._tk.setVariable(this._valueVariable, "");
158 
159 		return cast(T) this;
160 	}
161 
162 	/**
163 	 * Check if the check button is checked or not.
164 	 *
165 	 * Returns:
166 	 *     true if the check button is checked, false if not.
167 	 */
168 	public bool isChecked()
169 	{
170 		return this._tk.getVariable(this._valueVariable) == this._onValue;
171 	}
172 
173 	/**
174 	 * Set the value of the checked state.
175 	 *
176 	 * Params:
177 	 *     value = The value of the widget for the checked state.
178 	 *
179 	 * Returns:
180 	 *     This widget to aid method chaining.
181 	 */
182 	public auto setOnValue(this T)(string value)
183 	{
184 		this._onValue = value;
185 		this._tk.eval("%s configure -onvalue %s", this.id, this._onValue);
186 
187 		return cast(T) this;
188 	}
189 
190 	/**
191 	 * Set the value of the unchecked state.
192 	 *
193 	 * Params:
194 	 *     value = The value of the widget for the unchecked state.
195 	 *
196 	 * Returns:
197 	 *     This widget to aid method chaining.
198 	 */
199 	public auto setOffValue(this T)(string value)
200 	{
201 		this._offValue = value;
202 		this._tk.eval("%s configure -offvalue %s", this.id, this._offValue);
203 
204 		return cast(T) this;
205 	}
206 
207 	/**
208 	 * Mixin common commands.
209 	 */
210 	mixin Invoke;
211 	mixin Command;
212 	mixin Value!(this._valueVariable, string);
213 }