summaryrefslogtreecommitdiff
path: root/plugins/motion_capture/camera_panel.py
blob: 3fdd286ebe4d9ffc686c276e30e8cf5dba24629c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
motion_capture/camera_panel.py

CameraPanel for AddDeviceDialog — shows selected camera info and builds
a CameraDevice when the user clicks "Add Device".
Camera discovery and simulation toggle are handled by AddDeviceDialog.
"""

from __future__ import annotations

from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QLabel, QVBoxLayout, QWidget


class CameraScanThread(QThread):
    cameras_found = pyqtSignal(list)   # list of (index: int, label: str)

    def run(self):
        results = []
        try:
            import cv2
            for i in range(6):
                cap = cv2.VideoCapture(i)
                if cap.isOpened():
                    ret, _ = cap.read()
                    if ret:
                        w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
                        h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
                        results.append((i, f"Camera {i}  ({w}×{h})"))
                    cap.release()
        except ImportError:
            pass
        self.cameras_found.emit(results)


class CameraPanel(QWidget):
    """Config panel for Camera device in AddDeviceDialog."""

    def __init__(self):
        super().__init__()
        self._selected_index: int = 0
        self._simulate: bool = False

        lay = QVBoxLayout(self)
        lay.setContentsMargins(0, 4, 0, 4)
        lay.setSpacing(8)

        self._selected_lbl = QLabel("No camera selected — scan above and click a camera")
        self._selected_lbl.setObjectName("traceSource")
        self._selected_lbl.setWordWrap(True)
        lay.addWidget(self._selected_lbl)

        note = QLabel(
            "Requires OpenCV:  pip install opencv-python\n"
            "Use Simulation mode if no camera is available."
        )
        note.setObjectName("traceSource")
        note.setWordWrap(True)
        lay.addWidget(note)
        lay.addStretch()

    def is_valid(self) -> bool:
        return True

    def set_simulate(self, simulate: bool):
        self._simulate = simulate

    def set_camera_index(self, index: int):
        self._selected_index = index
        self._selected_lbl.setText(f"Selected: Camera {index}")

    def build_device(self, device_id: str):
        from device import CameraDevice
        return CameraDevice(
            device_id=device_id,
            camera_index=self._selected_index,
            simulate=self._simulate,
        )