From c5b3a076963517c93b6596f3e0a860be1d80ef80 Mon Sep 17 00:00:00 2001 From: Florrie Date: Tue, 12 Jun 2018 23:55:06 -0300 Subject: Add WrapLabel UI element --- package-lock.json | 13 +++++++++++++ package.json | 3 ++- ui/Label.js | 17 ++++++++++++----- ui/WrapLabel.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 package-lock.json create mode 100644 ui/WrapLabel.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d020d44 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "tui-lib", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + } + } +} diff --git a/package.json b/package.json index 6c386f7..f92515b 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "author": "Florrie ", "license": "GPL-3.0", "dependencies": { - "iac": "^1.1.0" + "iac": "^1.1.0", + "word-wrap": "^1.2.3" } } diff --git a/ui/Label.js b/ui/Label.js index 850edc0..faeee98 100644 --- a/ui/Label.js +++ b/ui/Label.js @@ -5,20 +5,23 @@ const DisplayElement = require('./DisplayElement') module.exports = class Label extends DisplayElement { // A simple text display. Automatically adjusts size to fit text. - constructor(text='') { + constructor(text = '') { super() this.text = text this.textAttributes = [] } + fixLayout() { + this.w = this.text.length + } + drawTo(writable) { if (this.textAttributes.length) { writable.write(ansi.setAttributes(this.textAttributes)) } - writable.write(ansi.moveCursor(this.absTop, this.absLeft)) - writable.write(this.text) + this.writeTextTo(writable) if (this.textAttributes.length) { writable.write(ansi.resetAttributes()) @@ -27,10 +30,14 @@ module.exports = class Label extends DisplayElement { super.drawTo(writable) } + writeTextTo(writable) { + writable.write(ansi.moveCursor(this.absTop, this.absLeft)) + writable.write(this.text) + } + set text(newText) { this._text = newText - - this.w = newText.length + this.fixLayout() } get text() { diff --git a/ui/WrapLabel.js b/ui/WrapLabel.js new file mode 100644 index 0000000..babf462 --- /dev/null +++ b/ui/WrapLabel.js @@ -0,0 +1,44 @@ +const ansi = require('../util/ansi') +const wrap = require('word-wrap') + +const Label = require('./Label') + +module.exports = class WrapLabel extends Label { + // A word-wrapping text display. Given a width, wraps text to fit. + + constructor(...args) { + super(...args) + } + + fixLayout() { + // Override Label.fixLayout to do nothing. We don't want to make the + // width of this label be set to the content of the text! (That would + // defeat the entire point of word wrapping.) + } + + writeTextTo(writable) { + const lines = this.getWrappedLines() + for (let i = 0; i < lines.length; i++) { + writable.write(ansi.moveCursor(this.absTop + i, this.absLeft)) + writable.write(lines[i]) + } + } + + getWrappedLines() { + if (this.text.trim().length === 0) { + return [] + } + + const options = {width: this.w, indent: ''} + return wrap(this.text, options).split('\n') + .map(l => l.trim()) + } + + get h() { + return this.getWrappedLines().length + } + + set h(newHeight) { + // Do nothing. Height is computed on the fly. + } +} -- cgit 1.3.0-6-gf8a5