- Обновлены коды базовых эффектов в Морской бой VR.lm с 0..12 на 10..22. - Создан новый файл настроек подсветки Резервная панель RZ.lm. - Полностью обновлен справочник команд Основные.csv с поддержкой новых команд v2.x. - Добавлен выпадающий список стандартных ролей/матриц в диалог role_dialog.py. - В led_test_dialog.py и led_test_section.py добавлены контролы для выбора физического канала, настройки яркости и гамма-коррекции WS2812.
133 lines
5.4 KiB
Python
133 lines
5.4 KiB
Python
"""Диалог «Задание роли» — чтение и установка пользовательской роли контроллера.
|
|
|
|
Команды:
|
|
97 — прочитать роль → ROLE : <значение>
|
|
96<text> — задать роль (до 20 символов)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from PySide6.QtWidgets import (
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QLineEdit,
|
|
QMessageBox,
|
|
QPushButton,
|
|
QVBoxLayout,
|
|
)
|
|
|
|
from ...services.com_service import ComConnection
|
|
from ...ui.icons import get_icon_color, get_icon_muted, icon
|
|
from ..no_wheel_combo_box import NoWheelComboBox
|
|
from .styled_dialog import StyledDialog
|
|
|
|
|
|
class RoleDialog(StyledDialog):
|
|
def __init__(self, connection: ComConnection, parent=None) -> None:
|
|
super().__init__(parent)
|
|
self._conn = connection
|
|
self.setWindowTitle("Задание роли")
|
|
self.setMinimumWidth(400)
|
|
self._setup_ui()
|
|
self._read_role()
|
|
|
|
def _setup_ui(self) -> None:
|
|
root = self.containerLayout()
|
|
root.setSpacing(12)
|
|
|
|
# ── Текущая роль ──
|
|
current_layout = QHBoxLayout()
|
|
current_layout.addWidget(QLabel("Текущая роль:"))
|
|
self._current_label = QLabel("—")
|
|
self._current_label.setStyleSheet("font-weight: 700; font-size: 14px;")
|
|
current_layout.addWidget(self._current_label, 1)
|
|
|
|
read_btn = QPushButton("Обновить")
|
|
read_btn.setIcon(icon("fa5s.sync-alt", color=get_icon_color()))
|
|
read_btn.clicked.connect(self._read_role)
|
|
current_layout.addWidget(read_btn)
|
|
root.addLayout(current_layout)
|
|
|
|
# ── Быстрый выбор роли ──
|
|
preset_layout = QHBoxLayout()
|
|
preset_layout.addWidget(QLabel("Шаблоны ролей:"))
|
|
self._role_preset_combo = NoWheelComboBox()
|
|
self._role_preset_combo.addItem("— Свой вариант —", "")
|
|
self._role_preset_combo.addItem("s_b (Морской бой)", "s_b")
|
|
self._role_preset_combo.addItem("s_b_v1 (Морской бой v1)", "s_b_v1")
|
|
self._role_preset_combo.addItem("s_b_v2 (Морской бой v2)", "s_b_v2")
|
|
self._role_preset_combo.addItem("dan_ro (Данро)", "dan_ro")
|
|
self._role_preset_combo.addItem("dan_ro_v1 (Данро v1)", "dan_ro_v1")
|
|
self._role_preset_combo.addItem("rz (Резервная панель RZ)", "rz")
|
|
self._role_preset_combo.addItem("rz_v1 (Резервная панель RZ v1)", "rz_v1")
|
|
self._role_preset_combo.currentIndexChanged.connect(self._on_preset_changed)
|
|
preset_layout.addWidget(self._role_preset_combo, 1)
|
|
root.addLayout(preset_layout)
|
|
|
|
# ── Установка новой роли ──
|
|
set_layout = QHBoxLayout()
|
|
set_layout.addWidget(QLabel("Новая роль:"))
|
|
self._role_input = QLineEdit()
|
|
self._role_input.setMaxLength(20)
|
|
self._role_input.setPlaceholderText("до 20 символов, напр. left, right, cabinet…")
|
|
set_layout.addWidget(self._role_input, 1)
|
|
|
|
set_btn = QPushButton("Задать")
|
|
set_btn.setProperty("role", "primary")
|
|
set_btn.setIcon(icon("fa5s.save", color="#ecfdf5"))
|
|
set_btn.clicked.connect(self._set_role)
|
|
set_layout.addWidget(set_btn)
|
|
root.addLayout(set_layout)
|
|
|
|
# ── Закрыть ──
|
|
btn_layout = QHBoxLayout()
|
|
btn_layout.addStretch()
|
|
close_btn = QPushButton("Закрыть")
|
|
close_btn.setIcon(icon("fa5s.times", color=get_icon_muted()))
|
|
close_btn.clicked.connect(self.close)
|
|
btn_layout.addWidget(close_btn)
|
|
root.addLayout(btn_layout)
|
|
|
|
def _on_preset_changed(self, index: int) -> None:
|
|
val = self._role_preset_combo.itemData(index)
|
|
if val:
|
|
self._role_input.setText(val)
|
|
|
|
def _read_role(self) -> None:
|
|
if not self._conn.is_connected:
|
|
return
|
|
try:
|
|
self._conn.send_command("97")
|
|
resp = self._conn.read_response(timeout=0.5)
|
|
self._conn.release()
|
|
if resp and "ROLE" in resp:
|
|
# формат: "ROLE : <значение>"
|
|
role = resp.split(":", 1)[-1].strip() if ":" in resp else resp
|
|
self._current_label.setText(role or "(пусто)")
|
|
else:
|
|
self._current_label.setText(resp or "—")
|
|
except Exception:
|
|
self._conn.release()
|
|
self._current_label.setText("ошибка")
|
|
|
|
def _set_role(self) -> None:
|
|
text = self._role_input.text().strip()
|
|
if not text:
|
|
QMessageBox.warning(self, "Роль", "Введите значение роли.")
|
|
return
|
|
if len(text) > 20:
|
|
QMessageBox.warning(self, "Роль", "Роль должна быть не длиннее 20 символов.")
|
|
return
|
|
if not self._conn.is_connected:
|
|
QMessageBox.warning(self, "Ошибка", "Порт не подключён.")
|
|
return
|
|
try:
|
|
self._conn.send_command(f"96{text}")
|
|
resp = self._conn.read_response(timeout=0.5)
|
|
self._conn.release()
|
|
QMessageBox.information(self, "Роль", f"Ответ: {resp or 'OK'}")
|
|
self._read_role()
|
|
except Exception as exc:
|
|
self._conn.release()
|
|
QMessageBox.critical(self, "Ошибка", str(exc))
|