3 # This file is part of jack_mixer
5 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
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.
23 class adjustment_dBFS(gtk
.Adjustment
):
24 def __init__(self
, scale
, default_db
):
25 self
.default_value
= scale
.db_to_scale(default_db
)
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
33 self
.set_value(self
.get_value() + self
.step_increment
)
36 self
.set_value(self
.get_value() - self
.step_increment
)
39 self
.set_value(self
.default_value
)
41 def get_value_db(self
):
44 def set_value_db(self
, 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
):
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)
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
94 self
.adjustment
.set_value(1 - float(y
- self
.slider_rail_up
)/float(self
.slider_rail_height
))
98 def on_value_changed(self
, adjustment
):
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
)
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
)
118 def on_size_request(self
, widget
, requisition
):
119 #print "size-request, %u x %u" % (requisition.width, requisition.height)
120 requisition
.width
= 20
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
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
])
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)
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
)
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
])
162 cairo_ctx
.set_source_color(self
.style
.fg
[state
])
163 for i
in range(int(slider_knob_height
/2)):
165 correction
= 1.0 + (float(slider_knob_height
)/2.0 - float(i
)) / 10.0
167 w
= float(slider_knob_width
)/2.0 - correction
170 cairo_ctx
.move_to(x1
, y
)
171 cairo_ctx
.line_to(x2
, y
)
173 cairo_ctx
.move_to(x1
, y
)
174 cairo_ctx
.line_to(x2
, y
)
175 cairo_ctx
.set_line_width(1)
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)