Newer
Older
RobotCar / src / pc / gui / panels / intersection_panel.py
"""
intersection_panel
十字路判定の有効/無効を切り替える UI パネル
"""

from PySide6.QtCore import Signal
from PySide6.QtWidgets import (
    QCheckBox,
    QDoubleSpinBox,
    QFormLayout,
    QLabel,
    QVBoxLayout,
)

from pc.gui.panels.collapsible_group_box import (
    CollapsibleGroupBox,
)


class IntersectionPanel(CollapsibleGroupBox):
    """十字路判定の切替 UI"""

    enabled_changed = Signal(bool)

    def __init__(self, available: bool = False) -> None:
        super().__init__("十字路判定")
        self._available = available
        self._setup_ui()

    def _setup_ui(self) -> None:
        """UI を構築する"""
        layout = QVBoxLayout()
        self.setLayout(layout)

        # 有効/無効チェックボックス
        self._enabled_cb = QCheckBox("十字路判定を有効にする")
        self._enabled_cb.setChecked(self._available)
        self._enabled_cb.setEnabled(self._available)
        self._enabled_cb.toggled.connect(
            self._on_toggled,
        )
        layout.addWidget(self._enabled_cb)

        # モデル状態の表示
        if self._available:
            status_text = "モデル: 読み込み済み"
        else:
            status_text = "モデル: 未学習(params/ にありません)"
        self._status_label = QLabel(status_text)
        self._status_label.setStyleSheet(
            "font-size: 11px; color: #888;"
        )
        layout.addWidget(self._status_label)

        # 十字路時の速度
        form = QFormLayout()
        layout.addLayout(form)

        self._spin_throttle = QDoubleSpinBox()
        self._spin_throttle.setRange(0.0, 1.0)
        self._spin_throttle.setSingleStep(0.05)
        self._spin_throttle.setDecimals(2)
        self._spin_throttle.setValue(0.4)
        form.addRow("十字路速度:", self._spin_throttle)

        # 判定結果の表示
        self._result_label = QLabel("")
        self._result_label.setStyleSheet(
            "font-size: 13px; font-weight: bold;"
            " padding: 2px;"
        )
        layout.addWidget(self._result_label)

    @property
    def enabled(self) -> bool:
        """十字路判定が有効かどうか"""
        return self._enabled_cb.isChecked()

    @property
    def throttle(self) -> float:
        """十字路時の速度"""
        return self._spin_throttle.value()

    def update_result(self, is_intersection: bool) -> None:
        """判定結果の表示を更新する

        Args:
            is_intersection: 十字路と判定されたか
        """
        if is_intersection:
            self._result_label.setText("判定: 十字路(直進)")
            self._result_label.setStyleSheet(
                "font-size: 13px; font-weight: bold;"
                " color: #f44; padding: 2px;"
            )
        else:
            self._result_label.setText("判定: 通常")
            self._result_label.setStyleSheet(
                "font-size: 13px; font-weight: bold;"
                " color: #4f4; padding: 2px;"
            )

    def clear_result(self) -> None:
        """判定結果の表示をクリアする"""
        self._result_label.setText("")

    def _on_toggled(self, checked: bool) -> None:
        """チェックボックスの切替をシグナルで通知する"""
        self.enabled_changed.emit(checked)