bus mono now a ButtonMenu.

this allows users to select between  `mono off`, `mono on` and `stereo reverse`. This properly reflects the Voicemeter GUI.
This commit is contained in:
onyx-and-iris 2026-03-11 01:11:17 +00:00
parent 1ea1c59f06
commit cc6e187998
3 changed files with 39 additions and 7 deletions

View File

@ -438,13 +438,20 @@ class Builder:
def make_tab3_button_row(self, i) -> psg.Frame:
"""tab3 row represents bus composite toggle"""
def add_strip_outputs(layout):
params = ['MONO', 'EQ', 'MUTE']
def add_bus_buttons(layout):
busmono = util.get_bus_mono()
params = ['EQ', 'MUTE']
if self.kind.name == 'basic':
params.remove('EQ')
busmodes = [util._bus_mode_map[mode] for mode in util.get_bus_modes(self.vm)]
layout.append(
[
psg.ButtonMenu(
'Mono',
size=(6, 2),
menu_def=['', busmono],
key=f'BUS {i}||MONO',
),
*[
psg.Button(
param.capitalize(),
@ -454,7 +461,7 @@ class Builder:
for param in params
],
psg.ButtonMenu(
'BUSMODE',
'Bus Mode',
size=(12, 2),
menu_def=['', busmodes],
key=f'BUS {i}||MODE',
@ -463,7 +470,7 @@ class Builder:
)
outputs = []
[step(outputs) for step in (add_strip_outputs,)]
[step(outputs) for step in (add_bus_buttons,)]
return psg.Frame(
self.window.cache['labels'][f'BUS {i}||LABEL'],
outputs,

View File

@ -155,6 +155,10 @@ def get_bus_modes(vm) -> list:
]
def get_bus_mono() -> list:
return ['off', 'on', 'stereo reverse']
def check_bounds(val, bounds: tuple) -> int | float:
lower, upper = bounds
if val > upper:

View File

@ -58,6 +58,7 @@ class NVDAVMWindow(psg.Window):
self[f'STRIP {i}||SLIDER LIMIT'].Widget.config(**slider_opts)
for i in range(self.kind.num_bus):
self[f'BUS {i}||SLIDER GAIN'].Widget.config(**slider_opts)
self[f'BUS {i}||MONO'].Widget.config(**buttonmenu_opts)
self[f'BUS {i}||MODE'].Widget.config(**buttonmenu_opts)
self.register_events()
@ -251,13 +252,16 @@ class NVDAVMWindow(psg.Window):
self[f'STRIP {i}||SLIDER {param}'].bind('<Control-Shift-KeyPress-R>', '||KEY CTRL SHIFT R')
# Bus Params
params = ['MONO', 'EQ', 'MUTE']
params = ['EQ', 'MUTE']
if self.kind.name == 'basic':
params.remove('EQ')
for i in range(self.kind.num_bus):
for param in params:
self[f'BUS {i}||{param}'].bind('<FocusIn>', '||FOCUS IN')
self[f'BUS {i}||{param}'].bind('<Return>', '||KEY ENTER')
self[f'BUS {i}||MONO'].bind('<FocusIn>', '||FOCUS IN')
self[f'BUS {i}||MONO'].bind('<space>', '||KEY SPACE', propagate=False)
self[f'BUS {i}||MONO'].bind('<Return>', '||KEY ENTER')
self[f'BUS {i}||MODE'].bind('<FocusIn>', '||FOCUS IN')
self[f'BUS {i}||MODE'].bind('<space>', '||KEY SPACE', propagate=False)
self[f'BUS {i}||MODE'].bind('<Return>', '||KEY ENTER', propagate=False)
@ -306,7 +310,7 @@ class NVDAVMWindow(psg.Window):
mode = None
continue
match parsed_cmd := self.parser.match.parseString(event):
match parsed_cmd := self.parser.match.parse_string(event):
# Slider mode
case [['ALT', 'LEFT' | 'RIGHT' | 'UP' | 'DOWN' as direction], ['PRESS' | 'RELEASE' as e]]:
if mode:
@ -972,7 +976,7 @@ class NVDAVMWindow(psg.Window):
self.nvda.speak,
'on' if val else 'off',
)
case 'MONO' | 'MUTE':
case 'MUTE':
val = not val
setattr(self.vm.bus[int(index)], param.lower(), val)
self.cache['bus'][event] = val
@ -981,6 +985,15 @@ class NVDAVMWindow(psg.Window):
self.nvda.speak,
'on' if val else 'off',
)
case 'MONO':
chosen = values[event]
self.vm.bus[int(index)].mono = util.get_bus_mono().index(chosen)
self.cache['bus'][event] = chosen
self.TKroot.after(
200,
self.nvda.speak,
f'mono {chosen}',
)
case 'MODE':
chosen = util._bus_mode_map_reversed[values[event]]
setattr(self.vm.bus[int(index)].mode, chosen, True)
@ -996,11 +1009,19 @@ class NVDAVMWindow(psg.Window):
val = self.cache['bus'][f'BUS {index}||{param}']
if param == 'MODE':
self.nvda.speak(f'{label} bus {param} {util._bus_mode_map[val]}')
elif param == 'MONO':
busmode = util.get_bus_mono()[val]
if busmode in ('on', 'off'):
self.nvda.speak(f'{label} {param} {busmode}')
else:
self.nvda.speak(f'{label} {busmode}')
else:
self.nvda.speak(f'{label} {param} {"on" if val else "off"}')
case [['BUS', index], [param], ['KEY', 'SPACE' | 'ENTER']]:
if param == 'MODE':
util.open_context_menu_for_buttonmenu(self, f'BUS {index}||MODE')
elif param == 'MONO':
util.open_context_menu_for_buttonmenu(self, f'BUS {index}||MONO')
else:
self.find_element_with_focus().click()