« get me outta code hell

Support disabling playback controls - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-07-06 14:06:08 -0300
committerFlorrie <towerofnix@gmail.com>2019-07-06 14:06:08 -0300
commite973550703ebc7f93b6bbb6b36a294d2823ad5ee (patch)
tree901286aa8f718ae0838a59dd946349e71d574437
parent86a94ba5c7e52a3291b0ae38fb5c6fa0a834b8d2 (diff)
Support disabling playback controls
I don't think I'm going to disable controls in the telnet client (by
default?), but it's good to have this implemented anyway.
-rw-r--r--telnet-server.js1
-rw-r--r--ui.js98
2 files changed, 68 insertions, 31 deletions
diff --git a/telnet-server.js b/telnet-server.js
index 4e87499..1e06c78 100644
--- a/telnet-server.js
+++ b/telnet-server.js
@@ -27,6 +27,7 @@ class TelnetServer {
       writable: socket,
       interfacer,
       appConfig: {
+        canControlPlayback: false,
         canSuspend: false,
         showLeftPane: false,
         stopPlayingUponQuit: false,
diff --git a/ui.js b/ui.js
index f72ec1e..b577568 100644
--- a/ui.js
+++ b/ui.js
@@ -143,6 +143,7 @@ class AppElement extends FocusElement {
     this.attachListeners()
 
     this.config = Object.assign({
+      canControlPlayback: true,
       canSuspend: true,
       menubarColor: 4, // blue
       showLeftPane: true,
@@ -278,17 +279,20 @@ class AppElement extends FocusElement {
 
     this.playingControl = new ToggleControl('Pause?', {
       setValue: val => this.backend.setPause(val),
-      getValue: () => this.backend.player.isPaused
+      getValue: () => this.backend.player.isPaused,
+      getEnabled: () => this.config.canControlPlayback
     })
 
     this.loopingControl = new ToggleControl('Loop current track?', {
       setValue: val => this.backend.setLoop(val),
-      getValue: () => this.backend.player.isLooping
+      getValue: () => this.backend.player.isLooping,
+      getEnabled: () => this.config.canControlPlayback
     })
 
     this.volumeSlider = new SliderElement('Volume', {
       setValue: val => this.backend.setVolume(val),
-      getValue: () => this.backend.player.volume
+      getValue: () => this.backend.player.volume,
+      getEnabled: () => this.config.canControlPlayback
     })
   }
 
@@ -690,27 +694,33 @@ class AppElement extends FocusElement {
 
     if ((telc.isEscape(keyBuf) || telc.isBackspace(keyBuf)) && this.menubar.isSelected) {
       this.menubar.restoreSelection()
-    } else if ((telc.isLeft(keyBuf) || telc.isRight(keyBuf)) && this.menubar.isSelected) {
-      return // le sigh
-    } else if (input.isRight(keyBuf)) {
-      this.backend.seekAhead(10)
-    } else if (input.isLeft(keyBuf)) {
-      this.backend.seekBack(10)
-    } else if (input.isTogglePause(keyBuf)) {
-      this.backend.togglePause()
-    } else if (input.isToggleLoop(keyBuf)) {
-      this.backend.toggleLoop()
-    } else if (input.isVolumeUp(keyBuf)) {
-      this.backend.volUp()
-    } else if (input.isVolumeDown(keyBuf)) {
-      this.backend.volDown()
-    } else if (input.isStop(keyBuf)) {
-      this.backend.stopPlaying()
-    } else if (input.isSkipBack(keyBuf)) {
-      this.backend.playPrevious(this.backend.playingTrack, true)
-    } else if (input.isSkipAhead(keyBuf)) {
-      this.backend.playNext(this.backend.playingTrack, true)
-    } else if (input.isFocusTabber(keyBuf) && this.paneLeft.visible && this.tabber.selectable) {
+    }
+
+    if (this.config.canControlPlayback) {
+      if ((telc.isLeft(keyBuf) || telc.isRight(keyBuf)) && this.menubar.isSelected) {
+        return // le sigh
+      } else if (input.isRight(keyBuf)) {
+        this.backend.seekAhead(10)
+      } else if (input.isLeft(keyBuf)) {
+        this.backend.seekBack(10)
+      } else if (input.isTogglePause(keyBuf)) {
+        this.backend.togglePause()
+      } else if (input.isToggleLoop(keyBuf)) {
+        this.backend.toggleLoop()
+      } else if (input.isVolumeUp(keyBuf)) {
+        this.backend.volUp()
+      } else if (input.isVolumeDown(keyBuf)) {
+        this.backend.volDown()
+      } else if (input.isStop(keyBuf)) {
+        this.backend.stopPlaying()
+      } else if (input.isSkipBack(keyBuf)) {
+        this.backend.playPrevious(this.backend.playingTrack, true)
+      } else if (input.isSkipAhead(keyBuf)) {
+        this.backend.playNext(this.backend.playingTrack, true)
+      }
+    }
+
+    if (input.isFocusTabber(keyBuf) && this.paneLeft.visible && this.tabber.selectable) {
       this.root.select(this.tabber)
     } else if (input.isFocusQueue(keyBuf) && this.queueListingElement.selectable) {
       this.root.select(this.queueListingElement)
@@ -1539,11 +1549,12 @@ class SliderElement extends FocusElement {
   // Same general principle and usage as InlineListPickerElement, but for
   // changing a numeric value.
 
-  constructor(labelText, {setValue, getValue, maxValue = 100, percent = true}) {
+  constructor(labelText, {setValue, getValue, maxValue = 100, percent = true, getEnabled = () => true}) {
     super()
     this.labelText = labelText
     this.setValue = setValue
     this.getValue = getValue
+    this.getEnabled = getEnabled
     this.maxValue = maxValue
     this.percent = percent
     this.keyboardIdentifier = this.labelText
@@ -1562,6 +1573,8 @@ class SliderElement extends FocusElement {
   }
 
   drawTo(writable) {
+    const enabled = this.getEnabled()
+
     if (this.isSelected) {
       writable.write(ansi.invert())
     }
@@ -1569,10 +1582,16 @@ class SliderElement extends FocusElement {
     let drawX = 0
     writable.write(ansi.moveCursor(this.absTop, this.absLeft))
 
+    if (!enabled) {
+      writable.write(ansi.setAttributes([ansi.A_DIM, ansi.C_WHITE]))
+    }
+
     writable.write(this.labelText + ' ')
     drawX += ansi.measureColumns(this.labelText) + 1
 
-    writable.write(ansi.setAttributes([ansi.A_BRIGHT, ansi.C_BLUE]))
+    if (enabled) {
+      writable.write(ansi.setAttributes([ansi.A_BRIGHT, ansi.C_BLUE]))
+    }
     writable.write(' ')
     drawX += 1
 
@@ -1584,7 +1603,10 @@ class SliderElement extends FocusElement {
     writable.write(' ' + numString + ' ')
     drawX += numString.length + 2
 
-    writable.write(ansi.setForeground(ansi.C_RESET))
+    if (enabled) {
+      writable.write(ansi.setForeground(ansi.C_RESET))
+    }
+
     writable.write(' '.repeat(Math.max(0, this.w - drawX)))
 
     writable.write(ansi.resetAttributes())
@@ -1620,9 +1642,10 @@ class SliderElement extends FocusElement {
   }
 
   keyPressed(keyBuf) {
-    if (telc.isRight(keyBuf)) {
+    const enabled = this.getEnabled()
+    if (enabled && telc.isRight(keyBuf)) {
       this.increment()
-    } else if (telc.isLeft(keyBuf)) {
+    } else if (enabled && telc.isLeft(keyBuf)) {
       this.decrement()
     } else {
       return true
@@ -1631,6 +1654,10 @@ class SliderElement extends FocusElement {
   }
 
   clicked(button) {
+    if (!this.getEnabled()) {
+      return
+    }
+
     if (button === 'left') {
       if (this.isSelected) {
         if (this.getValue() === this.maxValue) {
@@ -1662,21 +1689,26 @@ class SliderElement extends FocusElement {
 }
 
 class ToggleControl extends FocusElement {
-  constructor(labelText, {setValue, getValue}) {
+  constructor(labelText, {setValue, getValue, getEnabled = () => true}) {
     super()
     this.labelText = labelText
     this.setValue = setValue
     this.getValue = getValue
+    this.getEnabled = getEnabled
     this.keyboardIdentifier = this.labelText
   }
 
   keyPressed(keyBuf) {
-    if (input.isSelect(keyBuf)) {
+    if (input.isSelect(keyBuf) && this.getEnabled()) {
       this.toggle()
     }
   }
 
   clicked(button) {
+    if (!this.getEnabled()) {
+      return
+    }
+
     if (button === 'left') {
       if (this.isSelected) {
         this.toggle()
@@ -1708,6 +1740,10 @@ class ToggleControl extends FocusElement {
       writable.write(ansi.invert())
     }
 
+    if (!this.getEnabled()) {
+      writable.write(ansi.setAttributes([ansi.C_WHITE, ansi.A_DIM]))
+    }
+
     writable.write(ansi.moveCursor(this.absTop, this.absLeft))
 
     writable.write(this.getValue() ? '[X] ' : '[.] ')