preset browser widget / lock preset
This commit is contained in:
@@ -19,6 +19,7 @@ import threading
|
||||
from togglewidget import ToggleWidget
|
||||
from faderwidget import FaderWidget
|
||||
from transportwidget import TransportWidget
|
||||
from presetwidget import PresetWidget
|
||||
|
||||
from palette import (
|
||||
PALETTE,
|
||||
@@ -100,6 +101,7 @@ midi_in_port = None
|
||||
fader_show_hide_config = False
|
||||
transport_show_hide_config = False
|
||||
toggle_show_hide_config = False
|
||||
preset_switch_locked = False
|
||||
|
||||
uuid_presets_matched = []
|
||||
uuid_presets_received_values = []
|
||||
@@ -163,6 +165,14 @@ buttonImport = QPushButton("Import")
|
||||
buttonImport.setFixedWidth(55)
|
||||
buttonImport.clicked.connect(lambda: import_preset())
|
||||
|
||||
checkbox_lock_preset = QCheckBox("Lock Preset")
|
||||
checkbox_lock_preset.setStyleSheet("color: #aaa; font-size: 11px;")
|
||||
checkbox_lock_preset.setChecked(False)
|
||||
def on_lock_preset_toggled(checked):
|
||||
global preset_switch_locked
|
||||
preset_switch_locked = checked
|
||||
checkbox_lock_preset.toggled.connect(on_lock_preset_toggled)
|
||||
|
||||
#save status label (should be used for other stuff as well) -> save_status_label
|
||||
labelStatus = QLabel("")
|
||||
labelStatus.setStyleSheet("color: #00e676; font-style: italic;")
|
||||
@@ -488,42 +498,16 @@ textedit_osc_out_log.setStyleSheet("""
|
||||
""")
|
||||
|
||||
# MARK: PRESET BROWSER ROW MODULE
|
||||
# REFACTOR MAP: Old names → New names
|
||||
# self.browser_back_spin → spinner_preset_browser_back
|
||||
# self.browser_fwd_spin → spinner_preset_browser_fwd
|
||||
|
||||
# Widget: label_preset_browser_title
|
||||
label_preset_browser_title = QLabel("Preset Browser")
|
||||
|
||||
# Layout: hstack_preset_browser
|
||||
hstack_preset_browser = QHBoxLayout()
|
||||
hstack_preset_browser.setSpacing(8)
|
||||
|
||||
# Widget: button_preset_browser_back
|
||||
button_preset_browser_back = QPushButton("◀")
|
||||
button_preset_browser_back.setFixedSize(36, 28)
|
||||
preset_browser_back = PresetWidget(label="Back", default_cc=22)
|
||||
preset_browser_fwd = PresetWidget(label="Fwd", default_cc=23)
|
||||
preset_browsers = [preset_browser_back, preset_browser_fwd]
|
||||
|
||||
# Widget: spinner_preset_browser_back
|
||||
spinner_preset_browser_back = QSpinBox()
|
||||
spinner_preset_browser_back.setMinimum(1)
|
||||
spinner_preset_browser_back.setMaximum(127)
|
||||
spinner_preset_browser_back.setValue(22)
|
||||
spinner_preset_browser_back.setFixedWidth(55)
|
||||
|
||||
# Widget: button_preset_browser_fwd
|
||||
button_preset_browser_fwd = QPushButton("▶")
|
||||
button_preset_browser_fwd.setFixedSize(36, 28)
|
||||
|
||||
# Widget: spinner_preset_browser_fwd
|
||||
spinner_preset_browser_fwd = QSpinBox()
|
||||
spinner_preset_browser_fwd.setMinimum(1)
|
||||
spinner_preset_browser_fwd.setMaximum(127)
|
||||
spinner_preset_browser_fwd.setValue(23)
|
||||
spinner_preset_browser_fwd.setFixedWidth(55)
|
||||
|
||||
# Widget: spacer_preset_browser
|
||||
spacer_preset_browser = QWidget()
|
||||
spacer_preset_browser.setFixedWidth(12)
|
||||
# show/hide state (mirrors fader/toggle pattern)
|
||||
preset_browser_show_hide_config = False
|
||||
|
||||
# MARK: TRANSPORT MODULE
|
||||
# REFACTOR MAP: Old names → New names
|
||||
@@ -701,6 +685,13 @@ button_transport_show_hide_config.setStyleSheet(_show_hide_btn_style)
|
||||
hstack_row_toggle_control_buttons = QHBoxLayout()
|
||||
hstack_row_toggle_control_buttons.setSpacing(8)
|
||||
|
||||
# Widget: button_preset_browser_show_hide_config
|
||||
button_preset_browser_show_hide_config = QPushButton("Hide Parameters")
|
||||
button_preset_browser_show_hide_config.setFixedWidth(120)
|
||||
button_preset_browser_show_hide_config.setCheckable(True)
|
||||
button_preset_browser_show_hide_config.setFlat(True)
|
||||
button_preset_browser_show_hide_config.setStyleSheet(_show_hide_btn_style)
|
||||
|
||||
# Widget: button_toggle_show_hide_config
|
||||
button_toggle_show_hide_config = QPushButton("Hide Parameters")
|
||||
button_toggle_show_hide_config.setFixedWidth(120)
|
||||
@@ -756,6 +747,7 @@ class MainWindow(QMainWindow):
|
||||
hstack_preset_row.addWidget(buttonRemove) #remove button
|
||||
hstack_preset_row.addWidget(buttonExport)
|
||||
hstack_preset_row.addWidget(buttonImport)
|
||||
hstack_preset_row.addWidget(checkbox_lock_preset)
|
||||
hstack_preset_row.addWidget(label_preset_uuid)
|
||||
hstack_preset_row.addWidget(button_preset_uuid_gen)
|
||||
hstack_preset_row.addWidget(button_preset_uuid_copy)
|
||||
@@ -1031,32 +1023,26 @@ class MainWindow(QMainWindow):
|
||||
global container_preset_browser
|
||||
global label_preset_browser_title
|
||||
global hstack_preset_browser
|
||||
global button_preset_browser_back
|
||||
global spinner_preset_browser_back
|
||||
global button_preset_browser_fwd
|
||||
global spinner_preset_browser_fwd
|
||||
global spacer_preset_browser
|
||||
|
||||
container_preset_browser = QWidget()
|
||||
vstack_preset_browser_container = QVBoxLayout(container_preset_browser)
|
||||
vstack_preset_browser_container.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# assemble browser controls
|
||||
hstack_preset_browser.addWidget(button_preset_browser_back)
|
||||
hstack_preset_browser.addWidget(spinner_preset_browser_back)
|
||||
hstack_preset_browser.addWidget(spacer_preset_browser)
|
||||
hstack_preset_browser.addWidget(button_preset_browser_fwd)
|
||||
hstack_preset_browser.addWidget(spinner_preset_browser_fwd)
|
||||
hstack_preset_browser.addWidget(preset_browser_back)
|
||||
hstack_preset_browser.addWidget(preset_browser_fwd)
|
||||
hstack_preset_browser.addStretch(1)
|
||||
|
||||
hstack_preset_browser_controls = QHBoxLayout()
|
||||
hstack_preset_browser_controls.addWidget(button_preset_browser_show_hide_config)
|
||||
hstack_preset_browser_controls.addStretch()
|
||||
button_preset_browser_show_hide_config.clicked.connect(preset_browser_show_hide_config_toggle)
|
||||
|
||||
vstack_preset_browser_container.addWidget(make_separator())
|
||||
vstack_preset_browser_container.addWidget(label_preset_browser_title)
|
||||
vstack_preset_browser_container.addLayout(hstack_preset_browser_controls)
|
||||
vstack_preset_browser_container.addLayout(hstack_preset_browser)
|
||||
main_layout.addWidget(container_preset_browser)
|
||||
|
||||
# connect signals
|
||||
button_preset_browser_back.clicked.connect(lambda: send_cc(spinner_preset_browser_back.value(), 127))
|
||||
button_preset_browser_fwd.clicked.connect(lambda: send_cc(spinner_preset_browser_fwd.value(), 127))
|
||||
|
||||
# MARK: CONTAINER ROWS AND WIDGETS (fader + toggle only)
|
||||
global container_rows_and_widgets
|
||||
@@ -1285,7 +1271,7 @@ def new_blank_preset():
|
||||
if not ok or not name.strip():
|
||||
return
|
||||
name = name.strip()
|
||||
loaded_presets["presets"][name] = {"faders": [], "toggles": [], "preset_uuid": "", "browser": {}, "show_hide": {}}
|
||||
loaded_presets["presets"][name] = {"faders": [], "toggles": [], "preset_uuid": "", "browser": {"back": preset_browser_back.get_state(), "fwd": preset_browser_fwd.get_state()}, "show_hide": {}}
|
||||
loaded_presets["__last_used__"] = name
|
||||
save_presets_file(loaded_presets)
|
||||
populate_preset_dropdown_menu()
|
||||
@@ -1449,7 +1435,8 @@ def _check_track_uuid_arrived():
|
||||
_track_uuid_check_pending = False
|
||||
label_osc_status.setText("No preset linked to this track")
|
||||
label_osc_status.setStyleSheet("color: #f0c040; font-size: 11px; font-style: italic;")
|
||||
ui_show_uuid_error_overlay("No preset linked to this track", "#f0c040")
|
||||
if not preset_switch_locked:
|
||||
ui_show_uuid_error_overlay("No preset linked to this track", "#f0c040")
|
||||
|
||||
def update_ui_on_osc_track_received(name):
|
||||
global _track_uuid_check_pending
|
||||
@@ -1816,14 +1803,15 @@ def preset_build_snapshot(name):
|
||||
"faders": [f.get_state() for f in faders],
|
||||
"toggles": [t.get_state() for t in toggles],
|
||||
"browser": {
|
||||
"back_cc": spinner_preset_browser_back.value(),
|
||||
"fwd_cc": spinner_preset_browser_fwd.value()
|
||||
"back": preset_browser_back.get_state(),
|
||||
"fwd": preset_browser_fwd.get_state(),
|
||||
},
|
||||
"preset_uuid": label_preset_uuid.text().strip(),
|
||||
"show_hide": {
|
||||
"fader": fader_show_hide_config,
|
||||
"toggle": toggle_show_hide_config,
|
||||
"transport": transport_show_hide_config,
|
||||
"browser": preset_browser_show_hide_config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1916,8 +1904,14 @@ def preset_load(preset):
|
||||
hstack_toggle_zone_right.addWidget(t)
|
||||
|
||||
browser = preset.get("browser", {})
|
||||
spinner_preset_browser_back.setValue(browser.get("back_cc", 22))
|
||||
spinner_preset_browser_fwd.setValue(browser.get("fwd_cc", 23))
|
||||
# migrate old format that only stored cc numbers
|
||||
if "back" not in browser and "back_cc" in browser:
|
||||
browser = {
|
||||
"back": {"label": "Back", "cc": browser.get("back_cc", 22), "ch": 1},
|
||||
"fwd": {"label": "Fwd", "cc": browser.get("fwd_cc", 23), "ch": 1},
|
||||
}
|
||||
preset_browser_back.set_state(browser.get("back", {"label": "Back", "cc": 22, "ch": 1}))
|
||||
preset_browser_fwd.set_state(browser.get("fwd", {"label": "Fwd", "cc": 23, "ch": 1}))
|
||||
|
||||
show_hide = preset.get("show_hide", {})
|
||||
fader_show_hide_config_set(show_hide.get("fader", False))
|
||||
@@ -1928,6 +1922,10 @@ def preset_load(preset):
|
||||
button_toggle_show_hide_config.setText("Show Parameters" if show_hide.get("toggle", False) else "Hide Parameters")
|
||||
button_toggle_show_hide_config.setChecked(show_hide.get("toggle", False))
|
||||
|
||||
preset_browser_show_hide_config_set(show_hide.get("browser", False))
|
||||
button_preset_browser_show_hide_config.setText("Show Parameters" if show_hide.get("browser", False) else "Hide Parameters")
|
||||
button_preset_browser_show_hide_config.setChecked(show_hide.get("browser", False))
|
||||
|
||||
label_preset_uuid.setText(preset.get("preset_uuid", ""))
|
||||
check_and_index_strip_labels()
|
||||
|
||||
@@ -2012,22 +2010,25 @@ def resolve_uuid_batch():
|
||||
global uuid_presets_matched, uuid_presets_received_values
|
||||
uuid_presets_matched = list(dict.fromkeys(uuid_presets_matched))
|
||||
if len(uuid_presets_matched) == 1:
|
||||
menuPresets.setCurrentText(uuid_presets_matched[0])
|
||||
track_name = label_osc_track.text()
|
||||
label_osc_preset.setText(uuid_presets_matched[0])
|
||||
label_osc_status.setText(f"DAW Track Selected: {track_name}")
|
||||
label_osc_status.setStyleSheet("color: #00e676; font-size: 11px; font-style: italic;")
|
||||
ui_show_rows_and_widgets()
|
||||
if not preset_switch_locked:
|
||||
menuPresets.setCurrentText(uuid_presets_matched[0])
|
||||
ui_show_rows_and_widgets()
|
||||
elif len(uuid_presets_matched) > 1:
|
||||
label_osc_status.setText("MULTIPLE PRESET IDs DETECTED")
|
||||
label_osc_status.setStyleSheet("color: #ff4444; font-size: 11px; font-style: italic;")
|
||||
ui_show_uuid_error_overlay("MULTIPLE PRESET IDs DETECTED", "#ff4444")
|
||||
QTimer.singleShot(4000, lambda: (label_osc_status.setText(""), label_osc_status.setStyleSheet("color: #00e676; font-size: 11px; font-style: italic;")))
|
||||
if not preset_switch_locked:
|
||||
ui_show_uuid_error_overlay("MULTIPLE PRESET IDs DETECTED", "#ff4444")
|
||||
QTimer.singleShot(4000, lambda: (label_osc_status.setText(""), label_osc_status.setStyleSheet("color: #00e676; font-size: 11px; font-style: italic;")))
|
||||
else:
|
||||
label_osc_status.setText("NO MATCHING ID IN PRESET LIST")
|
||||
label_osc_status.setStyleSheet("color: #ff4444; font-size: 11px; font-style: italic;")
|
||||
ui_show_uuid_error_overlay("NO MATCHING ID IN PRESET LIST", "#ff4444")
|
||||
QTimer.singleShot(4000, lambda: (label_osc_status.setText(""), label_osc_status.setStyleSheet("color: #00e676; font-size: 11px; font-style: italic;")))
|
||||
if not preset_switch_locked:
|
||||
ui_show_uuid_error_overlay("NO MATCHING ID IN PRESET LIST", "#ff4444")
|
||||
QTimer.singleShot(4000, lambda: (label_osc_status.setText(""), label_osc_status.setStyleSheet("color: #00e676; font-size: 11px; font-style: italic;")))
|
||||
uuid_presets_matched.clear()
|
||||
uuid_presets_received_values.clear()
|
||||
|
||||
@@ -2086,6 +2087,7 @@ def route_midi_message_input(event, data=None):
|
||||
|
||||
bound_fader = None
|
||||
bound_transport = None
|
||||
bound_browser = None
|
||||
if status == 0xB0:
|
||||
for fader in faders:
|
||||
if fader.hw_cc == cc_num:
|
||||
@@ -2101,13 +2103,20 @@ def route_midi_message_input(event, data=None):
|
||||
if hasattr(t, 'hw_cc') and t.hw_cc == cc_num:
|
||||
bound_transport = t
|
||||
break
|
||||
if not bound_fader and not bound_transport:
|
||||
for w in preset_browsers:
|
||||
if w.hw_cc == cc_num:
|
||||
bound_browser = w
|
||||
break
|
||||
|
||||
if status == 0xB0 and learning_strip:
|
||||
learning_strip.bind_hw_cc(cc_num, channel=channel)
|
||||
learning_strip = None
|
||||
return
|
||||
|
||||
if bound_transport:
|
||||
if bound_browser:
|
||||
bound_browser.on_hw_trigger(cc_val)
|
||||
elif bound_transport:
|
||||
print(f"[transport hw] CC{cc_num} val={cc_val} → uid={bound_transport.uid}")
|
||||
midi_receiver.hw_cc_signal.emit(bound_transport.uid, cc_val)
|
||||
elif bound_fader:
|
||||
@@ -2333,7 +2342,30 @@ def toggle_show_hide_config_toggle():
|
||||
button_toggle_show_hide_config.setText("Show Parameters" if enabled else "Hide Parameters")
|
||||
button_toggle_show_hide_config.setChecked(enabled)
|
||||
|
||||
# MARK: PRESET BROWSER SHOW HIDE CONFIG
|
||||
def preset_browser_show_hide_config_set(enabled):
|
||||
global preset_browser_show_hide_config
|
||||
preset_browser_show_hide_config = enabled
|
||||
for w in preset_browsers:
|
||||
w.grp_learn.setVisible(not enabled)
|
||||
w.arrow_lbl.setVisible(not enabled)
|
||||
w.grp_cc.setVisible(not enabled)
|
||||
w.title_edit.setVisible(not enabled)
|
||||
w.momentary_btn.setVisible(not enabled)
|
||||
w.toggle_mode_btn.setVisible(not enabled)
|
||||
w.btn.setFixedHeight(24 if enabled else 40)
|
||||
w.container.setStyleSheet(
|
||||
"QFrame#presetContainer { background: transparent; border: none; }"
|
||||
if enabled else
|
||||
"QFrame#presetContainer { background-color: #4a5568; border-radius: 6px; border: 2px solid rgba(0,0,0,0.3); }"
|
||||
)
|
||||
|
||||
def preset_browser_show_hide_config_toggle():
|
||||
global preset_browser_show_hide_config
|
||||
enabled = not preset_browser_show_hide_config
|
||||
preset_browser_show_hide_config_set(enabled)
|
||||
button_preset_browser_show_hide_config.setText("Show Parameters" if enabled else "Hide Parameters")
|
||||
button_preset_browser_show_hide_config.setChecked(enabled)
|
||||
|
||||
|
||||
# VS Code dark theme palette
|
||||
|
||||
Reference in New Issue
Block a user