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
|
||||
terminal is resized (default: 300).
|
||||
- **tabSize** - the width of tabs within an element's content.
|
||||
- **autoPadding** - automatically position child elements with border and
|
||||
padding in mind.
|
||||
|
||||
##### Properties:
|
||||
|
||||
|
|
121
lib/widget.js
121
lib/widget.js
|
@ -282,6 +282,8 @@ function Screen(options) {
|
|||
this.tput = this.program.tput;
|
||||
this.output = this.program.output;
|
||||
|
||||
this.autoPadding = options.autoPadding;
|
||||
|
||||
this.tabc = Array((options.tabSize || 4) + 1).join(' ');
|
||||
this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff;
|
||||
|
||||
|
@ -292,6 +294,20 @@ function Screen(options) {
|
|||
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.history = [];
|
||||
this.clickable = [];
|
||||
|
@ -1703,6 +1719,13 @@ function Element(options) {
|
|||
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'
|
||||
|| options.position.height === 'shrink') {
|
||||
if (options.position.width === 'shrink') {
|
||||
|
@ -1792,6 +1815,10 @@ function Element(options) {
|
|||
style: this.style.label,
|
||||
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', ...).
|
||||
|
@ -2286,7 +2313,7 @@ Screen.prototype._getPos = function() {
|
|||
Element.prototype._getPos = function() {
|
||||
var pos = this.lpos;
|
||||
|
||||
assert.ok(pos && !pos.changed);
|
||||
assert.ok(pos);
|
||||
|
||||
if (pos.left != null) return pos;
|
||||
|
||||
|
@ -2300,20 +2327,6 @@ Element.prototype._getPos = function() {
|
|||
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
|
||||
*/
|
||||
|
@ -2342,6 +2355,11 @@ Element.prototype._getWidth = function(get) {
|
|||
left = parent.width * left | 0;
|
||||
}
|
||||
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;
|
||||
|
@ -2375,6 +2393,11 @@ Element.prototype._getHeight = function(get) {
|
|||
top = parent.height * top | 0;
|
||||
}
|
||||
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;
|
||||
|
@ -2401,6 +2424,13 @@ Element.prototype._getLeft = function(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;
|
||||
};
|
||||
|
||||
|
@ -2411,9 +2441,17 @@ Element.prototype.__defineGetter__('left', function() {
|
|||
Element.prototype._getRight = function(get) {
|
||||
var parent = get ? this.parent._getPos() : this.parent;
|
||||
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() {
|
||||
|
@ -2437,6 +2475,13 @@ Element.prototype._getTop = function(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;
|
||||
};
|
||||
|
||||
|
@ -2447,9 +2492,17 @@ Element.prototype.__defineGetter__('top', function() {
|
|||
Element.prototype._getBottom = function(get) {
|
||||
var parent = get ? this.parent._getPos() : this.parent;
|
||||
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() {
|
||||
|
@ -2630,10 +2683,18 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl) {
|
|||
|| this.position.right == null)) {
|
||||
if (this.position.left == null && this.position.right != null) {
|
||||
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 {
|
||||
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) {
|
||||
if (this.position.top == null && this.position.bottom != null) {
|
||||
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 {
|
||||
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
|
||||
};
|
||||
|
||||
if (this.screen.autoPadding) {
|
||||
options.top = this.items.length;
|
||||
options.left = 1;
|
||||
options.right = 1;
|
||||
}
|
||||
|
||||
['bg', 'fg', 'bold', 'underline',
|
||||
'blink', 'inverse', 'invisible'].forEach(function(name) {
|
||||
options[name] = function() {
|
||||
|
|
|
@ -103,6 +103,11 @@ list.prepend(blessed.text({
|
|||
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) {
|
||||
if (key.name === 'up' || key.name === 'k') {
|
||||
list.up();
|
||||
|
|
Loading…
Reference in New Issue