- встраивать исходное изображение подложки в JSON вместе с метаданными и контрольной суммой - сохранять геометрию и параметры встроенной подложки при повторном редактировании - показывать значение «Встроенная» в диалоге подложки до выбора замены - загружать встроенное изображение непосредственно из JSON на холст - защищать существующий файл схемы при ошибке чтения подложки - расширить автоматические проверки до 161 сценария
126 lines
4.9 KiB
Python
126 lines
4.9 KiB
Python
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):
|
||
EMBEDDED_PATH_LABEL = "Встроенная"
|
||
|
||
def __init__(self, background: BackgroundImage, parent=None) -> None: # noqa: ANN001
|
||
super().__init__(parent)
|
||
self.setWindowTitle("Подложка")
|
||
self.setMinimumWidth(460)
|
||
|
||
self._source_background = background
|
||
self._keep_embedded_image = background.has_embedded_image()
|
||
self.path = QLineEdit(self.EMBEDDED_PATH_LABEL if self._keep_embedded_image else background.path)
|
||
self.path.setPlaceholderText("PNG или JPEG")
|
||
self.path.setReadOnly(self._keep_embedded_image)
|
||
if self._keep_embedded_image:
|
||
source_name = background.embedded_image_name or "изображение"
|
||
self.path.setToolTip(f"{source_name} встроено в JSON схемы")
|
||
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:
|
||
embedded = self._source_background if self._keep_embedded_image else BackgroundImage()
|
||
return BackgroundImage(
|
||
path="" if self._keep_embedded_image else 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(),
|
||
embedded_image_base64=embedded.embedded_image_base64,
|
||
embedded_image_mime_type=embedded.embedded_image_mime_type,
|
||
embedded_image_name=embedded.embedded_image_name,
|
||
embedded_image_sha256=embedded.embedded_image_sha256,
|
||
)
|
||
|
||
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._set_external_path(selected)
|
||
|
||
def _set_external_path(self, path: str) -> None:
|
||
self._keep_embedded_image = False
|
||
self.path.setReadOnly(False)
|
||
self.path.setToolTip("")
|
||
self.path.setText(path)
|
||
|
||
@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
|