From bc14116cd7fa5ac3a80bf24ec2bf523b98f09ca4 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Fri, 15 Sep 2023 10:55:22 +0100 Subject: [PATCH] places gain sliders on slider tabs slider focus in/out events registered. --- src/nvda_voicemeeter/builder.py | 139 ++++++++++++++++++++++++++------ src/nvda_voicemeeter/models.py | 4 +- src/nvda_voicemeeter/window.py | 50 ++++++++++++ 3 files changed, 167 insertions(+), 26 deletions(-) diff --git a/src/nvda_voicemeeter/builder.py b/src/nvda_voicemeeter/builder.py index 3f9be22..0cdbf88 100644 --- a/src/nvda_voicemeeter/builder.py +++ b/src/nvda_voicemeeter/builder.py @@ -41,19 +41,31 @@ class Builder: layout0.append([step()]) layout1_1 = [] - steps = (self.make_tab1_rows,) + steps = (self.make_tab1_button_rows,) for step in steps: layout1_1.append([step()]) + layout1_2 = [] + steps = (self.make_tab1_slider_rows,) + for step in steps: + layout1_2.append([step()]) layout2_1 = [] - steps = (self.make_tab2_rows,) + steps = (self.make_tab2_button_rows,) for step in steps: layout2_1.append([step()]) + layout2_2 = [] + steps = (self.make_tab2_slider_rows,) + for step in steps: + layout2_2.append([step()]) layout3_1 = [] - steps = (self.make_tab3_rows,) + steps = (self.make_tab3_button_rows,) for step in steps: layout3_1.append([step()]) + layout3_2 = [] + steps = (self.make_tab3_slider_rows,) + for step in steps: + layout3_2.append([step()]) def _make_inner_tabgroup(layouts, identifier) -> psg.TabGroup: inner_layout = [] @@ -71,11 +83,11 @@ class Builder: case "Settings": return psg.Tab("Settings", layout0, key="tab||Settings") case "Physical Strip": - tabgroup = _make_inner_tabgroup((layout1_1, []), identifier) + tabgroup = _make_inner_tabgroup((layout1_1, layout1_2), identifier) case "Virtual Strip": - tabgroup = _make_inner_tabgroup((layout2_1, []), identifier) + tabgroup = _make_inner_tabgroup((layout2_1, layout2_2), identifier) case "Buses": - tabgroup = _make_inner_tabgroup((layout3_1, []), identifier) + tabgroup = _make_inner_tabgroup((layout3_1, layout3_2), identifier) return psg.Tab(identifier, [[tabgroup]], key=f"tab||{identifier}") tabs = [] @@ -118,7 +130,7 @@ class Builder: ] ) - hardware_in = list() + hardware_in = [] [step(hardware_in) for step in (add_physical_device_opts,)] return psg.Frame("Hardware In", hardware_in) @@ -142,7 +154,7 @@ class Builder: ] ) - hardware_out = list() + hardware_out = [] [step(hardware_out) for step in (add_physical_device_opts,)] return psg.Frame("Hardware Out", hardware_out) @@ -174,7 +186,7 @@ class Builder: ], ) - inner = list() + inner = [] asio_checkboxlists = ([] for _ in range(self.kind.phys_out)) for i, checkbox_list in enumerate(asio_checkboxlists): [step(checkbox_list, i + 1) for step in (add_asio_checkboxes,)] @@ -200,7 +212,7 @@ class Builder: ] ) - hardware_out = list() + hardware_out = [] [step(hardware_out) for step in (add_physical_device_opts,)] return psg.Frame("PATCH COMPOSITE", hardware_out) @@ -235,8 +247,8 @@ class Builder: ], ) - asio_checkboxes = list() - inner = list() + asio_checkboxes = [] + inner = [] checkbox_lists = ([] for _ in range(self.kind.num_strip)) for i, checkbox_list in enumerate(checkbox_lists): if i < self.kind.phys_in: @@ -266,7 +278,7 @@ class Builder: key="ADVANCED SETTINGS FRAME", ) - def make_tab1_row(self, i) -> psg.Frame: + def make_tab1_button_row(self, i) -> psg.Frame: """tab1 row represents a strip's outputs (A1-A5, B1-B3)""" def add_strip_outputs(layout): @@ -290,15 +302,40 @@ class Builder: ], ) - outputs = list() + outputs = [] [step(outputs) for step in (add_strip_outputs,)] return psg.Frame(self.window.cache["labels"][f"STRIP {i}||LABEL"], outputs, key=f"STRIP {i}||LABEL") - def make_tab1_rows(self) -> psg.Frame: - layout = [[self.make_tab1_row(i)] for i in range(self.kind.phys_in)] + def make_tab1_button_rows(self) -> psg.Frame: + layout = [[self.make_tab1_button_row(i)] for i in range(self.kind.phys_in)] return psg.Frame(None, layout, border_width=0) - def make_tab2_row(self, i) -> psg.Frame: + def make_tab1_slider_row(self, i) -> psg.Frame: + def add_gain_slider(layout): + layout.append( + [ + psg.Slider( + range=(-60, 12), + default_value=self.vm.strip[i].gain, + resolution=0.1, + disable_number_display=True, + expand_x=True, + enable_events=True, + orientation="horizontal", + key=f"STRIP {i}||SLIDER GAIN", + ) + ] + ) + + outputs = [] + [step(outputs) for step in (add_gain_slider,)] + return psg.Frame(self.window.cache["labels"][f"STRIP {i}||LABEL"], outputs, key=f"STRIP {i}||LABEL||SLIDER") + + def make_tab1_slider_rows(self) -> psg.Frame: + layout = [[self.make_tab1_slider_row(i)] for i in range(self.kind.phys_in)] + return psg.Frame(None, layout, border_width=0) + + def make_tab2_button_row(self, i) -> psg.Frame: """tab2 row represents a strip's outputs (A1-A5, B1-B3)""" def add_strip_outputs(layout): @@ -331,15 +368,44 @@ class Builder: ], ) - outputs = list() + outputs = [] [step(outputs) for step in (add_strip_outputs,)] return psg.Frame(self.window.cache["labels"][f"STRIP {i}||LABEL"], outputs, key=f"STRIP {i}||LABEL") - def make_tab2_rows(self) -> psg.Frame: - layout = [[self.make_tab2_row(i)] for i in range(self.kind.phys_in, self.kind.phys_in + self.kind.virt_in)] + def make_tab2_button_rows(self) -> psg.Frame: + layout = [ + [self.make_tab2_button_row(i)] for i in range(self.kind.phys_in, self.kind.phys_in + self.kind.virt_in) + ] return psg.Frame(None, layout, border_width=0) - def make_tab3_row(self, i) -> psg.Frame: + def make_tab2_slider_row(self, i) -> psg.Frame: + def add_gain_slider(layout): + layout.append( + [ + psg.Slider( + range=(-60, 12), + default_value=self.vm.strip[i].gain, + resolution=0.1, + disable_number_display=True, + expand_x=True, + enable_events=True, + orientation="horizontal", + key=f"STRIP {i}||SLIDER GAIN", + ) + ] + ) + + outputs = [] + [step(outputs) for step in (add_gain_slider,)] + return psg.Frame(self.window.cache["labels"][f"STRIP {i}||LABEL"], outputs, key=f"STRIP {i}||LABEL||SLIDER") + + def make_tab2_slider_rows(self) -> psg.Frame: + layout = [ + [self.make_tab2_slider_row(i)] for i in range(self.kind.phys_in, self.kind.phys_in + self.kind.virt_in) + ] + return psg.Frame(None, layout, border_width=0) + + def make_tab3_button_row(self, i) -> psg.Frame: """tab3 row represents bus composite toggle""" def add_strip_outputs(layout): @@ -358,10 +424,35 @@ class Builder: ] ) - outputs = list() + outputs = [] [step(outputs) for step in (add_strip_outputs,)] return psg.Frame(self.window.cache["labels"][f"BUS {i}||LABEL"], outputs, key=f"BUS {i}||LABEL") - def make_tab3_rows(self) -> psg.Frame: - layout = [[self.make_tab3_row(i)] for i in range(self.kind.num_bus)] + def make_tab3_button_rows(self) -> psg.Frame: + layout = [[self.make_tab3_button_row(i)] for i in range(self.kind.num_bus)] + return psg.Frame(None, layout, border_width=0) + + def make_tab3_slider_row(self, i) -> psg.Frame: + def add_gain_slider(layout): + layout.append( + [ + psg.Slider( + range=(-60, 12), + default_value=self.vm.bus[i].gain, + resolution=0.1, + disable_number_display=True, + expand_x=True, + enable_events=True, + orientation="horizontal", + key=f"BUS {i}||SLIDER GAIN", + ) + ] + ) + + outputs = [] + [step(outputs) for step in (add_gain_slider,)] + return psg.Frame(self.window.cache["labels"][f"BUS {i}||LABEL"], outputs, key=f"BUS {i}||LABEL||SLIDER") + + def make_tab3_slider_rows(self) -> psg.Frame: + layout = [[self.make_tab3_slider_row(i)] for i in range(self.kind.num_bus)] return psg.Frame(None, layout, border_width=0) diff --git a/src/nvda_voicemeeter/models.py b/src/nvda_voicemeeter/models.py index a1dcd36..3f1b962 100644 --- a/src/nvda_voicemeeter/models.py +++ b/src/nvda_voicemeeter/models.py @@ -42,14 +42,14 @@ def _make_param_cache(vm, channel_type) -> dict: **{f"STRIP {i}||SOLO": vm.strip[i].solo for i in range(vm.kind.num_strip)}, **{f"STRIP {i}||MUTE": vm.strip[i].mute for i in range(vm.kind.num_strip)}, } - return params else: - return { + params |= { **{f"BUS {i}||MONO": vm.bus[i].mono for i in range(vm.kind.num_bus)}, **{f"BUS {i}||EQ": vm.bus[i].eq.on for i in range(vm.kind.num_bus)}, **{f"BUS {i}||MUTE": vm.bus[i].mute for i in range(vm.kind.num_bus)}, **{f"BUS {i}||MODE": vm.bus[i].mode.get() for i in range(vm.kind.num_bus)}, } + return params def _make_label_cache(vm) -> dict: diff --git a/src/nvda_voicemeeter/window.py b/src/nvda_voicemeeter/window.py index a535a35..42967ef 100644 --- a/src/nvda_voicemeeter/window.py +++ b/src/nvda_voicemeeter/window.py @@ -64,6 +64,11 @@ class NVDAVMWindow(psg.Window): self[f"HARDWARE OUT||A2"].Widget.config(**buttonmenu_opts) if self.kind.name != "basic": [self[f"PATCH COMPOSITE||PC{i + 1}"].Widget.config(**buttonmenu_opts) for i in range(self.kind.phys_out)] + slider_opts = {"takefocus": 1, "highlightthickness": 1} + for i in range(self.kind.num_strip): + self[f"STRIP {i}||SLIDER GAIN"].Widget.config(**slider_opts) + for i in range(self.kind.num_bus): + self[f"BUS {i}||SLIDER GAIN"].Widget.config(**slider_opts) self.register_events() self["tabgroup"].set_focus() @@ -111,6 +116,11 @@ class NVDAVMWindow(psg.Window): } for key, value in self.cache["labels"].items(): self[key].update(value=value) + self[f"{key}||SLIDER"].update(value=value) + for i in range(self.kind.num_strip): + self[f"STRIP {i}||SLIDER GAIN"].update(value=self.vm.strip[i].gain) + for i in range(self.kind.num_bus): + self[f"BUS {i}||SLIDER GAIN"].update(value=self.vm.bus[i].gain) if self.kind.name != "basic": for key, value in self.cache["asio"].items(): identifier, i = key.split("||") @@ -192,6 +202,11 @@ class NVDAVMWindow(psg.Window): self[f"STRIP {i}||{param}"].bind("", "||FOCUS IN") self[f"STRIP {i}||{param}"].bind("", "||KEY ENTER") + # Strip Sliders + for i in range(self.kind.num_strip): + self[f"STRIP {i}||SLIDER GAIN"].bind("", "||FOCUS IN") + self[f"STRIP {i}||SLIDER GAIN"].bind("", "||FOCUS OUT") + # Bus Params params = ["MONO", "EQ", "MUTE", "MODE"] if self.vm.kind.name == "basic": @@ -201,6 +216,11 @@ class NVDAVMWindow(psg.Window): self[f"BUS {i}||{param}"].bind("", "||FOCUS IN") self[f"BUS {i}||{param}"].bind("", "||KEY ENTER") + # Bus Sliders + for i in range(self.kind.num_bus): + self[f"BUS {i}||SLIDER GAIN"].bind("", "||FOCUS IN") + self[f"BUS {i}||SLIDER GAIN"].bind("", "||FOCUS OUT") + def popup_save_as(self, message, title=None, initial_folder=None): layout = [ [psg.Text(message)], @@ -632,6 +652,21 @@ class NVDAVMWindow(psg.Window): case [["STRIP", index], [param], ["KEY", "ENTER"]]: self.find_element_with_focus().click() + # Strip Sliders + case [["STRIP", index], ["SLIDER", "GAIN"]]: + label = self.cache["labels"][f"STRIP {index}||LABEL"] + val = values[event] + self.vm.strip[int(index)].gain = val + self.nvda.speak(f"{label} gain slider {val}") + case [["STRIP", index], ["SLIDER", "GAIN"], ["FOCUS", "IN"]]: + if self.find_element_with_focus() is not None: + self.vm.event.pdirty = False + label = self.cache["labels"][f"STRIP {index}||LABEL"] + val = values[f"STRIP {index}||SLIDER GAIN"] + self.nvda.speak(f"{label} gain slider {val}") + case [["STRIP", index], ["SLIDER", "GAIN"], ["FOCUS", "OUT"]]: + self.vm.event.pdirty = True + # Bus Params case [["BUS", index], [param]]: val = self.cache["bus"][event] @@ -691,6 +726,21 @@ class NVDAVMWindow(psg.Window): case [["BUS", index], [param], ["KEY", "ENTER"]]: self.find_element_with_focus().click() + # Bus Sliders + case [["BUS", index], ["SLIDER", "GAIN"]]: + label = self.cache["labels"][f"BUS {index}||LABEL"] + val = values[event] + self.vm.bus[int(index)].gain = val + self.nvda.speak(f"{label} gain slider {val}") + case [["BUS", index], ["SLIDER", "GAIN"], ["FOCUS", "IN"]]: + if self.find_element_with_focus() is not None: + self.vm.event.pdirty = False + label = self.cache["labels"][f"BUS {index}||LABEL"] + val = values[f"BUS {index}||SLIDER GAIN"] + self.nvda.speak(f"{label} gain slider {val}") + case [["BUS", index], ["SLIDER", "GAIN"], ["FOCUS", "OUT"]]: + self.vm.event.pdirty = True + # Unknown case _: self.logger.debug(f"Unknown event {event}")