Move channel buffers from stack to structs so theyt can be reused when mixing with...
[jack_mixer.git] / slider.py
blobb7417182a3fe638ab9fa802bf645975697a24a9f
1 #!/usr/bin/env python
3 # This file is part of jack_mixer
5 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; version 2 of the License
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 import gtk
21 import gobject
23 class adjustment_dBFS(gtk.Adjustment):
24 def __init__(self, scale, default_db):
25 self.default_value = scale.db_to_scale(default_db)
26 self.db = default_db
27 self.scale = scale
28 gtk.Adjustment.__init__(self, self.default_value, 0.0, 1.0, 0.02)
29 self.connect("value-changed", self.on_value_changed)
30 self.disable_value_notify = False
32 def step_up(self):
33 self.set_value(self.get_value() + self.step_increment)
35 def step_down(self):
36 self.set_value(self.get_value() - self.step_increment)
38 def reset(self):
39 self.set_value(self.default_value)
41 def get_value_db(self):
42 return self.db
44 def set_value_db(self, db):
45 self.db = db
46 self.disable_value_notify = True
47 self.set_value(self.scale.db_to_scale(db))
48 self.disable_value_notify = False
49 self.emit("volume-changed")
51 def on_value_changed(self, adjustment):
52 if not self.disable_value_notify:
53 self.db = self.scale.scale_to_db(self.get_value())
54 self.emit("volume-changed")
56 def set_scale(self, scale):
57 self.scale = scale
58 self.disable_value_notify = True
59 self.set_value(self.scale.db_to_scale(self.db))
60 self.disable_value_notify = False
62 gobject.signal_new("volume-changed", adjustment_dBFS, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [])
64 class widget(gtk.DrawingArea):
65 def __init__(self, adjustment):
66 gtk.DrawingArea.__init__(self)
68 self.adjustment = adjustment
70 self.connect("expose-event", self.on_expose)
71 self.connect("size-request", self.on_size_request)
72 self.connect("size_allocate", self.on_size_allocate)
73 adjustment.connect("value-changed", self.on_value_changed)
74 self.connect("button-press-event", self.on_mouse)
75 self.connect("motion-notify-event", self.on_mouse)
76 self.set_events(gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK)
78 def on_mouse(self, widget, event):
79 if event.type == gtk.gdk.BUTTON_PRESS:
80 #print "mouse button %u pressed %u:%u" % (event.button, event.x, event.y)
81 if event.button == 1:
82 if event.y >= self.slider_rail_up and event.y < self.slider_rail_up + self.slider_rail_height:
83 self.adjustment.set_value(1 - float(event.y - self.slider_rail_up)/float(self.slider_rail_height))
84 elif event.button == 2:
85 self.adjustment.reset()
86 elif event.type == gtk.gdk.MOTION_NOTIFY:
87 #print "mouse motion %u:%u" % (event.x, event.y)
88 if event.y < self.slider_rail_up:
89 y = self.slider_rail_up
90 elif event.y > self.slider_rail_up + self.slider_rail_height:
91 y = self.slider_rail_up + self.slider_rail_height
92 else:
93 y = event.y
94 self.adjustment.set_value(1 - float(y - self.slider_rail_up)/float(self.slider_rail_height))
96 return False
98 def on_value_changed(self, adjustment):
99 self.invalidate_all()
101 def on_expose(self, widget, event):
102 cairo_ctx = widget.window.cairo_create()
104 # set a clip region for the expose event
105 cairo_ctx.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
106 cairo_ctx.clip()
108 self.draw(cairo_ctx)
110 return False
112 def on_size_allocate(self, widget, allocation):
113 #print allocation.x, allocation.y, allocation.width, allocation.height
114 self.width = float(allocation.width)
115 self.height = float(allocation.height)
116 self.font_size = 10
118 def on_size_request(self, widget, requisition):
119 #print "size-request, %u x %u" % (requisition.width, requisition.height)
120 requisition.width = 20
121 return
123 def invalidate_all(self):
124 self.queue_draw_area(0, 0, int(self.width), int(self.height))
126 def draw(self, cairo_ctx):
127 if self.flags() & gtk.HAS_FOCUS:
128 state = gtk.STATE_PRELIGHT
129 else:
130 state = gtk.STATE_NORMAL
132 #cairo_ctx.rectangle(0, 0, self.width, self.height)
133 #cairo_ctx.set_source_color(self.style.bg[state])
134 #cairo_ctx.fill_preserve()
135 cairo_ctx.set_source_color(self.style.fg[state])
136 #cairo_ctx.stroke()
138 slider_knob_width = self.width * 3 / 4
139 slider_knob_height = self.width * 3 / 2
140 slider_knob_height -= slider_knob_height % 2
142 slider_x = self.width/2
144 cairo_ctx.set_line_width(1)
146 # slider rail
147 cairo_ctx.set_source_color(self.style.dark[state])
148 self.slider_rail_up = slider_knob_height/2 + (self.width - slider_knob_width)/2
149 self.slider_rail_height = self.height - 2 * self.slider_rail_up
150 cairo_ctx.move_to(slider_x, self.slider_rail_up)
151 cairo_ctx.line_to(slider_x, self.slider_rail_height + self.slider_rail_up)
152 cairo_ctx.stroke()
154 # slider knob
155 slider_y = round(self.slider_rail_up + self.slider_rail_height * (1 - self.adjustment.get_value()))
156 cairo_ctx.rectangle(slider_x - float(slider_knob_width)/2, slider_y - slider_knob_height/2, float(slider_knob_width), slider_knob_height)
157 cairo_ctx.set_source_color(self.style.bg[state])
158 cairo_ctx.fill_preserve()
159 cairo_ctx.set_source_color(self.style.fg[state])
160 cairo_ctx.stroke()
161 # slider knob marks
162 cairo_ctx.set_source_color(self.style.fg[state])
163 for i in range(int(slider_knob_height/2)):
164 if i % 4 == 0:
165 correction = 1.0 + (float(slider_knob_height)/2.0 - float(i)) / 10.0
166 y = slider_y - i
167 w = float(slider_knob_width)/2.0 - correction
168 x1 = slider_x - w
169 x2 = slider_x + w
170 cairo_ctx.move_to(x1, y)
171 cairo_ctx.line_to(x2, y)
172 y = slider_y + i
173 cairo_ctx.move_to(x1, y)
174 cairo_ctx.line_to(x2, y)
175 cairo_ctx.set_line_width(1)
176 cairo_ctx.stroke()
177 # slider knob middle mark
178 cairo_ctx.move_to(slider_x - float(slider_knob_width)/2, slider_y)
179 cairo_ctx.line_to(slider_x + float(slider_knob_width)/2, slider_y)
180 cairo_ctx.set_line_width(2)
181 cairo_ctx.stroke()