diff --git a/lib/widget.js b/lib/widget.js index b09429f..8a47ad1 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -291,6 +291,7 @@ function Screen(options) { this.tput = this.program.tput; this.output = this.program.output; + this.tabc = Array((options.tabSize || 4) + 1).join(' '); this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff; this.position = { @@ -1876,7 +1877,7 @@ Element.prototype.parseContent = function() { // Could move these 2 lines back to setContent (?) content = content.replace(/\x1b(?!\[[\d;]*m)/g, ''); content = this._parseTags(content); - content = content.replace(/\t/g, ' '); + content = content.replace(/\t/g, this.screen.tabc); this._clines = this._wrapContent(content, width); this._clines.width = width; this._clines.content = this.content; @@ -2708,6 +2709,7 @@ Element.prototype._getCoords = function(get) { // Here be dragons. Element.prototype.render = function() { + this.emit('prerender'); this.parseContent(); var coords = this._getCoords(true); @@ -2931,6 +2933,8 @@ Element.prototype.render = function() { el.render(); }); + this.emit('render'); + return coords; }; @@ -4044,20 +4048,13 @@ function Textbox(options) { this.__updateCursor = this.updateCursor.bind(this); this.on('resize', this.__updateCursor); this.on('move', this.__updateCursor); + //this.on('prerender', this._render.bind(this)); } Textbox.prototype.__proto__ = Input.prototype; Textbox.prototype.type = 'textbox'; -Textbox.prototype.updateCursor = function() { - if (this.screen.focused !== this) return; - var lpos = this._getCoords(); - if (!lpos) return; - this.screen.program.cup(lpos.yi + this.itop, - lpos.xi + this.ileft + this.value.length); -}; - Textbox.prototype.input = Textbox.prototype.readInput = Textbox.prototype.setInput = function(callback) { @@ -4123,26 +4120,43 @@ Textbox.prototype._listener = function(ch, key) { if (this.value.length) { this.value = this.value.slice(0, -1); if (this.secret) return; - if (this.value.length < width - 1) { - this.screen.program.cub(); - } } } else if (ch) { - // Tabs only work with textareas. - if (ch === '\t') ch = ' '; + // if (ch === '\t') ch = ' '; this.value += ch; if (this.secret) return; - if (this.value.length < width) { - this.screen.program.cuf(); - } } - this.screen.render(); + if (this.value !== value) { + //this.setValue(); + this.screen.render(); + } }; +Textbox.prototype.setValue = function(value) { + var visible, val; + if (value == null) { + value = this.value; + } + if (this._value !== value) { + this.value = value; + this._value = value; + if (this.secret) { + this.setContent(''); + } else if (this.censor) { + this.setContent(Array(this.value.length + 1).join('*')); + } else { + visible = -(this.width - this.iwidth - 1); + val = this.value.replace(/\t/g, this.screen.tabc); + this.setContent(val.slice(visible)); + } + this.updateCursor(); + } +}; + +Textbox.prototype.clearValue = Textbox.prototype.clearInput = function() { - this.value = ''; - this.setContent(''); + return this.setValue(''); }; Textbox.prototype.submit = function() { @@ -4155,19 +4169,7 @@ Textbox.prototype.cancel = function() { Textbox.prototype._render = Input.prototype.render; Textbox.prototype.render = function() { - // setContent is necessary to clear the area in case - // .shrink is being used and the new content is smaller. - // Could technically optimize this. - if (this.secret) { - this.setContent(''); - return this._render(); - } - if (this.censor) { - this.setContent(Array(this.value.length + 1).join('*')); - return this._render(); - } - var visible = -(this.width - this.iwidth - 1); - this.setContent(this.value.slice(visible)); + this.setValue(); return this._render(); }; @@ -4209,6 +4211,7 @@ Textarea.prototype.__proto__ = ScrollableText.prototype; Textarea.prototype.type = 'textarea'; +Textbox.prototype.updateCursor = Textarea.prototype.updateCursor = function() { if (this.screen.focused !== this) { return; @@ -4232,7 +4235,7 @@ Textarea.prototype.updateCursor = function() { } line = Math.min( - this._clines.length - 1 - this.childBase, + this._clines.length - 1 - (this.childBase || 0), (lpos.yl - lpos.yi) - this.iheight - 1); cy = lpos.yi + this.itop + line; @@ -4338,9 +4341,7 @@ Textarea.prototype._listener = function(ch, key) { } if (this.value !== value) { - this.setContent(this.value); - this._typeScroll(); - this.updateCursor(); + //this.setValue(); this.screen.render(); } }; @@ -4354,9 +4355,22 @@ Textarea.prototype._typeScroll = function() { } }; +Textarea.prototype.setValue = function(value) { + if (value == null) { + value = this.value; + } + if (this._value !== value) { + this.value = value; + this._value = value; + this.setContent(this.value); + this._typeScroll(); + this.updateCursor(); + } +}; + +Textarea.prototype.clearValue = Textarea.prototype.clearInput = function() { - this.value = ''; - this.setContent(''); + return this.setValue(''); }; Textarea.prototype.submit = function() { @@ -4367,6 +4381,12 @@ Textarea.prototype.cancel = function() { return this._listener('\x1b', { name: 'escape' }); }; +Textarea.prototype._render = ScrollableBox.prototype.render; +Textarea.prototype.render = function() { + this.setValue(); + return this._render(); +}; + Textarea.prototype.editor = Textarea.prototype.readEditor = Textarea.prototype.setEditor = function(callback) {