import os from PyQt6.QtWidgets import ( QPushButton, QLabel, QButtonGroup, QDialog, QLineEdit, QVBoxLayout, QHBoxLayout, QMessageBox ) from PyQt6.QtGui import QPixmap, QIcon, QPainter, QColor, QFont from PyQt6.QtCore import Qt, QRect from PyQt6 import QtCore from gui.v2.ui.pages.Page import Page class ScreenPage(Page): def __init__(self, page_stack, main_window, parent=None): super().__init__("Screen", page_stack, main_window, parent) self.selected_dimentions = None self.update_status = main_window self.selected_dimentions_icon = None self.button_back.setVisible(True) self.title.setGeometry(585, 40, 200, 40) self.title.setText("Pick a Resolution") self.host_screen_info = QLabel( f"Host: {self.custom_window.host_screen_width}x{self.custom_window.host_screen_height}", self) self.host_screen_info.setGeometry(QtCore.QRect(355, 30, 200, 30)) self.host_screen_info.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.host_screen_info.setStyleSheet( "color: #00ffff; font-size: 14px; font-weight: bold;") self.host_screen_info.show() self.display.setGeometry(QtCore.QRect(5, 50, 580, 435)) self.showing_larger_resolutions = False self.larger_resolution_buttons = [] self.create_interface_elements() def create_interface_elements(self): self.buttonGroup = QButtonGroup(self) self.buttons = [] resolutions = [ ("800x600", (595, 90, 180, 70)), ("1024x760", (595, 170, 180, 70)), ("1152x1080", (595, 250, 180, 70)), ("1280x1024", (595, 330, 180, 70)), ("1920x1080", (595, 410, 180, 70)) ] valid_resolutions = [] for res, geom in resolutions: w, h = map(int, res.split('x')) if w < self.custom_window.host_screen_width and h < self.custom_window.host_screen_height: valid_resolutions.append((QPushButton, res, geom)) for j, (object_type, icon_name, geometry) in enumerate(valid_resolutions): boton = object_type(self) boton.setGeometry(*geometry) boton.setIconSize(boton.size()) boton.setCheckable(True) boton.setIcon( QIcon(self.create_resolution_button_image(icon_name))) self.buttons.append(boton) self.buttonGroup.addButton(boton, j) boton.clicked.connect( lambda _, dimentions=icon_name: self.show_dimentions(dimentions)) self.larger_resolutions_button = QPushButton(self) self.larger_resolutions_button.setGeometry(100, 450, 185, 50) self.larger_resolutions_button.setIconSize( self.larger_resolutions_button.size()) self.larger_resolutions_button.setIcon( QIcon(self.create_resolution_button_image("Larger Resolutions"))) self.larger_resolutions_button.clicked.connect( self.show_larger_resolutions) self.custom_resolution_button = QPushButton(self) self.custom_resolution_button.setGeometry(300, 450, 195, 50) self.custom_resolution_button.setIconSize( self.custom_resolution_button.size()) self.custom_resolution_button.setIcon( QIcon(self.create_resolution_button_image("Custom Resolution"))) self.custom_resolution_button.clicked.connect( self.show_custom_resolution_dialog) def create_resolution_button_image(self, resolution_text): template_path = os.path.join( self.btn_path, "resolution_template_button.png") if os.path.exists(template_path): base_image = QPixmap(template_path) if 'Resolution' in resolution_text: base_image = base_image.scaled(195, 50) font_size = 10 else: base_image = base_image.scaled(187, 75) font_size = 13 else: base_image = QPixmap(185, 75) base_image.fill(QColor(44, 62, 80)) font_size = 13 painter = QPainter(base_image) painter.setRenderHint(QPainter.RenderHint.Antialiasing) font = QFont() font.setPointSize(font_size) font.setBold(True) painter.setFont(font) painter.setPen(QColor(0, 255, 255)) text_rect = base_image.rect() painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter, resolution_text) painter.end() return base_image def show_larger_resolutions(self): if self.showing_larger_resolutions: self.hide_larger_resolutions() else: self.hide_standard_resolutions() self.showing_larger_resolutions = True self.larger_resolutions_button.setIcon( QIcon(self.create_resolution_button_image("Standard Resolutions"))) larger_resolutions_list = [ ("2560x1600", (595, 90, 180, 70)), ("2560x1440", (595, 170, 180, 70)), ("1920x1440", (595, 250, 180, 70)), ("1792x1344", (595, 330, 180, 70)), ("2048x1152", (595, 410, 180, 70)) ] valid_larger = list(larger_resolutions_list) for i, (resolution, geometry) in enumerate(valid_larger): button = QPushButton(self) button.setGeometry(*geometry) button.setIconSize(button.size()) button.setCheckable(True) button.setVisible(True) button.setIcon( QIcon(self.create_resolution_button_image(resolution))) button.clicked.connect( lambda _, res=resolution: self.show_dimentions(res)) self.larger_resolution_buttons.append(button) self.buttonGroup.addButton(button, len(self.buttons) + i) def hide_larger_resolutions(self): for button in self.larger_resolution_buttons: self.buttonGroup.removeButton(button) button.deleteLater() self.larger_resolution_buttons.clear() self.showing_larger_resolutions = False self.larger_resolutions_button.setIcon( QIcon(self.create_resolution_button_image("Larger Resolutions"))) self.show_standard_resolutions() def hide_standard_resolutions(self): for button in self.buttons: button.setVisible(False) def show_standard_resolutions(self): for button in self.buttons: button.setVisible(True) def show_custom_resolution_dialog(self): dialog = QDialog(self) dialog.setWindowTitle("Custom Resolution") dialog.setFixedSize(300, 150) dialog.setModal(True) dialog.setStyleSheet(""" QDialog { background-color: #2c3e50; border: 2px solid #00ffff; border-radius: 10px; } QLabel { color: white; font-size: 12px; } QLineEdit { background-color: #34495e; color: white; border: 1px solid #00ffff; border-radius: 5px; padding: 5px; font-size: 12px; } QPushButton { background-color: #2c3e50; color: white; border: 2px solid #00ffff; border-radius: 5px; padding: 8px; font-size: 12px; } QPushButton:hover { background-color: #34495e; } """) layout = QVBoxLayout() input_layout = QHBoxLayout() width_label = QLabel("Width:") width_input = QLineEdit() width_input.setPlaceholderText("1920") height_label = QLabel("Height:") height_input = QLineEdit() height_input.setPlaceholderText("1080") input_layout.addWidget(width_label) input_layout.addWidget(width_input) input_layout.addWidget(height_label) input_layout.addWidget(height_input) button_layout = QHBoxLayout() ok_button = QPushButton("OK") cancel_button = QPushButton("Cancel") button_layout.addWidget(cancel_button) button_layout.addWidget(ok_button) layout.addLayout(input_layout) layout.addLayout(button_layout) dialog.setLayout(layout) def validate_and_accept(): try: width = int(width_input.text()) height = int(height_input.text()) if width <= 0 or height <= 0: QMessageBox.warning( dialog, "Invalid Resolution", "Width and height must be positive numbers.") return host_w = self.custom_window.host_screen_width host_h = self.custom_window.host_screen_height adjusted = False if width > host_w: width = host_w - 50 adjusted = True if height > host_h: height = host_h - 50 adjusted = True if adjusted: QMessageBox.information( dialog, "Notice", "Adjusted to fit host size") if width > 10000 or height > 10000: QMessageBox.warning( dialog, "Invalid Resolution", "Resolution too large. Maximum 10000x10000.") return custom_resolution = f"{width}x{height}" self.show_dimentions(custom_resolution) dialog.accept() except ValueError: QMessageBox.warning( dialog, "Invalid Input", "Please enter valid numbers for width and height.") ok_button.clicked.connect(validate_and_accept) cancel_button.clicked.connect(dialog.reject) width_input.returnPressed.connect(validate_and_accept) height_input.returnPressed.connect(validate_and_accept) dialog.exec() def update_swarp_json(self): inserted_data = { "dimentions": self.selected_dimentions_icon } self.update_status.write_data(inserted_data) def show_dimentions(self, dimentions): try: image_path = os.path.join(self.btn_path, f"{dimentions}.png") if os.path.exists(image_path): self.display.setPixmap(QPixmap(image_path).scaled( self.display.size(), Qt.AspectRatioMode.KeepAspectRatio)) else: self.create_resolution_preview_image(dimentions) except: self.display.clear() self.selected_dimentions_icon = dimentions self.button_next.setVisible(True) self.update_swarp_json() def create_resolution_preview_image(self, resolution_text): template_path = os.path.join(self.btn_path, "resolution_template.png") if os.path.exists(template_path): base_image = QPixmap(template_path) base_image = base_image.scaled( 580, 435, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation) else: base_image = QPixmap(580, 435) base_image.fill(QColor(44, 62, 80)) painter = QPainter(base_image) painter.setRenderHint(QPainter.RenderHint.Antialiasing) try: width, height = map(int, resolution_text.split('x')) gcd = self._gcd(width, height) aspect_ratio = f"{width//gcd}:{height//gcd}" except: aspect_ratio = "" font = QFont() font.setPointSize(24) font.setBold(True) painter.setFont(font) painter.setPen(QColor(0, 255, 255)) text_rect = base_image.rect() painter.drawText( text_rect, Qt.AlignmentFlag.AlignCenter, resolution_text) if aspect_ratio: font.setPointSize(16) painter.setFont(font) painter.setPen(QColor(200, 200, 200)) aspect_rect = QRect( text_rect.x(), text_rect.y() + 80, text_rect.width(), 40) painter.drawText( aspect_rect, Qt.AlignmentFlag.AlignCenter, f"({aspect_ratio})") painter.end() self.display.setPixmap(base_image) def _gcd(self, a, b): while b: a, b = b, a % b return a def gestionar_next(self): self.custom_window.navigator.navigate("resume")