learn implemented on preset - transport widget - ui layout transport widget

This commit is contained in:
Paul Lipscomb
2026-06-29 03:41:25 -04:00
parent 6f6637eec8
commit 452a72d3ce
3 changed files with 89 additions and 46 deletions
+63 -31
View File
@@ -46,34 +46,42 @@ class TransportWidget(QWidget):
inner.setSpacing(4)
inner.setAlignment(Qt.AlignmentFlag.AlignHCenter)
# Learn button
_grp_style = "QFrame { border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; }"
# Group 1: Learn + input readout
self.grp_learn = QFrame()
self.grp_learn.setStyleSheet(_grp_style)
_grp1_layout = QVBoxLayout(self.grp_learn)
_grp1_layout.setContentsMargins(4, 4, 4, 4)
_grp1_layout.setSpacing(3)
self.learn_btn = QPushButton("Learn")
self.learn_btn.setFixedHeight(20)
self.learn_btn.setStyleSheet("border: none;")
self.learn_btn.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.learn_btn.customContextMenuRequested.connect(self.on_learn_context_menu)
inner.addWidget(self.learn_btn)
_grp1_layout.addWidget(self.learn_btn)
# CC In label
self.cc_input_lbl = QLabel("")
self.cc_input_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #888888; font-size: 10px; padding: 1px;")
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #888888; font-size: 10px; padding: 1px; border: none;")
self.cc_input_lbl.setFixedHeight(16)
inner.addWidget(self.cc_input_lbl)
_grp1_layout.addWidget(self.cc_input_lbl)
# CC spin
self.cc_spin = QSpinBox()
self.cc_spin.setMinimum(1)
self.cc_spin.setMaximum(127)
self.cc_spin.setValue(default_cc)
self.cc_spin.setFixedWidth(75)
inner.addWidget(self.cc_spin, alignment=Qt.AlignmentFlag.AlignHCenter)
inner.addWidget(self.grp_learn)
# CC Out label
self.cc_output_lbl = QLabel(f"Out CC{default_cc} [--]")
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
self.cc_output_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
self.cc_output_lbl.setFixedHeight(16)
inner.addWidget(self.cc_output_lbl)
self.arrow_lbl = QLabel("")
self.arrow_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
self.arrow_lbl.setStyleSheet("color: rgba(255,255,255,0.3); font-size: 9px; background: transparent;")
self.arrow_lbl.setFixedHeight(12)
inner.addWidget(self.arrow_lbl)
# Group 2: output controls + readout
self.grp_cc = QFrame()
self.grp_cc.setStyleSheet(_grp_style)
_grp2_layout = QVBoxLayout(self.grp_cc)
_grp2_layout.setContentsMargins(4, 4, 4, 4)
_grp2_layout.setSpacing(3)
# MIDI / OSC mode selector
mode_row = QHBoxLayout()
@@ -83,15 +91,17 @@ class TransportWidget(QWidget):
self.midi_btn.setFixedHeight(18)
self.midi_btn.setCheckable(True)
self.midi_btn.setChecked(True)
self.midi_btn.setStyleSheet("border: none;")
self.osc_btn = QPushButton("OSC")
self.osc_btn.setFixedHeight(18)
self.osc_btn.setCheckable(True)
self.osc_btn.setChecked(False)
self.osc_btn.setStyleSheet("border: none;")
self.midi_btn.clicked.connect(lambda: self.set_output_mode("midi"))
self.osc_btn.clicked.connect(lambda: self.set_output_mode("osc"))
mode_row.addWidget(self.midi_btn)
mode_row.addWidget(self.osc_btn)
inner.addLayout(mode_row)
_grp2_layout.addLayout(mode_row)
# Momentary / Toggle selector
trigger_row = QHBoxLayout()
@@ -101,26 +111,46 @@ class TransportWidget(QWidget):
self.momentary_btn.setFixedHeight(18)
self.momentary_btn.setCheckable(True)
self.momentary_btn.setChecked(True)
self.momentary_btn.setStyleSheet("border: none;")
self.toggle_mode_btn = QPushButton("Tog.")
self.toggle_mode_btn.setFixedHeight(18)
self.toggle_mode_btn.setCheckable(True)
self.toggle_mode_btn.setChecked(False)
self.toggle_mode_btn.setStyleSheet("border: none;")
self.momentary_btn.clicked.connect(lambda: self.set_trigger_mode("momentary"))
self.toggle_mode_btn.clicked.connect(lambda: self.set_trigger_mode("toggle"))
trigger_row.addWidget(self.momentary_btn)
trigger_row.addWidget(self.toggle_mode_btn)
inner.addLayout(trigger_row)
_grp2_layout.addLayout(trigger_row)
self.trigger_mode = "momentary" # "momentary" or "toggle"
self.trigger_mode = "momentary"
# CC spin (MIDI mode)
self.cc_spin = QSpinBox()
self.cc_spin.setMinimum(1)
self.cc_spin.setMaximum(127)
self.cc_spin.setValue(default_cc)
self.cc_spin.setFixedWidth(75)
_grp2_layout.addWidget(self.cc_spin, alignment=Qt.AlignmentFlag.AlignHCenter)
# OSC address field (hidden by default)
self.osc_addr_edit = QLineEdit("/play")
self.osc_addr_edit.setAlignment(Qt.AlignmentFlag.AlignHCenter)
self.osc_addr_edit.setPlaceholderText("/address")
self.osc_addr_edit.setVisible(False)
inner.addWidget(self.osc_addr_edit)
self.osc_addr_edit.setStyleSheet("border: none;")
_grp2_layout.addWidget(self.osc_addr_edit)
self.output_mode = "midi" # "midi" or "osc"
# Output readout — always visible, content adapts to mode
self.cc_output_lbl = QLabel(f"CC{default_cc} [--]")
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
self.cc_output_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px; border: none;")
self.cc_output_lbl.setFixedHeight(16)
_grp2_layout.addWidget(self.cc_output_lbl)
inner.addWidget(self.grp_cc)
self.output_mode = "midi"
# Transport button with LED dot
btn_container = QWidget()
@@ -219,27 +249,28 @@ class TransportWidget(QWidget):
self.midi_btn.setStyleSheet("font-weight: bold; color: #00e676;")
self.osc_btn.setStyleSheet("")
self.cc_spin.setVisible(True)
self.cc_output_lbl.setVisible(True)
self.osc_addr_edit.setVisible(False)
self.cc_output_lbl.setText(f"CC{self.cc_spin.value()} [--]")
else:
self.osc_btn.setChecked(True)
self.midi_btn.setChecked(False)
self.osc_btn.setStyleSheet("font-weight: bold; color: #00e676;")
self.midi_btn.setStyleSheet("")
self.cc_spin.setVisible(False)
self.cc_output_lbl.setVisible(False)
self.osc_addr_edit.setVisible(True)
addr = self.osc_addr_edit.text().strip() or "/play"
self.cc_output_lbl.setText(f"{addr} [--]")
def on_click(self):
if self.trigger_mode == "momentary":
if self.output_mode == "osc":
addr = self.osc_addr_edit.text().strip() or "/play"
send_osc_message(addr, 1.0)
self.cc_output_lbl.setText(f"OSC {addr}")
self.cc_output_lbl.setText(f"{addr} [1.0]")
else:
cc_num = self.cc_spin.value()
send_transport_cc(cc_num, 127)
self.cc_output_lbl.setText(f"Out CC{cc_num} [127]")
self.cc_output_lbl.setText(f"CC{cc_num} [127]")
self.led_dot.setStyleSheet("background-color: #00e676; border-radius: 3px;")
QTimer.singleShot(150, lambda: self.led_dot.setStyleSheet("background-color: #3c3c3c; border-radius: 3px;"))
else:
@@ -247,12 +278,13 @@ class TransportWidget(QWidget):
value = 127 if self.toggle_state else 0
if self.output_mode == "osc":
addr = self.osc_addr_edit.text().strip() or "/play"
send_osc_message(addr, 1.0 if self.toggle_state else 0.0)
self.cc_output_lbl.setText(f"OSC {addr}")
osc_val = 1.0 if self.toggle_state else 0.0
send_osc_message(addr, osc_val)
self.cc_output_lbl.setText(f"{addr} [{osc_val}]")
else:
cc_num = self.cc_spin.value()
send_transport_cc(cc_num, value)
self.cc_output_lbl.setText(f"Out CC{cc_num} [{value}]")
self.cc_output_lbl.setText(f"CC{cc_num} [{value}]")
self._update_btn_style()
def _update_btn_style(self):
@@ -315,7 +347,7 @@ class TransportWidget(QWidget):
self.learn_btn.setText("Learn")
self.cc_input_lbl.setText("")
def bind_hw_cc(self, cc_number):
def bind_hw_cc(self, cc_number, channel=None):
self.hw_cc = cc_number
self.stop_learn()