Danil Iarosh 85a7b4db55 Update app functions and configs for board command system v2.x
- Обновлены коды базовых эффектов в Морской бой VR.lm с 0..12 на 10..22.
- Создан новый файл настроек подсветки Резервная панель RZ.lm.
- Полностью обновлен справочник команд Основные.csv с поддержкой новых команд v2.x.
- Добавлен выпадающий список стандартных ролей/матриц в диалог role_dialog.py.
- В led_test_dialog.py и led_test_section.py добавлены контролы для выбора физического канала, настройки яркости и гамма-коррекции WS2812.
2026-06-29 16:13:29 +03:00

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))