diff --git a/README.md b/README.md index 66df954..8af9129 100644 --- a/README.md +++ b/README.md @@ -231,10 +231,14 @@ The screen on which every other node renders. - **height** - height of the screen (same as `program.rows`). - **cols** - same as `screen.width`. - **rows** - same as `screen.height`. -- **left**, **rleft** - left offset, always zero. -- **right**, **rright** - right offset, always zero. -- **top**, **rtop** - top offset, always zero. -- **bottom**, **rbottom** - bottom offset, always zero. +- **left** - relative left offset, always zero. +- **right** - relative right offset, always zero. +- **top** - relative top offset, always zero. +- **bottom** - relative bottom offset, always zero. +- **aleft** - absolute left offset, always zero. +- **aright** - absolute right offset, always zero. +- **atop** - absolute top offset, always zero. +- **abottom** - absolute bottom offset, always zero. - **grabKeys** - whether the focused element grabs all keypresses. - **lockKeys** - prevent keypresses from being received by any element. - **hover** - the currently hovered element. only set if mouse events are bound. @@ -380,14 +384,14 @@ The base element. - **bold, underline** - attributes. - **width** - calculated width. - **height** - calculated height. -- **left** - calculated absolute left offset. -- **right** - calculated absolute right offset. -- **top** - calculated absolute top offset. -- **bottom** - calculated absolute bottom offset. -- **rleft** - calculated relative left offset. -- **rright** - calculated relative right offset. -- **rtop** - calculated relative top offset. -- **rbottom** - calculated relative bottom offset. +- **left** - calculated relative left offset. +- **right** - calculated relative right offset. +- **top** - calculated relative top offset. +- **bottom** - calculated relative bottom offset. +- **aleft** - calculated absolute left offset. +- **aright** - calculated absolute right offset. +- **atop** - calculated absolute top offset. +- **abottom** - calculated absolute bottom offset. ##### Events: diff --git a/lib/widget.js b/lib/widget.js index 3dda68d..3698ad3 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -290,10 +290,10 @@ function Screen(options) { this.renders = 0; this.position = { - left: this.left = this.rleft = 0, - right: this.right = this.rright = 0, - top: this.top = this.rtop = 0, - bottom: this.bottom = this.rbottom = 0 + left: this.left = this.aleft = this.rleft = 0, + right: this.right = this.aright = this.rright = 0, + top: this.top = this.atop = this.rtop = 0, + bottom: this.bottom = this.abottom = this.rbottom = 0 //get height() { return self.height; }, //get width() { return self.width; } }; @@ -1488,7 +1488,7 @@ Screen.prototype._focus = function(self, old) { // NOTE: This is different from the other "visible" values - it needs the // visible height of the scrolling element itself, not the element within // it. - var visible = self.screen.height - el.top - el.itop - el.bottom - el.ibottom; + var visible = self.screen.height - el.atop - el.itop - el.abottom - el.ibottom; if (self.rtop < el.childBase) { el.scrollTo(self.rtop); self.screen.render(); @@ -2780,12 +2780,12 @@ Element.prototype._getPos = function() { assert.ok(pos); - if (pos.left != null) return pos; + if (pos.aleft != null) return pos; - pos.left = pos.xi; - pos.top = pos.yi; - pos.right = this.screen.cols - pos.xl; - pos.bottom = this.screen.rows - pos.yl; + pos.aleft = pos.xi; + pos.atop = pos.yi; + pos.aright = this.screen.cols - pos.xl; + pos.abottom = this.screen.rows - pos.yl; pos.width = pos.xl - pos.xi; pos.height = pos.yl - pos.yi; @@ -2908,10 +2908,10 @@ Element.prototype._getLeft = function(get) { } } - return (parent.left || 0) + left; + return (parent.aleft || 0) + left; }; -Element.prototype.__defineGetter__('left', function() { +Element.prototype.__defineGetter__('aleft', function() { return this._getLeft(false); }); @@ -2929,7 +2929,7 @@ Element.prototype._getRight = function(get) { return right; } - right = (parent.right || 0) + (this.position.right || 0); + right = (parent.aright || 0) + (this.position.right || 0); if (this.screen.autoPadding) { // if (this.position.right != null) { @@ -2940,7 +2940,7 @@ Element.prototype._getRight = function(get) { return right; }; -Element.prototype.__defineGetter__('right', function() { +Element.prototype.__defineGetter__('aright', function() { return this._getRight(false); }); @@ -2969,10 +2969,10 @@ Element.prototype._getTop = function(get) { } } - return (parent.top || 0) + top; + return (parent.atop || 0) + top; }; -Element.prototype.__defineGetter__('top', function() { +Element.prototype.__defineGetter__('atop', function() { return this._getTop(false); }); @@ -2990,7 +2990,7 @@ Element.prototype._getBottom = function(get) { return bottom; } - bottom = (parent.bottom || 0) + (this.position.bottom || 0); + bottom = (parent.abottom || 0) + (this.position.bottom || 0); if (this.screen.autoPadding) { // if (this.position.bottom != null) { @@ -3001,24 +3001,24 @@ Element.prototype._getBottom = function(get) { return bottom; }; -Element.prototype.__defineGetter__('bottom', function() { +Element.prototype.__defineGetter__('abottom', function() { return this._getBottom(false); }); Element.prototype.__defineGetter__('rleft', function() { - return this.left - this.parent.left; + return this.aleft - this.parent.aleft; }); Element.prototype.__defineGetter__('rright', function() { - return this.right - this.parent.right; + return this.aright - this.parent.aright; }); Element.prototype.__defineGetter__('rtop', function() { - return this.top - this.parent.top; + return this.atop - this.parent.atop; }); Element.prototype.__defineGetter__('rbottom', function() { - return this.bottom - this.parent.bottom; + return this.abottom - this.parent.abottom; }); /** @@ -3026,7 +3026,7 @@ Element.prototype.__defineGetter__('rbottom', function() { */ // NOTE: -// For right, bottom, rright, and rbottom: +// For aright, abottom, right, and bottom: // If position.bottom is null, we could simply set top instead. // But it wouldn't replicate bottom behavior appropriately if // the parent was resized, etc. @@ -3044,7 +3044,7 @@ Element.prototype.__defineSetter__('height', function(val) { return this.position.height = val; }); -Element.prototype.__defineSetter__('left', function(val) { +Element.prototype.__defineSetter__('aleft', function(val) { if (typeof val === 'string') { if (val === 'center') { val = this.screen.width / 2 | 0; @@ -3054,22 +3054,22 @@ Element.prototype.__defineSetter__('left', function(val) { val = this.screen.width * val | 0; } } - val -= this.parent.left; + val -= this.parent.aleft; if (this.position.left === val) return; this.emit('move'); this.clearPos(); return this.position.left = val; }); -Element.prototype.__defineSetter__('right', function(val) { - val -= this.parent.right; +Element.prototype.__defineSetter__('aright', function(val) { + val -= this.parent.aright; if (this.position.right === val) return; this.emit('move'); this.clearPos(); return this.position.right = val; }); -Element.prototype.__defineSetter__('top', function(val) { +Element.prototype.__defineSetter__('atop', function(val) { if (typeof val === 'string') { if (val === 'center') { val = this.screen.height / 2 | 0; @@ -3079,15 +3079,15 @@ Element.prototype.__defineSetter__('top', function(val) { val = this.screen.height * val | 0; } } - val -= this.parent.top; + val -= this.parent.atop; if (this.position.top === val) return; this.emit('move'); this.clearPos(); return this.position.top = val; }); -Element.prototype.__defineSetter__('bottom', function(val) { - val -= this.parent.bottom; +Element.prototype.__defineSetter__('abottom', function(val) { + val -= this.parent.abottom; if (this.position.bottom === val) return; this.emit('move'); this.clearPos(); @@ -3151,6 +3151,42 @@ Element.prototype.__defineGetter__('tpadding', function() { + this.padding.right + this.padding.bottom; }); +/** + * Relative coordinates as default properties + */ + +Element.prototype.__defineGetter__('left', function() { + return this.rleft; +}); + +Element.prototype.__defineGetter__('right', function() { + return this.rright; +}); + +Element.prototype.__defineGetter__('top', function() { + return this.rtop; +}); + +Element.prototype.__defineGetter__('bottom', function() { + return this.rbottom; +}); + +Element.prototype.__defineSetter__('left', function(val) { + return this.rleft = val; +}); + +Element.prototype.__defineSetter__('right', function(val) { + return this.rright = val; +}); + +Element.prototype.__defineSetter__('top', function(val) { + return this.rtop = val; +}); + +Element.prototype.__defineSetter__('bottom', function(val) { + return this.rbottom = val; +}); + /** * Rendering - here be dragons */ @@ -3534,7 +3570,6 @@ Element.prototype.render = function() { , battr , dattr , c - , rtop , visible , i , bch = this.ch; @@ -6484,7 +6519,7 @@ Listbar.prototype.addItem = Listbar.prototype.appendItem = function(item, callback) { var self = this , prev = this.items[this.items.length - 1] - , drawn = prev ? prev.left + prev.width : 0 + , drawn = prev ? prev.aleft + prev.width : 0 , cmd , title , len; @@ -6823,10 +6858,10 @@ Terminal.prototype.bootstrap = function() { this.screen.on('mouse', function(data) { if (self.screen.focused !== self) return; - if (data.x < self.left + self.ileft) return; - if (data.y < self.top + self.itop) return; - if (data.x > self.left - self.ileft + self.width) return; - if (data.y > self.top - self.itop + self.height) return; + if (data.x < self.aleft + self.ileft) return; + if (data.y < self.atop + self.itop) return; + if (data.x > self.aleft - self.ileft + self.width) return; + if (data.y > self.atop - self.itop + self.height) return; if (self.term.x10Mouse || self.term.vt200Mouse @@ -6841,8 +6876,8 @@ Terminal.prototype.bootstrap = function() { } var b = data.raw[0] - , x = data.x - self.left - , y = data.y - self.top + , x = data.x - self.aleft + , y = data.y - self.atop , s; if (self.term.urxvtMouse) { @@ -7184,20 +7219,20 @@ Image.prototype.setImage = function(img, callback) { var width = self.width * ratio.tw | 0 , height = self.height * ratio.th | 0 - , left = self.left * ratio.tw | 0 - , top = self.top * ratio.th | 0; + , aleft = self.aleft * ratio.tw | 0 + , atop = self.atop * ratio.th | 0; var input = '0;1;' - + left + ';' - + top + ';' + + aleft + ';' + + atop + ';' + width + ';' + height + ';;;;;' + img + '\n4;\n3;\n'; self._props = { - left: left, - top: top, + aleft: aleft, + atop: atop, width: width, height: height }; @@ -7234,8 +7269,8 @@ Image.prototype.setImage = function(img, callback) { && ratio.th === self._lastSize.th && size.width === self._lastSize.width && size.height === self._lastSize.height - && self.left === self._lastSize.left - && self.top === self._lastSize.top) { + && self.aleft === self._lastSize.aleft + && self.atop === self._lastSize.atop) { if (!callback) return; return callback(null, success); } @@ -7245,8 +7280,8 @@ Image.prototype.setImage = function(img, callback) { th: ratio.th, width: size.width, height: size.height, - left: self.left, - top: self.top + aleft: self.aleft, + atop: self.atop }; self.position.width = size.width / ratio.tw | 0; @@ -7295,12 +7330,12 @@ Image.prototype.clearImage = function(callback) { var width = this._props.width + 2 , height = this._props.height + 2 - , left = this._props.left - , top = this._props.top; + , aleft = this._props.aleft + , atop = this._props.atop; var input = '6;' - + left + ';' - + top + ';' + + aleft + ';' + + atop + ';' + width + ';' + height + '\n4;\n3;\n'; diff --git a/test/widget-pos.js b/test/widget-pos.js index 158a021..0b65f52 100644 --- a/test/widget-pos.js +++ b/test/widget-pos.js @@ -38,10 +38,10 @@ var inner = blessed.box({ main.append(inner); inner.setContent(inner.content + '\n' + JSON.stringify({ - left: inner.left, - right: inner.right, - top: inner.top, - bottom: inner.bottom, + aleft: inner.aleft, + aright: inner.aright, + atop: inner.atop, + abottom: inner.abottom, width: inner.width, height: inner.height, rleft: inner.rleft, @@ -53,10 +53,10 @@ inner.setContent(inner.content + '\n' + JSON.stringify({ assert.equal(inner.width, 57); assert.equal(inner.height, 7); -assert.equal(inner.left, 4); -assert.equal(inner.right, 93); -assert.equal(inner.top, 4); -assert.equal(inner.bottom, 8); +assert.equal(inner.aleft, 4); +assert.equal(inner.aright, 93); +assert.equal(inner.atop, 4); +assert.equal(inner.abottom, 8); assert.equal(inner.rleft, 2); assert.equal(inner.rright, 56); @@ -65,11 +65,11 @@ assert.equal(inner.rbottom, 5); // Change left to half of the parent width. inner.rleft = '50%'; -assert.equal(inner.left, 59); +assert.equal(inner.aleft, 59); // Change left to half of the screen width. -inner.left = '50%'; -assert.equal(inner.left, screen.width / 2 | 0); +inner.aleft = '50%'; +assert.equal(inner.aleft, screen.width / 2 | 0); // Test implied height/width. reset(inner, { @@ -82,8 +82,8 @@ reset(inner, { assert.equal(inner.width, 105); assert.equal(inner.height, 4); -// Demonstrate the difference between `left: 5`, and `.left = 5` (relative vs. absolute): -inner.top = inner.bottom = inner.left = inner.right = 5; +// Demonstrate the difference between `left: 5`, and `.aleft = 5` (relative vs. absolute): +inner.atop = inner.abottom = inner.aleft = inner.aright = 5; assert.equal(inner.width, 144); assert.equal(inner.height, 9); diff --git a/test/widget.js b/test/widget.js index cc00440..2d01b2a 100644 --- a/test/widget.js +++ b/test/widget.js @@ -249,5 +249,5 @@ setInterval(function() { progress.progress(2); screen.render(); setTimeout(fill, 300); - progress.top -= 2; + progress.atop -= 2; })();