mirror of
https://github.com/Omni-guides/Jackify.git
synced 2026-01-17 11:37:01 +01:00
Initial public release v0.1.0 - Linux Wabbajack Modlist Application
Jackify provides native Linux support for Wabbajack modlist installation and management with automated Steam integration and Proton configuration. Key Features: - Almost Native Linux implementation (texconv.exe run via proton) - Automated Steam shortcut creation and Proton prefix management - Both CLI and GUI interfaces, with Steam Deck optimization Supported Games: - Skyrim Special Edition - Fallout 4 - Fallout New Vegas - Oblivion, Starfield, Enderal, and diverse other games Technical Architecture: - Clean separation between frontend and backend services - Powered by jackify-engine 0.3.x for Wabbajack-matching modlist installation
This commit is contained in:
214
jackify/frontends/gui/screens/modlist_tasks.py
Normal file
214
jackify/frontends/gui/screens/modlist_tasks.py
Normal file
@@ -0,0 +1,214 @@
|
||||
"""
|
||||
Migrated Modlist Tasks Screen
|
||||
|
||||
This is a migrated version of the original modlist tasks menu that uses backend services
|
||||
directly instead of subprocess calls to jackify-cli.py.
|
||||
|
||||
Key changes:
|
||||
- Uses backend services directly instead of subprocess.Popen()
|
||||
- Direct backend service integration
|
||||
- Maintains same UI and workflow
|
||||
- Improved error handling and progress reporting
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||
QGridLayout, QSizePolicy, QApplication, QFrame, QMessageBox
|
||||
)
|
||||
from PySide6.QtCore import Qt, QThread, Signal, QTimer
|
||||
from PySide6.QtGui import QFont, QPalette, QColor, QPixmap
|
||||
|
||||
# Import our GUI services
|
||||
from jackify.backend.models.configuration import SystemInfo
|
||||
from ..shared_theme import JACKIFY_COLOR_BLUE
|
||||
|
||||
# Constants
|
||||
DEBUG_BORDERS = False
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ModlistTasksScreen(QWidget):
|
||||
"""
|
||||
Migrated Modlist Tasks screen that uses backend services directly.
|
||||
|
||||
This replaces the original ModlistTasksMenu's subprocess calls with
|
||||
direct navigation to existing automated workflows.
|
||||
"""
|
||||
|
||||
def __init__(self, stacked_widget=None, main_menu_index=0, system_info: Optional[SystemInfo] = None, dev_mode=False):
|
||||
super().__init__()
|
||||
logger.info("ModlistTasksScreen initializing (migrated version)")
|
||||
|
||||
self.stacked_widget = stacked_widget
|
||||
self.main_menu_index = main_menu_index
|
||||
self.debug = DEBUG_BORDERS
|
||||
self.dev_mode = dev_mode
|
||||
|
||||
# Initialize backend services
|
||||
if system_info is None:
|
||||
system_info = SystemInfo(is_steamdeck=self._is_steamdeck())
|
||||
self.system_info = system_info
|
||||
|
||||
# Setup UI
|
||||
self._setup_ui()
|
||||
|
||||
logger.info("ModlistTasksScreen initialized (migrated version)")
|
||||
|
||||
def _is_steamdeck(self) -> bool:
|
||||
"""Check if running on Steam Deck"""
|
||||
try:
|
||||
if os.path.exists("/etc/os-release"):
|
||||
with open("/etc/os-release", "r") as f:
|
||||
content = f.read()
|
||||
if "steamdeck" in content:
|
||||
return True
|
||||
return False
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Set up the user interface"""
|
||||
main_layout = QVBoxLayout(self)
|
||||
main_layout.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
|
||||
main_layout.setContentsMargins(50, 50, 50, 50)
|
||||
|
||||
if self.debug:
|
||||
self.setStyleSheet("border: 2px solid green;")
|
||||
|
||||
# Header section
|
||||
self._setup_header(main_layout)
|
||||
|
||||
# Menu buttons section
|
||||
self._setup_menu_buttons(main_layout)
|
||||
|
||||
# Bottom navigation
|
||||
self._setup_navigation(main_layout)
|
||||
|
||||
def _setup_header(self, layout):
|
||||
"""Set up the header section"""
|
||||
header_layout = QVBoxLayout()
|
||||
header_layout.setSpacing(2)
|
||||
|
||||
# Title
|
||||
title = QLabel("<b>Modlist Tasks</b>")
|
||||
title.setStyleSheet(f"font-size: 24px; color: {JACKIFY_COLOR_BLUE};")
|
||||
title.setAlignment(Qt.AlignHCenter)
|
||||
header_layout.addWidget(title)
|
||||
|
||||
# Add a spacer to match main menu vertical spacing
|
||||
header_layout.addSpacing(16)
|
||||
|
||||
# Description
|
||||
desc = QLabel(
|
||||
"Manage your modlists with native Linux tools. Choose "
|
||||
"from the options below to install or configure modlists.<br> "
|
||||
)
|
||||
desc.setWordWrap(True)
|
||||
desc.setStyleSheet("color: #ccc;")
|
||||
desc.setAlignment(Qt.AlignHCenter)
|
||||
header_layout.addWidget(desc)
|
||||
|
||||
header_layout.addSpacing(24)
|
||||
|
||||
# Separator
|
||||
sep = QLabel()
|
||||
sep.setFixedHeight(2)
|
||||
sep.setStyleSheet("background: #fff;")
|
||||
header_layout.addWidget(sep)
|
||||
|
||||
header_layout.addSpacing(16)
|
||||
layout.addLayout(header_layout)
|
||||
|
||||
def _setup_menu_buttons(self, layout):
|
||||
"""Set up the menu buttons section"""
|
||||
# Menu options
|
||||
MENU_ITEMS = [
|
||||
("Install a Modlist (Automated)", "install_modlist", "Download and install modlists automatically"),
|
||||
("Configure New Modlist (Post-Download)", "configure_new_modlist", "Configure a newly downloaded modlist"),
|
||||
("Configure Existing Modlist (In Steam)", "configure_existing_modlist", "Reconfigure an existing Steam modlist"),
|
||||
]
|
||||
if self.dev_mode:
|
||||
MENU_ITEMS.append(("Install Wabbajack Application", "install_wabbajack", "Set up the Wabbajack application"))
|
||||
MENU_ITEMS.append(("Return to Main Menu", "return_main_menu", "Go back to the main menu"))
|
||||
|
||||
# Create grid layout for buttons
|
||||
button_grid = QGridLayout()
|
||||
button_grid.setSpacing(16)
|
||||
button_grid.setAlignment(Qt.AlignHCenter)
|
||||
|
||||
button_width = 400
|
||||
button_height = 50
|
||||
|
||||
for i, (label, action_id, description) in enumerate(MENU_ITEMS):
|
||||
# Create button
|
||||
btn = QPushButton(label)
|
||||
btn.setFixedSize(button_width, button_height)
|
||||
btn.setStyleSheet(f"""
|
||||
QPushButton {{
|
||||
background-color: #4a5568;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}}
|
||||
QPushButton:hover {{
|
||||
background-color: #5a6578;
|
||||
}}
|
||||
QPushButton:pressed {{
|
||||
background-color: {JACKIFY_COLOR_BLUE};
|
||||
}}
|
||||
""")
|
||||
btn.clicked.connect(lambda checked, a=action_id: self.menu_action(a))
|
||||
|
||||
# Create description label
|
||||
desc_label = QLabel(description)
|
||||
desc_label.setAlignment(Qt.AlignHCenter)
|
||||
desc_label.setStyleSheet("color: #999; font-size: 12px;")
|
||||
desc_label.setWordWrap(True)
|
||||
desc_label.setFixedWidth(button_width)
|
||||
|
||||
# Add to grid
|
||||
button_grid.addWidget(btn, i * 2, 0, Qt.AlignHCenter)
|
||||
button_grid.addWidget(desc_label, i * 2 + 1, 0, Qt.AlignHCenter)
|
||||
|
||||
layout.addLayout(button_grid)
|
||||
|
||||
def _setup_navigation(self, layout):
|
||||
"""Set up the navigation section"""
|
||||
# Remove the bottom navigation bar entirely (no gray Back to Main Menu button)
|
||||
pass
|
||||
|
||||
def menu_action(self, action_id):
|
||||
"""Handle menu button clicks"""
|
||||
logger.info(f"Modlist tasks menu action: {action_id}")
|
||||
|
||||
if not self.stacked_widget:
|
||||
return
|
||||
|
||||
# Navigate to different screens based on action
|
||||
if action_id == "return_main_menu":
|
||||
self.stacked_widget.setCurrentIndex(0)
|
||||
elif action_id == "install_modlist":
|
||||
self.stacked_widget.setCurrentIndex(4)
|
||||
elif action_id == "configure_new_modlist":
|
||||
self.stacked_widget.setCurrentIndex(5)
|
||||
elif action_id == "configure_existing_modlist":
|
||||
self.stacked_widget.setCurrentIndex(6)
|
||||
|
||||
def go_back(self):
|
||||
"""Return to main menu"""
|
||||
if self.stacked_widget:
|
||||
self.stacked_widget.setCurrentIndex(self.main_menu_index)
|
||||
|
||||
def cleanup(self):
|
||||
"""Clean up resources when the screen is closed"""
|
||||
pass
|
||||
Reference in New Issue
Block a user