hydraveil-gui/gui/v2/ui/pages/screen_page.py
2026-06-13 16:19:11 -04:00

347 lines
12 KiB
Python
Executable file

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