diff --git a/projects/EU-Utility/core/overlay_window.py b/projects/EU-Utility/core/overlay_window.py index dd3c6a5..5cf2730 100644 --- a/projects/EU-Utility/core/overlay_window.py +++ b/projects/EU-Utility/core/overlay_window.py @@ -1,7 +1,7 @@ """ EU-Utility - Overlay Window -Transparent, always-on-top overlay for in-game use. +Spotlight-style overlay with frosted glass effect. """ import sys @@ -12,10 +12,10 @@ try: from PyQt6.QtWidgets import ( QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QStackedWidget, QSystemTrayIcon, - QMenu, QApplication, QFrame + QMenu, QApplication, QFrame, QGraphicsDropShadowEffect ) - from PyQt6.QtCore import Qt, QTimer, pyqtSignal - from PyQt6.QtGui import QAction, QIcon, QKeySequence, QShortcut + from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QSize + from PyQt6.QtGui import QAction, QIcon, QColor, QFont PYQT6_AVAILABLE = True except ImportError: PYQT6_AVAILABLE = False @@ -23,7 +23,7 @@ except ImportError: class OverlayWindow(QMainWindow): - """Transparent overlay window for in-game use.""" + """Spotlight-style overlay window.""" visibility_changed = pyqtSignal(bool) @@ -35,6 +35,7 @@ class OverlayWindow(QMainWindow): self.plugin_manager = plugin_manager self.is_visible = False + self.plugin_buttons = [] self._setup_window() self._setup_ui() @@ -57,22 +58,19 @@ class OverlayWindow(QMainWindow): # Transparent background self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) - # Size and position - self.resize(800, 600) + # Size and position - wider but shorter for spotlight style + self.resize(700, 500) self._center_window() - - # Click-through when inactive (optional) - # self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents) def _center_window(self): """Center window on screen.""" screen = QApplication.primaryScreen().geometry() x = (screen.width() - self.width()) // 2 - y = (screen.height() - self.height()) // 2 + y = (screen.height() - self.height()) // 3 # Upper third like Spotlight self.move(x, y) def _setup_ui(self): - """Setup the user interface.""" + """Setup the Spotlight-style UI.""" # Central widget central = QWidget() self.setCentralWidget(central) @@ -80,101 +78,186 @@ class OverlayWindow(QMainWindow): # Main layout layout = QVBoxLayout(central) layout.setContentsMargins(20, 20, 20, 20) + layout.setSpacing(0) - # Container with background + # Frosted glass container self.container = QFrame() - self.container.setObjectName("overlayContainer") + self.container.setObjectName("spotlightContainer") self.container.setStyleSheet(""" - #overlayContainer { - background-color: rgba(30, 30, 30, 240); - border-radius: 10px; - border: 2px solid #444; + #spotlightContainer { + background-color: rgba(40, 40, 40, 180); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 30); } """) + + # Add shadow effect + shadow = QGraphicsDropShadowEffect() + shadow.setBlurRadius(30) + shadow.setColor(QColor(0, 0, 0, 100)) + shadow.setOffset(0, 10) + self.container.setGraphicsEffect(shadow) + container_layout = QVBoxLayout(self.container) - container_layout.setContentsMargins(15, 15, 15, 15) + container_layout.setContentsMargins(0, 0, 0, 0) + container_layout.setSpacing(0) - # Header - header = QHBoxLayout() + # Header with search bar style + header = QWidget() + header.setStyleSheet(""" + QWidget { + background-color: rgba(255, 255, 255, 15); + border-top-left-radius: 20px; + border-top-right-radius: 20px; + border-bottom: 1px solid rgba(255, 255, 255, 20); + } + """) + header_layout = QHBoxLayout(header) + header_layout.setContentsMargins(20, 15, 20, 15) + header_layout.setSpacing(15) + # Search icon + search_icon = QLabel("🔍") + search_icon.setStyleSheet("font-size: 18px; background: transparent; border: none;") + header_layout.addWidget(search_icon) + + # Title/Search label title = QLabel("EU-Utility") title.setStyleSheet(""" - color: #fff; - font-size: 18px; - font-weight: bold; + color: rgba(255, 255, 255, 200); + font-size: 16px; + font-weight: 500; + background: transparent; + border: none; """) - header.addWidget(title) + header_layout.addWidget(title) - header.addStretch() + header_layout.addStretch() - # Close button + # Close button (X) - subtle close_btn = QPushButton("×") - close_btn.setFixedSize(30, 30) + close_btn.setFixedSize(28, 28) close_btn.setStyleSheet(""" QPushButton { background-color: transparent; - color: #999; + color: rgba(255, 255, 255, 150); font-size: 20px; + font-weight: 300; border: none; - border-radius: 15px; + border-radius: 14px; } QPushButton:hover { - background-color: #c44; + background-color: rgba(255, 255, 255, 20); color: white; } """) close_btn.clicked.connect(self.hide_overlay) - header.addWidget(close_btn) + header_layout.addWidget(close_btn) - container_layout.addLayout(header) + container_layout.addWidget(header) - # Plugin tabs / stack + # Plugin content area + self.content_area = QWidget() + self.content_area.setStyleSheet("background: transparent;") + content_layout = QVBoxLayout(self.content_area) + content_layout.setContentsMargins(20, 20, 20, 20) + content_layout.setSpacing(15) + + # Plugin stack self.plugin_stack = QStackedWidget() - container_layout.addWidget(self.plugin_stack) + self.plugin_stack.setStyleSheet("background: transparent;") + content_layout.addWidget(self.plugin_stack, 1) - # Plugin buttons + container_layout.addWidget(self.content_area, 1) + + # Plugin selector bar (at bottom) if self.plugin_manager: - self._setup_plugin_buttons(container_layout) + self._setup_plugin_bar(container_layout) layout.addWidget(self.container) - def _setup_plugin_buttons(self, layout): - """Setup buttons to switch between plugins.""" - btn_layout = QHBoxLayout() + def _setup_plugin_bar(self, layout): + """Setup circular plugin icon bar at bottom.""" + bar = QWidget() + bar.setStyleSheet(""" + QWidget { + background-color: rgba(0, 0, 0, 40); + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; + } + """) + bar_layout = QHBoxLayout(bar) + bar_layout.setContentsMargins(20, 12, 20, 12) + bar_layout.setSpacing(15) + bar_layout.addStretch() - for plugin_id, plugin in self.plugin_manager.get_all_plugins().items(): - btn = QPushButton(plugin.name) + # Add plugin icons + plugin_icons = { + "Universal Search": "🔍", + "Calculator": "🧮", + "Spotify": "🎵", + "Nexus Search": "🌐", + } + + for idx, (plugin_id, plugin) in enumerate(self.plugin_manager.get_all_plugins().items()): + btn = QPushButton() + + # Get icon emoji or default + icon = plugin_icons.get(plugin.name, "⚡") + btn.setText(icon) + + btn.setFixedSize(44, 44) btn.setStyleSheet(""" QPushButton { - background-color: #333; + background-color: rgba(255, 255, 255, 15); color: white; - padding: 8px 16px; - border-radius: 4px; + font-size: 20px; border: none; + border-radius: 22px; } QPushButton:hover { - background-color: #444; + background-color: rgba(255, 255, 255, 30); } - QPushButton:pressed { - background-color: #555; + QPushButton:checked, QPushButton:pressed { + background-color: #4a9eff; } """) + btn.setCheckable(True) + btn.setToolTip(plugin.name) # Add plugin UI to stack try: plugin_ui = plugin.get_ui() if plugin_ui: + plugin_ui.setStyleSheet("background: transparent;") self.plugin_stack.addWidget(plugin_ui) btn.clicked.connect( - lambda checked, idx=self.plugin_stack.count()-1: - self.plugin_stack.setCurrentIndex(idx) + lambda checked, i=idx, b=btn: self._switch_plugin(i, b) ) - btn_layout.addWidget(btn) + self.plugin_buttons.append(btn) + bar_layout.addWidget(btn) except Exception as e: print(f"Error loading UI for {plugin.name}: {e}") - btn_layout.addStretch() - layout.addLayout(btn_layout) + bar_layout.addStretch() + layout.addWidget(bar) + + # Select first plugin by default + if self.plugin_buttons: + self.plugin_buttons[0].setChecked(True) + + def _switch_plugin(self, index, button): + """Switch to selected plugin.""" + # Uncheck all other buttons + for btn in self.plugin_buttons: + if btn != button: + btn.setChecked(False) + + # Ensure clicked button stays checked + button.setChecked(True) + + # Switch stack + self.plugin_stack.setCurrentIndex(index) def _setup_tray(self): """Setup system tray icon.""" @@ -187,18 +270,30 @@ class OverlayWindow(QMainWindow): # Tray menu tray_menu = QMenu() + tray_menu.setStyleSheet(""" + QMenu { + background-color: rgba(40, 40, 40, 240); + color: white; + border: 1px solid rgba(255, 255, 255, 30); + border-radius: 8px; + padding: 8px; + } + QMenu::item { + padding: 8px 20px; + border-radius: 4px; + } + QMenu::item:selected { + background-color: #4a9eff; + } + """) - show_action = QAction("Show", self) + show_action = QAction("🔍 Show EU-Utility", self) show_action.triggered.connect(self.show_overlay) tray_menu.addAction(show_action) - hide_action = QAction("Hide", self) - hide_action.triggered.connect(self.hide_overlay) - tray_menu.addAction(hide_action) - tray_menu.addSeparator() - quit_action = QAction("Quit", self) + quit_action = QAction("❌ Quit", self) quit_action.triggered.connect(self.quit_app) tray_menu.addAction(quit_action)