2 volumecontrol.py (a volume control widget)
4 Copyright 2004 Kenneth Hayber <ken@hayber.us>
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; either 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 import rox
, gtk
, gobject
, sys
33 class VolumeControl(gtk
.Frame
):
35 A Class that implements a volume control (stereo or mono) for a sound card
36 mixer. Each instance represents one mixer channel on the sound card.
38 def __init__(self
, channel
, option_mask
, option_value
, show_value
, label
=None, vertical
=True):
40 Create a volume control widget
41 'channel' specifies the audio device mixer channel.
42 'option_mask' configures the widget while 'option_value' sets the actual
43 value of the corresponding mask (e.g. 'option_mask |= _MUTE' shows the mute
44 checkbox while 'option_value |= _MUTE' causes it to be checked by default)
45 'show_value' controls whether the volume text is displayed or not.
46 'label' is the name of the channel (e.g. 'PCM).
47 'vertical' sets the widget's orientation (used for vertical panels)
49 The widget supports two signals 'volume_changed' and 'volume_setting_toggled'.
50 'volume_changed' always sends left and right volume settings regardless of
51 whether the control is locked or mono.
53 'volume_setting_toggled' notifies the parent of changes in the optional checkboxes.
55 gtk
.Frame
.__init
__(self
, label
)
57 self
.rec
= self
.lock
= self
.stereo
= self
.mute
= False
58 if option_mask
& _LOCK
:
60 self
.channel_locked
= option_value
& _LOCK
62 if option_mask
& _REC
:
64 self
.channel_rec
= option_value
& _REC
66 if option_mask
& _MUTE
:
68 self
.channel_muted
= option_value
& _MUTE
70 if option_mask
& _STEREO
:
73 self
.channel
= channel
74 self
.vol_left
= self
.vol_right
= 0
75 self
.set_size_request(-1, 200)
82 self
.volume1
= gtk
.Adjustment(0.0, 0.0, 100.0, 1.0, 10.0, 0.0)
84 self
.volume1
.connect('value_changed', self
.value_changed
,
85 channel
, CHANNEL_LEFT
)
87 self
.volume1
.connect('value_changed', self
.value_changed
,
88 channel
, CHANNEL_MONO
)
91 volume1_control
= gtk
.VScale(self
.volume1
)
92 volume1_control
.set_inverted(True)
94 volume1_control
= gtk
.HScale(self
.volume1
)
95 volume1_control
.set_value_pos(gtk
.POS_RIGHT
)
96 volume1_control
.set_draw_value(show_value
)
97 volume1_control
.set_digits(0)
98 hbox
.pack_start(volume1_control
)
101 self
.volume2
= gtk
.Adjustment(0.0, 0.0, 100.0, 1.0, 10.0, 0.0)
102 self
.volume2
.connect('value_changed', self
.value_changed
,
103 channel
, CHANNEL_RIGHT
)
106 volume2_control
= gtk
.VScale(self
.volume2
)
107 volume2_control
.set_inverted(True)
109 volume2_control
= gtk
.HScale(self
.volume2
)
110 volume2_control
.set_value_pos(gtk
.POS_RIGHT
)
111 volume2_control
.set_draw_value(show_value
)
112 volume2_control
.set_digits(0)
113 hbox
.pack_start(volume2_control
)
116 rec_check
= gtk
.CheckButton(label
=_('Rec.'))
117 rec_check
.set_active(self
.channel_rec
)
118 rec_check
.connect('toggled', self
.check
, channel
, _REC
)
119 vbox
.pack_end(rec_check
, False, False)
120 self
.rec_check
= rec_check
123 mute_check
= gtk
.CheckButton(label
=_('Mute'))
124 mute_check
.set_active(self
.channel_muted
)
125 mute_check
.connect('toggled', self
.check
, channel
, _MUTE
)
126 vbox
.pack_end(mute_check
, False, False)
128 if self
.stereo
and self
.lock
:
129 lock_check
= gtk
.CheckButton(label
=_('Lock'))
130 lock_check
.set_active(self
.channel_locked
)
131 lock_check
.connect('toggled', self
.check
, channel
, _LOCK
)
132 vbox
.pack_end(lock_check
, False, False)
136 self
.control1
= volume1_control
138 self
.control2
= volume2_control
141 def set_level(self
, level
):
143 Allow the volume settings to be passed in from the parent.
144 'level' is a tuple of integers from 0-100 as (left, right).
146 self
.volume1
.set_value(level
[0])
148 self
.volume2
.set_value(level
[1])
150 def set_recsrc(self
, val
):
152 self
.rec_check
.set_active(val
)
158 Return the current widget's volume settings as a tuple of
159 integers from 0-100 as (left, right)
161 return (self
.vol_left
, self
.vol_right
)
163 def value_changed(self
, vol
, channel
, channel_lr
):
165 Track changes in the volume controls and pass them back to the parent
166 via the 'volume_changed' signal.
168 if channel_lr
== CHANNEL_LEFT
:
169 self
.vol_left
= int(vol
.get_value())
170 if self
.lock
and self
.channel_locked
:
171 self
.volume2
.set_value(vol
.get_value())
173 elif channel_lr
== CHANNEL_RIGHT
:
174 self
.vol_right
= int(vol
.get_value())
175 if self
.lock
and self
.channel_locked
:
176 self
.volume1
.set_value(vol
.get_value())
179 self
.vol_left
= self
.vol_right
= int(vol
.get_value())
180 self
.emit("volume_changed", channel
, self
.vol_left
, self
.vol_right
)
183 def show_values(self
, show_value
):
184 self
.control1
.set_draw_value(show_value
)
186 self
.control2
.set_draw_value(show_value
)
189 def check(self
, button
, channel
, id):
191 Process the various checkboxes and signal the parent when they change
192 via the 'volume_setting_changed' signal.
195 self
.channel_locked
= not self
.channel_locked
196 if self
.channel_locked
:
197 avg_vol
= (self
.vol_left
+self
.vol_right
)/2
198 self
.volume1
.set_value(avg_vol
)
199 self
.volume2
.set_value(avg_vol
)
201 self
.channel_muted
= not self
.channel_muted
203 self
.channel_rec
= not self
.channel_rec
204 self
.emit('volume_setting_toggled', channel
, id, button
.get_active())
207 #I need these to be called only once, not each time an instance is created.
208 gobject
.signal_new('volume_changed', VolumeControl
,
209 gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_BOOLEAN
,
210 (gobject
.TYPE_INT
, gobject
.TYPE_INT
, gobject
.TYPE_INT
))
212 gobject
.signal_new('volume_setting_toggled', VolumeControl
,
213 gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_BOOLEAN
,
214 (gobject
.TYPE_INT
, gobject
.TYPE_INT
, gobject
.TYPE_INT
))