fix: UI improvements based on feedback
1. Sidebar toggle: Now uses arrows (chevron-right when collapsed, chevron-left when expanded) 2. Dashboard: Quick actions filtered to show only installed plugins 3. Plugins page: New tabs - 'Installed' (enable/disable plugins) and 'Store' (browse/install) 4. Widgets page: Now shows registered widgets from plugins with enable/disable 5. Settings page: Removed Plugin Store and My Plugins tabs (moved to Plugins page) 6. Settings: Changed 'Overlay Opacity' to 'Background Opacity' for clarity 7. Status bar: Shows plugin count, EU window status (Not Running/Running/Focused), version 8. New files: plugins_view.py, widgets_view.py with proper functionality
This commit is contained in:
parent
0f1c41b58d
commit
cfdf21ea6d
|
|
@ -62,6 +62,12 @@ try:
|
|||
except ImportError:
|
||||
PLUGINS_VIEW_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from core.ui.widgets_view import WidgetsView
|
||||
WIDGETS_VIEW_AVAILABLE = True
|
||||
except ImportError:
|
||||
WIDGETS_VIEW_AVAILABLE = False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# DESIGN TOKENS - Material Design 3 Inspired
|
||||
|
|
@ -381,12 +387,12 @@ class NavigationRail(QFrame):
|
|||
self.main_layout.setContentsMargins(0, 12, 0, 12)
|
||||
self.main_layout.setSpacing(0)
|
||||
|
||||
# Top toggle button
|
||||
# Top toggle button - use arrow pointing right when collapsed
|
||||
self.toggle_btn = QPushButton()
|
||||
self.toggle_btn.setFixedSize(56, 32)
|
||||
self.toggle_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
||||
self.toggle_btn.setToolTip("Expand sidebar")
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("menu"))
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("chevron-right")) # Arrow pointing right when collapsed
|
||||
self.toggle_btn.setIconSize(QSize(20, 20))
|
||||
self.toggle_btn.setStyleSheet(f"""
|
||||
QPushButton {{
|
||||
|
|
@ -429,13 +435,13 @@ class NavigationRail(QFrame):
|
|||
# Animate width change
|
||||
self._animate_width()
|
||||
|
||||
# Update toggle button icon
|
||||
# Update toggle button icon - use arrows instead of menu/close
|
||||
if self._expanded:
|
||||
self.toggle_btn.setToolTip("Collapse sidebar")
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("close")) # Or "collapse" icon
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("chevron-left")) # Arrow pointing left
|
||||
else:
|
||||
self.toggle_btn.setToolTip("Expand sidebar")
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("menu"))
|
||||
self.toggle_btn.setIcon(self.icon_manager.get_icon("chevron-right")) # Arrow pointing right
|
||||
|
||||
# Update all destinations to show/hide labels
|
||||
for dest in self.destinations:
|
||||
|
|
@ -1034,6 +1040,14 @@ class PerfectMainWindow(QMainWindow):
|
|||
|
||||
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}")
|
||||
|
||||
# Fallback to placeholder
|
||||
container = QWidget()
|
||||
layout = QVBoxLayout(container)
|
||||
layout.setContentsMargins(32, 32, 32, 32)
|
||||
|
|
@ -1081,7 +1095,7 @@ class PerfectMainWindow(QMainWindow):
|
|||
return container
|
||||
|
||||
def _create_status_bar(self):
|
||||
"""Create bottom status bar."""
|
||||
"""Create bottom status bar with useful info."""
|
||||
self.status_bar = QFrame()
|
||||
self.status_bar.setFixedHeight(32)
|
||||
self.status_bar.setStyleSheet("""
|
||||
|
|
@ -1094,17 +1108,61 @@ class PerfectMainWindow(QMainWindow):
|
|||
layout = QHBoxLayout(self.status_bar)
|
||||
layout.setContentsMargins(16, 0, 16, 0)
|
||||
|
||||
self.status_text = QLabel("Ready")
|
||||
self.status_text.setStyleSheet("color: rgba(255, 255, 255, 0.5); font-size: 12px;")
|
||||
layout.addWidget(self.status_text)
|
||||
# Left side - Plugin count
|
||||
try:
|
||||
plugin_count = len(self.plugin_manager.get_all_plugins()) if self.plugin_manager else 0
|
||||
except:
|
||||
plugin_count = 0
|
||||
|
||||
self.plugin_count_label = QLabel(f"{plugin_count} Plugins")
|
||||
self.plugin_count_label.setStyleSheet("color: rgba(255, 255, 255, 0.5); font-size: 12px;")
|
||||
layout.addWidget(self.plugin_count_label)
|
||||
|
||||
layout.addSpacing(20)
|
||||
|
||||
# Middle - EU Status
|
||||
self.eu_status_label = QLabel("EU: Not Running")
|
||||
self.eu_status_label.setStyleSheet("color: rgba(255, 255, 255, 0.4); font-size: 12px;")
|
||||
layout.addWidget(self.eu_status_label)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# Right side - Version
|
||||
self.version_text = QLabel("EU-Utility v2.2.0")
|
||||
self.version_text.setStyleSheet("color: rgba(255, 255, 255, 0.3); font-size: 11px;")
|
||||
layout.addWidget(self.version_text)
|
||||
|
||||
self.centralWidget().layout().addWidget(self.status_bar)
|
||||
|
||||
# Start EU status timer
|
||||
self._start_eu_status_timer()
|
||||
|
||||
def _start_eu_status_timer(self):
|
||||
"""Start timer to update EU status in status bar."""
|
||||
from PyQt6.QtCore import QTimer
|
||||
self._status_timer = QTimer(self)
|
||||
self._status_timer.timeout.connect(self._update_eu_status)
|
||||
self._status_timer.start(2000) # Update every 2 seconds
|
||||
|
||||
def _update_eu_status(self):
|
||||
"""Update EU status in status bar."""
|
||||
try:
|
||||
from core.window_manager import get_window_manager
|
||||
wm = get_window_manager()
|
||||
if wm and wm.is_available():
|
||||
eu_window = wm.find_eu_window()
|
||||
if eu_window:
|
||||
if eu_window.is_focused:
|
||||
self.eu_status_label.setText("EU: Focused")
|
||||
self.eu_status_label.setStyleSheet("color: #4ecca3; font-size: 12px;") # Green
|
||||
else:
|
||||
self.eu_status_label.setText("EU: Running")
|
||||
self.eu_status_label.setStyleSheet("color: #ffd93d; font-size: 12px;") # Yellow
|
||||
else:
|
||||
self.eu_status_label.setText("EU: Not Running")
|
||||
self.eu_status_label.setStyleSheet("color: rgba(255, 255, 255, 0.4); font-size: 12px;")
|
||||
except:
|
||||
pass
|
||||
|
||||
def _setup_shortcuts(self):
|
||||
"""Setup keyboard shortcuts."""
|
||||
|
|
@ -1125,7 +1183,11 @@ class PerfectMainWindow(QMainWindow):
|
|||
|
||||
if destination_id in view_map:
|
||||
self._animate_transition(view_map[destination_id])
|
||||
self.status_text.setText(f"View: {destination_id.title()}")
|
||||
# Update status bar view indicator
|
||||
if hasattr(self, 'plugin_count_label'):
|
||||
view_name = destination_id.replace('_', ' ').title()
|
||||
# Don't overwrite the plugin count, just update the view context
|
||||
# The status bar now shows plugins, EU status, and version
|
||||
|
||||
def _animate_transition(self, index: int):
|
||||
"""Animate view transition."""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,242 @@
|
|||
"""
|
||||
EU-Utility - Plugins View (Core Framework Component)
|
||||
|
||||
Built-in plugins interface with Installed and Store tabs.
|
||||
"""
|
||||
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QPushButton, QCheckBox, QTabWidget, QFrame,
|
||||
QScrollArea, QGridLayout, QSizePolicy
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from core.icon_manager import get_icon_manager
|
||||
|
||||
|
||||
class PluginsView(QWidget):
|
||||
"""Main plugins interface - built into the framework.
|
||||
|
||||
Features:
|
||||
- Installed tab: Manage installed plugins (enable/disable)
|
||||
- Store tab: Browse and install new plugins
|
||||
"""
|
||||
|
||||
def __init__(self, overlay_window, parent=None):
|
||||
super().__init__(parent)
|
||||
self.overlay = overlay_window
|
||||
self.plugin_manager = overlay_window.plugin_manager if hasattr(overlay_window, 'plugin_manager') else None
|
||||
self.icon_manager = get_icon_manager()
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Create the plugins UI."""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(16)
|
||||
layout.setContentsMargins(24, 24, 24, 24)
|
||||
|
||||
# Header with icon
|
||||
header_layout = QHBoxLayout()
|
||||
header_layout.setSpacing(12)
|
||||
|
||||
header_icon = QLabel()
|
||||
header_pixmap = self.icon_manager.get_pixmap("plugins", size=28)
|
||||
header_icon.setPixmap(header_pixmap)
|
||||
header_layout.addWidget(header_icon)
|
||||
|
||||
header = QLabel("Plugins")
|
||||
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
||||
header_layout.addWidget(header)
|
||||
header_layout.addStretch()
|
||||
|
||||
layout.addLayout(header_layout)
|
||||
|
||||
# Tabs - Installed and Store
|
||||
self.tabs = QTabWidget()
|
||||
self.tabs.setStyleSheet("""
|
||||
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: #ff8c42;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
|
||||
# Add tabs
|
||||
self.tabs.addTab(self._create_installed_tab(), "Installed")
|
||||
self.tabs.addTab(self._create_store_tab(), "Store")
|
||||
|
||||
layout.addWidget(self.tabs)
|
||||
|
||||
def _create_installed_tab(self):
|
||||
"""Create installed plugins tab."""
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
layout.setSpacing(16)
|
||||
|
||||
# Info label
|
||||
info = QLabel("Manage your installed plugins. Enable or disable as needed.")
|
||||
info.setStyleSheet("color: rgba(255,255,255,150); font-size: 13px;")
|
||||
info.setWordWrap(True)
|
||||
layout.addWidget(info)
|
||||
|
||||
# Scroll area for plugin list
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setStyleSheet("background: transparent; border: none;")
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
|
||||
self.installed_container = QWidget()
|
||||
self.installed_layout = QVBoxLayout(self.installed_container)
|
||||
self.installed_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
self.installed_layout.setSpacing(8)
|
||||
|
||||
self._populate_installed_plugins()
|
||||
|
||||
scroll.setWidget(self.installed_container)
|
||||
layout.addWidget(scroll)
|
||||
|
||||
return tab
|
||||
|
||||
def _populate_installed_plugins(self):
|
||||
"""Populate the installed plugins list."""
|
||||
# Clear existing
|
||||
while self.installed_layout.count():
|
||||
item = self.installed_layout.takeAt(0)
|
||||
if item.widget():
|
||||
item.widget().deleteLater()
|
||||
|
||||
if not self.plugin_manager:
|
||||
error = QLabel("Plugin Manager not available")
|
||||
error.setStyleSheet("color: #ff4757;")
|
||||
self.installed_layout.addWidget(error)
|
||||
return
|
||||
|
||||
# Get discovered plugins
|
||||
try:
|
||||
all_plugins = self.plugin_manager.get_all_discovered_plugins()
|
||||
except AttributeError:
|
||||
# Fallback - try different method
|
||||
try:
|
||||
all_plugins = {p.plugin_id: p for p in self.plugin_manager.plugins.values()}
|
||||
except:
|
||||
all_plugins = {}
|
||||
|
||||
if not all_plugins:
|
||||
no_plugins = QLabel("No plugins installed.\n\nVisit the Store tab to install plugins.")
|
||||
no_plugins.setStyleSheet("color: rgba(255,255,255,100); padding: 40px;")
|
||||
no_plugins.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.installed_layout.addWidget(no_plugins)
|
||||
return
|
||||
|
||||
# Sort by name
|
||||
sorted_plugins = sorted(all_plugins.items(), key=lambda x: x[1].name if hasattr(x[1], 'name') else str(x[0]))
|
||||
|
||||
for plugin_id, plugin_class in sorted_plugins:
|
||||
row = QHBoxLayout()
|
||||
row.setSpacing(12)
|
||||
|
||||
# Enable/Disable 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
|
||||
name = QLabel(getattr(plugin_class, 'name', str(plugin_id)))
|
||||
name.setStyleSheet("color: white; font-size: 14px; font-weight: 500;")
|
||||
name_layout.addWidget(name)
|
||||
|
||||
# Version
|
||||
version = getattr(plugin_class, 'version', '?.?.?')
|
||||
version_label = QLabel(f"v{version}")
|
||||
version_label.setStyleSheet("color: rgba(255,255,255,100); font-size: 11px;")
|
||||
name_layout.addWidget(version_label)
|
||||
name_layout.addStretch()
|
||||
|
||||
info_layout.addLayout(name_layout)
|
||||
|
||||
# Description
|
||||
desc = getattr(plugin_class, 'description', 'No description available')
|
||||
desc_label = QLabel(desc)
|
||||
desc_label.setStyleSheet("color: rgba(255,255,255,120); font-size: 12px;")
|
||||
desc_label.setWordWrap(True)
|
||||
info_layout.addWidget(desc_label)
|
||||
|
||||
row.addLayout(info_layout, 1)
|
||||
|
||||
self.installed_layout.addLayout(row)
|
||||
|
||||
# Separator
|
||||
sep = QFrame()
|
||||
sep.setFrameShape(QFrame.Shape.HLine)
|
||||
sep.setStyleSheet("background-color: rgba(255, 140, 66, 0.1);")
|
||||
sep.setFixedHeight(1)
|
||||
self.installed_layout.addWidget(sep)
|
||||
|
||||
self.installed_layout.addStretch()
|
||||
|
||||
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"[PluginsView] Enabled plugin: {plugin_id}")
|
||||
else:
|
||||
self.plugin_manager.disable_plugin(plugin_id)
|
||||
print(f"[PluginsView] Disabled plugin: {plugin_id}")
|
||||
except Exception as e:
|
||||
print(f"[PluginsView] Error toggling plugin {plugin_id}: {e}")
|
||||
|
||||
def _create_store_tab(self):
|
||||
"""Create plugin store tab."""
|
||||
try:
|
||||
from core.plugin_store import PluginStoreUI
|
||||
|
||||
if self.plugin_manager:
|
||||
return PluginStoreUI(self.plugin_manager)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Fallback
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
info = QLabel("Plugin Store")
|
||||
info.setStyleSheet("font-size: 18px; font-weight: bold; color: white;")
|
||||
layout.addWidget(info)
|
||||
|
||||
desc = QLabel("Browse and install plugins from the community repository.")
|
||||
desc.setStyleSheet("color: rgba(255,255,255,150);")
|
||||
desc.setWordWrap(True)
|
||||
layout.addWidget(desc)
|
||||
|
||||
# Placeholder
|
||||
placeholder = QLabel("Plugin Store interface will appear here.")
|
||||
placeholder.setStyleSheet("color: rgba(255,255,255,100); padding: 40px;")
|
||||
placeholder.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(placeholder)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
return tab
|
||||
|
|
@ -49,7 +49,7 @@ class SettingsView(QWidget):
|
|||
|
||||
layout.addLayout(header_layout)
|
||||
|
||||
# Tabs
|
||||
# Tabs - removed Plugin Store and My Plugins (moved to Plugins page)
|
||||
self.tabs = QTabWidget()
|
||||
self.tabs.setStyleSheet("""
|
||||
QTabBar::tab {
|
||||
|
|
@ -66,10 +66,8 @@ class SettingsView(QWidget):
|
|||
}
|
||||
""")
|
||||
|
||||
# Add tabs
|
||||
# Add tabs - Plugin Store and My Plugins moved to Plugins page
|
||||
self.tabs.addTab(self._create_general_tab(), "General")
|
||||
self.tabs.addTab(self._create_plugin_store_tab(), "Plugin Store")
|
||||
self.tabs.addTab(self._create_plugins_tab(), "My Plugins")
|
||||
self.tabs.addTab(self._create_hotkeys_tab(), "Hotkeys")
|
||||
self.tabs.addTab(self._create_data_tab(), "Data & Backup")
|
||||
self.tabs.addTab(self._create_updates_tab(), "Updates")
|
||||
|
|
@ -96,9 +94,9 @@ class SettingsView(QWidget):
|
|||
theme_layout.addStretch()
|
||||
appear_layout.addLayout(theme_layout)
|
||||
|
||||
# Opacity
|
||||
# Opacity - changed from "Overlay" to "Background"
|
||||
opacity_layout = QHBoxLayout()
|
||||
opacity_layout.addWidget(QLabel("Overlay Opacity:"))
|
||||
opacity_layout.addWidget(QLabel("Background Opacity:"))
|
||||
self.opacity_slider = QSlider(Qt.Orientation.Horizontal)
|
||||
self.opacity_slider.setMinimum(50)
|
||||
self.opacity_slider.setMaximum(100)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,210 @@
|
|||
"""
|
||||
EU-Utility - Widgets View (Core Framework Component)
|
||||
|
||||
Shows registered widgets from plugins.
|
||||
"""
|
||||
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QPushButton, QFrame, QScrollArea, QGridLayout
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from core.icon_manager import get_icon_manager
|
||||
|
||||
|
||||
class WidgetsView(QWidget):
|
||||
"""Widgets management interface - shows registered widgets from plugins."""
|
||||
|
||||
def __init__(self, overlay_window, parent=None):
|
||||
super().__init__(parent)
|
||||
self.overlay = overlay_window
|
||||
self.plugin_manager = overlay_window.plugin_manager if hasattr(overlay_window, 'plugin_manager') else None
|
||||
self.icon_manager = get_icon_manager()
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Create the widgets UI."""
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(16)
|
||||
layout.setContentsMargins(24, 24, 24, 24)
|
||||
|
||||
# Header with icon
|
||||
header_layout = QHBoxLayout()
|
||||
header_layout.setSpacing(12)
|
||||
|
||||
header_icon = QLabel()
|
||||
header_pixmap = self.icon_manager.get_pixmap("widgets", size=28)
|
||||
header_icon.setPixmap(header_pixmap)
|
||||
header_layout.addWidget(header_icon)
|
||||
|
||||
header = QLabel("Widgets")
|
||||
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
||||
header_layout.addWidget(header)
|
||||
header_layout.addStretch()
|
||||
|
||||
layout.addLayout(header_layout)
|
||||
|
||||
# Info label
|
||||
info = QLabel("Manage overlay widgets for in-game use. Enable widgets to show them on the activity bar.")
|
||||
info.setStyleSheet("color: rgba(255,255,255,150); font-size: 13px;")
|
||||
info.setWordWrap(True)
|
||||
layout.addWidget(info)
|
||||
|
||||
# Scroll area for widgets
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setStyleSheet("background: transparent; border: none;")
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
|
||||
self.widgets_container = QWidget()
|
||||
self.widgets_layout = QVBoxLayout(self.widgets_container)
|
||||
self.widgets_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
self.widgets_layout.setSpacing(12)
|
||||
|
||||
self._populate_widgets()
|
||||
|
||||
scroll.setWidget(self.widgets_container)
|
||||
layout.addWidget(scroll)
|
||||
|
||||
def _populate_widgets(self):
|
||||
"""Populate the widgets list from registered widgets."""
|
||||
# Clear existing
|
||||
while self.widgets_layout.count():
|
||||
item = self.widgets_layout.takeAt(0)
|
||||
if item.widget():
|
||||
item.widget().deleteLater()
|
||||
|
||||
# Get widgets from widget registry
|
||||
widgets = []
|
||||
try:
|
||||
from core.widget_registry import get_widget_registry
|
||||
registry = get_widget_registry()
|
||||
widgets = registry.get_all_widgets()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Also check plugins for widgets
|
||||
plugin_widgets = []
|
||||
if self.plugin_manager:
|
||||
try:
|
||||
all_plugins = self.plugin_manager.get_all_plugins()
|
||||
for plugin in all_plugins:
|
||||
if hasattr(plugin, 'get_widgets'):
|
||||
plugin_widgets.extend(plugin.get_widgets())
|
||||
except:
|
||||
pass
|
||||
|
||||
# Hardcoded widgets for now until registry is fully implemented
|
||||
builtin_widgets = [
|
||||
{
|
||||
'id': 'clock',
|
||||
'name': 'Clock Widget',
|
||||
'description': 'Digital clock with date display for activity bar',
|
||||
'plugin': 'Clock Widget',
|
||||
'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
|
||||
},
|
||||
]
|
||||
|
||||
all_widgets = widgets + plugin_widgets + builtin_widgets
|
||||
|
||||
if not all_widgets:
|
||||
no_widgets = QLabel("No widgets available.\n\nInstall plugins that provide widgets to see them here.")
|
||||
no_widgets.setStyleSheet("color: rgba(255,255,255,100); padding: 40px;")
|
||||
no_widgets.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.widgets_layout.addWidget(no_widgets)
|
||||
return
|
||||
|
||||
for widget_info in all_widgets:
|
||||
widget_card = self._create_widget_card(widget_info)
|
||||
self.widgets_layout.addWidget(widget_card)
|
||||
|
||||
self.widgets_layout.addStretch()
|
||||
|
||||
def _create_widget_card(self, widget_info) -> QFrame:
|
||||
"""Create a widget card."""
|
||||
card = QFrame()
|
||||
card.setStyleSheet("""
|
||||
QFrame {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 12px;
|
||||
padding: 4px;
|
||||
}
|
||||
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)
|
||||
cb.setToolTip("Enable/disable widget on activity bar")
|
||||
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 Widget'))
|
||||
name.setStyleSheet("color: white; 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("color: rgba(255,140,66,0.8); font-size: 11px;")
|
||||
name_row.addWidget(plugin_label)
|
||||
|
||||
name_row.addStretch()
|
||||
info_layout.addLayout(name_row)
|
||||
|
||||
# Description
|
||||
desc = widget_info.get('description', 'No description')
|
||||
desc_label = QLabel(desc)
|
||||
desc_label.setStyleSheet("color: rgba(255,255,255,120); 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("""
|
||||
QPushButton {
|
||||
background: rgba(255, 140, 66, 0.2);
|
||||
color: #ff8c42;
|
||||
border: 1px solid rgba(255, 140, 66, 0.3);
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 11px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background: rgba(255, 140, 66, 0.3);
|
||||
}
|
||||
""")
|
||||
layout.addWidget(preview_btn)
|
||||
|
||||
return card
|
||||
Loading…
Reference in New Issue