From 3d98b2accdcaed2fa33212a78fcf0af7e0448707 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Sat, 24 Jun 2023 23:30:35 +0100 Subject: [PATCH] add gui example --- examples/gui/README.md | 13 +++++ examples/gui/__main__.py | 100 +++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + scripts.py | 5 ++ 4 files changed, 119 insertions(+) create mode 100644 examples/gui/README.md create mode 100644 examples/gui/__main__.py diff --git a/examples/gui/README.md b/examples/gui/README.md new file mode 100644 index 0000000..5cd7316 --- /dev/null +++ b/examples/gui/README.md @@ -0,0 +1,13 @@ +## About + +A single channel GUI demonstrating controls for the first virtual strip if Voicemeeter Banana. + +This example demonstrates (to an extent) two way communication. +- Sending parameters values to the Voicemeeter driver. +- Receiving level updates + +Parameter updates (pdirty) events are not being received so changing a UI element on the main Voicemeeter app will not be reflected in the example GUI. + +## Use + +Simply run the script and try the controls. diff --git a/examples/gui/__main__.py b/examples/gui/__main__.py new file mode 100644 index 0000000..b792040 --- /dev/null +++ b/examples/gui/__main__.py @@ -0,0 +1,100 @@ +import logging + +import voicemeeterlib + +logging.basicConfig(level=logging.DEBUG) +import tkinter as tk +from tkinter import ttk + + +class App(tk.Tk): + def __init__(self, vm): + super().__init__() + self.vm = vm + self.title(f"{vm} - version {vm.version}") + self.vm.observer.add(self.on_ldirty) + + # create widget variables + self.button_var = tk.BooleanVar(value=vm.strip[3].mute) + self.slider_var = tk.DoubleVar(value=vm.strip[3].gain) + self.meter_var = tk.DoubleVar(value=self._get_level()) + self.gainlabel_var = tk.StringVar(value=self.slider_var.get()) + + # initialize style table + self.style = ttk.Style() + self.style.theme_use("clam") + self.style.configure( + "Mute.TButton", foreground="#cd5c5c" if vm.strip[3].mute else "#5a5a5a" + ) + + # create labelframe and grid it onto the mainframe + self.labelframe = tk.LabelFrame(text=self.vm.strip[3].label) + self.labelframe.grid(padx=1) + + # create slider and grid it + slider = ttk.Scale( + self.labelframe, + from_=12, + to_=-60, + orient="vertical", + variable=self.slider_var, + command=lambda arg: self.on_slider_move(arg), + ) + slider.grid( + column=0, + row=0, + ) + + # create level meter and grid it onto the labelframe + level_meter = ttk.Progressbar( + self.labelframe, + orient="vertical", + variable=self.meter_var, + maximum=72, + mode="determinate", + ) + level_meter.grid(column=1, row=0) + + # create gainlabel and grid it onto the labelframe + gainlabel = ttk.Label(self.labelframe, textvariable=self.gainlabel_var) + gainlabel.grid(column=0, row=1, columnspan=2) + + # create button and grid it onto the labelframe + button = ttk.Button( + self.labelframe, + text="Mute", + style="Mute.TButton", + command=lambda: self.on_button_press(), + ) + button.grid(column=0, row=2, columnspan=2, padx=1, pady=2) + + # define callbacks + + def on_slider_move(self, *args): + val = round(self.slider_var.get(), 1) + self.vm.strip[3].gain = val + self.gainlabel_var.set(val) + + def on_button_press(self): + self.button_var.set(not self.button_var.get()) + self.vm.strip[3].mute = self.button_var.get() + self.style.configure( + "Mute.TButton", foreground="#cd5c5c" if self.button_var.get() else "#5a5a5a" + ) + + def _get_level(self): + val = max(self.vm.strip[3].levels.postfader) + return 0 if self.button_var.get() else 72 + val - 12 + + def on_ldirty(self): + self.meter_var.set(self._get_level()) + + +def main(): + with voicemeeterlib.api("banana", ldirty=True) as vm: + app = App(vm) + app.mainloop() + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index 1cb1224..136d2ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.scripts] dsl = "scripts:ex_dsl" events = "scripts:ex_events" +gui = "scripts:ex_gui" levels = "scripts:ex_levels" midi = "scripts:ex_midi" obs = "scripts:ex_obs" diff --git a/scripts.py b/scripts.py index 2203318..0d65cf1 100644 --- a/scripts.py +++ b/scripts.py @@ -12,6 +12,11 @@ def ex_events(): subprocess.run(["py", str(path)]) +def ex_gui(): + path = Path.cwd() / "examples" / "gui" / "." + subprocess.run(["py", str(path)]) + + def ex_levels(): path = Path.cwd() / "examples" / "levels" / "." subprocess.run(["py", str(path)])