diff --git a/js/term/widgets/progressbar.js b/js/term/widgets/progressbar.js new file mode 100644 index 0000000..a5418f9 --- /dev/null +++ b/js/term/widgets/progressbar.js @@ -0,0 +1,183 @@ +/** + ** ============================== + ** O O O OOOO + ** O O O O O O + ** O O O O O O + ** OOOO OOOO O OOO OOOO + ** O O O O O O O + ** O O O O O O O + ** OOOO OOOO O O OOOO + ** ============================== + ** Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR(S). + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Christopher Jeffrey, Stefan Bosse + ** $INITIAL: (C) 2013-2015, Christopher Jeffrey and contributors + ** $MODIFIED: by sbosse + ** $REVESIO: 1.2.1 + ** + ** $INFO: + ** + ** progressbar.js - progress bar element for blessed + ** + ** $ENDOFINFO + */ + +/** + * Modules + */ +var Comp = Require('com/compat'); + +var Node = Require('term/widgets/node'); +var Input = Require('term/widgets/input'); + +/** + * ProgressBar + */ + +function ProgressBar(options) { + var self = this; + + if (!instanceOf(this,Node)) { + return new ProgressBar(options); + } + + options = options || {}; + + Input.call(this, options); + + this.filled = options.filled || 0; + if (typeof this.filled === 'string') { + this.filled = +this.filled.slice(0, -1); + } + this.value = this.filled; + + this.pch = options.pch || ' '; + + // XXX Workaround that predates the usage of `el.ch`. + if (options.ch) { + this.pch = options.ch; + this.ch = ' '; + } + if (options.bch) { + this.ch = options.bch; + } + + if (!this.style.bar) { + this.style.bar = {}; + this.style.bar.fg = options.barFg; + this.style.bar.bg = options.barBg; + } + + this.orientation = options.orientation || 'horizontal'; + + if (options.keys) { + this.on('keypress', function(ch, key) { + var back, forward; + if (self.orientation === 'horizontal') { + back = ['left', 'h']; + forward = ['right', 'l']; + } else if (self.orientation === 'vertical') { + back = ['down', 'j']; + forward = ['up', 'k']; + } + if (key.name === back[0] || (options.vi && key.name === back[1])) { + self.progress(-5); + self.screen.render(); + return; + } + if (key.name === forward[0] || (options.vi && key.name === forward[1])) { + self.progress(5); + self.screen.render(); + return; + } + }); + } + + if (options.mouse) { + this.on('click', function(data) { + var x, y, m, p; + if (!self.lpos) return; + if (self.orientation === 'horizontal') { + x = data.x - self.lpos.xi; + m = (self.lpos.xl - self.lpos.xi) - self.iwidth; + p = x / m * 100 | 0; + } else if (self.orientation === 'vertical') { + y = data.y - self.lpos.yi; + m = (self.lpos.yl - self.lpos.yi) - self.iheight; + p = y / m * 100 | 0; + } + self.setProgress(p); + }); + } +} + +//ProgressBar.prototype.__proto__ = Input.prototype; +inheritPrototype(ProgressBar,Input); + +ProgressBar.prototype.type = 'progress-bar'; + +ProgressBar.prototype.render = function() { + var ret = this._render(); + if (!ret) return; + + var xi = ret.xi + , xl = ret.xl + , yi = ret.yi + , yl = ret.yl + , dattr; + + if (this.border) xi++, yi++, xl--, yl--; + + if (this.orientation === 'horizontal') { + xl = xi + ((xl - xi) * (this.filled / 100)) | 0; + } else if (this.orientation === 'vertical') { + yi = yi + ((yl - yi) - (((yl - yi) * (this.filled / 100)) | 0)); + } + + dattr = this.sattr(this.style.bar); + + this.screen.fillRegion(dattr, this.pch, xi, xl, yi, yl); + + if (this.content) { + var line = this.screen.lines[yi]; + for (var i = 0; i < this.content.length; i++) { + line[xi + i][1] = this.content[i]; + } + line.dirty = true; + } + + return ret; +}; + +ProgressBar.prototype.progress = function(filled) { + this.filled += filled; + if (this.filled < 0) this.filled = 0; + else if (this.filled > 100) this.filled = 100; + if (this.filled === 100) { + this.emit('complete'); + } + this.value = this.filled; +}; + +ProgressBar.prototype.setProgress = function(filled) { + this.filled = 0; + this.progress(filled); +}; + +ProgressBar.prototype.reset = function() { + this.emit('reset'); + this.filled = 0; + this.value = this.filled; +}; + +/** + * Expose + */ + +module.exports = ProgressBar;