Add Dispatch_V0.1.1

This commit is contained in:
2026-04-29 08:18:54 +04:00
commit a7ede6ded4
404 changed files with 39167 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
# gui/components/model_view/_scenario_camera.py
"""Камерный сценарий — базовый слой, всегда активен.
Обрабатывает ПКМ (вращение), СКМ (панорамирование), подавление ЛКМ drag.
Политика камеры текущего доменного сценария определяет, работает ли этот слой.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from PySide6.QtCore import Qt
from PySide6.QtGui import QGuiApplication
from gui.components.model_view._interaction_scenario import (
CameraPolicy,
InteractionScenario,
)
from error_logger import log_exception
if TYPE_CHECKING: # pragma: no cover
from gui.components.model_view_widget import ModelViewWidget
class CameraScenario(InteractionScenario):
"""Базовый камерный слой: вращение (ПКМ), панорамирование (СКМ)."""
name = "camera"
camera_policy = CameraPolicy.FREE
def on_mouse_press(self, mv: "ModelViewWidget", event) -> bool:
if event.button() == Qt.MouseButton.RightButton:
# В режиме контура ПКМ передаётся PyVista (remove point)
if mv._zone_selection_mode and mv.is_scenario_active("contour_edit"):
return False
mv._cam_rotate_active = True
mv._cam_last_pos = (event.position().x(), event.position().y())
return True
if event.button() == Qt.MouseButton.MiddleButton:
mv._cam_pan_active = True
mv._cam_last_pos = (event.position().x(), event.position().y())
return True
return False
def on_mouse_move(self, mv: "ModelViewWidget", event) -> bool:
# Safeguard: если release-событие потерялось (после модалок/фокуса),
# синхронизируем drag-флаги с реальным состоянием кнопок мыши.
try:
real_buttons = QGuiApplication.mouseButtons()
except Exception as _exc:
real_buttons = Qt.MouseButton.NoButton
if mv._cam_rotate_active and not (real_buttons & Qt.MouseButton.RightButton):
mv._cam_rotate_active = False
mv._cam_last_pos = None
if mv._cam_pan_active and not (real_buttons & Qt.MouseButton.MiddleButton):
mv._cam_pan_active = False
mv._cam_last_pos = None
# Подавление ЛКМ drag (не конфликтует с click-сценариями)
if hasattr(event, "buttons") and (event.buttons() & Qt.MouseButton.LeftButton):
return True
# ПКМ drag → вращение камеры
if (
mv._cam_rotate_active
and hasattr(event, "buttons")
and (event.buttons() & Qt.MouseButton.RightButton)
):
cx, cy = mv._cam_last_pos or (event.position().x(), event.position().y())
nx, ny = event.position().x(), event.position().y()
dx, dy = float(nx - cx), float(ny - cy)
mv._cam_last_pos = (nx, ny)
try:
cam = mv._plotter.camera
cam.Azimuth(-dx * 0.35)
cam.Elevation(dy * 0.35)
cam.OrthogonalizeViewUp()
if hasattr(mv, "_reset_camera_clipping_range"):
mv._reset_camera_clipping_range()
mv._safe_render(min_interval_s=1.0 / 75.0)
except Exception as _exc:
log_exception(__name__, "on_mouse_move", _exc)
return True
# СКМ drag → панорамирование
if (
mv._cam_pan_active
and hasattr(event, "buttons")
and (event.buttons() & Qt.MouseButton.MiddleButton)
):
cx, cy = mv._cam_last_pos or (event.position().x(), event.position().y())
nx, ny = event.position().x(), event.position().y()
dx, dy = float(nx - cx), float(ny - cy)
mv._cam_last_pos = (nx, ny)
mv._pan_camera_by_pixels(dx, dy)
try:
if hasattr(mv, "_reset_camera_clipping_range"):
mv._reset_camera_clipping_range()
mv._safe_render(min_interval_s=1.0 / 75.0)
except Exception as _exc:
log_exception(__name__, "on_mouse_move", _exc)
return True
return False
def on_mouse_release(self, mv: "ModelViewWidget", event) -> bool:
if event.button() == Qt.MouseButton.RightButton:
mv._cam_rotate_active = False
mv._cam_last_pos = None
return True
if event.button() == Qt.MouseButton.MiddleButton:
mv._cam_pan_active = False
mv._cam_last_pos = None
return True
return False