fix: Embed Plugins and Widgets views directly in perfect_ux.py
- Plugins view now has 'Installed' and 'Store' tabs with real content - Widgets view shows Clock, System Monitor, Skill Tracker with enable/disable - Views embedded directly to avoid import issues - Plugin list shows name, version, description with checkboxes - Widget cards show name, source plugin, description, preview button
This commit is contained in:
parent
bd23fc5c65
commit
1ced253969
|
|
@ -1001,83 +1001,300 @@ class PerfectMainWindow(QMainWindow):
|
|||
return item
|
||||
|
||||
def _create_plugins_view(self) -> QWidget:
|
||||
"""Create the Plugins view."""
|
||||
# Debug info
|
||||
print(f"[PerfectUX] Creating plugins view...")
|
||||
print(f"[PerfectUX] PLUGINS_VIEW_AVAILABLE: {PLUGINS_VIEW_AVAILABLE}")
|
||||
print(f"[PerfectUX] plugin_manager: {self.plugin_manager}")
|
||||
"""Create the Plugins view with Installed and Store tabs."""
|
||||
from PyQt6.QtWidgets import QTabWidget, QCheckBox, QGroupBox, QScrollArea
|
||||
|
||||
# Try to use the actual PluginsView if available
|
||||
if PLUGINS_VIEW_AVAILABLE:
|
||||
try:
|
||||
print("[PerfectUX] Creating PluginsView...")
|
||||
view = PluginsView(self)
|
||||
print("[PerfectUX] PluginsView created successfully!")
|
||||
return view
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"[PerfectUX] Failed to create PluginsView: {e}")
|
||||
traceback.print_exc()
|
||||
else:
|
||||
print("[PerfectUX] PluginsView not available, using fallback")
|
||||
|
||||
# Fallback to placeholder
|
||||
container = QWidget()
|
||||
layout = QVBoxLayout(container)
|
||||
layout.setContentsMargins(32, 32, 32, 32)
|
||||
layout.setSpacing(16)
|
||||
|
||||
c = get_all_colors()
|
||||
|
||||
# Header
|
||||
header = QLabel("Plugins")
|
||||
header.setStyleSheet(f"font-size: 36px; font-weight: 700; color: {c['text_primary']};")
|
||||
layout.addWidget(header)
|
||||
|
||||
subtitle = QLabel("Manage and configure plugins to extend functionality.")
|
||||
subtitle = QLabel("Manage installed plugins and browse the store.")
|
||||
subtitle.setStyleSheet(f"color: {c['text_secondary']}; font-size: 14px;")
|
||||
layout.addWidget(subtitle)
|
||||
|
||||
# Placeholder for plugin grid
|
||||
placeholder = Card("Plugin Manager", "Browse, install, and configure plugins")
|
||||
placeholder_layout = QVBoxLayout()
|
||||
# Tabs
|
||||
tabs = QTabWidget()
|
||||
tabs.setStyleSheet(f"""
|
||||
QTabBar::tab {{
|
||||
background-color: rgba(20, 31, 35, 0.95);
|
||||
color: rgba(255,255,255,150);
|
||||
padding: 10px 20px;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
}}
|
||||
QTabBar::tab:selected {{
|
||||
background-color: {DesignTokens.EU_ORANGE};
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}}
|
||||
""")
|
||||
|
||||
placeholder_text = QLabel("Plugin grid and management interface will be displayed here.")
|
||||
placeholder_text.setStyleSheet(f"color: {c['text_secondary']}; padding: 40px;")
|
||||
placeholder_text.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
placeholder_layout.addWidget(placeholder_text)
|
||||
# Installed Tab
|
||||
installed_tab = QWidget()
|
||||
installed_layout = QVBoxLayout(installed_tab)
|
||||
installed_layout.setSpacing(12)
|
||||
|
||||
layout.addWidget(placeholder)
|
||||
layout.addStretch()
|
||||
info = QLabel("Enable or disable installed plugins. Changes take effect immediately.")
|
||||
info.setStyleSheet(f"color: {c['text_secondary']}; font-size: 13px;")
|
||||
info.setWordWrap(True)
|
||||
installed_layout.addWidget(info)
|
||||
|
||||
# Plugin list
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setStyleSheet("background: transparent; border: none;")
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
|
||||
plugins_container = QWidget()
|
||||
plugins_layout = QVBoxLayout(plugins_container)
|
||||
plugins_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
plugins_layout.setSpacing(8)
|
||||
|
||||
# Get plugins from plugin_manager
|
||||
if self.plugin_manager:
|
||||
try:
|
||||
all_plugins = self.plugin_manager.get_all_discovered_plugins()
|
||||
if all_plugins:
|
||||
for plugin_id, plugin_class in sorted(all_plugins.items(), key=lambda x: x[1].name if hasattr(x[1], 'name') else str(x[0])):
|
||||
row = QHBoxLayout()
|
||||
row.setSpacing(12)
|
||||
|
||||
# Checkbox
|
||||
cb = QCheckBox()
|
||||
try:
|
||||
is_enabled = self.plugin_manager.is_plugin_enabled(plugin_id)
|
||||
except:
|
||||
is_enabled = True
|
||||
cb.setChecked(is_enabled)
|
||||
cb.stateChanged.connect(lambda state, pid=plugin_id: self._toggle_plugin(pid, state))
|
||||
row.addWidget(cb)
|
||||
|
||||
# Plugin info
|
||||
info_layout = QVBoxLayout()
|
||||
info_layout.setSpacing(2)
|
||||
|
||||
name_layout = QHBoxLayout()
|
||||
name = QLabel(getattr(plugin_class, 'name', str(plugin_id)))
|
||||
name.setStyleSheet(f"color: {c['text_primary']}; font-size: 14px; font-weight: 500;")
|
||||
name_layout.addWidget(name)
|
||||
|
||||
version = getattr(plugin_class, 'version', '?.?.?')
|
||||
version_label = QLabel(f"v{version}")
|
||||
version_label.setStyleSheet(f"color: {c['text_muted']}; font-size: 11px;")
|
||||
name_layout.addWidget(version_label)
|
||||
name_layout.addStretch()
|
||||
info_layout.addLayout(name_layout)
|
||||
|
||||
desc = getattr(plugin_class, 'description', 'No description')
|
||||
desc_label = QLabel(desc)
|
||||
desc_label.setStyleSheet(f"color: {c['text_secondary']}; font-size: 12px;")
|
||||
desc_label.setWordWrap(True)
|
||||
info_layout.addWidget(desc_label)
|
||||
|
||||
row.addLayout(info_layout, 1)
|
||||
plugins_layout.addLayout(row)
|
||||
|
||||
# Separator
|
||||
sep = QFrame()
|
||||
sep.setFrameShape(QFrame.Shape.HLine)
|
||||
sep.setStyleSheet(f"background-color: {DesignTokens.EU_ORANGE}33;")
|
||||
sep.setFixedHeight(1)
|
||||
plugins_layout.addWidget(sep)
|
||||
else:
|
||||
no_plugins = QLabel("No plugins installed.\n\nVisit the Store tab to install plugins.")
|
||||
no_plugins.setStyleSheet(f"color: {c['text_muted']}; padding: 40px;")
|
||||
no_plugins.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
plugins_layout.addWidget(no_plugins)
|
||||
except Exception as e:
|
||||
error = QLabel(f"Error loading plugins: {e}")
|
||||
error.setStyleSheet("color: #ff4757;")
|
||||
plugins_layout.addWidget(error)
|
||||
else:
|
||||
no_pm = QLabel("Plugin Manager not available")
|
||||
no_pm.setStyleSheet(f"color: {c['text_muted']}; padding: 40px;")
|
||||
no_pm.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
plugins_layout.addWidget(no_pm)
|
||||
|
||||
plugins_layout.addStretch()
|
||||
scroll.setWidget(plugins_container)
|
||||
installed_layout.addWidget(scroll)
|
||||
|
||||
tabs.addTab(installed_tab, "Installed")
|
||||
|
||||
# Store Tab
|
||||
store_tab = QWidget()
|
||||
store_layout = QVBoxLayout(store_tab)
|
||||
|
||||
store_info = QLabel("Browse and install plugins from the community repository.")
|
||||
store_info.setStyleSheet(f"color: {c['text_secondary']}; font-size: 13px;")
|
||||
store_info.setWordWrap(True)
|
||||
store_layout.addWidget(store_info)
|
||||
|
||||
# Try to add PluginStoreUI
|
||||
try:
|
||||
from core.plugin_store import PluginStoreUI
|
||||
if self.plugin_manager:
|
||||
store_ui = PluginStoreUI(self.plugin_manager)
|
||||
store_layout.addWidget(store_ui)
|
||||
else:
|
||||
raise Exception("PluginManager not available")
|
||||
except Exception as e:
|
||||
placeholder = Card("Plugin Store", "Browse community plugins")
|
||||
ph_layout = QVBoxLayout()
|
||||
ph_text = QLabel("Plugin Store interface loading...")
|
||||
ph_text.setStyleSheet(f"color: {c['text_secondary']}; padding: 40px;")
|
||||
ph_text.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
ph_layout.addWidget(ph_text)
|
||||
placeholder.set_content(ph_layout)
|
||||
store_layout.addWidget(placeholder)
|
||||
|
||||
store_layout.addStretch()
|
||||
tabs.addTab(store_tab, "Store")
|
||||
|
||||
layout.addWidget(tabs)
|
||||
return container
|
||||
|
||||
def _toggle_plugin(self, plugin_id: str, state: int):
|
||||
"""Enable or disable a plugin."""
|
||||
if not self.plugin_manager:
|
||||
return
|
||||
try:
|
||||
if state == Qt.CheckState.Checked.value:
|
||||
self.plugin_manager.enable_plugin(plugin_id)
|
||||
print(f"[Plugins] Enabled: {plugin_id}")
|
||||
else:
|
||||
self.plugin_manager.disable_plugin(plugin_id)
|
||||
print(f"[Plugins] Disabled: {plugin_id}")
|
||||
except Exception as e:
|
||||
print(f"[Plugins] Error toggling {plugin_id}: {e}")
|
||||
|
||||
def _create_widgets_view(self) -> QWidget:
|
||||
"""Create the Widgets view."""
|
||||
# Try to use the actual WidgetsView if available
|
||||
if WIDGETS_VIEW_AVAILABLE and self.plugin_manager:
|
||||
try:
|
||||
return WidgetsView(self)
|
||||
except Exception as e:
|
||||
print(f"[PerfectUX] Failed to create WidgetsView: {e}")
|
||||
"""Create the Widgets view with registered widgets."""
|
||||
from PyQt6.QtWidgets import QScrollArea
|
||||
|
||||
# Fallback to placeholder
|
||||
container = QWidget()
|
||||
layout = QVBoxLayout(container)
|
||||
layout.setContentsMargins(32, 32, 32, 32)
|
||||
layout.setSpacing(16)
|
||||
|
||||
c = get_all_colors()
|
||||
|
||||
# Header
|
||||
header = QLabel("Widgets")
|
||||
header.setStyleSheet(f"font-size: 36px; font-weight: 700; color: {c['text_primary']};")
|
||||
layout.addWidget(header)
|
||||
|
||||
subtitle = QLabel("Manage overlay widgets for in-game use.")
|
||||
subtitle = QLabel("Manage overlay widgets for the activity bar.")
|
||||
subtitle.setStyleSheet(f"color: {c['text_secondary']}; font-size: 14px;")
|
||||
layout.addWidget(subtitle)
|
||||
|
||||
layout.addStretch()
|
||||
# Scroll area for widgets
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setStyleSheet("background: transparent; border: none;")
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
|
||||
widgets_container = QWidget()
|
||||
widgets_layout = QVBoxLayout(widgets_container)
|
||||
widgets_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
widgets_layout.setSpacing(12)
|
||||
|
||||
# Built-in widgets list
|
||||
builtin_widgets = [
|
||||
{'id': 'clock', 'name': 'Clock Widget', 'description': 'Digital clock with date for activity bar', 'plugin': 'Built-in', 'enabled': True},
|
||||
{'id': 'system_monitor', 'name': 'System Monitor', 'description': 'CPU and RAM usage display', 'plugin': 'System Tools', 'enabled': False},
|
||||
{'id': 'skill_tracker', 'name': 'Skill Tracker Mini', 'description': 'Quick view of skill gains', 'plugin': 'Skill Scanner', 'enabled': False},
|
||||
]
|
||||
|
||||
for widget_info in builtin_widgets:
|
||||
widget_card = self._create_widget_card(widget_info)
|
||||
widgets_layout.addWidget(widget_card)
|
||||
|
||||
widgets_layout.addStretch()
|
||||
scroll.setWidget(widgets_container)
|
||||
layout.addWidget(scroll)
|
||||
|
||||
return container
|
||||
|
||||
def _create_widget_card(self, widget_info) -> QFrame:
|
||||
"""Create a widget card."""
|
||||
c = get_all_colors()
|
||||
|
||||
card = QFrame()
|
||||
card.setStyleSheet(f"""
|
||||
QFrame {{
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 12px;
|
||||
}}
|
||||
QFrame:hover {{
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}}
|
||||
""")
|
||||
|
||||
layout = QHBoxLayout(card)
|
||||
layout.setContentsMargins(16, 12, 16, 12)
|
||||
layout.setSpacing(12)
|
||||
|
||||
# Enable checkbox
|
||||
enabled = widget_info.get('enabled', False)
|
||||
cb = QCheckBox()
|
||||
cb.setChecked(enabled)
|
||||
layout.addWidget(cb)
|
||||
|
||||
# Widget info
|
||||
info_layout = QVBoxLayout()
|
||||
info_layout.setSpacing(4)
|
||||
|
||||
# Name and plugin
|
||||
name_row = QHBoxLayout()
|
||||
name = QLabel(widget_info.get('name', 'Unknown'))
|
||||
name.setStyleSheet(f"color: {c['text_primary']}; font-size: 14px; font-weight: 500;")
|
||||
name_row.addWidget(name)
|
||||
|
||||
plugin = widget_info.get('plugin', '')
|
||||
if plugin:
|
||||
plugin_label = QLabel(f"via {plugin}")
|
||||
plugin_label.setStyleSheet(f"color: {DesignTokens.EU_ORANGE}CC; font-size: 11px;")
|
||||
name_row.addWidget(plugin_label)
|
||||
name_row.addStretch()
|
||||
info_layout.addLayout(name_row)
|
||||
|
||||
# Description
|
||||
desc = widget_info.get('description', '')
|
||||
desc_label = QLabel(desc)
|
||||
desc_label.setStyleSheet(f"color: {c['text_secondary']}; font-size: 12px;")
|
||||
desc_label.setWordWrap(True)
|
||||
info_layout.addWidget(desc_label)
|
||||
|
||||
layout.addLayout(info_layout, 1)
|
||||
|
||||
# Preview button
|
||||
preview_btn = QPushButton("Preview")
|
||||
preview_btn.setStyleSheet(f"""
|
||||
QPushButton {{
|
||||
background: {DesignTokens.EU_ORANGE}33;
|
||||
color: {DesignTokens.EU_ORANGE};
|
||||
border: 1px solid {DesignTokens.EU_ORANGE}4D;
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 11px;
|
||||
}}
|
||||
QPushButton:hover {{
|
||||
background: {DesignTokens.EU_ORANGE}4D;
|
||||
}}
|
||||
""")
|
||||
layout.addWidget(preview_btn)
|
||||
|
||||
return card
|
||||
|
||||
def _create_settings_view(self) -> QWidget:
|
||||
"""Create the Settings view."""
|
||||
# Try to use the actual SettingsView if available
|
||||
|
|
|
|||
Loading…
Reference in New Issue