""" 미니 위젯 — Always-on-top 컴팩트 디스플레이. 남은 시간만 큰 글씨로 보여주는 작은 창. 메인 창과 동일한 1Hz 갱신을 부모 윈도우의 시그널/직접 호출로 받음. """ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication from PyQt5.QtCore import Qt, QPoint from PyQt5.QtGui import QFont, QMouseEvent from core.i18n import tr from ui.styles import apply_dark_titlebar class MiniWidget(QWidget): """Always-on-top 미니 위젯. 제공 기능: - 남은 시간 큰 글씨 - 마우스 드래그로 이동 - 우클릭 메뉴: 메인 창 열기 / 닫기 """ def __init__(self, parent_window=None): super().__init__() self.parent_window = parent_window self._drag_pos: QPoint = None self.setWindowTitle(tr('window.mini_widget')) self.setWindowFlags( Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool ) self.setAttribute(Qt.WA_TranslucentBackground, False) self.setFixedSize(220, 80) layout = QVBoxLayout() layout.setContentsMargins(12, 8, 12, 8) layout.setSpacing(2) self.title_label = QLabel(tr('label.remaining')) self.title_label.setAlignment(Qt.AlignCenter) self.title_label.setStyleSheet("color: #888; font-size: 11px;") self.time_label = QLabel("--:--:--") self.time_label.setAlignment(Qt.AlignCenter) self.time_label.setFont(QFont("Consolas", 22, QFont.Bold)) layout.addWidget(self.title_label) layout.addWidget(self.time_label) self.setLayout(layout) # 기본 스타일 (테마 무관 가독성 유지) self.setStyleSheet(""" QWidget { background-color: rgba(30, 30, 30, 230); border-radius: 8px; } QLabel { color: #fff; } """) apply_dark_titlebar(self) def update_remaining(self, remaining_str: str): """메인 윈도우에서 호출 — 남은 시간 동기화.""" self.time_label.setText(remaining_str) if remaining_str.startswith('+'): self.title_label.setText(tr('label.overtime_progress')) self.time_label.setStyleSheet("color: #ff6b6b;") else: self.title_label.setText(tr('label.remaining')) self.time_label.setStyleSheet("color: #fff;") # 드래그 이동 def mousePressEvent(self, event: QMouseEvent): if event.button() == Qt.LeftButton: self._drag_pos = event.globalPos() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event: QMouseEvent): if self._drag_pos and event.buttons() & Qt.LeftButton: self.move(event.globalPos() - self._drag_pos) event.accept() def mouseDoubleClickEvent(self, event: QMouseEvent): """더블클릭 시 메인 창 열기.""" if self.parent_window: self.parent_window.show() self.parent_window.raise_() self.parent_window.activateWindow() def contextMenuEvent(self, event): from PyQt5.QtWidgets import QMenu menu = QMenu(self) open_main = menu.addAction("메인 창 열기") close_mini = menu.addAction("미니 위젯 닫기") action = menu.exec_(event.globalPos()) if action == open_main and self.parent_window: self.parent_window.show() self.parent_window.raise_() self.parent_window.activateWindow() elif action == close_mini: self.close()