2023-12-24 09:21:13 +13:00
|
|
|
import platform as pf
|
2023-09-20 10:39:15 +12:00
|
|
|
import shlex
|
2022-03-10 08:47:52 +13:00
|
|
|
import shutil
|
2022-02-27 12:14:47 +13:00
|
|
|
from logging import getLogger
|
2024-01-23 00:05:18 +13:00
|
|
|
from typing import Optional, Tuple, Iterable
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2024-01-21 04:11:41 +13:00
|
|
|
from PyQt5.QtCore import pyqtSignal, QSize, Qt, QMimeData, pyqtSlot
|
2023-12-19 04:34:18 +13:00
|
|
|
from PyQt5.QtGui import QDrag, QDropEvent, QDragEnterEvent, QDragMoveEvent, QFont, QMouseEvent, QShowEvent
|
2023-02-19 06:36:49 +13:00
|
|
|
from PyQt5.QtWidgets import (
|
|
|
|
QHBoxLayout,
|
|
|
|
QLabel,
|
|
|
|
QFrame,
|
|
|
|
QMessageBox,
|
|
|
|
QSizePolicy,
|
|
|
|
QWidget,
|
|
|
|
QScrollArea,
|
2023-08-22 05:22:54 +12:00
|
|
|
QAction,
|
2024-01-23 00:05:18 +13:00
|
|
|
QMenu, QStackedWidget, QPushButton, QLineEdit, QVBoxLayout, QComboBox,
|
2023-02-19 06:36:49 +13:00
|
|
|
)
|
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
from rare.models.wrapper import Wrapper
|
2023-02-19 06:36:49 +13:00
|
|
|
from rare.shared import RareCore
|
2024-02-22 00:21:44 +13:00
|
|
|
from rare.utils.misc import qta_icon
|
2024-01-22 12:26:27 +13:00
|
|
|
from rare.widgets.dialogs import ButtonDialog, game_title
|
2023-12-24 09:21:13 +13:00
|
|
|
|
2023-12-26 09:23:50 +13:00
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
2024-02-18 23:44:04 +13:00
|
|
|
from rare.utils.compat import steam
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-02-19 06:36:49 +13:00
|
|
|
logger = getLogger("WrapperSettings")
|
2022-02-27 12:14:47 +13:00
|
|
|
|
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
class WrapperEditDialog(ButtonDialog):
|
2024-01-21 03:21:53 +13:00
|
|
|
result_ready = pyqtSignal(bool, str)
|
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(WrapperEditDialog, self).__init__(parent=parent)
|
2024-01-21 03:21:53 +13:00
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
self.line_edit = QLineEdit(self)
|
2024-01-21 03:21:53 +13:00
|
|
|
self.line_edit.textChanged.connect(self.__on_text_changed)
|
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
self.widget_layout = QVBoxLayout()
|
|
|
|
self.widget_layout.addWidget(self.line_edit)
|
2024-01-21 03:21:53 +13:00
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
self.setCentralLayout(self.widget_layout)
|
2024-01-21 03:21:53 +13:00
|
|
|
|
|
|
|
self.accept_button.setText(self.tr("Save"))
|
2024-02-22 00:21:44 +13:00
|
|
|
self.accept_button.setIcon(qta_icon("fa.edit"))
|
2024-01-21 03:21:53 +13:00
|
|
|
self.accept_button.setEnabled(False)
|
|
|
|
|
|
|
|
self.result: Tuple = ()
|
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
def setup(self, wrapper: Wrapper):
|
|
|
|
header = self.tr("Edit wrapper")
|
|
|
|
self.setWindowTitle(header)
|
|
|
|
self.setSubtitle(game_title(header, wrapper.name))
|
2024-02-13 05:30:23 +13:00
|
|
|
self.line_edit.setText(wrapper.as_str)
|
2024-01-23 00:05:18 +13:00
|
|
|
|
2024-01-21 03:21:53 +13:00
|
|
|
@pyqtSlot(str)
|
|
|
|
def __on_text_changed(self, text: str):
|
|
|
|
self.accept_button.setEnabled(bool(text))
|
|
|
|
|
|
|
|
def done_handler(self):
|
|
|
|
self.result_ready.emit(*self.result)
|
|
|
|
|
|
|
|
def accept_handler(self):
|
|
|
|
self.result = (True, self.line_edit.text())
|
|
|
|
|
|
|
|
def reject_handler(self):
|
|
|
|
self.result = (False, self.line_edit.text())
|
2023-08-14 01:35:22 +12:00
|
|
|
|
|
|
|
|
2024-01-23 00:05:18 +13:00
|
|
|
class WrapperAddDialog(WrapperEditDialog):
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(WrapperAddDialog, self).__init__(parent=parent)
|
|
|
|
self.combo_box = QComboBox(self)
|
|
|
|
self.combo_box.addItem("None", "")
|
|
|
|
self.combo_box.currentIndexChanged.connect(self.__on_index_changed)
|
|
|
|
self.widget_layout.insertWidget(0, self.combo_box)
|
|
|
|
|
|
|
|
def setup(self, wrappers: Iterable[Wrapper]):
|
|
|
|
header = self.tr("Add wrapper")
|
|
|
|
self.setWindowTitle(header)
|
|
|
|
self.setSubtitle(header)
|
|
|
|
for wrapper in wrappers:
|
2024-02-13 05:30:23 +13:00
|
|
|
self.combo_box.addItem(f"{wrapper.name} ({wrapper.as_str})", wrapper.as_str)
|
2024-01-23 00:05:18 +13:00
|
|
|
|
|
|
|
@pyqtSlot(int)
|
|
|
|
def __on_index_changed(self, index: int):
|
|
|
|
command = self.combo_box.itemData(index, Qt.UserRole)
|
|
|
|
self.line_edit.setText(command)
|
|
|
|
|
|
|
|
|
2022-03-02 10:20:45 +13:00
|
|
|
class WrapperWidget(QFrame):
|
2023-09-20 10:39:15 +12:00
|
|
|
# object: current, object: new
|
|
|
|
update_wrapper = pyqtSignal(object, object)
|
|
|
|
# object: current
|
|
|
|
delete_wrapper = pyqtSignal(object)
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def __init__(self, wrapper: Wrapper, parent=None):
|
2022-03-12 11:08:36 +13:00
|
|
|
super(WrapperWidget, self).__init__(parent=parent)
|
2022-03-20 03:32:46 +13:00
|
|
|
self.setFrameShape(QFrame.StyledPanel)
|
|
|
|
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
2024-02-13 05:30:23 +13:00
|
|
|
self.setToolTip(wrapper.as_str)
|
2022-03-20 03:32:46 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
text_lbl = QLabel(wrapper.name, parent=self)
|
2023-08-22 05:22:54 +12:00
|
|
|
text_lbl.setFont(QFont("monospace"))
|
2023-09-20 10:39:15 +12:00
|
|
|
text_lbl.setEnabled(wrapper.is_editable)
|
2023-08-22 05:22:54 +12:00
|
|
|
|
|
|
|
image_lbl = QLabel(parent=self)
|
2024-02-22 00:21:44 +13:00
|
|
|
image_lbl.setPixmap(qta_icon("mdi.drag-vertical").pixmap(QSize(20, 20)))
|
2023-08-22 05:22:54 +12:00
|
|
|
|
|
|
|
edit_action = QAction("Edit", parent=self)
|
2024-01-21 03:21:53 +13:00
|
|
|
edit_action.triggered.connect(self.__on_edit)
|
2023-08-22 05:22:54 +12:00
|
|
|
delete_action = QAction("Delete", parent=self)
|
2024-01-21 03:21:53 +13:00
|
|
|
delete_action.triggered.connect(self.__on_delete)
|
2023-08-22 05:22:54 +12:00
|
|
|
|
|
|
|
manage_menu = QMenu(parent=self)
|
|
|
|
manage_menu.addActions([edit_action, delete_action])
|
|
|
|
|
2024-02-22 07:25:03 +13:00
|
|
|
manage_button = QPushButton(parent=self)
|
|
|
|
manage_button.setIcon(qta_icon("mdi.menu", fallback="fa.align-justify"))
|
2023-08-22 05:22:54 +12:00
|
|
|
manage_button.setMenu(manage_menu)
|
2023-09-20 10:39:15 +12:00
|
|
|
manage_button.setEnabled(wrapper.is_editable)
|
|
|
|
if not wrapper.is_editable:
|
2023-08-22 05:22:54 +12:00
|
|
|
manage_button.setToolTip(self.tr("Manage through settings"))
|
2023-08-17 05:55:41 +12:00
|
|
|
else:
|
2023-08-22 05:22:54 +12:00
|
|
|
manage_button.setToolTip(self.tr("Manage"))
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-08-17 05:55:41 +12:00
|
|
|
layout = QHBoxLayout(self)
|
2022-03-20 03:32:46 +13:00
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
2023-08-22 05:22:54 +12:00
|
|
|
layout.addWidget(image_lbl)
|
|
|
|
layout.addWidget(text_lbl)
|
|
|
|
layout.addWidget(manage_button)
|
2022-03-20 03:32:46 +13:00
|
|
|
self.setLayout(layout)
|
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
self.wrapper = wrapper
|
|
|
|
|
2022-03-20 03:32:46 +13:00
|
|
|
# lk: set object names for the stylesheet
|
|
|
|
self.setObjectName(type(self).__name__)
|
2023-08-22 05:22:54 +12:00
|
|
|
manage_button.setObjectName(f"{self.objectName()}Button")
|
2022-03-10 08:47:52 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def data(self) -> Wrapper:
|
|
|
|
return self.wrapper
|
|
|
|
|
2023-08-21 09:59:10 +12:00
|
|
|
@pyqtSlot()
|
2024-01-21 03:21:53 +13:00
|
|
|
def __on_delete(self) -> None:
|
2023-09-20 10:39:15 +12:00
|
|
|
self.delete_wrapper.emit(self.wrapper)
|
|
|
|
self.deleteLater()
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot()
|
2024-01-21 03:21:53 +13:00
|
|
|
def __on_edit(self) -> None:
|
2024-01-23 00:05:18 +13:00
|
|
|
dialog = WrapperEditDialog(self)
|
|
|
|
dialog.setup(self.wrapper)
|
2024-01-21 03:21:53 +13:00
|
|
|
dialog.result_ready.connect(self.__on_edit_result)
|
|
|
|
dialog.show()
|
|
|
|
|
|
|
|
@pyqtSlot(bool, str)
|
|
|
|
def __on_edit_result(self, accepted: bool, command: str):
|
2023-09-20 10:39:15 +12:00
|
|
|
if accepted and command:
|
|
|
|
new_wrapper = Wrapper(command=shlex.split(command))
|
|
|
|
self.update_wrapper.emit(self.wrapper, new_wrapper)
|
|
|
|
self.deleteLater()
|
2023-08-21 09:59:10 +12:00
|
|
|
|
2023-08-17 21:33:49 +12:00
|
|
|
def mouseMoveEvent(self, a0: QMouseEvent) -> None:
|
|
|
|
if a0.buttons() == Qt.LeftButton:
|
|
|
|
a0.accept()
|
2023-09-20 10:39:15 +12:00
|
|
|
if self.wrapper.is_compat_tool:
|
|
|
|
return
|
2022-03-10 08:47:52 +13:00
|
|
|
drag = QDrag(self)
|
|
|
|
mime = QMimeData()
|
|
|
|
drag.setMimeData(mime)
|
|
|
|
drag.exec_(Qt.MoveAction)
|
|
|
|
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-08-22 05:33:27 +12:00
|
|
|
class WrapperSettings(QWidget):
|
2023-09-20 10:39:15 +12:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(WrapperSettings, self).__init__(parent=parent)
|
2023-12-19 04:34:18 +13:00
|
|
|
self.widget_stack = QStackedWidget(self)
|
2022-03-20 03:32:46 +13:00
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
self.wrapper_scroll = QScrollArea(self.widget_stack)
|
2022-03-20 03:32:46 +13:00
|
|
|
self.wrapper_scroll.setSizeAdjustPolicy(QScrollArea.AdjustToContents)
|
|
|
|
self.wrapper_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
2023-12-19 04:34:18 +13:00
|
|
|
self.wrapper_scroll.setWidgetResizable(True)
|
2022-03-20 03:32:46 +13:00
|
|
|
self.wrapper_scroll.setProperty("no_kinetic_scroll", True)
|
2023-09-20 10:39:15 +12:00
|
|
|
self.wrapper_container = WrapperContainer(parent=self.wrapper_scroll)
|
|
|
|
self.wrapper_container.orderChanged.connect(self.__on_order_changed)
|
|
|
|
self.wrapper_scroll.setWidget(self.wrapper_container)
|
2022-03-10 08:47:52 +13:00
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
self.no_wrapper_label = QLabel(self.tr("No wrappers defined"), self.widget_stack)
|
|
|
|
|
|
|
|
self.widget_stack.addWidget(self.wrapper_scroll)
|
|
|
|
self.widget_stack.addWidget(self.no_wrapper_label)
|
|
|
|
|
|
|
|
self.add_button = QPushButton(self.tr("Add wrapper"), self)
|
2024-01-21 03:21:53 +13:00
|
|
|
self.add_button.clicked.connect(self.__on_add)
|
2023-12-19 04:34:18 +13:00
|
|
|
|
2022-03-20 03:32:46 +13:00
|
|
|
self.wrapper_scroll.horizontalScrollBar().rangeChanged.connect(self.adjust_scrollarea)
|
|
|
|
|
|
|
|
# lk: set object names for the stylesheet
|
2023-12-19 04:34:18 +13:00
|
|
|
self.setObjectName("WrapperSettings")
|
|
|
|
self.no_wrapper_label.setObjectName(f"{self.objectName()}Label")
|
2022-03-20 03:32:46 +13:00
|
|
|
self.wrapper_scroll.setObjectName(f"{self.objectName()}Scroll")
|
|
|
|
self.wrapper_scroll.horizontalScrollBar().setObjectName(
|
|
|
|
f"{self.wrapper_scroll.objectName()}Bar")
|
|
|
|
self.wrapper_scroll.verticalScrollBar().setObjectName(
|
|
|
|
f"{self.wrapper_scroll.objectName()}Bar")
|
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
main_layout = QHBoxLayout(self)
|
|
|
|
main_layout.addWidget(self.widget_stack)
|
|
|
|
main_layout.addWidget(self.add_button, alignment=Qt.AlignTop)
|
|
|
|
main_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
main_layout.setAlignment(Qt.AlignTop)
|
|
|
|
|
|
|
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
2023-09-20 10:39:15 +12:00
|
|
|
|
|
|
|
self.app_name: str = "default"
|
|
|
|
self.core = RareCore.instance().core()
|
|
|
|
self.wrappers = RareCore.instance().wrappers()
|
|
|
|
|
2023-12-19 04:34:18 +13:00
|
|
|
def showEvent(self, a0: QShowEvent):
|
|
|
|
if a0.spontaneous():
|
|
|
|
return super().showEvent(a0)
|
|
|
|
self.update_state()
|
|
|
|
return super().showEvent(a0)
|
|
|
|
|
2022-03-20 03:32:46 +13:00
|
|
|
@pyqtSlot(int, int)
|
2023-09-20 10:39:15 +12:00
|
|
|
def adjust_scrollarea(self, minh: int, maxh: int):
|
|
|
|
wrapper_widget = self.wrapper_container.findChild(WrapperWidget)
|
2023-01-29 23:50:37 +13:00
|
|
|
if not wrapper_widget:
|
2023-09-20 10:39:15 +12:00
|
|
|
return
|
2022-03-20 03:32:46 +13:00
|
|
|
# lk: when the scrollbar is not visible, min and max are 0
|
2023-09-20 10:39:15 +12:00
|
|
|
if maxh > minh:
|
2022-03-20 03:32:46 +13:00
|
|
|
self.wrapper_scroll.setMaximumHeight(
|
|
|
|
wrapper_widget.sizeHint().height()
|
|
|
|
+ self.wrapper_scroll.rect().height() // 2
|
|
|
|
- self.wrapper_scroll.contentsRect().height() // 2
|
2023-09-20 10:39:15 +12:00
|
|
|
+ self.wrapper_container.layout().spacing()
|
2022-03-20 03:32:46 +13:00
|
|
|
+ self.wrapper_scroll.horizontalScrollBar().sizeHint().height()
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.wrapper_scroll.setMaximumHeight(
|
|
|
|
wrapper_widget.sizeHint().height()
|
|
|
|
+ self.wrapper_scroll.rect().height()
|
|
|
|
- self.wrapper_scroll.contentsRect().height()
|
|
|
|
)
|
2022-03-10 08:47:52 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot(QWidget, int)
|
|
|
|
def __on_order_changed(self, widget: WrapperWidget, new_index: int):
|
|
|
|
wrapper = widget.data()
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
wrappers.remove(wrapper)
|
|
|
|
wrappers.insert(new_index, wrapper)
|
|
|
|
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
|
2022-03-07 07:48:35 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot()
|
2024-01-21 03:21:53 +13:00
|
|
|
def __on_add(self) -> None:
|
2024-01-23 00:05:18 +13:00
|
|
|
dialog = WrapperAddDialog(self)
|
|
|
|
dialog.setup(self.wrappers.user_wrappers)
|
2024-01-21 03:21:53 +13:00
|
|
|
dialog.result_ready.connect(self.__on_add_result)
|
|
|
|
dialog.show()
|
|
|
|
|
|
|
|
@pyqtSlot(bool, str)
|
|
|
|
def __on_add_result(self, accepted: bool, command: str):
|
|
|
|
if accepted and command:
|
2023-09-20 10:39:15 +12:00
|
|
|
wrapper = Wrapper(shlex.split(command))
|
|
|
|
self.add_user_wrapper(wrapper)
|
2022-03-14 05:20:55 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def __add_wrapper(self, wrapper: Wrapper, position: int = -1):
|
2023-12-19 04:34:18 +13:00
|
|
|
self.widget_stack.setCurrentWidget(self.wrapper_scroll)
|
2023-09-20 10:39:15 +12:00
|
|
|
widget = WrapperWidget(wrapper, self.wrapper_container)
|
2023-08-17 21:33:49 +12:00
|
|
|
if position < 0:
|
2023-09-20 10:39:15 +12:00
|
|
|
self.wrapper_container.addWidget(widget)
|
2023-08-17 21:33:49 +12:00
|
|
|
else:
|
2023-09-20 10:39:15 +12:00
|
|
|
self.wrapper_container.insertWidget(position, widget)
|
2022-03-20 03:32:46 +13:00
|
|
|
self.adjust_scrollarea(
|
|
|
|
self.wrapper_scroll.horizontalScrollBar().minimum(),
|
2023-08-23 05:57:54 +12:00
|
|
|
self.wrapper_scroll.horizontalScrollBar().maximum(),
|
2022-03-20 03:32:46 +13:00
|
|
|
)
|
2023-09-20 10:39:15 +12:00
|
|
|
widget.update_wrapper.connect(self.__update_wrapper)
|
|
|
|
widget.delete_wrapper.connect(self.__delete_wrapper)
|
2023-08-17 21:33:49 +12:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def add_wrapper(self, wrapper: Wrapper, position: int = -1):
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
if position < 0 or wrapper.is_compat_tool:
|
|
|
|
wrappers.append(wrapper)
|
|
|
|
else:
|
|
|
|
wrappers.insert(position, wrapper)
|
|
|
|
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
|
|
|
|
self.__add_wrapper(wrapper, position)
|
2022-03-02 10:20:45 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def add_user_wrapper(self, wrapper: Wrapper, position: int = -1):
|
|
|
|
if not wrapper:
|
|
|
|
return
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-12-26 09:23:50 +13:00
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
2024-02-18 23:44:04 +13:00
|
|
|
compat_cmds = [tool.command() for tool in steam.find_tools()]
|
2024-02-13 05:30:23 +13:00
|
|
|
if wrapper.as_str in compat_cmds:
|
2023-12-24 09:21:13 +13:00
|
|
|
QMessageBox.warning(
|
|
|
|
self,
|
|
|
|
self.tr("Warning"),
|
|
|
|
self.tr("Do not insert compatibility tools manually. Add them through Proton settings"),
|
|
|
|
)
|
|
|
|
return
|
2023-08-17 21:33:49 +12:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
if wrapper.checksum in self.wrappers.get_game_md5sum_list(self.app_name):
|
|
|
|
QMessageBox.warning(
|
2024-02-13 05:30:23 +13:00
|
|
|
self, self.tr("Warning"), self.tr("Wrapper <b>{0}</b> is already in the list").format(wrapper.as_str)
|
2023-09-20 10:39:15 +12:00
|
|
|
)
|
|
|
|
return
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
if not shutil.which(wrapper.executable):
|
|
|
|
ans = QMessageBox.question(
|
|
|
|
self,
|
|
|
|
self.tr("Warning"),
|
|
|
|
self.tr("Wrapper <b>{0}</b> is not in $PATH. Add it anyway?").format(wrapper.executable),
|
|
|
|
QMessageBox.Yes | QMessageBox.No,
|
|
|
|
QMessageBox.No
|
|
|
|
)
|
|
|
|
if ans == QMessageBox.No:
|
|
|
|
return
|
2022-02-27 12:14:47 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
self.add_wrapper(wrapper, position)
|
2022-03-07 07:48:35 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot(object)
|
|
|
|
def __delete_wrapper(self, wrapper: Wrapper):
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
wrappers.remove(wrapper)
|
|
|
|
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
|
|
|
|
if not wrappers:
|
2023-12-19 04:34:18 +13:00
|
|
|
self.wrapper_scroll.setMaximumHeight(self.no_wrapper_label.sizeHint().height())
|
|
|
|
self.widget_stack.setCurrentWidget(self.no_wrapper_label)
|
2022-03-07 07:48:35 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot(object, object)
|
|
|
|
def __update_wrapper(self, old: Wrapper, new: Wrapper):
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
index = wrappers.index(old)
|
|
|
|
wrappers.remove(old)
|
|
|
|
wrappers.insert(index, new)
|
|
|
|
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
|
|
|
|
self.__add_wrapper(new, index)
|
2022-03-07 07:48:35 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
@pyqtSlot()
|
|
|
|
def update_state(self):
|
|
|
|
for w in self.wrapper_container.findChildren(WrapperWidget, options=Qt.FindDirectChildrenOnly):
|
|
|
|
w.deleteLater()
|
|
|
|
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
|
|
|
|
if not wrappers:
|
2023-12-19 04:34:18 +13:00
|
|
|
self.wrapper_scroll.setMaximumHeight(self.no_wrapper_label.sizeHint().height())
|
|
|
|
self.widget_stack.setCurrentWidget(self.no_wrapper_label)
|
2022-02-27 12:14:47 +13:00
|
|
|
else:
|
2023-12-19 04:34:18 +13:00
|
|
|
self.widget_stack.setCurrentWidget(self.wrapper_scroll)
|
2023-09-20 10:39:15 +12:00
|
|
|
for wrapper in wrappers:
|
|
|
|
self.__add_wrapper(wrapper)
|
2022-03-14 05:20:55 +13:00
|
|
|
|
2022-03-12 11:08:36 +13:00
|
|
|
|
|
|
|
class WrapperContainer(QWidget):
|
2023-09-20 10:39:15 +12:00
|
|
|
# QWidget: moving widget, int: new index
|
|
|
|
orderChanged: pyqtSignal = pyqtSignal(QWidget, int)
|
2022-03-12 11:08:36 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def __init__(self, parent=None):
|
2022-03-12 11:08:36 +13:00
|
|
|
super(WrapperContainer, self).__init__(parent=parent)
|
|
|
|
self.setAcceptDrops(True)
|
2023-09-20 10:39:15 +12:00
|
|
|
self.__layout = QHBoxLayout(self)
|
|
|
|
self.__layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self.__layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
2022-03-20 03:32:46 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
self.__drag_widget: Optional[QWidget] = None
|
2023-08-22 05:33:27 +12:00
|
|
|
|
2022-03-20 03:32:46 +13:00
|
|
|
# lk: set object names for the stylesheet
|
|
|
|
self.setObjectName(type(self).__name__)
|
2022-03-12 11:08:36 +13:00
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
# def count(self) -> int:
|
|
|
|
# return self.__layout.count()
|
|
|
|
#
|
|
|
|
# def itemData(self, index: int) -> Any:
|
|
|
|
# widget: WrapperWidget = self.__layout.itemAt(index).widget()
|
|
|
|
# return widget.data()
|
|
|
|
|
|
|
|
def addWidget(self, widget: WrapperWidget):
|
|
|
|
self.__layout.addWidget(widget)
|
|
|
|
|
|
|
|
def insertWidget(self, index: int, widget: WrapperWidget):
|
|
|
|
self.__layout.insertWidget(index, widget)
|
|
|
|
|
2022-03-10 08:47:52 +13:00
|
|
|
def dragEnterEvent(self, e: QDragEnterEvent):
|
|
|
|
widget = e.source()
|
2023-09-20 10:39:15 +12:00
|
|
|
self.__drag_widget = widget
|
2022-03-10 08:47:52 +13:00
|
|
|
e.accept()
|
|
|
|
|
2023-09-20 10:39:15 +12:00
|
|
|
def __get_drop_index(self, x) -> int:
|
|
|
|
drag_idx = self.__layout.indexOf(self.__drag_widget)
|
2022-03-12 11:08:36 +13:00
|
|
|
|
|
|
|
if drag_idx > 0:
|
2023-09-20 10:39:15 +12:00
|
|
|
prev_widget = self.__layout.itemAt(drag_idx - 1).widget()
|
|
|
|
if x < self.__drag_widget.x() - prev_widget.width() // 2:
|
2022-03-12 11:08:36 +13:00
|
|
|
return drag_idx - 1
|
2023-09-20 10:39:15 +12:00
|
|
|
if drag_idx < self.__layout.count() - 1:
|
|
|
|
next_widget = self.__layout.itemAt(drag_idx + 1).widget()
|
|
|
|
if x > self.__drag_widget.x() + self.__drag_widget.width() + next_widget.width() // 2:
|
2022-03-12 11:08:36 +13:00
|
|
|
return drag_idx + 1
|
|
|
|
|
|
|
|
return drag_idx
|
2022-03-10 08:47:52 +13:00
|
|
|
|
|
|
|
def dragMoveEvent(self, e: QDragMoveEvent) -> None:
|
2023-09-20 10:39:15 +12:00
|
|
|
new_x = self.__get_drop_index(e.pos().x())
|
|
|
|
self.__layout.insertWidget(new_x, self.__drag_widget)
|
2022-03-10 08:47:52 +13:00
|
|
|
|
|
|
|
def dropEvent(self, e: QDropEvent):
|
|
|
|
pos = e.pos()
|
|
|
|
widget = e.source()
|
2023-09-20 10:39:15 +12:00
|
|
|
new_x = self.__get_drop_index(pos.x())
|
|
|
|
self.__layout.insertWidget(new_x, widget)
|
|
|
|
self.__drag_widget = None
|
|
|
|
self.orderChanged.emit(widget, new_x)
|
2022-03-10 08:47:52 +13:00
|
|
|
e.accept()
|