Source code for plugins.pygbag_designer

import json
import os
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QFormLayout, QLineEdit, QCheckBox,
                             QGroupBox, QLabel, QPushButton, QColorDialog, QHBoxLayout,
                             QComboBox, QFileDialog, QScrollArea)
from PyQt6.QtGui import QColor
from PyQt6.QtCore import Qt

_manager = None
_ui_hooked = False

[docs] def register_plugin(manager): global _manager _manager = manager
[docs] def on_load(context): _inject_project_settings()
[docs] def on_unload(): pass
[docs] def on_project_open(project_path: str): pass
def _inject_project_settings(): try: from editor.ui.project_settings import ProjectSettingsDialog original_setup_ui = ProjectSettingsDialog.setup_ui original_save_config = ProjectSettingsDialog.save_config def new_setup_ui(self): original_setup_ui(self) # Find or create "Plugins" tab plugins_tab_index = -1 for i in range(self.tabs.count()): if self.tabs.tabText(i) == "Plugins": plugins_tab_index = i break if plugins_tab_index == -1: self.plugins_tab = QWidget() self.plugins_layout = QVBoxLayout(self.plugins_tab) self.plugins_layout.setAlignment(Qt.AlignmentFlag.AlignTop) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(self.plugins_tab) self.tabs.addTab(scroll, "Plugins") else: scroll_widget = self.tabs.widget(plugins_tab_index) if isinstance(scroll_widget, QScrollArea): self.plugins_tab = scroll_widget.widget() else: self.plugins_tab = scroll_widget self.plugins_layout = self.plugins_tab.layout() designer_config = self.config_data.get("pygbag_designer", {}) # ── Pygbag Designer group ──────────────────────────────── group = QGroupBox("Pygbag Loading Screen Designer") layout = QFormLayout(group) # Background color self.pgd_bg_color = designer_config.get("background_color", "#222222") self.pgd_bg_btn = QPushButton() _set_color_btn(self.pgd_bg_btn, self.pgd_bg_color) self.pgd_bg_btn.clicked.connect(lambda: _pick_color(self, "pgd_bg_color", self.pgd_bg_btn)) layout.addRow("Background Color:", self.pgd_bg_btn) # Text color self.pgd_text_color = designer_config.get("text_color", "#cccccc") self.pgd_text_btn = QPushButton() _set_color_btn(self.pgd_text_btn, self.pgd_text_color) self.pgd_text_btn.clicked.connect(lambda: _pick_color(self, "pgd_text_color", self.pgd_text_btn)) layout.addRow("Text Color:", self.pgd_text_btn) # Accent / progress bar color self.pgd_accent_color = designer_config.get("accent_color", "#4fc3f7") self.pgd_accent_btn = QPushButton() _set_color_btn(self.pgd_accent_btn, self.pgd_accent_color) self.pgd_accent_btn.clicked.connect(lambda: _pick_color(self, "pgd_accent_color", self.pgd_accent_btn)) layout.addRow("Accent Color:", self.pgd_accent_btn) # Loading text self.pgd_loading_text_edit = QLineEdit(designer_config.get("loading_text", "Loading, please wait ...")) layout.addRow("Loading Text:", self.pgd_loading_text_edit) # Font family self.pgd_font_combo = QComboBox() self.pgd_font_combo.setEditable(True) fonts = [ "Arial, Helvetica, sans-serif", "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif", "'Courier New', Courier, monospace", "Georgia, 'Times New Roman', Times, serif", "'Trebuchet MS', sans-serif", "Verdana, Geneva, sans-serif", ] self.pgd_font_combo.addItems(fonts) current_font = designer_config.get("font_family", fonts[0]) idx = self.pgd_font_combo.findText(current_font) if idx >= 0: self.pgd_font_combo.setCurrentIndex(idx) else: self.pgd_font_combo.setCurrentText(current_font) layout.addRow("Font Family:", self.pgd_font_combo) # Show progress bar self.pgd_progress_chk = QCheckBox("Show loading progress bar") self.pgd_progress_chk.setChecked(designer_config.get("show_progress_bar", True)) layout.addRow(self.pgd_progress_chk) # Logo image URL / path logo_row = QHBoxLayout() self.pgd_logo_edit = QLineEdit(designer_config.get("logo_url", "")) self.pgd_logo_edit.setPlaceholderText("URL or filename (copied into build)") self.pgd_logo_browse_btn = QPushButton("Browse...") self.pgd_logo_browse_btn.clicked.connect(lambda: _browse_logo(self)) logo_row.addWidget(self.pgd_logo_edit, 1) logo_row.addWidget(self.pgd_logo_browse_btn) layout.addRow("Logo Image:", logo_row) # Background image URL / path bgimg_row = QHBoxLayout() self.pgd_bgimg_edit = QLineEdit(designer_config.get("background_image_url", "")) self.pgd_bgimg_edit.setPlaceholderText("URL or filename (optional)") self.pgd_bgimg_browse_btn = QPushButton("Browse...") self.pgd_bgimg_browse_btn.clicked.connect(lambda: _browse_bgimg(self)) bgimg_row.addWidget(self.pgd_bgimg_edit, 1) bgimg_row.addWidget(self.pgd_bgimg_browse_btn) layout.addRow("Background Image:", bgimg_row) # Layout preset self.pgd_layout_combo = QComboBox() self.pgd_layout_combo.addItems(["centered", "top-left", "bottom-center"]) self.pgd_layout_combo.setCurrentText(designer_config.get("layout", "centered")) layout.addRow("Layout:", self.pgd_layout_combo) # Preview hint hint = QLabel("These settings customize the pygbag web loading screen template.\n" "All web plugins (Game Distribution, etc.) can also add their own\n" "scripts and styles — they are merged automatically.") hint.setWordWrap(True) hint.setStyleSheet("color: #888; font-size: 11px;") layout.addRow(hint) self.plugins_layout.addWidget(group) def new_save_config(self): if hasattr(self, "pgd_bg_color"): self.config_data["pygbag_designer"] = { "background_color": self.pgd_bg_color, "text_color": self.pgd_text_color, "accent_color": self.pgd_accent_color, "loading_text": self.pgd_loading_text_edit.text().strip() or "Loading, please wait ...", "font_family": self.pgd_font_combo.currentText().strip() or "Arial, Helvetica, sans-serif", "show_progress_bar": self.pgd_progress_chk.isChecked(), "logo_url": self.pgd_logo_edit.text().strip(), "background_image_url": self.pgd_bgimg_edit.text().strip(), "layout": self.pgd_layout_combo.currentText(), } original_save_config(self) ProjectSettingsDialog.setup_ui = new_setup_ui ProjectSettingsDialog.save_config = new_save_config global _ui_hooked _ui_hooked = True except Exception as e: if _manager: _manager._logger.error("Pygbag Designer: Failed to inject UI", error=str(e)) # ── Helper functions ───────────────────────────────────────────────── def _set_color_btn(btn, hex_color): btn.setStyleSheet( f"background-color: {hex_color}; border: 1px solid #555; " f"min-width: 60px; min-height: 22px;" ) btn.setText(hex_color) def _pick_color(dialog, attr_name, btn): current = getattr(dialog, attr_name, "#222222") color = QColorDialog.getColor(QColor(current), dialog, "Pick Color") if color.isValid(): hex_val = color.name() setattr(dialog, attr_name, hex_val) _set_color_btn(btn, hex_val) def _browse_logo(dialog): start_dir = os.path.dirname(dialog.pgd_logo_edit.text().strip()) or dialog.project_path or os.path.expanduser("~") path, _ = QFileDialog.getOpenFileName( dialog, "Select Logo Image", start_dir, "Image Files (*.png *.jpg *.jpeg *.svg *.gif *.webp);;All Files (*)" ) if path: dialog.pgd_logo_edit.setText(os.path.normpath(path)) def _browse_bgimg(dialog): start_dir = os.path.dirname(dialog.pgd_bgimg_edit.text().strip()) or dialog.project_path or os.path.expanduser("~") path, _ = QFileDialog.getOpenFileName( dialog, "Select Background Image", start_dir, "Image Files (*.png *.jpg *.jpeg *.svg *.gif *.webp);;All Files (*)" ) if path: dialog.pgd_bgimg_edit.setText(os.path.normpath(path))