Package flumotion :: Package component :: Package effects :: Package volume :: Module admin_gtk
[hide private]

Source Code for Module flumotion.component.effects.volume.admin_gtk

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  from gettext import gettext as _ 
 19   
 20  import gtk 
 21  import os 
 22  import math 
 23   
 24  # import custom glade handler 
 25  from flumotion.ui import glade 
 26  from flumotion.ui.fvumeter import FVUMeter 
 27  from flumotion.component.base.effectsnode import EffectAdminGtkNode 
 28   
 29  __version__ = "$Rev$" 
 30   
 31   
32 -def clamp(x, min, max):
33 if x < min: 34 return min 35 elif x > max: 36 return max 37 return x
38 39
40 -class VolumeAdminGtkNode(EffectAdminGtkNode):
41 logCategory = 'volume' 42 gladeFile = os.path.join('flumotion', 'component', 'effects', 43 'volume', 'volume.glade') 44 45 uiStateHandlers = None 46
47 - def haveWidgetTree(self):
48 self.widget = self.wtree.get_widget('volume-widget') 49 self.level_widgets = [] 50 self._volume_set_label = self.wtree.get_widget('volume-set-label') 51 self._volume_set_label.set_text('0') 52 self.shown = False 53 54 # now do the callbacks for the volume setting 55 self._hscale = self.wtree.get_widget('volume-set-hscale') 56 self._scale_changed_id = self._hscale.connect('value_changed', 57 self.cb_volume_set) 58 self._hscale.set_sensitive(False) 59 # callback for checkbutton 60 check = self.wtree.get_widget('volume-set-check') 61 check.set_sensitive(False) 62 check.connect('toggled', self._check_toggled_cb) 63 changeLabel = self.wtree.get_widget('volume-change-label') 64 changeLabel.set_sensitive(False)
65
66 - def setUIState(self, state):
67 EffectAdminGtkNode.setUIState(self, state) 68 if not self.uiStateHandlers: 69 self.uiStateHandlers = {'volume-volume': self.volumeSet, 70 'volume-peak': self.peakSet, 71 'volume-decay': self.decaySet} 72 for k, handler in self.uiStateHandlers.items(): 73 handler(state.get(k)) 74 # volume-allow-increase is static for lifetime of component 75 # for soundcard it is false, for others that have a gst volume 76 # element it is true 77 if state.get("volume-allow-increase"): 78 check = self.wtree.get_widget('volume-set-check') 79 if check is not None: 80 check.set_sensitive(True) 81 if state.get("volume-allow-set"): 82 self._hscale.set_sensitive(True) 83 changeLabel = self.wtree.get_widget('volume-change-label') 84 if changeLabel is not None: 85 changeLabel.set_sensitive(True)
86
87 - def _createEnoughLevelWidgets(self, numchannels):
88 """ 89 This method dynamically creates labels and level meters for channels 90 that currently do not have level meters. The glade file no longer 91 contains the labels or the level meters. Also the table size in the 92 glade file is set to 50 and the widgets inside the table that are 93 statically configured have a bottom y of 50 allowing about 23 channels 94 in the audio. 95 96 @param numchannels: total number of channels there is volume data for 97 """ 98 if numchannels > len(self.level_widgets): 99 totalLevelWidgets = len(self.level_widgets) 100 for chan in range(totalLevelWidgets, numchannels): 101 levelWidget = FVUMeter() 102 levelLabel = gtk.Label() 103 if chan == 0 and numchannels > 1: 104 levelLabel.set_text(_("Left channel level:")) 105 elif numchannels == 1: 106 levelLabel.set_text(_("Mono channel level:")) 107 elif chan == 1: 108 levelLabel.set_text(_("Right channel level:")) 109 else: 110 levelLabel.set_text(_("Channel %d level:") % chan) 111 levelLabel.set_property("xpad", 0) 112 levelLabel.set_property("ypad", 0) 113 levelLabel.set_property("xalign", 0) 114 levelLabel.set_property("yalign", 0.5) 115 levelLabel.set_justify(gtk.JUSTIFY_LEFT) 116 self.widget.attach(levelLabel, 0, 1, chan * 2, chan * 2 + 1, 117 xoptions=gtk.FILL, yoptions=0, xpadding=3, ypadding=3) 118 self.widget.attach(levelWidget, 0, 1, chan * 2 + 1, 119 chan * 2 + 2, yoptions=gtk.FILL, 120 xpadding=6, ypadding=3) 121 levelLabel.show() 122 levelWidget.show() 123 self.level_widgets.append(levelWidget)
124
125 - def peakSet(self, peak):
126 if len(peak) > len(self.level_widgets): 127 self._createEnoughLevelWidgets(len(peak)) 128 for i in range(0, len(peak)): 129 self.level_widgets[i].set_property('peak', 130 clamp(peak[i], -90.0, 0.0))
131
132 - def decaySet(self, decay):
133 if len(decay) > len(self.level_widgets): 134 self._createEnoughLevelWidgets(len(decay)) 135 for i in range(0, len(decay)): 136 self.level_widgets[i].set_property('decay', 137 clamp(decay[i], -90.0, 0.0))
138 139 # when volume has been set by another admin client 140
141 - def volumeSet(self, volume):
142 self._hscale.handler_block(self._scale_changed_id) 143 144 # Ensure that the scale has an adjustment. 145 # This is not a proper solution to a problem that 146 # can be when switching components, but it avoids an 147 # unexpected segfault in set_value which expects 148 # range->adjustment to be non-NULL 149 self._hscale.get_adjustment() 150 151 self._hscale.set_value(volume) 152 self.debug("volume: %f", volume) 153 dB = "- inf" 154 if volume: 155 dB = "%2.2f" % (20.0 * math.log10(volume)) 156 self._volume_set_label.set_text(dB) 157 self._hscale.handler_unblock(self._scale_changed_id)
158
159 - def stateSet(self, state, key, value):
160 handler = self.uiStateHandlers.get(key, None) 161 if handler: 162 handler(value)
163 164 # run when the scale is moved by user 165
166 - def cb_volume_set(self, widget):
167 # do something 168 volume = self._hscale.get_value() 169 #self.volumeSet(volume) 170 d = self.effectCallRemote("setVolume", volume) 171 d.addErrback(self.setVolumeErrback)
172
173 - def setVolumeErrback(self, failure):
174 self.warning("Failure %s setting volume: %s" % ( 175 failure.type, failure.getErrorMessage())) 176 return None
177
178 - def _update_volume_label(self):
179 # update the volume label's dB value 180 pass
181 182 # when the "increase volume" checkbutton is toggled 183
184 - def _check_toggled_cb(self, widget):
185 checked = widget.get_property('active') 186 self.debug('checkbutton toggled; now %r' % checked) 187 value = self._hscale.get_value() 188 if checked: 189 self._hscale.set_range(0.0, 4.0) 190 else: 191 if value > 1.0: 192 value = 1.0 193 self._hscale.set_range(0.0, 1.0) 194 self.volumeSet(value)
195