diff --git a/main.py b/main.py
index 5de6f0d..120b5fa 100644
--- a/main.py
+++ b/main.py
@@ -7,7 +7,7 @@ from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QSlider, QComboBox, QLabel, QPushButton,
QSizePolicy, QSpinBox, QLineEdit, QInputDialog, QFrame,
- QCheckBox
+ QCheckBox, QTextEdit
)
from PyQt6.QtCore import Qt, QObject, pyqtSignal, QTimer, QEvent
from PyQt6.QtGui import QAction, QColor
@@ -192,14 +192,12 @@ hstack_io_row.setSpacing(16)
-# ===== MODULE LEVEL =====
# REFACTOR MAP: Old names → New names
# self.in_blink → activity_indicator_midi_in
# self.in_status → label_connection_midi_in
# self.in_combo → picker_midi_in
# self.available_in_ports → available_ports_midi_in
-
# vstack_midi_in
vstack_midi_in = QVBoxLayout()
vstack_midi_in.setSpacing(2)
@@ -225,8 +223,439 @@ picker_midi_in.setFixedWidth(200)
picker_midi_in.setStyleSheet("background-color: rgba(0, 255, 0, 0.15); border: 1px solid green;")
+# REFACTOR MAP: Old names → New names
+# self.out_blink → activity_indicator_midi_out
+# self.out_status → label_connection_midi_out
+# self.port_combo → picker_midi_out
+
+# vstack_midi_out
+vstack_midi_out = QVBoxLayout()
+vstack_midi_out.setSpacing(2)
+
+# hstack_midi_out_activity_and_label
+hstack_midi_out_activity_and_label = QHBoxLayout()
+
+# activity_indicator_midi_out
+activity_indicator_midi_out = QLabel("●")
+activity_indicator_midi_out.setStyleSheet("color: #444; font-size: 14px; background-color: rgba(255, 0, 0, 0.15); border: 1px solid red; padding: 2px;")
+
+# label_connection_midi_out
+label_connection_midi_out = QLabel("Not Connected")
+label_connection_midi_out.setStyleSheet("color: #888; background-color: rgba(0, 0, 255, 0.15); border: 1px solid blue; padding: 2px;")
+
+# label_midi_out
+label_midi_out = QLabel("MIDI Output")
+label_midi_out.setStyleSheet("background-color: rgba(255, 255, 0, 0.15); border: 1px solid yellow; padding: 2px;")
+
+# picker_midi_out
+picker_midi_out = QComboBox()
+picker_midi_out.setFixedWidth(200)
+picker_midi_out.setStyleSheet("background-color: rgba(0, 255, 0, 0.15); border: 1px solid green;")
+
+# REFACTOR MAP: Old names → New names
+# self.t_out_blink → activity_indicator_transport_out
+# self.t_out_status → label_connection_transport_out
+# self.t_out_combo → picker_transport_out
+
+# vstack_transport_out
+vstack_transport_out = QVBoxLayout()
+vstack_transport_out.setSpacing(2)
+
+# hstack_transport_out_activity_and_label
+hstack_transport_out_activity_and_label = QHBoxLayout()
+
+# activity_indicator_transport_out
+activity_indicator_transport_out = QLabel("●")
+activity_indicator_transport_out.setStyleSheet("color: #444; font-size: 14px; background-color: rgba(255, 0, 0, 0.15); border: 1px solid red; padding: 2px;")
+
+# label_connection_transport_out
+label_connection_transport_out = QLabel("Not Connected")
+label_connection_transport_out.setStyleSheet("color: #888; background-color: rgba(0, 0, 255, 0.15); border: 1px solid blue; padding: 2px;")
+
+# label_transport_out
+label_transport_out = QLabel("Transport Output")
+label_transport_out.setStyleSheet("background-color: rgba(255, 255, 0, 0.15); border: 1px solid yellow; padding: 2px;")
+
+# picker_transport_out
+picker_transport_out = QComboBox()
+picker_transport_out.setFixedWidth(200)
+picker_transport_out.setStyleSheet("background-color: rgba(0, 255, 0, 0.15); border: 1px solid green;")
+
+# REFACTOR MAP: Old names → New names
+# self.osc_blink → activity_indicator_osc
+# self.osc_status → label_connection_osc
+# self.osc_ip_edit → textbox_osc_daw_ip
+# self.osc_port_spin → spinner_osc_listen_port
+# self.osc_send_port_spin → spinner_osc_send_port
+# self.osc_toggle_btn → button_osc_toggle
+# self.osc_log_btn → button_osc_messages_log
+
+# Layout: vstack_osc
+vstack_osc = QVBoxLayout()
+vstack_osc.setSpacing(2)
+
+# Layout: hstack_osc_activity_and_label
+hstack_osc_activity_and_label = QHBoxLayout()
+
+# Layout: hstack_osc_ip
+hstack_osc_ip = QHBoxLayout()
+
+# Layout: hstack_osc_ports
+hstack_osc_ports = QHBoxLayout()
+
+# Layout: hstack_osc_buttons
+hstack_osc_buttons = QHBoxLayout()
+
+# Widget: activity_indicator_osc
+activity_indicator_osc = QLabel("●")
+activity_indicator_osc.setStyleSheet("color: #444; font-size: 14px; background-color: rgba(255, 0, 0, 0.15); border: 1px solid red; padding: 2px;")
+
+# Widget: label_connection_osc
+label_connection_osc = QLabel("Not Listening")
+label_connection_osc.setStyleSheet("color: #888; background-color: rgba(0, 0, 255, 0.15); border: 1px solid blue; padding: 2px;")
+
+# Widget: textbox_osc_daw_ip
+textbox_osc_daw_ip = QLineEdit("127.0.0.1")
+textbox_osc_daw_ip.setFixedWidth(110)
+textbox_osc_daw_ip.setPlaceholderText("127.0.0.1")
+
+# Widget: spinner_osc_listen_port
+spinner_osc_listen_port = QSpinBox()
+spinner_osc_listen_port.setMinimum(1024)
+spinner_osc_listen_port.setMaximum(65535)
+spinner_osc_listen_port.setValue(9000)
+spinner_osc_listen_port.setFixedWidth(65)
+
+# Widget: spinner_osc_send_port
+spinner_osc_send_port = QSpinBox()
+spinner_osc_send_port.setMinimum(1024)
+spinner_osc_send_port.setMaximum(65535)
+spinner_osc_send_port.setValue(8000)
+spinner_osc_send_port.setFixedWidth(65)
+
+# Widget: button_osc_toggle
+button_osc_toggle = QPushButton("Start OSC")
+button_osc_toggle.setFixedWidth(90)
+
+# Widget: button_osc_messages_log
+button_osc_messages_log = QPushButton("Messages")
+button_osc_messages_log.setFixedWidth(80)
+button_osc_messages_log.setCheckable(True)
+# MARK: OSC STATUS ROW MODULE
+# REFACTOR MAP: Old names → New names
+# self.osc_panel → container_osc_feedback
+# self.osc_play_lbl → label_osc_play_state
+# self.osc_record_lbl → label_osc_record_state
+# self.osc_tempo_lbl → label_osc_tempo
+# self.osc_pos_lbl → label_osc_position
+# self.osc_track_lbl → label_osc_track
+# self.osc_preset_lbl → label_osc_preset
+# self.osc_log_panel → container_osc_in_log
+# self.osc_log → textedit_osc_in_log
+# self.osc_out_log_panel → container_osc_out_log
+# self.osc_out_log → textedit_osc_out_log
+
+# Container: container_osc_feedback
+container_osc_feedback = QWidget()
+container_osc_feedback.setStyleSheet("background-color: #252526; border-radius: 4px;")
+
+# Layout: vstack_osc_feedback
+vstack_osc_feedback = QVBoxLayout(container_osc_feedback)
+vstack_osc_feedback.setContentsMargins(8, 6, 8, 6)
+vstack_osc_feedback.setSpacing(4)
+
+# Layout: hstack_osc_transport_state
+hstack_osc_transport_state = QHBoxLayout()
+hstack_osc_transport_state.setSpacing(12)
+
+# Widget: label_osc_play_state
+label_osc_play_state = QLabel("■ STOPPED")
+label_osc_play_state.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
+
+# Widget: label_osc_record_state
+label_osc_record_state = QLabel("● REC")
+label_osc_record_state.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
+
+# Widget: label_osc_tempo
+label_osc_tempo = QLabel("BPM: —")
+label_osc_tempo.setStyleSheet("color: #888; font-size: 11px;")
+
+# Widget: label_osc_position
+label_osc_position = QLabel("Pos: —")
+label_osc_position.setStyleSheet("color: #888; font-size: 11px;")
+
+# Widget: divider_osc_feedback
+divider_osc_feedback = QWidget()
+divider_osc_feedback.setFixedHeight(1)
+divider_osc_feedback.setStyleSheet("background-color: #3a3a3a;")
+
+# Layout: hstack_osc_info
+hstack_osc_info = QHBoxLayout()
+hstack_osc_info.setSpacing(8)
+
+# Widget: label_track_header
+label_track_header = QLabel("TRACK")
+label_track_header.setStyleSheet("color: #555; font-size: 9px; font-weight: bold;")
+
+# Widget: label_osc_track
+label_osc_track = QLabel("—")
+label_osc_track.setStyleSheet("color: #d4d4d4; font-size: 12px; font-weight: bold;")
+
+# Widget: label_preset_header
+label_preset_header = QLabel("PRESET")
+label_preset_header.setStyleSheet("color: #555; font-size: 9px; font-weight: bold;")
+
+# Widget: label_osc_preset
+label_osc_preset = QLabel("—")
+label_osc_preset.setStyleSheet("color: #00e676; font-size: 12px; font-weight: bold;")
+
+# Widget: spacer_osc_info
+spacer_osc_info = QWidget()
+spacer_osc_info.setFixedWidth(16)
+
+# Container: container_osc_in_log
+container_osc_in_log = QWidget(None, Qt.WindowType.Tool)
+container_osc_in_log.setWindowTitle("OSC In — Incoming")
+container_osc_in_log.setStyleSheet("background-color: #1a1a1a;")
+container_osc_in_log.setFixedWidth(360)
+
+# Layout: vstack_osc_in_log
+vstack_osc_in_log = QVBoxLayout(container_osc_in_log)
+vstack_osc_in_log.setContentsMargins(6, 6, 6, 6)
+vstack_osc_in_log.setSpacing(4)
+
+# Layout: hstack_osc_in_log_header
+hstack_osc_in_log_header = QHBoxLayout()
+
+# Widget: label_osc_in_log_title
+label_osc_in_log_title = QLabel("OSC In — Incoming from REAPER")
+label_osc_in_log_title.setStyleSheet("color: #00e676; font-weight: bold; font-size: 11px;")
+
+# Widget: button_osc_in_clear
+button_osc_in_clear = QPushButton("Clear")
+button_osc_in_clear.setFixedSize(45, 18)
+
+# Widget: textedit_osc_in_log
+textedit_osc_in_log = QTextEdit()
+textedit_osc_in_log.setReadOnly(True)
+textedit_osc_in_log.setStyleSheet("""
+ QTextEdit {
+ background-color: #111111;
+ color: #00e676;
+ font-family: monospace;
+ font-size: 10px;
+ border: none;
+ }
+""")
+
+# Container: container_osc_out_log
+container_osc_out_log = QWidget(None, Qt.WindowType.Tool)
+container_osc_out_log.setWindowTitle("OSC Out — Outgoing")
+container_osc_out_log.setStyleSheet("background-color: #1a1a1a;")
+container_osc_out_log.setFixedWidth(360)
+
+# Layout: vstack_osc_out_log
+vstack_osc_out_log = QVBoxLayout(container_osc_out_log)
+vstack_osc_out_log.setContentsMargins(6, 6, 6, 6)
+vstack_osc_out_log.setSpacing(4)
+
+# Layout: hstack_osc_out_log_header
+hstack_osc_out_log_header = QHBoxLayout()
+
+# Widget: label_osc_out_log_title
+label_osc_out_log_title = QLabel("OSC Out — Sent to REAPER")
+label_osc_out_log_title.setStyleSheet("color: #1e88e5; font-weight: bold; font-size: 11px;")
+
+# Widget: button_osc_out_clear
+button_osc_out_clear = QPushButton("Clear")
+button_osc_out_clear.setFixedSize(45, 18)
+
+# Widget: textedit_osc_out_log
+textedit_osc_out_log = QTextEdit()
+textedit_osc_out_log.setReadOnly(True)
+textedit_osc_out_log.setStyleSheet("""
+ QTextEdit {
+ background-color: #111111;
+ color: #1e88e5;
+ font-family: monospace;
+ font-size: 10px;
+ border: none;
+ }
+""")
+
+# MARK: PRESET BROWSER ROW MODULE
+# REFACTOR MAP: Old names → New names
+# self.browser_back_spin → spinner_preset_browser_back
+# self.browser_fwd_spin → spinner_preset_browser_fwd
+
+# Widget: label_preset_browser_title
+label_preset_browser_title = QLabel("Preset Browser")
+
+# Layout: hstack_preset_browser
+hstack_preset_browser = QHBoxLayout()
+hstack_preset_browser.setSpacing(8)
+
+# Widget: button_preset_browser_back
+button_preset_browser_back = QPushButton("◀")
+button_preset_browser_back.setFixedSize(36, 28)
+
+# Widget: spinner_preset_browser_back
+spinner_preset_browser_back = QSpinBox()
+spinner_preset_browser_back.setMinimum(1)
+spinner_preset_browser_back.setMaximum(127)
+spinner_preset_browser_back.setValue(22)
+spinner_preset_browser_back.setFixedWidth(55)
+
+# Widget: button_preset_browser_fwd
+button_preset_browser_fwd = QPushButton("▶")
+button_preset_browser_fwd.setFixedSize(36, 28)
+
+# Widget: spinner_preset_browser_fwd
+spinner_preset_browser_fwd = QSpinBox()
+spinner_preset_browser_fwd.setMinimum(1)
+spinner_preset_browser_fwd.setMaximum(127)
+spinner_preset_browser_fwd.setValue(23)
+spinner_preset_browser_fwd.setFixedWidth(55)
+
+# Widget: spacer_preset_browser
+spacer_preset_browser = QWidget()
+spacer_preset_browser.setFixedWidth(12)
+
+# MARK: TRANSPORT MODULE
+# REFACTOR MAP: Old names → New names
+# self.full_transport_row → hstack_full_transport
+# self.transport_zone_left_slot → hstack_transport_zone_left
+# self.transport_vsep_left → vsep_transport_left
+# self.transport_row → hstack_transport_center
+# self.transport_vsep_right → vsep_transport_right
+# self.transport_zone_right_slot → hstack_transport_zone_right
+
+# Layout: hstack_full_transport
+hstack_full_transport = QHBoxLayout()
+hstack_full_transport.setSpacing(spacing)
+
+# Layout: hstack_transport_zone_left
+hstack_transport_zone_left = QHBoxLayout()
+hstack_transport_zone_left.setSpacing(0)
+
+# Widget: vsep_transport_left
+vsep_transport_left = QFrame()
+vsep_transport_left.setFrameShape(QFrame.Shape.VLine)
+vsep_transport_left.setFixedWidth(1)
+vsep_transport_left.setStyleSheet("background-color: #3a3a3a; border: none;")
+vsep_transport_left.setVisible(False)
+
+# Layout: hstack_transport_center
+hstack_transport_center = QHBoxLayout()
+hstack_transport_center.setSpacing(spacing)
+
+# Widget: vsep_transport_right
+vsep_transport_right = QFrame()
+vsep_transport_right.setFrameShape(QFrame.Shape.VLine)
+vsep_transport_right.setFixedWidth(1)
+vsep_transport_right.setStyleSheet("background-color: #3a3a3a; border: none;")
+vsep_transport_right.setVisible(False)
+
+# Layout: hstack_transport_zone_right
+hstack_transport_zone_right = QHBoxLayout()
+hstack_transport_zone_right.setSpacing(0)
+
+# MARK: SELECTED CHANNEL ROW MODULE
+# REFACTOR MAP: Old names → New names
+# self.selected_label → label_selected_channel
+
+# Layout: hstack_selected_channel_and_save_status
+hstack_selected_channel_and_save_status = QHBoxLayout()
+
+# Widget: label_selected_channel
+label_selected_channel = QLabel("Selected: None")
+label_selected_channel.setStyleSheet("color: #00ff88; font-weight: bold;")
+label_selected_channel.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+# MARK: FADERS ROW MODULE
+# REFACTOR MAP: Old names → New names
+# self.full_fader_row → hstack_full_fader
+# self.zone_left_slot → hstack_fader_zone_left
+# self.vsep_left → separator_vertical_fader_zone_left
+# self.fader_row → hstack_fader_center
+# self.vsep_right → separator_vertical_fader_zone_right
+# self.zone_right_slot → hstack_fader_zone_right
+
+# Layout: hstack_full_fader
+hstack_full_fader = QHBoxLayout()
+hstack_full_fader.setSpacing(spacing)
+
+# Layout: hstack_fader_zone_left
+hstack_fader_zone_left = QHBoxLayout()
+hstack_fader_zone_left.setSpacing(0)
+
+# Widget: separator_vertical_fader_zone_left
+separator_vertical_fader_zone_left = QFrame()
+separator_vertical_fader_zone_left.setFrameShape(QFrame.Shape.VLine)
+separator_vertical_fader_zone_left.setFixedWidth(1)
+separator_vertical_fader_zone_left.setStyleSheet("background-color: #3a3a3a; border: none;")
+separator_vertical_fader_zone_left.setVisible(False)
+
+# Layout: hstack_fader_center
+hstack_fader_center = QHBoxLayout()
+hstack_fader_center.setSpacing(spacing)
+
+# Widget: separator_vertical_fader_zone_right
+separator_vertical_fader_zone_right = QFrame()
+separator_vertical_fader_zone_right.setFrameShape(QFrame.Shape.VLine)
+separator_vertical_fader_zone_right.setFixedWidth(1)
+separator_vertical_fader_zone_right.setStyleSheet("background-color: #3a3a3a; border: none;")
+separator_vertical_fader_zone_right.setVisible(False)
+
+# Layout: hstack_fader_zone_right
+hstack_fader_zone_right = QHBoxLayout()
+hstack_fader_zone_right.setSpacing(0)
+
+# MARK: TOGGLE ROW MODULE
+# REFACTOR MAP: Old names → New names
+# self.full_toggle_row → hstack_full_toggle
+# self.toggle_zone_left_slot → hstack_toggle_zone_left
+# self.toggle_vsep_left → separator_vertical_toggle_zone_left
+# self.toggle_row → hstack_toggle_center
+# self.toggle_vsep_right → separator_vertical_toggle_zone_right
+# self.toggle_zone_right_slot → hstack_toggle_zone_right
+
+# Layout: hstack_full_toggle
+hstack_full_toggle = QHBoxLayout()
+hstack_full_toggle.setSpacing(spacing)
+
+# Layout: hstack_toggle_zone_left
+hstack_toggle_zone_left = QHBoxLayout()
+hstack_toggle_zone_left.setSpacing(0)
+
+# Widget: separator_vertical_toggle_zone_left
+separator_vertical_toggle_zone_left = QFrame()
+separator_vertical_toggle_zone_left.setFrameShape(QFrame.Shape.VLine)
+separator_vertical_toggle_zone_left.setFixedWidth(1)
+separator_vertical_toggle_zone_left.setStyleSheet("background-color: #3a3a3a; border: none;")
+separator_vertical_toggle_zone_left.setVisible(False)
+
+# Layout: hstack_toggle_center
+hstack_toggle_center = QHBoxLayout()
+hstack_toggle_center.setSpacing(10)
+
+# Widget: separator_vertical_toggle_zone_right
+separator_vertical_toggle_zone_right = QFrame()
+separator_vertical_toggle_zone_right.setFrameShape(QFrame.Shape.VLine)
+separator_vertical_toggle_zone_right.setFixedWidth(1)
+separator_vertical_toggle_zone_right.setStyleSheet("background-color: #3a3a3a; border: none;")
+separator_vertical_toggle_zone_right.setVisible(False)
+
+# Layout: hstack_toggle_zone_right
+hstack_toggle_zone_right = QHBoxLayout()
+hstack_toggle_zone_right.setSpacing(0)
+
+
+
+
+#MARK: MAIN WINDOW START
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
@@ -240,6 +669,12 @@ class MainWindow(QMainWindow):
global labelStatus
global hstack_io_row
global available_ports_midi_in
+ global picker_midi_in
+ global label_midi_in
+ global label_connection_midi_in
+ global activity_indicator_midi_in
+ global hstack_midi_in_activity_and_label
+ global vstack_midi_in
self.setWindowTitle("Controller")
#set app window reference
@@ -262,7 +697,7 @@ class MainWindow(QMainWindow):
#section seperator
main_layout.addWidget(self._separator())
- #MARK: MIDI IN COLUMN
+ #MARK: MIDI IN COLUMN 1
#build the hstack with activity indicator and connection state label
hstack_midi_in_activity_and_label.addWidget(activity_indicator_midi_in)
hstack_midi_in_activity_and_label.addWidget(label_connection_midi_in)
@@ -276,11 +711,6 @@ class MainWindow(QMainWindow):
# add the combined stack to the row
hstack_io_row.addLayout(vstack_midi_in)
-
-
-
-
-
# picker_midi_in population & signal
available_ports_midi_in = get_available_input_ports()
for display_name, idx, available in available_ports_midi_in:
@@ -293,437 +723,316 @@ class MainWindow(QMainWindow):
picker_midi_in.currentTextChanged.connect(self.on_input_port_select)
+ #MARK: MIDI OUT COLUMN 2
+ # Globals for mutation safety
+ global vstack_midi_out
+ global hstack_midi_out_activity_and_label
+ global activity_indicator_midi_out
+ global label_connection_midi_out
+ global label_midi_out
+ global picker_midi_out
+
+ # build the hstack with activity indicator and connection state label
+ hstack_midi_out_activity_and_label.addWidget(activity_indicator_midi_out)
+ hstack_midi_out_activity_and_label.addWidget(label_connection_midi_out)
+ hstack_midi_out_activity_and_label.addStretch()
+
+ # add all 3 to the vstack
+ vstack_midi_out.addLayout(hstack_midi_out_activity_and_label) # activity indicator and connection label
+ vstack_midi_out.addWidget(label_midi_out) # midi output label
+ vstack_midi_out.addWidget(picker_midi_out) # port dropdown
+
+ # populate the dropdown
+ picker_midi_out.addItems(available_ports)
+ picker_midi_out.currentTextChanged.connect(self.on_port_select)
+
+ # add the combined stack to the row
+ hstack_io_row.addLayout(vstack_midi_out)
-
-
-
-
-
-
-
-
+ #MARK: TRANSPORT OUT COLUMN 3
+ # Globals for mutation safety
+ global vstack_transport_out
+ global hstack_transport_out_activity_and_label
+ global activity_indicator_transport_out
+ global label_connection_transport_out
+ global label_transport_out
+ global picker_transport_out
+ # build the hstack with activity indicator and connection state label
+ hstack_transport_out_activity_and_label.addWidget(activity_indicator_transport_out)
+ hstack_transport_out_activity_and_label.addWidget(label_connection_transport_out)
+ hstack_transport_out_activity_and_label.addStretch()
+ # add all 3 to the vstack
+ vstack_transport_out.addLayout(hstack_transport_out_activity_and_label) # activity indicator and connection label
+ vstack_transport_out.addWidget(label_transport_out) # transport output label
+ vstack_transport_out.addWidget(picker_transport_out) # port dropdown
+ # populate the dropdown
+ picker_transport_out.addItems(available_ports)
+ picker_transport_out.currentTextChanged.connect(self.on_transport_output_select)
+ # add the combined stack to the row
+ hstack_io_row.addLayout(vstack_transport_out)
+ #MARK: OSC COLUMN 4
+ # Globals for mutation safety
+ global vstack_osc
+ global hstack_osc_activity_and_label
+ global activity_indicator_osc
+ global label_connection_osc
+ global hstack_osc_ip
+ global textbox_osc_daw_ip
+ global hstack_osc_ports
+ global spinner_osc_listen_port
+ global spinner_osc_send_port
+ global hstack_osc_buttons
+ global button_osc_toggle
+ global button_osc_messages_log
- #MARK: COL 2 MIDI OUT
- # Output side
- out_col = QVBoxLayout()
- out_col.setSpacing(2)
- out_top = QHBoxLayout()
- self.out_blink = QLabel("●")
- self.out_blink.setStyleSheet("color: #444; font-size: 14px;")
- self.out_status = QLabel("Not Connected")
- self.out_status.setStyleSheet("color: #888;")
- out_top.addWidget(self.out_blink)
- out_top.addWidget(self.out_status)
- out_top.addStretch()
- out_col.addLayout(out_top)
- out_col.addWidget(QLabel("MIDI Output"))
- self.port_combo = QComboBox()
- self.port_combo.addItems(available_ports)
- self.port_combo.setFixedWidth(200)
- self.port_combo.currentTextChanged.connect(self.on_port_select)
- out_col.addWidget(self.port_combo)
- hstack_io_row.addLayout(out_col)
+ # build hstack with activity indicator and connection label
+ hstack_osc_activity_and_label.addWidget(activity_indicator_osc)
+ hstack_osc_activity_and_label.addWidget(label_connection_osc)
+ hstack_osc_activity_and_label.addStretch()
- #MARK: COL 3 TRANSPORT
- # Transport Output column
- t_col = QVBoxLayout()
- t_col.setSpacing(2)
- t_out_top = QHBoxLayout()
- self.t_out_blink = QLabel("●")
- self.t_out_blink.setStyleSheet("color: #444; font-size: 14px;")
- self.t_out_status = QLabel("Not Connected")
- self.t_out_status.setStyleSheet("color: #888;")
- t_out_top.addWidget(self.t_out_blink)
- t_out_top.addWidget(self.t_out_status)
- t_out_top.addStretch()
- t_col.addLayout(t_out_top)
- t_col.addWidget(QLabel("Transport Output"))
- self.t_out_combo = QComboBox()
- self.t_out_combo.addItems(available_ports)
- self.t_out_combo.setFixedWidth(200)
- self.t_out_combo.currentTextChanged.connect(self.on_transport_output_select)
- t_col.addWidget(self.t_out_combo)
- hstack_io_row.addLayout(t_col)
+ # build hstack for DAW IP configuration
+ hstack_osc_ip.addWidget(QLabel("DAW IP"))
+ hstack_osc_ip.addWidget(textbox_osc_daw_ip)
+ hstack_osc_ip.addStretch()
+ # build hstack for listen/send ports
+ hstack_osc_ports.addWidget(QLabel("Listen"))
+ hstack_osc_ports.addWidget(spinner_osc_listen_port)
+ hstack_osc_ports.addSpacing(6)
+ hstack_osc_ports.addWidget(QLabel("Send"))
+ hstack_osc_ports.addWidget(spinner_osc_send_port)
+ hstack_osc_ports.addStretch()
- # #MARK: COL 4 OSC
- # OSC column
- osc_col = QVBoxLayout()
- osc_col.setSpacing(2)
- osc_top = QHBoxLayout()
- self.osc_blink = QLabel("●")
- self.osc_blink.setStyleSheet("color: #444; font-size: 14px;")
- self.osc_status = QLabel("Not Listening")
- self.osc_status.setStyleSheet("color: #888;")
- osc_top.addWidget(self.osc_blink)
- osc_top.addWidget(self.osc_status)
- osc_top.addStretch()
- osc_col.addLayout(osc_top)
- # IP address row
- osc_ip_row = QHBoxLayout()
- osc_ip_row.addWidget(QLabel("DAW IP"))
- self.osc_ip_edit = QLineEdit("127.0.0.1")
- self.osc_ip_edit.setFixedWidth(110)
- self.osc_ip_edit.setPlaceholderText("127.0.0.1")
- self.osc_ip_edit.textChanged.connect(self.on_osc_ip_changed)
- osc_ip_row.addWidget(self.osc_ip_edit)
- osc_ip_row.addStretch()
- osc_col.addLayout(osc_ip_row)
+ # build hstack for control buttons
+ hstack_osc_buttons.addWidget(button_osc_toggle)
+ hstack_osc_buttons.addWidget(button_osc_messages_log)
+ hstack_osc_buttons.addStretch()
- # Port row
- osc_port_row = QHBoxLayout()
- osc_port_row.addWidget(QLabel("Listen"))
- self.osc_port_spin = QSpinBox()
- self.osc_port_spin.setMinimum(1024)
- self.osc_port_spin.setMaximum(65535)
- self.osc_port_spin.setValue(9000)
- self.osc_port_spin.setFixedWidth(65)
- osc_port_row.addWidget(self.osc_port_spin)
- osc_port_row.addSpacing(6)
- osc_port_row.addWidget(QLabel("Send"))
- self.osc_send_port_spin = QSpinBox()
- self.osc_send_port_spin.setMinimum(1024)
- self.osc_send_port_spin.setMaximum(65535)
- self.osc_send_port_spin.setValue(8000)
- self.osc_send_port_spin.setFixedWidth(65)
- self.osc_send_port_spin.valueChanged.connect(self.on_osc_send_port_changed)
- osc_port_row.addWidget(self.osc_send_port_spin)
- osc_port_row.addStretch()
- osc_col.addLayout(osc_port_row)
- osc_btn_row = QHBoxLayout()
- self.osc_toggle_btn = QPushButton("Start OSC")
- self.osc_toggle_btn.setFixedWidth(90)
- self.osc_toggle_btn.clicked.connect(self.toggle_osc)
- osc_btn_row.addWidget(self.osc_toggle_btn)
- self.osc_log_btn = QPushButton("Messages")
- self.osc_log_btn.setFixedWidth(80)
- self.osc_log_btn.setCheckable(True)
- self.osc_log_btn.clicked.connect(self.toggle_osc_log)
- osc_btn_row.addWidget(self.osc_log_btn)
- osc_btn_row.addStretch()
- osc_col.addLayout(osc_btn_row)
- hstack_io_row.addLayout(osc_col)
+ # add all rows to vstack
+ vstack_osc.addLayout(hstack_osc_activity_and_label) # activity indicator and connection label
+ vstack_osc.addLayout(hstack_osc_ip) # DAW IP input
+ vstack_osc.addLayout(hstack_osc_ports) # listen and send ports
+ vstack_osc.addLayout(hstack_osc_buttons) # control buttons
+
+ # connect signals
+ textbox_osc_daw_ip.textChanged.connect(self.on_osc_ip_changed)
+ spinner_osc_send_port.valueChanged.connect(self.on_osc_send_port_changed)
+ button_osc_toggle.clicked.connect(self.toggle_osc)
+ button_osc_messages_log.clicked.connect(self.toggle_osc_log)
+
+ # add the combined stack to the row
+ hstack_io_row.addLayout(vstack_osc)
+
+ # add the combined stack to the row
+ hstack_io_row.addLayout(vstack_osc)
hstack_io_row.addStretch()
main_layout.addLayout(hstack_io_row)
main_layout.addWidget(self._separator())
- # #MARK: OSC STATUS ROW
- # --- OSC Feedback panel ---
- self.osc_panel = QWidget()
- self.osc_panel.setStyleSheet("background-color: #252526; border-radius: 4px;")
- osc_panel_layout = QVBoxLayout(self.osc_panel)
- osc_panel_layout.setContentsMargins(8, 6, 8, 6)
- osc_panel_layout.setSpacing(4)
+ # MARK: OSC STATUS ROW
+ global container_osc_feedback
+ global vstack_osc_feedback
+ global hstack_osc_transport_state
+ global label_osc_play_state
+ global label_osc_record_state
+ global label_osc_tempo
+ global label_osc_position
+ global divider_osc_feedback
+ global hstack_osc_info
+ global label_track_header
+ global label_osc_track
+ global label_preset_header
+ global label_osc_preset
+ global spacer_osc_info
+ global container_osc_in_log
+ global vstack_osc_in_log
+ global hstack_osc_in_log_header
+ global label_osc_in_log_title
+ global button_osc_in_clear
+ global textedit_osc_in_log
+ global container_osc_out_log
+ global vstack_osc_out_log
+ global hstack_osc_out_log_header
+ global label_osc_out_log_title
+ global button_osc_out_clear
+ global textedit_osc_out_log
- # Top row — transport state indicators
- osc_transport_row = QHBoxLayout()
- osc_transport_row.setSpacing(12)
+ #MARK: OSC FEEDBACK CONTAINER
+ # assemble transport state row
+ hstack_osc_transport_state.addWidget(label_osc_play_state)
+ hstack_osc_transport_state.addWidget(label_osc_record_state)
+ hstack_osc_transport_state.addStretch()
+ hstack_osc_transport_state.addWidget(label_osc_tempo)
+ hstack_osc_transport_state.addWidget(label_osc_position)
- self.osc_play_lbl = QLabel("■ STOPPED")
- self.osc_play_lbl.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
- osc_transport_row.addWidget(self.osc_play_lbl)
+ # assemble track and preset info row
+ hstack_osc_info.addWidget(label_track_header)
+ hstack_osc_info.addWidget(label_osc_track)
+ hstack_osc_info.addWidget(spacer_osc_info)
+ hstack_osc_info.addWidget(label_preset_header)
+ hstack_osc_info.addWidget(label_osc_preset)
+ hstack_osc_info.addStretch()
- self.osc_record_lbl = QLabel("● REC")
- self.osc_record_lbl.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
- osc_transport_row.addWidget(self.osc_record_lbl)
+ # assemble main feedback container
+ vstack_osc_feedback.addLayout(hstack_osc_transport_state) # play, record, tempo, position
+ vstack_osc_feedback.addWidget(divider_osc_feedback) # divider line
+ vstack_osc_feedback.addLayout(hstack_osc_info) # track and preset labels
- osc_transport_row.addStretch()
+ container_osc_feedback.setVisible(False)
+ main_layout.addWidget(container_osc_feedback)
- self.osc_tempo_lbl = QLabel("BPM: —")
- self.osc_tempo_lbl.setStyleSheet("color: #888; font-size: 11px;")
- osc_transport_row.addWidget(self.osc_tempo_lbl)
+ #MARK: OSC IN LOG CONTAINER
+ # assemble header
+ hstack_osc_in_log_header.addWidget(label_osc_in_log_title)
+ hstack_osc_in_log_header.addStretch()
+ hstack_osc_in_log_header.addWidget(button_osc_in_clear)
- self.osc_pos_lbl = QLabel("Pos: —")
- self.osc_pos_lbl.setStyleSheet("color: #888; font-size: 11px;")
- osc_transport_row.addWidget(self.osc_pos_lbl)
+ # assemble container
+ vstack_osc_in_log.addLayout(hstack_osc_in_log_header)
+ vstack_osc_in_log.addWidget(textedit_osc_in_log)
- osc_panel_layout.addLayout(osc_transport_row)
+ # connect signal
+ button_osc_in_clear.clicked.connect(lambda: textedit_osc_in_log.clear())
- # Divider
- osc_div = QWidget()
- osc_div.setFixedHeight(1)
- osc_div.setStyleSheet("background-color: #3a3a3a;")
- osc_panel_layout.addWidget(osc_div)
+ container_osc_in_log.setVisible(False)
+ #MARK: OSC OUT LOG CONTAINER
+ # assemble header
+ hstack_osc_out_log_header.addWidget(label_osc_out_log_title)
+ hstack_osc_out_log_header.addStretch()
+ hstack_osc_out_log_header.addWidget(button_osc_out_clear)
- # Bottom row — track and preset info
- osc_info_row = QHBoxLayout()
- osc_info_row.setSpacing(8)
+ # assemble container
+ vstack_osc_out_log.addLayout(hstack_osc_out_log_header)
+ vstack_osc_out_log.addWidget(textedit_osc_out_log)
- track_header = QLabel("TRACK")
- track_header.setStyleSheet("color: #555; font-size: 9px; font-weight: bold;")
- osc_info_row.addWidget(track_header)
+ # connect signal
+ button_osc_out_clear.clicked.connect(lambda: textedit_osc_out_log.clear())
- self.osc_track_lbl = QLabel("—")
- self.osc_track_lbl.setStyleSheet("color: #d4d4d4; font-size: 12px; font-weight: bold;")
- osc_info_row.addWidget(self.osc_track_lbl)
+ container_osc_out_log.setVisible(False)
+
+ #MARK: PRESET BROWSER
+ # Globals for mutation safety
+ global label_preset_browser_title
+ global hstack_preset_browser
+ global button_preset_browser_back
+ global spinner_preset_browser_back
+ global button_preset_browser_fwd
+ global spinner_preset_browser_fwd
+ global spacer_preset_browser
- osc_info_row.addSpacing(16)
+ # assemble browser controls
+ hstack_preset_browser.addWidget(button_preset_browser_back)
+ hstack_preset_browser.addWidget(spinner_preset_browser_back)
+ hstack_preset_browser.addWidget(spacer_preset_browser)
+ hstack_preset_browser.addWidget(button_preset_browser_fwd)
+ hstack_preset_browser.addWidget(spinner_preset_browser_fwd)
+ hstack_preset_browser.addStretch()
- preset_header = QLabel("PRESET")
- preset_header.setStyleSheet("color: #555; font-size: 9px; font-weight: bold;")
- osc_info_row.addWidget(preset_header)
+ # add to main layout
+ main_layout.addWidget(label_preset_browser_title)
+ main_layout.addLayout(hstack_preset_browser)
- self.osc_preset_lbl = QLabel("—")
- self.osc_preset_lbl.setStyleSheet("color: #00e676; font-size: 12px; font-weight: bold;")
- osc_info_row.addWidget(self.osc_preset_lbl)
-
- osc_info_row.addStretch()
- osc_panel_layout.addLayout(osc_info_row)
-
- self.osc_panel.setVisible(False)
- main_layout.addWidget(self.osc_panel)
-
- # OSC In log panel
- from PyQt6.QtWidgets import QTextEdit
- self.osc_log_panel = QWidget(None, Qt.WindowType.Tool)
- self.osc_log_panel.setWindowTitle("OSC In — Incoming")
- self.osc_log_panel.setStyleSheet("background-color: #1a1a1a;")
- self.osc_log_panel.setFixedWidth(360)
- log_layout = QVBoxLayout(self.osc_log_panel)
- log_layout.setContentsMargins(6, 6, 6, 6)
- log_layout.setSpacing(4)
-
- log_header = QHBoxLayout()
- log_title = QLabel("OSC In — Incoming from REAPER")
- log_title.setStyleSheet("color: #00e676; font-weight: bold; font-size: 11px;")
- log_header.addWidget(log_title)
- log_header.addStretch()
- clear_in_btn = QPushButton("Clear")
- clear_in_btn.setFixedSize(45, 18)
- clear_in_btn.clicked.connect(lambda: self.osc_log.clear())
- log_header.addWidget(clear_in_btn)
- log_layout.addLayout(log_header)
-
- self.osc_log = QTextEdit()
- self.osc_log.setReadOnly(True)
- self.osc_log.setStyleSheet("""
- QTextEdit {
- background-color: #111111;
- color: #00e676;
- font-family: monospace;
- font-size: 10px;
- border: none;
- }
- """)
- log_layout.addWidget(self.osc_log)
- self.osc_log_panel.setVisible(False)
-
- # OSC Out log panel
- self.osc_out_log_panel = QWidget(None, Qt.WindowType.Tool)
- self.osc_out_log_panel.setWindowTitle("OSC Out — Outgoing")
- self.osc_out_log_panel.setStyleSheet("background-color: #1a1a1a;")
- self.osc_out_log_panel.setFixedWidth(360)
- out_log_layout = QVBoxLayout(self.osc_out_log_panel)
- out_log_layout.setContentsMargins(6, 6, 6, 6)
- out_log_layout.setSpacing(4)
-
- out_log_header = QHBoxLayout()
- out_log_title = QLabel("OSC Out — Sent to REAPER")
- out_log_title.setStyleSheet("color: #1e88e5; font-weight: bold; font-size: 11px;")
- out_log_header.addWidget(out_log_title)
- out_log_header.addStretch()
- clear_out_btn = QPushButton("Clear")
- clear_out_btn.setFixedSize(45, 18)
- clear_out_btn.clicked.connect(lambda: self.osc_out_log.clear())
- out_log_header.addWidget(clear_out_btn)
- out_log_layout.addLayout(out_log_header)
-
- self.osc_out_log = QTextEdit()
- self.osc_out_log.setReadOnly(True)
- self.osc_out_log.setStyleSheet("""
- QTextEdit {
- background-color: #111111;
- color: #1e88e5;
- font-family: monospace;
- font-size: 10px;
- border: none;
- }
- """)
- out_log_layout.addWidget(self.osc_out_log)
- self.osc_out_log_panel.setVisible(False)
-
-
- #MARK: PRESET ROW
- # --- Preset browser ---
- main_layout.addWidget(QLabel("Preset Browser"))
- browser_row = QHBoxLayout()
- browser_row.setSpacing(8)
-
- back_btn = QPushButton("◀")
- back_btn.setFixedSize(36, 28)
- browser_row.addWidget(back_btn)
-
- self.browser_back_spin = QSpinBox()
- self.browser_back_spin.setMinimum(1)
- self.browser_back_spin.setMaximum(127)
- self.browser_back_spin.setValue(22)
- self.browser_back_spin.setFixedWidth(55)
- browser_row.addWidget(self.browser_back_spin)
-
- browser_row.addSpacing(12)
-
- fwd_btn = QPushButton("▶")
- fwd_btn.setFixedSize(36, 28)
- browser_row.addWidget(fwd_btn)
-
- self.browser_fwd_spin = QSpinBox()
- self.browser_fwd_spin.setMinimum(1)
- self.browser_fwd_spin.setMaximum(127)
- self.browser_fwd_spin.setValue(23)
- self.browser_fwd_spin.setFixedWidth(55)
- browser_row.addWidget(self.browser_fwd_spin)
-
- browser_row.addStretch()
- main_layout.addLayout(browser_row)
-
- back_btn.clicked.connect(lambda: send_cc(self.browser_back_spin.value(), 127))
- fwd_btn.clicked.connect(lambda: send_cc(self.browser_fwd_spin.value(), 127))
+ # connect signals
+ button_preset_browser_back.clicked.connect(lambda: send_cc(spinner_preset_browser_back.value(), 127))
+ button_preset_browser_fwd.clicked.connect(lambda: send_cc(spinner_preset_browser_fwd.value(), 127))
main_layout.addWidget(self._separator())
-
#MARK: TRANSPORT ROW
- # --- Transport ---
+ # Instance state
self.transports = []
self.transport_strip_width = 100
self._capturing_key_for = None
- self.full_transport_row = QHBoxLayout()
- self.full_transport_row.setSpacing(spacing)
- main_layout.addLayout(self.full_transport_row)
+ # Globals for mutation safety
+ global hstack_full_transport
+ global hstack_transport_zone_left
+ global vsep_transport_left
+ global hstack_transport_center
+ global vsep_transport_right
+ global hstack_transport_zone_right
- self.transport_zone_left_slot = QHBoxLayout()
- self.transport_zone_left_slot.setSpacing(0)
- self.full_transport_row.addLayout(self.transport_zone_left_slot)
+ #MARK: TRANSPORT ROW
+ # assemble full transport row
+ hstack_full_transport.addLayout(hstack_transport_zone_left) # left zone slot
+ hstack_full_transport.addWidget(vsep_transport_left) # left separator
+ hstack_full_transport.addLayout(hstack_transport_center) # center controls
+ hstack_full_transport.addWidget(vsep_transport_right) # right separator
+ hstack_full_transport.addLayout(hstack_transport_zone_right) # right zone slot
- self.transport_vsep_left = QFrame()
- self.transport_vsep_left.setFrameShape(QFrame.Shape.VLine)
- self.transport_vsep_left.setFixedWidth(1)
- self.transport_vsep_left.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.transport_vsep_left.setVisible(False)
- self.full_transport_row.addWidget(self.transport_vsep_left)
+ # add to main layout
+ main_layout.addLayout(hstack_full_transport)
- self.transport_row = QHBoxLayout()
- self.transport_row.setSpacing(spacing)
- self.full_transport_row.addLayout(self.transport_row)
+ # MARK: SELECTED CHANNEL ROW
+ global hstack_selected_channel_and_save_status
+ global label_selected_channel
+ global labelStatus
- self.transport_vsep_right = QFrame()
- self.transport_vsep_right.setFrameShape(QFrame.Shape.VLine)
- self.transport_vsep_right.setFixedWidth(1)
- self.transport_vsep_right.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.transport_vsep_right.setVisible(False)
- self.full_transport_row.addWidget(self.transport_vsep_right)
-
- self.transport_zone_right_slot = QHBoxLayout()
- self.transport_zone_right_slot.setSpacing(0)
- self.full_transport_row.addLayout(self.transport_zone_right_slot)
-
- main_layout.addWidget(self._separator())
-
- #MARK: SELECTED CHANNEL ROW
- # --- Selected channel label row ---
- info_row = QHBoxLayout()
- info_row.addStretch()
- self.selected_label = QLabel("Selected: None")
- self.selected_label.setStyleSheet("color: #00ff88; font-weight: bold;")
- self.selected_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
- info_row.addWidget(self.selected_label)
- info_row.addStretch()
- labelStatus.setParent(None)
- info_row.addWidget(labelStatus)
- main_layout.addLayout(info_row)
+ #MARK: SELECTED CHANNEL AND SAVE STATUS ROW
+ # assemble info row
+ hstack_selected_channel_and_save_status.addStretch()
+ hstack_selected_channel_and_save_status.addWidget(label_selected_channel)
+ hstack_selected_channel_and_save_status.addStretch()
+ labelStatus.setParent(None) # reparent status label
+ hstack_selected_channel_and_save_status.addWidget(labelStatus)
+ # add to main layout
+ main_layout.addLayout(hstack_selected_channel_and_save_status)
#MARK: FADERS ROW
- # --- Faders row ---
- self.full_fader_row = QHBoxLayout()
- self.full_fader_row.setSpacing(spacing)
- main_layout.addLayout(self.full_fader_row)
+ global hstack_full_fader
+ global hstack_fader_zone_left
+ global separator_vertical_fader_zone_left
+ global hstack_fader_center
+ global separator_vertical_fader_zone_right
+ global hstack_fader_zone_right
- # Zone Left slot
- self.zone_left_slot = QHBoxLayout()
- self.zone_left_slot.setSpacing(0)
- self.full_fader_row.addLayout(self.zone_left_slot)
+ # assemble full fader row
+ hstack_full_fader.addLayout(hstack_fader_zone_left) # left zone slot
+ hstack_full_fader.addWidget(separator_vertical_fader_zone_left) # left separator
+ hstack_full_fader.addLayout(hstack_fader_center) # center faders
+ hstack_full_fader.addWidget(separator_vertical_fader_zone_right) # right separator
+ hstack_full_fader.addLayout(hstack_fader_zone_right) # right zone slot
- # Left vertical separator — always visible
- self.vsep_left = QFrame()
- self.vsep_left.setFrameShape(QFrame.Shape.VLine)
- self.vsep_left.setFixedWidth(1)
- self.vsep_left.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.vsep_left.setVisible(False)
- self.full_fader_row.addWidget(self.vsep_left)
-
- # Custom fader row
- self.fader_row = QHBoxLayout()
- self.fader_row.setSpacing(spacing)
- self.full_fader_row.addLayout(self.fader_row)
-
- # Right vertical separator — always visible
- self.vsep_right = QFrame()
- self.vsep_right.setFrameShape(QFrame.Shape.VLine)
- self.vsep_right.setFixedWidth(1)
- self.vsep_right.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.vsep_right.setVisible(False)
- self.full_fader_row.addWidget(self.vsep_right)
-
- # Zone Right slot
- self.zone_right_slot = QHBoxLayout()
- self.zone_right_slot.setSpacing(0)
- self.full_fader_row.addLayout(self.zone_right_slot)
+ # add to main layout
+ main_layout.addLayout(hstack_full_fader)
main_layout.addWidget(self._separator())
-
#MARK: TOGGLE ROW
- # --- Toggle ---
self.toggles = []
self.toggle_strip_width = 100
- self.full_toggle_row = QHBoxLayout()
- self.full_toggle_row.setSpacing(spacing)
- main_layout.addLayout(self.full_toggle_row)
+ # Globals for mutation safety
+ global hstack_full_toggle
+ global hstack_toggle_zone_left
+ global separator_vertical_toggle_zone_left
+ global hstack_toggle_center
+ global separator_vertical_toggle_zone_right
+ global hstack_toggle_zone_right
- self.toggle_zone_left_slot = QHBoxLayout()
- self.toggle_zone_left_slot.setSpacing(0)
- self.full_toggle_row.addLayout(self.toggle_zone_left_slot)
-
- self.toggle_vsep_left = QFrame()
- self.toggle_vsep_left.setFrameShape(QFrame.Shape.VLine)
- self.toggle_vsep_left.setFixedWidth(1)
- self.toggle_vsep_left.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.toggle_vsep_left.setVisible(False)
- self.full_toggle_row.addWidget(self.toggle_vsep_left)
-
- self.toggle_row = QHBoxLayout()
- self.toggle_row.setSpacing(10)
- self.full_toggle_row.addLayout(self.toggle_row)
-
- self.toggle_vsep_right = QFrame()
- self.toggle_vsep_right.setFrameShape(QFrame.Shape.VLine)
- self.toggle_vsep_right.setFixedWidth(1)
- self.toggle_vsep_right.setStyleSheet("background-color: #3a3a3a; border: none;")
- self.toggle_vsep_right.setVisible(False)
- self.full_toggle_row.addWidget(self.toggle_vsep_right)
-
- self.toggle_zone_right_slot = QHBoxLayout()
- self.toggle_zone_right_slot.setSpacing(0)
- self.full_toggle_row.addLayout(self.toggle_zone_right_slot)
+ #MARK: TOGGLES ROW
+ # assemble full toggle row
+ hstack_full_toggle.addLayout(hstack_toggle_zone_left) # left zone slot
+ hstack_full_toggle.addWidget(separator_vertical_toggle_zone_left) # left separator
+ hstack_full_toggle.addLayout(hstack_toggle_center) # center toggles
+ hstack_full_toggle.addWidget(separator_vertical_toggle_zone_right) # right separator
+ hstack_full_toggle.addLayout(hstack_toggle_zone_right) # right zone slot
+ # add to main layout
+ main_layout.addLayout(hstack_full_toggle)
main_layout.addStretch()
-
-
- #MARK: SET DEFAULTS
+ #MARK: SET DEFAULTS / LOAD PRESETS
# Add initial 2 faders, 1 toggle, 4 transport strips
- #load presets
loaded_presets = ensure_preset_structure(loaded_presets)
self.add_fader()
@@ -741,8 +1050,8 @@ class MainWindow(QMainWindow):
self.refresh_port_availability()
midi_receiver.midi_in_signal.connect(lambda msg: self.blink(activity_indicator_midi_in))
- midi_receiver.midi_out_signal.connect(lambda: self.blink(self.out_blink))
- midi_receiver.transport_out_signal.connect(lambda: self.blink(self.t_out_blink))
+ midi_receiver.midi_out_signal.connect(lambda: self.blink(activity_indicator_midi_out))
+ midi_receiver.transport_out_signal.connect(lambda: self.blink(activity_indicator_transport_out))
midi_receiver.hw_cc_signal.connect(self.on_hw_cc)
# OSC signals
@@ -801,7 +1110,7 @@ class MainWindow(QMainWindow):
if toggle in self.toggles:
toggle.center_index = self.toggles.index(toggle)
- for layout in [self.toggle_row, self.toggle_zone_left_slot, self.toggle_zone_right_slot]:
+ for layout in [hstack_toggle_center, hstack_toggle_zone_left, hstack_toggle_zone_right]:
for i in range(layout.count()):
item = layout.itemAt(i)
if item and item.widget() and hasattr(item.widget(), 'uid') and item.widget().uid == toggle.uid:
@@ -810,23 +1119,23 @@ class MainWindow(QMainWindow):
break
if toggle.zone == "left":
- toggle.zone_index = self.toggle_zone_left_slot.count() - 1
- self.toggle_zone_left_slot.addWidget(toggle)
- self.toggle_vsep_left.setVisible(True)
+ toggle.zone_index = hstack_toggle_zone_left.count() - 1
+ hstack_toggle_zone_left.addWidget(toggle)
+ separator_vertical_toggle_zone_left.setVisible(True)
elif toggle.zone == "right":
- toggle.zone_index = self.toggle_zone_right_slot.count() - 1
- self.toggle_zone_right_slot.addWidget(toggle)
- self.toggle_vsep_right.setVisible(True)
+ toggle.zone_index = hstack_toggle_zone_right.count() - 1
+ hstack_toggle_zone_right.addWidget(toggle)
+ separator_vertical_toggle_zone_right.setVisible(True)
else:
- idx = toggle.center_index if toggle.center_index is not None else self.toggle_row.count()
- idx = min(idx, self.toggle_row.count())
- self.toggle_row.insertWidget(idx, toggle)
+ idx = toggle.center_index if toggle.center_index is not None else hstack_toggle_center.count()
+ idx = min(idx, hstack_toggle_center.count())
+ hstack_toggle_center.insertWidget(idx, toggle)
toggle.center_index = None
toggle.zone_index = None
- self.toggle_vsep_left.setVisible(any(t.zone == "left" for t in self.toggles))
- self.toggle_vsep_right.setVisible(any(t.zone == "right" for t in self.toggles))
+ separator_vertical_toggle_zone_left.setVisible(any(t.zone == "left" for t in self.toggles))
+ separator_vertical_toggle_zone_right.setVisible(any(t.zone == "right" for t in self.toggles))
has_left = any(t.zone == "left" for t in self.toggles)
has_right = any(t.zone == "right" for t in self.toggles)
@@ -844,7 +1153,7 @@ class MainWindow(QMainWindow):
fader.center_index = faders.index(fader)
# Remove by UUID from whichever slot it's in
- for layout in [self.fader_row, self.zone_left_slot, self.zone_right_slot]:
+ for layout in [hstack_fader_center, hstack_fader_zone_left, hstack_fader_zone_right]:
for i in range(layout.count()):
item = layout.itemAt(i)
if item and item.widget() and hasattr(item.widget(), 'uid') and item.widget().uid == fader.uid:
@@ -853,23 +1162,23 @@ class MainWindow(QMainWindow):
break
if fader.zone == "left":
- fader.zone_index = self.zone_left_slot.count() - 1 # subtract placeholder
- self.zone_left_slot.addWidget(fader)
- self.vsep_left.setVisible(True)
+ fader.zone_index = hstack_fader_zone_left.count() - 1 # subtract placeholder
+ hstack_fader_zone_left.addWidget(fader)
+ separator_vertical_fader_zone_left.setVisible(True)
elif fader.zone == "right":
- fader.zone_index = self.zone_right_slot.count() - 1
- self.zone_right_slot.addWidget(fader)
- self.vsep_right.setVisible(True)
+ fader.zone_index = hstack_fader_zone_right.count() - 1
+ hstack_fader_zone_right.addWidget(fader)
+ separator_vertical_fader_zone_right.setVisible(True)
else:
- idx = fader.center_index if fader.center_index is not None else self.fader_row.count()
- idx = min(idx, self.fader_row.count())
- self.fader_row.insertWidget(idx, fader)
+ idx = fader.center_index if fader.center_index is not None else hstack_fader_center.count()
+ idx = min(idx, hstack_fader_center.count())
+ hstack_fader_center.insertWidget(idx, fader)
fader.center_index = None
fader.zone_index = None
- self.vsep_left.setVisible(any(f.zone == "left" for f in faders))
- self.vsep_right.setVisible(any(f.zone == "right" for f in faders))
+ separator_vertical_fader_zone_left.setVisible(any(f.zone == "left" for f in faders))
+ separator_vertical_fader_zone_right.setVisible(any(f.zone == "right" for f in faders))
has_left = any(f.zone == "left" for f in faders)
has_right = any(f.zone == "right" for f in faders)
@@ -883,7 +1192,7 @@ class MainWindow(QMainWindow):
selected_strip.set_selected(False)
selected_strip = strip
strip.set_selected(True)
- self.selected_label.setText(f"Selected: {strip.title_edit.text()}")
+ label_selected_channel.setText(f"Selected: {strip.title_edit.text()}")
def add_toggle(self, insert_after=None):
n = len(self.toggles) + 1
@@ -891,10 +1200,10 @@ class MainWindow(QMainWindow):
if insert_after is not None and insert_after in self.toggles:
idx = self.toggles.index(insert_after)
self.toggles.insert(idx + 1, toggle)
- self.toggle_row.insertWidget(idx + 1, toggle)
+ hstack_toggle_center.insertWidget(idx + 1, toggle)
else:
self.toggles.append(toggle)
- self.toggle_row.addWidget(toggle)
+ hstack_toggle_center.addWidget(toggle)
toggle.plus_btn.clicked.connect(lambda: self.add_toggle(insert_after=toggle))
toggle.minus_btn.clicked.connect(lambda: self.remove_toggle(toggle))
toggle.on_select_callback = self.select_strip
@@ -909,8 +1218,8 @@ class MainWindow(QMainWindow):
return
if selected_strip == toggle:
selected_strip = None
- self.selected_label.setText("Selected: None")
- self.toggle_row.removeWidget(toggle)
+ label_selected_channel.setText("Selected: None")
+ hstack_toggle_center.removeWidget(toggle)
toggle.deleteLater()
self.toggles.remove(toggle)
self.update_window_width()
@@ -925,10 +1234,10 @@ class MainWindow(QMainWindow):
if insert_after is not None and insert_after in faders:
idx = faders.index(insert_after)
faders.insert(idx + 1, fader)
- self.fader_row.insertWidget(idx + 1, fader)
+ hstack_fader_center.insertWidget(idx + 1, fader)
else:
faders.append(fader)
- self.fader_row.addWidget(fader)
+ hstack_fader_center.addWidget(fader)
fader.plus_btn.clicked.connect(lambda: self.add_fader(insert_after=fader))
fader.minus_btn.clicked.connect(lambda: self.remove_fader(fader))
fader.learn_btn.clicked.connect(lambda: self.start_learn(fader))
@@ -947,8 +1256,8 @@ class MainWindow(QMainWindow):
return
if selected_strip == fader:
selected_strip = None
- self.selected_label.setText("Selected: None")
- self.fader_row.removeWidget(fader)
+ label_selected_channel.setText("Selected: None")
+ hstack_fader_center.removeWidget(fader)
fader.deleteLater()
faders.remove(fader)
self.update_window_width()
@@ -1020,20 +1329,20 @@ class MainWindow(QMainWindow):
global faders
return {
- "midi_port": self.port_combo.currentText(),
+ "midi_port": picker_midi_out.currentText(),
"midi_input": picker_midi_in.currentText(),
- "transport_port": self.t_out_combo.currentText(),
+ "transport_port": picker_transport_out.currentText(),
"faders": [f.get_state() for f in faders],
"toggles": [t.get_state() for t in self.toggles],
"transports": [t.get_state() for t in self.transports],
"browser": {
- "back_cc": self.browser_back_spin.value(),
- "fwd_cc": self.browser_fwd_spin.value()
+ "back_cc": spinner_preset_browser_back.value(),
+ "fwd_cc": spinner_preset_browser_fwd.value()
},
"osc": {
- "ip": self.osc_ip_edit.text(),
- "listen_port": self.osc_port_spin.value(),
- "send_port": self.osc_send_port_spin.value(),
+ "ip": textbox_osc_daw_ip.text(),
+ "listen_port": spinner_osc_listen_port.value(),
+ "send_port": spinner_osc_send_port.value(),
}
}
@@ -1045,11 +1354,11 @@ class MainWindow(QMainWindow):
port_name = preset.get("midi_port", "")
if port_name in available_ports:
- self.port_combo.setCurrentText(port_name)
+ picker_midi_out.setCurrentText(port_name)
transport_port = preset.get("transport_port", "")
if transport_port in available_ports:
- self.t_out_combo.setCurrentText(transport_port)
+ picker_transport_out.setCurrentText(transport_port)
midi_input = preset.get("midi_input", "")
input_names = [entry[0] for entry in available_ports_midi_in]
@@ -1060,7 +1369,7 @@ class MainWindow(QMainWindow):
self.add_fader()
while len(faders) > len(fader_states):
widget = faders.pop()
- self.fader_row.removeWidget(widget)
+ hstack_fader_center.removeWidget(widget)
widget.deleteLater()
self.update_window_width()
for i, widget in enumerate(faders):
@@ -1072,10 +1381,10 @@ class MainWindow(QMainWindow):
key=lambda f: f.center_index if f.center_index is not None else 999
)
for f in center_faders:
- self.fader_row.removeWidget(f)
+ hstack_fader_center.removeWidget(f)
f.setParent(None)
for f in center_faders:
- self.fader_row.addWidget(f)
+ hstack_fader_center.addWidget(f)
# Then place zoned faders in zone order
left_faders = sorted(
@@ -1087,13 +1396,13 @@ class MainWindow(QMainWindow):
key=lambda f: f.zone_index if f.zone_index is not None else 999
)
for f in left_faders:
- self.fader_row.removeWidget(f)
+ hstack_fader_center.removeWidget(f)
f.setParent(None)
- self.zone_left_slot.addWidget(f)
+ hstack_fader_zone_left.addWidget(f)
for f in right_faders:
- self.fader_row.removeWidget(f)
+ hstack_fader_center.removeWidget(f)
f.setParent(None)
- self.zone_right_slot.addWidget(f)
+ hstack_fader_zone_right.addWidget(f)
self.update_window_width()
# Migration: old presets have 'toggle' (singular), new have 'toggles' (list)
@@ -1112,7 +1421,7 @@ class MainWindow(QMainWindow):
self.add_toggle()
while len(self.toggles) > len(toggle_states):
widget = self.toggles.pop()
- self.toggle_row.removeWidget(widget)
+ hstack_toggle_center.removeWidget(widget)
widget.deleteLater()
self.update_window_width()
for i, widget in enumerate(self.toggles):
@@ -1124,10 +1433,10 @@ class MainWindow(QMainWindow):
key=lambda t: t.center_index if t.center_index is not None else 999
)
for t in center_toggles:
- self.toggle_row.removeWidget(t)
+ hstack_toggle_center.removeWidget(t)
t.setParent(None)
for t in center_toggles:
- self.toggle_row.addWidget(t)
+ hstack_toggle_center.addWidget(t)
# Place zoned toggles
left_toggles = sorted(
@@ -1139,18 +1448,18 @@ class MainWindow(QMainWindow):
key=lambda t: t.zone_index if t.zone_index is not None else 999
)
for t in left_toggles:
- self.toggle_row.removeWidget(t)
+ hstack_toggle_center.removeWidget(t)
t.setParent(None)
- self.toggle_zone_left_slot.addWidget(t)
+ hstack_toggle_zone_left.addWidget(t)
for t in right_toggles:
- self.toggle_row.removeWidget(t)
+ hstack_toggle_center.removeWidget(t)
t.setParent(None)
- self.toggle_zone_right_slot.addWidget(t)
+ hstack_toggle_zone_right.addWidget(t)
browser = preset.get("browser", {})
- self.browser_back_spin.setValue(browser.get("back_cc", 22))
- self.browser_fwd_spin.setValue(browser.get("fwd_cc", 23))
+ spinner_preset_browser_back.setValue(browser.get("back_cc", 22))
+ spinner_preset_browser_fwd.setValue(browser.get("fwd_cc", 23))
transport_states = preset.get("transports", [])
for i, t in enumerate(self.transports):
@@ -1159,9 +1468,9 @@ class MainWindow(QMainWindow):
osc = preset.get("osc", {})
if osc:
- self.osc_ip_edit.setText(osc.get("ip", "127.0.0.1"))
- self.osc_port_spin.setValue(osc.get("listen_port", 9000))
- self.osc_send_port_spin.setValue(osc.get("send_port", 8000))
+ textbox_osc_daw_ip.setText(osc.get("ip", "127.0.0.1"))
+ spinner_osc_listen_port.setValue(osc.get("listen_port", 9000))
+ spinner_osc_send_port.setValue(osc.get("send_port", 8000))
@@ -1303,12 +1612,12 @@ class MainWindow(QMainWindow):
def refresh_port_availability(self):
"""Gray out ports already in use by another dropdown."""
- out_port = self.port_combo.currentText()
- t_port = self.t_out_combo.currentText()
+ out_port = picker_midi_out.currentText()
+ t_port = picker_transport_out.currentText()
# Output combo — gray out transport port
- for i in range(self.port_combo.model().rowCount()):
- item = self.port_combo.model().item(i)
+ for i in range(picker_midi_out.model().rowCount()):
+ item = picker_midi_out.model().item(i)
# Strip any existing [in use] tag before comparing
base = item.text().replace(" [in use]", "")
if base == t_port and base != out_port:
@@ -1321,8 +1630,8 @@ class MainWindow(QMainWindow):
item.setForeground(QColor('#ffffff'))
# Transport combo — gray out output port
- for i in range(self.t_out_combo.model().rowCount()):
- item = self.t_out_combo.model().item(i)
+ for i in range(picker_transport_out.model().rowCount()):
+ item = picker_transport_out.model().item(i)
base = item.text().replace(" [in use]", "")
if base == out_port and base != t_port:
item.setText(f"{base} [in use]")
@@ -1338,8 +1647,8 @@ class MainWindow(QMainWindow):
midi_out.close_port()
port_index = available_ports.index(port_name)
midi_out.open_port(port_index)
- self.out_status.setText("Connected")
- self.out_status.setStyleSheet("color: #27ae60;")
+ label_connection_midi_out.setText("Connected")
+ label_connection_midi_out.setStyleSheet("color: #27ae60;")
print(f"Opened output port: {port_name}")
self.refresh_port_availability()
@@ -1350,8 +1659,8 @@ class MainWindow(QMainWindow):
transport_midi_out.close_port()
port_index = available_ports.index(port_name)
transport_midi_out.open_port(port_index)
- self.t_out_status.setText("Connected")
- self.t_out_status.setStyleSheet("color: #27ae60;")
+ label_connection_transport_out.setText("Connected")
+ label_connection_transport_out.setStyleSheet("color: #27ae60;")
print(f"Opened transport output port: {port_name}")
self.refresh_port_availability()
@@ -1361,14 +1670,14 @@ class MainWindow(QMainWindow):
t.learn_btn.clicked.connect(lambda: self.start_learn(t))
t.on_zone_change_callback = self.on_transport_zone_change
self.transports.append(t)
- self.transport_row.addWidget(t)
+ hstack_transport_center.addWidget(t)
self.refresh_all_id_labels()
def on_transport_zone_change(self, transport):
if transport.zone is not None and transport.center_index is None:
if transport in self.transports:
transport.center_index = self.transports.index(transport)
- for layout in [self.transport_row, self.transport_zone_left_slot, self.transport_zone_right_slot]:
+ for layout in [hstack_transport_center, hstack_transport_zone_left, hstack_transport_zone_right]:
for i in range(layout.count()):
item = layout.itemAt(i)
if item and item.widget() and hasattr(item.widget(), 'uid') and item.widget().uid == transport.uid:
@@ -1376,58 +1685,58 @@ class MainWindow(QMainWindow):
transport.setParent(None)
break
if transport.zone == "left":
- transport.zone_index = self.transport_zone_left_slot.count()
- self.transport_zone_left_slot.addWidget(transport)
- self.transport_vsep_left.setVisible(True)
+ transport.zone_index = hstack_transport_zone_left.count()
+ hstack_transport_zone_left.addWidget(transport)
+ vsep_transport_left.setVisible(True)
elif transport.zone == "right":
- transport.zone_index = self.transport_zone_right_slot.count()
- self.transport_zone_right_slot.addWidget(transport)
- self.transport_vsep_right.setVisible(True)
+ transport.zone_index = hstack_transport_zone_right.count()
+ hstack_transport_zone_right.addWidget(transport)
+ vsep_transport_right.setVisible(True)
else:
- idx = transport.center_index if transport.center_index is not None else self.transport_row.count()
- self.transport_row.insertWidget(min(idx, self.transport_row.count()), transport)
+ idx = transport.center_index if transport.center_index is not None else hstack_transport_center.count()
+ hstack_transport_center.insertWidget(min(idx, hstack_transport_center.count()), transport)
transport.center_index = None
transport.zone_index = None
- self.transport_vsep_left.setVisible(any(t.zone == "left" for t in self.transports))
- self.transport_vsep_right.setVisible(any(t.zone == "right" for t in self.transports))
+ vsep_transport_left.setVisible(any(t.zone == "left" for t in self.transports))
+ vsep_transport_right.setVisible(any(t.zone == "right" for t in self.transports))
self.refresh_all_id_labels()
def toggle_osc_log(self, checked):
- self.osc_log_panel.setVisible(checked)
- self.osc_out_log_panel.setVisible(checked)
+ container_osc_in_log.setVisible(checked)
+ container_osc_out_log.setVisible(checked)
self._position_osc_log()
def _position_osc_log(self):
geo = self.frameGeometry()
h = geo.height()
# In panel to the right
- self.osc_log_panel.setFixedHeight(h)
- self.osc_log_panel.move(geo.right() + 4, geo.top())
+ container_osc_in_log.setFixedHeight(h)
+ container_osc_in_log.move(geo.right() + 4, geo.top())
# Out panel stacked below in panel
- self.osc_out_log_panel.setFixedWidth(360)
- self.osc_out_log_panel.setFixedHeight(h // 2)
- self.osc_out_log_panel.move(geo.right() + 4, geo.top() + h // 2 + 4)
+ container_osc_out_log.setFixedWidth(360)
+ container_osc_out_log.setFixedHeight(h // 2)
+ container_osc_out_log.move(geo.right() + 4, geo.top() + h // 2 + 4)
# Adjust in panel height
- self.osc_log_panel.setFixedHeight(h // 2 - 4)
+ container_osc_in_log.setFixedHeight(h // 2 - 4)
def resizeEvent(self, event):
super().resizeEvent(event)
- if self.osc_log_panel.isVisible():
+ if container_osc_in_log.isVisible():
self._position_osc_log()
def moveEvent(self, event):
super().moveEvent(event)
- if self.osc_log_panel.isVisible():
+ if container_osc_in_log.isVisible():
self._position_osc_log()
def on_osc_raw(self, addr, val):
from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S")
line = f"{ts} {addr} {val}"
- self.osc_log.append(line)
- doc = self.osc_log.document()
+ textedit_osc_in_log.append(line)
+ doc = textedit_osc_in_log.document()
if doc.blockCount() > 200:
- cursor = self.osc_log.textCursor()
+ cursor = textedit_osc_in_log.textCursor()
cursor.movePosition(cursor.MoveOperation.Start)
cursor.select(cursor.SelectionType.LineUnderCursor)
cursor.removeSelectedText()
@@ -1437,10 +1746,10 @@ class MainWindow(QMainWindow):
from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S")
line = f"{ts} {addr} {val}"
- self.osc_out_log.append(line)
- doc = self.osc_out_log.document()
+ textedit_osc_out_log.append(line)
+ doc = textedit_osc_out_log.document()
if doc.blockCount() > 200:
- cursor = self.osc_out_log.textCursor()
+ cursor = textedit_osc_out_log.textCursor()
cursor.movePosition(cursor.MoveOperation.Start)
cursor.select(cursor.SelectionType.LineUnderCursor)
cursor.removeSelectedText()
@@ -1455,53 +1764,53 @@ class MainWindow(QMainWindow):
def toggle_osc(self):
if _osc_server is not None:
stop_osc_server()
- self.osc_status.setText("Not Listening")
- self.osc_status.setStyleSheet("color: #888;")
- self.osc_toggle_btn.setText("Start OSC")
- self.osc_blink.setStyleSheet("color: #444; font-size: 14px;")
- self.osc_panel.setVisible(False)
+ label_connection_osc.setText("Not Listening")
+ label_connection_osc.setStyleSheet("color: #888;")
+ button_osc_toggle.setText("Start OSC")
+ activity_indicator_osc.setStyleSheet("color: #444; font-size: 14px;")
+ container_osc_feedback.setVisible(False)
else:
- port = self.osc_port_spin.value()
+ port = spinner_osc_listen_port.value()
ok = start_osc_server(port)
if ok:
- self.osc_status.setText(f"Listening :{port}")
- self.osc_status.setStyleSheet("color: #27ae60;")
- self.osc_toggle_btn.setText("Stop OSC")
- self.osc_blink.setStyleSheet("color: #2ecc71; font-size: 14px;")
- self.osc_panel.setVisible(True)
+ label_connection_osc.setText(f"Listening :{port}")
+ label_connection_osc.setStyleSheet("color: #27ae60;")
+ button_osc_toggle.setText("Stop OSC")
+ activity_indicator_osc.setStyleSheet("color: #2ecc71; font-size: 14px;")
+ container_osc_feedback.setVisible(True)
else:
- self.osc_status.setText("Failed")
- self.osc_status.setStyleSheet("color: #c0392b;")
+ label_connection_osc.setText("Failed")
+ label_connection_osc.setStyleSheet("color: #c0392b;")
def on_osc_track(self, name):
- self.osc_track_lbl.setText(name)
- self.blink(self.osc_blink)
+ label_osc_track.setText(name)
+ self.blink(activity_indicator_osc)
def on_osc_preset(self, name):
- self.osc_preset_lbl.setText(name)
- self.blink(self.osc_blink)
+ label_osc_preset.setText(name)
+ self.blink(activity_indicator_osc)
def on_osc_tempo(self, bpm):
- self.osc_tempo_lbl.setText(f"BPM: {bpm:.1f}")
+ label_osc_tempo.setText(f"BPM: {bpm:.1f}")
def on_osc_position(self, pos):
- self.osc_pos_lbl.setText(f"Pos: {pos}")
+ label_osc_position.setText(f"Pos: {pos}")
def on_osc_play(self, state):
if state:
- self.osc_play_lbl.setText("▶ PLAYING")
- self.osc_play_lbl.setStyleSheet("color: #00e676; font-size: 11px; font-weight: bold;")
+ label_osc_play_state.setText("▶ PLAYING")
+ label_osc_play_state.setStyleSheet("color: #00e676; font-size: 11px; font-weight: bold;")
else:
- self.osc_play_lbl.setText("■ STOPPED")
- self.osc_play_lbl.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
+ label_osc_play_state.setText("■ STOPPED")
+ label_osc_play_state.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
def on_osc_record(self, state):
if state:
- self.osc_record_lbl.setText("● REC")
- self.osc_record_lbl.setStyleSheet("color: #e53935; font-size: 11px; font-weight: bold;")
+ label_osc_record_state.setText("● REC")
+ label_osc_record_state.setStyleSheet("color: #e53935; font-size: 11px; font-weight: bold;")
else:
- self.osc_record_lbl.setText("● REC")
- self.osc_record_lbl.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
+ label_osc_record_state.setText("● REC")
+ label_osc_record_state.setStyleSheet("color: #555; font-size: 11px; font-weight: bold;")
def fire_transport(self, name):
for t in self.transports:
diff --git a/presets/presets.json b/presets/presets.json
index b3679c1..30d9a07 100644
--- a/presets/presets.json
+++ b/presets/presets.json
@@ -1,5 +1,5 @@
{
- "__last_used__": null,
+ "__last_used__": "gay3",
"presets": {
"1": {
"midi_port": "IAC Driver Bus 1",
@@ -1027,7 +1027,7 @@
"hw_cc": null,
"output_mode": "osc",
"osc_addr": "/play",
- "trigger_mode": "momentary"
+ "trigger_mode": "toggle"
},
{
"uid": "e2e8eb84-c2c9-4060-a818-b087ebd5aabd",
@@ -1041,7 +1041,7 @@
"hw_cc": null,
"output_mode": "osc",
"osc_addr": "/play",
- "trigger_mode": "momentary"
+ "trigger_mode": "toggle"
},
{
"uid": "6b5bcaf7-1d01-4ccd-b23a-ebae8da57a7f",
@@ -1055,7 +1055,7 @@
"hw_cc": null,
"output_mode": "osc",
"osc_addr": "/play",
- "trigger_mode": "momentary"
+ "trigger_mode": "toggle"
},
{
"uid": "2a1fcb50-b9f2-4c33-bce0-5bd5cadd9c46",
@@ -1069,7 +1069,7 @@
"hw_cc": null,
"output_mode": "osc",
"osc_addr": "/play",
- "trigger_mode": "momentary"
+ "trigger_mode": "toggle"
}
],
"browser": {