« get me outta code hell

tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
path: root/ui/form/ListScrollForm.js
diff options
context:
space:
mode:
Diffstat (limited to 'ui/form/ListScrollForm.js')
-rw-r--r--ui/form/ListScrollForm.js303
1 files changed, 0 insertions, 303 deletions
diff --git a/ui/form/ListScrollForm.js b/ui/form/ListScrollForm.js
deleted file mode 100644
index e4f4249..0000000
--- a/ui/form/ListScrollForm.js
+++ /dev/null
@@ -1,303 +0,0 @@
-const ansi = require('../../util/ansi')
-const telc = require('../../util/telchars')
-
-const Form = require('./Form')
-const ScrollBar = require('./ScrollBar')
-
-module.exports = class ListScrollForm extends Form {
-  // A form that lets the user scroll through a list of items. It
-  // automatically adjusts to always allow the selected item to be visible.
-  // Unless disabled in the constructor, a scrollbar is automatically displayed
-  // if there are more items than can be shown in the height of the form at a
-  // single time.
-
-  constructor(layoutType = 'vertical', enableScrollBar = true) {
-    super()
-
-    this.layoutType = layoutType
-    this.wheelMode = 'scroll' // scroll, selection
-
-    this.scrollItems = 0
-
-    this.scrollBarEnabled = enableScrollBar
-
-    this.scrollBar = new ScrollBar({
-      getLayoutType: () => this.layoutType,
-      getCurrentScroll: () => this.scrollItems,
-      getMaximumScroll: () => this.getScrollItemsLength(),
-      getTotalItems: () => this.inputs.length
-    })
-    this.scrollBarShown = false
-  }
-
-  fixLayout() {
-    this.keepScrollInBounds()
-
-    const scrollItems = this.scrollItems
-
-    // The scrollItems property represents the item to the very left of where
-    // we've scrolled, so we know right away that none of those will be
-    // visible and we won't bother iterating over them. We do need to hide
-    // them, though.
-    for (let i = 0; i < Math.min(scrollItems, this.inputs.length); i++) {
-      this.inputs[i].visible = false
-    }
-
-    // This variable stores how far along the respective axis (implied by
-    // layoutType) the next element should be.
-    let nextPos = 0
-
-    let formEdge
-    if (this.layoutType === 'horizontal') {
-      formEdge = this.contentW
-    } else {
-      formEdge = this.contentH
-    }
-
-    for (let i = scrollItems; i < this.inputs.length; i++) {
-      const item = this.inputs[i]
-      item.fixLayout()
-
-      const curPos = nextPos
-      let curSize
-      if (this.layoutType === 'horizontal') {
-        item.x = curPos
-        curSize = item.w
-      } else {
-        item.y = curPos
-        curSize = item.h
-      }
-      nextPos += curSize
-
-      // By default, the item should be visible..
-      item.visible = true
-
-      // ..but the item's far edge is past the form's far edge, it isn't
-      // fully visible and should be hidden.
-      if (curPos + curSize > formEdge) {
-        item.visible = false
-      }
-
-      // Same deal goes for the close edge. We can check it against 0 since
-      // the close edge of the form's content is going to be 0, of course!
-      if (curPos < 0) {
-        item.visible = false
-      }
-    }
-
-    delete this._scrollItemsLength
-
-    if (this.scrollBarEnabled) {
-      this.showScrollbarIfNecessary()
-    }
-  }
-
-  keyPressed(keyBuf) {
-    let ret
-
-    handleKeyPress: {
-      if (this.layoutType === 'horizontal') {
-        if (telc.isLeft(keyBuf)) {
-          this.previousInput()
-          ret = false; break handleKeyPress
-        } else if (telc.isRight(keyBuf)) {
-          this.nextInput()
-          ret = false; break handleKeyPress
-        }
-      } else if (this.layoutType === 'vertical') {
-        if (telc.isUp(keyBuf)) {
-          this.previousInput()
-          ret = false; break handleKeyPress
-        } else if (telc.isDown(keyBuf)) {
-          this.nextInput()
-          ret = false; break handleKeyPress
-        }
-      }
-
-      ret = super.keyPressed(keyBuf)
-    }
-
-    this.scrollSelectedElementIntoView()
-
-    return ret
-  }
-
-  clicked(button) {
-    if (this.wheelMode === 'selection') {
-      // Change the actual selected item.
-      if (button === 'scroll-up') {
-        this.previousInput()
-        this.scrollSelectedElementIntoView()
-      } else if (button === 'scroll-down') {
-        this.nextInput()
-        this.scrollSelectedElementIntoView()
-      }
-    } else if (this.wheelMode === 'scroll') {
-      // Scrolling is typically pretty slow with a mouse wheel when it's by
-      // a single line, so scroll at 3x that speed.
-      for (let i = 0; i < 3; i++) {
-        if (button === 'scroll-up') {
-          this.scrollItems--
-        } else if (button === 'scroll-down') {
-          this.scrollItems++
-        } else {
-          return
-        }
-      }
-    }
-
-    this.fixLayout()
-  }
-
-  scrollSelectedElementIntoView() {
-    const sel = this.inputs[this.curIndex]
-
-    if (!sel) {
-      return
-    }
-
-    let formEdge
-    if (this.layoutType === 'horizontal') {
-      formEdge = this.contentW
-    } else {
-      formEdge = this.contentH
-    }
-
-    // If the item is ahead of our view (either to the right of or below),
-    // we should move the view so that the item is the farthest right (of all
-    // the visible items).
-    if (this.getItemPos(sel) > formEdge + this.scrollSize) {
-      this.scrollElementIntoEndOfView(sel)
-    }
-
-    // Adjusting the number of scroll items is much simpler to deal with if
-    // the item is behind our view. Since the item's behind, we need to move
-    // the scroll to be immediately behind it, which is simple since we
-    // already have its index.
-    if (this.getItemPos(sel) <= this.scrollSize) {
-      this.scrollItems = this.curIndex
-    }
-
-    this.fixLayout()
-  }
-
-  firstInput(...args) {
-    this.scrollItems = 0
-
-    super.firstInput(...args)
-
-    this.fixLayout()
-  }
-
-  getScrollPositionOfElementAtEndOfView(element) {
-    // We can decide how many items to scroll past by moving forward until
-    // the item's far edge is visible.
-    const pos = this.getItemPos(element)
-
-    let edge
-    if (this.layoutType === 'horizontal') {
-      edge = this.contentW
-    } else {
-      edge = this.contentH
-    }
-
-    for (let i = 0; i < this.inputs.length; i++) {
-      if (pos <= edge) {
-        return i
-      }
-
-      if (this.layoutType === 'horizontal') {
-        edge += this.inputs[i].w
-      } else {
-        edge += this.inputs[i].h
-      }
-    }
-    // No result? Well, it's at the end.
-    return this.inputs.length
-  }
-
-  scrollElementIntoEndOfView(element) {
-    this.scrollItems = this.getScrollPositionOfElementAtEndOfView(element)
-  }
-
-  scrollToBeginning() {
-    this.scrollItems = 0
-    this.fixLayout()
-  }
-
-  scrollToEnd() {
-    this.scrollElementIntoEndOfView(this.inputs[this.inputs.length - 1])
-    this.fixLayout()
-  }
-
-  keepScrollInBounds() {
-    this.scrollItems = Math.max(this.scrollItems, 0)
-    this.scrollItems = Math.min(this.scrollItems, this.getScrollItemsLength())
-  }
-
-  getScrollItemsLength() {
-    if (typeof this._scrollItemsLength === 'undefined') {
-      const lastInput = this.inputs[this.inputs.length - 1]
-      this._scrollItemsLength = this.getScrollPositionOfElementAtEndOfView(lastInput)
-    }
-
-    return this._scrollItemsLength
-  }
-
-  getItemPos(item) {
-    // Gets the position of the item in an unscrolled view.
-
-    const index = this.inputs.indexOf(item)
-    let pos = 0
-    for (let i = 0; i <= index; i++) {
-      if (this.layoutType === 'horizontal') {
-        pos += this.inputs[i].w
-      } else {
-        pos += this.inputs[i].h
-      }
-    }
-    return pos
-  }
-
-  showScrollbarIfNecessary() {
-    this.scrollBarShown = this.scrollBar.canScrollAtAll()
-
-    const isChild = this.children.includes(this.scrollBar)
-    if (this.scrollBarShown) {
-      if (!isChild) this.addChild(this.scrollBar)
-    } else {
-      if (isChild) this.removeChild(this.scrollBar)
-    }
-  }
-
-  get scrollSize() {
-    // Gets the actual length made up by all of the items currently scrolled
-    // past.
-
-    let size = 0
-    for (let i = 0; i < Math.min(this.scrollItems, this.inputs.length); i++) {
-      if (this.layoutType === 'horizontal') {
-        size += this.inputs[i].w
-      } else {
-        size += this.inputs[i].h
-      }
-    }
-    return size
-  }
-
-  get contentW() {
-    if (this.scrollBarShown && this.layoutType === 'vertical') {
-      return this.w - 1
-    } else {
-      return this.w
-    }
-  }
-
-  get contentH() {
-    if (this.scrollBarShown && this.layoutType === 'horizontal') {
-      return this.h - 1
-    } else {
-      return this.h
-    }
-  }
-}