1 /**
2  * Widget module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.widget.progressbar;
8 
9 /**
10  * Imports.
11  */
12 import std..string;
13 import tkd.element.uielement;
14 import tkd.widget.common.length;
15 import tkd.widget.common.value;
16 import tkd.widget.orientation;
17 import tkd.widget.widget;
18 
19 /**
20  * A progress bar widget shows the status of a long-running operation. They can 
21  * operate in two modes: determinate mode shows the amount completed relative 
22  * to the total amount of work to be done, and indeterminate mode provides an 
23  * animated display to let the user know that something is happening.
24  *
25  * Example:
26  * ---
27  * auto progressBar = new ProgressBar()
28  * 	.setMaxValue(100)
29  * 	.setValue(10)
30  * 	.pack();
31  * ---
32  *
33  * Common_Commands:
34  *     These are injected common commands that can also be used with this widget.
35  *     $(P
36  *         $(LINK2 ./common/length.html, Length) $(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  *         <<PrevWindow>>,
44  *         <Alt-Key>,
45  *         <Key-F10>,
46  *         <Key-Tab>,
47  *     )
48  *
49  * See_Also:
50  *     $(LINK2 ./widget.html, tkd.widget.widget)
51  */
52 class ProgressBar : Widget
53 {
54 	/**
55 	 * The name of the variable that contains the widget's value.
56 	 */
57 	private string _valueVariable;
58 
59 	/**
60 	 * Construct the widget.
61 	 *
62 	 * Params:
63 	 *     parent = The parent of this widget.
64 	 *     orientation = The orientation of the widget.
65 	 *
66 	 * See_Also:
67 	 *     $(LINK2 ../element/uielement.html, tkd.element.UiElement) $(BR)
68 	 *     $(LINK2 ./orientation.html, tkd.widget.orientation) for orientations.
69 	 */
70 	public this(UiElement parent, string orientation = Orientation.horizontal)
71 	{
72 		super(parent);
73 		this._elementId     = "progressbar";
74 		this._valueVariable = format("variable-%s", this.generateHash(this.id));
75 
76 		this._tk.eval("ttk::progressbar %s -orient %s -variable %s", this.id, orientation, this._valueVariable);
77 	}
78 
79 	/**
80 	 * Construct the widget.
81 	 *
82 	 * Params:
83 	 *     orientation = The orientation of the widget.
84 	 *
85 	 * See_Also:
86 	 *     $(LINK2 ./orientation.html, tkd.widget.orientation) for orientations.
87 	 */
88 	public this(string orientation = Orientation.horizontal)
89 	{
90 		this(null, orientation);
91 	}
92 
93 	/**
94 	 * Set the mode of the progress bar.
95 	 *
96 	 * Params:
97 	 *     mode = The mode of the progress bar.
98 	 *
99 	 * Returns:
100 	 *     This widget to aid method chaining.
101 	 *
102 	 * See_Also:
103 	 *     $(LINK2 ./progressbar.html#ProgressBarMode, tkd.widget.progressbar.ProgressBarMode) $(BR)
104 	 */
105 	public auto setMode(this T)(string mode)
106 	{
107 		this._tk.eval("%s configure -mode %s", this.id, mode);
108 
109 		return cast(T) this;
110 	}
111 
112 	/**
113 	 * Set the maximum value of the progress bar.
114 	 *
115 	 * Params:
116 	 *     maximum = The maximum value of the progress bar.
117 	 *
118 	 * Returns:
119 	 *     This widget to aid method chaining.
120 	 */
121 	public auto setMaxValue(this T)(double maximum)
122 	{
123 		this._tk.eval("%s configure -maximum %s", this.id, maximum);
124 
125 		return cast(T) this;
126 	}
127 
128 	/**
129 	 * The widget periodically increments the value of this option whenever the 
130 	 * value is greater than 0 and, in determinate mode, less than the maximum. 
131 	 * This option may be used by the current theme to provide additional 
132 	 * animation effects.
133 	 *
134 	 * Returns:
135 	 *     A string containing the phase value.
136 	 */
137 	public string getPhase()
138 	{
139 		this._tk.eval("%s cget -phase", this.id);
140 		return this._tk.getResult!(string);
141 	}
142 
143 	/**
144 	 * Begin autoincrement mode: schedules a recurring timer event that calls 
145 	 * step every interval.
146 	 *
147 	 * Params:
148 	 *     milliseconds = The interval between steps.
149 	 *
150 	 * Returns:
151 	 *     This widget to aid method chaining.
152 	 *
153 	 * See_Also:
154 	 *     $(LINK2 ./progressbar.html#ProgressBar.stop, tkd.widget.progressbar.stop) $(BR)
155 	 */
156 	public auto start(this T)(int milliseconds = 50)
157 	{
158 		this._tk.eval("%s start %s", this.id, milliseconds);
159 
160 		return cast(T) this;
161 	}
162 
163 	/**
164 	 * Increments the progress bar by an amount.
165 	 *
166 	 * Params:
167 	 *     increment = The amount to increment by.
168 	 *
169 	 * Returns:
170 	 *     This widget to aid method chaining.
171 	 */
172 	public auto step(this T)(int increment = 1)
173 	{
174 		this._tk.eval("%s step %s", this.id, increment);
175 
176 		return cast(T) this;
177 	}
178 
179 	/**
180 	 * Stop autoincrement mode: cancels any recurring timer event initiated by 
181 	 * the start method.
182 	 *
183 	 * Returns:
184 	 *     This widget to aid method chaining.
185 	 *
186 	 * See_Also:
187 	 *     $(LINK2 ./progressbar.html#ProgressBar.start, tkd.widget.progressbar.start) $(BR)
188 	 */
189 	public auto stop(this T)()
190 	{
191 		this._tk.eval("%s stop", this.id);
192 
193 		return cast(T) this;
194 	}
195 
196 	/**
197 	 * Mixin common commands.
198 	 */
199 	mixin Length;
200 	mixin Value!(this._valueVariable, double);
201 }
202 
203 /**
204  * The mode of a progress bar.
205  */
206 enum ProgressBarMode : string
207 {
208 	determinate   = "determinate",   /// Shows the amount completed relative to the total amount of work to be done.
209 	indeterminate = "indeterminate", /// Provides an animated display to let the user know that something is happening.
210 }