v0.3: Enhanced Script Mods tab — grouped by mod name, file counts, toggle, context menu
- Script mods now grouped by mod name instead of flat file list - Shows file count per mod and category totals - Toggle button to enable/disable script mods - Right-click context menu for script mods - Info label showing total mods and files - Support for redscript, TweakXL, CET, red4ext, ArchiveXL
This commit is contained in:
+77
-6
@@ -856,11 +856,24 @@ class ModManagerWindow(QMainWindow):
|
||||
layout.addWidget(QLabel("📜 Script-based mods (redscript, TweakXL, CET, red4ext, ArchiveXL):"))
|
||||
|
||||
self.script_tree = QTreeWidget()
|
||||
self.script_tree.setHeaderLabels(["Type", "Path", "Status"])
|
||||
self.script_tree.setHeaderLabels(["Type", "Mod Name", "Path", "Files", "Status"])
|
||||
self.script_tree.setAlternatingRowColors(True)
|
||||
header = self.script_tree.header()
|
||||
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
||||
header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
|
||||
header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
||||
header.setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
|
||||
header.setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
|
||||
self.script_tree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||
self.script_tree.customContextMenuRequested.connect(self._script_context_menu)
|
||||
layout.addWidget(self.script_tree, 1)
|
||||
|
||||
# Add script mod button
|
||||
# Info label
|
||||
self.script_info_label = QLabel("Ready. Click Refresh to scan.")
|
||||
self.script_info_label.setStyleSheet("color: #888; font-size: 11px;")
|
||||
layout.addWidget(self.script_info_label)
|
||||
|
||||
# Buttons
|
||||
btn_layout = QHBoxLayout()
|
||||
add_script_btn = QPushButton("➕ Add Script Mod (.yaml, .reds, .zip, .7z)")
|
||||
add_script_btn.clicked.connect(self.add_script_mod)
|
||||
@@ -870,6 +883,10 @@ class ModManagerWindow(QMainWindow):
|
||||
refresh_script_btn.clicked.connect(self.refresh_script_mods)
|
||||
btn_layout.addWidget(refresh_script_btn)
|
||||
|
||||
toggle_script_btn = QPushButton("🔄 Toggle Selected")
|
||||
toggle_script_btn.clicked.connect(self._toggle_script_mod)
|
||||
btn_layout.addWidget(toggle_script_btn)
|
||||
|
||||
btn_layout.addStretch()
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
@@ -1113,23 +1130,77 @@ class ModManagerWindow(QMainWindow):
|
||||
"archivexl": "🗂️",
|
||||
}
|
||||
|
||||
total_mods = 0
|
||||
total_files = 0
|
||||
|
||||
for category, files in self.script_mods.items():
|
||||
if not files:
|
||||
continue
|
||||
|
||||
# Group by mod name (top-level folder or filename)
|
||||
mod_groups = {}
|
||||
for f in files:
|
||||
# Extract mod name from path
|
||||
path_parts = f.split("/")
|
||||
if category == "cet" and len(path_parts) >= 7:
|
||||
# bin/x64/plugins/cyber_engine_tweaks/mods/<modname>/...
|
||||
mod_name = path_parts[6]
|
||||
elif category == "red4ext" and len(path_parts) >= 3:
|
||||
# red4ext/plugins/<modname>/...
|
||||
mod_name = path_parts[2]
|
||||
elif category == "redscript" and len(path_parts) >= 3:
|
||||
# r6/scripts/<modname>/...
|
||||
mod_name = path_parts[2] if path_parts[2] != "r6" else path_parts[-1]
|
||||
elif category == "tweakxl" and len(path_parts) >= 3:
|
||||
# r6/tweaks/<modname>/...
|
||||
mod_name = path_parts[2] if path_parts[2] != "r6" else path_parts[-1]
|
||||
else:
|
||||
mod_name = path_parts[-1]
|
||||
|
||||
if mod_name not in mod_groups:
|
||||
mod_groups[mod_name] = []
|
||||
mod_groups[mod_name].append(f)
|
||||
|
||||
parent = QTreeWidgetItem()
|
||||
parent.setText(0, f"{icons.get(category, '📋')} {category.upper()}")
|
||||
parent.setText(2, f"{len(files)} items")
|
||||
parent.setText(1, f"{len(mod_groups)} mods")
|
||||
parent.setText(3, f"{len(files)} files")
|
||||
parent.setText(4, "✅ Active")
|
||||
parent.setForeground(0, QColor("#00ff9f"))
|
||||
parent.setForeground(4, QColor("#00ff9f"))
|
||||
parent.setExpanded(True)
|
||||
|
||||
for f in files:
|
||||
for mod_name, mod_files in sorted(mod_groups.items()):
|
||||
child = QTreeWidgetItem()
|
||||
child.setText(1, f)
|
||||
child.setText(2, "✅ Active")
|
||||
child.setText(1, mod_name)
|
||||
child.setText(3, str(len(mod_files)))
|
||||
|
||||
# Check if disabled (.disabled suffix on folder or file)
|
||||
is_disabled = any(".disabled" in f for f in mod_files)
|
||||
child.setText(4, "❌ Disabled" if is_disabled else "✅ Active")
|
||||
if is_disabled:
|
||||
child.setForeground(4, QColor("#ff0080"))
|
||||
else:
|
||||
child.setForeground(4, QColor("#00ff9f"))
|
||||
|
||||
child.setData(0, Qt.ItemDataRole.UserRole, {
|
||||
"category": category,
|
||||
"mod_name": mod_name,
|
||||
"files": mod_files,
|
||||
"disabled": is_disabled
|
||||
})
|
||||
|
||||
# Show first file as path hint
|
||||
child.setText(2, mod_files[0] if mod_files else "")
|
||||
|
||||
parent.addChild(child)
|
||||
total_mods += 1
|
||||
total_files += len(mod_files)
|
||||
|
||||
self.script_tree.addTopLevelItem(parent)
|
||||
parent.setExpanded(True)
|
||||
|
||||
self.script_info_label.setText(f"Total: {total_mods} mods, {total_files} files")
|
||||
|
||||
def _on_mod_checkbox_changed(self, item, column):
|
||||
if column != 0:
|
||||
|
||||
Reference in New Issue
Block a user