'use strict'; /*@ Ox.Progressbar Progress Bar ([options[, self]]) -> Progress Bar options Options object cancelled If true, progress bar is cancelled paused If true, progress bar is paused progress Progress, float between 0 and 1, or -1 for indeterminate showCancelButton If true, show cancel button showPauseButton If true, show pause button showPercent If true, show progress in percent showRestartButton If true, show restart button showTime If true, show remaining time showTooltips If true, buttons have tooltips width Width in px self Shared private variable cancel cancelled complete completed pause paused resume resumed @*/ Ox.Progressbar = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ cancelled: false, paused: false, progress: 0, showCancelButton: false, showPauseButton: false, showPercent: false, showRestartButton: false, showTime: false, showTooltips: false, width: 256 }) .options(options || {}) .update({ cancelled: toggleCancelled, paused: togglePaused, progress: function() { self.options.progress = Ox.limit(self.options.progress, 0, 1); !self.options.paused && !self.options.cancelled && setProgress(true); } }) .addClass('OxProgressbar') .css({width: self.options.width - 2 + 'px'}); self.indeterminate = self.options.progress == -1; 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', tooltip: self.options.showTooltips ? ['Pause', 'Resume'] : '', type: 'image', value: !self.options.paused ? 'pause' : 'redo', values: ['pause', 'redo'] }) .bindEvent({ click: togglePaused }) .appendTo(that); } if (self.options.showCancelButton) { self.$cancelButton = Ox.Button(Ox.extend({ style: 'symbol', type: 'image' }, self.options.showRestartButton ? { tooltip: self.options.showTooltips ? ['Cancel', 'Restart'] : '', value: 'close', values: ['close', 'redo'] } : { title: 'close', tooltip: self.options.showTooltips ? 'Cancel' : '' })) .bindEvent({ click: toggleCancelled }) .appendTo(that); } setProgress(); !self.options.paused && resume(); function cancel() { self.options.cancelled = true; if (self.options.paused) { self.options.paused = false; self.$pauseButton && self.$pauseButton.toggle(); } stop(); that.triggerEvent('cancel'); } function complete() { self.complete = true; stop(); self.paused = false; that.triggerEvent('complete'); } function pause() { self.pauseTime = +new Date(); self.$progress.removeClass('OxAnimate'); ($.browser.mozilla || $.browser.opera) && clearInterval(self.interval); self.$time && self.$time.html( self.options.cancelled ? 'Cancelled' : 'Paused' ); } function restart() { self.options.cancelled = false; if (!self.indeterminate) { self.options.progress = 0; } delete self.startTime; self.$pauseButton && self.$pauseButton.options({disabled: false}); setProgress(); resume(); that.triggerEvent('restart'); } function resume() { self.startTime = !self.startTime ? +new Date() : self.startTime + +new Date() - self.pauseTime; self.$progress.addClass('OxAnimate'); if ($.browser.mozilla || $.browser.opera) { self.offset = 0; self.interval = setInterval(function() { self.$progress.css({backgroundPosition: --self.offset + 'px 0, 0 0'}) }, 1000 / 32); } self.$time && self.$time.html( self.options.progress ? Ox.formatDuration(that.status().remaining) : 'unknown' ); } function setProgress(animate) { 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 + Math.abs(self.options.progress) * (self.trackWidth - 16)) + 'px' }, animate ? 250 : 0, function() { self.options.progress == 1 && complete(); }); } function stop() { pause(); self.$time && self.$time.html( self.options.cancelled ? 'Cancelled' : 'Complete' ); if (self.$pauseButton && (self.options.cancelled || self.complete)) { self.$pauseButton.options({disabled: true}); } if (self.$cancelButton && (self.complete || !self.options.showRestartButton)) { self.$cancelButton.options({disabled: true}); } } function toggleCancelled(e) { if (e) { self.options.cancelled = !self.options.cancelled; } else if (self.$cancelButton) { self.$cancelButton.toggle(); } self.options.cancelled ? cancel() : restart(); that.triggerEvent(self.options.cancelled ? 'cancel' : 'restart'); } function togglePaused(e) { if (e) { self.options.paused = !self.options.paused; } else if (self.$pauseButton) { self.$pauseButton.toggle(); } self.options.paused ? pause() : resume(); that.triggerEvent(self.options.paused ? 'pause' : 'resume'); } /*@ that.status Returns time elapsed / remaining () -> status @*/ 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; };