1 /**
2 * Widget module.
3 *
4 * License:
5 * MIT. See LICENSE for full details.
6 */
7 module tkd.widget.spinbox;
8
9 /**
10 * Imports.
11 */
12 import std..string;
13 import tkd.element.uielement;
14 import tkd.widget.common.boundingbox;
15 import tkd.widget.common.color;
16 import tkd.widget.common.command;
17 import tkd.widget.common.cursor;
18 import tkd.widget.common.data;
19 import tkd.widget.common.delete_;
20 import tkd.widget.common.exportselection;
21 import tkd.widget.common.font;
22 import tkd.widget.common.index;
23 import tkd.widget.common.insert;
24 import tkd.widget.common.justify;
25 import tkd.widget.common.range;
26 import tkd.widget.common.selection;
27 import tkd.widget.common.show;
28 import tkd.widget.common.value;
29 import tkd.widget.common.width;
30 import tkd.widget.common.xscrollcommand;
31 import tkd.widget.common.xview;
32 import tkd.widget.widget;
33
34 /**
35 * A spinbox widget is an entry widget with built-in up and down buttons that
36 * are used to either modify a numeric value or to select among a set of
37 * values. The widget implements all the features of the entry widget.
38 *
39 * If a list of string values are set to be controlled by this widget it will
40 * override any numeric range or step set. The widget will instead use the
41 * values specified beginning with the first value.
42 *
43 * Example:
44 * ---
45 * auto spinBox = new SpinBox()
46 * .setCommand(delegate(CommandArgs arg){ ... })
47 * .setFromValue(0.0)
48 * .setToValue(100.0)
49 * .setStep(0.5)
50 * .setValue(0.0)
51 * .pack();
52 * ---
53 *
54 * Common_Commands:
55 * These are injected common commands that can also be used with this widget.
56 * $(P
57 * $(LINK2 ./common/boundingbox.html, BoundingBox) $(BR)
58 * $(LINK2 ./common/color.html, Color) $(BR)
59 * $(LINK2 ./common/command.html, Command) $(BR)
60 * $(LINK2 ./common/cursor.html, Cursor) $(BR)
61 * $(LINK2 ./common/data.html, Data) $(BR)
62 * $(LINK2 ./common/delete_.html, Delete) $(BR)
63 * $(LINK2 ./common/exportselection.html, Exportselection) $(BR)
64 * $(LINK2 ./common/font.html, Font) $(BR)
65 * $(LINK2 ./common/index.html, Index) $(BR)
66 * $(LINK2 ./common/insert.html, Insert) $(BR)
67 * $(LINK2 ./common/justify.html, Justify) $(BR)
68 * $(LINK2 ./common/range.html, Range) $(BR)
69 * $(LINK2 ./common/selection.html, Selection) $(BR)
70 * $(LINK2 ./common/show.html, Show) $(BR)
71 * $(LINK2 ./common/value.html, Value) $(BR)
72 * $(LINK2 ./common/width.html, Width) $(BR)
73 * $(LINK2 ./common/xscrollcommand.html, XScrollCommand) $(BR)
74 * $(LINK2 ./common/xview.html, XView) $(BR)
75 * )
76 *
77 * Additional_Events:
78 * Additional events that can also be bound to using the $(LINK2 ../element/uielement.html#UiElement.bind, bind) method.
79 * $(P
80 * <<Clear>>,
81 * <<Copy>>,
82 * <<Cut>>,
83 * <<Decrement>>,
84 * <<Increment>>,
85 * <<Paste>>,
86 * <<PasteSelection>>,
87 * <<PrevWindow>>,
88 * <<TraverseIn>>,
89 * <Alt-Key>,
90 * <B1-Enter>,
91 * <B1-Leave>,
92 * <B1-Motion>,
93 * <B2-Motion>,
94 * <Button-1>,
95 * <Button-2>,
96 * <ButtonRelease-1>,
97 * <Control-Button-1>,
98 * <Control-Key>,
99 * <Control-Key-Left>,
100 * <Control-Key-Right>,
101 * <Control-Key-a>,
102 * <Control-Key-b>,
103 * <Control-Key-backslash>,
104 * <Control-Key-d>,
105 * <Control-Key-e>,
106 * <Control-Key-f>,
107 * <Control-Key-h>,
108 * <Control-Key-k>,
109 * <Control-Key-slash>,
110 * <Control-Key-space>,
111 * <Control-Key-t>,
112 * <Control-Shift-Key-Left>,
113 * <Control-Shift-Key-Right>,
114 * <Control-Shift-Key-space>,
115 * <Double-Button-1>,
116 * <Double-Shift-Button-1>,
117 * <Key>,
118 * <Key-BackSpace>,
119 * <Key-Delete>,
120 * <Key-Down>,
121 * <Key-End>,
122 * <Key-Escape>,
123 * <Key-F10>,
124 * <Key-Home>,
125 * <Key-Insert>,
126 * <Key-KP_Enter>,
127 * <Key-Left>,
128 * <Key-Return>,
129 * <Key-Right>,
130 * <Key-Select>,
131 * <Key-Tab>,
132 * <Key-Up>,
133 * <Meta-Key>,
134 * <Meta-Key-BackSpace>,
135 * <Meta-Key-Delete>,
136 * <Meta-Key-b>,
137 * <Meta-Key-d>,
138 * <Meta-Key-f>,
139 * <Shift-Button-1>,
140 * <Shift-Key-End>,
141 * <Shift-Key-Home>,
142 * <Shift-Key-Left>,
143 * <Shift-Key-Right>,
144 * <Shift-Key-Select>,
145 * <Triple-Button-1>,
146 * <Triple-Shift-Button-1>,
147 * )
148 *
149 * See_Also:
150 * $(LINK2 ./widget.html, tkd.widget.widget)
151 */
152 class SpinBox : Widget, IXScrollable!(SpinBox)
153 {
154 /**
155 * The name of the variable that contains the widget's value.
156 */
157 private string _valueVariable;
158
159 /**
160 * Construct the widget.
161 *
162 * Params:
163 * parent = The parent of this widget.
164 *
165 * See_Also:
166 * $(LINK2 ../element/uielement.html, tkd.element.uielement) $(BR)
167 */
168 this(UiElement parent = null)
169 {
170 super(parent);
171 this._elementId = "spinbox";
172 this._valueVariable = format("variable-%s", this.generateHash(this.id));
173
174 this._tk.eval("ttk::spinbox %s -textvariable %s", this.id, this._valueVariable);
175
176 this.setFromValue(int.min);
177 this.setToValue(int.max);
178 this.setValue("0");
179 }
180
181 /**
182 * For widgets using a numeric range, this method sets the step value of
183 * each increment or decrement.
184 *
185 * Params:
186 * stepValue = The step value to increment and decrement by.
187 *
188 * Returns:
189 * This widget to aid method chaining.
190 */
191 public auto setStep(this T)(double stepValue)
192 {
193 assert(stepValue > 0, "Step value should be greater than zero.");
194
195 this._tk.eval("%s configure -increment %s", this.id, stepValue);
196
197 return cast(T) this;
198 }
199
200 /**
201 * Set whether the values wrap when the limit is reached during increment
202 * or decrement.
203 *
204 * Params:
205 * wrapValue = Value specifing whether the value wraps.
206 *
207 * Returns:
208 * This widget to aid method chaining.
209 */
210 public auto setWrap(this T)(bool wrapValue)
211 {
212 this._tk.eval("%s configure -wrap %s", this.id, wrapValue);
213
214 return cast(T) this;
215 }
216
217 /**
218 * Specifies an alternate format to use when using a numerical range. This
219 * must be a format specifier of the form '%5.2f', as it will format a
220 * floating-point number.
221 *
222 * Params:
223 * digitsBefore = The amount of digits to show before a decimal point.
224 * digitsAfter = The amount of digits to show after a decimal point.
225 *
226 * Returns:
227 * This widget to aid method chaining.
228 */
229 public auto setNumericFormat(this T)(int digitsBefore, int digitsAfter)
230 {
231 this._tk.eval("%s configure -format %%%s.%sf", this.id, digitsBefore, digitsAfter);
232
233 return cast(T) this;
234 }
235
236 /**
237 * Mixin common commands.
238 */
239 mixin BoundingBox;
240 mixin Color;
241 mixin Command;
242 mixin Cursor;
243 mixin Data;
244 mixin Delete_;
245 mixin ExportSelection;
246 mixin Font;
247 mixin Index;
248 mixin Insert;
249 mixin Justify;
250 mixin Range;
251 mixin Selection;
252 mixin Show;
253 mixin Value!(this._valueVariable, string);
254 mixin Width;
255 mixin XScrollCommand!(SpinBox);
256 mixin XView;
257 }