From 0ea19cacad35a24861caf050ce49aff1db374e62 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 1 May 2015 19:11:34 -0700 Subject: [PATCH] fix off-screen coords. fix draggable. --- lib/widget.js | 52 ++++++++++++++++++++++++++++++++++++---------- test/widget-csr.js | 26 ++++++++++++++++++----- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/lib/widget.js b/lib/widget.js index 5f44804..ae617a6 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -975,12 +975,14 @@ Screen.prototype.cleanSides = function(el) { return pos._cleanSides; } - if (pos.xi === 0 && pos.xl === this.width) { + if (pos.xi <= 0 && pos.xl >= this.width) { return pos._cleanSides = true; } if (this.options.fastCSR) { // Maybe just do this instead of parsing. + if (pos.yi < 0) return pos._cleanSides = false; + if (pos.yl > this.height) return pos._cleanSides = false; if (this.width - (pos.xl - pos.xi) < 40) { return pos._cleanSides = true; } @@ -1010,9 +1012,16 @@ Screen.prototype.cleanSides = function(el) { , x , y; + if (pos.yi < 0) return pos._cleanSides = false; + if (pos.yl > this.height) return pos._cleanSides = false; + if (pos.xi - 1 < 0) return pos._cleanSides = true; + if (pos.xl > this.width) return pos._cleanSides = true; + for (x = pos.xi - 1; x >= 0; x--) { + if (!this.olines[yi]) break; first = this.olines[yi][x]; for (y = yi; y < yl; y++) { + if (!this.olines[y] || !this.olines[y][x]) break; ch = this.olines[y][x]; if (ch[0] !== first[0] || ch[1] !== first[1]) { return pos._cleanSides = false; @@ -1021,8 +1030,10 @@ Screen.prototype.cleanSides = function(el) { } for (x = pos.xl; x < this.width; x++) { + if (!this.olines[yi]) break; first = this.olines[yi][x]; for (y = yi; y < yl; y++) { + if (!this.olines[y] || !this.olines[y][x]) break; ch = this.olines[y][x]; if (ch[0] !== first[0] || ch[1] !== first[1]) { return pos._cleanSides = false; @@ -2151,6 +2162,9 @@ Screen.prototype.screenshot = function(xi, xl, yi, yl, term) { if (yi == null) yi = 0; if (yl == null) yl = this.rows; + if (xi < 0) xi = 0; + if (yi < 0) yi = 0; + var x , y , line @@ -2999,8 +3013,23 @@ Element.prototype.enableDrag = function() { , x = data.x - px - ox , y = data.y - py - oy; + if (self.position.right != null) { + if (self.position.left != null) { + self.width = '100%-' + (self.parent.width - self.width); + } + self.position.right = null; + } + + if (self.position.bottom != null) { + if (self.position.top != null) { + self.height = '100%-' + (self.parent.height - self.height); + } + self.position.bottom = null; + } + self.rleft = x; self.rtop = y; + self.screen.render(); }); @@ -4092,9 +4121,10 @@ Element.prototype.render = function() { // ahead of time. This could be optimized. if (this.tpadding || (this.valign && this.valign !== 'top')) { if (this.style.transparent) { - for (y = yi; y < yl; y++) { + for (y = Math.max(yi, 0); y < yl; y++) { if (!lines[y]) break; - for (x = xi; x < xl; x++) { + for (x = Math.max(xi, 0); x < xl; x++) { + if (!lines[y][x]) break; lines[y][x][0] = this._blend(attr, lines[y][x][0]); lines[y][x][1] = ch; lines[y].dirty = true; @@ -4452,12 +4482,12 @@ Element.prototype.render = function() { if (this.shadow) { // right - y = yi + 1; + y = Math.max(yi + 1, 0); for (; y < yl + 1; y++) { - if (!lines[y]) continue; + if (!lines[y]) break; x = xl; for (; x < xl + 2; x++) { - if (!lines[y][x]) continue; + if (!lines[y][x]) break; // lines[y][x][0] = this._blend(this.dattr, lines[y][x][0]); lines[y][x][0] = this._blend(lines[y][x][0]); lines[y].dirty = true; @@ -4466,9 +4496,9 @@ Element.prototype.render = function() { // bottom y = yl; for (; y < yl + 1; y++) { - if (!lines[y]) continue; - for (x = xi + 1; x < xl; x++) { - if (!lines[y][x]) continue; + if (!lines[y]) break; + for (x = Math.max(xi + 1, 0); x < xl; x++) { + if (!lines[y][x]) break; // lines[y][x][0] = this._blend(this.dattr, lines[y][x][0]); lines[y][x][0] = this._blend(lines[y][x][0]); lines[y].dirty = true; @@ -8494,7 +8524,7 @@ Terminal.prototype.render = function() { var scrollback = this.term.lines.length - (yl - yi); - for (var y = yi; y < yl; y++) { + for (var y = Math.max(yi, 0); y < yl; y++) { var line = this.screen.lines[y]; if (!line || !this.term.lines[scrollback + y - yi]) break; @@ -8508,7 +8538,7 @@ Terminal.prototype.render = function() { cursor = -1; } - for (var x = xi; x < xl; x++) { + for (var x = Math.max(xi, 0); x < xl; x++) { if (!line[x] || !this.term.lines[scrollback + y - yi][x - xi]) break; line[x][0] = this.term.lines[scrollback + y - yi][x - xi][0]; diff --git a/test/widget-csr.js b/test/widget-csr.js index f34a19a..23b86ed 100644 --- a/test/widget-csr.js +++ b/test/widget-csr.js @@ -8,9 +8,9 @@ screen = blessed.screen({ var lorem = require('fs').readFileSync(__dirname + '/git.diff', 'utf8'); +var cleanSides = screen.cleanSides; function expectClean(value) { - var cleanSides = screen.cleanSides; - screen.cleanSides = function() { + screen.cleanSides = function(el) { var ret = cleanSides.apply(this, arguments); if (ret !== value) { throw new Error('Failed. Expected ' @@ -36,7 +36,7 @@ blessed.box({ expectClean(false); */ -blessed.box({ +var btext = blessed.box({ parent: screen, left: 'center', top: 'center', @@ -48,7 +48,11 @@ blessed.box({ border: 'line', content: 'CSR should still work.' }); -expectClean(true); +btext._oscroll = btext.scroll; +btext.scroll = function(offset, always) { + expectClean(true); + return btext._oscroll(offset, always); +}; var text = blessed.scrollabletext({ parent: screen, @@ -56,7 +60,7 @@ var text = blessed.scrollabletext({ border: 'line', left: 'center', top: 'center', - width: '100%', + draggable: true, width: '50%', height: '50%', mouse: true, @@ -64,6 +68,18 @@ var text = blessed.scrollabletext({ vi: true }); +text._oscroll = text.scroll; +text.scroll = function(offset, always) { + var el = this; + var value = true; + if (el.left < 0) value = true; + if (el.top < 0) value = false; + if (el.left + el.width > screen.width) value = true; + if (el.top + el.height > screen.height) value = false; + expectClean(value); + return text._oscroll(offset, always); +}; + text.focus(); screen.key('q', function() {