]> git.0d.be Git - jack_mixer.git/blobdiff - slider.py
Set version to 14 in preparation for next release
[jack_mixer.git] / slider.py
index e155f3a1968f7d65e06ea17c6cfb81a0c26c8d3e..9cc7d6d6e0a21f9ef0e558b48351cf3aff2846c2 100644 (file)
--- a/slider.py
+++ b/slider.py
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
+import logging
+
+import cairo
 from gi.repository import Gtk
 from gi.repository import Gdk
 from gi.repository import GObject
-import cairo
+
+
+log = logging.getLogger(__name__)
+
 
 class AdjustmentdBFS(Gtk.Adjustment):
     def __init__(self, scale, default_db, step_inc):
@@ -63,6 +69,7 @@ class AdjustmentdBFS(Gtk.Adjustment):
         self.set_value(self.scale.db_to_scale(self.db))
         self.disable_value_notify = False
 
+
 GObject.signal_new("volume-changed", AdjustmentdBFS,
                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
 
@@ -70,9 +77,31 @@ GObject.signal_new("volume-changed-from-midi", AdjustmentdBFS,
                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
 
 
-class GtkSlider(Gtk.VScale):
+class BalanceAdjustment(Gtk.Adjustment):
+    def __init__(self):
+        Gtk.Adjustment.__init__(self, 0.0, -1.0, 1.0, 0.02)
+        self.connect("value-changed", self.on_value_changed)
+        self.disable_value_notify = False
+
+    def set_balance(self, value, from_midi = False):
+        self.disable_value_notify = True
+        self.set_value(value)
+        self.disable_value_notify = False
+        if not from_midi:
+            self.emit("balance-changed")
+
+    def on_value_changed(self, adjustment):
+        if not self.disable_value_notify:
+            self.emit("balance-changed")
+
+
+GObject.signal_new("balance-changed", BalanceAdjustment,
+                   GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
+
+
+class VolumeSlider(Gtk.Scale):
     def __init__(self, adjustment):
-        Gtk.VScale.__init__(self)#, adjustment)
+        Gtk.Scale.__init__(self, orientation=Gtk.Orientation.VERTICAL)
         self.adjustment = adjustment
         self.set_adjustment(adjustment)
         self.set_draw_value(False)
@@ -81,31 +110,26 @@ class GtkSlider(Gtk.VScale):
         self.button_down_y = 0
         self.button_down_value = 0
 
-        # HACK: we want the behaviour you get with the middle button, so we
-        # mangle the events. Clicking with other buttons moves the slider in
-        # step increments, clicking with the middle button moves the slider
-        # to the location of the click.
         self.connect('button-press-event', self.button_press_event)
         self.connect('button-release-event', self.button_release_event)
         self.connect("motion-notify-event", self.motion_notify_event)
         self.connect("scroll-event", self.scroll_event)
 
     def button_press_event(self, widget, event):
-        if event.type == Gdk.EventType.BUTTON_PRESS:
-            widget.get_style_context().set_state(Gtk.StateFlags.FOCUSED)
-            widget.get_style_context().set_state(Gtk.StateFlags.PRELIGHT|Gtk.StateFlags.FOCUSED)
-            widget.get_style_context().add_class('dragging')
-            widget.get_style_context().add_class(':focused')
-            self.button_down = True
-            self.button_down_y = event.y
-            self.button_down_value = self.adjustment.get_value()
-            return True
-        if not event.state & Gdk.ModifierType.CONTROL_MASK and event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
-            self.adjustment.set_value(0)
-            return True
-        if event.state & Gdk.ModifierType.CONTROL_MASK and event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
-            self.adjustment.set_value(self.adjustment.scale.db_to_scale(1))
-            return True
+        if event.button == 1:
+            if event.state & Gdk.ModifierType.CONTROL_MASK:
+                if event.type == Gdk.EventType.BUTTON_PRESS:
+                    self.adjustment.set_value_db(0)
+                    return True
+            elif event.type == Gdk.EventType.BUTTON_PRESS:
+                self.button_down = True
+                self.button_down_y = event.y
+                self.button_down_value = self.adjustment.get_value()
+                return True
+            elif event.type == Gdk.EventType._2BUTTON_PRESS:
+                self.adjustment.set_value(0)
+                return True
+
         return False
 
     def button_release_event(self, widget, event):
@@ -113,7 +137,10 @@ class GtkSlider(Gtk.VScale):
         return False
 
     def motion_notify_event(self, widget, event):
-        slider_length = widget.get_allocation().height - widget.get_style_context().get_property('min-height', Gtk.StateFlags.NORMAL)
+        slider_length = (
+            widget.get_allocation().height -
+            widget.get_style_context().get_property('min-height', Gtk.StateFlags.NORMAL)
+        )
         if self.button_down:
             delta_y = (self.button_down_y - event.y) / slider_length
             y = self.button_down_value + delta_y
@@ -121,6 +148,7 @@ class GtkSlider(Gtk.VScale):
                 y = 1
             elif y <= 0:
                 y = 0
+
             self.adjustment.set_value(y)
             return True
 
@@ -138,13 +166,97 @@ class GtkSlider(Gtk.VScale):
             y = 1
         elif y <= 0:
             y = 0
+
         self.adjustment.set_value(y)
         return True
 
+
+class BalanceSlider(Gtk.Scale):
+    def __init__(self, adjustment, preferred_width, preferred_height):
+        Gtk.Scale.__init__(self, orientation=Gtk.Orientation.HORIZONTAL)
+        self.adjustment = adjustment
+        self.set_adjustment(adjustment)
+        self.set_has_origin(False)
+        self.set_draw_value(False)
+        self.set_property("has-tooltip", True)
+        self._preferred_width = preferred_width
+        self._preferred_height = preferred_height
+        self._button_down = False
+
+        self.add_mark(-1.0, Gtk.PositionType.TOP)
+        self.add_mark(0.0, Gtk.PositionType.TOP)
+        self.add_mark(1.0, Gtk.PositionType.TOP)
+
+        self.connect("button-press-event", self.on_button_press_event)
+        self.connect("button-release-event", self.on_button_release_event)
+        self.connect("motion-notify-event", self.on_motion_notify_event)
+        self.connect("scroll-event", self.on_scroll_event)
+        self.connect("query-tooltip", self.on_query_tooltip)
+
+    def get_preferred_width(self):
+        return self._preferred_width
+
+    def get_preferred_height(self):
+        return self._preferred_height
+
+    def on_button_press_event(self, widget, event):
+        if event.button == 1:
+            if event.type == Gdk.EventType.BUTTON_PRESS:
+                self._button_down = True
+                self._button_down_x = event.x
+                self._button_down_value = self.get_value()
+                return True
+            elif event.type == Gdk.EventType._2BUTTON_PRESS:
+                self.adjustment.set_balance(0)
+                return True
+
+        return False
+
+    def on_button_release_event(self, widget, event):
+        self._button_down = False
+        return False
+
+    def on_motion_notify_event(self, widget, event):
+        slider_length = (
+            widget.get_allocation().width -
+            widget.get_style_context().get_property('min-width', Gtk.StateFlags.NORMAL)
+        )
+
+        if self._button_down:
+            delta_x = (event.x - self._button_down_x) / slider_length
+            x = self._button_down_value + 2 * delta_x
+            self.adjustment.set_balance(min(1, max(x, -1)))
+            return True
+
+        return False
+
+    def on_query_tooltip(self, widget, x, y, keyboard_mode, tooltip, *args):
+        val = int(self.adjustment.get_value() * 50)
+        if val == 0:
+            tooltip.set_text("Center")
+        else:
+            tooltip.set_text("Left: %s / Right: %d" % (50 - val, val + 50))
+
+        return True
+
+    def on_scroll_event(self, widget, event):
+        delta = self.get_adjustment().get_step_increment()
+        value = self.get_value()
+
+        if event.direction == Gdk.ScrollDirection.UP:
+            x = value - delta
+        elif event.direction == Gdk.ScrollDirection.DOWN:
+            x = value + delta
+        elif event.direction == Gdk.ScrollDirection.SMOOTH:
+            x = value - event.delta_y * delta
+
+        self.set_value(min(1, max(x, -1)))
+        return True
+
+
 class CustomSliderWidget(Gtk.DrawingArea):
     def __init__(self, adjustment):
         Gtk.DrawingArea.__init__(self)
-
         self.adjustment = adjustment
 
         self.connect("draw", self.on_expose)
@@ -154,7 +266,7 @@ class CustomSliderWidget(Gtk.DrawingArea):
         self.connect("motion-notify-event", self.on_mouse)
         self.connect("scroll-event", self.on_scroll)
         self.set_events(Gdk.EventMask.BUTTON1_MOTION_MASK |
-                Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
+                        Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
 
     def on_scroll(self, widget, event):
         delta = self.adjustment.step_increment
@@ -172,19 +284,19 @@ class CustomSliderWidget(Gtk.DrawingArea):
 
     def on_mouse(self, widget, event):
         if event.type == Gdk.EventType.BUTTON_PRESS:
-            #print "mouse button %u pressed %u:%u" % (event.button, event.x, event.y)
+            log.debug("Mouse button %u pressed %ux%u", event.button, event.x, event.y)
             if event.button == 1:
                 if event.y >= self.slider_rail_up and event.y < self.slider_rail_up + self.slider_rail_height:
-                    self.adjustment.set_value(1 - float(event.y - self.slider_rail_up)/float(self.slider_rail_height))
+                    self.adjustment.set_value(1 - float(event.y - self.slider_rail_up) / float(self.slider_rail_height))
         elif event.type == Gdk.EventType.MOTION_NOTIFY:
-            #print "mouse motion %u:%u" % (event.x, event.y)
+            log.debug("Mouse motion %ux%u", event.x, event.y)
             if event.y < self.slider_rail_up:
                 y = self.slider_rail_up
             elif event.y > self.slider_rail_up + self.slider_rail_height:
                 y = self.slider_rail_up + self.slider_rail_height
             else:
                 y = event.y
-            self.adjustment.set_value(1 - float(y - self.slider_rail_up)/float(self.slider_rail_height))
+            self.adjustment.set_value(1 - float(y - self.slider_rail_up) / float(self.slider_rail_height))
 
         return False
 
@@ -192,9 +304,7 @@ class CustomSliderWidget(Gtk.DrawingArea):
         self.invalidate_all()
 
     def on_expose(self, widget, cairo_ctx):
-
         self.draw(cairo_ctx)
-
         return False
 
     def get_preferred_width(self, widget):
@@ -207,7 +317,6 @@ class CustomSliderWidget(Gtk.DrawingArea):
         minimal_height = natural_heigt = requisition.height
         return (minimal_height, natural_height)
 
-
     def on_size_allocate(self, widget, allocation):
         self.width = float(allocation.width)
         self.height = float(allocation.height)
@@ -215,7 +324,6 @@ class CustomSliderWidget(Gtk.DrawingArea):
 
     def on_size_request(self, widget, requisition):
         requisition.width = 20
-        return
 
     def invalidate_all(self):
         if hasattr(self, 'width') and hasattr(self, 'height'):