Browse Source

mute button, combo box change changes default in pulse, event handling

main
Stefan Naumann 7 months ago
parent
commit
59c2dd2b5b
  1. 120
      main.py
  2. 100
      view.glade

120
main.py

@ -12,6 +12,9 @@ pulse = pulsectl.Pulse("PiPulse")
import threading
class CannotFindError ( Exception ):
pass
class MainWindow ( object ):
def __init__ ( self, gladeFile ):
self.builder = Gtk.Builder()
@ -23,6 +26,8 @@ class MainWindow ( object ):
self.default_sink = ""
self.default_source = ""
self.actions = []
self.MainWindow = self.builder.get_object ( "MainWindow" );
self.SourceImg = self.builder.get_object ( "InputImg" )
@ -30,17 +35,45 @@ class MainWindow ( object ):
self.SourceComboBox = self.builder.get_object ( "InputComboBox" );
self.SinkComboBox = self.builder.get_object ( "OutputComboBox" );
self.SourceComboBox.set_wrap_width(1)
self.SinkComboBox.set_wrap_width(1)
self.SourceDefault = self.builder.get_object ("InputDefault" )
self.SinkDefault = self.builder.get_object ("OutputDefault" )
self.SinkToggle = self.builder.get_object ( "OutputToggle" )
self.SourceToggle = self.builder.get_object ( "InputToggle" )
self.MainWindow.connect ("destroy", self.Destroy )
self.MainWindow.connect ("window-state-event", self.WindowStateTrigger )
self.SinkToggleSignal = self.SinkToggle.connect ("clicked", self.Mute, "sink" )
self.SourceToggleSignal = self.SourceToggle.connect ("clicked", self.Mute, "source" )
self.SinkChangedSignal = self.SinkComboBox.connect ("changed", self.SetDefaultThing, "sink" )
self.SourceChangedSignal = self.SourceComboBox.connect ("changed", self.SetDefaultThing, "source" )
self.waiter = threading.Thread ( target = self.WaitForEvents )
self.waiter.start()
self.MainWindow.set_title ( "PiPulse" )
def Mute ( self, w, d=None ):
if d == "sink":
self.actions += ["mute_sink"]
elif d=="source":
self.actions += ["mute_source"]
else:
return
pulse.event_listen_stop();
def SetDefaultThing ( self, w, d=None ):
if d == "sink":
self.actions += ["default_sink"]
elif d == "source":
self.actions += ["default_source"]
else:
return
print ("DefaultTrigger")
pulse.event_listen_stop()
def WaitForEvents ( self ):
while self.alive:
@ -49,53 +82,128 @@ class MainWindow ( object ):
pulse.event_callback_set( self.EvalEvents )
pulse.event_listen(timeout=10)
def Default ( self, l, default, attr="name" ):
for li in l:
if getattr(li, attr) == default:
return li
raise CannotFindError
def UpdateInternal ( self ):
self.sources = pulse.source_list()
self.sinks = pulse.sink_list()
self.default_source = pulse.server_info().default_source_name
self.default_sink = pulse.server_info().default_sink_name
actions = self.actions
for action in actions:
if action == "mute_sink":
try:
d = self.Default ( self.sinks, self.default_sink );
if d.mute == 0:
pulse.mute ( d, True );
else:
pulse.mute ( d, False );
except CannotFindError:
print ( "was not able to find default sink")
elif action == "mute_source":
try:
d = self.Default ( self.sources, self.default_source );
if d.mute == 0:
pulse.mute ( d, True );
else:
pulse.mute ( d, False );
except CannotFindError:
print ( "was not able to find default source")
elif action == "default_sink":
x = self.SinkComboBox.get_active_text()
try:
d = self.Default ( self.sinks, x, "description" )
pulse.default_set ( d )
except CannotFindError:
print ("was not able to find the selected sink")
elif action == "default_source":
x = self.SourceComboBox.get_active_text()
try:
d = self.Default ( self.sources, x, "description" )
pulse.default_set ( d )
except CannotFindError:
print ("was not able to find the selected sink")
self.actions.clear()
self.sources = pulse.source_list()
self.sinks = pulse.sink_list()
self.default_source = pulse.server_info().default_source_name
self.default_sink = pulse.server_info().default_sink_name
GLib.idle_add ( self.Update );
def EvalEvents ( self, ev ):
print ( ev )
self.cs = True
raise pulsectl.PulseLoopStop
def Update ( self, w=None, d=None ):
self.UpdateSinks()
self.UpdateSources()
def SetMute ( self, img, mute, mode ):
def SetMute ( self, img, mute, mode, toggle ):
if mode != "sink" and mode != "source":
return
if mode == "sink":
toggle.disconnect ( self.SinkToggleSignal )
else:
toggle.disconnect ( self.SourceToggleSignal )
muted = "muted"
if mute == 0:
muted = "unmuted"
toggle.set_active(False)
else:
muted = "muted"
toggle.set_active(True)
if mode == "sink":
self.SinkToggleSignal = toggle.connect ( "clicked", self.Mute, mode )
else:
self.SourceToggleSignal = toggle.connect ( "clicked", self.Mute, mode )
pic = os.path.dirname(__file__) + "/symbol-" + mode + "-" + muted + ".svg"
img.set_from_file ( pic );
def UpdateSinks ( self ):
self.SinkComboBox.disconnect ( self.SinkChangedSignal )
self.SinkComboBox.remove_all()
i = 0
index = 0
for sink in self.sinks:
if sink.name == self.default_sink:
self.SinkDefault.set_text ( sink.description )
self.SetMute ( self.SinkImg, sink.mute, "sink" )
self.SetMute ( self.SinkImg, sink.mute, "sink", self.SinkToggle )
index = i
i+=1
self.SinkComboBox.append_text ( sink.description )
self.SinkComboBox.set_active(index)
self.SinkChangedSignal = self.SinkComboBox.connect ( "changed", self.SetDefaultThing, "sink" )
def UpdateSources ( self ):
print ( self.sources );
self.SourceComboBox.disconnect ( self.SourceChangedSignal )
self.SourceComboBox.remove_all()
i = 0
index = 0
for source in self.sources:
if source.name == self.default_source:
self.SourceDefault.set_text ( source.description )
self.SetMute ( self.SourceImg, source.mute, "source" )
self.SetMute ( self.SourceImg, source.mute, "source", self.SourceToggle )
index = i
i+=1
self.SourceComboBox.append_text ( source.description )
self.SourceComboBox.set_active(index)
self.SourceChangedSignal = self.SourceComboBox.connect ( "changed", self.SetDefaultThing, "source" )
## show the window
def Show ( self ):

100
view.glade

@ -2,6 +2,16 @@
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkImage" id="InputImg">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">cancel</property>
</object>
<object class="GtkImage" id="OutputImg">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">cancel</property>
</object>
<object class="GtkWindow" id="MainWindow">
<property name="can-focus">False</property>
<child>
@ -14,7 +24,10 @@
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Output</property>
<property name="label" translatable="yes">Sink</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
@ -25,7 +38,10 @@
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Input</property>
<property name="label" translatable="yes">Source</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left-attach">1</property>
@ -33,60 +49,50 @@
</packing>
</child>
<child>
<object class="GtkImage" id="OutputImg">
<object class="GtkComboBoxText" id="InputComboBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="icon-name">checkbox</property>
<property name="icon_size">3</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="popup-fixed-width">False</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkImage" id="InputImg">
<object class="GtkLabel" id="OutputDefault">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="icon-name">error</property>
<property name="icon_size">3</property>
<property name="label" translatable="yes">label</property>
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="OutputComboBox">
<property name="width-request">300</property>
<object class="GtkLabel" id="InputDefault">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">5</property>
<property name="margin-end">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="popup-fixed-width">False</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">label</property>
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="InputComboBox">
<property name="width-request">300</property>
<object class="GtkComboBoxText" id="OutputComboBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">5</property>
@ -96,34 +102,38 @@
<property name="popup-fixed-width">False</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="OutputDefault">
<object class="GtkToggleButton" id="OutputToggle">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
<property name="vexpand">True</property>
<property name="image">OutputImg</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="InputDefault">
<object class="GtkToggleButton" id="InputToggle">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">label</property>
<property name="wrap">True</property>
<property name="vexpand">True</property>
<property name="image">InputImg</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>

Loading…
Cancel
Save