Ox.Progressbar = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ paused: false, progress: 0, showCancelButton: false, showPauseButton: false, showPercent: false, showTime: false, width: 256 }) .options(options || {}) .addClass('OxProgressbar') .css({width: self.options.width - 2 + 'px'}); self.trackWidth = self.options.width - self.options.showPercent * 36 - self.options.showTime * 60 - self.options.showPauseButton * 16 - self.options.showCancelButton * 16; self.$track = $('
') .addClass('OxTrack') .css({ width: self.trackWidth - 2 + 'px' }) .appendTo(that); self.$progress = $('
') .addClass('OxProgress') .appendTo(self.$track); if (self.options.showPercent) { self.$percent = $('
') .addClass('OxText') .css({width: '36px'}) .appendTo(that); } if (self.options.showTime) { self.$time = $('
') .addClass('OxText') .css({width: '60px'}) .appendTo(that); } if (self.options.showPauseButton) { self.$pauseButton = Ox.Button({ style: 'symbol', title: [ {id: 'pause', title: 'pause', selected: !self.options.paused}, {id: 'resume', title: 'redo', selected: self.options.paused} ], tooltip: ['Pause', 'Resume'], type: 'image' }) .bindEvent({ click: togglePaused }) .appendTo(that); } if (self.options.showCancelButton) { self.$cancelButton = Ox.Button({ style: 'symbol', title: 'close', tooltip: 'Cancel', type: 'image' }) .bindEvent({ click: cancel }) .appendTo(that); } !self.options.paused && resume(); function cancel() { self.cancelled = true; stop(); that.triggerEvent('cancel'); } function pause() { self.pauseTime = +new Date(); self.$progress.removeClass('OxAnimate'); $.browser.mozilla && clearInterval(self.interval); self.$time && self.$time .addClass('OxSmall') .html(self.cancelled ? 'Cancelled' : 'Paused'); } function resume() { self.startTime = !self.startTime ? +new Date() : self.startTime + +new Date() - self.pauseTime; self.$progress.addClass('OxAnimate'); if ($.browser.mozilla) { self.offset = 0; self.interval = setInterval(function() { self.$progress.css({backgroundPosition: --self.offset + 'px 0, 0 0'}) }, 1000 / 32); } self.$time && self.$time .removeClass('OxSmall') .html(self.options.progress ? Ox.formatDuration(that.status().remaining) : 'unknown'); } function setProgress() { self.$percent && self.$percent.html( Math.floor(self.options.progress * 100) + '%' ); self.$time && self.$time.html( self.options.progress ? Ox.formatDuration(that.status().remaining) : 'unknown' ); self.$progress.stop().animate({ width: Math.round(14 + self.options.progress * (self.trackWidth - 16)) + 'px' }, 250, function() { self.options.progress == 1 && stop(); }); } function stop() { pause(); self.$time && self.$time .addClass('OxSmall') .html(self.cancelled ? 'Cancelled' : 'Complete'); self.$pauseButton.options({disabled: true}); self.$cancelButton.options({disabled: true}); } function togglePaused() { self.options.paused = !self.options.paused; if (self.options.paused) { pause() } else { resume(); } that.triggerEvent(self.options.paused ? 'pause' : 'resume'); } self.setOption = function(key, value) { if (key == 'paused') { togglePaused(); } if (key == 'progress') { self.options.progress = Ox.limit(self.options.progress, 0, 1); !self.options.paused && !self.options.cancelled && setProgress(); } }; that.status = function() { var elapsed = +new Date() - self.startTime, remaining = elapsed / self.options.progress * (1 - self.options.progress); return { elapsed: Math.floor(elapsed / 1000), remaining: self.options.progress ? Math.ceil(remaining / 1000) : Infinity }; }; return that; };