1
by Deng Dongpo
initial |
1 |
/*!
|
2 |
* Ext JS Library 3.2.1
|
|
3 |
* Copyright(c) 2006-2010 Ext JS, Inc.
|
|
4 |
* licensing@extjs.com
|
|
5 |
* http://www.extjs.com/license
|
|
6 |
*/
|
|
7 |
/**
|
|
8 |
* @class Ext.ProgressBar
|
|
9 |
* @extends Ext.BoxComponent
|
|
10 |
* <p>An updateable progress bar component. The progress bar supports two different modes: manual and automatic.</p>
|
|
11 |
* <p>In manual mode, you are responsible for showing, updating (via {@link #updateProgress}) and clearing the
|
|
12 |
* progress bar as needed from your own code. This method is most appropriate when you want to show progress
|
|
13 |
* throughout an operation that has predictable points of interest at which you can update the control.</p>
|
|
14 |
* <p>In automatic mode, you simply call {@link #wait} and let the progress bar run indefinitely, only clearing it
|
|
15 |
* once the operation is complete. You can optionally have the progress bar wait for a specific amount of time
|
|
16 |
* and then clear itself. Automatic mode is most appropriate for timed operations or asynchronous operations in
|
|
17 |
* which you have no need for indicating intermediate progress.</p>
|
|
18 |
* @cfg {Float} value A floating point value between 0 and 1 (e.g., .5, defaults to 0)
|
|
19 |
* @cfg {String} text The progress bar text (defaults to '')
|
|
20 |
* @cfg {Mixed} textEl The element to render the progress text to (defaults to the progress
|
|
21 |
* bar's internal text element)
|
|
22 |
* @cfg {String} id The progress bar element's id (defaults to an auto-generated id)
|
|
23 |
* @xtype progress
|
|
24 |
*/
|
|
25 |
Ext.ProgressBar = Ext.extend(Ext.BoxComponent, { |
|
26 |
/**
|
|
27 |
* @cfg {String} baseCls
|
|
28 |
* The base CSS class to apply to the progress bar's wrapper element (defaults to 'x-progress')
|
|
29 |
*/
|
|
30 |
baseCls : 'x-progress', |
|
31 |
||
32 |
/**
|
|
33 |
* @cfg {Boolean} animate
|
|
34 |
* True to animate the progress bar during transitions (defaults to false)
|
|
35 |
*/
|
|
36 |
animate : false, |
|
37 |
||
38 |
// private
|
|
39 |
waitTimer : null, |
|
40 |
||
41 |
// private
|
|
42 |
initComponent : function(){ |
|
43 |
Ext.ProgressBar.superclass.initComponent.call(this); |
|
44 |
this.addEvents( |
|
45 |
/**
|
|
46 |
* @event update
|
|
47 |
* Fires after each update interval
|
|
48 |
* @param {Ext.ProgressBar} this
|
|
49 |
* @param {Number} The current progress value
|
|
50 |
* @param {String} The current progress text
|
|
51 |
*/
|
|
52 |
"update"
|
|
53 |
);
|
|
54 |
},
|
|
55 |
||
56 |
// private
|
|
57 |
onRender : function(ct, position){ |
|
58 |
var tpl = new Ext.Template( |
|
59 |
'<div class="{cls}-wrap">', |
|
60 |
'<div class="{cls}-inner">', |
|
61 |
'<div class="{cls}-bar">', |
|
62 |
'<div class="{cls}-text">', |
|
63 |
'<div> </div>', |
|
64 |
'</div>', |
|
65 |
'</div>', |
|
66 |
'<div class="{cls}-text {cls}-text-back">', |
|
67 |
'<div> </div>', |
|
68 |
'</div>', |
|
69 |
'</div>', |
|
70 |
'</div>'
|
|
71 |
);
|
|
72 |
||
73 |
this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true) |
|
74 |
: tpl.append(ct, {cls: this.baseCls}, true); |
|
75 |
||
76 |
if(this.id){ |
|
77 |
this.el.dom.id = this.id; |
|
78 |
}
|
|
79 |
var inner = this.el.dom.firstChild; |
|
80 |
this.progressBar = Ext.get(inner.firstChild); |
|
81 |
||
82 |
if(this.textEl){ |
|
83 |
//use an external text el
|
|
84 |
this.textEl = Ext.get(this.textEl); |
|
85 |
delete this.textTopEl; |
|
86 |
}else{ |
|
87 |
//setup our internal layered text els
|
|
88 |
this.textTopEl = Ext.get(this.progressBar.dom.firstChild); |
|
89 |
var textBackEl = Ext.get(inner.childNodes[1]); |
|
90 |
this.textTopEl.setStyle("z-index", 99).addClass('x-hidden'); |
|
91 |
this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]); |
|
92 |
this.textEl.setWidth(inner.offsetWidth); |
|
93 |
}
|
|
94 |
this.progressBar.setHeight(inner.offsetHeight); |
|
95 |
},
|
|
96 |
||
97 |
// private
|
|
98 |
afterRender : function(){ |
|
99 |
Ext.ProgressBar.superclass.afterRender.call(this); |
|
100 |
if(this.value){ |
|
101 |
this.updateProgress(this.value, this.text); |
|
102 |
}else{ |
|
103 |
this.updateText(this.text); |
|
104 |
}
|
|
105 |
},
|
|
106 |
||
107 |
/**
|
|
108 |
* Updates the progress bar value, and optionally its text. If the text argument is not specified,
|
|
109 |
* any existing text value will be unchanged. To blank out existing text, pass ''. Note that even
|
|
110 |
* if the progress bar value exceeds 1, it will never automatically reset -- you are responsible for
|
|
111 |
* determining when the progress is complete and calling {@link #reset} to clear and/or hide the control.
|
|
112 |
* @param {Float} value (optional) A floating point value between 0 and 1 (e.g., .5, defaults to 0)
|
|
113 |
* @param {String} text (optional) The string to display in the progress text element (defaults to '')
|
|
114 |
* @param {Boolean} animate (optional) Whether to animate the transition of the progress bar. If this value is
|
|
115 |
* not specified, the default for the class is used (default to false)
|
|
116 |
* @return {Ext.ProgressBar} this
|
|
117 |
*/
|
|
118 |
updateProgress : function(value, text, animate){ |
|
119 |
this.value = value || 0; |
|
120 |
if(text){ |
|
121 |
this.updateText(text); |
|
122 |
}
|
|
123 |
if(this.rendered && !this.isDestroyed){ |
|
124 |
var w = Math.floor(value*this.el.dom.firstChild.offsetWidth); |
|
125 |
this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate)); |
|
126 |
if(this.textTopEl){ |
|
127 |
//textTopEl should be the same width as the bar so overflow will clip as the bar moves
|
|
128 |
this.textTopEl.removeClass('x-hidden').setWidth(w); |
|
129 |
}
|
|
130 |
}
|
|
131 |
this.fireEvent('update', this, value, text); |
|
132 |
return this; |
|
133 |
},
|
|
134 |
||
135 |
/**
|
|
136 |
* Initiates an auto-updating progress bar. A duration can be specified, in which case the progress
|
|
137 |
* bar will automatically reset after a fixed amount of time and optionally call a callback function
|
|
138 |
* if specified. If no duration is passed in, then the progress bar will run indefinitely and must
|
|
139 |
* be manually cleared by calling {@link #reset}. The wait method accepts a config object with
|
|
140 |
* the following properties:
|
|
141 |
* <pre>
|
|
142 |
Property Type Description
|
|
143 |
---------- ------------ ----------------------------------------------------------------------
|
|
144 |
duration Number The length of time in milliseconds that the progress bar should
|
|
145 |
run before resetting itself (defaults to undefined, in which case it
|
|
146 |
will run indefinitely until reset is called)
|
|
147 |
interval Number The length of time in milliseconds between each progress update
|
|
148 |
(defaults to 1000 ms)
|
|
149 |
animate Boolean Whether to animate the transition of the progress bar. If this value is
|
|
150 |
not specified, the default for the class is used.
|
|
151 |
increment Number The number of progress update segments to display within the progress
|
|
152 |
bar (defaults to 10). If the bar reaches the end and is still
|
|
153 |
updating, it will automatically wrap back to the beginning.
|
|
154 |
text String Optional text to display in the progress bar element (defaults to '').
|
|
155 |
fn Function A callback function to execute after the progress bar finishes auto-
|
|
156 |
updating. The function will be called with no arguments. This function
|
|
157 |
will be ignored if duration is not specified since in that case the
|
|
158 |
progress bar can only be stopped programmatically, so any required function
|
|
159 |
should be called by the same code after it resets the progress bar.
|
|
160 |
scope Object The scope that is passed to the callback function (only applies when
|
|
161 |
duration and fn are both passed).
|
|
162 |
</pre>
|
|
163 |
*
|
|
164 |
* Example usage:
|
|
165 |
* <pre><code>
|
|
166 |
var p = new Ext.ProgressBar({
|
|
167 |
renderTo: 'my-el'
|
|
168 |
});
|
|
169 |
||
170 |
//Wait for 5 seconds, then update the status el (progress bar will auto-reset)
|
|
171 |
p.wait({
|
|
172 |
interval: 100, //bar will move fast!
|
|
173 |
duration: 5000,
|
|
174 |
increment: 15,
|
|
175 |
text: 'Updating...',
|
|
176 |
scope: this,
|
|
177 |
fn: function(){
|
|
178 |
Ext.fly('status').update('Done!');
|
|
179 |
}
|
|
180 |
});
|
|
181 |
||
182 |
//Or update indefinitely until some async action completes, then reset manually
|
|
183 |
p.wait();
|
|
184 |
myAction.on('complete', function(){
|
|
185 |
p.reset();
|
|
186 |
Ext.fly('status').update('Done!');
|
|
187 |
});
|
|
188 |
</code></pre>
|
|
189 |
* @param {Object} config (optional) Configuration options
|
|
190 |
* @return {Ext.ProgressBar} this
|
|
191 |
*/
|
|
192 |
wait : function(o){ |
|
193 |
if(!this.waitTimer){ |
|
194 |
var scope = this; |
|
195 |
o = o || {}; |
|
196 |
this.updateText(o.text); |
|
197 |
this.waitTimer = Ext.TaskMgr.start({ |
|
198 |
run: function(i){ |
|
199 |
var inc = o.increment || 10; |
|
200 |
i -= 1; |
|
201 |
this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate); |
|
202 |
},
|
|
203 |
interval: o.interval || 1000, |
|
204 |
duration: o.duration, |
|
205 |
onStop: function(){ |
|
206 |
if(o.fn){ |
|
207 |
o.fn.apply(o.scope || this); |
|
208 |
}
|
|
209 |
this.reset(); |
|
210 |
},
|
|
211 |
scope: scope |
|
212 |
});
|
|
213 |
}
|
|
214 |
return this; |
|
215 |
},
|
|
216 |
||
217 |
/**
|
|
218 |
* Returns true if the progress bar is currently in a {@link #wait} operation
|
|
219 |
* @return {Boolean} True if waiting, else false
|
|
220 |
*/
|
|
221 |
isWaiting : function(){ |
|
222 |
return this.waitTimer !== null; |
|
223 |
},
|
|
224 |
||
225 |
/**
|
|
226 |
* Updates the progress bar text. If specified, textEl will be updated, otherwise the progress
|
|
227 |
* bar itself will display the updated text.
|
|
228 |
* @param {String} text (optional) The string to display in the progress text element (defaults to '')
|
|
229 |
* @return {Ext.ProgressBar} this
|
|
230 |
*/
|
|
231 |
updateText : function(text){ |
|
232 |
this.text = text || ' '; |
|
233 |
if(this.rendered){ |
|
234 |
this.textEl.update(this.text); |
|
235 |
}
|
|
236 |
return this; |
|
237 |
},
|
|
238 |
||
239 |
/**
|
|
240 |
* Synchronizes the inner bar width to the proper proportion of the total componet width based
|
|
241 |
* on the current progress {@link #value}. This will be called automatically when the ProgressBar
|
|
242 |
* is resized by a layout, but if it is rendered auto width, this method can be called from
|
|
243 |
* another resize handler to sync the ProgressBar if necessary.
|
|
244 |
*/
|
|
245 |
syncProgressBar : function(){ |
|
246 |
if(this.value){ |
|
247 |
this.updateProgress(this.value, this.text); |
|
248 |
}
|
|
249 |
return this; |
|
250 |
},
|
|
251 |
||
252 |
/**
|
|
253 |
* Sets the size of the progress bar.
|
|
254 |
* @param {Number} width The new width in pixels
|
|
255 |
* @param {Number} height The new height in pixels
|
|
256 |
* @return {Ext.ProgressBar} this
|
|
257 |
*/
|
|
258 |
setSize : function(w, h){ |
|
259 |
Ext.ProgressBar.superclass.setSize.call(this, w, h); |
|
260 |
if(this.textTopEl){ |
|
261 |
var inner = this.el.dom.firstChild; |
|
262 |
this.textEl.setSize(inner.offsetWidth, inner.offsetHeight); |
|
263 |
}
|
|
264 |
this.syncProgressBar(); |
|
265 |
return this; |
|
266 |
},
|
|
267 |
||
268 |
/**
|
|
269 |
* Resets the progress bar value to 0 and text to empty string. If hide = true, the progress
|
|
270 |
* bar will also be hidden (using the {@link #hideMode} property internally).
|
|
271 |
* @param {Boolean} hide (optional) True to hide the progress bar (defaults to false)
|
|
272 |
* @return {Ext.ProgressBar} this
|
|
273 |
*/
|
|
274 |
reset : function(hide){ |
|
275 |
this.updateProgress(0); |
|
276 |
if(this.textTopEl){ |
|
277 |
this.textTopEl.addClass('x-hidden'); |
|
278 |
}
|
|
279 |
this.clearTimer(); |
|
280 |
if(hide === true){ |
|
281 |
this.hide(); |
|
282 |
}
|
|
283 |
return this; |
|
284 |
},
|
|
285 |
||
286 |
// private
|
|
287 |
clearTimer : function(){ |
|
288 |
if(this.waitTimer){ |
|
289 |
this.waitTimer.onStop = null; //prevent recursion |
|
290 |
Ext.TaskMgr.stop(this.waitTimer); |
|
291 |
this.waitTimer = null; |
|
292 |
}
|
|
293 |
},
|
|
294 |
||
295 |
onDestroy: function(){ |
|
296 |
this.clearTimer(); |
|
297 |
if(this.rendered){ |
|
298 |
if(this.textEl.isComposite){ |
|
299 |
this.textEl.clear(); |
|
300 |
}
|
|
301 |
Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl'); |
|
302 |
}
|
|
303 |
Ext.ProgressBar.superclass.onDestroy.call(this); |
|
304 |
}
|
|
305 |
});
|
|
306 |
Ext.reg('progress', Ext.ProgressBar); |