1 # This file is part of jack_mixer
3 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
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
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.
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.
21 class AdjustmentdBFS(gtk
.Adjustment
):
22 def __init__(self
, scale
, default_db
):
23 self
.default_value
= scale
.db_to_scale(default_db
)
26 gtk
.Adjustment
.__init
__(self
, self
.default_value
, 0.0, 1.0, 0.02)
27 self
.connect("value-changed", self
.on_value_changed
)
28 self
.disable_value_notify
= False
31 self
.set_value(self
.get_value() + self
.step_increment
)
34 self
.set_value(self
.get_value() - self
.step_increment
)
37 self
.set_value(self
.default_value
)
39 def get_value_db(self
):
42 def set_value_db(self
, db
):
44 self
.disable_value_notify
= True
45 self
.set_value(self
.scale
.db_to_scale(db
))
46 self
.disable_value_notify
= False
47 self
.emit("volume-changed")
49 def on_value_changed(self
, adjustment
):
50 if not self
.disable_value_notify
:
51 self
.db
= self
.scale
.scale_to_db(self
.get_value())
52 self
.emit("volume-changed")
54 def set_scale(self
, scale
):
56 self
.disable_value_notify
= True
57 self
.set_value(self
.scale
.db_to_scale(self
.db
))
58 self
.disable_value_notify
= False
60 gobject
.signal_new("volume-changed", AdjustmentdBFS
,
61 gobject
.SIGNAL_RUN_FIRST | gobject
.SIGNAL_ACTION
, gobject
.TYPE_NONE
, [])
64 class GtkSlider(gtk
.VScale
):
65 def __init__(self
, adjustment
):
66 gtk
.VScale
.__init
__(self
, adjustment
)
67 self
.set_draw_value(False)
68 self
.set_inverted(True)
70 # HACK: we want the behaviour you get with the middle button, so we
71 # mangle the events. Clicking with other buttons moves the slider in
72 # step increments, clicking with the middle button moves the slider
73 # to the location of the click.
74 self
.connect('button-press-event', self
.button_press_event
)
75 self
.connect('button-release-event', self
.button_release_event
)
77 def button_press_event(self
, widget
, event
):
81 def button_release_event(self
, widget
, event
):
86 class CustomSliderWidget(gtk
.DrawingArea
):
87 def __init__(self
, adjustment
):
88 gtk
.DrawingArea
.__init
__(self
)
90 self
.adjustment
= adjustment
92 self
.connect("expose-event", self
.on_expose
)
93 self
.connect("size-request", self
.on_size_request
)
94 self
.connect("size_allocate", self
.on_size_allocate
)
95 adjustment
.connect("value-changed", self
.on_value_changed
)
96 self
.connect("button-press-event", self
.on_mouse
)
97 self
.connect("motion-notify-event", self
.on_mouse
)
98 self
.set_events(gtk
.gdk
.BUTTON1_MOTION_MASK | gtk
.gdk
.BUTTON1_MOTION_MASK | gtk
.gdk
.BUTTON_PRESS_MASK
)
100 def on_mouse(self
, widget
, event
):
101 if event
.type == gtk
.gdk
.BUTTON_PRESS
:
102 #print "mouse button %u pressed %u:%u" % (event.button, event.x, event.y)
103 if event
.button
== 1:
104 if event
.y
>= self
.slider_rail_up
and event
.y
< self
.slider_rail_up
+ self
.slider_rail_height
:
105 self
.adjustment
.set_value(1 - float(event
.y
- self
.slider_rail_up
)/float(self
.slider_rail_height
))
106 elif event
.button
== 2:
107 self
.adjustment
.reset()
108 elif event
.type == gtk
.gdk
.MOTION_NOTIFY
:
109 #print "mouse motion %u:%u" % (event.x, event.y)
110 if event
.y
< self
.slider_rail_up
:
111 y
= self
.slider_rail_up
112 elif event
.y
> self
.slider_rail_up
+ self
.slider_rail_height
:
113 y
= self
.slider_rail_up
+ self
.slider_rail_height
116 self
.adjustment
.set_value(1 - float(y
- self
.slider_rail_up
)/float(self
.slider_rail_height
))
120 def on_value_changed(self
, adjustment
):
121 self
.invalidate_all()
123 def on_expose(self
, widget
, event
):
124 cairo_ctx
= widget
.window
.cairo_create()
126 # set a clip region for the expose event
127 cairo_ctx
.rectangle(event
.area
.x
, event
.area
.y
, event
.area
.width
, event
.area
.height
)
134 def on_size_allocate(self
, widget
, allocation
):
135 #print allocation.x, allocation.y, allocation.width, allocation.height
136 self
.width
= float(allocation
.width
)
137 self
.height
= float(allocation
.height
)
140 def on_size_request(self
, widget
, requisition
):
141 #print "size-request, %u x %u" % (requisition.width, requisition.height)
142 requisition
.width
= 20
145 def invalidate_all(self
):
146 self
.queue_draw_area(0, 0, int(self
.width
), int(self
.height
))
148 def draw(self
, cairo_ctx
):
149 if self
.flags() & gtk
.HAS_FOCUS
:
150 state
= gtk
.STATE_PRELIGHT
152 state
= gtk
.STATE_NORMAL
154 #cairo_ctx.rectangle(0, 0, self.width, self.height)
155 #cairo_ctx.set_source_color(self.style.bg[state])
156 #cairo_ctx.fill_preserve()
157 cairo_ctx
.set_source_color(self
.style
.fg
[state
])
160 slider_knob_width
= self
.width
* 3 / 4
161 slider_knob_height
= self
.width
* 3 / 2
162 slider_knob_height
-= slider_knob_height
% 2
163 slider_knob_height
+= 1
165 slider_x
= self
.width
/2
167 cairo_ctx
.set_line_width(1)
170 cairo_ctx
.set_source_color(self
.style
.dark
[state
])
171 self
.slider_rail_up
= slider_knob_height
/2 + (self
.width
- slider_knob_width
)/2
172 self
.slider_rail_height
= self
.height
- 2 * self
.slider_rail_up
173 cairo_ctx
.move_to(slider_x
, self
.slider_rail_up
)
174 cairo_ctx
.line_to(slider_x
, self
.slider_rail_height
+ self
.slider_rail_up
)
178 slider_y
= round(self
.slider_rail_up
+ self
.slider_rail_height
* (1 - self
.adjustment
.get_value()))
179 cairo_ctx
.rectangle(slider_x
- float(slider_knob_width
)/2,
180 slider_y
- slider_knob_height
/2,
181 float(slider_knob_width
),
183 cairo_ctx
.set_source_color(self
.style
.bg
[state
])
184 cairo_ctx
.fill_preserve()
185 cairo_ctx
.set_source_color(self
.style
.fg
[state
])
188 cairo_ctx
.set_source_color(self
.style
.fg
[state
])
189 for i
in range(int(slider_knob_height
/2))[8:]:
191 correction
= 1.0 + (float(slider_knob_height
)/2.0 - float(i
)) / 10.0
194 w
= float(slider_knob_width
)/2.0 - correction
197 cairo_ctx
.move_to(x1
, y
+0.5)
198 cairo_ctx
.line_to(x2
, y
+0.5)
200 cairo_ctx
.move_to(x1
, y
-0.5)
201 cairo_ctx
.line_to(x2
, y
-0.5)
202 cairo_ctx
.set_line_width(1)
204 # slider knob middle mark
205 cairo_ctx
.move_to(slider_x
- float(slider_knob_width
)/2, slider_y
)
206 cairo_ctx
.line_to(slider_x
+ float(slider_knob_width
)/2, slider_y
)
207 cairo_ctx
.set_line_width(2)