from __future__ import annotations from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtGui import QMouseEvent from PyQt6.QtWidgets import QApplication, QFrame, QLabel, QPushButton, QVBoxLayout from .theme import app_logo_pixmap class DropZone(QFrame): """The empty-state target for drag and drop.""" browseRequested = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self.setObjectName("dropZone") self.setProperty("dragActive", False) self.setCursor(Qt.CursorShape.PointingHandCursor) self.setMinimumHeight(250) layout = QVBoxLayout(self) layout.setContentsMargins(28, 26, 28, 26) layout.setSpacing(12) layout.addStretch(1) icon_label = QLabel() icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter) screen = QApplication.primaryScreen() dpr = screen.devicePixelRatio() if screen else 1.0 pixmap = app_logo_pixmap(max(64, int(64 * dpr))) pixmap.setDevicePixelRatio(dpr) icon_label.setPixmap(pixmap) layout.addWidget(icon_label) self.title_label = QLabel("Drop media to get started") self.title_label.setObjectName("emptyTitle") self.title_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.title_label) subtitle = QLabel( "Videos and images are compressed locally, on your computer.\n" "MP4 · MOV · MKV · JPG · PNG · WebP" ) subtitle.setObjectName("emptyText") subtitle.setAlignment(Qt.AlignmentFlag.AlignCenter) subtitle.setWordWrap(True) layout.addWidget(subtitle) button = QPushButton("Browse files") button.setObjectName("accentSmall") button.setCursor(Qt.CursorShape.PointingHandCursor) button.clicked.connect(self.browseRequested) layout.addWidget(button, 0, Qt.AlignmentFlag.AlignHCenter) hint = QLabel("or drag and drop anywhere in this window") hint.setObjectName("hintLabel") hint.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(hint) layout.addStretch(1) def set_drag_active(self, active: bool) -> None: if bool(self.property("dragActive")) == active: return self.setProperty("dragActive", active) self.title_label.setText("Drop to add to the queue" if active else "Drop media to get started") self.style().unpolish(self) self.style().polish(self) self.update() def mouseReleaseEvent(self, event: QMouseEvent) -> None: if event.button() == Qt.MouseButton.LeftButton: self.browseRequested.emit() super().mouseReleaseEvent(event)