feat: Redesign Plugins Settings tab with categorization

IMPROVED PLUGINS SETTINGS UI:

1. Visual Improvements:
   - Added header with plugin management info
   - Added color-coded legend (Core/Test/Other)
   - Styled plugin rows with hover effects
   - Version badges with orange accent color
   - Scrollable plugin list for large numbers
   - Better spacing and visual hierarchy

2. Plugin Categorization:
   - Core Plugins (teal): skill_scanner, loot_tracker, mining_helper,
     chat_logger, global_tracker, nexus_search, universal_search,
     calculator, settings, dashboard
   - Test Plugins (orange): game_reader_test, log_parser_test
   - Other Plugins (gray): All remaining plugins

3. Naming Convention:
   - Core plugins prefixed with 'Core-'
   - Test plugins prefixed with 'Test-'
   - Other plugins have no prefix

4. Technical Changes:
   - Added QScrollArea import
   - New _add_plugin_row() helper method
   - Grouped plugins by category
   - Styled checkboxes with EU theme
   - Added author attribution display
This commit is contained in:
LemonNexus 2026-02-14 19:14:22 +00:00
parent 219d0847b2
commit db0eb5bf65
1 changed files with 234 additions and 36 deletions

View File

@ -18,7 +18,8 @@ try:
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QStackedWidget, QSystemTrayIcon, QLabel, QPushButton, QStackedWidget, QSystemTrayIcon,
QMenu, QApplication, QFrame, QListWidget, QListWidgetItem, QMenu, QApplication, QFrame, QListWidget, QListWidgetItem,
QButtonGroup, QSplitter, QSizePolicy, QCheckBox, QTabWidget QButtonGroup, QSplitter, QSizePolicy, QCheckBox, QTabWidget,
QScrollArea
) )
from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QSize, QPropertyAnimation, QEasingCurve, QParallelAnimationGroup from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QSize, QPropertyAnimation, QEasingCurve, QParallelAnimationGroup
from PyQt6.QtGui import QAction, QIcon, QColor, QFont, QKeySequence, QShortcut from PyQt6.QtGui import QAction, QIcon, QColor, QFont, QKeySequence, QShortcut
@ -751,59 +752,256 @@ class OverlayWindow(QMainWindow):
dialog.exec() dialog.exec()
def _create_plugins_settings_tab(self) -> QWidget: def _create_plugins_settings_tab(self) -> QWidget:
"""Create plugins settings tab.""" """Create plugins settings tab with improved UI and categorization."""
c = get_all_colors() c = get_all_colors()
tab = QWidget() tab = QWidget()
layout = QVBoxLayout(tab) layout = QVBoxLayout(tab)
layout.setSpacing(16) layout.setSpacing(16)
layout.setContentsMargins(16, 16, 16, 16)
info = QLabel("Enable or disable plugins:") # Header with info
info.setStyleSheet(f"color: {c['text_secondary']};") header_frame = QFrame()
layout.addWidget(info) header_frame.setStyleSheet(f"""
QFrame {{
background-color: {c['bg_secondary']};
border-left: 3px solid {c['accent_primary']};
border-radius: 4px;
padding: 12px;
}}
""")
header_layout = QVBoxLayout(header_frame)
header_layout.setSpacing(4)
# Plugin list info_title = QLabel("Plugin Management")
info_title.setStyleSheet(f"color: {c['text_primary']}; font-weight: bold; font-size: 13px;")
header_layout.addWidget(info_title)
info_desc = QLabel("Enable or disable plugins. Changes take effect after restarting the overlay.")
info_desc.setStyleSheet(f"color: {c['text_secondary']}; font-size: 11px;")
info_desc.setWordWrap(True)
header_layout.addWidget(info_desc)
layout.addWidget(header_frame)
# Legend
legend_frame = QFrame()
legend_layout = QHBoxLayout(legend_frame)
legend_layout.setSpacing(16)
core_label = QLabel("● Core")
core_label.setStyleSheet("color: #4ecdc4; font-size: 11px; font-weight: bold;")
legend_layout.addWidget(core_label)
test_label = QLabel("● Test")
test_label.setStyleSheet("color: #ff8c42; font-size: 11px; font-weight: bold;")
legend_layout.addWidget(test_label)
other_label = QLabel("● Other")
other_label.setStyleSheet("color: #a0aec0; font-size: 11px;")
legend_layout.addWidget(other_label)
legend_layout.addStretch()
layout.addWidget(legend_frame)
# Plugin list container
self.settings_checkboxes = {} self.settings_checkboxes = {}
if self.plugin_manager: if self.plugin_manager:
all_plugins = self.plugin_manager.get_all_discovered_plugins() all_plugins = self.plugin_manager.get_all_discovered_plugins()
# Sort by name with error handling # Categorize plugins
def get_plugin_name(item): core_plugins = []
try: test_plugins = []
return getattr(item[1], 'name', item[0]) other_plugins = []
except:
return item[0]
sorted_plugins = sorted(all_plugins.items(), key=get_plugin_name) for plugin_id, plugin_class in all_plugins.items():
for plugin_id, plugin_class in sorted_plugins:
try: try:
row = QHBoxLayout()
# Safely get plugin attributes
name = getattr(plugin_class, 'name', plugin_id.split('.')[-1]) name = getattr(plugin_class, 'name', plugin_id.split('.')[-1])
version = getattr(plugin_class, 'version', '?.?.?') if 'test' in plugin_id.lower() or name.lower().endswith('test'):
description = getattr(plugin_class, 'description', 'No description') test_plugins.append((plugin_id, plugin_class))
elif plugin_id.startswith(('core.', 'plugins.skill_scanner', 'plugins.loot_tracker',
cb = QCheckBox(f"{name} (v{version})") 'plugins.mining_helper', 'plugins.chat_logger',
cb.setChecked(self.plugin_manager.is_plugin_enabled(plugin_id)) 'plugins.global_tracker', 'plugins.nexus_search',
cb.setStyleSheet(f"color: {c['text_primary']};") 'plugins.universal_search', 'plugins.calculator',
self.settings_checkboxes[plugin_id] = cb 'plugins.settings', 'plugins.dashboard')):
row.addWidget(cb) core_plugins.append((plugin_id, plugin_class))
else:
desc = QLabel(description) other_plugins.append((plugin_id, plugin_class))
desc.setStyleSheet(f"color: {c['text_muted']}; font-size: {EU_TYPOGRAPHY['size_xs']};") except:
row.addWidget(desc, 1) other_plugins.append((plugin_id, plugin_class))
layout.addLayout(row) # Sort each category
except Exception as e: def get_name(item):
print(f"[Overlay] Error creating settings for {plugin_id}: {e}") try:
continue return getattr(item[1], 'name', item[0]).lower()
except:
return item[0].lower()
core_plugins.sort(key=get_name)
test_plugins.sort(key=get_name)
other_plugins.sort(key=get_name)
# Create scroll area for plugins
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameShape(QFrame.Shape.NoFrame)
scroll.setStyleSheet(f"""
QScrollArea {{
background-color: transparent;
border: none;
}}
QScrollBar:vertical {{
background-color: {c['bg_secondary']};
width: 10px;
border-radius: 5px;
}}
QScrollBar::handle:vertical {{
background-color: {c['accent_primary']};
border-radius: 5px;
min-height: 30px;
}}
""")
plugins_container = QWidget()
plugins_layout = QVBoxLayout(plugins_container)
plugins_layout.setSpacing(8)
plugins_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
# Add Core Plugins section
if core_plugins:
core_header = QLabel("CORE PLUGINS")
core_header.setStyleSheet(f"""
color: #4ecdc4;
font-weight: bold;
font-size: 10px;
padding: 8px 4px 4px 4px;
border-bottom: 1px solid {c['border_color']};
""")
plugins_layout.addWidget(core_header)
for plugin_id, plugin_class in core_plugins:
self._add_plugin_row(plugins_layout, plugin_id, plugin_class, c, "Core")
# Add Test Plugins section
if test_plugins:
test_header = QLabel("TEST PLUGINS")
test_header.setStyleSheet(f"""
color: #ff8c42;
font-weight: bold;
font-size: 10px;
padding: 16px 4px 4px 4px;
border-bottom: 1px solid {c['border_color']};
""")
plugins_layout.addWidget(test_header)
for plugin_id, plugin_class in test_plugins:
self._add_plugin_row(plugins_layout, plugin_id, plugin_class, c, "Test")
# Add Other Plugins section
if other_plugins:
other_header = QLabel("OTHER PLUGINS")
other_header.setStyleSheet(f"""
color: {c['text_muted']};
font-weight: bold;
font-size: 10px;
padding: 16px 4px 4px 4px;
border-bottom: 1px solid {c['border_color']};
""")
plugins_layout.addWidget(other_header)
for plugin_id, plugin_class in other_plugins:
self._add_plugin_row(plugins_layout, plugin_id, plugin_class, c, None)
plugins_layout.addStretch()
scroll.setWidget(plugins_container)
layout.addWidget(scroll, 1) # Stretch factor 1
layout.addStretch()
return tab return tab
def _add_plugin_row(self, layout, plugin_id, plugin_class, colors, prefix):
"""Add a plugin row to the layout."""
try:
row_widget = QFrame()
row_widget.setStyleSheet(f"""
QFrame {{
background-color: {colors['bg_secondary']};
border-radius: 4px;
padding: 2px;
}}
QFrame:hover {{
background-color: {colors['bg_hover']};
}}
""")
row_layout = QHBoxLayout(row_widget)
row_layout.setSpacing(12)
row_layout.setContentsMargins(10, 8, 10, 8)
# Get plugin attributes
name = getattr(plugin_class, 'name', plugin_id.split('.')[-1])
version = getattr(plugin_class, 'version', '?.?.?')
description = getattr(plugin_class, 'description', 'No description')
author = getattr(plugin_class, 'author', 'Unknown')
# Add prefix to name
display_name = f"{prefix}-{name}" if prefix else name
# Checkbox
cb = QCheckBox(f"{display_name}")
cb.setChecked(self.plugin_manager.is_plugin_enabled(plugin_id))
cb.setStyleSheet(f"""
QCheckBox {{
color: {colors['text_primary']};
font-weight: bold;
spacing: 8px;
}}
QCheckBox::indicator {{
width: 16px;
height: 16px;
border-radius: 3px;
border: 2px solid {colors['accent_primary']};
}}
QCheckBox::indicator:checked {{
background-color: {colors['accent_primary']};
}}
""")
self.settings_checkboxes[plugin_id] = cb
row_layout.addWidget(cb)
# Version badge
version_label = QLabel(f"v{version}")
version_label.setStyleSheet(f"""
color: {colors['accent_primary']};
font-size: 9px;
font-weight: bold;
background-color: {colors['bg_primary']};
padding: 2px 6px;
border-radius: 3px;
""")
row_layout.addWidget(version_label)
# Description
desc_label = QLabel(description)
desc_label.setStyleSheet(f"""
color: {colors['text_muted']};
font-size: 11px;
""")
desc_label.setWordWrap(True)
row_layout.addWidget(desc_label, 1)
# Author (small)
author_label = QLabel(f"by {author}")
author_label.setStyleSheet(f"""
color: {colors['text_secondary']};
font-size: 9px;
""")
row_layout.addWidget(author_label)
layout.addWidget(row_widget)
except Exception as e:
print(f"[Overlay] Error creating settings for {plugin_id}: {e}")
def _create_appearance_settings_tab(self) -> QWidget: def _create_appearance_settings_tab(self) -> QWidget:
"""Create appearance settings tab.""" """Create appearance settings tab."""
c = get_all_colors() c = get_all_colors()