add percentage offsets. see #118.
This commit is contained in:
parent
5aeeed7683
commit
2c6b34a86b
15
README.md
15
README.md
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue