254 lines
7.4 KiB
Python
254 lines
7.4 KiB
Python
import logging
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Callable
|
|
|
|
from PySide6 import QtWidgets
|
|
from PySide6.QtCore import QSize
|
|
from PySide6.QtGui import QIcon, Qt, QPixmap
|
|
from PySide6.QtWidgets import QApplication, QWidget, QStyle, QToolButton
|
|
|
|
from constant import LAUNCHER_VERSION
|
|
from core_lib.qt.hack import move_window_to_center, is_light_theme, \
|
|
recolor_icon
|
|
from core_lib.qt import messagebox
|
|
from core_lib.launcher.object import Launcher as LauncherObject
|
|
from manager.game import GameManager
|
|
from manager.profile import ProfileManager
|
|
from manager.widgets import WidgetManager
|
|
from window import LauncherMainWindow
|
|
|
|
class ToolBar(QtWidgets.QToolBar):
|
|
def __init__(self, app: QApplication, parent=None):
|
|
super(ToolBar, self).__init__(parent)
|
|
self.app = app
|
|
self.spacer = QWidget()
|
|
self.orientationChanged.connect(self._update_widget_size)
|
|
|
|
def _update_widget_size(self, orientation):
|
|
vertical = orientation == Qt.Orientation.Vertical
|
|
|
|
if vertical:
|
|
self.spacer.setSizePolicy(
|
|
QtWidgets.QSizePolicy.Policy.Preferred,
|
|
QtWidgets.QSizePolicy.Policy.Expanding,
|
|
)
|
|
else:
|
|
self.spacer.setSizePolicy(
|
|
QtWidgets.QSizePolicy.Policy.Expanding,
|
|
QtWidgets.QSizePolicy.Policy.Preferred,
|
|
)
|
|
|
|
for button in self.findChildren(QToolButton):
|
|
if vertical:
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonIconOnly
|
|
)
|
|
button.setFixedSize(60, 60)
|
|
continue
|
|
|
|
button.setMinimumSize(0, 0)
|
|
button.setMaximumSize(16777215, 16777215)
|
|
|
|
if not button.icon().isNull() and not button.text():
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonIconOnly
|
|
)
|
|
button.setFixedSize(60, 60)
|
|
elif button.icon().isNull():
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonTextOnly
|
|
)
|
|
button.setFixedWidth(150)
|
|
else:
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
|
|
)
|
|
button.setMinimumWidth(60)
|
|
|
|
def add_button(self, text=None, icon: QIcon=None) -> QToolButton:
|
|
button = QtWidgets.QToolButton(self)
|
|
|
|
if text:
|
|
text = " "+text
|
|
button.setText(text)
|
|
# else:
|
|
# button.setText("\u00a0")
|
|
|
|
if icon:
|
|
button.setIcon(icon)
|
|
button.setIconSize(QSize(32, 32))
|
|
|
|
if text:
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
|
|
)
|
|
else:
|
|
button.setToolButtonStyle(
|
|
Qt.ToolButtonStyle.ToolButtonIconOnly
|
|
)
|
|
|
|
button.setAutoRaise(True)
|
|
button.setFixedHeight(60)
|
|
|
|
return button
|
|
|
|
def update_all(self):
|
|
self._update_widget_size(self.orientation())
|
|
self.update()
|
|
|
|
class Launcher(QApplication, LauncherObject):
|
|
def __init__(self, logger):
|
|
super().__init__()
|
|
# logger
|
|
self.logger = logger
|
|
|
|
# dirs
|
|
self.program_dir = Path(__file__).parent
|
|
self.work_dir = Path.cwd()
|
|
|
|
# Widget (Signal, Event)
|
|
self.widget_manager = WidgetManager()
|
|
self.game_manager = GameManager(self)
|
|
|
|
# Manager
|
|
self.profile_manager = ProfileManager(self, self.widget_manager)
|
|
|
|
# Window config
|
|
self.setApplicationName("TestLauncher")
|
|
self.main_window = LauncherMainWindow(
|
|
app=self
|
|
)
|
|
self.main_window.setGeometry(0, 0, 800, 600)
|
|
move_window_to_center(self.main_window)
|
|
|
|
# Set icon
|
|
if self.icon_path.exists():
|
|
self.setWindowIcon(QIcon(self.icon_path.as_posix()))
|
|
else:
|
|
self.logger.error("No icon found.")
|
|
|
|
def exec(self):
|
|
self.main_window.show()
|
|
self.main_window.toolbar.update_all()
|
|
|
|
# init managers
|
|
self.profile_manager.profile_load.emit()
|
|
|
|
self.exec_()
|
|
|
|
def get_icon(self, path: Path):
|
|
icon = self.style().standardIcon(QStyle.StandardPixmap.SP_MessageBoxWarning)
|
|
if not path.exists() or not path.is_file():
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Missing icon file: {}".format(path)
|
|
)
|
|
|
|
return icon
|
|
|
|
try:
|
|
if is_light_theme() and path.name.endswith(".png"):
|
|
icon = recolor_icon(
|
|
path
|
|
)
|
|
else:
|
|
icon = QIcon(path.as_posix())
|
|
except Exception as e:
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Failed to load icon {}: {}".format(path, e)
|
|
)
|
|
|
|
return icon
|
|
|
|
def get_picture(self, path: Path, size: QSize, custom_error: str=None) -> QPixmap:
|
|
picture = self.style().standardIcon(QStyle.StandardPixmap.SP_MessageBoxWarning).pixmap(size)
|
|
if not path.exists() or not path.is_file():
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Missing icon file: {}".format(path) if not custom_error else custom_error
|
|
)
|
|
|
|
return picture
|
|
|
|
try:
|
|
picture = QPixmap(path.as_posix())
|
|
except Exception as e:
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Failed to load icon {}: {}".format(path, e)
|
|
)
|
|
|
|
return picture
|
|
|
|
@property
|
|
def temp_dir(self):
|
|
return self.work_dir / "temp"
|
|
|
|
@property
|
|
def config_dir(self):
|
|
return self.work_dir / "config"
|
|
|
|
@property
|
|
def data_dir(self):
|
|
return self.work_dir / "data"
|
|
|
|
@property
|
|
def log_dir(self):
|
|
return self.work_dir / "log"
|
|
|
|
@property
|
|
def default_game_dir(self) -> Path:
|
|
return self.work_dir / "minecraft" if sys.platform.lower() == "darwin" else self.work_dir / ".minecraft"
|
|
|
|
@property
|
|
def resources_dir(self):
|
|
return self.program_dir / "resources"
|
|
|
|
@property
|
|
def icon_path(self):
|
|
return self.resources_dir / "icons" / "icon.png"
|
|
|
|
@property
|
|
def icon_dir(self):
|
|
return self.resources_dir / "icons"
|
|
|
|
@property
|
|
def launcher_version(self):
|
|
return LAUNCHER_VERSION
|
|
|
|
@property
|
|
def styles_path(self):
|
|
return self.resources_dir / "styles"
|
|
|
|
def apply_qss(self, qss_relative_path: Path, apply_qss_callback: Callable[[str], None]) -> str:
|
|
full_path = self.styles_path / qss_relative_path
|
|
if not full_path.exists():
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Missing stylesheet file: {}".format(full_path),
|
|
)
|
|
return ""
|
|
|
|
try:
|
|
data = full_path.read_text()
|
|
apply_qss_callback(data)
|
|
except Exception as e:
|
|
messagebox.error(
|
|
self.main_window,
|
|
"Resource Error",
|
|
"Unable to apply QSS stylesheet {}: {}".format(full_path, e),
|
|
)
|
|
|
|
return ""
|
|
|
|
def get_main_window(self):
|
|
return self.main_window
|