fix app title.

merge subject classes.

modify obsevers callback

ensure sunvalley theme loaded only once.

minor version bump
This commit is contained in:
onyx-and-iris 2022-06-20 00:09:27 +01:00
parent 60e55fd7f9
commit fd30a5ef0d
8 changed files with 59 additions and 70 deletions

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "voicemeeter-compact"
version = "1.0.4"
version = "1.0.5"
description = "A Compact Voicemeeter Remote App"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"

View File

@ -22,7 +22,7 @@ class App(tk.Tk):
"""
APP_cls = type(
f"Voicemeeter{kind.name}.Compact",
f"Voicemeeter{kind}.Compact",
(cls,),
{
"kind": kind,
@ -38,8 +38,7 @@ class App(tk.Tk):
if icon_path.is_file():
self.iconbitmap(str(icon_path))
self.minsize(275, False)
self.subject_pdirty = Subject()
self.subject_ldirty = Subject()
self.subject = Subject()
self.strip_levels = None
self.bus_levels = None
self["menu"] = Menus(self, vmr)
@ -92,26 +91,14 @@ class App(tk.Tk):
if self.kind.name == "potato":
self.builder.create_banner()
def on_update(self, subject, data):
def on_update(self, subject):
"""called whenever notified of update"""
if not _base_values.in_scale_button_1:
if subject == "pdirty":
self.after(1, self.notify_pdirty)
self.subject.notify("pdirty")
elif subject == "ldirty" and not _base_values.dragging:
(
self.strip_levels,
self.strip_comp,
self.bus_levels,
self.bus_comp,
) = data
self.after(1, self.notify_ldirty)
def notify_pdirty(self):
self.subject_pdirty.notify()
def notify_ldirty(self):
self.subject_ldirty.notify()
self.subject.notify("ldirty")
def _destroy_top_level_frames(self):
"""
@ -122,8 +109,7 @@ class App(tk.Tk):
Destroy all top level frames.
"""
self.target.subject.remove(self)
self.subject_pdirty.clear()
self.subject_ldirty.clear()
self.subject.clear()
[
frame.destroy()
for frame in self.winfo_children()

View File

@ -37,8 +37,9 @@ class MainFrameBuilder(AbstractBuilder):
)
self.app.resizable(False, False)
if _configuration.themes_enabled:
print("Applying Sunvalley Theme")
if sv_ttk.get_theme() not in ("light", "dark"):
sv_ttk.set_theme(_configuration.theme_mode)
print(f"Sunvalley {sv_ttk.get_theme().capitalize()} Theme applied")
def create_channelframe(self, type_):
if type_ == "strip":
@ -301,7 +302,7 @@ class ChannelConfigFrameBuilder(AbstractBuilder):
def teardown(self):
"""Deregister as observable, then destroy frame"""
self.configframe.parent.subject_pdirty.remove(self.configframe)
self.configframe.parent.subject.remove(self.configframe)
self.configframe.destroy()
def grid_configure(self):

View File

@ -118,10 +118,10 @@ class ChannelLabelFrame(ttk.LabelFrame):
retval = f"{retval[:8]}.."
if not retval:
self.parent.columnconfigure(self.index, minsize=0)
self.parent.parent.subject_ldirty.remove(self)
self.parent.parent.subject.remove(self)
self.grid_remove()
else:
self.parent.parent.subject_ldirty.add(self)
self.parent.parent.subject.add(self)
self.grid()
self.configure(text=retval)
@ -167,10 +167,10 @@ class Strip(ChannelLabelFrame):
Checks offset against expected level array size to avoid a race condition
"""
if self.level_offset + 1 < len(self.parent.parent.strip_levels):
if self.level_offset + 1 < len(self.parent.target.strip_levels):
if (
any(
self.parent.parent.strip_comp[
self.parent.target._strip_comp[
self.level_offset : self.level_offset + 1
]
)
@ -178,7 +178,7 @@ class Strip(ChannelLabelFrame):
):
val = self.convert_level(
max(
self.parent.parent.strip_levels[
self.parent.target.strip_levels[
self.level_offset : self.level_offset + 1
]
)
@ -187,9 +187,9 @@ class Strip(ChannelLabelFrame):
(0 if self.mute.get() else 100 + val - 18 + self.gain.get())
)
def on_update(self):
def on_update(self, subject):
"""update levels"""
if subject == "ldirty":
self.after(_base_values.ldelay, self.upd_levels)
@ -208,10 +208,10 @@ class Bus(ChannelLabelFrame):
return getattr(_target, self.identifier)[self.index]
def upd_levels(self):
if self.level_offset + 1 < len(self.parent.parent.bus_levels):
if self.level_offset + 1 < len(self.parent.target.bus_levels):
if (
any(
self.parent.parent.bus_comp[
self.parent.target._bus_comp[
self.level_offset : self.level_offset + 1
]
)
@ -219,16 +219,16 @@ class Bus(ChannelLabelFrame):
):
val = self.convert_level(
max(
self.parent.parent.bus_levels[
self.parent.target.bus_levels[
self.level_offset : self.level_offset + 1
]
)
)
self.level.set((0 if self.mute.get() else 100 + val - 18))
def on_update(self):
def on_update(self, subject):
"""update levels"""
if subject == "ldirty":
self.after(_base_values.ldelay, self.upd_levels)
@ -241,7 +241,7 @@ class ChannelFrame(ttk.Frame):
self.phys_out, self.virt_out = parent.kind.outs
# registers channelframe as pdirty observer
self.parent.subject_pdirty.add(self)
self.parent.subject.add(self)
@property
def target(self):
@ -273,16 +273,16 @@ class ChannelFrame(ttk.Frame):
def upd_labelframe(self, labelframe):
labelframe.sync()
def on_update(self):
def on_update(self, subject):
"""update parameters"""
if subject == "pdirty":
for labelframe in self.labelframes:
self.after(1, self.upd_labelframe, labelframe)
def teardown(self):
# deregisters channelframe as pdirty observer
self.parent.subject_pdirty.remove(self)
self.parent.subject.remove(self)
self.destroy()
setattr(self.parent, f"{self.identifier}_frame", None)

View File

@ -16,7 +16,7 @@ class Config(ttk.Frame):
self.phys_in, self.virt_in = parent.kind.ins
self.phys_out, self.virt_out = parent.kind.outs
self.parent.subject_pdirty.add(self)
self.parent.subject.add(self)
@property
def identifier(self):
@ -68,9 +68,9 @@ class Config(ttk.Frame):
f"{param}.TButton", background=f'{"green" if val else "white"}'
)
def on_update(self):
def on_update(self, subject):
"""update parameters"""
if subject == "pdirty":
self.after(_base_values.pdelay, self.sync)

View File

@ -120,10 +120,10 @@ class GainLayer(ttk.LabelFrame):
retval = f"{retval[:8]}.."
if not retval:
self.parent.columnconfigure(self.index, minsize=0)
self.parent.parent.subject_ldirty.remove(self)
self.parent.parent.subject.remove(self)
self.grid_remove()
else:
self.parent.parent.subject_ldirty.add(self)
self.parent.parent.subject.add(self)
self.grid()
self.configure(text=retval)
@ -138,10 +138,10 @@ class GainLayer(ttk.LabelFrame):
Checks offset against expected level array size to avoid a race condition
"""
if self.level_offset + 1 < len(self.parent.parent.strip_levels):
if self.level_offset + 1 < len(self.parent.target.strip_levels):
if (
any(
self.parent.parent.strip_comp[
self.parent.target._strip_comp[
self.level_offset : self.level_offset + 1
]
)
@ -149,7 +149,7 @@ class GainLayer(ttk.LabelFrame):
):
val = self.convert_level(
max(
self.parent.parent.strip_levels[
self.parent.target.strip_levels[
self.level_offset : self.level_offset + 1
]
)
@ -163,9 +163,9 @@ class GainLayer(ttk.LabelFrame):
)
)
def on_update(self):
def on_update(self, subject):
"""update levels"""
if subject == "ldirty":
self.after(_base_values.ldelay, self.upd_levels)
def grid_configure(self):
@ -222,7 +222,7 @@ class SubMixFrame(ttk.Frame):
self.grid(row=2, column=0, sticky=(tk.W))
# registers submixframe as pdirty observer
self.parent.subject_pdirty.add(self)
self.parent.subject.add(self)
self.grid_configure()
"""
@ -263,11 +263,12 @@ class SubMixFrame(ttk.Frame):
def upd_labelframe(self, labelframe):
labelframe.sync()
def on_update(self):
def on_update(self, subject):
if subject == "pdirty":
for labelframe in self.labelframes:
self.after(1, self.upd_labelframe, labelframe)
def teardown(self):
# deregisters submixframe as pdirty observer
self.parent.subject_pdirty.remove(self)
self.parent.subject.remove(self)
self.destroy()

View File

@ -10,7 +10,7 @@ class Navigation(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.grid(row=0, column=3, padx=(0, 5), pady=(5, 5), sticky=(tk.W, tk.E))
self.grid(row=0, column=3, padx=(0, 2), pady=(5, 5), sticky=(tk.W, tk.E))
self.styletable = self.parent.styletable
self.builder = builders.NavigationFrameBuilder(self)

View File

@ -1,35 +1,36 @@
class Subject:
"""Adds support for observers"""
def __init__(self):
"""list of current observers"""
self._observables = []
self._observers = list()
def notify(self, modifier=None):
"""run callbacks on update"""
for observer in self._observables:
observer.on_update()
[o.on_update(modifier) for o in self._observers]
def add(self, observer):
"""adds an observer to observables"""
if observer not in self._observables:
self._observables.append(observer)
if observer not in self._observers:
self._observers.append(observer)
def remove(self, observer):
"""removes an observer from observables"""
try:
self._observables.remove(observer)
self._observers.remove(observer)
except ValueError:
pass
def get(self) -> list:
"""returns the current observables"""
return self._observables
return self._observers
def clear(self):
"""clears the observables list"""
self._observables.clear()
self._observers.clear()