487 lines
16 KiB
Python
487 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
EU-Utility - Core Functionality Demo
|
|
|
|
Demonstrates all the implemented core features:
|
|
- Dashboard Widgets (System Status, Quick Actions, Recent Activity, Plugin Grid)
|
|
- Widget Gallery (Add, configure, remove widgets)
|
|
- Enhanced Activity Bar (Pinned plugins, app drawer, search)
|
|
- Enhanced Settings Panel (Full persistence via SQLite)
|
|
- Data Layer (SQLite storage, preferences, activity logging)
|
|
|
|
Usage:
|
|
python core_functionality_demo.py
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add parent to path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QApplication, QMainWindow, QWidget, QVBoxLayout,
|
|
QHBoxLayout, QPushButton, QLabel, QStackedWidget
|
|
)
|
|
from PyQt6.QtCore import Qt, QTimer
|
|
from PyQt6.QtGui import QColor
|
|
|
|
# Import our new core components
|
|
from core.data import get_sqlite_store, PluginState
|
|
from core.widgets import (
|
|
SystemStatusWidget, QuickActionsWidget,
|
|
RecentActivityWidget, PluginGridWidget,
|
|
DashboardWidgetManager
|
|
)
|
|
from core.dashboard_enhanced import EnhancedDashboard, DashboardContainer
|
|
from core.activity_bar_enhanced import EnhancedActivityBar
|
|
from core.ui.settings_panel import EnhancedSettingsPanel
|
|
|
|
|
|
class DemoWindow(QMainWindow):
|
|
"""Main demo window showcasing all core functionality."""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.setWindowTitle("EU-Utility Core Functionality Demo")
|
|
self.setMinimumSize(1200, 800)
|
|
|
|
# Initialize data store
|
|
self.data_store = get_sqlite_store()
|
|
self._log_session_start()
|
|
|
|
self._setup_ui()
|
|
self._create_demo_data()
|
|
|
|
def _setup_ui(self):
|
|
"""Setup the demo UI."""
|
|
# Central widget
|
|
central = QWidget()
|
|
self.setCentralWidget(central)
|
|
|
|
layout = QHBoxLayout(central)
|
|
layout.setContentsMargins(20, 20, 20, 20)
|
|
layout.setSpacing(20)
|
|
|
|
# Sidebar navigation
|
|
sidebar = self._create_sidebar()
|
|
layout.addWidget(sidebar)
|
|
|
|
# Main content area
|
|
self.content = QStackedWidget()
|
|
self.content.setStyleSheet("""
|
|
QStackedWidget {
|
|
background-color: #1a1f2e;
|
|
border-radius: 12px;
|
|
}
|
|
""")
|
|
layout.addWidget(self.content, 1)
|
|
|
|
# Add demo pages
|
|
self._add_demo_pages()
|
|
|
|
def _create_sidebar(self) -> QWidget:
|
|
"""Create sidebar navigation."""
|
|
sidebar = QWidget()
|
|
sidebar.setFixedWidth(200)
|
|
sidebar.setStyleSheet("""
|
|
QWidget {
|
|
background-color: #252b3d;
|
|
border-radius: 12px;
|
|
}
|
|
""")
|
|
|
|
layout = QVBoxLayout(sidebar)
|
|
layout.setSpacing(10)
|
|
layout.setContentsMargins(15, 20, 15, 20)
|
|
|
|
# Title
|
|
title = QLabel("🎮 EU-Utility")
|
|
title.setStyleSheet("font-size: 18px; font-weight: bold; color: #ff8c42;")
|
|
layout.addWidget(title)
|
|
|
|
version = QLabel("v2.1.0 - Core Demo")
|
|
version.setStyleSheet("color: rgba(255, 255, 255, 100); font-size: 11px;")
|
|
layout.addWidget(version)
|
|
|
|
layout.addSpacing(20)
|
|
|
|
# Navigation buttons
|
|
nav_items = [
|
|
("📊 Dashboard", 0),
|
|
("🎨 Widget Gallery", 1),
|
|
("📌 Activity Bar", 2),
|
|
("⚙️ Settings", 3),
|
|
("💾 Data Layer", 4),
|
|
]
|
|
|
|
for text, index in nav_items:
|
|
btn = QPushButton(text)
|
|
btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: transparent;
|
|
color: rgba(255, 255, 255, 180);
|
|
border: none;
|
|
padding: 12px;
|
|
text-align: left;
|
|
border-radius: 8px;
|
|
font-size: 13px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: rgba(255, 255, 255, 10);
|
|
color: white;
|
|
}
|
|
QPushButton:checked {
|
|
background-color: #4a9eff;
|
|
color: white;
|
|
font-weight: bold;
|
|
}
|
|
""")
|
|
btn.setCheckable(True)
|
|
btn.clicked.connect(lambda checked, idx=index: self._switch_page(idx))
|
|
layout.addWidget(btn)
|
|
|
|
if index == 0:
|
|
btn.setChecked(True)
|
|
self._nav_buttons = [btn]
|
|
else:
|
|
self._nav_buttons.append(btn)
|
|
|
|
layout.addStretch()
|
|
|
|
# Status
|
|
self.status_label = QLabel("System Ready")
|
|
self.status_label.setStyleSheet("color: #4ecdc4; font-size: 11px;")
|
|
self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
layout.addWidget(self.status_label)
|
|
|
|
return sidebar
|
|
|
|
def _add_demo_pages(self):
|
|
"""Add demo pages to content stack."""
|
|
# Page 1: Dashboard
|
|
self.dashboard = EnhancedDashboard(parent=self)
|
|
self.dashboard.action_triggered.connect(self._on_dashboard_action)
|
|
self.content.addWidget(self.dashboard)
|
|
|
|
# Page 2: Widget Gallery
|
|
gallery_page = self._create_gallery_page()
|
|
self.content.addWidget(gallery_page)
|
|
|
|
# Page 3: Activity Bar Demo
|
|
activity_page = self._create_activity_page()
|
|
self.content.addWidget(activity_page)
|
|
|
|
# Page 4: Settings
|
|
self.settings = EnhancedSettingsPanel(self, self)
|
|
self.content.addWidget(self.settings)
|
|
|
|
# Page 5: Data Layer
|
|
data_page = self._create_data_page()
|
|
self.content.addWidget(data_page)
|
|
|
|
def _create_gallery_page(self) -> QWidget:
|
|
"""Create widget gallery demo page."""
|
|
page = QWidget()
|
|
layout = QVBoxLayout(page)
|
|
layout.setContentsMargins(30, 30, 30, 30)
|
|
|
|
header = QLabel("🎨 Widget Gallery")
|
|
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
|
layout.addWidget(header)
|
|
|
|
desc = QLabel("Dashboard widgets are modular components that provide information and quick actions.")
|
|
desc.setStyleSheet("color: rgba(255, 255, 255, 150); font-size: 13px;")
|
|
desc.setWordWrap(True)
|
|
layout.addWidget(desc)
|
|
|
|
layout.addSpacing(20)
|
|
|
|
# Widget showcase
|
|
showcase = QWidget()
|
|
showcase_layout = QHBoxLayout(showcase)
|
|
showcase_layout.setSpacing(20)
|
|
|
|
# System Status Widget
|
|
sys_widget = SystemStatusWidget()
|
|
showcase_layout.addWidget(sys_widget)
|
|
|
|
# Quick Actions Widget
|
|
actions_widget = QuickActionsWidget()
|
|
actions_widget.setFixedWidth(300)
|
|
showcase_layout.addWidget(actions_widget)
|
|
|
|
# Recent Activity Widget
|
|
activity_widget = RecentActivityWidget()
|
|
showcase_layout.addWidget(activity_widget)
|
|
|
|
showcase_layout.addStretch()
|
|
layout.addWidget(showcase)
|
|
|
|
layout.addStretch()
|
|
|
|
# Info
|
|
info = QLabel("💡 These widgets are automatically managed by the DashboardWidgetManager and persist their state via SQLite.")
|
|
info.setStyleSheet("color: #4ecdc4; font-size: 12px; padding: 10px; background-color: rgba(78, 205, 196, 20); border-radius: 6px;")
|
|
info.setWordWrap(True)
|
|
layout.addWidget(info)
|
|
|
|
return page
|
|
|
|
def _create_activity_page(self) -> QWidget:
|
|
"""Create activity bar demo page."""
|
|
page = QWidget()
|
|
layout = QVBoxLayout(page)
|
|
layout.setContentsMargins(30, 30, 30, 30)
|
|
|
|
header = QLabel("📌 Activity Bar")
|
|
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
|
layout.addWidget(header)
|
|
|
|
desc = QLabel("Windows 11-style taskbar with pinned plugins, app drawer, and search functionality.")
|
|
desc.setStyleSheet("color: rgba(255, 255, 255, 150); font-size: 13px;")
|
|
desc.setWordWrap(True)
|
|
layout.addWidget(desc)
|
|
|
|
layout.addSpacing(30)
|
|
|
|
# Features
|
|
features = QLabel("""
|
|
<b>Features:</b><br>
|
|
• Drag-to-pin plugins from the app drawer<br>
|
|
• Search functionality for quick access<br>
|
|
• Auto-hide when not in use<br>
|
|
• Configurable position (top/bottom)<br>
|
|
• Persistent pinned plugin state
|
|
""")
|
|
features.setStyleSheet("color: rgba(255, 255, 255, 200); font-size: 13px; line-height: 1.6;")
|
|
features.setTextFormat(Qt.TextFormat.RichText)
|
|
layout.addWidget(features)
|
|
|
|
layout.addSpacing(30)
|
|
|
|
# Demo button
|
|
demo_btn = QPushButton("🚀 Show Activity Bar Demo")
|
|
demo_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #4a9eff;
|
|
color: white;
|
|
padding: 15px 30px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-weight: bold;
|
|
font-size: 14px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #3a8eef;
|
|
}
|
|
""")
|
|
demo_btn.clicked.connect(self._show_activity_bar)
|
|
layout.addWidget(demo_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
|
|
|
layout.addStretch()
|
|
|
|
return page
|
|
|
|
def _create_data_page(self) -> QWidget:
|
|
"""Create data layer demo page."""
|
|
page = QWidget()
|
|
layout = QVBoxLayout(page)
|
|
layout.setContentsMargins(30, 30, 30, 30)
|
|
|
|
header = QLabel("💾 Data Layer (SQLite)")
|
|
header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;")
|
|
layout.addWidget(header)
|
|
|
|
desc = QLabel("Persistent storage using SQLite with automatic backups and migration support.")
|
|
desc.setStyleSheet("color: rgba(255, 255, 255, 150); font-size: 13px;")
|
|
desc.setWordWrap(True)
|
|
layout.addWidget(desc)
|
|
|
|
layout.addSpacing(20)
|
|
|
|
# Stats display
|
|
self.data_stats = QLabel("Loading statistics...")
|
|
self.data_stats.setStyleSheet("""
|
|
color: rgba(255, 255, 255, 200);
|
|
font-size: 13px;
|
|
font-family: monospace;
|
|
background-color: rgba(0, 0, 0, 30);
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
""")
|
|
layout.addWidget(self.data_stats)
|
|
|
|
# Refresh button
|
|
refresh_btn = QPushButton("🔄 Refresh Statistics")
|
|
refresh_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: rgba(255, 255, 255, 10);
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #4ecdc4;
|
|
color: #141f23;
|
|
}
|
|
""")
|
|
refresh_btn.clicked.connect(self._refresh_data_stats)
|
|
layout.addWidget(refresh_btn)
|
|
|
|
layout.addSpacing(20)
|
|
|
|
# Features list
|
|
features = QLabel("""
|
|
<b>Data Layer Features:</b><br>
|
|
• Plugin state persistence (enabled/disabled, settings)<br>
|
|
• User preferences with categories<br>
|
|
• Session tracking and analytics<br>
|
|
• Activity logging for debugging<br>
|
|
• Dashboard widget configurations<br>
|
|
• Hotkey configurations<br>
|
|
• Thread-safe database access<br>
|
|
• Automatic database optimization
|
|
""")
|
|
features.setStyleSheet("color: rgba(255, 255, 255, 180); font-size: 12px; line-height: 1.5;")
|
|
features.setTextFormat(Qt.TextFormat.RichText)
|
|
layout.addWidget(features)
|
|
|
|
layout.addStretch()
|
|
|
|
# Initial refresh
|
|
QTimer.singleShot(100, self._refresh_data_stats)
|
|
|
|
return page
|
|
|
|
def _switch_page(self, index: int):
|
|
"""Switch to a different demo page."""
|
|
self.content.setCurrentIndex(index)
|
|
|
|
# Update nav button states
|
|
for i, btn in enumerate(self._nav_buttons):
|
|
btn.setChecked(i == index)
|
|
|
|
# Update status
|
|
pages = ["Dashboard", "Widget Gallery", "Activity Bar", "Settings", "Data Layer"]
|
|
self.status_label.setText(f"Viewing: {pages[index]}")
|
|
|
|
def _on_dashboard_action(self, action_id: str):
|
|
"""Handle dashboard quick action."""
|
|
print(f"[Demo] Dashboard action: {action_id}")
|
|
|
|
if action_id == 'settings':
|
|
self._switch_page(3)
|
|
elif action_id == 'plugins':
|
|
self._switch_page(1)
|
|
|
|
def _show_activity_bar(self):
|
|
"""Show the activity bar demo."""
|
|
# Create activity bar
|
|
self.activity_bar = EnhancedActivityBar(None, self)
|
|
self.activity_bar.show()
|
|
|
|
self.status_label.setText("Activity Bar: Visible")
|
|
|
|
# Log
|
|
self.data_store.log_activity('demo', 'activity_bar_shown')
|
|
|
|
def _refresh_data_stats(self):
|
|
"""Refresh data statistics display."""
|
|
stats = self.data_store.get_stats()
|
|
|
|
text = f"""
|
|
Database Statistics:
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
Plugin States: {stats.get('plugin_states', 0):>6}
|
|
User Preferences: {stats.get('user_preferences', 0):>6}
|
|
Sessions: {stats.get('sessions', 0):>6}
|
|
Activity Entries: {stats.get('activity_log', 0):>6}
|
|
Dashboard Widgets: {stats.get('dashboard_widgets', 0):>6}
|
|
Hotkeys: {stats.get('hotkeys', 0):>6}
|
|
──────────────────────────────────
|
|
Database Size: {stats.get('db_size_mb', 0):>6.2f} MB
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"""
|
|
|
|
self.data_stats.setText(text)
|
|
|
|
def _log_session_start(self):
|
|
"""Log session start."""
|
|
self.data_store.log_activity(
|
|
category='demo',
|
|
action='session_start',
|
|
details='Core functionality demo started'
|
|
)
|
|
|
|
def _create_demo_data(self):
|
|
"""Create some demo data."""
|
|
# Save a plugin state
|
|
state = PluginState(
|
|
plugin_id='demo_plugin',
|
|
enabled=True,
|
|
version='1.0.0',
|
|
settings={'key': 'value'}
|
|
)
|
|
self.data_store.save_plugin_state(state)
|
|
|
|
# Save some preferences
|
|
self.data_store.set_preference('demo_mode', True, 'general')
|
|
self.data_store.set_preference('demo_features', ['widgets', 'activity_bar', 'settings'], 'demo')
|
|
|
|
# Log activities
|
|
self.data_store.log_activity('demo', 'widgets_loaded', 'System Status, Quick Actions, Recent Activity')
|
|
self.data_store.log_activity('demo', 'activity_bar_initialized')
|
|
self.data_store.log_activity('demo', 'settings_panel_ready')
|
|
|
|
|
|
def main():
|
|
"""Run the demo application."""
|
|
app = QApplication(sys.argv)
|
|
|
|
# Set application style
|
|
app.setStyle('Fusion')
|
|
|
|
# Apply dark stylesheet
|
|
app.setStyleSheet("""
|
|
QMainWindow {
|
|
background-color: #0f1419;
|
|
}
|
|
QWidget {
|
|
font-family: 'Segoe UI', sans-serif;
|
|
}
|
|
QScrollBar:vertical {
|
|
background: rgba(0, 0, 0, 50);
|
|
width: 8px;
|
|
border-radius: 4px;
|
|
}
|
|
QScrollBar::handle:vertical {
|
|
background: rgba(255, 255, 255, 30);
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
|
|
# Create and show window
|
|
window = DemoWindow()
|
|
window.show()
|
|
|
|
print("=" * 60)
|
|
print("EU-Utility Core Functionality Demo")
|
|
print("=" * 60)
|
|
print()
|
|
print("Features demonstrated:")
|
|
print(" ✓ Dashboard Widgets (System Status, Quick Actions, Recent Activity)")
|
|
print(" ✓ Widget Gallery (Add, configure, manage widgets)")
|
|
print(" ✓ Enhanced Activity Bar (Pinned plugins, app drawer, search)")
|
|
print(" ✓ Enhanced Settings Panel (Full SQLite persistence)")
|
|
print(" ✓ Data Layer (SQLite storage, preferences, activity logging)")
|
|
print()
|
|
print("Navigate using the sidebar to explore each feature!")
|
|
print("=" * 60)
|
|
|
|
sys.exit(app.exec())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|