mirror of
https://github.com/onyx-and-iris/voicemeeter-compact.git
synced 2026-03-09 19:59:13 +00:00
bus mode button now reads current mode from tkVar (more reliable). bus mono button fixed (possible to set stereo reverse)
293 lines
9.6 KiB
Python
293 lines
9.6 KiB
Python
import logging
|
|
from tkinter import ttk
|
|
|
|
from . import builders
|
|
from .data import _base_values, _configuration
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Config(ttk.Frame):
|
|
def __init__(self, parent, index, _id):
|
|
super().__init__(parent)
|
|
self.parent = parent
|
|
self.index = index
|
|
self.id = _id
|
|
self.logger = logger.getChild(self.__class__.__name__)
|
|
self.styletable = parent.styletable
|
|
self.phys_in, self.virt_in = parent.kind.ins
|
|
self.phys_out, self.virt_out = parent.kind.outs
|
|
|
|
self.parent.subject.add(self)
|
|
|
|
@property
|
|
def identifier(self):
|
|
return self.id
|
|
|
|
@property
|
|
def target(self):
|
|
"""returns the current interface"""
|
|
|
|
return self.parent.target
|
|
|
|
def getter(self, param):
|
|
param = param.split('.')
|
|
try:
|
|
if len(param) == 2:
|
|
target = getattr(self.target, param[0])
|
|
return getattr(target, param[1])
|
|
else:
|
|
return getattr(self.target, param[0])
|
|
except AttributeError as e:
|
|
self.logger.error(f'{type(e).__name__}: {e}')
|
|
|
|
def setter(self, param, value):
|
|
param = param.split('.')
|
|
try:
|
|
if len(param) == 2:
|
|
target = getattr(self.target, param[0])
|
|
setattr(target, param[1], value)
|
|
else:
|
|
setattr(self.target, param[0], value)
|
|
except AttributeError as e:
|
|
self.logger(f'{type(e).__name__}: {e}')
|
|
|
|
def scale_press(self, *args):
|
|
self.after(1, self.remove_events)
|
|
|
|
def remove_events(self):
|
|
self.parent.target.event.remove('pdirty')
|
|
self.parent.target.event.remove('ldirty')
|
|
|
|
def scale_release(self, *args):
|
|
_base_values.run_update = False
|
|
self.after(1, self.add_events)
|
|
|
|
def add_events(self):
|
|
self.parent.target.event.add('pdirty')
|
|
self.parent.target.event.add('ldirty')
|
|
self.after(350, self.resume_updates)
|
|
|
|
def pause_updates(self, func, *args):
|
|
"""function wrapper, adds a 50ms delay on updates"""
|
|
_base_values.run_update = False
|
|
|
|
func(*args)
|
|
|
|
self.after(50, self.resume_updates)
|
|
|
|
def resume_updates(self):
|
|
_base_values.run_update = True
|
|
|
|
def scale_enter(self, param, *args):
|
|
val = self.slider_vars[self.slider_params.index(param)].get()
|
|
self.parent.nav_frame.info_text.set(round(val, 1))
|
|
|
|
def scale_leave(self, *args):
|
|
self.parent.nav_frame.info_text.set('')
|
|
|
|
def scale_callback(self, param, *args):
|
|
"""callback function for scale widget"""
|
|
|
|
val = self.slider_vars[self.slider_params.index(param)].get()
|
|
self.setter(param, round(val, 1))
|
|
self.parent.nav_frame.info_text.set(round(val, 1))
|
|
|
|
def reset_scale(self, param, val, *args):
|
|
self.setter(param, val)
|
|
self.slider_vars[self.slider_params.index(param)].set(val)
|
|
|
|
def toggle_p(self, param):
|
|
val = self.bool_param_vars[self.bool_params.index(param)].get()
|
|
self.setter(param, val)
|
|
if not _configuration.themes_enabled:
|
|
self.styletable.configure(
|
|
f'{param}.TButton', background=f'{"green" if val else "white"}'
|
|
)
|
|
|
|
def on_update(self, subject):
|
|
"""update parameters"""
|
|
if subject == 'pdirty':
|
|
self.sync()
|
|
|
|
|
|
class StripConfig(Config):
|
|
def __init__(self, parent, index, _id):
|
|
super().__init__(parent, index, _id)
|
|
self.grid(column=0, row=1, columnspan=4, padx=(2,))
|
|
self.builder = builders.StripConfigFrameBuilder(self)
|
|
self.builder.setup()
|
|
self.make_row_0()
|
|
self.make_row_1()
|
|
self.make_row_2()
|
|
self.builder.grid_configure()
|
|
|
|
self.parent.target.clear_dirty()
|
|
self.sync()
|
|
|
|
@property
|
|
def target(self):
|
|
"""returns the strip class for this configframe in the current interface"""
|
|
|
|
_target = super(StripConfig, self).target
|
|
return getattr(_target, self.identifier)[self.index]
|
|
|
|
def make_row_0(self):
|
|
if self.index < self.phys_in:
|
|
if self.parent.kind.name == 'basic':
|
|
self.builder.create_audibility_slider()
|
|
else:
|
|
self.builder.create_comp_slider()
|
|
self.builder.create_gate_slider()
|
|
self.builder.create_limit_slider()
|
|
|
|
def make_row_1(self):
|
|
self.builder.create_a_buttons()
|
|
self.builder.create_b_buttons()
|
|
|
|
def make_row_2(self):
|
|
self.builder.create_param_buttons()
|
|
|
|
def toggle_a(self, param):
|
|
val = self.phys_out_params_vars[self.phys_out_params.index(param)].get()
|
|
self.setter(param, val)
|
|
if not _configuration.themes_enabled:
|
|
self.styletable.configure(
|
|
f'{param}.TButton', background=f'{"green" if val else "white"}'
|
|
)
|
|
|
|
def toggle_b(self, param):
|
|
val = self.virt_out_params_vars[self.virt_out_params.index(param)].get()
|
|
self.setter(param, val)
|
|
if not _configuration.themes_enabled:
|
|
self.styletable.configure(
|
|
f'{param}.TButton', background=f'{"green" if val else "white"}'
|
|
)
|
|
|
|
def teardown(self):
|
|
self.builder.teardown()
|
|
|
|
def sync(self):
|
|
[
|
|
self.phys_out_params_vars[i].set(self.getter(param))
|
|
for i, param in enumerate(self.phys_out_params)
|
|
]
|
|
[
|
|
self.virt_out_params_vars[i].set(self.getter(param))
|
|
for i, param in enumerate(self.virt_out_params)
|
|
]
|
|
[
|
|
self.bool_param_vars[i].set(self.getter(param))
|
|
for i, param in enumerate(self.bool_params)
|
|
]
|
|
[
|
|
self.slider_vars[i].set(self.getter(param))
|
|
for i, param in enumerate(self.slider_params)
|
|
if self.index < self.phys_in
|
|
]
|
|
|
|
if not _configuration.themes_enabled:
|
|
[
|
|
self.styletable.configure(
|
|
f'{param}.TButton',
|
|
background=f'{"green" if self.phys_out_params_vars[i].get() else "white"}',
|
|
)
|
|
for i, param in enumerate(self.phys_out_params)
|
|
]
|
|
[
|
|
self.styletable.configure(
|
|
f'{param}.TButton',
|
|
background=f'{"green" if self.virt_out_params_vars[i].get() else "white"}',
|
|
)
|
|
for i, param in enumerate(self.virt_out_params)
|
|
]
|
|
[
|
|
self.styletable.configure(
|
|
f'{param}.TButton',
|
|
background=f'{"green" if self.param_vars[i].get() else "white"}',
|
|
)
|
|
for i, param in enumerate(self.bool_params)
|
|
]
|
|
|
|
|
|
class BusConfig(Config):
|
|
def __init__(self, parent, index, _id):
|
|
super().__init__(parent, index, _id)
|
|
if _configuration.extends_horizontal:
|
|
self.grid(column=0, row=1, columnspan=4, padx=(2,))
|
|
else:
|
|
self.grid(column=0, row=3, columnspan=4, padx=(2,))
|
|
self.builder = builders.BusConfigFrameBuilder(self)
|
|
self.builder.setup()
|
|
self.make_row_0()
|
|
self.make_row_1()
|
|
self.builder.grid_configure()
|
|
|
|
self.parent.target.clear_dirty()
|
|
self.sync()
|
|
|
|
@property
|
|
def target(self):
|
|
"""returns the bus class for this configframe in the current interface"""
|
|
|
|
_target = super(BusConfig, self).target
|
|
return getattr(_target, self.identifier)[self.index]
|
|
|
|
def make_row_0(self):
|
|
self.builder.create_bus_mode_button()
|
|
|
|
def make_row_1(self):
|
|
self.builder.create_bus_mono_button()
|
|
self.builder.create_param_buttons()
|
|
|
|
def current_bus_mode(self):
|
|
return self.target.mode.get()
|
|
|
|
def rotate_bus_modes_right(self, *args):
|
|
current_mode = self.bus_mode_map_reverse[self.bus_mode_label_text.get()]
|
|
current_index = self.bus_modes.index(current_mode)
|
|
next_index = (current_index + 1) % len(self.bus_modes)
|
|
next_mode = self.bus_modes[next_index]
|
|
|
|
setattr(self.target.mode, next_mode, True)
|
|
self.bus_mode_label_text.set(self.bus_mode_map[next_mode])
|
|
|
|
def rotate_bus_modes_left(self, *args):
|
|
current_mode = self.bus_mode_map_reverse[self.bus_mode_label_text.get()]
|
|
current_index = self.bus_modes.index(current_mode)
|
|
prev_index = (current_index - 1) % len(self.bus_modes)
|
|
prev_mode = self.bus_modes[prev_index]
|
|
|
|
setattr(self.target.mode, prev_mode, True)
|
|
self.bus_mode_label_text.set(self.bus_mode_map[prev_mode])
|
|
|
|
def rotate_mono_right(self, *args):
|
|
current_val = self.mono_modes.index(self.bus_mono_label_text.get())
|
|
next_val = (current_val + 1) % 3
|
|
self.bus_mono_label_text.set(self.mono_modes[next_val])
|
|
self.setter('mono', next_val)
|
|
|
|
def rotate_mono_left(self, *args):
|
|
current_val = self.mono_modes.index(self.bus_mono_label_text.get())
|
|
next_val = (current_val - 1) % 3
|
|
self.bus_mono_label_text.set(self.mono_modes[next_val])
|
|
self.setter('mono', next_val)
|
|
|
|
def teardown(self):
|
|
self.builder.teardown()
|
|
|
|
def sync(self):
|
|
[
|
|
self.bool_param_vars[i].set(self.getter(param))
|
|
for i, param in enumerate(self.bool_params)
|
|
]
|
|
self.bus_mode_label_text.set(self.bus_mode_map[self.current_bus_mode()])
|
|
if not _configuration.themes_enabled:
|
|
[
|
|
self.styletable.configure(
|
|
f'{param}.TButton',
|
|
background=f'{"green" if self.bool_param_vars[i].get() else "white"}',
|
|
)
|
|
for i, param in enumerate(self.bool_params)
|
|
]
|