"""Встраиваемая секция «Тест цвета» — цветовое чередование диодов. Позволяет задать порядок цветов (RGB/RBG/…) командой 89 и запустить тест: красный → зелёный → синий. """ from __future__ import annotations from PySide6.QtCore import Qt, QTimer from PySide6.QtWidgets import ( QCheckBox, QColorDialog, QFormLayout, QGroupBox, QHBoxLayout, QLabel, QMessageBox, QPushButton, QSpinBox, QVBoxLayout, QWidget, ) from ...services.com_service import ComConnection from ...ui.icons import get_icon_color, icon from ..no_wheel_combo_box import NoWheelComboBox _COLOR_ORDERS: list[tuple[int, str]] = [ (0, "RGB"), (1, "RBG"), (2, "BRG"), (3, "BGR"), (4, "GRB"), (5, "GBR"), ] class LedTestSection(QWidget): """Inline-секция тест цвета (для базового режима).""" def __init__(self, connection: ComConnection, parent: QWidget | None = None) -> None: super().__init__(parent) self._conn = connection self._setup_ui() # ── UI ──────────────────────────────────────────────────────────── def _setup_ui(self) -> None: root = QVBoxLayout(self) root.setContentsMargins(0, 0, 0, 0) root.setSpacing(10) # ── Настройки WS2812 (cmd 89) ── color_group = QGroupBox("Настройки WS2812 (cmd 89)") color_form = QFormLayout(color_group) color_form.setSpacing(6) desc = QLabel( "Настройки вывода WS2812. Выберите физический канал и настройте порядок цветов, " "яркость или гамма-коррекцию." ) desc.setWordWrap(True) desc.setObjectName("HelpText") color_form.addRow(desc) # Выбор физического канала self._cmd89_channel_combo = NoWheelComboBox() self._cmd89_channel_combo.addItem("Все ленты (0)", 0) self._cmd89_channel_combo.addItem("2-й канал (1)", 1) self._cmd89_channel_combo.addItem("3-й канал (2)", 2) self._cmd89_channel_combo.addItem("4-й канал (3)", 3) color_form.addRow("Физический канал:", self._cmd89_channel_combo) # Порядок цветов self._color_order_combo = NoWheelComboBox() for code, name in _COLOR_ORDERS: self._color_order_combo.addItem(f"{code} — {name}", code) self._set_color_btn = QPushButton("Применить порядок") self._set_color_btn.setProperty("role", "primary") self._set_color_btn.setIcon(icon("fa5s.palette", color="#ecfdf5")) self._set_color_btn.clicked.connect(self._send_color_order) order_layout = QHBoxLayout() order_layout.addWidget(self._color_order_combo, 1) order_layout.addWidget(self._set_color_btn) color_form.addRow("Порядок цветов:", order_layout) # Яркость self._cmd89_brightness_spin = QSpinBox() self._cmd89_brightness_spin.setRange(0, 255) self._cmd89_brightness_spin.setValue(255) apply_bright_btn = QPushButton("Применить яркость") apply_bright_btn.setIcon(icon("fa5s.sun", color=get_icon_color())) apply_bright_btn.clicked.connect(self._send_brightness) bright_layout = QHBoxLayout() bright_layout.addWidget(self._cmd89_brightness_spin, 1) bright_layout.addWidget(apply_bright_btn) color_form.addRow("Яркость:", bright_layout) # Гамма-коррекция self._cmd89_gamma_check = QCheckBox("Включить гамма-коррекцию") apply_gamma_btn = QPushButton("Применить гамму") apply_gamma_btn.setIcon(icon("fa5s.adjust", color=get_icon_color())) apply_gamma_btn.clicked.connect(self._send_gamma) gamma_layout = QHBoxLayout() gamma_layout.addWidget(self._cmd89_gamma_check, 1) gamma_layout.addWidget(apply_gamma_btn) color_form.addRow("Гамма-коррекция:", gamma_layout) # Пользовательский цвет self._custom_color_btn = QPushButton("Выбрать и отправить цвет") self._custom_color_btn.setIcon(icon("fa5s.palette", color=get_icon_color())) self._custom_color_btn.clicked.connect(self._send_custom_color) color_form.addRow("Свой цвет (08):", self._custom_color_btn) # Тест цвета self._color_test_btn = QPushButton("Тест цвета") self._color_test_btn.setProperty("role", "primary") self._color_test_btn.setIcon(icon("fa5s.eye", color="#ecfdf5")) self._color_test_btn.clicked.connect(self._run_color_test) color_form.addRow(self._color_test_btn) color_hint = QLabel("Должны вывестись: красный → зелёный → синий") color_hint.setStyleSheet("color: #9ca3af; font-size: 11px;") color_hint.setWordWrap(True) color_form.addRow(color_hint) root.addWidget(color_group) # ── Лог ── self._log = QLabel("") self._log.setObjectName("LogLabel") self._log.setWordWrap(True) root.addWidget(self._log) # ── Public ──────────────────────────────────────────────────────── def refresh_icons(self) -> None: """Нет theme-dependent иконок — ничего не делаем.""" # ── Отправка ────────────────────────────────────────────────────── def _send_color_order(self) -> None: ch = self._cmd89_channel_combo.currentData() code = self._color_order_combo.currentData() cmd = f"89{ch}0{code}" self._send(cmd) def _send_brightness(self) -> None: ch = self._cmd89_channel_combo.currentData() val = self._cmd89_brightness_spin.value() cmd = f"89{ch}1{val}" self._send(cmd) def _send_gamma(self) -> None: ch = self._cmd89_channel_combo.currentData() val = 1 if self._cmd89_gamma_check.isChecked() else 0 cmd = f"89{ch}2{val}" self._send(cmd) def _send_custom_color(self) -> None: color = QColorDialog.getColor(Qt.GlobalColor.white, self, "Выберите цвет") if color.isValid(): ch = self._cmd89_channel_combo.currentData() r = color.red() g = color.green() b = color.blue() cmd = f"8{ch}08{r:03d}{g:03d}{b:03d}" self._send(cmd) def _run_color_test(self) -> None: self._color_test_cmds = ["8003", "8004", "8005", "8002", "8000"] self._color_test_idx = 0 self._color_test_btn.setEnabled(False) self._color_test_timer = QTimer(self) self._color_test_timer.setInterval(1000) self._color_test_timer.timeout.connect(self._color_test_step) self._color_test_step() self._color_test_timer.start() def _color_test_step(self) -> None: if self._color_test_idx >= len(self._color_test_cmds): self._color_test_timer.stop() self._color_test_btn.setEnabled(True) return cmd = self._color_test_cmds[self._color_test_idx] self._color_test_idx += 1 self._send(cmd) def _send(self, cmd: str) -> None: if not cmd: return if not self._conn.is_connected: QMessageBox.warning(self, "Ошибка", "Порт не подключён.") return try: self._conn.send_command(cmd) self._log.setText(f"→ {cmd}") resp = self._conn.read_response(timeout=0.3) self._conn.release() if resp: self._log.setText(f"→ {cmd}\n← {resp}") except Exception as exc: self._conn.release() self._log.setText(f"Ошибка: {exc}")