diff --git a/lib/widget.js b/lib/widget.js index 85fcdfd..303bc01 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -728,8 +728,8 @@ Screen.prototype.cleanSides = function(el) { return false; } - var yi = pos.yi + (el.border ? 1 : 0) + el.padding - , yl = pos.yl - (el.border ? 1 : 0) - el.padding + var yi = pos.yi + el.itop + , yl = pos.yl - el.ibottom , first , ch , x @@ -1437,7 +1437,22 @@ function Element(options) { this.align = options.align || 'left'; this.valign = options.valign || 'top'; this.shrink = options.shrink; - this.padding = options.padding || 0; + + if (typeof options.padding === 'number' || !options.padding) { + options.padding = { + left: options.padding, + top: options.padding, + right: options.padding, + bottom: options.padding + }; + } + + this.padding = { + left: options.padding.left || 0, + top: options.padding.top || 0, + right: options.padding.right || 0, + bottom: options.padding.bottom || 0 + }; this.border = options.border; if (this.border) { @@ -1614,7 +1629,7 @@ Element.prototype.setContent = function(content, noClear) { Element.prototype.parseContent = function() { if (this.detached) return false; - var width = this.width - (this.border ? 2 : 0) - this.padding * 2; + var width = this.width - this.iwidth; if (this._clines == null || this._clines.width !== width || this._clines.content !== this.content) { @@ -2174,27 +2189,32 @@ Element.prototype.__defineSetter__('rbottom', function(val) { }); Element.prototype.__defineGetter__('ileft', function() { - return this.left + (this.border ? 1 : 0) + this.padding; + return (this.border ? 1 : 0) + this.padding.left; }); Element.prototype.__defineGetter__('itop', function() { - return this.top + (this.border ? 1 : 0) + this.padding; + return (this.border ? 1 : 0) + this.padding.top; }); Element.prototype.__defineGetter__('iright', function() { - return this.right - (this.border ? 1 : 0) - this.padding; + return (this.border ? 1 : 0) + this.padding.right; }); Element.prototype.__defineGetter__('ibottom', function() { - return this.bottom - (this.border ? 1 : 0) - this.padding; + return (this.border ? 1 : 0) + this.padding.bottom; }); Element.prototype.__defineGetter__('iwidth', function() { - return this.width - (this.border ? 2 : 0) - this.padding * 2; + return (this.border ? 2 : 0) + this.padding.left + this.padding.right; }); Element.prototype.__defineGetter__('iheight', function() { - return this.height - (this.border ? 2 : 0) - this.padding * 2; + return (this.border ? 2 : 0) + this.padding.top + this.padding.bottom; +}); + +Element.prototype.__defineGetter__('tpadding', function() { + return this.padding.left + this.padding.top + + this.padding.right + this.padding.bottom; }); /** @@ -2250,10 +2270,10 @@ Box.prototype._getShrinkBox = function(xi, xl, yi, yl) { || this.options.right == null)) { if (this.options.left == null && this.options.right != null) { xi = xl - (mxl - mxi); - xi -= this.padding * 2; + xi -= this.padding.left + this.padding.right; } else { xl = mxl; - xl += this.padding * 2; + xl += this.padding.left + this.padding.right; } } @@ -2263,10 +2283,10 @@ Box.prototype._getShrinkBox = function(xi, xl, yi, yl) { && this.childBase == null) { if (this.options.top == null && this.options.bottom != null) { yi = yl - (myl - myi); - yi -= this.padding * 2; + yi -= this.padding.top + this.padding.bottom; } else { yl = myl; - yl += this.padding * 2; + yl += this.padding.top + this.padding.bottom; } } @@ -2282,9 +2302,9 @@ Box.prototype._getShrinkContent = function(xi, xl, yi, yl) { && (this.options.left == null || this.options.right == null)) { if (this.options.left == null && this.options.right != null) { - xi = xl - w - (this.border ? 2 : 0) - this.padding * 2; + xi = xl - w - this.iwidth; } else { - xl = xi + w + (this.border ? 2 : 0) + this.padding * 2; + xl = xi + w + this.iwidth; } } @@ -2293,9 +2313,9 @@ Box.prototype._getShrinkContent = function(xi, xl, yi, yl) { || this.options.bottom == null) && this.childBase == null) { if (this.options.top == null && this.options.bottom != null) { - yi = yl - h - (this.border ? 2 : 0) - this.padding * 2; + yi = yl - h - this.iheight; } else { - yl = yi + h + (this.border ? 2 : 0) + this.padding * 2; + yl = yi + h + this.iheight; } } @@ -2359,15 +2379,9 @@ Box.prototype._getCoords = function(get) { if (this.parent.childBase != null && (!this.parent.items || ~this.parent.items.indexOf(this))) { - ryi = yi - this.parent._getTop(get) - - (this.parent.border ? 1 : 0) - - this.parent.padding; - ryl = yl - this.parent._getTop(get) - - (this.parent.border ? 1 : 0) - - this.parent.padding; - visible = this.parent._getHeight(get) - - (this.parent.border ? 2 : 0) - - this.parent.padding * 2; + ryi = yi - this.parent._getTop(get) - this.parent.itop; + ryl = yl - this.parent._getTop(get) - this.parent.ibottom; + visible = this.parent._getHeight(get) - this.parent.iheight; if (ryi < this.parent.childBase) { if (ryl > this.parent.childBase) { @@ -2454,13 +2468,13 @@ Box.prototype.render = function() { // content-drawing loop will skip a few cells/lines. // To deal with this, we can just fill the whole thing // ahead of time. This could be optimized. - if (this.padding || (this.valign && this.valign !== 'top')) { + if (this.tpadding || (this.valign && this.valign !== 'top')) { this.screen.fillRegion(dattr, ' ', xi, xl, yi, yl); } - if (this.padding) { - xi += this.padding, xl -= this.padding; - yi += this.padding, yl -= this.padding; + if (this.tpadding) { + xi += this.padding.left, xl -= this.padding.right; + yi += this.padding.top, yl -= this.padding.bottom; } // Determine where to place the text if it's vertically aligned. @@ -2563,9 +2577,9 @@ Box.prototype.render = function() { if (this.border) xi--, xl++, yi--, yl++; - if (this.padding) { - xi -= this.padding, xl += this.padding; - yi -= this.padding, yl += this.padding; + if (this.tpadding) { + xi -= this.padding.left, xl += this.padding.right; + yi -= this.padding.top, yl += this.padding.bottom; } // Draw the border. @@ -2665,15 +2679,15 @@ Box.prototype.insertLine = function(i, line) { i = Math.max(i, 0); //i = Math.min(i, this._clines.length); - var height = pos.yl - pos.yi - (this.border ? 2 : 0) - this.padding * 2 + var height = pos.yl - pos.yi - this.iheight , base = this.childBase || 0 , visible = i >= base && i - base < height; if (pos && visible && this.screen.cleanSides(this)) { this.screen.insertLine(line.length, - pos.yi + (this.border ? 1 : 0) + this.padding + i - base, + pos.yi + this.itop + i - base, pos.yi, - pos.yl - (this.border ? 1 : 0) - this.padding - 1); + pos.yl - this.ibottom - 1); } line.forEach(function(line, j) { @@ -2692,15 +2706,15 @@ Box.prototype.deleteLine = function(i, n) { i = Math.max(i, 0); i = Math.min(i, this._clines.length - 1); - var height = pos.yl - pos.yi - (this.border ? 2 : 0) - this.padding * 2 + var height = pos.yl - pos.yi - this.iheight , base = this.childBase || 0 , visible = i >= base && i - base < height; if (pos && visible && this.screen.cleanSides(this)) { this.screen.deleteLine(n, - pos.yi + (this.border ? 1 : 0) + this.padding + i - base, + pos.yi + this.itop + i - base, pos.yi, - pos.yl - (this.border ? 1 : 0) - this.padding - 1); + pos.yl - this.ibottom - 1); reset = false; } @@ -2717,7 +2731,7 @@ Box.prototype.insertTop = function(line) { Box.prototype.insertBottom = function(line) { return this.insertLine((this.childBase || 0) - + this.height - (this.border ? 2 : 0) - this.padding * 2, line); + + this.height - this.iheight, line); }; Box.prototype.deleteTop = function() { @@ -2726,7 +2740,7 @@ Box.prototype.deleteTop = function() { Box.prototype.deleteBottom = function() { return this.deleteLine((this.childBase || 0) - + this.height - (this.border ? 2 : 0) - this.padding * 2); + + this.height - this.iheight); }; Box.prototype.setLine = function(i, line) { @@ -2882,7 +2896,7 @@ ScrollableBox.prototype.scrollTo = function(offset) { }; ScrollableBox.prototype.scroll = function(offset) { - var visible = this.height - (this.border ? 2 : 0) - this.padding * 2 + var visible = this.height - this.iheight , base = this.childBase , d , p @@ -2928,11 +2942,11 @@ ScrollableBox.prototype.scroll = function(offset) { // Optimize scrolling with CSR + IL/DL. p = this.lpos; if (this.childBase !== base && this.screen.cleanSides(this)) { - t = p.yi + (this.border ? 1 : 0) + this.padding; - b = p.yl - (this.border ? 1 : 0) - this.padding - 1; + t = p.yi + this.itop; + b = p.yl - this.ibottom - 1; d = this.childBase - base; - // var i = p.xi + (this.border ? 1 : 0) + this.padding; + // var i = p.xi + this.ileft; // var attr = this.screen.olines[t][i][0]; // this.screen.program.write(this.screen.codeAttr(attr, this.screen)); @@ -3123,7 +3137,7 @@ function List(options) { } this.on('resize', function() { - var visible = self.height - (self.border ? 2 : 0) - self.padding * 2; + var visible = self.height - self.iheight; if (visible >= self.selected + 1) { //if (self.selected < visible - 1) { self.childBase = 0; @@ -3147,9 +3161,9 @@ List.prototype.add = function(item) { screen: this.screen, content: item, align: this.align || 'left', - top: this.items.length + (this.border ? 1 : 0) + this.padding, - left: (this.border ? 1 : 0) + this.padding + 1, - right: (this.border ? 1 : 0) + this.padding + 1, + top: this.itop + this.items.length, + left: this.ileft + 1, + right: this.iright + 1, tags: this.parseTags, height: 1, hoverEffects: this.mouse ? this.style.item.hover : null, @@ -3363,8 +3377,7 @@ ScrollableText.prototype.scroll = function(offset) { if (this.content != null) { this.parseContent(); - max = this._clines.length - - (this.height - (this.border ? 2 : 0) - this.padding * 2); + max = this._clines.length - (this.height - this.iheight); if (max < 0) max = 0; if (cb > max) { @@ -3395,8 +3408,7 @@ ScrollableText.prototype.scroll = function(offset) { ScrollableText.prototype._recalculateIndex = function() { if (this.detached) return; - var max = this._clines.length - - (this.height - (this.border ? 2 : 0) - this.padding * 2); + var max = this._clines.length - (this.height - this.iheight); if (max < 0) max = 0; if (this.childBase > max) { @@ -3697,8 +3709,8 @@ Textbox.prototype.setInput = function(callback) { // Could possibly save and restore cursor. this.screen.program.cup( - this.top + (this.border ? 1 : 0) + this.padding, - this.left + (this.border ? 1 : 0) + this.padding + this.top + this.itop, + this.left + this.ileft + this.value.length); this.screen.program.showCursor(); this.screen.program.sgr('normal'); @@ -3734,7 +3746,7 @@ Textbox.prototype.setInput = function(callback) { Textbox.prototype._listener = function(ch, key) { var callback = this._callback , value = this.value - , width = this.width - (this.border ? 2 : 0) - this.padding * 2; + , width = this.width - this.iwidth; if (key.name === 'escape' || key.name === 'enter') { delete this._callback; @@ -3764,7 +3776,7 @@ Textbox.prototype._listener = function(ch, key) { // Maybe just use this instead of render hook: // Problem - user can't set .value willy nilly. // if (this.value !== value) { - // var i = -(this.width - (this.border ? 2 : 0) - this.padding * 2 - 1); + // var i = -(this.width - this.iwidth - 1); // this.setContent(this.value.slice(i)); // } @@ -3797,7 +3809,7 @@ Textbox.prototype.render = function() { this.setContent(Array(this.value.length + 1).join('*')); return this._render(); } - var visible = -(this.width - (this.border ? 2 : 0) - this.padding * 2 - 1); + var visible = -(this.width - this.iwidth - 1); this.setContent(this.value.slice(visible)); return this._render(); }; @@ -3861,10 +3873,10 @@ Textarea.prototype.updateCursor = function() { line = Math.min( this._clines.length - 1 - this.childBase, - this.height - (this.border ? 2 : 0) - this.padding * 2 - 1); + this.height - this.iheight - 1); - cy = this.top + (this.border ? 1 : 0) + this.padding + line; - cx = this.left + (this.border ? 1 : 0) + this.padding + last.length; + cy = this.top + this.itop + line; + cx = this.left + this.ileft + last.length; if (cy === program.y && cx === program.x) { return; @@ -3971,7 +3983,7 @@ Textarea.prototype._listener = function(ch, key) { Textarea.prototype._typeScroll = function() { // XXX Workaround - var width = this.height - (this.border ? 2 : 0) - this.padding * 2; + var width = this.height - this.iheight; if (this._clines.length - this.childBase > width) { //this.setContent(this.value + '\n'); this.scroll(this._clines.length); @@ -4104,11 +4116,11 @@ function ProgressBar(options) { var x, y, m, p; if (self.orientation === 'horizontal') { x = data.x - self.left; - m = self.width - (self.border ? 2 : 0) - self.padding * 2; + m = self.width - self.iwidth; p = x / m * 100 | 0; } else if (self.orientation === 'vertical') { y = data.y - self.top; - m = self.height - (self.border ? 2 : 0) - self.padding * 2; + m = self.height - self.iheight; p = y / m * 100 | 0; } self.setProgress(p); @@ -4992,7 +5004,7 @@ Listbar.prototype.select = function(offset) { , visible = 0 , el; - width = width - (this.border ? 2 : 0) - this.padding * 2; + width = width - this.iwidth; if (offset < 0) offset = 0; else if (offset >= this.items.length) offset = this.items.length - 1; diff --git a/test/widget-form.js b/test/widget-form.js index 0b9b01a..1ea7725 100644 --- a/test/widget-form.js +++ b/test/widget-form.js @@ -89,7 +89,10 @@ var submit = blessed.button({ mouse: true, keys: true, shrink: true, - padding: 1, + padding: { + left: 1, + right: 1 + }, left: 30, top: 2, shrink: true,