feat: per-strip CC/CH translation, layout groups, show/hide improvements
This commit is contained in:
+97
-23
@@ -22,10 +22,12 @@ from midi_sender import send_cc
|
|||||||
|
|
||||||
class FaderWidget(QWidget):
|
class FaderWidget(QWidget):
|
||||||
def __init__(self, label, default_cc):
|
def __init__(self, label, default_cc):
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
|
||||||
self.setFixedWidth(100)
|
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Maximum)
|
||||||
self.current_color = "transparent"
|
self.setFixedWidth(115)
|
||||||
|
self.current_color = PALETTE_HEX.get("Gray", "#263238")
|
||||||
|
|
||||||
self.uid = str(uuid.uuid4())
|
self.uid = str(uuid.uuid4())
|
||||||
|
|
||||||
@@ -48,41 +50,96 @@ class FaderWidget(QWidget):
|
|||||||
inner.setSpacing(4)
|
inner.setSpacing(4)
|
||||||
inner.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
inner.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
|
|
||||||
# Learn button
|
# Learn / CC / CH group
|
||||||
self.hw_cc = None
|
self.hw_cc = None
|
||||||
|
self.hw_channel = None
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
|
|
||||||
|
_grp_style = "QFrame { border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; }"
|
||||||
|
|
||||||
|
# Group 1: Learn + input readout (border always visible; learn_btn hideable)
|
||||||
|
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;")
|
||||||
inner.addWidget(self.cc_input_lbl)
|
self.cc_input_lbl.setFixedHeight(16)
|
||||||
|
_grp1_layout.addWidget(self.cc_input_lbl)
|
||||||
|
|
||||||
|
inner.addWidget(self.grp_learn)
|
||||||
|
|
||||||
|
_arrow_lbl = QLabel("▼")
|
||||||
|
_arrow_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
|
_arrow_lbl.setStyleSheet("color: rgba(255,255,255,0.3); font-size: 9px; background: transparent;")
|
||||||
|
_arrow_lbl.setFixedHeight(12)
|
||||||
|
inner.addWidget(_arrow_lbl)
|
||||||
|
|
||||||
|
# Group 2: CC spin + CH spin + output readout (border always visible; spins hideable)
|
||||||
|
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)
|
||||||
|
|
||||||
# CC spin
|
|
||||||
self.cc_spin = QSpinBox()
|
self.cc_spin = QSpinBox()
|
||||||
self.cc_spin.setMinimum(1)
|
self.cc_spin.setMinimum(0)
|
||||||
self.cc_spin.setMaximum(127)
|
self.cc_spin.setMaximum(127)
|
||||||
self.cc_spin.setValue(default_cc)
|
self.cc_spin.setValue(default_cc)
|
||||||
self.cc_spin.setFixedWidth(75)
|
self.cc_spin.setFixedWidth(55)
|
||||||
inner.addWidget(self.cc_spin, alignment=Qt.AlignmentFlag.AlignHCenter)
|
_cc_lbl = QLabel("CC")
|
||||||
|
_cc_lbl.setStyleSheet("color: #fff; font-size: 10px; border: none;")
|
||||||
|
self.cc_spin_row = QWidget()
|
||||||
|
_hbox_cc = QHBoxLayout(self.cc_spin_row)
|
||||||
|
_hbox_cc.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_hbox_cc.setSpacing(4)
|
||||||
|
_hbox_cc.addWidget(_cc_lbl)
|
||||||
|
_hbox_cc.addWidget(self.cc_spin)
|
||||||
|
_grp2_layout.addWidget(self.cc_spin_row)
|
||||||
|
|
||||||
self.cc_output_lbl = QLabel("")
|
self.ch_spin = QSpinBox()
|
||||||
|
self.ch_spin.setMinimum(1)
|
||||||
|
self.ch_spin.setMaximum(16)
|
||||||
|
self.ch_spin.setValue(1)
|
||||||
|
self.ch_spin.setFixedWidth(55)
|
||||||
|
_ch_lbl = QLabel("CH")
|
||||||
|
_ch_lbl.setStyleSheet("color: #fff; font-size: 10px; border: none;")
|
||||||
|
self.ch_spin_row = QWidget()
|
||||||
|
_hbox_ch = QHBoxLayout(self.ch_spin_row)
|
||||||
|
_hbox_ch.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_hbox_ch.setSpacing(4)
|
||||||
|
_hbox_ch.addWidget(_ch_lbl)
|
||||||
|
_hbox_ch.addWidget(self.ch_spin)
|
||||||
|
_grp2_layout.addWidget(self.ch_spin_row)
|
||||||
|
|
||||||
|
self.cc_output_lbl = QLabel(f"CC{default_cc} [--]")
|
||||||
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
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.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px; border: none;")
|
||||||
inner.addWidget(self.cc_output_lbl)
|
self.cc_output_lbl.setFixedHeight(16)
|
||||||
|
_grp2_layout.addWidget(self.cc_output_lbl)
|
||||||
|
|
||||||
|
inner.addWidget(self.grp_cc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Fader
|
# Fader
|
||||||
self.fader = QSlider(Qt.Orientation.Vertical)
|
self.fader = QSlider(Qt.Orientation.Vertical)
|
||||||
self.fader.setMinimum(0)
|
self.fader.setMinimum(0)
|
||||||
self.fader.setMaximum(127)
|
self.fader.setMaximum(127)
|
||||||
self.fader.setValue(64)
|
self.fader.setValue(64)
|
||||||
self.fader.setFixedHeight(200)
|
self.fader.setMinimumHeight(200)
|
||||||
self.fader.setFixedWidth(40)
|
self.fader.setFixedWidth(40)
|
||||||
|
self.fader.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Expanding)
|
||||||
self.fader.setStyleSheet(FADER_STYLE)
|
self.fader.setStyleSheet(FADER_STYLE)
|
||||||
inner.addWidget(self.fader, alignment=Qt.AlignmentFlag.AlignHCenter)
|
inner.addWidget(self.fader, alignment=Qt.AlignmentFlag.AlignHCenter)
|
||||||
|
|
||||||
@@ -214,7 +271,7 @@ class FaderWidget(QWidget):
|
|||||||
|
|
||||||
def on_fader_moved(self, value):
|
def on_fader_moved(self, value):
|
||||||
cc_num = self.cc_spin.value()
|
cc_num = self.cc_spin.value()
|
||||||
self.cc_output_lbl.setText(f"Out CC{cc_num} [{value}]")
|
self.cc_output_lbl.setText(self._cc_output_label(value))
|
||||||
if self.pickup_mode and self.hunting:
|
if self.pickup_mode and self.hunting:
|
||||||
crossed = (
|
crossed = (
|
||||||
(self.prev_position < self.last_sent <= value) or
|
(self.prev_position < self.last_sent <= value) or
|
||||||
@@ -226,21 +283,21 @@ class FaderWidget(QWidget):
|
|||||||
self._stop_blink()
|
self._stop_blink()
|
||||||
self._set_readout_style("orange")
|
self._set_readout_style("orange")
|
||||||
self.last_sent = value
|
self.last_sent = value
|
||||||
send_cc(cc_num, value)
|
send_cc(cc_num, value, channel=self.ch_spin.value())
|
||||||
else:
|
else:
|
||||||
self.readout.setText(f"CC {cc_num} → {value}")
|
self.readout.setText(f"CC {cc_num} → {value}")
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.last_sent = value
|
self.last_sent = value
|
||||||
self.prev_position = value
|
self.prev_position = value
|
||||||
send_cc(cc_num, value)
|
send_cc(cc_num, value, channel=self.ch_spin.value())
|
||||||
self.readout.setText(f"CC {cc_num} → {value}")
|
self.readout.setText(f"CC {cc_num} → {value}")
|
||||||
|
|
||||||
def on_cc_changed(self):
|
def on_cc_changed(self):
|
||||||
cc_num = self.cc_spin.value()
|
cc_num = self.cc_spin.value()
|
||||||
value = self.fader.value()
|
value = self.fader.value()
|
||||||
self.readout.setText(f"CC {cc_num} → {value}")
|
self.readout.setText(f"CC {cc_num} → {value}")
|
||||||
self.cc_output_lbl.setText(f"Out CC{cc_num} [{value}]")
|
self.cc_output_lbl.setText(self._cc_output_label(value))
|
||||||
if self.pickup_mode:
|
if self.pickup_mode:
|
||||||
self.hunting = True
|
self.hunting = True
|
||||||
self._start_blink()
|
self._start_blink()
|
||||||
@@ -307,6 +364,7 @@ class FaderWidget(QWidget):
|
|||||||
action = menu.exec(self.learn_btn.mapToGlobal(pos))
|
action = menu.exec(self.learn_btn.mapToGlobal(pos))
|
||||||
if action == clear_action:
|
if action == clear_action:
|
||||||
self.hw_cc = None
|
self.hw_cc = None
|
||||||
|
self.hw_channel = None
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.learn_btn.setStyleSheet("")
|
self.learn_btn.setStyleSheet("")
|
||||||
@@ -326,20 +384,32 @@ class FaderWidget(QWidget):
|
|||||||
self.learn_btn.setText("Listening...")
|
self.learn_btn.setText("Listening...")
|
||||||
self.learn_btn.setStyleSheet("color: orange; font-weight: bold;")
|
self.learn_btn.setStyleSheet("color: orange; font-weight: bold;")
|
||||||
|
|
||||||
|
def _cc_input_label(self, vel="--"):
|
||||||
|
if self.hw_cc is None:
|
||||||
|
return ""
|
||||||
|
ch = f" CH{self.hw_channel}" if self.hw_channel is not None else ""
|
||||||
|
return f"CC{self.hw_cc}{ch} [{vel}]"
|
||||||
|
|
||||||
|
def _cc_output_label(self, vel="--"):
|
||||||
|
out_cc = self.cc_spin.value()
|
||||||
|
out_ch = self.ch_spin.value()
|
||||||
|
return f"CC{out_cc} CH{out_ch} [{vel}]"
|
||||||
|
|
||||||
def stop_learn(self):
|
def stop_learn(self):
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
self.learn_btn.setStyleSheet("")
|
self.learn_btn.setStyleSheet("")
|
||||||
if self.hw_cc is not None:
|
if self.hw_cc is not None:
|
||||||
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
||||||
self.cc_input_lbl.setText(f"In CC{self.hw_cc} [--]")
|
self.cc_input_lbl.setText(self._cc_input_label())
|
||||||
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
||||||
else:
|
else:
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.cc_input_lbl.setText("")
|
self.cc_input_lbl.setText("")
|
||||||
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;")
|
||||||
|
|
||||||
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.hw_channel = channel
|
||||||
self.stop_learn()
|
self.stop_learn()
|
||||||
|
|
||||||
def get_state(self):
|
def get_state(self):
|
||||||
@@ -347,11 +417,13 @@ class FaderWidget(QWidget):
|
|||||||
"uid": self.uid,
|
"uid": self.uid,
|
||||||
"label": self.title_edit.text(),
|
"label": self.title_edit.text(),
|
||||||
"cc": self.cc_spin.value(),
|
"cc": self.cc_spin.value(),
|
||||||
|
"ch": self.ch_spin.value(),
|
||||||
"value": self.fader.value(),
|
"value": self.fader.value(),
|
||||||
"color": self.color_name,
|
"color": self.color_name,
|
||||||
"pickup": self.pickup_checkbox.isChecked(),
|
"pickup": self.pickup_checkbox.isChecked(),
|
||||||
"last_sent": self.last_sent,
|
"last_sent": self.last_sent,
|
||||||
"hw_cc": self.hw_cc,
|
"hw_cc": self.hw_cc,
|
||||||
|
"hw_channel": self.hw_channel,
|
||||||
"zone": self.zone,
|
"zone": self.zone,
|
||||||
"center_index": self.center_index,
|
"center_index": self.center_index,
|
||||||
"zone_index": self.zone_index
|
"zone_index": self.zone_index
|
||||||
@@ -362,6 +434,7 @@ class FaderWidget(QWidget):
|
|||||||
self.uid = state["uid"]
|
self.uid = state["uid"]
|
||||||
self.title_edit.setText(state.get("label", ""))
|
self.title_edit.setText(state.get("label", ""))
|
||||||
self.cc_spin.setValue(state.get("cc", 1))
|
self.cc_spin.setValue(state.get("cc", 1))
|
||||||
|
self.ch_spin.setValue(state.get("ch", 1))
|
||||||
self.last_sent = state.get("last_sent", 64)
|
self.last_sent = state.get("last_sent", 64)
|
||||||
self.fader.setValue(state.get("value", 64))
|
self.fader.setValue(state.get("value", 64))
|
||||||
color_name = state.get("color", "Gray")
|
color_name = state.get("color", "Gray")
|
||||||
@@ -379,9 +452,10 @@ class FaderWidget(QWidget):
|
|||||||
self.zone_index = state.get("zone_index", None)
|
self.zone_index = state.get("zone_index", None)
|
||||||
self.zone_btn.set_state(self.zone == "left", self.zone == "right")
|
self.zone_btn.set_state(self.zone == "left", self.zone == "right")
|
||||||
self.hw_cc = state.get("hw_cc", None)
|
self.hw_cc = state.get("hw_cc", None)
|
||||||
|
self.hw_channel = state.get("hw_channel", None)
|
||||||
if self.hw_cc is not None:
|
if self.hw_cc is not None:
|
||||||
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
||||||
self.cc_input_lbl.setText(f"In CC{self.hw_cc} [--]")
|
self.cc_input_lbl.setText(self._cc_input_label())
|
||||||
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
||||||
else:
|
else:
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
|
|||||||
+3
-3
@@ -12,11 +12,11 @@ available_ports = midi_out.get_ports()
|
|||||||
print("Available MIDI ports:", available_ports)
|
print("Available MIDI ports:", available_ports)
|
||||||
|
|
||||||
|
|
||||||
def send_cc(cc_number, value):
|
def send_cc(cc_number, value, channel=None):
|
||||||
|
ch = (channel - 1) if channel is not None else MIDI_CH
|
||||||
if midi_out.is_port_open():
|
if midi_out.is_port_open():
|
||||||
midi_out.send_message([0xB0 | MIDI_CH, cc_number, value])
|
midi_out.send_message([0xB0 | ch, cc_number, value])
|
||||||
midi_receiver.midi_out_signal.emit()
|
midi_receiver.midi_out_signal.emit()
|
||||||
#print([0xB0 | MIDI_CH, cc_number, value])
|
|
||||||
|
|
||||||
|
|
||||||
def send_transport_cc(cc_number, value):
|
def send_transport_cc(cc_number, value):
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ class OSCReceiver(QObject):
|
|||||||
record_signal = pyqtSignal(int)
|
record_signal = pyqtSignal(int)
|
||||||
raw_message_signal = pyqtSignal(str, str)
|
raw_message_signal = pyqtSignal(str, str)
|
||||||
osc_out_signal = pyqtSignal(str, str)
|
osc_out_signal = pyqtSignal(str, str)
|
||||||
|
uuid_preset = pyqtSignal(str)
|
||||||
|
bar_signal = pyqtSignal(str)
|
||||||
|
|
||||||
|
|
||||||
osc_receiver = OSCReceiver()
|
osc_receiver = OSCReceiver()
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
from pythonosc import udp_client
|
from pythonosc import udp_client
|
||||||
from midi_receiver import midi_receiver
|
|
||||||
from osc_receiver import osc_receiver
|
from osc_receiver import osc_receiver
|
||||||
|
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ def set_osc_target(ip=None, port=None):
|
|||||||
def send_osc_message(address, value=1.0):
|
def send_osc_message(address, value=1.0):
|
||||||
try:
|
try:
|
||||||
get_osc_client().send_message(address, float(value))
|
get_osc_client().send_message(address, float(value))
|
||||||
midi_receiver.transport_out_signal.emit()
|
|
||||||
osc_receiver.osc_out_signal.emit(address, str(value))
|
osc_receiver.osc_out_signal.emit(address, str(value))
|
||||||
print(f"[OSC] → {address} {value}")
|
print(f"[OSC] → {address} {value}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
+27
-14
@@ -15,6 +15,7 @@ PRESETS_FILE = os.path.join(PRESETS_DIR, "presets.json")
|
|||||||
os.makedirs(PRESETS_DIR, exist_ok=True)
|
os.makedirs(PRESETS_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def load_presets_file():
|
def load_presets_file():
|
||||||
if os.path.exists(PRESETS_FILE):
|
if os.path.exists(PRESETS_FILE):
|
||||||
with open(PRESETS_FILE, "r") as f:
|
with open(PRESETS_FILE, "r") as f:
|
||||||
@@ -27,32 +28,42 @@ def save_presets_file(data):
|
|||||||
|
|
||||||
def ensure_preset_structure(presets):
|
def ensure_preset_structure(presets):
|
||||||
if "presets" not in presets:
|
if "presets" not in presets:
|
||||||
return {"__last_used__": None, "presets": presets}
|
return {"__last_used__": None, "presets": presets, "transport_preset": [], "transport_show_hide": False, "io_config": {}}
|
||||||
|
if "transport_preset" not in presets:
|
||||||
|
presets["transport_preset"] = []
|
||||||
|
if "transport_show_hide" not in presets:
|
||||||
|
presets["transport_show_hide"] = False
|
||||||
|
if "io_config" not in presets:
|
||||||
|
presets["io_config"] = {}
|
||||||
return presets
|
return presets
|
||||||
|
|
||||||
def on_preset_selected(menu_presets: QComboBox, app_window: QMainWindow, ready: bool, loaded_presets: dict):
|
def on_preset_selected(menu_presets: QComboBox, app_window: QMainWindow, ready: bool, loaded_presets: dict, on_load=None):
|
||||||
|
|
||||||
selectedOption = menu_presets.currentText()
|
selectedOption = menu_presets.currentText()
|
||||||
|
|
||||||
if ready and selectedOption and selectedOption in loaded_presets["presets"]:
|
if ready and selectedOption and selectedOption in loaded_presets["presets"]:
|
||||||
loaded_presets["__last_used__"] = selectedOption
|
loaded_presets["__last_used__"] = selectedOption
|
||||||
save_presets_file(loaded_presets)
|
save_presets_file(loaded_presets)
|
||||||
app_window.apply_preset(loaded_presets["presets"][selectedOption])
|
if on_load:
|
||||||
|
on_load(loaded_presets["presets"][selectedOption])
|
||||||
|
|
||||||
def save_preset(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict):
|
|
||||||
|
def save_preset(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict, on_save=None, on_build=None, on_save_as=None):
|
||||||
|
|
||||||
selectedOption = menu_presets.currentText()
|
selectedOption = menu_presets.currentText()
|
||||||
|
|
||||||
if not selectedOption or selectedOption not in loaded_presets["presets"]:
|
if not selectedOption or selectedOption not in loaded_presets["presets"]:
|
||||||
app_window.save_preset_as() # not self
|
if on_save_as:
|
||||||
|
on_save_as()
|
||||||
return
|
return
|
||||||
loaded_presets["presets"][selectedOption] = app_window._build_preset_data(selectedOption) # not self
|
loaded_presets["presets"][selectedOption] = on_build(selectedOption) if on_build else {}
|
||||||
loaded_presets["__last_used__"] = selectedOption
|
loaded_presets["__last_used__"] = selectedOption
|
||||||
save_presets_file(loaded_presets)
|
save_presets_file(loaded_presets)
|
||||||
app_window._show_save_status() # not self
|
if on_save:
|
||||||
|
on_save()
|
||||||
print(f"Saved preset: {selectedOption}")
|
print(f"Saved preset: {selectedOption}")
|
||||||
|
|
||||||
def save_preset_as(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict):
|
def save_preset_as(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict, on_save=None, on_refresh=None, on_build=None):
|
||||||
|
|
||||||
print(f"save as button tapped")
|
print(f"save as button tapped")
|
||||||
|
|
||||||
@@ -62,18 +73,19 @@ def save_preset_as(app_window: QMainWindow, menu_presets: QComboBox, loaded_pres
|
|||||||
if not ok or not selectedOption.strip():
|
if not ok or not selectedOption.strip():
|
||||||
return
|
return
|
||||||
selectedOption = selectedOption.strip()
|
selectedOption = selectedOption.strip()
|
||||||
loaded_presets["presets"][selectedOption] = app_window._build_preset_data(selectedOption)
|
loaded_presets["presets"][selectedOption] = on_build(selectedOption) if on_build else {}
|
||||||
loaded_presets["__last_used__"] = selectedOption
|
loaded_presets["__last_used__"] = selectedOption
|
||||||
save_presets_file(loaded_presets)
|
save_presets_file(loaded_presets)
|
||||||
app_window.refresh_preset_combo()
|
if on_refresh:
|
||||||
|
on_refresh()
|
||||||
menu_presets.setCurrentText(selectedOption)
|
menu_presets.setCurrentText(selectedOption)
|
||||||
app_window._show_save_status()
|
if on_save:
|
||||||
|
on_save()
|
||||||
print(f"Saved preset as: {selectedOption}")
|
print(f"Saved preset as: {selectedOption}")
|
||||||
|
|
||||||
|
|
||||||
def delete_preset(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict):
|
|
||||||
|
|
||||||
selectedOption = menu_presets.currentText()
|
def delete_preset(app_window: QMainWindow, menu_presets: QComboBox, loaded_presets: dict, on_refresh=None):
|
||||||
|
|
||||||
selectedOption = menu_presets.currentText()
|
selectedOption = menu_presets.currentText()
|
||||||
|
|
||||||
@@ -96,5 +108,6 @@ def delete_preset(app_window: QMainWindow, menu_presets: QComboBox, loaded_prese
|
|||||||
loaded_presets["__last_used__"] = None
|
loaded_presets["__last_used__"] = None
|
||||||
|
|
||||||
save_presets_file(loaded_presets)
|
save_presets_file(loaded_presets)
|
||||||
app_window.refresh_preset_combo()
|
if on_refresh:
|
||||||
|
on_refresh()
|
||||||
print(f"Deleted preset: {selectedOption}")
|
print(f"Deleted preset: {selectedOption}")
|
||||||
+212
-859
File diff suppressed because it is too large
Load Diff
+95
-27
@@ -16,8 +16,8 @@ class ToggleWidget(QWidget):
|
|||||||
def __init__(self, label, default_cc):
|
def __init__(self, label, default_cc):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
||||||
self.setFixedWidth(100)
|
self.setFixedWidth(115)
|
||||||
self.current_color = "transparent"
|
self.current_color = PALETTE_HEX.get("Gray", "#263238")
|
||||||
self.toggle_state = False
|
self.toggle_state = False
|
||||||
self.uid = str(uuid.uuid4())
|
self.uid = str(uuid.uuid4())
|
||||||
self.zone = None
|
self.zone = None
|
||||||
@@ -38,33 +38,83 @@ class ToggleWidget(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.hw_cc = None
|
self.hw_cc = None
|
||||||
|
self.hw_channel = None
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
|
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;")
|
||||||
inner.addWidget(self.cc_input_lbl)
|
self.cc_input_lbl.setFixedHeight(16)
|
||||||
|
_grp1_layout.addWidget(self.cc_input_lbl)
|
||||||
|
|
||||||
|
inner.addWidget(self.grp_learn)
|
||||||
|
|
||||||
|
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: CC spin + CH spin + output 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)
|
||||||
|
|
||||||
# CC spin
|
|
||||||
self.cc_spin = QSpinBox()
|
self.cc_spin = QSpinBox()
|
||||||
self.cc_spin.setMinimum(1)
|
self.cc_spin.setMinimum(0)
|
||||||
self.cc_spin.setMaximum(127)
|
self.cc_spin.setMaximum(127)
|
||||||
self.cc_spin.setValue(default_cc)
|
self.cc_spin.setValue(default_cc)
|
||||||
self.cc_spin.setFixedWidth(75)
|
self.cc_spin.setFixedWidth(55)
|
||||||
inner.addWidget(self.cc_spin, alignment=Qt.AlignmentFlag.AlignHCenter)
|
_cc_lbl = QLabel("CC")
|
||||||
|
_cc_lbl.setStyleSheet("color: #fff; font-size: 10px; border: none;")
|
||||||
|
self.cc_spin_row = QWidget()
|
||||||
|
_hbox_cc = QHBoxLayout(self.cc_spin_row)
|
||||||
|
_hbox_cc.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_hbox_cc.setSpacing(4)
|
||||||
|
_hbox_cc.addWidget(_cc_lbl)
|
||||||
|
_hbox_cc.addWidget(self.cc_spin)
|
||||||
|
_grp2_layout.addWidget(self.cc_spin_row)
|
||||||
|
|
||||||
self.cc_output_lbl = QLabel(f"Out CC{default_cc} [--]")
|
self.ch_spin = QSpinBox()
|
||||||
|
self.ch_spin.setMinimum(1)
|
||||||
|
self.ch_spin.setMaximum(16)
|
||||||
|
self.ch_spin.setValue(1)
|
||||||
|
self.ch_spin.setFixedWidth(55)
|
||||||
|
_ch_lbl = QLabel("CH")
|
||||||
|
_ch_lbl.setStyleSheet("color: #fff; font-size: 10px; border: none;")
|
||||||
|
self.ch_spin_row = QWidget()
|
||||||
|
_hbox_ch = QHBoxLayout(self.ch_spin_row)
|
||||||
|
_hbox_ch.setContentsMargins(0, 0, 0, 0)
|
||||||
|
_hbox_ch.setSpacing(4)
|
||||||
|
_hbox_ch.addWidget(_ch_lbl)
|
||||||
|
_hbox_ch.addWidget(self.ch_spin)
|
||||||
|
_grp2_layout.addWidget(self.ch_spin_row)
|
||||||
|
|
||||||
|
self.cc_output_lbl = QLabel(f"CC{default_cc} [--]")
|
||||||
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
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.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px; border: none;")
|
||||||
inner.addWidget(self.cc_output_lbl)
|
self.cc_output_lbl.setFixedHeight(16)
|
||||||
|
_grp2_layout.addWidget(self.cc_output_lbl)
|
||||||
|
|
||||||
|
inner.addWidget(self.grp_cc)
|
||||||
|
|
||||||
# Toggle button with LED dot overlay
|
# Toggle button with LED dot overlay
|
||||||
btn_container = QWidget()
|
btn_container = QWidget()
|
||||||
@@ -161,6 +211,17 @@ class ToggleWidget(QWidget):
|
|||||||
def set_selected(self, selected):
|
def set_selected(self, selected):
|
||||||
self.apply_color(self.current_color, selected=selected)
|
self.apply_color(self.current_color, selected=selected)
|
||||||
|
|
||||||
|
def _cc_input_label(self, vel="--"):
|
||||||
|
if self.hw_cc is None:
|
||||||
|
return ""
|
||||||
|
ch = f" CH{self.hw_channel}" if self.hw_channel is not None else ""
|
||||||
|
return f"CC{self.hw_cc}{ch} [{vel}]"
|
||||||
|
|
||||||
|
def _cc_output_label(self, vel="--"):
|
||||||
|
out_cc = self.cc_spin.value()
|
||||||
|
out_ch = self.ch_spin.value()
|
||||||
|
return f"CC{out_cc} CH{out_ch} [{vel}]"
|
||||||
|
|
||||||
def start_learn(self):
|
def start_learn(self):
|
||||||
self.is_learning = True
|
self.is_learning = True
|
||||||
self.learn_btn.setText("Listening...")
|
self.learn_btn.setText("Listening...")
|
||||||
@@ -168,18 +229,19 @@ class ToggleWidget(QWidget):
|
|||||||
|
|
||||||
def stop_learn(self):
|
def stop_learn(self):
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
self.learn_btn.setStyleSheet("")
|
self.learn_btn.setStyleSheet("border: none;")
|
||||||
if self.hw_cc is not None:
|
if self.hw_cc is not None:
|
||||||
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
||||||
self.cc_input_lbl.setText(f"In CC{self.hw_cc} [--]")
|
self.cc_input_lbl.setText(self._cc_input_label())
|
||||||
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px; border: none;")
|
||||||
else:
|
else:
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.cc_input_lbl.setText("")
|
self.cc_input_lbl.setText("")
|
||||||
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;")
|
||||||
|
|
||||||
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.hw_channel = channel
|
||||||
self.stop_learn()
|
self.stop_learn()
|
||||||
|
|
||||||
def on_learn_context_menu(self, pos):
|
def on_learn_context_menu(self, pos):
|
||||||
@@ -191,9 +253,10 @@ class ToggleWidget(QWidget):
|
|||||||
action = menu.exec(self.learn_btn.mapToGlobal(pos))
|
action = menu.exec(self.learn_btn.mapToGlobal(pos))
|
||||||
if action == clear_action:
|
if action == clear_action:
|
||||||
self.hw_cc = None
|
self.hw_cc = None
|
||||||
|
self.hw_channel = None
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.learn_btn.setStyleSheet("")
|
self.learn_btn.setStyleSheet("border: none;")
|
||||||
self.cc_input_lbl.setText("")
|
self.cc_input_lbl.setText("")
|
||||||
|
|
||||||
def update_id_label(self, zone, index):
|
def update_id_label(self, zone, index):
|
||||||
@@ -229,9 +292,11 @@ class ToggleWidget(QWidget):
|
|||||||
def on_click(self):
|
def on_click(self):
|
||||||
self.toggle_state = not self.toggle_state
|
self.toggle_state = not self.toggle_state
|
||||||
cc_num = self.cc_spin.value()
|
cc_num = self.cc_spin.value()
|
||||||
|
out_ch = self.ch_spin.value()
|
||||||
value = 127 if self.toggle_state else 0
|
value = 127 if self.toggle_state else 0
|
||||||
send_cc(cc_num, value)
|
print(f"[toggle] CC{cc_num} CH{out_ch} ({value})")
|
||||||
self.cc_output_lbl.setText(f"Out CC{cc_num} [{value}]")
|
send_cc(cc_num, value, channel=out_ch)
|
||||||
|
self.cc_output_lbl.setText(self._cc_output_label(value))
|
||||||
self._update_btn_style()
|
self._update_btn_style()
|
||||||
|
|
||||||
def _update_btn_style(self):
|
def _update_btn_style(self):
|
||||||
@@ -245,12 +310,14 @@ class ToggleWidget(QWidget):
|
|||||||
"uid": self.uid,
|
"uid": self.uid,
|
||||||
"label": self.title_edit.text(),
|
"label": self.title_edit.text(),
|
||||||
"cc": self.cc_spin.value(),
|
"cc": self.cc_spin.value(),
|
||||||
|
"ch": self.ch_spin.value(),
|
||||||
"state": self.toggle_state,
|
"state": self.toggle_state,
|
||||||
"color": self.color_name,
|
"color": self.color_name,
|
||||||
"zone": self.zone,
|
"zone": self.zone,
|
||||||
"center_index": self.center_index,
|
"center_index": self.center_index,
|
||||||
"zone_index": self.zone_index,
|
"zone_index": self.zone_index,
|
||||||
"hw_cc": self.hw_cc
|
"hw_cc": self.hw_cc,
|
||||||
|
"hw_channel": self.hw_channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
def set_state(self, state):
|
def set_state(self, state):
|
||||||
@@ -258,6 +325,7 @@ class ToggleWidget(QWidget):
|
|||||||
self.uid = state["uid"]
|
self.uid = state["uid"]
|
||||||
self.title_edit.setText(state.get("label", ""))
|
self.title_edit.setText(state.get("label", ""))
|
||||||
self.cc_spin.setValue(state.get("cc", 1))
|
self.cc_spin.setValue(state.get("cc", 1))
|
||||||
|
self.ch_spin.setValue(state.get("ch", 1))
|
||||||
color_name = state.get("color", "Gray")
|
color_name = state.get("color", "Gray")
|
||||||
hex_color = PALETTE_HEX.get(color_name, "transparent")
|
hex_color = PALETTE_HEX.get(color_name, "transparent")
|
||||||
self.color_name = color_name
|
self.color_name = color_name
|
||||||
@@ -265,18 +333,18 @@ class ToggleWidget(QWidget):
|
|||||||
self.apply_color(hex_color)
|
self.apply_color(hex_color)
|
||||||
self.toggle_state = state.get("state", False)
|
self.toggle_state = state.get("state", False)
|
||||||
self._update_btn_style()
|
self._update_btn_style()
|
||||||
cc_num = self.cc_spin.value()
|
|
||||||
value = 127 if self.toggle_state else 0
|
value = 127 if self.toggle_state else 0
|
||||||
self.cc_output_lbl.setText(f"Out CC{cc_num} [{value}]")
|
self.cc_output_lbl.setText(self._cc_output_label(value))
|
||||||
self.zone = state.get("zone", None)
|
self.zone = state.get("zone", None)
|
||||||
self.center_index = state.get("center_index", None)
|
self.center_index = state.get("center_index", None)
|
||||||
self.zone_index = state.get("zone_index", None)
|
self.zone_index = state.get("zone_index", None)
|
||||||
self.zone_btn.set_state(self.zone == "left", self.zone == "right")
|
self.zone_btn.set_state(self.zone == "left", self.zone == "right")
|
||||||
self.hw_cc = state.get("hw_cc", None)
|
self.hw_cc = state.get("hw_cc", None)
|
||||||
|
self.hw_channel = state.get("hw_channel", None)
|
||||||
if self.hw_cc is not None:
|
if self.hw_cc is not None:
|
||||||
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
self.learn_btn.setText(f"HW: CC{self.hw_cc}")
|
||||||
self.cc_input_lbl.setText(f"In CC{self.hw_cc} [--]")
|
self.cc_input_lbl.setText(self._cc_input_label())
|
||||||
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
self.cc_input_lbl.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px; border: none;")
|
||||||
else:
|
else:
|
||||||
self.learn_btn.setText("Learn")
|
self.learn_btn.setText("Learn")
|
||||||
self.cc_input_lbl.setText("")
|
self.cc_input_lbl.setText("")
|
||||||
+11
-9
@@ -4,7 +4,7 @@ from PyQt6.QtWidgets import (
|
|||||||
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
||||||
QLabel, QSpinBox, QLineEdit, QFrame, QSizePolicy
|
QLabel, QSpinBox, QLineEdit, QFrame, QSizePolicy
|
||||||
)
|
)
|
||||||
from PyQt6.QtCore import Qt, QEvent
|
from PyQt6.QtCore import Qt, QEvent, QTimer
|
||||||
|
|
||||||
from palette import PALETTE_HEX, PALETTE_VIVID
|
from palette import PALETTE_HEX, PALETTE_VIVID
|
||||||
from styles import TITLE_STYLE
|
from styles import TITLE_STYLE
|
||||||
@@ -24,13 +24,13 @@ class TransportWidget(QWidget):
|
|||||||
self.toggle_state = False
|
self.toggle_state = False
|
||||||
self.hw_cc = None
|
self.hw_cc = None
|
||||||
self.is_learning = False
|
self.is_learning = False
|
||||||
self.current_color = "transparent"
|
self.current_color = PALETTE_HEX.get("Gray", "#263238")
|
||||||
self.color_name = "Gray"
|
self.color_name = "Gray"
|
||||||
self.on_select_callback = None
|
self.on_select_callback = None
|
||||||
self.on_zone_change_callback = None
|
self.on_zone_change_callback = None
|
||||||
self._label = label
|
self._label = label
|
||||||
|
|
||||||
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Maximum)
|
||||||
self.setFixedWidth(100)
|
self.setFixedWidth(100)
|
||||||
|
|
||||||
outer = QVBoxLayout(self)
|
outer = QVBoxLayout(self)
|
||||||
@@ -57,6 +57,7 @@ class TransportWidget(QWidget):
|
|||||||
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;")
|
||||||
|
self.cc_input_lbl.setFixedHeight(16)
|
||||||
inner.addWidget(self.cc_input_lbl)
|
inner.addWidget(self.cc_input_lbl)
|
||||||
|
|
||||||
# CC spin
|
# CC spin
|
||||||
@@ -71,6 +72,7 @@ class TransportWidget(QWidget):
|
|||||||
self.cc_output_lbl = QLabel(f"Out CC{default_cc} [--]")
|
self.cc_output_lbl = QLabel(f"Out CC{default_cc} [--]")
|
||||||
self.cc_output_lbl.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
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.setStyleSheet("background-color: #000000; color: #00e676; font-size: 10px; padding: 1px;")
|
||||||
|
self.cc_output_lbl.setFixedHeight(16)
|
||||||
inner.addWidget(self.cc_output_lbl)
|
inner.addWidget(self.cc_output_lbl)
|
||||||
|
|
||||||
# MIDI / OSC mode selector
|
# MIDI / OSC mode selector
|
||||||
@@ -114,10 +116,9 @@ class TransportWidget(QWidget):
|
|||||||
# 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.setFixedWidth(75)
|
|
||||||
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, alignment=Qt.AlignmentFlag.AlignHCenter)
|
inner.addWidget(self.osc_addr_edit)
|
||||||
|
|
||||||
self.output_mode = "midi" # "midi" or "osc"
|
self.output_mode = "midi" # "midi" or "osc"
|
||||||
|
|
||||||
@@ -140,6 +141,7 @@ class TransportWidget(QWidget):
|
|||||||
self.title_edit = QLineEdit(label)
|
self.title_edit = QLineEdit(label)
|
||||||
self.title_edit.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
self.title_edit.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
self.title_edit.setStyleSheet(TITLE_STYLE)
|
self.title_edit.setStyleSheet(TITLE_STYLE)
|
||||||
|
self.title_edit.textChanged.connect(self.btn.setText)
|
||||||
inner.addWidget(self.title_edit)
|
inner.addWidget(self.title_edit)
|
||||||
|
|
||||||
# Color swatch
|
# Color swatch
|
||||||
@@ -170,10 +172,10 @@ class TransportWidget(QWidget):
|
|||||||
inner.addWidget(self.zone_btn)
|
inner.addWidget(self.zone_btn)
|
||||||
|
|
||||||
# Separator + ID label
|
# Separator + ID label
|
||||||
id_sep = QWidget()
|
self.id_sep = QWidget()
|
||||||
id_sep.setFixedHeight(1)
|
self.id_sep.setFixedHeight(1)
|
||||||
id_sep.setStyleSheet("background-color: #3a3a3a;")
|
self.id_sep.setStyleSheet("background-color: #3a3a3a;")
|
||||||
inner.addWidget(id_sep)
|
inner.addWidget(self.id_sep)
|
||||||
|
|
||||||
self.id_label = QLabel("")
|
self.id_label = QLabel("")
|
||||||
self.id_label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
self.id_label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class ZoneButton(QPushButton):
|
|||||||
self._update_style()
|
self._update_style()
|
||||||
|
|
||||||
def _update_style(self):
|
def _update_style(self):
|
||||||
l_color = "#00c853" if self.left_active else "#2a2a2a"
|
l_color = "#ff8c00" if self.left_active else "#2a2a2a"
|
||||||
r_color = "#00c853" if self.right_active else "#2a2a2a"
|
r_color = "#00c853" if self.right_active else "#2a2a2a"
|
||||||
|
|
||||||
self.setStyleSheet(f"""
|
self.setStyleSheet(f"""
|
||||||
|
|||||||
Reference in New Issue
Block a user