learn implemented on preset - transport widget - ui layout transport widget
This commit is contained in:
@@ -1480,6 +1480,9 @@ def check_and_start_midi_learn(strip):
|
|||||||
learning_strip = strip
|
learning_strip = strip
|
||||||
strip.start_learn()
|
strip.start_learn()
|
||||||
|
|
||||||
|
preset_browser_back.learn_btn.clicked.connect(lambda: check_and_start_midi_learn(preset_browser_back))
|
||||||
|
preset_browser_fwd.learn_btn.clicked.connect(lambda: check_and_start_midi_learn(preset_browser_fwd))
|
||||||
|
|
||||||
def update_window_width():
|
def update_window_width():
|
||||||
nf = len(faders)
|
nf = len(faders)
|
||||||
nt = len(toggles)
|
nt = len(toggles)
|
||||||
@@ -1716,8 +1719,7 @@ def transport_toggle_add(label, default_cc, insert_after=None):
|
|||||||
t.plus_btn.clicked.connect(lambda: transport_toggle_add(f"T{len(transports)+1}", 20, insert_after=t))
|
t.plus_btn.clicked.connect(lambda: transport_toggle_add(f"T{len(transports)+1}", 20, insert_after=t))
|
||||||
t.minus_btn.clicked.connect(lambda: transport_remove(t))
|
t.minus_btn.clicked.connect(lambda: transport_remove(t))
|
||||||
params_visible = not transport_show_hide_config
|
params_visible = not transport_show_hide_config
|
||||||
for attr in ['learn_btn', 'cc_input_lbl', 'cc_spin', 'cc_output_lbl', 'midi_btn', 'osc_btn',
|
for attr in ['grp_learn', 'arrow_lbl', 'grp_cc', 'zone_btn', 'minus_btn',
|
||||||
'momentary_btn', 'toggle_mode_btn', 'osc_addr_edit', 'zone_btn', 'minus_btn',
|
|
||||||
'plus_btn', 'title_edit', 'id_sep', 'id_label', 'color_swatch_btn']:
|
'plus_btn', 'title_edit', 'id_sep', 'id_label', 'color_swatch_btn']:
|
||||||
getattr(t, attr).setVisible(params_visible)
|
getattr(t, attr).setVisible(params_visible)
|
||||||
if insert_after is not None and insert_after in transports:
|
if insert_after is not None and insert_after in transports:
|
||||||
@@ -2299,15 +2301,9 @@ def transport_show_hide_config_set(enabled):
|
|||||||
button_transport_show_hide_config.setText("Show Parameters" if enabled else "Hide Parameters")
|
button_transport_show_hide_config.setText("Show Parameters" if enabled else "Hide Parameters")
|
||||||
button_transport_show_hide_config.setChecked(enabled)
|
button_transport_show_hide_config.setChecked(enabled)
|
||||||
for t in transports:
|
for t in transports:
|
||||||
t.learn_btn.setVisible(not enabled)
|
t.grp_learn.setVisible(not enabled)
|
||||||
t.cc_input_lbl.setVisible(not enabled)
|
t.arrow_lbl.setVisible(not enabled)
|
||||||
t.cc_spin.setVisible(not enabled)
|
t.grp_cc.setVisible(not enabled)
|
||||||
t.cc_output_lbl.setVisible(not enabled)
|
|
||||||
t.midi_btn.setVisible(not enabled)
|
|
||||||
t.osc_btn.setVisible(not enabled)
|
|
||||||
t.momentary_btn.setVisible(not enabled)
|
|
||||||
t.toggle_mode_btn.setVisible(not enabled)
|
|
||||||
t.osc_addr_edit.setVisible(not enabled)
|
|
||||||
t.zone_btn.setVisible(not enabled)
|
t.zone_btn.setVisible(not enabled)
|
||||||
t.minus_btn.setVisible(not enabled)
|
t.minus_btn.setVisible(not enabled)
|
||||||
t.plus_btn.setVisible(not enabled)
|
t.plus_btn.setVisible(not enabled)
|
||||||
|
|||||||
+19
-4
@@ -373,14 +373,29 @@
|
|||||||
],
|
],
|
||||||
"toggles": [],
|
"toggles": [],
|
||||||
"browser": {
|
"browser": {
|
||||||
"back_cc": 22,
|
"back": {
|
||||||
"fwd_cc": 23
|
"label": "Back",
|
||||||
|
"cc": 22,
|
||||||
|
"ch": 1,
|
||||||
|
"hw_cc": null,
|
||||||
|
"hw_channel": null,
|
||||||
|
"trigger_mode": "momentary"
|
||||||
|
},
|
||||||
|
"fwd": {
|
||||||
|
"label": "Fwd",
|
||||||
|
"cc": 23,
|
||||||
|
"ch": 1,
|
||||||
|
"hw_cc": null,
|
||||||
|
"hw_channel": null,
|
||||||
|
"trigger_mode": "momentary"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"preset_uuid": "3e9d51d2-cf55-49f4-80a4-2f7f4466f959",
|
"preset_uuid": "3e9d51d2-cf55-49f4-80a4-2f7f4466f959",
|
||||||
"show_hide": {
|
"show_hide": {
|
||||||
"fader": false,
|
"fader": false,
|
||||||
"toggle": false,
|
"toggle": false,
|
||||||
"transport": false
|
"transport": false,
|
||||||
|
"browser": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"new preset browser shit": {
|
"new preset browser shit": {
|
||||||
@@ -466,7 +481,7 @@
|
|||||||
"trigger_mode": "momentary"
|
"trigger_mode": "momentary"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"transport_show_hide": true,
|
"transport_show_hide": false,
|
||||||
"io_config": {
|
"io_config": {
|
||||||
"midi_out": "Not Connected",
|
"midi_out": "Not Connected",
|
||||||
"midi_in": "VMPK Output",
|
"midi_in": "VMPK Output",
|
||||||
|
|||||||
+63
-31
@@ -46,34 +46,42 @@ class TransportWidget(QWidget):
|
|||||||
inner.setSpacing(4)
|
inner.setSpacing(4)
|
||||||
inner.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
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 = QPushButton("Learn")
|
||||||
self.learn_btn.setFixedHeight(20)
|
self.learn_btn.setFixedHeight(20)
|
||||||
|
self.learn_btn.setStyleSheet("border: none;")
|
||||||
self.learn_btn.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
self.learn_btn.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||||
self.learn_btn.customContextMenuRequested.connect(self.on_learn_context_menu)
|
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 = QLabel("")
|
||||||
self.cc_input_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
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)
|
self.cc_input_lbl.setFixedHeight(16)
|
||||||
inner.addWidget(self.cc_input_lbl)
|
_grp1_layout.addWidget(self.cc_input_lbl)
|
||||||
|
|
||||||
# CC spin
|
inner.addWidget(self.grp_learn)
|
||||||
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)
|
|
||||||
|
|
||||||
# CC Out label
|
self.arrow_lbl = QLabel("▼")
|
||||||
self.cc_output_lbl = QLabel(f"Out CC{default_cc} [--]")
|
self.arrow_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
self.arrow_lbl.setStyleSheet("color: rgba(255,255,255,0.3); font-size: 9px; background: transparent;")
|
||||||
self.cc_output_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
self.arrow_lbl.setFixedHeight(12)
|
||||||
self.cc_output_lbl.setFixedHeight(16)
|
inner.addWidget(self.arrow_lbl)
|
||||||
inner.addWidget(self.cc_output_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
|
# MIDI / OSC mode selector
|
||||||
mode_row = QHBoxLayout()
|
mode_row = QHBoxLayout()
|
||||||
@@ -83,15 +91,17 @@ class TransportWidget(QWidget):
|
|||||||
self.midi_btn.setFixedHeight(18)
|
self.midi_btn.setFixedHeight(18)
|
||||||
self.midi_btn.setCheckable(True)
|
self.midi_btn.setCheckable(True)
|
||||||
self.midi_btn.setChecked(True)
|
self.midi_btn.setChecked(True)
|
||||||
|
self.midi_btn.setStyleSheet("border: none;")
|
||||||
self.osc_btn = QPushButton("OSC")
|
self.osc_btn = QPushButton("OSC")
|
||||||
self.osc_btn.setFixedHeight(18)
|
self.osc_btn.setFixedHeight(18)
|
||||||
self.osc_btn.setCheckable(True)
|
self.osc_btn.setCheckable(True)
|
||||||
self.osc_btn.setChecked(False)
|
self.osc_btn.setChecked(False)
|
||||||
|
self.osc_btn.setStyleSheet("border: none;")
|
||||||
self.midi_btn.clicked.connect(lambda: self.set_output_mode("midi"))
|
self.midi_btn.clicked.connect(lambda: self.set_output_mode("midi"))
|
||||||
self.osc_btn.clicked.connect(lambda: self.set_output_mode("osc"))
|
self.osc_btn.clicked.connect(lambda: self.set_output_mode("osc"))
|
||||||
mode_row.addWidget(self.midi_btn)
|
mode_row.addWidget(self.midi_btn)
|
||||||
mode_row.addWidget(self.osc_btn)
|
mode_row.addWidget(self.osc_btn)
|
||||||
inner.addLayout(mode_row)
|
_grp2_layout.addLayout(mode_row)
|
||||||
|
|
||||||
# Momentary / Toggle selector
|
# Momentary / Toggle selector
|
||||||
trigger_row = QHBoxLayout()
|
trigger_row = QHBoxLayout()
|
||||||
@@ -101,26 +111,46 @@ class TransportWidget(QWidget):
|
|||||||
self.momentary_btn.setFixedHeight(18)
|
self.momentary_btn.setFixedHeight(18)
|
||||||
self.momentary_btn.setCheckable(True)
|
self.momentary_btn.setCheckable(True)
|
||||||
self.momentary_btn.setChecked(True)
|
self.momentary_btn.setChecked(True)
|
||||||
|
self.momentary_btn.setStyleSheet("border: none;")
|
||||||
self.toggle_mode_btn = QPushButton("Tog.")
|
self.toggle_mode_btn = QPushButton("Tog.")
|
||||||
self.toggle_mode_btn.setFixedHeight(18)
|
self.toggle_mode_btn.setFixedHeight(18)
|
||||||
self.toggle_mode_btn.setCheckable(True)
|
self.toggle_mode_btn.setCheckable(True)
|
||||||
self.toggle_mode_btn.setChecked(False)
|
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.momentary_btn.clicked.connect(lambda: self.set_trigger_mode("momentary"))
|
||||||
self.toggle_mode_btn.clicked.connect(lambda: self.set_trigger_mode("toggle"))
|
self.toggle_mode_btn.clicked.connect(lambda: self.set_trigger_mode("toggle"))
|
||||||
trigger_row.addWidget(self.momentary_btn)
|
trigger_row.addWidget(self.momentary_btn)
|
||||||
trigger_row.addWidget(self.toggle_mode_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)
|
# OSC address field (hidden by default)
|
||||||
self.osc_addr_edit = QLineEdit("/play")
|
self.osc_addr_edit = QLineEdit("/play")
|
||||||
self.osc_addr_edit.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
self.osc_addr_edit.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
self.osc_addr_edit.setPlaceholderText("/address")
|
self.osc_addr_edit.setPlaceholderText("/address")
|
||||||
self.osc_addr_edit.setVisible(False)
|
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
|
# Transport button with LED dot
|
||||||
btn_container = QWidget()
|
btn_container = QWidget()
|
||||||
@@ -219,27 +249,28 @@ class TransportWidget(QWidget):
|
|||||||
self.midi_btn.setStyleSheet("font-weight: bold; color: #00e676;")
|
self.midi_btn.setStyleSheet("font-weight: bold; color: #00e676;")
|
||||||
self.osc_btn.setStyleSheet("")
|
self.osc_btn.setStyleSheet("")
|
||||||
self.cc_spin.setVisible(True)
|
self.cc_spin.setVisible(True)
|
||||||
self.cc_output_lbl.setVisible(True)
|
|
||||||
self.osc_addr_edit.setVisible(False)
|
self.osc_addr_edit.setVisible(False)
|
||||||
|
self.cc_output_lbl.setText(f"CC{self.cc_spin.value()} [--]")
|
||||||
else:
|
else:
|
||||||
self.osc_btn.setChecked(True)
|
self.osc_btn.setChecked(True)
|
||||||
self.midi_btn.setChecked(False)
|
self.midi_btn.setChecked(False)
|
||||||
self.osc_btn.setStyleSheet("font-weight: bold; color: #00e676;")
|
self.osc_btn.setStyleSheet("font-weight: bold; color: #00e676;")
|
||||||
self.midi_btn.setStyleSheet("")
|
self.midi_btn.setStyleSheet("")
|
||||||
self.cc_spin.setVisible(False)
|
self.cc_spin.setVisible(False)
|
||||||
self.cc_output_lbl.setVisible(False)
|
|
||||||
self.osc_addr_edit.setVisible(True)
|
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):
|
def on_click(self):
|
||||||
if self.trigger_mode == "momentary":
|
if self.trigger_mode == "momentary":
|
||||||
if self.output_mode == "osc":
|
if self.output_mode == "osc":
|
||||||
addr = self.osc_addr_edit.text().strip() or "/play"
|
addr = self.osc_addr_edit.text().strip() or "/play"
|
||||||
send_osc_message(addr, 1.0)
|
send_osc_message(addr, 1.0)
|
||||||
self.cc_output_lbl.setText(f"OSC {addr}")
|
self.cc_output_lbl.setText(f"{addr} [1.0]")
|
||||||
else:
|
else:
|
||||||
cc_num = self.cc_spin.value()
|
cc_num = self.cc_spin.value()
|
||||||
send_transport_cc(cc_num, 127)
|
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;")
|
self.led_dot.setStyleSheet("background-color: #00e676; border-radius: 3px;")
|
||||||
QTimer.singleShot(150, lambda: self.led_dot.setStyleSheet("background-color: #3c3c3c; border-radius: 3px;"))
|
QTimer.singleShot(150, lambda: self.led_dot.setStyleSheet("background-color: #3c3c3c; border-radius: 3px;"))
|
||||||
else:
|
else:
|
||||||
@@ -247,12 +278,13 @@ class TransportWidget(QWidget):
|
|||||||
value = 127 if self.toggle_state else 0
|
value = 127 if self.toggle_state else 0
|
||||||
if self.output_mode == "osc":
|
if self.output_mode == "osc":
|
||||||
addr = self.osc_addr_edit.text().strip() or "/play"
|
addr = self.osc_addr_edit.text().strip() or "/play"
|
||||||
send_osc_message(addr, 1.0 if self.toggle_state else 0.0)
|
osc_val = 1.0 if self.toggle_state else 0.0
|
||||||
self.cc_output_lbl.setText(f"OSC {addr}")
|
send_osc_message(addr, osc_val)
|
||||||
|
self.cc_output_lbl.setText(f"{addr} [{osc_val}]")
|
||||||
else:
|
else:
|
||||||
cc_num = self.cc_spin.value()
|
cc_num = self.cc_spin.value()
|
||||||
send_transport_cc(cc_num, 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()
|
self._update_btn_style()
|
||||||
|
|
||||||
def _update_btn_style(self):
|
def _update_btn_style(self):
|
||||||
@@ -315,7 +347,7 @@ class TransportWidget(QWidget):
|
|||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.cc_input_lbl.setText("")
|
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.hw_cc = cc_number
|
||||||
self.stop_learn()
|
self.stop_learn()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user