From 6e4e3fb76cbceb34338c62fb08394ffdffcdc687 Mon Sep 17 00:00:00 2001 From: Florrie Date: Thu, 5 Jul 2018 09:27:14 -0300 Subject: Tabber display --- ui.js | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 3 deletions(-) (limited to 'ui.js') diff --git a/ui.js b/ui.js index ab85bf7..3e04f85 100644 --- a/ui.js +++ b/ui.js @@ -674,6 +674,14 @@ class GrouplikeListingElement extends FocusElement { selectAndShow(item) { this.form.selectAndShow(item) } + + get tabberLabel() { + if (this.grouplike) { + return this.grouplike.name || 'Unnamed group' + } else { + return 'No group open' + } + } } class GrouplikeListingForm extends ListScrollForm { @@ -1050,18 +1058,43 @@ class Tabber extends FocusElement { this.tabberElements = [] this.currentElementIndex = 0 + + this.listElement = new TabberList(this) + this.addChild(this.listElement) } fixLayout() { - if (this.currentElement) { - this.currentElement.fillParent() - this.currentElement.fixLayout() + const el = this.currentElement + if (el) { + // Only make space for the tab list if there's more than one tab visible. + // (The tab list isn't shown if there's only one.) + if (this.tabberElements.length > 1) { + el.w = this.contentW + el.h = this.contentH - 1 + el.x = 0 + el.y = 1 + } else { + el.fillParent() + el.x = 0 + el.y = 0 + } + el.fixLayout() + } + + if (this.tabberElements.length > 1) { + this.listElement.visible = true + this.listElement.w = this.contentW + this.listElement.h = 1 + this.listElement.fixLayout() + } else { + this.listElement.visible = false } } addTab(element) { this.tabberElements.push(element) this.addChild(element) + this.listElement.buildItems() } nextTab() { @@ -1113,4 +1146,84 @@ class Tabber extends FocusElement { } } +class TabberList extends ListScrollForm { + constructor(tabber) { + super('horizontal') + this.tabber = tabber + this.captureTab = false + } + + buildItems() { + while (this.inputs.length) { + this.removeInput(this.inputs[0]) + } + + for (const item of this.tabber.tabberElements) { + const element = new TabberListItem(item, this.tabber) + this.addInput(element) + element.fixLayout() + } + + this.scrollToEnd() + this.fixLayout() + } + + fixLayout() { + this.w = this.parent.contentW + this.h = 1 + this.x = 0 + this.y = 0 + this.scrollElementIntoEndOfView(this.inputs[this.curIndex]) + super.fixLayout() + } + + drawTo() { + let changed = false + for (const input of this.inputs) { + input.fixLayout() + if (input._oldW !== input.w) { + input._oldW = input.w + changed = true + } + } + if (changed) { + this.fixLayout() + } + } + + // TODO: Be less hacky about these! Right now the tabber list is totally not + // interactive. + get curIndex() { return this.tabber.currentElementIndex } + set curIndex(newVal) {} +} + +class TabberListItem extends FocusElement { + constructor(tab, tabber) { + super() + + this.tab = tab + this.tabber = tabber + } + + fixLayout() { + this.w = this.text.length + 3 + } + + drawTo(writable) { + if (this.tabber.currentElement === this.tab) { + writable.write(ansi.setAttributes([ansi.A_BRIGHT])) + writable.write(ansi.moveCursor(this.absTop, this.absLeft)) + writable.write('<' + this.text + '>') + writable.write(ansi.resetAttributes()) + } else { + writable.write(ansi.moveCursor(this.absTop, this.absLeft + 1)) + writable.write(this.text) + } + } + + get text() { + return this.tab.tabberLabel || 'a(n) ' + this.tab.constructor.name + } +} + module.exports.AppElement = AppElement -- cgit 1.3.0-6-gf8a5