AddGameDialog rewrite from @VectorNull #19

Manually merged
Dervart merged 7 commits from Dervart/PortProtonQt:fixes-2 into main 2025-06-29 08:58:21 +00:00
2 changed files with 44 additions and 19 deletions

View File

@ -17,6 +17,7 @@
- Статус выделения и наведения на карточки теперь взаимоисключают друг друга - Статус выделения и наведения на карточки теперь взаимоисключают друг друга
- Все desktop файлы создаются с коментарием "Запустить игру {название} через PortProton" - Все desktop файлы создаются с коментарием "Запустить игру {название} через PortProton"
- Заполнители в переводах теперь стали более осмысленными - Заполнители в переводах теперь стали более осмысленными
- Изменена компоновка диалога добавления игры для лучшего отображения в Gamescope
### Fixed ### Fixed
- Дублирование обводки выделения карточек при быстром перемешении мыши - Дублирование обводки выделения карточек при быстром перемешении мыши

View File

@ -3,10 +3,9 @@ import tempfile
from typing import cast, TYPE_CHECKING from typing import cast, TYPE_CHECKING
from PySide6.QtGui import QPixmap, QIcon from PySide6.QtGui import QPixmap, QIcon
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QDialog, QLineEdit, QFormLayout, QPushButton, QDialog, QLineEdit, QFormLayout, QHBoxLayout, QLabel, QVBoxLayout, QListWidget, QScrollArea, QWidget, QListWidgetItem
QHBoxLayout, QLabel, QVBoxLayout, QListWidget, QScrollArea, QWidget, QListWidgetItem
) )
from PySide6.QtCore import Qt, QObject, Signal, QMimeDatabase from PySide6.QtCore import Qt, QObject, Signal, QMimeDatabase, QTimer
from icoextract import IconExtractor, IconExtractorError from icoextract import IconExtractor, IconExtractorError
from PIL import Image from PIL import Image
from portprotonqt.config_utils import get_portproton_location from portprotonqt.config_utils import get_portproton_location
@ -164,8 +163,9 @@ class FileExplorer(QDialog):
self.drives_container.setLayout(self.drives_layout) self.drives_container.setLayout(self.drives_layout)
self.drives_scroll.setWidget(self.drives_container) self.drives_scroll.setWidget(self.drives_container)
self.drives_scroll.setStyleSheet(self.theme.SCROLL_AREA_STYLE) self.drives_scroll.setStyleSheet(self.theme.SCROLL_AREA_STYLE)
self.drives_scroll.setFixedHeight(60) self.drives_scroll.setFixedHeight(70)
self.main_layout.addWidget(self.drives_scroll) self.main_layout.addWidget(self.drives_scroll)
self.drives_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Путь # Путь
self.path_label = QLabel() self.path_label = QLabel()
@ -388,10 +388,13 @@ class AddGameDialog(QDialog):
self.setWindowTitle(_("Edit Game") if edit_mode else _("Add Game")) self.setWindowTitle(_("Edit Game") if edit_mode else _("Add Game"))
self.setModal(True) self.setModal(True)
self.setFixedWidth(600)
self.setStyleSheet(self.theme.MAIN_WINDOW_STYLE + self.theme.MESSAGE_BOX_STYLE) self.setStyleSheet(self.theme.MAIN_WINDOW_STYLE + self.theme.MESSAGE_BOX_STYLE)
layout = QFormLayout(self) layout = QFormLayout(self)
layout.setLabelAlignment(Qt.AlignmentFlag.AlignLeft) layout.setLabelAlignment(Qt.AlignmentFlag.AlignLeft)
layout.setFormAlignment(Qt.AlignmentFlag.AlignLeft)
layout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
# Game name # Game name
self.nameEdit = QLineEdit(self) self.nameEdit = QLineEdit(self)
@ -403,36 +406,48 @@ class AddGameDialog(QDialog):
layout.addRow(name_label, self.nameEdit) layout.addRow(name_label, self.nameEdit)
# Exe path # Exe path
exe_label = QLabel(_("Path to Executable:"))
exe_label.setStyleSheet(
self.theme.PARAMS_TITLE_STYLE + " QLabel { color: #ffffff; font-size: 14px; font-weight: bold; }")
self.exeEdit = QLineEdit(self) self.exeEdit = QLineEdit(self)
self.exeEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE) self.exeEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
if exe_path: if exe_path:
self.exeEdit.setText(exe_path) self.exeEdit.setText(exe_path)
exeBrowseButton = QPushButton(_("Browse..."), self)
exeBrowseButton = AutoSizeButton(_("Browse..."), icon=self.theme_manager.get_icon("search"))
exeBrowseButton.setStyleSheet(self.theme.ACTION_BUTTON_STYLE) exeBrowseButton.setStyleSheet(self.theme.ACTION_BUTTON_STYLE)
exeBrowseButton.clicked.connect(self.browseExe) exeBrowseButton.clicked.connect(self.browseExe)
exeBrowseButton.setObjectName("exeBrowseButton") # Для поиска кнопки
exeLayout = QHBoxLayout() # Добавляем поле ввода для exe
exeLayout.addWidget(self.exeEdit) layout.addRow(exe_label, self.exeEdit)
exeLayout.addWidget(exeBrowseButton)
exe_label = QLabel(_("Path to Executable:")) # Добавляем кнопку обзора под полем ввода с выравниванием
exe_label.setStyleSheet(self.theme.PARAMS_TITLE_STYLE + " QLabel { color: #ffffff; font-size: 14px; font-weight: bold; }") empty_label = QLabel("")
layout.addRow(exe_label, exeLayout) empty_label.setFixedWidth(exe_label.sizeHint().width())
layout.addRow(empty_label, exeBrowseButton)
# Cover path # Cover path
cover_label = QLabel(_("Custom Cover:"))
cover_label.setStyleSheet(
self.theme.PARAMS_TITLE_STYLE + " QLabel { color: #ffffff; font-size: 14px; font-weight: bold; }")
self.coverEdit = QLineEdit(self) self.coverEdit = QLineEdit(self)
self.coverEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE) self.coverEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
if cover_path: if cover_path:
self.coverEdit.setText(cover_path) self.coverEdit.setText(cover_path)
coverBrowseButton = QPushButton(_("Browse..."), self)
coverBrowseButton = AutoSizeButton(_("Browse..."), icon=self.theme_manager.get_icon("search"))
coverBrowseButton.setStyleSheet(self.theme.ACTION_BUTTON_STYLE) coverBrowseButton.setStyleSheet(self.theme.ACTION_BUTTON_STYLE)
coverBrowseButton.clicked.connect(self.browseCover) coverBrowseButton.clicked.connect(self.browseCover)
coverBrowseButton.setObjectName("coverBrowseButton") # Для поиска кнопки
coverLayout = QHBoxLayout() # Добавляем поле ввода для обложки
coverLayout.addWidget(self.coverEdit) layout.addRow(cover_label, self.coverEdit)
coverLayout.addWidget(coverBrowseButton)
cover_label = QLabel(_("Custom Cover:")) # Добавляем кнопку обзора под полем ввода с выравниванием
cover_label.setStyleSheet(self.theme.PARAMS_TITLE_STYLE + " QLabel { color: #ffffff; font-size: 14px; font-weight: bold; }") layout.addRow(empty_label, coverBrowseButton)
layout.addRow(cover_label, coverLayout)
# Preview # Preview
self.coverPreview = QLabel(self) self.coverPreview = QLabel(self)
@ -452,12 +467,21 @@ class AddGameDialog(QDialog):
self.button_layout.addWidget(self.cancel_button) self.button_layout.addWidget(self.cancel_button)
layout.addRow(self.button_layout) layout.addRow(self.button_layout)
# Подключение сигналов
self.select_button.clicked.connect(self.accept) self.select_button.clicked.connect(self.accept)
self.cancel_button.clicked.connect(self.reject) self.cancel_button.clicked.connect(self.reject)
self.coverEdit.textChanged.connect(self.updatePreview) self.coverEdit.textChanged.connect(self.updatePreview)
self.exeEdit.textChanged.connect(self.updatePreview) self.exeEdit.textChanged.connect(self.updatePreview)
# Установка одинаковой ширины для кнопок и полей ввода
def update_button_widths():
exeBrowseButton.setFixedWidth(self.exeEdit.width())
coverBrowseButton.setFixedWidth(self.coverEdit.width())
# Вызываем после отображения окна, когда размеры установлены, чтобы реально дождаться, когда всё сформируется
QTimer.singleShot(0, update_button_widths)
# Обновляем превью, если в режиме редактирования
if edit_mode: if edit_mode:
self.updatePreview() self.updatePreview()