sp-hydra-veil-gui/gui/v2/ui/pages/browser_page.py
2026-06-13 16:19:11 -04:00

241 lines
8.8 KiB
Python
Executable file

import os
from PyQt6.QtWidgets import (
QApplication, QWidget, QPushButton, QButtonGroup, QScrollArea
)
from PyQt6.QtGui import QPixmap, QIcon, QPainter, QColor, QFont
from PyQt6.QtCore import Qt
from PyQt6 import QtCore
from gui.v2.ui.pages.Page import Page
class BrowserPage(Page):
def __init__(self, page_stack, main_window, parent=None):
super().__init__("Browser", page_stack, main_window, parent)
self.btn_path = main_window.btn_path
self.update_status = main_window
self.selected_browser_icon = None
self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
self.title.setGeometry(395, 40, 380, 40)
self.title.setText("Pick a Browser")
self.button_back.setVisible(True)
cm = main_window.connection_manager
if cm.is_synced():
from gui.v2.actions.sync import generate_grid_positions
browsers = cm.get_browser_list()
positions = generate_grid_positions(len(browsers))
available = [(QPushButton, brw, positions[i]) for i, brw in enumerate(browsers)]
self.create_interface_elements(available)
def create_interface_elements(self, available_browsers):
self._setup_scroll_area()
button_widget = self._create_button_widget()
self._populate_button_widget(button_widget, available_browsers)
self.scroll_area.setWidget(button_widget)
def _setup_scroll_area(self):
self.scroll_area = QScrollArea(self)
self.scroll_area.setGeometry(400, 90, 385, 400)
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setHorizontalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self._apply_scroll_area_style()
def _apply_scroll_area_style(self):
self.scroll_area.setStyleSheet("""
QScrollArea {
background: transparent;
border: none;
}
QScrollBar:vertical {
border: 1px solid white;
background: white;
width: 10px;
margin: 0px 0px 0px 0px;
}
QScrollBar::handle:vertical {
background: cyan;
min-height: 0px;
}
QScrollBar::add-line:vertical {
height: 0px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
height: 0px;
subcontrol-position: top;
subcontrol-origin: margin;
}
""")
def _create_button_widget(self):
button_widget = QWidget()
button_widget.setStyleSheet("background: transparent;")
self.buttonGroup = QButtonGroup(self)
self.buttons = []
return button_widget
def _populate_button_widget(self, button_widget, available_browsers):
dimensions = self._get_button_dimensions()
total_height = self._create_browser_buttons(
button_widget, available_browsers, dimensions)
self._set_final_widget_size(button_widget, dimensions, total_height)
def _get_button_dimensions(self):
return {
'width': 185,
'height': 75,
'spacing': 20,
'x_offset': 195
}
def _create_browser_buttons(self, button_widget, browser_icons, dims):
total_height = 0
for browser_tuple in browser_icons:
_, browser_string, geometry = browser_tuple
x_coord = geometry[0] - 395
y_coord = geometry[1] - 90
self._create_single_button(
button_widget, browser_string, x_coord, y_coord, dims)
total_height = max(total_height, y_coord + dims['height'])
return total_height
def _create_single_button(self, parent, icon_name, x_coord, y_coord, dims):
button = QPushButton(parent)
button.setFixedSize(dims['width'], dims['height'])
button.move(x_coord, y_coord)
button.setIconSize(button.size())
button.setCheckable(True)
browser_name, version = icon_name.split(':')
button.setIcon(QIcon(BrowserPage.create_browser_button_image(
f"{browser_name} {version}", self.btn_path)))
if button.icon().isNull():
fallback_path = os.path.join(
self.btn_path, "default_browser_button.png")
button.setIcon(QIcon(BrowserPage.create_browser_button_image(
f"{browser_name} {version}", fallback_path, True)))
self._apply_button_style(button)
self.buttons.append(button)
self.buttonGroup.addButton(button)
button.clicked.connect(
lambda _, b=icon_name: self.show_browser(b.replace(':', ' ')))
@staticmethod
def create_browser_button_image(browser_text, btn_path, is_fallback=False):
if ':' in browser_text:
browser_name, version = browser_text.split(':', 1)
else:
browser_name, version = browser_text.split(
)[0], ' '.join(browser_text.split()[1:])
if is_fallback:
base_image = QPixmap(btn_path)
else:
base_image = QPixmap(os.path.join(
btn_path, f"{browser_name}_button.png"))
if base_image.isNull():
base_image = QPixmap(185, 75)
base_image.fill(QColor(44, 62, 80))
painter = QPainter(base_image)
if painter.isActive():
BrowserPage._setup_version_font(painter, version, base_image)
if is_fallback:
BrowserPage._setup_browser_name(
painter, browser_name, base_image)
painter.end()
return base_image
@staticmethod
def _setup_browser_name(painter, browser_name, base_image):
font_size = 13
app_font = QApplication.font()
app_font.setPointSize(font_size)
app_font.setWeight(QFont.Weight.Bold)
painter.setFont(app_font)
painter.setPen(QColor(0, 255, 255))
text_rect = painter.fontMetrics().boundingRect(browser_name)
while text_rect.width() > base_image.width() * 0.6 and font_size > 6:
font_size -= 1
x = (base_image.width() - text_rect.width()) // 2 - 30
y = (base_image.height() + text_rect.height()) // 2 - 10
painter.drawText(x, y, browser_name)
@staticmethod
def _setup_version_font(painter, version, base_image):
font_size = 11
painter.setFont(QFont('Arial', font_size))
painter.setPen(QColor(0x88, 0x88, 0x88))
text_rect = painter.fontMetrics().boundingRect(version)
while text_rect.width() > base_image.width() * 0.6 and font_size > 6:
font_size -= 1
painter.setFont(QFont('Arial', font_size))
text_rect = painter.fontMetrics().boundingRect(version)
x = (base_image.width() - text_rect.width()) // 2 - 27
y = (base_image.height() + text_rect.height()) // 2 + 10
painter.drawText(x, y, version)
def _apply_button_style(self, button):
button.setStyleSheet("""
QPushButton {
background: transparent;
border: none;
}
QPushButton:hover {
background-color: rgba(200, 200, 200, 30);
}
QPushButton:checked {
background-color: rgba(200, 200, 200, 50);
}
""")
def _set_final_widget_size(self, widget, dims, total_height):
widget.setFixedSize(dims['width'] * 2 + 5,
total_height + dims['spacing'])
def show_browser(self, browser):
browser_name, version = browser.split(
)[0], ' '.join(browser.split()[1:])
try:
base_image = self._create_browser_display_image(
browser_name, version)
self.display.setPixmap(base_image.scaled(
self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
except Exception:
pass
self.selected_browser_icon = browser
self.button_next.setVisible(True)
self.update_swarp_json()
def _create_browser_display_image(self, browser_name, version):
base_image = QPixmap(os.path.join(
self.btn_path, f"{browser_name}_icon.png"))
painter = QPainter(base_image)
painter.setFont(QFont('Arial', 25))
painter.setPen(QColor(0, 255, 255))
text_rect = painter.fontMetrics().boundingRect(version)
x = (base_image.width() - text_rect.width()) // 2
y = base_image.height() - 45
painter.drawText(x, y, version)
painter.end()
return base_image
def update_swarp_json(self):
inserted_data = {
"browser": self.selected_browser_icon
}
self.update_status.write_data(inserted_data)
def gestionar_next(self):
self.custom_window.navigator.navigate("screen")