add percentage offsets. see #118.

This commit is contained in:
Christopher Jeffrey 2015-04-03 22:55:56 -07:00
parent 5aeeed7683
commit 2c6b34a86b
3 changed files with 75 additions and 28 deletions

View File

@ -415,10 +415,12 @@ The base element.
- __padding__ - amount of padding on the inside of the element. can be a number
or an object containing the properties: `left`, `right`, `top`, and `bottom`.
- __width, height__ - width/height of the element, can be a number, percentage
(`0-100%`), or keyword (`half` or `shrink`).
(`0-100%`), or keyword (`half` or `shrink`). percentages can also have
offsets (`50%+1`, `50%-1`).
- __left, right, top, bottom__ - offsets of the element __relative to its
parent__. can be a number, percentage (`0-100%`), or keyword (`center`).
`right` and `bottom` do not accept keywords.
`right` and `bottom` do not accept keywords. percentages can also have
offsets (`50%+1`, `50%-1`).
- __position__ - can contain the above options.
- __scrollable__ - whether the element is scrollable or not.
- __ch__ - background character (default is whitespace ` `).
@ -1339,6 +1341,15 @@ var box = blessed.box({
This tells blessed to create a box, perfectly centered __relative to its
parent__, 50% as wide and 50% as tall as its parent.
Percentages can also have offsets applied to them:
``` js
...
height: '50%-1',
left: '45%+1',
...
```
To access the calculated offsets, relative to the parent:
``` js

View File

@ -2934,12 +2934,17 @@ Element.prototype._getPos = function() {
Element.prototype._getWidth = function(get) {
var parent = get ? this.parent._getPos() : this.parent
, width = this.position.width || 0
, left;
, left
, expr;
if (typeof width === 'string') {
if (width === 'half') width = '50%';
expr = width.split(/(?=\+|-)/);
width = expr[0];
width = +width.slice(0, -1) / 100;
return parent.width * width | 0;
width = parent.width * width | 0;
width += +(expr[1] || 0);
return width;
}
// This is for if the element is being streched or shrunken.
@ -2952,8 +2957,11 @@ Element.prototype._getWidth = function(get) {
left = this.position.left || 0;
if (typeof left === 'string') {
if (left === 'center') left = '50%';
expr = left.split(/(?=\+|-)/);
left = expr[0];
left = +left.slice(0, -1) / 100;
left = parent.width * left | 0;
left += +(expr[1] || 0);
}
width = parent.width - (this.position.right || 0) - left;
if (this.screen.autoPadding) {
@ -2975,12 +2983,17 @@ Element.prototype.__defineGetter__('width', function() {
Element.prototype._getHeight = function(get) {
var parent = get ? this.parent._getPos() : this.parent
, height = this.position.height || 0
, top;
, top
, expr;
if (typeof height === 'string') {
if (height === 'half') height = '50%';
expr = height.split(/(?=\+|-)/);
height = expr[0];
height = +height.slice(0, -1) / 100;
return parent.height * height | 0;
height = parent.height * height | 0;
height += +(expr[1] || 0);
return height;
}
// This is for if the element is being streched or shrunken.
@ -2993,8 +3006,11 @@ Element.prototype._getHeight = function(get) {
top = this.position.top || 0;
if (typeof top === 'string') {
if (top === 'center') top = '50%';
expr = top.split(/(?=\+|-)/);
top = expr[0];
top = +top.slice(0, -1) / 100;
top = parent.height * top | 0;
top += +(expr[1] || 0);
}
height = parent.height - (this.position.bottom || 0) - top;
if (this.screen.autoPadding) {
@ -3016,12 +3032,16 @@ Element.prototype.__defineGetter__('height', function() {
Element.prototype._getLeft = function(get) {
var parent = get ? this.parent._getPos() : this.parent
, left = this.position.left || 0;
, left = this.position.left || 0
, expr;
if (typeof left === 'string') {
if (left === 'center') left = '50%';
expr = left.split(/(?=\+|-)/);
left = expr[0];
left = +left.slice(0, -1) / 100;
left = parent.width * left | 0;
left += +(expr[1] || 0);
if (this.position.left === 'center') {
left -= this._getWidth(get) / 2 | 0;
}
@ -3073,12 +3093,16 @@ Element.prototype.__defineGetter__('aright', function() {
Element.prototype._getTop = function(get) {
var parent = get ? this.parent._getPos() : this.parent
, top = this.position.top || 0;
, top = this.position.top || 0
, expr;
if (typeof top === 'string') {
if (top === 'center') top = '50%';
expr = top.split(/(?=\+|-)/);
top = expr[0];
top = +top.slice(0, -1) / 100;
top = parent.height * top | 0;
top += +(expr[1] || 0);
if (this.position.top === 'center') {
top -= this._getHeight(get) / 2 | 0;
}
@ -3155,6 +3179,7 @@ Element.prototype.__defineGetter__('rbottom', function() {
// the parent was resized, etc.
Element.prototype.__defineSetter__('width', function(val) {
if (this.position.width === val) return;
if (/^\d+$/.test(val)) val = +val;
this.emit('resize');
this.clearPos();
return this.position.width = val;
@ -3162,19 +3187,24 @@ Element.prototype.__defineSetter__('width', function(val) {
Element.prototype.__defineSetter__('height', function(val) {
if (this.position.height === val) return;
if (/^\d+$/.test(val)) val = +val;
this.emit('resize');
this.clearPos();
return this.position.height = val;
});
Element.prototype.__defineSetter__('aleft', function(val) {
var expr;
if (typeof val === 'string') {
if (val === 'center') {
val = this.screen.width / 2 | 0;
val -= this.width / 2 | 0;
} else {
expr = val.split(/(?=\+|-)/);
val = expr[0];
val = +val.slice(0, -1) / 100;
val = this.screen.width * val | 0;
val += +(expr[1] || 0);
}
}
val -= this.parent.aleft;
@ -3193,13 +3223,17 @@ Element.prototype.__defineSetter__('aright', function(val) {
});
Element.prototype.__defineSetter__('atop', function(val) {
var expr;
if (typeof val === 'string') {
if (val === 'center') {
val = this.screen.height / 2 | 0;
val -= this.height / 2 | 0;
} else {
expr = val.split(/(?=\+|-)/);
val = expr[0];
val = +val.slice(0, -1) / 100;
val = this.screen.height * val | 0;
val += +(expr[1] || 0);
}
}
val -= this.parent.atop;
@ -3219,6 +3253,7 @@ Element.prototype.__defineSetter__('abottom', function(val) {
Element.prototype.__defineSetter__('rleft', function(val) {
if (this.position.left === val) return;
if (/^\d+$/.test(val)) val = +val;
this.emit('move');
this.clearPos();
return this.position.left = val;
@ -3233,6 +3268,7 @@ Element.prototype.__defineSetter__('rright', function(val) {
Element.prototype.__defineSetter__('rtop', function(val) {
if (this.position.top === val) return;
if (/^\d+$/.test(val)) val = +val;
this.emit('move');
this.clearPos();
return this.position.top = val;
@ -3869,6 +3905,8 @@ Element.prototype.render = function() {
if (!lines[y]) break;
if (coords.noleft && x === xi) continue;
if (coords.noright && x === xl - 1) continue;
cell = lines[y][x];
if (!cell) break;
if (this.border.type === 'line') {
if (x === xi) {
ch = '┌';
@ -3930,8 +3968,6 @@ Element.prototype.render = function() {
} else if (this.border.type === 'bg') {
ch = this.border.ch;
}
cell = lines[y][x];
if (!cell) break;
if (battr !== cell[0] || ch !== cell[1]) {
lines[y][x][0] = battr;
lines[y][x][1] = ch;
@ -3941,6 +3977,8 @@ Element.prototype.render = function() {
y = yi + 1;
for (; y < yl - 1; y++) {
if (!lines[y]) break;
cell = lines[y][xi];
if (!cell) break;
if (this.border.type === 'line') {
ch = '│';
if (this.screen.dockBorders || this.dockBorders) {
@ -3953,14 +3991,14 @@ Element.prototype.render = function() {
} else if (this.border.type === 'bg') {
ch = this.border.ch;
}
cell = lines[y][xi];
if (!cell) break;
if (!coords.noleft)
if (battr !== cell[0] || ch !== cell[1]) {
lines[y][xi][0] = battr;
lines[y][xi][1] = ch;
lines[y].dirty = true;
}
cell = lines[y][xl - 1];
if (!cell) break;
if (this.border.type === 'line') {
ch = '│';
if (this.screen.dockBorders || this.dockBorders) {
@ -3986,8 +4024,6 @@ Element.prototype.render = function() {
} else if (this.border.type === 'bg') {
ch = this.border.ch;
}
cell = lines[y][xl - 1];
if (!cell) break;
if (!coords.noright)
if (battr !== cell[0] || ch !== cell[1]) {
lines[y][xl - 1][0] = battr;
@ -4001,6 +4037,8 @@ Element.prototype.render = function() {
if (!lines[y]) break;
if (coords.noleft && x === xi) continue;
if (coords.noright && x === xl - 1) continue;
cell = lines[y][x];
if (!cell) break;
if (this.border.type === 'line') {
if (x === xi) {
ch = '└';
@ -4064,8 +4102,6 @@ Element.prototype.render = function() {
} else if (this.border.type === 'bg') {
ch = this.border.ch;
}
cell = lines[y][x];
if (!cell) break;
if (battr !== cell[0] || ch !== cell[1]) {
lines[y][x][0] = battr;
lines[y][x][1] = ch;

View File

@ -11,18 +11,18 @@ blessed.box({
parent: screen,
left: 0,
top: 0,
width: 10,
height: 5,
width: '50%',
height: '50%',
border: 'line',
content: 'Foo'
});
blessed.box({
parent: screen,
left: 9,
left: '50%-1',
top: 0,
width: 10,
height: 5,
width: '50%+1',
height: '50%',
content: 'Bar',
border: 'line'
});
@ -30,19 +30,19 @@ blessed.box({
blessed.box({
parent: screen,
left: 0,
top: 4,
width: 10,
height: 5,
top: '50%-1',
width: '50%',
height: '50%+1',
border: 'line',
content: 'Foo'
});
blessed.box({
parent: screen,
left: 9,
top: 4,
width: 10,
height: 5,
left: '50%-1',
top: '50%-1',
width: '50%+1',
height: '50%+1',
border: 'line',
content: 'Bar'
});