aboutsummaryrefslogtreecommitdiff
path: root/inter.py
diff options
context:
space:
mode:
Diffstat (limited to 'inter.py')
-rw-r--r--inter.py262
1 files changed, 153 insertions, 109 deletions
diff --git a/inter.py b/inter.py
index a665540..a2f3456 100644
--- a/inter.py
+++ b/inter.py
@@ -11,9 +11,33 @@ except Exception as e:
__all__ = ["start", "end", "mainloop", "update"]
-inps = None
-sinks = None
-sel = (0, 0)
+class Section:
+ def __init__(self, title, keys, updater):
+ self.items = None
+ self.title = title
+ self.keys = keys
+ self.link_section = None # sinks for sink-inputs, sources for source-outputs
+ self._updater = updater
+ self.update()
+
+ def update(self):
+ self.items = (self._updater)()
+
+class Selection:
+ def __init__(self, section, item):
+ self.section = section
+ self.item = item
+
+sections = [
+ Section("Sink Inputs", "qvm", lambda: pa.list_sink_inputs()),
+ Section("Sinks", "qvd", lambda: pa.list_sinks()),
+ Section("Source Outputs", "qvm", lambda: pa.list_source_outputs()),
+ Section("Sources", "qvd", lambda: pa.list_sources()),
+]
+sections[0].link_section = sections[1]
+sections[2].link_section = sections[3]
+
+sel = Selection(0, 0)
prompt_y = 0 # updated by redraw()
MENU_MAIN, MENU_VOLUME, NUM_MENUS = range(3)
@@ -23,15 +47,15 @@ menutext = [0] * NUM_MENUS
menuopts = [0] * NUM_MENUS
menutext[MENU_MAIN] = ""
-menuopts[MENU_MAIN] = [
- ("(q)uit", [0,1]),
- ("(v)olume", [0,1]),
- ("(d)efault", [1]),
- ("(m)ove", [0])
-]
+menuopts[MENU_MAIN] = {
+ "q": "(q)uit",
+ "v": "(v)olume",
+ "d": "(d)efault",
+ "m": "(m)ove",
+}
menutext[MENU_VOLUME] = "Change volume: <- / -> (alt: 1%) (m)ute [q/esc: return]"
-menuopts[MENU_VOLUME] = []
+menuopts[MENU_VOLUME] = {}
def start():
@@ -52,45 +76,40 @@ def mainloop():
global sel, menu
while True:
update()
- selected_things = [inps, sinks][sel[0]]
- other_things = [sinks, inps][sel[0]]
- if len(selected_things) == 0 and len(other_things) != 0:
- sel = (1 - sel[0], sel[1])
- redraw()
- if sel[1] < 0 or sel[1] >= len(selected_things):
- sel = (sel[0], 0)
+ sel.item = max(0, min(len(sections[sel.section].items) - 1, sel.item))
+ if len(sections[sel.section].items) == 0:
+ for i, s in enumerate(sections):
+ if len(s.items) != 0:
+ sel.section = i
+ sel.item = 0
+ break
+ else:
+ sel = Selection(0, 0)
+
+ # We changed the selection, let's return to the main menu
+ menu = MENU_MAIN
+
+ redraw()
key = T.tgetkey()
- if menu != MENU_MAIN and (key == T.KEY_ESC or key == ord('q')):
+ if menu != MENU_MAIN and (key == T.KEY_ESC or key == ord("q")):
menu = MENU_MAIN
elif menu == MENU_MAIN:
if key == T.KEY_DOWN:
- if sel[0] == 0 and sel[1] >= len(inps) - 1:
- if len(sinks) > 0:
- sel = (1, 0)
- elif sel[0] == 1 and sel[1] >= len(sinks) - 1:
- pass
- else:
- sel = (sel[0], sel[1] + 1)
+ sel = selection_down(sel)
elif key == T.KEY_UP:
- if sel[0] == 0 and sel[1] == 0:
- pass
- elif sel[0] == 1 and sel[1] == 0:
- if len(inps) > 0:
- sel = (0, len(inps) - 1)
- else:
- sel = (sel[0], sel[1] - 1)
+ sel = selection_up(sel)
elif key == ord('q'):
break
- elif key == ord('v'):
+ elif "v" in sections[sel.section].keys and key == ord("v"):
thing = get_selected()
- kind = "sink" if type(thing) == pa.Sink else "input"
+ kind = thing.kind()
vol = thing.volume()
if len(vol) >= 2 and vol[0] != vol[1]:
show_message(
@@ -98,13 +117,14 @@ def mainloop():
menu = MENU_VOLUME
- elif sel[0] == 1 and key == ord('d'):
- wrap_pacmd(lambda: sinks[sel[1]].set_default())
+ elif "d" in sections[sel.section].keys and key == ord("d"):
+ wrap_pacmd(lambda: get_selected().set_default())
- elif sel[0] == 0 and key == ord('m'):
+ elif "m" in sections[sel.section].keys and key == ord("m"):
+ thing = get_selected()
idx = show_prompt(
- "Enter sink number to link input {} to"
- .format(inps[sel[1]].index()))
+ "Enter {} number to link {} {} to"
+ .format(thing.linked_kind(), thing.kind(), thing.index()))
if idx is None:
continue
@@ -115,15 +135,18 @@ def mainloop():
show_message("Invalid number!")
continue
- for i in range(len(sinks)):
- if sinks[i].index() == idx:
- wrap_pacmd(lambda: inps[sel[1]].move_to_sink(idx))
+ link_section = sections[sel.section].link_section
+
+ for i in range(len(link_section.items)):
+ if link_section.items[i].index() == idx:
+ wrap_pacmd(lambda: thing.move_to(idx))
break
else:
- show_message("No sink found with that index!")
+ show_message("No {} found with that index!"
+ .format(thing.linked_kind()))
elif menu == MENU_VOLUME:
- thing = [inps, sinks][sel[0]][sel[1]]
+ thing = get_selected()
incr = 0
if key == T.KEY_RIGHT:
@@ -134,7 +157,7 @@ def mainloop():
incr = 0.01
elif key == T.KEY_ALT + T.KEY_LEFT:
incr = -0.01
- elif key == ord('m'):
+ elif key == ord("m"):
thing.set_muted(not thing.muted())
continue
else:
@@ -149,8 +172,42 @@ def mainloop():
else:
assert False
+def selection_down(sel):
+ if sel.item >= len(sections[sel.section].items) - 1:
+ if sel.section >= len(sections) - 1:
+ T.bel()
+ return sel
+ else:
+ i = sel.section + 1
+ while i < len(sections) and len(sections[i].items) == 0:
+ i += 1
+ if i < len(sections):
+ return Selection(i, 0)
+ else:
+ T.bel()
+ return sel
+ else:
+ return Selection(sel.section, sel.item + 1)
+
+def selection_up(sel):
+ if sel.item <= 0:
+ if sel.section <= 0:
+ T.bel()
+ return sel
+ else:
+ i = sel.section - 1
+ while i >= 0 and len(sections[i].items) == 0:
+ i -= 1
+ if i >= 0:
+ return Selection(i, len(sections[i].items) - 1)
+ else:
+ T.bel()
+ return sel
+ else:
+ return Selection(sel.section, sel.item - 1)
+
def get_selected():
- return [inps, sinks][sel[0]][sel[1]]
+ return sections[sel.section].items[sel.item]
def wrap_pacmd(lam):
try:
@@ -184,9 +241,24 @@ def show_prompt(msg):
T.fillrect(0, prompt_y, sz.w, sz.h - prompt_y, ' ')
return line
+# Returns y after end of section on screen
+def draw_section(y, items, title, section_selected):
+ T.moveto(0, y)
+ T.setbold(True)
+ T.tprint(title)
+ T.setbold(False)
+ y += 1
+
+ for i, item in enumerate(items):
+ T.moveto(1, y)
+ print_item(item, section_selected and sel.item == i)
+ y += 1
+
+ return y
+
def redraw():
global prompt_y
- if inps is None:
+ if sections[0].items is None:
update()
sz = T.gettermsize()
@@ -195,45 +267,23 @@ def redraw():
T.setstyle(T.Style(9, 9, False, False))
y = 0
- T.moveto(0, y)
- T.setbold(True)
- T.tprint("Sink Inputs")
- T.setbold(False)
- y += 1
-
- for i, inp in enumerate(inps):
- T.moveto(4, y)
- print_input(inp, sel[0] == 0 and sel[1] == i)
+ for i, section in enumerate(sections):
+ y = draw_section(y, section.items, section.title, sel.section == i)
y += 1
y += 1
- T.moveto(0, y)
- T.setbold(True)
- T.tprint("Sinks")
- T.setbold(False)
- y += 1
-
- for i, sink in enumerate(sinks):
- T.moveto(4, y)
- print_sink(sink, sel[0] == 1 and sel[1] == i)
- y += 1
-
- y += 2
prompt_y = y
T.moveto(0, y)
T.tprint(menutext[menu])
first = True
- for (text, groups) in menuopts[menu]:
- if sel[0] in groups:
- if first: first = False
- else: T.tprint(" ")
- T.tprint(text)
- # if sel[0] not in groups:
- # T.setfg(6)
- # T.tprint(text)
- # T.setfg(9)
+ for key in sections[sel.section].keys:
+ if key not in menuopts[menu]:
+ continue
+ if first: first = False
+ else: T.tprint(" ")
+ T.tprint(menuopts[menu][key])
y += 1
@@ -271,49 +321,43 @@ def print_volume(thing):
" (MUTED)" if thing.muted() else ""))
T.setfg(9)
-def print_input(inp, selected):
- print_prefix(inp, selected)
+def print_item(item, selected):
+ print_prefix(item, selected)
T.setfg(3)
- T.tprint("[{}]".format(inp.index()))
+ T.tprint("[{}]".format(item.index()))
T.setfg(9)
T.tprint(" ")
- T.tprint(inp.name())
-
- T.tprint(" ")
- print_volume(inp)
-
- T.setfg(3)
- T.tprint(" -> ")
- T.tprint("[{}]".format(inp.sink()))
- T.setfg(9)
-
-def print_sink(sink, selected):
- print_prefix(sink, selected)
-
- T.setfg(3)
- T.tprint("[{}]".format(sink.index()))
- T.setfg(9)
+ T.tprint(item.name())
- T.tprint(" ")
- T.tprint(sink.name())
+ if isinstance(item, pa.SinkSource):
+ T.tprint(" ")
+ print_state(item)
T.tprint(" ")
- print_volume(sink)
+ print_volume(item)
+
+ if isinstance(item, pa.SinkSource):
+ if item.default():
+ T.tprint(" ")
+ T.setbold(True)
+ T.tprint("[default]")
+ T.setbold(False)
+ else:
+ T.setfg(3)
+ T.tprint(" -> " if isinstance(item, pa.SinkInput) else " <- ")
+ T.tprint("[{}]".format(item.linked_index()))
+ T.setfg(9)
- if sink.default():
- T.tprint(" ")
- T.setbold(True)
- T.tprint("[default]")
- T.setbold(False)
+def print_state(thing):
+ T.setfg(6)
+ T.tprint("({})".format(thing.state()))
+ T.setfg(9)
def update():
- global inps, sinks
-
- inps = pa.list_sink_inputs()
- sinks = pa.list_sinks()
- redraw()
+ for section in sections:
+ section.update()
orig_excepthook = sys.excepthook