4db7165797
- Restructured project into /app, /server, /client with run.py entry point - WSServer (QWebSocketServer) with log_signal, start/stop, client tracking - HTTP server serves /client on port 8080 - Vanilla JS client: faders, toggles, transport, drag-to-arrange, lock/save layout - Start Tablet button + floating Tablet log window in app UI - Preset broadcast on load/switch, DAW state relay, hardware sync via widget_update - Widget colors synced from app palette, toggle state fixed (sends 0/127 correctly) - Layout saved per preset UUID back to presets.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from PyQt6.QtWidgets import QPushButton
|
|
from PyQt6.QtCore import Qt
|
|
from PyQt6.QtGui import QPainter, QColor, QFont
|
|
|
|
|
|
class ZoneButton(QPushButton):
|
|
"""Split L/R zone button. Left half = L, Right half = R."""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.left_active = False
|
|
self.right_active = False
|
|
self.setFixedHeight(20)
|
|
self.left_callback = None
|
|
self.right_callback = None
|
|
self._update_style()
|
|
|
|
def mousePressEvent(self, event):
|
|
if event.button() == Qt.MouseButton.LeftButton:
|
|
if event.position().x() < self.width() / 2:
|
|
self.left_active = not self.left_active
|
|
if self.left_active:
|
|
self.right_active = False
|
|
if self.left_callback:
|
|
self.left_callback(self.left_active)
|
|
else:
|
|
self.right_active = not self.right_active
|
|
if self.right_active:
|
|
self.left_active = False
|
|
if self.right_callback:
|
|
self.right_callback(self.right_active)
|
|
|
|
self._update_style()
|
|
|
|
def set_state(self, left, right):
|
|
self.left_active = left
|
|
self.right_active = right
|
|
self._update_style()
|
|
|
|
def _update_style(self):
|
|
l_color = "#ff8c00" if self.left_active else "#2a2a2a"
|
|
r_color = "#00c853" if self.right_active else "#2a2a2a"
|
|
|
|
self.setStyleSheet(f"""
|
|
QPushButton {{
|
|
background: qlineargradient(
|
|
x1:0, y1:0, x2:1, y2:0,
|
|
stop:0 {l_color},
|
|
stop:0.499 {l_color},
|
|
stop:0.5 {r_color},
|
|
stop:1 {r_color}
|
|
);
|
|
border-top-left-radius: 4px;
|
|
border-bottom-left-radius: 4px;
|
|
border-top-right-radius: 4px;
|
|
border-bottom-right-radius: 4px;
|
|
border: 1px solid #444;
|
|
color: #aaaaaa;
|
|
font-size: 9px;
|
|
font-weight: bold;
|
|
}}
|
|
""")
|
|
|
|
self.setText("")
|
|
self.update()
|
|
|
|
def paintEvent(self, event):
|
|
super().paintEvent(event)
|
|
|
|
painter = QPainter(self)
|
|
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
|
|
|
mid = self.width() // 2
|
|
|
|
painter.setPen(QColor("#666666"))
|
|
painter.drawLine(mid, 3, mid, self.height() - 3)
|
|
|
|
painter.setPen(QColor("#ffffff"))
|
|
|
|
font = QFont()
|
|
font.setPointSize(7)
|
|
font.setBold(True)
|
|
painter.setFont(font)
|
|
|
|
painter.drawText(0, 0, mid, self.height(), 0x0084, "L")
|
|
painter.drawText(mid, 0, mid, self.height(), 0x0084, "R")
|
|
|
|
painter.end() |