mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-01-11 03:25:45 +00:00
add auto-positioning which respects padding and borders.
This commit is contained in:
parent
ac88ceaebe
commit
78a3726f2f
@ -151,6 +151,8 @@ The screen on which every other node renders.
|
|||||||
- **resizeTimeout** - amount of time (in ms) to redraw the screen after the
|
- **resizeTimeout** - amount of time (in ms) to redraw the screen after the
|
||||||
terminal is resized (default: 300).
|
terminal is resized (default: 300).
|
||||||
- **tabSize** - the width of tabs within an element's content.
|
- **tabSize** - the width of tabs within an element's content.
|
||||||
|
- **autoPadding** - automatically position child elements with border and
|
||||||
|
padding in mind.
|
||||||
|
|
||||||
##### Properties:
|
##### Properties:
|
||||||
|
|
||||||
|
121
lib/widget.js
121
lib/widget.js
@ -282,6 +282,8 @@ function Screen(options) {
|
|||||||
this.tput = this.program.tput;
|
this.tput = this.program.tput;
|
||||||
this.output = this.program.output;
|
this.output = this.program.output;
|
||||||
|
|
||||||
|
this.autoPadding = options.autoPadding;
|
||||||
|
|
||||||
this.tabc = Array((options.tabSize || 4) + 1).join(' ');
|
this.tabc = Array((options.tabSize || 4) + 1).join(' ');
|
||||||
this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff;
|
this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff;
|
||||||
|
|
||||||
@ -292,6 +294,20 @@ function Screen(options) {
|
|||||||
bottom: this.bottom = this.rbottom = 0
|
bottom: this.bottom = this.rbottom = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.ileft = 0;
|
||||||
|
this.itop = 0;
|
||||||
|
this.iright = 0;
|
||||||
|
this.ibottom = 0;
|
||||||
|
this.iheight = 0;
|
||||||
|
this.iwidth = 0;
|
||||||
|
|
||||||
|
this.padding = {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0
|
||||||
|
};
|
||||||
|
|
||||||
this.hover = null;
|
this.hover = null;
|
||||||
this.history = [];
|
this.history = [];
|
||||||
this.clickable = [];
|
this.clickable = [];
|
||||||
@ -1703,6 +1719,13 @@ function Element(options) {
|
|||||||
height: options.height
|
height: options.height
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// if (options.position.left == null && options.position.right == null) {
|
||||||
|
// options.position.left = 0;
|
||||||
|
// }
|
||||||
|
// if (options.position.top == null && options.position.bottom == null) {
|
||||||
|
// options.position.top = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
if (options.position.width === 'shrink'
|
if (options.position.width === 'shrink'
|
||||||
|| options.position.height === 'shrink') {
|
|| options.position.height === 'shrink') {
|
||||||
if (options.position.width === 'shrink') {
|
if (options.position.width === 'shrink') {
|
||||||
@ -1792,6 +1815,10 @@ function Element(options) {
|
|||||||
style: this.style.label,
|
style: this.style.label,
|
||||||
fixed: true
|
fixed: true
|
||||||
}));
|
}));
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
this.children[this.children.length-1].rleft = -this.ileft + 2;
|
||||||
|
this.children[this.children.length-1].rtop = -this.itop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Possibly move this to Node for screen.on('mouse', ...).
|
// TODO: Possibly move this to Node for screen.on('mouse', ...).
|
||||||
@ -2286,7 +2313,7 @@ Screen.prototype._getPos = function() {
|
|||||||
Element.prototype._getPos = function() {
|
Element.prototype._getPos = function() {
|
||||||
var pos = this.lpos;
|
var pos = this.lpos;
|
||||||
|
|
||||||
assert.ok(pos && !pos.changed);
|
assert.ok(pos);
|
||||||
|
|
||||||
if (pos.left != null) return pos;
|
if (pos.left != null) return pos;
|
||||||
|
|
||||||
@ -2300,20 +2327,6 @@ Element.prototype._getPos = function() {
|
|||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype._bindPosChanged = function() {
|
|
||||||
function changed() {
|
|
||||||
self.forDescendants(function(el) {
|
|
||||||
if (el.lpos) el.lpos.changed = true;
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.on('move', changed);
|
|
||||||
// Resize might be tricky because it's
|
|
||||||
// emitted recursively for a screen resize.
|
|
||||||
this.on('resize', changed);
|
|
||||||
this.on('reparent', changed);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Position Getters
|
* Position Getters
|
||||||
*/
|
*/
|
||||||
@ -2342,6 +2355,11 @@ Element.prototype._getWidth = function(get) {
|
|||||||
left = parent.width * left | 0;
|
left = parent.width * left | 0;
|
||||||
}
|
}
|
||||||
width = parent.width - (this.position.right || 0) - left;
|
width = parent.width - (this.position.right || 0) - left;
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
width -= ((this.position.left != null || this.position.right == null)
|
||||||
|
&& this.position.left !== 'center' ? this.parent.ileft : 0);
|
||||||
|
width -= (this.position.right != null ? this.parent.iright : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
@ -2375,6 +2393,11 @@ Element.prototype._getHeight = function(get) {
|
|||||||
top = parent.height * top | 0;
|
top = parent.height * top | 0;
|
||||||
}
|
}
|
||||||
height = parent.height - (this.position.bottom || 0) - top;
|
height = parent.height - (this.position.bottom || 0) - top;
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
height -= ((this.position.top != null || this.position.bottom == null)
|
||||||
|
&& this.position.top !== 'center' ? this.parent.itop : 0);
|
||||||
|
height -= (this.position.bottom != null ? this.parent.ibottom : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
@ -2401,6 +2424,13 @@ Element.prototype._getLeft = function(get) {
|
|||||||
return this.screen.cols - this._getWidth(get) - this._getRight(get);
|
return this.screen.cols - this._getWidth(get) - this._getRight(get);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
if ((this.position.left != null || this.position.right == null)
|
||||||
|
&& this.position.left !== 'center') {
|
||||||
|
left += this.parent.ileft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (parent.left || 0) + left;
|
return (parent.left || 0) + left;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2411,9 +2441,17 @@ Element.prototype.__defineGetter__('left', function() {
|
|||||||
Element.prototype._getRight = function(get) {
|
Element.prototype._getRight = function(get) {
|
||||||
var parent = get ? this.parent._getPos() : this.parent;
|
var parent = get ? this.parent._getPos() : this.parent;
|
||||||
if (this.position.right == null && this.position.left != null) {
|
if (this.position.right == null && this.position.left != null) {
|
||||||
return this.screen.cols - (this._getLeft(get) + this._getWidth(get));
|
var right = this.screen.cols - (this._getLeft(get) + this._getWidth(get));
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
right += (this.position.right != null ? this.parent.iright : 0);
|
||||||
|
}
|
||||||
|
return right;
|
||||||
}
|
}
|
||||||
return (parent.right || 0) + (this.position.right || 0);
|
var right = (parent.right || 0) + (this.position.right || 0);
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
right += (this.position.right != null ? this.parent.iright : 0);
|
||||||
|
}
|
||||||
|
return right;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.__defineGetter__('right', function() {
|
Element.prototype.__defineGetter__('right', function() {
|
||||||
@ -2437,6 +2475,13 @@ Element.prototype._getTop = function(get) {
|
|||||||
return this.screen.rows - this._getHeight(get) - this._getBottom(get);
|
return this.screen.rows - this._getHeight(get) - this._getBottom(get);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
if ((this.position.top != null || this.position.bottom == null)
|
||||||
|
&& this.position.top !== 'center') {
|
||||||
|
top += this.parent.itop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (parent.top || 0) + top;
|
return (parent.top || 0) + top;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2447,9 +2492,17 @@ Element.prototype.__defineGetter__('top', function() {
|
|||||||
Element.prototype._getBottom = function(get) {
|
Element.prototype._getBottom = function(get) {
|
||||||
var parent = get ? this.parent._getPos() : this.parent;
|
var parent = get ? this.parent._getPos() : this.parent;
|
||||||
if (this.position.bottom == null && this.position.top != null) {
|
if (this.position.bottom == null && this.position.top != null) {
|
||||||
return this.screen.rows - (this._getTop(get) + this._getHeight(get));
|
var bottom = this.screen.rows - (this._getTop(get) + this._getHeight(get));
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
bottom += (this.position.bottom != null ? this.parent.ibottom : 0);
|
||||||
|
}
|
||||||
|
return bottom;
|
||||||
}
|
}
|
||||||
return (parent.bottom || 0) + (this.position.bottom || 0);
|
var bottom = (parent.bottom || 0) + (this.position.bottom || 0);
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
bottom += (this.position.bottom != null ? this.parent.ibottom : 0);
|
||||||
|
}
|
||||||
|
return bottom;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.__defineGetter__('bottom', function() {
|
Element.prototype.__defineGetter__('bottom', function() {
|
||||||
@ -2630,10 +2683,18 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl) {
|
|||||||
|| this.position.right == null)) {
|
|| this.position.right == null)) {
|
||||||
if (this.position.left == null && this.position.right != null) {
|
if (this.position.left == null && this.position.right != null) {
|
||||||
xi = xl - (mxl - mxi);
|
xi = xl - (mxl - mxi);
|
||||||
xi -= this.padding.left + this.padding.right;
|
if (!this.screen.autoPadding) {
|
||||||
|
xi -= this.padding.left + this.padding.right;
|
||||||
|
} else {
|
||||||
|
xi -= this.padding.left;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
xl = mxl;
|
xl = mxl;
|
||||||
xl += this.padding.left + this.padding.right;
|
if (!this.screen.autoPadding) {
|
||||||
|
xl += this.padding.left + this.padding.right;
|
||||||
|
} else {
|
||||||
|
xl += this.padding.right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2643,10 +2704,18 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl) {
|
|||||||
&& !this.scrollable) {
|
&& !this.scrollable) {
|
||||||
if (this.position.top == null && this.position.bottom != null) {
|
if (this.position.top == null && this.position.bottom != null) {
|
||||||
yi = yl - (myl - myi);
|
yi = yl - (myl - myi);
|
||||||
yi -= this.padding.top + this.padding.bottom;
|
if (!this.screen.autoPadding) {
|
||||||
|
yi -= this.padding.top + this.padding.bottom;
|
||||||
|
} else {
|
||||||
|
yi -= this.padding.top;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
yl = myl;
|
yl = myl;
|
||||||
yl += this.padding.top + this.padding.bottom;
|
if (!this.screen.autoPadding) {
|
||||||
|
yl += this.padding.top + this.padding.bottom;
|
||||||
|
} else {
|
||||||
|
yl += this.padding.bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3822,6 +3891,12 @@ List.prototype.add = function(item) {
|
|||||||
focusEffects: this.mouse ? this.style.item.focus : null
|
focusEffects: this.mouse ? this.style.item.focus : null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.screen.autoPadding) {
|
||||||
|
options.top = this.items.length;
|
||||||
|
options.left = 1;
|
||||||
|
options.right = 1;
|
||||||
|
}
|
||||||
|
|
||||||
['bg', 'fg', 'bold', 'underline',
|
['bg', 'fg', 'bold', 'underline',
|
||||||
'blink', 'inverse', 'invisible'].forEach(function(name) {
|
'blink', 'inverse', 'invisible'].forEach(function(name) {
|
||||||
options[name] = function() {
|
options[name] = function() {
|
||||||
|
@ -103,6 +103,11 @@ list.prepend(blessed.text({
|
|||||||
content: ' My list '
|
content: ' My list '
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (screen.autoPadding) {
|
||||||
|
list.children[0].rleft = -list.ileft + 2;
|
||||||
|
list.children[0].rtop = -list.itop;
|
||||||
|
}
|
||||||
|
|
||||||
list.on('keypress', function(ch, key) {
|
list.on('keypress', function(ch, key) {
|
||||||
if (key.name === 'up' || key.name === 'k') {
|
if (key.name === 'up' || key.name === 'k') {
|
||||||
list.up();
|
list.up();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user