« get me outta code hell

Adjust the way the scrollbar handle is drawn - 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
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-05-12 16:51:44 -0300
committerFlorrie <towerofnix@gmail.com>2019-05-12 16:51:44 -0300
commit8bc775cfea02e8b1986393918ed7720b5764c5f2 (patch)
treeeb4b62c757f0d69797f30f7553fa3e57583af44d /ui
parentdff1213ae0069afcc0aa1b87daa6658732f742b8 (diff)
Adjust the way the scrollbar handle is drawn
Specifically, it now clearly represents how much of the scrollable form
is visible and not visible at the moment. It also will never touch the
top or bottom if it's possible to scroll further in the correspodning
direction.
Diffstat (limited to 'ui')
-rw-r--r--ui/form/ListScrollForm.js32
1 files changed, 30 insertions, 2 deletions
diff --git a/ui/form/ListScrollForm.js b/ui/form/ListScrollForm.js
index 892f964..d748d40 100644
--- a/ui/form/ListScrollForm.js
+++ b/ui/form/ListScrollForm.js
@@ -312,12 +312,40 @@ class ScrollBar extends DisplayElement {
     const totalLength = this.h - 2
     const totalScroll = this.listScrollForm.getScrollItemsLength()
     const currentScroll = this.listScrollForm.scrollItems
-    const handlePosition = Math.floor(totalLength / (totalScroll + 1) * currentScroll)
-    const handleLength = totalLength / (totalScroll + 1)
+
+    // ..[-----]..
+    //   ^start|
+    //         ^end
+    //
+    // Start and end should correspond to how much of the scroll area
+    // is currently visible. So, if you can see 60% of the full scroll length
+    // at a time, and you are scrolled 10% down, the start position of the
+    // handle should be 10% down, and it should extend 60% of the scrollbar
+    // length, to the 70% mark.
+
+    const edgeLength = this.listScrollForm.contentH
+    const totalItems = this.listScrollForm.inputs.length
+    const itemsVisibleAtOnce = Math.min(totalItems, edgeLength)
+    const handleLength = itemsVisibleAtOnce / totalItems * totalLength
+    let handlePosition = Math.floor(totalLength / totalItems * currentScroll)
 
     const canScrollBackwards = (currentScroll > 0)
     const canScrollForwards = (currentScroll < totalScroll)
 
+    // Silly peeve of mine: The handle should only be visibly touching the top
+    // or bottom of the scrollbar area if you're actually scrolled all the way
+    // to the start or end. Otherwise, it shouldn't be touching! There should
+    // visible space indicating that you can scroll in that direction
+    // (in addition to the arrows we show at the ends).
+
+    if (canScrollBackwards && handlePosition === 0) {
+      handlePosition = 1
+    }
+
+    if (canScrollForwards && (handlePosition + handleLength) === edgeLength) {
+      handlePosition--
+    }
+
     if (this.listScrollForm.layoutType === 'vertical') {
       const start = this.absTop + handlePosition + 1
       for (let i = 0; i < handleLength; i++) {