# 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):
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, [])
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)
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):
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
y = 1
elif y <= 0:
y = 0
+
self.adjustment.set_value(y)
return True
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)
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
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
self.invalidate_all()
def on_expose(self, widget, cairo_ctx):
-
self.draw(cairo_ctx)
-
return False
def get_preferred_width(self, widget):
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)
def on_size_request(self, widget, requisition):
requisition.width = 20
- return
def invalidate_all(self):
if hasattr(self, 'width') and hasattr(self, 'height'):