Browse Source

semi-working prototype. needs more work with the event listening on pulse events

main
Stefan Naumann 7 months ago
parent
commit
81d56cec62
  1. 113
      main.py
  2. 83
      symbol-sink-muted.svg
  3. 75
      symbol-sink-unmuted.svg
  4. 74
      symbol-source-muted.svg
  5. 64
      symbol-source-unmuted.svg
  6. 125
      view.glade

113
main.py

@ -0,0 +1,113 @@
#!/usr/bin/python3
import os
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib
import glib
import pulsectl
pulse = pulsectl.Pulse("PiPulse")
import threading
class MainWindow ( object ):
def __init__ ( self, gladeFile ):
self.builder = Gtk.Builder()
self.builder.add_from_file ( gladeFile );
self.MainWindow = self.builder.get_object ( "MainWindow" );
self.SourceImg = self.builder.get_object ( "InputImg" )
self.SinkImg = self.builder.get_object ( "OutputImg" )
self.SourceComboBox = self.builder.get_object ( "InputComboBox" );
self.SinkComboBox = self.builder.get_object ( "OutputComboBox" );
self.SourceDefault = self.builder.get_object ("InputDefault" )
self.SinkDefault = self.builder.get_object ("OutputDefault" )
self.MainWindow.connect ("destroy", self.Destroy )
self.MainWindow.connect ("window-state-event", self.WindowStateTrigger )
self.Update()
self.waiter = threading.Thread ( target = self.WaitForEvents )
self.waiter.start()
self.cs = False
self.MainWindow.set_title ( "PiPulse" )
def WaitForEvents ( self ):
while 1:
if self.cs == True:
pass
pulse.event_mask_set('sink','source')
pulse.event_callback_set( self.EvalEvents )
pulse.event_listen(timeout=10)
def EvalEvents ( self, ev ):
print ( ev )
GLib.idle_add ( self.Update );
self.cs = True
raise pulsectl.PulseLoopStop
def Update ( self, w=None, d=None ):
self.UpdateSinks()
self.UpdateSources()
def SetMute ( self, img, mute, mode ):
if mode != "sink" and mode != "source":
return
muted = "muted"
if mute == 0:
muted = "unmuted"
else:
muted = "muted"
pic = os.path.dirname(__file__) + "/symbol-" + mode + "-" + muted + ".svg"
img.set_from_file ( pic );
def UpdateSinks ( self ):
self.cs = True
pulse.event_listen_stop()
default = pulse.server_info().default_sink_name
self.SinkComboBox.remove_all()
for sink in pulse.sink_list():
if sink.name == default:
self.SinkDefault.set_text ( sink.description )
self.SetMute ( self.SinkImg, sink.mute, "sink" )
self.SinkComboBox.append_text ( sink.description )
self.cs = False
def UpdateSources ( self ):
self.cs = True
pulse.event_listen_stop()
default = pulse.server_info().default_source_name
self.SourceComboBox.remove_all()
for source in pulse.source_list():
if source.name == default:
self.SourceDefault.set_text ( source.description )
self.SetMute ( self.SourceImg, source.mute, "source" )
self.SourceComboBox.append_text ( source.description )
self.cs = False
## show the window
def Show ( self ):
self.MainWindow.show_all ()
def Destroy ( self, w, d=None ):
pulse.close()
Gtk.main_quit()
def WindowStateTrigger ( self, w, d=None ):
pass
gladefile = os.path.dirname(__file__) + "/view.glade"
hwnd = MainWindow ( gladefile )
hwnd.Show()
Gtk.main()

83
symbol-sink-muted.svg

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 128 128"
version="1.1"
viewBox="0 0 180.88458 129"
xml:space="preserve"
id="svg14"
sodipodi:docname="symbol-sink-muted.svg"
width="180.88458"
height="129"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"><metadata
id="metadata20"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs18" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1440"
id="namedview16"
showgrid="false"
fit-margin-top="10"
fit-margin-right="10"
fit-margin-bottom="10"
fit-margin-left="10"
inkscape:zoom="3.8172718"
inkscape:cx="63.294592"
inkscape:cy="105.69336"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg14" />
<g
fill="#231F20"
id="g12"
style="fill:#c0392b;fill-opacity:1"
transform="translate(24.139124,0.5)">
<polygon
points="61,9.5 25,36 25,92 61,118.5 "
id="polygon2"
style="fill:#c0392b;fill-opacity:1" />
<rect
x="1"
y="36"
width="17"
height="56"
id="rect4"
style="fill:#c0392b;fill-opacity:1" />
<path
d="m 68.923,48.729 c -1.171,1.172 -1.171,3.071 0.001,4.243 2.946,2.946 4.569,6.862 4.569,11.028 0,4.166 -1.623,8.083 -4.569,11.03 -1.172,1.171 -1.172,3.071 0,4.242 0.586,0.586 1.354,0.879 2.121,0.879 0.767,0 1.535,-0.293 2.121,-0.879 4.08,-4.08 6.327,-9.504 6.327,-15.272 0,-5.769 -2.247,-11.192 -6.327,-15.271 -1.172,-1.171 -3.071,-1.172 -4.243,0 z"
id="path6"
style="fill:#c0392b;fill-opacity:1" />
<path
d="m 89.245,32.653 c -1.171,-1.172 -3.069,-1.173 -4.242,-0.002 -1.172,1.171 -1.173,3.07 -0.002,4.243 7.237,7.246 11.224,16.872 11.224,27.106 0,10.234 -3.986,19.86 -11.224,27.105 -1.171,1.172 -1.17,3.071 0.002,4.242 0.586,0.586 1.353,0.878 2.12,0.878 0.769,0 1.536,-0.293 2.122,-0.88 C 97.615,86.968 102.224,75.836 102.224,64 102.225,52.165 97.615,41.032 89.245,32.653 Z"
id="path8"
style="fill:#c0392b;fill-opacity:1" />
<path
d="m 105.31,16.582 c -1.172,-1.171 -3.072,-1.171 -4.242,0 -1.172,1.171 -1.172,3.071 0,4.243 11.533,11.532 17.884,26.865 17.884,43.175 0,16.307 -6.352,31.641 -17.885,43.176 -1.172,1.172 -1.172,3.071 0,4.242 0.586,0.586 1.354,0.879 2.121,0.879 0.767,0 1.536,-0.293 2.121,-0.879 12.667,-12.669 19.643,-29.509 19.643,-47.418 0,-17.913 -6.976,-34.753 -19.642,-47.418 z"
id="path10"
style="fill:#c0392b;fill-opacity:1" />
</g>
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.3378;stroke-opacity:0.994703"
id="rect845"
width="178.6622"
height="8.6622086"
x="-135.74475"
y="-104.82489"
ry="0"
transform="rotate(150)" /></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

75
symbol-sink-unmuted.svg

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 128 128"
version="1.1"
viewBox="0 0 180.88458 129"
xml:space="preserve"
id="svg14"
sodipodi:docname="symbol-sink-unmuted.svg"
width="180.88458"
height="129"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"><metadata
id="metadata20"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs18" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1440"
id="namedview16"
showgrid="false"
fit-margin-top="10"
fit-margin-right="10"
fit-margin-bottom="10"
fit-margin-left="10"
inkscape:zoom="3.8172718"
inkscape:cx="63.294592"
inkscape:cy="105.69336"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg14" />
<g
fill="#231F20"
id="g12"
style="fill:#27ae60;fill-opacity:1"
transform="translate(24.139124,0.5)">
<polygon
points="61,9.5 25,36 25,92 61,118.5 "
id="polygon2"
style="fill:#27ae60;fill-opacity:1" />
<rect
x="1"
y="36"
width="17"
height="56"
id="rect4"
style="fill:#27ae60;fill-opacity:1" />
<path
d="m 68.923,48.729 c -1.171,1.172 -1.171,3.071 0.001,4.243 2.946,2.946 4.569,6.862 4.569,11.028 0,4.166 -1.623,8.083 -4.569,11.03 -1.172,1.171 -1.172,3.071 0,4.242 0.586,0.586 1.354,0.879 2.121,0.879 0.767,0 1.535,-0.293 2.121,-0.879 4.08,-4.08 6.327,-9.504 6.327,-15.272 0,-5.769 -2.247,-11.192 -6.327,-15.271 -1.172,-1.171 -3.071,-1.172 -4.243,0 z"
id="path6"
style="fill:#27ae60;fill-opacity:1" />
<path
d="m 89.245,32.653 c -1.171,-1.172 -3.069,-1.173 -4.242,-0.002 -1.172,1.171 -1.173,3.07 -0.002,4.243 7.237,7.246 11.224,16.872 11.224,27.106 0,10.234 -3.986,19.86 -11.224,27.105 -1.171,1.172 -1.17,3.071 0.002,4.242 0.586,0.586 1.353,0.878 2.12,0.878 0.769,0 1.536,-0.293 2.122,-0.88 C 97.615,86.968 102.224,75.836 102.224,64 102.225,52.165 97.615,41.032 89.245,32.653 Z"
id="path8"
style="fill:#27ae60;fill-opacity:1" />
<path
d="m 105.31,16.582 c -1.172,-1.171 -3.072,-1.171 -4.242,0 -1.172,1.171 -1.172,3.071 0,4.243 11.533,11.532 17.884,26.865 17.884,43.175 0,16.307 -6.352,31.641 -17.885,43.176 -1.172,1.172 -1.172,3.071 0,4.242 0.586,0.586 1.354,0.879 2.121,0.879 0.767,0 1.536,-0.293 2.121,-0.879 12.667,-12.669 19.643,-29.509 19.643,-47.418 0,-17.913 -6.976,-34.753 -19.642,-47.418 z"
id="path10"
style="fill:#27ae60;fill-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

74
symbol-source-muted.svg

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 60 100"
viewBox="0 0 182.2506 120.21677"
version="1.1"
id="svg6"
sodipodi:docname="symbol-source-muted.svg"
width="182.2506"
height="120.21677"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1440"
id="namedview8"
showgrid="false"
fit-margin-top="10"
fit-margin-right="10"
fit-margin-bottom="10"
fit-margin-left="10"
inkscape:zoom="4.14"
inkscape:cx="203.19253"
inkscape:cy="101.61788"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
d="m 111.56916,48 v 14 c 0,9.757 -8.242,18 -18.000002,18 h -8 c -9.757,0 -18,-8.243 -18,-18 V 48 h -8 v 14 c 0,14.094 11.906,26 26,26 v 14 h -17 v 8 h 42.000002 v -8 H 93.569158 V 88 C 107.66316,88 119.56916,76.094 119.56916,62 V 48 Z"
id="path2"
style="fill:#c0392b;fill-opacity:1;stroke:none" />
<path
d="m 85.569158,74 h 8 c 5.714,0 10.788002,-4.483 11.804002,-10 H 93.486158 V 60 H 105.56916 V 56 H 93.486158 V 52 H 105.56916 V 48 H 93.486158 V 44 H 105.56916 V 40 H 93.486158 V 36 H 105.56916 V 32 H 93.486158 V 28 H 105.56916 V 24 H 93.486158 v -4 h 11.887002 c -1.016,-5.517 -6.090002,-10 -11.804002,-10 h -8 c -6.393,0 -12,5.607 -12,12 v 40 c 0,6.393 5.607,12 12,12 z"
id="path4"
style="fill:#c0392b;fill-opacity:1;stroke:none" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:0.994703"
id="rect837"
width="180"
height="10"
x="-41.184986"
y="92.700516"
ry="0"
rx="0"
transform="rotate(-30)" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

64
symbol-source-unmuted.svg

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
enable-background="new 0 0 60 100"
viewBox="0 0 182.2506 120.21677"
version="1.1"
id="svg6"
sodipodi:docname="symbol-source-unmuted.svg"
width="182.2506"
height="120.21677"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1440"
id="namedview8"
showgrid="false"
fit-margin-top="10"
fit-margin-right="10"
fit-margin-bottom="10"
fit-margin-left="10"
inkscape:zoom="4.14"
inkscape:cx="203.19253"
inkscape:cy="101.61788"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
d="m 111.56916,48 v 14 c 0,9.757 -8.242,18 -18.000002,18 h -8 c -9.757,0 -18,-8.243 -18,-18 V 48 h -8 v 14 c 0,14.094 11.906,26 26,26 v 14 h -17 v 8 h 42.000002 v -8 H 93.569158 V 88 C 107.66316,88 119.56916,76.094 119.56916,62 V 48 Z"
id="path2"
style="fill:#27ae60;fill-opacity:1;stroke:none" />
<path
d="m 85.569158,74 h 8 c 5.714,0 10.788002,-4.483 11.804002,-10 H 93.486158 V 60 H 105.56916 V 56 H 93.486158 V 52 H 105.56916 V 48 H 93.486158 V 44 H 105.56916 V 40 H 93.486158 V 36 H 105.56916 V 32 H 93.486158 V 28 H 105.56916 V 24 H 93.486158 v -4 h 11.887002 c -1.016,-5.517 -6.090002,-10 -11.804002,-10 h -8 c -6.393,0 -12,5.607 -12,12 v 40 c 0,6.393 5.607,12 12,12 z"
id="path4"
style="fill:#27ae60;fill-opacity:1;stroke:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

125
view.glade

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow" id="MainWindow">
<property name="can-focus">False</property>
<child>
<!-- n-columns=2 n-rows=4 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Output</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Input</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="OutputImg">
<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>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage" id="InputImg">
<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>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="OutputComboBox">
<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>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="InputComboBox">
<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>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="OutputDefault">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="InputDefault">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Loading…
Cancel
Save