add Mom/Tog to ToggleWidget, Big Title, Layout panel scaffold
- ToggleWidget: add Momentary/Toggle mode selector (mirrors TransportWidget minus OSC); HW routing respects trigger_mode; fix invisible button on init by removing explicit empty stylesheet; saves/loads trigger_mode per preset - Big Title: full-width 28px bold QLineEdit above fader row, saves per-preset as big_title; green underline on focus; single bottom border, no separator - Layout panel: floating 220px window to the left of main window, toggled by new Layout button next to Messages; shows Sections checkboxes (Preset Browser, Big Title, Fader Row, Toggle Row, Transport Row); tracks window move/resize; checkboxes not yet wired to functionality Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,7 @@ view_uuid_error_overlay = None
|
||||
label_overlay_message = None
|
||||
placeholder_fader_empty = None
|
||||
placeholder_toggle_empty = None
|
||||
big_title_edit = None
|
||||
|
||||
|
||||
|
||||
@@ -346,6 +347,11 @@ button_osc_messages_log = QPushButton("Messages")
|
||||
button_osc_messages_log.setFixedWidth(80)
|
||||
button_osc_messages_log.setCheckable(True)
|
||||
|
||||
# Widget: button_layout_panel
|
||||
button_layout_panel = QPushButton("Layout")
|
||||
button_layout_panel.setFixedWidth(65)
|
||||
button_layout_panel.setCheckable(True)
|
||||
|
||||
|
||||
# Layout: hstack_osc_status
|
||||
hstack_osc_status = QHBoxLayout()
|
||||
@@ -553,6 +559,54 @@ textedit_midi_out_log.setStyleSheet("""
|
||||
}
|
||||
""")
|
||||
|
||||
# MARK: LAYOUT PANEL
|
||||
container_layout_panel = QWidget(None, Qt.WindowType.Window)
|
||||
container_layout_panel.setWindowTitle("Layout")
|
||||
container_layout_panel.setStyleSheet("background-color: #1a1a1a;")
|
||||
container_layout_panel.setFixedWidth(220)
|
||||
|
||||
vstack_layout_panel = QVBoxLayout(container_layout_panel)
|
||||
vstack_layout_panel.setContentsMargins(10, 10, 10, 10)
|
||||
vstack_layout_panel.setSpacing(6)
|
||||
|
||||
label_layout_panel_title = QLabel("Sections")
|
||||
label_layout_panel_title.setStyleSheet("color: #ffffff; font-weight: bold; font-size: 12px;")
|
||||
vstack_layout_panel.addWidget(label_layout_panel_title)
|
||||
|
||||
_section_sep = QFrame()
|
||||
_section_sep.setFrameShape(QFrame.Shape.HLine)
|
||||
_section_sep.setStyleSheet("color: #3a3a3a;")
|
||||
vstack_layout_panel.addWidget(_section_sep)
|
||||
|
||||
# Section rows (layout only — not wired yet)
|
||||
_section_rows = [
|
||||
("Preset Browser", "chk_section_preset_browser"),
|
||||
("Big Title", "chk_section_big_title"),
|
||||
("Fader Row", "chk_section_fader_row"),
|
||||
("Toggle Row", "chk_section_toggle_row"),
|
||||
("Transport Row", "chk_section_transport_row"),
|
||||
]
|
||||
from PyQt6.QtWidgets import QCheckBox
|
||||
for _lbl, _attr in _section_rows:
|
||||
_row = QWidget()
|
||||
_row.setStyleSheet("background: transparent;")
|
||||
_hbox = QHBoxLayout(_row)
|
||||
_hbox.setContentsMargins(4, 2, 4, 2)
|
||||
_hbox.setSpacing(8)
|
||||
_chk = QCheckBox()
|
||||
_chk.setChecked(True)
|
||||
_chk.setFixedSize(16, 16)
|
||||
_name_lbl = QLabel(_lbl)
|
||||
_name_lbl.setStyleSheet("color: #d4d4d4; font-size: 12px; background: transparent;")
|
||||
_hbox.addWidget(_chk)
|
||||
_hbox.addWidget(_name_lbl)
|
||||
_hbox.addStretch()
|
||||
globals()[_attr] = _chk
|
||||
vstack_layout_panel.addWidget(_row)
|
||||
del _lbl, _attr, _row, _hbox, _chk, _name_lbl, _section_rows
|
||||
|
||||
vstack_layout_panel.addStretch()
|
||||
|
||||
# MARK: PRESET BROWSER ROW MODULE
|
||||
label_preset_browser_title = QLabel("Preset Browser")
|
||||
hstack_preset_browser = QHBoxLayout()
|
||||
@@ -931,6 +985,7 @@ class MainWindow(QMainWindow):
|
||||
# build hstack for control buttons
|
||||
hstack_osc_buttons.addWidget(button_osc_toggle)
|
||||
hstack_osc_buttons.addWidget(button_osc_messages_log)
|
||||
hstack_osc_buttons.addWidget(button_layout_panel)
|
||||
hstack_osc_buttons.addStretch()
|
||||
|
||||
# add all rows to vstack
|
||||
@@ -944,6 +999,7 @@ class MainWindow(QMainWindow):
|
||||
spinner_osc_send_port.valueChanged.connect(update_osc_server_port)
|
||||
button_osc_toggle.clicked.connect(start_stop_osc_server)
|
||||
button_osc_messages_log.clicked.connect(log_ui_show_hide)
|
||||
button_layout_panel.clicked.connect(layout_panel_show_hide)
|
||||
|
||||
# add the combined stack to the row
|
||||
hstack_io_row.addLayout(vstack_osc)
|
||||
@@ -1061,6 +1117,9 @@ class MainWindow(QMainWindow):
|
||||
button_midi_out_clear.clicked.connect(lambda: textedit_midi_out_log.clear())
|
||||
container_midi_out_log.setVisible(False)
|
||||
|
||||
#MARK: LAYOUT PANEL
|
||||
container_layout_panel.setVisible(False)
|
||||
|
||||
main_layout.addWidget(make_separator())
|
||||
|
||||
# MARK: TRANSPORT ROW CONTROLS
|
||||
@@ -1122,12 +1181,22 @@ class MainWindow(QMainWindow):
|
||||
global container_rows_and_widgets
|
||||
global view_uuid_error_overlay
|
||||
global label_overlay_message
|
||||
global big_title_edit
|
||||
container_rows_and_widgets = QWidget()
|
||||
controls_layout = QVBoxLayout(container_rows_and_widgets)
|
||||
controls_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.addWidget(container_rows_and_widgets)
|
||||
|
||||
controls_layout.addWidget(make_separator())
|
||||
# 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; 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
|
||||
global hstack_row_fader_control_buttons
|
||||
@@ -1288,11 +1357,15 @@ class MainWindow(QMainWindow):
|
||||
super().resizeEvent(event)
|
||||
if container_osc_in_log.isVisible():
|
||||
log_ui_window_calc()
|
||||
if container_layout_panel.isVisible():
|
||||
layout_panel_window_calc()
|
||||
|
||||
def moveEvent(self, event):
|
||||
super().moveEvent(event)
|
||||
if container_osc_in_log.isVisible():
|
||||
log_ui_window_calc()
|
||||
if container_layout_panel.isVisible():
|
||||
layout_panel_window_calc()
|
||||
|
||||
def make_separator():
|
||||
sep = QWidget()
|
||||
@@ -1347,12 +1420,13 @@ def new_blank_preset():
|
||||
if not ok or not name.strip():
|
||||
return
|
||||
name = name.strip()
|
||||
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["presets"][name] = {"faders": [], "toggles": [], "preset_uuid": "", "browser": {"back": preset_browser_back.get_state(), "fwd": preset_browser_fwd.get_state()}, "show_hide": {}, "big_title": ""}
|
||||
loaded_presets["__last_used__"] = name
|
||||
save_presets_file(loaded_presets)
|
||||
populate_preset_dropdown_menu()
|
||||
menuPresets.setCurrentText(name)
|
||||
clear_all_strips()
|
||||
big_title_edit.setText("")
|
||||
show_save_status()
|
||||
|
||||
def show_save_status():
|
||||
@@ -1904,6 +1978,7 @@ def preset_build_snapshot(name):
|
||||
"back": preset_browser_back.get_state(),
|
||||
"fwd": preset_browser_fwd.get_state(),
|
||||
},
|
||||
"big_title": big_title_edit.text(),
|
||||
"preset_uuid": label_preset_uuid.text().strip(),
|
||||
"show_hide": {
|
||||
"fader": fader_show_hide_config,
|
||||
@@ -2024,6 +2099,7 @@ def preset_load(preset):
|
||||
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))
|
||||
|
||||
big_title_edit.setText(preset.get("big_title", ""))
|
||||
label_preset_uuid.setText(preset.get("preset_uuid", ""))
|
||||
check_and_index_strip_labels()
|
||||
|
||||
@@ -2249,15 +2325,21 @@ def midi_message_route_hw_to_output_cc(fader_uid, value):
|
||||
if toggle.uid == fader_uid:
|
||||
out_cc = toggle.cc_spin.value()
|
||||
out_ch = toggle.ch_spin.value()
|
||||
print(f"[toggle convert] HW CC{toggle.hw_cc} CH{toggle.hw_channel} ({value}) → CC{out_cc} CH{out_ch} ({value})")
|
||||
should_be_on = value > 63
|
||||
if toggle.toggle_state != should_be_on:
|
||||
toggle.toggle_state = should_be_on
|
||||
out_val = 127 if should_be_on else 0
|
||||
send_cc(out_cc, out_val, channel=out_ch)
|
||||
toggle.cc_input_lbl.setText(toggle._cc_input_label(value))
|
||||
toggle.cc_output_lbl.setText(toggle._cc_output_label(out_val))
|
||||
toggle._update_btn_style()
|
||||
print(f"[toggle convert] HW CC{toggle.hw_cc} CH{toggle.hw_channel} ({value}) → CC{out_cc} CH{out_ch}")
|
||||
toggle.cc_input_lbl.setText(toggle._cc_input_label(value))
|
||||
if toggle.trigger_mode == "momentary":
|
||||
send_cc(out_cc, 127, channel=out_ch)
|
||||
toggle.cc_output_lbl.setText(toggle._cc_output_label(127))
|
||||
toggle.led_dot.setStyleSheet("background-color: #00e676; border-radius: 3px;")
|
||||
QTimer.singleShot(150, lambda: toggle.led_dot.setStyleSheet("background-color: #3c3c3c; border-radius: 3px;"))
|
||||
else:
|
||||
should_be_on = value > 63
|
||||
if toggle.toggle_state != should_be_on:
|
||||
toggle.toggle_state = should_be_on
|
||||
out_val = 127 if should_be_on else 0
|
||||
send_cc(out_cc, out_val, channel=out_ch)
|
||||
toggle.cc_output_lbl.setText(toggle._cc_output_label(out_val))
|
||||
toggle._update_btn_style()
|
||||
return
|
||||
for t in transports:
|
||||
if t.uid == fader_uid:
|
||||
@@ -2312,6 +2394,20 @@ def log_ui_window_calc():
|
||||
container_midi_out_log.setFixedHeight(half)
|
||||
container_midi_out_log.move(geo.right() + 368, geo.top() + half + 4)
|
||||
|
||||
|
||||
def layout_panel_show_hide(checked):
|
||||
container_layout_panel.setVisible(checked)
|
||||
if checked:
|
||||
layout_panel_window_calc()
|
||||
|
||||
|
||||
def layout_panel_window_calc():
|
||||
geo = app_window.frameGeometry()
|
||||
container_layout_panel.setFixedWidth(220)
|
||||
container_layout_panel.setFixedHeight(geo.height())
|
||||
container_layout_panel.move(geo.left() - 224, geo.top())
|
||||
|
||||
|
||||
def start_osc_server(port=9000):
|
||||
global _osc_server, _osc_thread
|
||||
stop_osc_server()
|
||||
|
||||
Reference in New Issue
Block a user