| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- """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)
|