Layout panel wired, section visibility, preset management improvements
- Wire all 5 Layout panel section toggles (Preset Browser, Big Title, Fader Row, Toggle Row, Transport Row) - Replace checkboxes with clickable title buttons (highlighted=visible, dimmed=hidden) - Move Big Title inside fader container, between Hide Params button and fader strips - Wrap transport/fader/toggle rows in container widgets for setVisible support - Reposition separator between preset browser and mixer row - Open Layout panel by default on launch - Add Duplicate preset button (auto-generates new UUID) - Add Rename preset button - Swap preset browser label and show-hide button order - Persist section visibility state per preset under new 'sections' key Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -166,6 +166,14 @@ buttonImport = QPushButton("Import")
|
|||||||
buttonImport.setFixedWidth(55)
|
buttonImport.setFixedWidth(55)
|
||||||
buttonImport.clicked.connect(lambda: import_preset())
|
buttonImport.clicked.connect(lambda: import_preset())
|
||||||
|
|
||||||
|
buttonDuplicate = QPushButton("Duplicate")
|
||||||
|
buttonDuplicate.setFixedWidth(75)
|
||||||
|
buttonDuplicate.clicked.connect(lambda: duplicate_preset())
|
||||||
|
|
||||||
|
buttonRename = QPushButton("Rename")
|
||||||
|
buttonRename.setFixedWidth(65)
|
||||||
|
buttonRename.clicked.connect(lambda: rename_preset())
|
||||||
|
|
||||||
checkbox_lock_preset = QCheckBox("Lock Preset")
|
checkbox_lock_preset = QCheckBox("Lock Preset")
|
||||||
checkbox_lock_preset.setStyleSheet("color: #aaa; font-size: 11px;")
|
checkbox_lock_preset.setStyleSheet("color: #aaa; font-size: 11px;")
|
||||||
checkbox_lock_preset.setChecked(True)
|
checkbox_lock_preset.setChecked(True)
|
||||||
@@ -578,32 +586,29 @@ _section_sep.setFrameShape(QFrame.Shape.HLine)
|
|||||||
_section_sep.setStyleSheet("color: #3a3a3a;")
|
_section_sep.setStyleSheet("color: #3a3a3a;")
|
||||||
vstack_layout_panel.addWidget(_section_sep)
|
vstack_layout_panel.addWidget(_section_sep)
|
||||||
|
|
||||||
# Section rows (layout only — not wired yet)
|
_section_btn_style = (
|
||||||
_section_rows = [
|
"QPushButton { background: transparent; border: none; color: #ffffff;"
|
||||||
("Preset Browser", "chk_section_preset_browser"),
|
" font-size: 12px; font-weight: bold; text-align: left; padding: 4px 6px; }"
|
||||||
("Big Title", "chk_section_big_title"),
|
"QPushButton:!checked { color: #444444; font-weight: normal; }"
|
||||||
("Fader Row", "chk_section_fader_row"),
|
)
|
||||||
("Toggle Row", "chk_section_toggle_row"),
|
|
||||||
("Transport Row", "chk_section_transport_row"),
|
def _make_section_row(label_text):
|
||||||
]
|
btn = QPushButton(label_text)
|
||||||
from PyQt6.QtWidgets import QCheckBox
|
btn.setCheckable(True)
|
||||||
for _lbl, _attr in _section_rows:
|
btn.setChecked(True)
|
||||||
_row = QWidget()
|
btn.setFlat(True)
|
||||||
_row.setStyleSheet("background: transparent;")
|
btn.setStyleSheet(_section_btn_style)
|
||||||
_hbox = QHBoxLayout(_row)
|
return btn
|
||||||
_hbox.setContentsMargins(4, 2, 4, 2)
|
|
||||||
_hbox.setSpacing(8)
|
chk_section_preset_browser = _make_section_row("Preset Browser")
|
||||||
_chk = QCheckBox()
|
chk_section_big_title = _make_section_row("Big Title")
|
||||||
_chk.setChecked(True)
|
chk_section_fader_row = _make_section_row("Fader Row")
|
||||||
_chk.setFixedSize(16, 16)
|
chk_section_toggle_row = _make_section_row("Toggle Row")
|
||||||
_name_lbl = QLabel(_lbl)
|
chk_section_transport_row = _make_section_row("Transport Row")
|
||||||
_name_lbl.setStyleSheet("color: #d4d4d4; font-size: 12px; background: transparent;")
|
|
||||||
_hbox.addWidget(_chk)
|
for _btn in (chk_section_preset_browser, chk_section_big_title, chk_section_fader_row, chk_section_toggle_row, chk_section_transport_row):
|
||||||
_hbox.addWidget(_name_lbl)
|
vstack_layout_panel.addWidget(_btn)
|
||||||
_hbox.addStretch()
|
del _btn
|
||||||
globals()[_attr] = _chk
|
|
||||||
vstack_layout_panel.addWidget(_row)
|
|
||||||
del _lbl, _attr, _row, _hbox, _chk, _name_lbl, _section_rows
|
|
||||||
|
|
||||||
vstack_layout_panel.addStretch()
|
vstack_layout_panel.addStretch()
|
||||||
|
|
||||||
@@ -855,6 +860,8 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_preset_row.addWidget(buttonSave) #save button
|
hstack_preset_row.addWidget(buttonSave) #save button
|
||||||
hstack_preset_row.addWidget(buttonSaveAs) #save as button
|
hstack_preset_row.addWidget(buttonSaveAs) #save as button
|
||||||
hstack_preset_row.addWidget(buttonRemove) #remove button
|
hstack_preset_row.addWidget(buttonRemove) #remove button
|
||||||
|
hstack_preset_row.addWidget(buttonDuplicate)
|
||||||
|
hstack_preset_row.addWidget(buttonRename)
|
||||||
hstack_preset_row.addWidget(buttonExport)
|
hstack_preset_row.addWidget(buttonExport)
|
||||||
hstack_preset_row.addWidget(buttonImport)
|
hstack_preset_row.addWidget(buttonImport)
|
||||||
hstack_preset_row.addWidget(checkbox_lock_preset)
|
hstack_preset_row.addWidget(checkbox_lock_preset)
|
||||||
@@ -1118,9 +1125,15 @@ class MainWindow(QMainWindow):
|
|||||||
container_midi_out_log.setVisible(False)
|
container_midi_out_log.setVisible(False)
|
||||||
|
|
||||||
#MARK: LAYOUT PANEL
|
#MARK: LAYOUT PANEL
|
||||||
container_layout_panel.setVisible(False)
|
container_layout_panel.setVisible(True)
|
||||||
|
button_layout_panel.setChecked(True)
|
||||||
|
|
||||||
main_layout.addWidget(make_separator())
|
container_transport_row = QWidget()
|
||||||
|
_vbox_transport_row = QVBoxLayout(container_transport_row)
|
||||||
|
_vbox_transport_row.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_vbox_transport_row.setSpacing(0)
|
||||||
|
_vbox_transport_row.addWidget(make_separator())
|
||||||
|
_vbox_transport_row.addSpacing(4)
|
||||||
|
|
||||||
# MARK: TRANSPORT ROW CONTROLS
|
# MARK: TRANSPORT ROW CONTROLS
|
||||||
global hstack_row_transport_control_buttons
|
global hstack_row_transport_control_buttons
|
||||||
@@ -1129,7 +1142,7 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_row_transport_control_buttons.addWidget(button_transport_show_hide_config)
|
hstack_row_transport_control_buttons.addWidget(button_transport_show_hide_config)
|
||||||
hstack_row_transport_control_buttons.addStretch()
|
hstack_row_transport_control_buttons.addStretch()
|
||||||
button_transport_show_hide_config.clicked.connect(transport_show_hide_config_toggle)
|
button_transport_show_hide_config.clicked.connect(transport_show_hide_config_toggle)
|
||||||
main_layout.addLayout(hstack_row_transport_control_buttons)
|
_vbox_transport_row.addLayout(hstack_row_transport_control_buttons)
|
||||||
|
|
||||||
#MARK: TRANSPORT ROW
|
#MARK: TRANSPORT ROW
|
||||||
|
|
||||||
@@ -1150,7 +1163,9 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_full_transport.addWidget(vsep_transport_right)
|
hstack_full_transport.addWidget(vsep_transport_right)
|
||||||
hstack_full_transport.addLayout(hstack_transport_zone_right)
|
hstack_full_transport.addLayout(hstack_transport_zone_right)
|
||||||
|
|
||||||
main_layout.addLayout(hstack_full_transport)
|
_vbox_transport_row.addLayout(hstack_full_transport)
|
||||||
|
main_layout.addWidget(container_transport_row)
|
||||||
|
chk_section_transport_row.toggled.connect(container_transport_row.setVisible)
|
||||||
|
|
||||||
#MARK: PRESET BROWSER CONTAINER
|
#MARK: PRESET BROWSER CONTAINER
|
||||||
global container_preset_browser
|
global container_preset_browser
|
||||||
@@ -1171,10 +1186,13 @@ class MainWindow(QMainWindow):
|
|||||||
button_preset_browser_show_hide_config.clicked.connect(preset_browser_show_hide_config_toggle)
|
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(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_controls)
|
||||||
|
vstack_preset_browser_container.addWidget(label_preset_browser_title)
|
||||||
vstack_preset_browser_container.addLayout(hstack_preset_browser)
|
vstack_preset_browser_container.addLayout(hstack_preset_browser)
|
||||||
main_layout.addWidget(container_preset_browser)
|
main_layout.addWidget(container_preset_browser)
|
||||||
|
main_layout.addWidget(make_separator())
|
||||||
|
|
||||||
|
chk_section_preset_browser.toggled.connect(container_preset_browser.setVisible)
|
||||||
|
|
||||||
|
|
||||||
# MARK: CONTAINER ROWS AND WIDGETS (fader + toggle only)
|
# MARK: CONTAINER ROWS AND WIDGETS (fader + toggle only)
|
||||||
@@ -1187,16 +1205,10 @@ class MainWindow(QMainWindow):
|
|||||||
controls_layout.setContentsMargins(0, 0, 0, 0)
|
controls_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
main_layout.addWidget(container_rows_and_widgets)
|
main_layout.addWidget(container_rows_and_widgets)
|
||||||
|
|
||||||
# MARK: BIG TITLE
|
container_fader_row = QWidget()
|
||||||
big_title_edit = QLineEdit("")
|
_vbox_fader_row = QVBoxLayout(container_fader_row)
|
||||||
big_title_edit.setPlaceholderText("Title")
|
_vbox_fader_row.setContentsMargins(0, 0, 0, 0)
|
||||||
big_title_edit.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
_vbox_fader_row.setSpacing(0)
|
||||||
big_title_edit.setStyleSheet(
|
|
||||||
"QLineEdit { background: transparent; border: none; border-bottom: 1px solid #3a3a3a;"
|
|
||||||
" color: #ffffff; font-size: 28px; font-weight: bold; padding: 4px 0; }"
|
|
||||||
"QLineEdit:focus { border-bottom: 1px solid #00e676; }"
|
|
||||||
)
|
|
||||||
controls_layout.addWidget(big_title_edit)
|
|
||||||
|
|
||||||
# MARK: FADER ROW CONTROLS
|
# MARK: FADER ROW CONTROLS
|
||||||
global hstack_row_fader_control_buttons
|
global hstack_row_fader_control_buttons
|
||||||
@@ -1207,7 +1219,19 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_row_fader_control_buttons.addStretch()
|
hstack_row_fader_control_buttons.addStretch()
|
||||||
button_fader_show_hide_config.clicked.connect(fader_show_hide_config_toggle)
|
button_fader_show_hide_config.clicked.connect(fader_show_hide_config_toggle)
|
||||||
button_fader_clear_all.clicked.connect(clear_all_faders)
|
button_fader_clear_all.clicked.connect(clear_all_faders)
|
||||||
controls_layout.addLayout(hstack_row_fader_control_buttons)
|
_vbox_fader_row.addLayout(hstack_row_fader_control_buttons)
|
||||||
|
|
||||||
|
# MARK: BIG TITLE
|
||||||
|
big_title_edit = QLineEdit("")
|
||||||
|
big_title_edit.setPlaceholderText("Title")
|
||||||
|
big_title_edit.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
big_title_edit.setStyleSheet(
|
||||||
|
"QLineEdit { background: transparent; border: none;"
|
||||||
|
" color: #ffffff; font-size: 28px; font-weight: bold; padding: 4px 0; }"
|
||||||
|
"QLineEdit:focus { border-bottom: 1px solid #00e676; }"
|
||||||
|
)
|
||||||
|
_vbox_fader_row.addWidget(big_title_edit)
|
||||||
|
chk_section_big_title.toggled.connect(big_title_edit.setVisible)
|
||||||
|
|
||||||
#MARK: FADERS ROW
|
#MARK: FADERS ROW
|
||||||
global hstack_full_fader
|
global hstack_full_fader
|
||||||
@@ -1224,7 +1248,7 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_full_fader.addWidget(separator_vertical_fader_zone_right)
|
hstack_full_fader.addWidget(separator_vertical_fader_zone_right)
|
||||||
hstack_full_fader.addLayout(hstack_fader_zone_right)
|
hstack_full_fader.addLayout(hstack_fader_zone_right)
|
||||||
|
|
||||||
controls_layout.addLayout(hstack_full_fader)
|
_vbox_fader_row.addLayout(hstack_full_fader)
|
||||||
|
|
||||||
global placeholder_fader_empty
|
global placeholder_fader_empty
|
||||||
placeholder_fader_empty = QWidget()
|
placeholder_fader_empty = QWidget()
|
||||||
@@ -1240,7 +1264,10 @@ class MainWindow(QMainWindow):
|
|||||||
_pf_btn.clicked.connect(fader_add)
|
_pf_btn.clicked.connect(fader_add)
|
||||||
_pf_layout.addWidget(_pf_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
_pf_layout.addWidget(_pf_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
||||||
_pf_layout.addWidget(_pf_lbl)
|
_pf_layout.addWidget(_pf_lbl)
|
||||||
controls_layout.addWidget(placeholder_fader_empty)
|
_vbox_fader_row.addWidget(placeholder_fader_empty)
|
||||||
|
|
||||||
|
controls_layout.addWidget(container_fader_row)
|
||||||
|
chk_section_fader_row.toggled.connect(container_fader_row.setVisible)
|
||||||
|
|
||||||
controls_layout.addWidget(make_separator())
|
controls_layout.addWidget(make_separator())
|
||||||
|
|
||||||
@@ -1252,6 +1279,11 @@ class MainWindow(QMainWindow):
|
|||||||
global separator_vertical_toggle_zone_right
|
global separator_vertical_toggle_zone_right
|
||||||
global hstack_toggle_zone_right
|
global hstack_toggle_zone_right
|
||||||
|
|
||||||
|
container_toggle_row = QWidget()
|
||||||
|
_vbox_toggle_row = QVBoxLayout(container_toggle_row)
|
||||||
|
_vbox_toggle_row.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_vbox_toggle_row.setSpacing(0)
|
||||||
|
|
||||||
# MARK: TOGGLE ROW CONTROLS
|
# MARK: TOGGLE ROW CONTROLS
|
||||||
global hstack_row_toggle_control_buttons
|
global hstack_row_toggle_control_buttons
|
||||||
global button_toggle_show_hide_config
|
global button_toggle_show_hide_config
|
||||||
@@ -1261,7 +1293,7 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_row_toggle_control_buttons.addStretch()
|
hstack_row_toggle_control_buttons.addStretch()
|
||||||
button_toggle_show_hide_config.clicked.connect(toggle_show_hide_config_toggle)
|
button_toggle_show_hide_config.clicked.connect(toggle_show_hide_config_toggle)
|
||||||
button_toggle_clear_all.clicked.connect(clear_all_toggles)
|
button_toggle_clear_all.clicked.connect(clear_all_toggles)
|
||||||
controls_layout.addLayout(hstack_row_toggle_control_buttons)
|
_vbox_toggle_row.addLayout(hstack_row_toggle_control_buttons)
|
||||||
|
|
||||||
#MARK: TOGGLES ROW
|
#MARK: TOGGLES ROW
|
||||||
# assemble full toggle row
|
# assemble full toggle row
|
||||||
@@ -1271,7 +1303,7 @@ class MainWindow(QMainWindow):
|
|||||||
hstack_full_toggle.addWidget(separator_vertical_toggle_zone_right)
|
hstack_full_toggle.addWidget(separator_vertical_toggle_zone_right)
|
||||||
hstack_full_toggle.addLayout(hstack_toggle_zone_right)
|
hstack_full_toggle.addLayout(hstack_toggle_zone_right)
|
||||||
|
|
||||||
controls_layout.addLayout(hstack_full_toggle)
|
_vbox_toggle_row.addLayout(hstack_full_toggle)
|
||||||
|
|
||||||
global placeholder_toggle_empty
|
global placeholder_toggle_empty
|
||||||
placeholder_toggle_empty = QWidget()
|
placeholder_toggle_empty = QWidget()
|
||||||
@@ -1287,7 +1319,10 @@ class MainWindow(QMainWindow):
|
|||||||
_pt_btn.clicked.connect(toggle_add)
|
_pt_btn.clicked.connect(toggle_add)
|
||||||
_pt_layout.addWidget(_pt_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
_pt_layout.addWidget(_pt_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
||||||
_pt_layout.addWidget(_pt_lbl)
|
_pt_layout.addWidget(_pt_lbl)
|
||||||
controls_layout.addWidget(placeholder_toggle_empty)
|
_vbox_toggle_row.addWidget(placeholder_toggle_empty)
|
||||||
|
|
||||||
|
controls_layout.addWidget(container_toggle_row)
|
||||||
|
chk_section_toggle_row.toggled.connect(container_toggle_row.setVisible)
|
||||||
|
|
||||||
controls_layout.addStretch()
|
controls_layout.addStretch()
|
||||||
|
|
||||||
@@ -1427,6 +1462,47 @@ def new_blank_preset():
|
|||||||
menuPresets.setCurrentText(name)
|
menuPresets.setCurrentText(name)
|
||||||
clear_all_strips()
|
clear_all_strips()
|
||||||
big_title_edit.setText("")
|
big_title_edit.setText("")
|
||||||
|
chk_section_preset_browser.setChecked(True)
|
||||||
|
chk_section_big_title.setChecked(True)
|
||||||
|
chk_section_fader_row.setChecked(True)
|
||||||
|
chk_section_toggle_row.setChecked(True)
|
||||||
|
chk_section_transport_row.setChecked(True)
|
||||||
|
show_save_status()
|
||||||
|
|
||||||
|
def rename_preset():
|
||||||
|
from PyQt6.QtWidgets import QInputDialog
|
||||||
|
current_name = menuPresets.currentText()
|
||||||
|
if not current_name:
|
||||||
|
return
|
||||||
|
new_name, ok = QInputDialog.getText(app_window, "Rename Preset", "New name:", text=current_name)
|
||||||
|
if not ok or not new_name.strip() or new_name.strip() == current_name:
|
||||||
|
return
|
||||||
|
new_name = new_name.strip()
|
||||||
|
loaded_presets["presets"][new_name] = loaded_presets["presets"].pop(current_name)
|
||||||
|
if loaded_presets.get("__last_used__") == current_name:
|
||||||
|
loaded_presets["__last_used__"] = new_name
|
||||||
|
save_presets_file(loaded_presets)
|
||||||
|
populate_preset_dropdown_menu()
|
||||||
|
menuPresets.setCurrentText(new_name)
|
||||||
|
show_save_status()
|
||||||
|
|
||||||
|
def duplicate_preset():
|
||||||
|
from PyQt6.QtWidgets import QInputDialog
|
||||||
|
current_name = menuPresets.currentText()
|
||||||
|
if not current_name:
|
||||||
|
return
|
||||||
|
new_name, ok = QInputDialog.getText(app_window, "Duplicate Preset", "Name for duplicate:", text=f"{current_name} Copy")
|
||||||
|
if not ok or not new_name.strip():
|
||||||
|
return
|
||||||
|
new_name = new_name.strip()
|
||||||
|
snapshot = preset_build_snapshot(current_name)
|
||||||
|
snapshot["preset_uuid"] = str(uuid.uuid4())
|
||||||
|
loaded_presets["presets"][new_name] = snapshot
|
||||||
|
loaded_presets["__last_used__"] = new_name
|
||||||
|
save_presets_file(loaded_presets)
|
||||||
|
populate_preset_dropdown_menu()
|
||||||
|
menuPresets.setCurrentText(new_name)
|
||||||
|
label_preset_uuid.setText(snapshot["preset_uuid"])
|
||||||
show_save_status()
|
show_save_status()
|
||||||
|
|
||||||
def show_save_status():
|
def show_save_status():
|
||||||
@@ -1985,6 +2061,13 @@ def preset_build_snapshot(name):
|
|||||||
"toggle": toggle_show_hide_config,
|
"toggle": toggle_show_hide_config,
|
||||||
"transport": transport_show_hide_config,
|
"transport": transport_show_hide_config,
|
||||||
"browser": preset_browser_show_hide_config,
|
"browser": preset_browser_show_hide_config,
|
||||||
|
},
|
||||||
|
"sections": {
|
||||||
|
"preset_browser": chk_section_preset_browser.isChecked(),
|
||||||
|
"big_title": chk_section_big_title.isChecked(),
|
||||||
|
"fader_row": chk_section_fader_row.isChecked(),
|
||||||
|
"toggle_row": chk_section_toggle_row.isChecked(),
|
||||||
|
"transport_row": chk_section_transport_row.isChecked(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2101,6 +2184,14 @@ def preset_load(preset):
|
|||||||
|
|
||||||
big_title_edit.setText(preset.get("big_title", ""))
|
big_title_edit.setText(preset.get("big_title", ""))
|
||||||
label_preset_uuid.setText(preset.get("preset_uuid", ""))
|
label_preset_uuid.setText(preset.get("preset_uuid", ""))
|
||||||
|
|
||||||
|
sections = preset.get("sections", {})
|
||||||
|
chk_section_preset_browser.setChecked(sections.get("preset_browser", True))
|
||||||
|
chk_section_big_title.setChecked(sections.get("big_title", True))
|
||||||
|
chk_section_fader_row.setChecked(sections.get("fader_row", True))
|
||||||
|
chk_section_toggle_row.setChecked(sections.get("toggle_row", True))
|
||||||
|
chk_section_transport_row.setChecked(sections.get("transport_row", True))
|
||||||
|
|
||||||
check_and_index_strip_labels()
|
check_and_index_strip_labels()
|
||||||
|
|
||||||
def export_preset():
|
def export_preset():
|
||||||
@@ -2602,4 +2693,5 @@ app.setPalette(dark_palette)
|
|||||||
window = MainWindow()
|
window = MainWindow()
|
||||||
set_window(window)
|
set_window(window)
|
||||||
window.show()
|
window.show()
|
||||||
|
layout_panel_window_calc()
|
||||||
sys.exit(app.exec())
|
sys.exit(app.exec())
|
||||||
Reference in New Issue
Block a user