"""Fullscreen timer display window.""" from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QApplication from PyQt6.QtCore import QTimer, Qt, pyqtSignal from PyQt6.QtGui import QFont, QScreen class TimerWindow(QWidget): finished = pyqtSignal() def __init__(self, timer, monitor_index=0, position=0): super().__init__() self.timer_model = timer self.remaining_seconds = timer.duration self.monitor_index = monitor_index self.position = position # 0 for left half, 1 for right half self.countdown_timer = None self.is_paused = False self.init_ui() self.start_countdown() def init_ui(self): # Set window flags for fullscreen self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint) # Set background color self.setStyleSheet(f"background-color: {self.timer_model.bg_color};") # Layout layout = QVBoxLayout(self) layout.setContentsMargins(50, 50, 50, 50) # Timer title self.title_label = QLabel(self.timer_model.name) self.title_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.title_label.setStyleSheet(f"color: {self.timer_model.text_color};") title_font = QFont("Arial", self.timer_model.font_size // 3, QFont.Weight.Bold) self.title_label.setFont(title_font) layout.addWidget(self.title_label) # Timer label self.time_label = QLabel(self.format_time(self.remaining_seconds)) self.time_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.time_label.setStyleSheet(f"color: {self.timer_model.text_color};") font = QFont("Arial", self.timer_model.font_size, QFont.Weight.Bold) self.time_label.setFont(font) layout.addWidget(self.time_label) # Control buttons control_layout = QHBoxLayout() control_layout.addStretch() button_font = QFont("Arial", 16, QFont.Weight.Bold) button_style = f""" QPushButton {{ background-color: rgba(255, 255, 255, 0.2); color: {self.timer_model.text_color}; border: 2px solid {self.timer_model.text_color}; border-radius: 10px; padding: 15px 30px; min-width: 120px; }} QPushButton:hover {{ background-color: rgba(255, 255, 255, 0.3); }} QPushButton:pressed {{ background-color: rgba(255, 255, 255, 0.4); }} """ self.pause_btn = QPushButton("Pause") self.pause_btn.setFont(button_font) self.pause_btn.setStyleSheet(button_style) self.pause_btn.clicked.connect(self.toggle_pause) control_layout.addWidget(self.pause_btn) self.stop_btn = QPushButton("Stop") self.stop_btn.setFont(button_font) self.stop_btn.setStyleSheet(button_style) self.stop_btn.clicked.connect(self.stop_timer) control_layout.addWidget(self.stop_btn) self.restart_btn = QPushButton("Restart") self.restart_btn.setFont(button_font) self.restart_btn.setStyleSheet(button_style) self.restart_btn.clicked.connect(self.restart_timer) control_layout.addWidget(self.restart_btn) control_layout.addStretch() layout.addLayout(control_layout) # Position on selected monitor self.position_on_monitor() # Show fullscreen self.showFullScreen() def position_on_monitor(self): screens = QApplication.screens() if self.monitor_index < len(screens): screen = screens[self.monitor_index] geometry = screen.geometry() else: # Fallback to primary screen screen = QApplication.primaryScreen() geometry = screen.geometry() # Split screen in half if position is 0 or 1 if self.position == 0: # Left half self.setGeometry(geometry.x(), geometry.y(), geometry.width() // 2, geometry.height()) elif self.position == 1: # Right half self.setGeometry(geometry.x() + geometry.width() // 2, geometry.y(), geometry.width() // 2, geometry.height()) else: # Full screen (shouldn't happen with current logic) self.setGeometry(geometry) def start_countdown(self): self.countdown_timer = QTimer(self) self.countdown_timer.timeout.connect(self.update_timer) self.countdown_timer.start(1000) # Update every second def update_timer(self): if not self.is_paused: self.remaining_seconds -= 1 if self.remaining_seconds <= 0: self.countdown_timer.stop() self.time_label.setText("TIME'S UP!") self.pause_btn.setEnabled(False) self.restart_btn.setEnabled(True) QTimer.singleShot(3000, self.close_window) # Close after 3 seconds else: self.time_label.setText(self.format_time(self.remaining_seconds)) def format_time(self, seconds): hours = seconds // 3600 minutes = (seconds % 3600) // 60 secs = seconds % 60 if hours > 0: return f"{hours:02d}:{minutes:02d}:{secs:02d}" else: return f"{minutes:02d}:{secs:02d}" def toggle_pause(self): """Toggle pause/resume state.""" self.is_paused = not self.is_paused if self.is_paused: self.pause_btn.setText("Resume") else: self.pause_btn.setText("Pause") def restart_timer(self): """Restart the timer from the beginning.""" self.remaining_seconds = self.timer_model.duration self.time_label.setText(self.format_time(self.remaining_seconds)) self.is_paused = False self.pause_btn.setText("Pause") self.pause_btn.setEnabled(True) if not self.countdown_timer.isActive(): self.countdown_timer.start(1000) def stop_timer(self): """Stop the timer and close the window.""" if self.countdown_timer and self.countdown_timer.isActive(): self.countdown_timer.stop() self.close_window() def close_window(self): self.finished.emit() self.close() def keyPressEvent(self, event): # Allow ESC key to close the timer if event.key() == Qt.Key.Key_Escape: self.stop_timer() # Space bar to pause/resume elif event.key() == Qt.Key.Key_Space: self.toggle_pause() super().keyPressEvent(event)