]> git.0d.be Git - jack_mixer.git/blob - slider.py
Remove commented code
[jack_mixer.git] / slider.py
1 # This file is part of jack_mixer
2 #
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 import logging
19
20 import cairo
21 from gi.repository import Gtk
22 from gi.repository import Gdk
23 from gi.repository import GObject
24
25
26 log = logging.getLogger(__name__)
27
28
29 class AdjustmentdBFS(Gtk.Adjustment):
30     def __init__(self, scale, default_db, step_inc):
31         self.default_value = scale.db_to_scale(default_db)
32         self.db = default_db
33         self.scale = scale
34         self.step_increment = step_inc
35         Gtk.Adjustment.__init__(self, self.default_value, 0.0, 1.0, 0.02)
36         self.connect("value-changed", self.on_value_changed)
37         self.disable_value_notify = False
38
39     def step_up(self):
40         self.set_value(self.get_value() + self.step_increment)
41
42     def step_down(self):
43         self.set_value(self.get_value() - self.step_increment)
44
45     def reset(self):
46         self.set_value(self.default_value)
47
48     def get_value_db(self):
49         return self.db
50
51     def set_value_db(self, db, from_midi = False):
52         self.db = db
53         self.disable_value_notify = True
54         self.set_value(self.scale.db_to_scale(db))
55         self.disable_value_notify = False
56         if not from_midi:
57             self.emit("volume-changed")
58         else:
59             self.emit("volume-changed-from-midi")
60
61     def on_value_changed(self, adjustment):
62         if not self.disable_value_notify:
63             self.db = self.scale.scale_to_db(self.get_value())
64             self.emit("volume-changed")
65
66     def set_scale(self, scale):
67         self.scale = scale
68         self.disable_value_notify = True
69         self.set_value(self.scale.db_to_scale(self.db))
70         self.disable_value_notify = False
71
72 GObject.signal_new("volume-changed", AdjustmentdBFS,
73                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
74
75 GObject.signal_new("volume-changed-from-midi", AdjustmentdBFS,
76                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
77
78 class BalanceAdjustment(Gtk.Adjustment):
79     def __init__(self):
80         Gtk.Adjustment.__init__(self, 0.0, -1.0, 1.0, 0.02)
81         self.connect("value-changed", self.on_value_changed)
82         self.disable_value_notify = False
83
84     def set_balance(self, value, from_midi = False):
85         self.disable_value_notify = True
86         self.set_value(value)
87         self.disable_value_notify = False
88         if not from_midi:
89             self.emit("balance-changed")
90         else:
91             self.emit("balance-changed-from-midi")
92
93     def on_value_changed(self, adjustment):
94         if not self.disable_value_notify:
95             self.emit("balance-changed")
96
97 GObject.signal_new("balance-changed", BalanceAdjustment,
98                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
99
100 GObject.signal_new("balance-changed-from-midi", BalanceAdjustment,
101                    GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION, None, [])
102
103
104 class GtkSlider(Gtk.VScale):
105     def __init__(self, adjustment):
106         Gtk.VScale.__init__(self)#, adjustment)
107         self.adjustment = adjustment
108         self.set_adjustment(adjustment)
109         self.set_draw_value(False)
110         self.set_inverted(True)
111         self.button_down = False
112         self.button_down_y = 0
113         self.button_down_value = 0
114
115         self.connect('button-press-event', self.button_press_event)
116         self.connect('button-release-event', self.button_release_event)
117         self.connect("motion-notify-event", self.motion_notify_event)
118         self.connect("scroll-event", self.scroll_event)
119
120     def button_press_event(self, widget, event):
121         if not event.state & Gdk.ModifierType.CONTROL_MASK and event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
122             self.button_down = True
123             self.button_down_y = event.y
124             self.button_down_value = self.adjustment.get_value()
125             return True
126         if not event.state & Gdk.ModifierType.CONTROL_MASK and event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
127             self.adjustment.set_value(0)
128             return True
129         if event.state & Gdk.ModifierType.CONTROL_MASK and event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
130             self.adjustment.set_value(self.adjustment.scale.db_to_scale(1))
131             return True
132         return False
133
134     def button_release_event(self, widget, event):
135         self.button_down = False
136         return False
137
138     def motion_notify_event(self, widget, event):
139         slider_length = widget.get_allocation().height - widget.get_style_context().get_property('min-height', Gtk.StateFlags.NORMAL)
140         if self.button_down:
141             delta_y = (self.button_down_y - event.y) / slider_length
142             y = self.button_down_value + delta_y
143             if y >= 1:
144                 y = 1
145             elif y <= 0:
146                 y = 0
147             self.adjustment.set_value(y)
148             return True
149
150     def scroll_event(self, widget, event):
151         delta = self.adjustment.step_increment
152         value = self.adjustment.get_value()
153         if event.direction == Gdk.ScrollDirection.UP:
154             y = value + delta
155         elif event.direction == Gdk.ScrollDirection.DOWN:
156             y = value - delta
157         elif event.direction == Gdk.ScrollDirection.SMOOTH:
158             y = value - event.delta_y * delta
159
160         if y >= 1:
161             y = 1
162         elif y <= 0:
163             y = 0
164         self.adjustment.set_value(y)
165         return True
166
167 class CustomSliderWidget(Gtk.DrawingArea):
168     def __init__(self, adjustment):
169         Gtk.DrawingArea.__init__(self)
170
171         self.adjustment = adjustment
172
173         self.connect("draw", self.on_expose)
174         self.connect("size_allocate", self.on_size_allocate)
175         adjustment.connect("value-changed", self.on_value_changed)
176         self.connect("button-press-event", self.on_mouse)
177         self.connect("motion-notify-event", self.on_mouse)
178         self.connect("scroll-event", self.on_scroll)
179         self.set_events(Gdk.EventMask.BUTTON1_MOTION_MASK |
180                 Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
181
182     def on_scroll(self, widget, event):
183         delta = self.adjustment.step_increment
184         value = self.adjustment.get_value()
185         if event.direction == Gdk.ScrollDirection.UP:
186             y = value + delta
187         elif event.direction == Gdk.ScrollDirection.DOWN:
188             y = value - delta
189         if y >= 1:
190             y = 1
191         elif y <= 0:
192             y = 0
193         self.adjustment.set_value(y)
194         return True
195
196     def on_mouse(self, widget, event):
197         if event.type == Gdk.EventType.BUTTON_PRESS:
198             log.debug("Mouse button %u pressed %ux%u", event.button, event.x, event.y)
199             if event.button == 1:
200                 if event.y >= self.slider_rail_up and event.y < self.slider_rail_up + self.slider_rail_height:
201                     self.adjustment.set_value(1 - float(event.y - self.slider_rail_up)/float(self.slider_rail_height))
202         elif event.type == Gdk.EventType.MOTION_NOTIFY:
203             log.debug("Mouse motion %ux%u", event.x, event.y)
204             if event.y < self.slider_rail_up:
205                 y = self.slider_rail_up
206             elif event.y > self.slider_rail_up + self.slider_rail_height:
207                 y = self.slider_rail_up + self.slider_rail_height
208             else:
209                 y = event.y
210             self.adjustment.set_value(1 - float(y - self.slider_rail_up)/float(self.slider_rail_height))
211
212         return False
213
214     def on_value_changed(self, adjustment):
215         self.invalidate_all()
216
217     def on_expose(self, widget, cairo_ctx):
218
219         self.draw(cairo_ctx)
220
221         return False
222
223     def get_preferred_width(self, widget):
224         minimal_width = natural_width = self.width
225         return (minimal_width, natural_width)
226
227     def get_preferred_height(self, widget):
228         requisition = Gtk.Requisition()
229         on_size_request(self, widget, requisition)
230         minimal_height = natural_heigt = requisition.height
231         return (minimal_height, natural_height)
232
233
234     def on_size_allocate(self, widget, allocation):
235         self.width = float(allocation.width)
236         self.height = float(allocation.height)
237         self.font_size = 10
238
239     def on_size_request(self, widget, requisition):
240         requisition.width = 20
241         return
242
243     def invalidate_all(self):
244         if hasattr(self, 'width') and hasattr(self, 'height'):
245             self.queue_draw_area(0, 0, int(self.width), int(self.height))
246
247     def draw(self, cairo_ctx):
248         if self.has_focus():
249             state = Gtk.StateType.PRELIGHT
250         else:
251             state = Gtk.StateType.NORMAL
252
253         #cairo_ctx.rectangle(0, 0, self.width, self.height)
254         #cairo_ctx.set_source_color(self.style.bg[state])
255         #cairo_ctx.fill_preserve()
256         #Gdk.cairo_set_source_color(cairo_ctx,
257         #        self.get_style_context().get_color(state).to_color())
258         #cairo_ctx.stroke()
259
260         slider_knob_width = 37.5 if self.width * 3 / 4 > 37.5 else self.width * 3 / 4
261         slider_knob_height = slider_knob_width * 2
262         slider_knob_height -= slider_knob_height % 2
263         slider_knob_height += 1
264
265         slider_x = self.width/2
266
267         cairo_ctx.set_line_width(1)
268
269         # slider rail
270         Gdk.cairo_set_source_color(cairo_ctx,
271                 self.get_style_context().get_color(state).to_color())
272         self.slider_rail_up = slider_knob_height/2 + (self.width - slider_knob_width)/2
273         self.slider_rail_height = self.height - 2 * self.slider_rail_up
274         cairo_ctx.move_to(slider_x, self.slider_rail_up)
275         cairo_ctx.line_to(slider_x, self.slider_rail_height + self.slider_rail_up)
276         cairo_ctx.stroke()
277
278         # slider knob
279         slider_y = round(self.slider_rail_up + self.slider_rail_height * (1 - self.adjustment.get_value()))
280         lg = cairo.LinearGradient(slider_x -
281                 float(slider_knob_width)/2, slider_y - slider_knob_height/2,
282                 slider_x - float(slider_knob_width)/2, slider_y +
283                 slider_knob_height/2)
284         slider_alpha = 1.0
285         lg.add_color_stop_rgba(0, 0.55, 0.55, 0.55, slider_alpha)
286         lg.add_color_stop_rgba(0.1, 0.65, 0.65, 0.65, slider_alpha)
287         lg.add_color_stop_rgba(0.1, 0.75, 0.75, 0.75, slider_alpha)
288         lg.add_color_stop_rgba(0.125, 0.75, 0.75, 0.75, slider_alpha)
289         lg.add_color_stop_rgba(0.125, 0.15, 0.15, 0.15, slider_alpha)
290         lg.add_color_stop_rgba(0.475, 0.35, 0.35, 0.35, slider_alpha)
291         lg.add_color_stop_rgba(0.475, 0, 0, 0, slider_alpha)
292         lg.add_color_stop_rgba(0.525, 0, 0, 0, slider_alpha)
293         lg.add_color_stop_rgba(0.525, 0.35, 0.35, 0.35, slider_alpha)
294         lg.add_color_stop_rgba(0.875, 0.65, 0.65, 0.65, slider_alpha)
295         lg.add_color_stop_rgba(0.875, 0.75, 0.75, 0.75, slider_alpha)
296         lg.add_color_stop_rgba(0.900, 0.75, 0.75, 0.75, slider_alpha)
297         lg.add_color_stop_rgba(0.900, 0.15, 0.15, 0.15, slider_alpha)
298         lg.add_color_stop_rgba(1.000, 0.10, 0.10, 0.10, slider_alpha)
299         cairo_ctx.rectangle(slider_x - float(slider_knob_width)/2,
300                             slider_y - slider_knob_height/2,
301                             float(slider_knob_width),
302                             slider_knob_height)
303         Gdk.cairo_set_source_color(cairo_ctx,
304                 self.get_style_context().get_background_color(state).to_color())
305         cairo_ctx.fill_preserve()
306         cairo_ctx.set_source(lg)
307         cairo_ctx.fill()