« get me outta code hell

mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--todo.txt3
-rw-r--r--ui.js23
2 files changed, 26 insertions, 0 deletions
diff --git a/todo.txt b/todo.txt
index 869e88d..722e79c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -501,5 +501,8 @@ TODO: "Lock scroll to cursor" option in queue listing. Will make the listing
       past the ends... maybe put a dim background behind the element currently
       occupying the locked position, scrolling such that the selected element
       is at that position whenever doing so doesn't go out of bounds?)
+      (Done! This was less work than expected. Dim background not implemented
+       because (1) it's more work and (2) I don't want to overcomplicate the
+       user interface.)
 
 TODO: Revisit labels and notes features! They're commented out for now :P
diff --git a/ui.js b/ui.js
index 8cb0501..a21bf3c 100644
--- a/ui.js
+++ b/ui.js
@@ -1025,6 +1025,8 @@ class AppElement extends FocusElement {
         canControlQueue && {label: 'Clear past this track', action: () => this.clearQueuePast(item)},
         canControlQueue && {label: 'Clear up to this track', action: () => this.clearQueueUpTo(item)},
         {divider: true},
+        {label: 'Autoscroll', action: () => listing.toggleAutoscroll()},
+        {divider: true},
         canControlQueue && {label: 'Remove from queue', action: () => this.unqueue(item)}
       ]
     } else {
@@ -1615,6 +1617,7 @@ class GrouplikeListingElement extends Form {
     this.form.on('selected', input => {
       if (input && this.pathElement) {
         this.pathElement.showItem(input.item)
+        this.autoscroll()
         this.emit('selected', input.item)
       }
     })
@@ -1634,6 +1637,8 @@ class GrouplikeListingElement extends Form {
 
     this.commentLabel = new WrapLabel()
     this.addChild(this.commentLabel)
+
+    this.autoscrollOffset = null
   }
 
   getNewForm() {
@@ -1651,6 +1656,7 @@ class GrouplikeListingElement extends Form {
     if (this.jumpElement.visible) this.form.h -= 1
 
     this.form.fixLayout() // Respond to being resized
+    this.autoscroll()
     this.form.scrollSelectedElementIntoView()
 
     this.pathElement.y = this.contentH - 1
@@ -1747,6 +1753,23 @@ class GrouplikeListingElement extends Form {
   }
   */
 
+  toggleAutoscroll() {
+    if (this.autoscrollOffset === null) {
+      this.autoscrollOffset = this.form.curIndex - this.form.scrollItems
+    } else {
+      this.autoscrollOffset = null
+    }
+  }
+
+  autoscroll() {
+    if (this.autoscrollOffset !== null) {
+      const distanceFromTop = this.form.curIndex - this.form.scrollItems
+      const delta = this.autoscrollOffset - distanceFromTop
+      this.form.scrollItems -= delta
+      this.form.fixLayout()
+    }
+  }
+
   buildItems(resetIndex = false) {
     if (!this.grouplike) {
       throw new Error('Attempted to call buildItems before a grouplike was loaded')