204 lines
6.9 KiB
Python
204 lines
6.9 KiB
Python
"""
|
|
EU-Utility - Dashboard (Core Framework Component)
|
|
|
|
Built-in dashboard - not a plugin. Provides hooks for plugins to add widgets.
|
|
"""
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QGridLayout, QFrame, QScrollArea, QPushButton
|
|
)
|
|
from PyQt6.QtCore import Qt, QSize
|
|
|
|
from core.icon_manager import get_icon_manager
|
|
|
|
|
|
class DashboardView(QWidget):
|
|
"""Main dashboard - built into the framework.
|
|
|
|
Plugins can register dashboard widgets via PluginAPI:
|
|
api.register_dashboard_widget(
|
|
name="My Widget",
|
|
widget=my_widget,
|
|
position="left", # left, right, center
|
|
priority=10
|
|
)
|
|
"""
|
|
|
|
def __init__(self, overlay_window, parent=None):
|
|
super().__init__(parent)
|
|
self.overlay = overlay_window
|
|
self.widgets = [] # Registered dashboard widgets
|
|
self.icon_manager = get_icon_manager()
|
|
|
|
self._setup_ui()
|
|
|
|
def _setup_ui(self):
|
|
"""Create the dashboard 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("dashboard", size=28)
|
|
header_icon.setPixmap(header_pixmap)
|
|
header_layout.addWidget(header_icon)
|
|
|
|
header = QLabel("Dashboard")
|
|
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
|
header_layout.addWidget(header)
|
|
header_layout.addStretch()
|
|
|
|
layout.addLayout(header_layout)
|
|
|
|
# Scroll area for widgets
|
|
scroll = QScrollArea()
|
|
scroll.setWidgetResizable(True)
|
|
scroll.setFrameShape(QFrame.Shape.NoFrame)
|
|
scroll.setStyleSheet("background: transparent; border: none;")
|
|
|
|
self.content = QWidget()
|
|
self.content_layout = QVBoxLayout(self.content)
|
|
self.content_layout.setSpacing(16)
|
|
self.content_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
|
|
# Add built-in widgets
|
|
self._add_builtin_widgets()
|
|
|
|
scroll.setWidget(self.content)
|
|
layout.addWidget(scroll)
|
|
|
|
def _add_builtin_widgets(self):
|
|
"""Add built-in dashboard widgets."""
|
|
# Welcome widget
|
|
welcome = self._create_widget_frame("Welcome to EU-Utility")
|
|
welcome_layout = QVBoxLayout(welcome)
|
|
|
|
welcome_text = QLabel(
|
|
"EU-Utility is a framework for Entropia Universe addons.\n\n"
|
|
"Install plugins from the Plugin Store to get started!"
|
|
)
|
|
welcome_text.setStyleSheet("color: rgba(255,255,255,150);")
|
|
welcome_text.setWordWrap(True)
|
|
welcome_layout.addWidget(welcome_text)
|
|
|
|
# Plugin store button with icon
|
|
store_btn = QPushButton("Open Plugin Store")
|
|
store_btn.setIcon(self.icon_manager.get_icon("shopping-bag"))
|
|
store_btn.setIconSize(QSize(18, 18))
|
|
store_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #ff8c42;
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
font-weight: bold;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #ffa366;
|
|
}
|
|
""")
|
|
store_btn.clicked.connect(self._open_plugin_store)
|
|
welcome_layout.addWidget(store_btn)
|
|
|
|
self.content_layout.addWidget(welcome)
|
|
|
|
# Quick stats widget
|
|
stats = self._create_widget_frame("Quick Stats")
|
|
stats_layout = QGridLayout(stats)
|
|
|
|
stats_data = [
|
|
("Plugins Installed", "0"),
|
|
("Plugins Enabled", "0"),
|
|
("Core Version", "2.1.0"),
|
|
]
|
|
|
|
for i, (label, value) in enumerate(stats_data):
|
|
label_widget = QLabel(f"{label}:")
|
|
label_widget.setStyleSheet("color: rgba(255,255,255,150);")
|
|
stats_layout.addWidget(label_widget, i, 0)
|
|
|
|
value_widget = QLabel(value)
|
|
value_widget.setStyleSheet("color: #ff8c42; font-weight: bold;")
|
|
stats_layout.addWidget(value_widget, i, 1)
|
|
|
|
self.content_layout.addWidget(stats)
|
|
|
|
# Plugin widgets section
|
|
plugin_section = QLabel("Plugin Widgets")
|
|
plugin_section.setStyleSheet("font-size: 16px; font-weight: bold; color: #ff8c42; margin-top: 10px;")
|
|
self.content_layout.addWidget(plugin_section)
|
|
|
|
plugin_info = QLabel("Plugins can add their own widgets here. Install some plugins to see them!")
|
|
plugin_info.setStyleSheet("color: rgba(255,255,255,100); font-style: italic;")
|
|
self.content_layout.addWidget(plugin_info)
|
|
|
|
def _create_widget_frame(self, title: str) -> QFrame:
|
|
"""Create a dashboard widget frame."""
|
|
frame = QFrame()
|
|
frame.setStyleSheet("""
|
|
QFrame {
|
|
background-color: rgba(20, 31, 35, 0.95);
|
|
border: 1px solid rgba(255, 140, 66, 0.1);
|
|
border-radius: 8px;
|
|
}
|
|
""")
|
|
|
|
layout = QVBoxLayout(frame)
|
|
layout.setSpacing(12)
|
|
layout.setContentsMargins(16, 16, 16, 16)
|
|
|
|
# Title
|
|
title_label = QLabel(title)
|
|
title_label.setStyleSheet("font-size: 14px; font-weight: bold; color: white;")
|
|
layout.addWidget(title_label)
|
|
|
|
# Separator
|
|
sep = QFrame()
|
|
sep.setFrameShape(QFrame.Shape.HLine)
|
|
sep.setStyleSheet("background-color: rgba(255, 140, 66, 0.1);")
|
|
sep.setFixedHeight(1)
|
|
layout.addWidget(sep)
|
|
|
|
return frame
|
|
|
|
def _open_plugin_store(self):
|
|
"""Open the plugin store."""
|
|
# Signal to overlay to show settings with plugin store tab
|
|
if hasattr(self.overlay, 'show_settings'):
|
|
self.overlay.show_settings(tab="Plugin Store")
|
|
|
|
def register_widget(self, name: str, widget: QWidget, priority: int = 100):
|
|
"""Register a widget from a plugin.
|
|
|
|
Args:
|
|
name: Widget name (shown as title)
|
|
widget: QWidget to display
|
|
priority: Lower numbers appear first
|
|
"""
|
|
# Wrap in frame
|
|
frame = self._create_widget_frame(name)
|
|
frame.layout().addWidget(widget)
|
|
|
|
# Add to layout based on priority
|
|
self.content_layout.addWidget(frame)
|
|
|
|
self.widgets.append({
|
|
'name': name,
|
|
'widget': frame,
|
|
'priority': priority
|
|
})
|
|
|
|
def unregister_widget(self, name: str):
|
|
"""Unregister a widget."""
|
|
for widget_info in self.widgets:
|
|
if widget_info['name'] == name:
|
|
widget_info['widget'].deleteLater()
|
|
self.widgets.remove(widget_info)
|
|
break
|