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:
arch_agent
2026-07-19 16:12:50 +02:00
parent bfcab791c9
commit 3f48ac5fb0
+77 -6
View File
@@ -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: