LED-mapper/background_dialog.py
Danil Iarosh d8c95a15e2 feat: Improve editor overlays and stability
- Добавлена подложка с видимостью, прозрачностью, масштабом, перемещением и редактированием через отдельное меню.

- Добавлен инструмент создания свободных светодиодов и редактирование X/Y для вручную созданных точек в таблице.

- Упрощена таблица выбранных LED: единый ID, координаты X/Y и UID в конце.

- Добавлены настраиваемые горячие клавиши для всех действий и переключатель отображения id светодиодов.

- Улучшена отрисовка линий: стрелки направления, изгибы при полном и частичном визуальном наложении сегментов.

- Оптимизировано переключение активных линий, выбор точек и поиск наложений соединений для снижения подвисаний.

- Исправлена логика ручных LED: row/col рассчитываются по сетке 34 мм, а ручные точки не сдвигают якорь сетки.

- Обновлена сборка EXE: имя использует тег, короткий хэш или дату/время для dirty-репозитория.

- Расширен smoke-набор до 113 проверок для новых функций и регрессий.
2026-05-25 13:39:59 +03:00

107 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from pathlib import Path
from PySide6.QtWidgets import (
QDialog,
QDialogButtonBox,
QCheckBox,
QDoubleSpinBox,
QFileDialog,
QFormLayout,
QHBoxLayout,
QLineEdit,
QPushButton,
QWidget,
)
try:
from .localization import localize_dialog_buttons
from .models import BackgroundImage
except ImportError:
from localization import localize_dialog_buttons
from models import BackgroundImage
class BackgroundDialog(QDialog):
def __init__(self, background: BackgroundImage, parent=None) -> None: # noqa: ANN001
super().__init__(parent)
self.setWindowTitle("Подложка")
self.setMinimumWidth(460)
self.path = QLineEdit(background.path)
self.path.setPlaceholderText("PNG или JPEG")
browse = QPushButton("Выбрать")
browse.clicked.connect(self._browse)
path_row = QWidget()
path_layout = QHBoxLayout(path_row)
path_layout.setContentsMargins(0, 0, 0, 0)
path_layout.addWidget(self.path, 1)
path_layout.addWidget(browse)
self.offset_x = self._spin(-100000.0, 100000.0, background.offset_x, "")
self.offset_y = self._spin(-100000.0, 100000.0, background.offset_y, "")
self.scale_x = self._spin(1.0, 10000.0, background.scale_x_percent, " %")
self.scale_y = self._spin(1.0, 10000.0, background.scale_y_percent, " %")
self.opacity = self._spin(0.0, 100.0, background.opacity_percent, " %")
self.visible = QCheckBox("Показывать подложку")
self.visible.setChecked(background.visible)
reset_scale = QPushButton("100%")
reset_scale.clicked.connect(self._reset_scale)
scale_row = QWidget()
scale_layout = QHBoxLayout(scale_row)
scale_layout.setContentsMargins(0, 0, 0, 0)
scale_layout.addWidget(self.scale_x, 1)
scale_layout.addWidget(self.scale_y, 1)
scale_layout.addWidget(reset_scale)
form = QFormLayout(self)
form.addRow("Изображение", path_row)
form.addRow("Смещение центра X", self.offset_x)
form.addRow("Смещение центра Y", self.offset_y)
form.addRow("Масштаб X / Y", scale_row)
form.addRow("Прозрачность", self.opacity)
form.addRow("", self.visible)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
localize_dialog_buttons(buttons)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
form.addRow(buttons)
def background(self) -> BackgroundImage:
return BackgroundImage(
path=self.path.text().strip(),
offset_x=self.offset_x.value(),
offset_y=self.offset_y.value(),
scale_x_percent=self.scale_x.value(),
scale_y_percent=self.scale_y.value(),
opacity_percent=self.opacity.value(),
visible=self.visible.isChecked(),
)
def _reset_scale(self) -> None:
self.scale_x.setValue(100.0)
self.scale_y.setValue(100.0)
def _browse(self) -> None:
start = self.path.text().strip()
start_path = Path(start).parent if start else Path.home()
selected, _ = QFileDialog.getOpenFileName(
self,
"Выбрать подложку",
str(start_path),
"Изображения (*.png *.jpg *.jpeg);;Все файлы (*.*)",
)
if selected:
self.path.setText(selected)
@staticmethod
def _spin(minimum: float, maximum: float, value: float, suffix: str) -> QDoubleSpinBox:
spin = QDoubleSpinBox()
spin.setRange(minimum, maximum)
spin.setDecimals(2)
spin.setSingleStep(1.0)
spin.setValue(value)
spin.setSuffix(suffix)
return spin