4 Commits

Author SHA1 Message Date
c2db0f2757 dependencies updated.
patch bump
2023-08-06 23:16:20 +01:00
bfb0482c32 on_close_window() callback added.
cleanly shuts down vban connection on windows close
if vban connected.
2023-08-06 23:15:54 +01:00
6222ab1e62 id renamed to identifier in _make_channelframe()
label_cache arrays now initialised with empty strings

update_levels() now called when initialising ChannelFrame
2023-08-06 23:15:08 +01:00
0ad40ab708 use vm.version for healthcheck
update deps

patch bump
2023-07-13 01:32:01 +01:00
5 changed files with 67 additions and 53 deletions

32
poetry.lock generated
View File

@@ -36,13 +36,13 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
version = "8.1.4"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
{file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"},
{file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"},
]
[package.dependencies]
@@ -100,13 +100,13 @@ files = [
[[package]]
name = "platformdirs"
version = "3.8.0"
version = "3.8.1"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"},
{file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"},
{file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"},
{file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"},
]
[package.extras]
@@ -115,13 +115,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-
[[package]]
name = "sv-ttk"
version = "2.5.1"
version = "2.5.5"
description = "A gorgeous theme for Tkinter, based on Windows 11's UI"
optional = false
python-versions = ">=3.7"
files = [
{file = "sv_ttk-2.5.1-py3-none-any.whl", hash = "sha256:c7388741e14316b4e9c3b9fd135e1e2e5b501f1b30c89b7af1e26286b38f2ccc"},
{file = "sv_ttk-2.5.1.tar.gz", hash = "sha256:e32d60587db7debe4d7d7438f66257ffcd9db5b8efbcb52151697fa8a662a4f5"},
{file = "sv_ttk-2.5.5-py3-none-any.whl", hash = "sha256:49d1cd03c032728c183d1fe2318f88cdb658ef3e87157e1ca3fcf6661054965b"},
{file = "sv_ttk-2.5.5.tar.gz", hash = "sha256:9bbfe2aba6cc6f9fdf70d79331046543c9666fcccc78bad5ff648a9987e3cedb"},
]
[[package]]
@@ -137,13 +137,13 @@ files = [
[[package]]
name = "vban-cmd"
version = "2.2.0"
version = "2.4.4"
description = "Python interface for the VBAN RT Packet Service (Sendtext)"
optional = false
python-versions = ">=3.10,<4.0"
files = [
{file = "vban_cmd-2.2.0-py3-none-any.whl", hash = "sha256:ad0bd848b5412004c4c14976e8a9a18d0fc727599e343db0fb67f9427c8541fa"},
{file = "vban_cmd-2.2.0.tar.gz", hash = "sha256:7bad6001504fd052df3192c7d817e604703353f57efa7648c1f1d6e425665006"},
{file = "vban_cmd-2.4.4-py3-none-any.whl", hash = "sha256:f439219a2dc6a45123bb70fc94d2aabfc643f26dffc9206da2228e2520f83e01"},
{file = "vban_cmd-2.4.4.tar.gz", hash = "sha256:31dbf6abb681d57772c9082722b024d0798eff99b4c622bfbb539179852a935d"},
]
[package.dependencies]
@@ -151,13 +151,13 @@ tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
[[package]]
name = "voicemeeter-api"
version = "2.1.2"
version = "2.4.4"
description = "A Python wrapper for the Voiceemeter API"
optional = false
python-versions = ">=3.10,<4.0"
files = [
{file = "voicemeeter_api-2.1.2-py3-none-any.whl", hash = "sha256:43a6e36282a89f2701b58f627bdd21c5e17f9f9044bf3337059d89e91f25fc09"},
{file = "voicemeeter_api-2.1.2.tar.gz", hash = "sha256:c24c643e868535786860420fe5775a10e2ace6f79ec4905a172a1c64712f3d6b"},
{file = "voicemeeter_api-2.4.4-py3-none-any.whl", hash = "sha256:2e2f0b475de7cfc0d1c397838498162f0b405ab82a6f6ca0095434b43385b43e"},
{file = "voicemeeter_api-2.4.4.tar.gz", hash = "sha256:a4f8ecaa7f5d6b9e9a8545dcf047754711af9a120628b3a98821466c7d65c1e7"},
]
[package.dependencies]
@@ -166,4 +166,4 @@ tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "3a59de3a76e4c0ca11c0166750fa1af7d7c887750f855b48c45359068ef04798"
content-hash = "cde74de8c9de0895555068efea354edf6b51f2332c253f02f6c8f26fe6b4e795"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "voicemeeter-compact"
version = "1.9.0"
version = "1.9.2"
description = "A Compact Voicemeeter Remote App"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"
@@ -12,10 +12,10 @@ include = ["vmcompact/img/cat.ico"]
[tool.poetry.dependencies]
python = "^3.10"
sv-ttk = "^2.5.1"
sv-ttk = "^2.5.5"
tomli = { version = "^2.0.1", python = "<3.11" }
voicemeeter-api = "^2.1.2"
vban-cmd = "^2.2.0"
voicemeeter-api = "^2.4.4"
vban-cmd = "^2.4.4"
[tool.poetry.dev-dependencies]
black = { version = "^22.6.0", allow-prereleases = true }

View File

@@ -50,6 +50,7 @@ class App(tk.Tk):
self.minsize(275, False)
self.subject = Subject()
self._configs = None
self.protocol("WM_DELETE_WINDOW", self.on_close_window)
self.menu = self["menu"] = Menus(self, vmr)
self.styletable = ttk.Style()
if _configuration.config:
@@ -155,7 +156,7 @@ class App(tk.Tk):
def healthcheck_step(self):
if not _base_values.vban_connected:
try:
self._vmr.pdirty
self._vmr.version
except voicemeeterlib.error.CAPIError:
resp = messagebox.askyesno(message="Restart Voicemeeter GUI?")
if resp:
@@ -182,6 +183,11 @@ class App(tk.Tk):
self.destroy()
self.after(250, self.healthcheck_step)
def on_close_window(self):
if _base_values.vban_connected:
self._vban.logout()
self.destroy()
_apps = {kind.name: App.make(kind) for kind in _kinds_all}

View File

@@ -151,17 +151,18 @@ class ChannelLabelFrame(ttk.LabelFrame):
def sync_labels(self):
"""sync labelframes according to label text"""
retval = self.getter("label")
self.parent.label_cache[self.id].insert(self.index, retval)
if len(retval) > 10:
retval = f"{retval[:8]}.."
if not retval:
self.parent.columnconfigure(self.index, minsize=0)
self.parent.parent.subject.remove(self)
self.grid_remove()
else:
self.parent.parent.subject.add(self)
self.grid()
self.configure(text=retval)
if self.parent.label_cache[self.id][self.index] != retval:
self.parent.label_cache[self.id][self.index] = retval
if len(retval) > 10:
retval = f"{retval[:8]}.."
if not retval:
self.parent.columnconfigure(self.index, minsize=0)
self.parent.parent.subject.remove(self)
self.grid_remove()
else:
self.parent.parent.subject.add(self)
self.grid()
self.configure(text=retval)
def grid_configure(self):
self.grid(padx=_configuration.channel_xpadding, sticky=(tk.N, tk.S))
@@ -228,15 +229,18 @@ class Bus(ChannelLabelFrame):
class ChannelFrame(ttk.Frame):
label_cache = {"strip": list(), "bus": list()}
def init(self, parent, id):
super().__init__(parent)
self.parent = parent
self.id = id
self.phys_in, self.virt_in = parent.kind.ins
self.phys_out, self.virt_out = parent.kind.outs
self.label_cache = {
"strip": [""] * (self.phys_in + self.virt_in),
"bus": [""] * (self.phys_out + self.virt_out),
}
self.parent.subject.add(self)
self.update_labels()
@property
def target(self):
@@ -258,13 +262,13 @@ class ChannelFrame(ttk.Frame):
if isinstance(frame, ttk.LabelFrame)
)
def update_labels(self):
for labelframe in self.labelframes:
labelframe.on_update("labelframe")
def on_update(self, subject):
if subject == "pdirty":
target = getattr(self.target, self.id)
num = getattr(self.parent.kind, f"num_{self.id}")
if self.label_cache[self.id] != [target[i].label for i in range(num)]:
for labelframe in self.labelframes:
labelframe.on_update("labelframe")
self.update_labels()
def grid_configure(self):
[
@@ -280,7 +284,7 @@ class ChannelFrame(ttk.Frame):
setattr(self.parent, f"{self.identifier}_frame", None)
def _make_channelframe(parent, id):
def _make_channelframe(parent, identifier):
"""
Creates a Channel Frame class of type strip or bus
"""
@@ -288,29 +292,33 @@ def _make_channelframe(parent, id):
phys_in, virt_in = parent.kind.ins
phys_out, virt_out = parent.kind.outs
def init_labels(self, id):
def init_labels(self):
"""
Grids each labelframe, grid_removes any without a label
"""
for i, labelframe in enumerate(
getattr(self, "strips" if id == "strip" else "buses")
getattr(self, "strips" if identifier == "strip" else "buses")
):
labelframe.grid(row=0, column=i)
if not labelframe.target.label:
label = labelframe.target.label
if not label:
self.columnconfigure(i, minsize=0)
labelframe.grid_remove()
self.label_cache[identifier][i] = label
def init_strip(self, *args, **kwargs):
self.init(parent, id)
self.strips = tuple(Strip(self, i, id) for i in range(phys_in + virt_in))
self.init(parent, identifier)
self.strips = tuple(
Strip(self, i, identifier) for i in range(phys_in + virt_in)
)
self.grid(row=0, column=0, sticky=(tk.W))
self.grid_configure()
init_labels(self, id)
init_labels(self)
def init_bus(self, *args, **kwargs):
self.init(parent, id)
self.buses = tuple(Bus(self, i, id) for i in range(phys_out + virt_out))
self.init(parent, identifier)
self.buses = tuple(Bus(self, i, identifier) for i in range(phys_out + virt_out))
if _configuration.extended:
if _configuration.extends_horizontal:
self.grid(row=0, column=2, sticky=(tk.W))
@@ -319,11 +327,11 @@ def _make_channelframe(parent, id):
else:
self.grid(row=0, column=0)
self.grid_configure()
init_labels(self, id)
init_labels(self)
if id == "strip":
if identifier == "strip":
CHANNELFRAME_cls = type(
f"ChannelFrame{id.capitalize()}",
f"ChannelFrame{identifier.capitalize()}",
(ChannelFrame,),
{
"__init__": init_strip,
@@ -331,7 +339,7 @@ def _make_channelframe(parent, id):
)
else:
CHANNELFRAME_cls = type(
f"ChannelFrame{id.capitalize()}",
f"ChannelFrame{identifier.capitalize()}",
(ChannelFrame,),
{
"__init__": init_bus,

View File

@@ -227,7 +227,7 @@ class Menus(tk.Menu):
if fn := getattr(self.target.command, cmd):
fn()
if cmd == "shutdown":
self.parent.destroy()
self.parent.on_close_window()
def action_set_voicemeeter(self, cmd, val=True):
if cmd == "lock":