Christophe Weblog Wiki Code Publications Music
mouse events for mixer sliders
[squeeze-el.git] / squeeze.el
index 95bfdf140f358be70e5d1de1e16a4e825629fb68..5ca2f7cb41492ec9eeadfbfef579396ee8be6e66 100644 (file)
                   ((string= current "1") "0"))))))
 
 (defun squeeze-update-mixer-volume (player value)
-  (let ((current (squeeze-player-volume player)))
+  (let ((current (squeeze-player-volume player))
+        (number (string-to-number value)))
     (if (string-match "^[-+]" value)
-        (when current
-          (setf (squeeze-player-volume player) (+ current (string-to-number value))))
-      (setf (squeeze-player-volume player) (string-to-number value)))))
+        (setf (squeeze-player-volume player)
+              (and current (max 0 (min 100 (+ current number)))))
+      (setf (squeeze-player-volume player) number))))
 
 (defun squeeze-update-state-from-line (string)
   (cond
                   (t "█"))
             (make-string nblank ? ))))
 
-(defun squeeze-mixer-insert-bar (vol width)
+(defun squeeze-mixer-make-bar (vol width)
   (let ((bar (squeeze-mixer-compute-bar vol width))
         (lo (floor (* 0.65 width)))
         (hi (floor (* 0.9 width))))
-    (insert ?▕
+    (concat "▕"
             (propertize (substring bar 0 lo) 'face 'squeeze-mixer-quiet-face)
             (propertize (substring bar lo hi) 'face 'squeeze-mixer-medium-face)
             (propertize (substring bar hi) 'face 'squeeze-mixer-loud-face)
-            ?▏
-            )))
+            (propertize "▏" 'intangible t))))
 
 (defvar squeeze-players ())
 
   (when id
     (comint-send-string (get-buffer-process "*squeeze*") (format "%s mixer volume %+d\n" id (- inc)))))
 
+(defun squeeze-control-volume-set (id val)
+  (interactive)
+  (comint-send-string (get-buffer-process "*squeeze*") (format "%s mixer volume %d\n" id val)))
+
 (defun squeeze-control-query-mixer-volume (&optional id)
   (interactive)
   (unless id
       (accept-process-output (get-buffer-process "*squeeze*"))))
   (squeeze-control-display-players))
 
+(defvar squeeze-control-mixer-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") 'squeeze-control-mixer-set-volume)
+    (define-key map [mouse-1] 'squeeze-control-mixer-mouse-1)
+    map))
+
+(defun squeeze-control-compute-volume (pos)
+  (let* ((end (next-single-property-change pos 'keymap))
+         (start (previous-single-property-change end 'keymap)))
+    (/ (* 100 (- (point) start)) (- end start 1))))
+
+(defun squeeze-control-mixer-mouse-1 (event)
+  (interactive "e")
+  (let* ((pos (cadadr event))
+         (val (squeeze-control-compute-volume pos))
+         (id (get-text-property pos 'squeeze-playerid)))
+    (squeeze-control-volume-set id val)))
+
+(defun squeeze-control-mixer-set-volume ()
+  (interactive)
+  (let* ((val (squeeze-control-compute-volume (point)))
+         (id (get-text-property (point) 'squeeze-playerid)))
+    (squeeze-control-volume-set id val)))
+
 (defun squeeze-control-display-players ()
   (interactive)
   (let ((players squeeze-players))
                             'face (squeeze-control-player-face player)
                             'squeeze-playerid (squeeze-player-playerid player)))
         (when (squeeze-player-volume player)
-          (squeeze-mixer-insert-bar (squeeze-player-volume player) 28))
-        (insert "\n"))
+          (insert (propertize (squeeze-mixer-make-bar (squeeze-player-volume player) 28)
+                              'squeeze-playerid (squeeze-player-playerid player)
+                              'keymap squeeze-control-mixer-map
+                              'pointer 'hdrag
+                              'rear-nonsticky '(keymap))))
+        (insert (propertize "\n" 'intangible t)))
       (read-only-mode 1))))
 
 (cl-defstruct (squeeze-player (:constructor squeeze-make-player))