onyx-and-iris 81a5497a32 add feedback for comp/gate sliders.
bus mode button now reads current mode from tkVar (more reliable).

bus mono button fixed (possible to set stereo reverse)
2026-03-08 21:13:30 +00:00

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)
]