diff --git a/projects/EU-Utility/assets/icons/armor.svg b/projects/EU-Utility/assets/icons/armor.svg new file mode 100644 index 0000000..e435040 --- /dev/null +++ b/projects/EU-Utility/assets/icons/armor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/calculator.svg b/projects/EU-Utility/assets/icons/calculator.svg index 0598645..3f2f3ae 100644 --- a/projects/EU-Utility/assets/icons/calculator.svg +++ b/projects/EU-Utility/assets/icons/calculator.svg @@ -1,7 +1 @@ - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/camera.svg b/projects/EU-Utility/assets/icons/camera.svg index 653b884..a0feec5 100644 --- a/projects/EU-Utility/assets/icons/camera.svg +++ b/projects/EU-Utility/assets/icons/camera.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/check.svg b/projects/EU-Utility/assets/icons/check.svg index d2a6020..e5ec744 100644 --- a/projects/EU-Utility/assets/icons/check.svg +++ b/projects/EU-Utility/assets/icons/check.svg @@ -1,3 +1 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/close.svg b/projects/EU-Utility/assets/icons/close.svg index 944be66..5619a6b 100644 --- a/projects/EU-Utility/assets/icons/close.svg +++ b/projects/EU-Utility/assets/icons/close.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/esi.svg b/projects/EU-Utility/assets/icons/esi.svg new file mode 100644 index 0000000..7e1cf4e --- /dev/null +++ b/projects/EU-Utility/assets/icons/esi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/external.svg b/projects/EU-Utility/assets/icons/external.svg index f538f84..0f065d2 100644 --- a/projects/EU-Utility/assets/icons/external.svg +++ b/projects/EU-Utility/assets/icons/external.svg @@ -1,5 +1 @@ - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/file.svg b/projects/EU-Utility/assets/icons/file.svg index 1e50eb6..4a1e961 100644 --- a/projects/EU-Utility/assets/icons/file.svg +++ b/projects/EU-Utility/assets/icons/file.svg @@ -1,7 +1 @@ - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/globe.svg b/projects/EU-Utility/assets/icons/globe.svg index 34e608e..45878b5 100644 --- a/projects/EU-Utility/assets/icons/globe.svg +++ b/projects/EU-Utility/assets/icons/globe.svg @@ -1,5 +1 @@ - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/loot.svg b/projects/EU-Utility/assets/icons/loot.svg new file mode 100644 index 0000000..2ffb911 --- /dev/null +++ b/projects/EU-Utility/assets/icons/loot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/mob.svg b/projects/EU-Utility/assets/icons/mob.svg new file mode 100644 index 0000000..e761b27 --- /dev/null +++ b/projects/EU-Utility/assets/icons/mob.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/music.svg b/projects/EU-Utility/assets/icons/music.svg index 6d334a9..d2753ab 100644 --- a/projects/EU-Utility/assets/icons/music.svg +++ b/projects/EU-Utility/assets/icons/music.svg @@ -1,5 +1 @@ - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/ped.svg b/projects/EU-Utility/assets/icons/ped.svg new file mode 100644 index 0000000..f594711 --- /dev/null +++ b/projects/EU-Utility/assets/icons/ped.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/search.svg b/projects/EU-Utility/assets/icons/search.svg index a851064..842d975 100644 --- a/projects/EU-Utility/assets/icons/search.svg +++ b/projects/EU-Utility/assets/icons/search.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/settings.svg b/projects/EU-Utility/assets/icons/settings.svg index 45cc776..8919916 100644 --- a/projects/EU-Utility/assets/icons/settings.svg +++ b/projects/EU-Utility/assets/icons/settings.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/skills.svg b/projects/EU-Utility/assets/icons/skills.svg index 5e33c76..7248eb2 100644 --- a/projects/EU-Utility/assets/icons/skills.svg +++ b/projects/EU-Utility/assets/icons/skills.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/target.svg b/projects/EU-Utility/assets/icons/target.svg new file mode 100644 index 0000000..e3dc354 --- /dev/null +++ b/projects/EU-Utility/assets/icons/target.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/trash.svg b/projects/EU-Utility/assets/icons/trash.svg index 7116ee4..37381ce 100644 --- a/projects/EU-Utility/assets/icons/trash.svg +++ b/projects/EU-Utility/assets/icons/trash.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/projects/EU-Utility/assets/icons/weapon.svg b/projects/EU-Utility/assets/icons/weapon.svg new file mode 100644 index 0000000..7707621 --- /dev/null +++ b/projects/EU-Utility/assets/icons/weapon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/EU-Utility/core/floating_icon.py b/projects/EU-Utility/core/floating_icon.py index 80df404..71faf78 100644 --- a/projects/EU-Utility/core/floating_icon.py +++ b/projects/EU-Utility/core/floating_icon.py @@ -1,24 +1,26 @@ """ EU-Utility - Floating Icon -In-game floating button styled to match Entropia Universe UI. -Uses white/frosted icon style. +In-game floating button with Phosphor solid icons. """ +from pathlib import Path from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication from PyQt6.QtCore import Qt, QPoint, pyqtSignal, QSize -from PyQt6.QtGui import QMouseEvent, QEnterEvent, QFont, QGraphicsDropShadowEffect, QColor +from PyQt6.QtGui import QMouseEvent, QEnterEvent, QFont, QGraphicsDropShadowEffect, QColor, QPixmap, QPainter +from PyQt6.QtSvg import QSvgRenderer class FloatingIcon(QWidget): - """Draggable floating icon that matches Entropia Universe UI.""" + """Draggable floating icon with Phosphor solid icon.""" clicked = pyqtSignal() + ICONS_DIR = Path(__file__).parent.parent / "assets" / "icons" def __init__(self, parent=None): super().__init__(parent) - # Frameless, always on top, click-through when not interacting + # Frameless, always on top self.setWindowFlags( Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint | @@ -28,43 +30,60 @@ class FloatingIcon(QWidget): self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setFixedSize(40, 40) - # Position - near top-left game icons (offset from corner) + # Position - near top-left game icons screen = QApplication.primaryScreen().geometry() - # Position near other game UI elements (top left area) self.move(250, 10) self.dragging = False self.drag_position = QPoint() - self.click_threshold = 5 # pixels + self.click_threshold = 5 self.click_start_pos = QPoint() self._setup_ui() + def _load_svg_icon(self, name, size=24): + """Load SVG icon as pixmap.""" + svg_path = self.ICONS_DIR / f"{name}.svg" + if not svg_path.exists(): + return None + + renderer = QSvgRenderer(str(svg_path)) + pixmap = QPixmap(size, size) + pixmap.fill(Qt.GlobalColor.transparent) + + painter = QPainter(pixmap) + renderer.render(painter) + painter.end() + + return pixmap + def _setup_ui(self): - """Setup the floating icon with EU-style white/frosted look.""" + """Setup floating icon with Phosphor target icon.""" layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) - # Diamond shape - clean, sci-fi, white/frosted - self.icon_label = QLabel("◆") + self.icon_label = QLabel() self.icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.icon_label.setFixedSize(40, 40) - # EU-style: frosted glass effect - # Dark background with subtle white border and glow + # Load Phosphor target icon + pixmap = self._load_svg_icon("target", size=22) + if pixmap: + self.icon_label.setPixmap(pixmap) + else: + self.icon_label.setText("◆") + + # EU-style frosted glass self.icon_label.setStyleSheet(""" QLabel { - font-size: 18px; - font-weight: bold; - color: rgba(255, 255, 255, 220); background-color: rgba(25, 30, 40, 230); border-radius: 10px; border: 1.5px solid rgba(255, 255, 255, 40); } """) - # Add subtle glow effect + # Glow effect shadow = QGraphicsDropShadowEffect() shadow.setBlurRadius(15) shadow.setColor(QColor(100, 150, 200, 80)) @@ -74,7 +93,6 @@ class FloatingIcon(QWidget): layout.addWidget(self.icon_label) def mousePressEvent(self, event: QMouseEvent): - """Handle mouse press.""" if event.button() == Qt.MouseButton.LeftButton: self.dragging = True self.click_start_pos = event.globalPosition().toPoint() @@ -82,48 +100,33 @@ class FloatingIcon(QWidget): event.accept() def mouseMoveEvent(self, event: QMouseEvent): - """Handle mouse move for dragging.""" if self.dragging: new_pos = event.globalPosition().toPoint() - self.drag_position self.move(new_pos) event.accept() def mouseReleaseEvent(self, event: QMouseEvent): - """Handle mouse release - detect click vs drag.""" if event.button() == Qt.MouseButton.LeftButton: release_pos = event.globalPosition().toPoint() distance = (release_pos - self.click_start_pos).manhattanLength() - self.dragging = False - - # If moved less than threshold, treat as click if distance < self.click_threshold: self.clicked.emit() - event.accept() def enterEvent(self, event: QEnterEvent): - """Mouse entered - highlight with frosted effect.""" self.icon_label.setStyleSheet(""" QLabel { - font-size: 18px; - font-weight: bold; - color: white; background-color: rgba(45, 60, 85, 250); border-radius: 10px; border: 1.5px solid rgba(120, 180, 255, 100); } """) - # Change cursor to indicate clickable self.setCursor(Qt.CursorShape.PointingHandCursor) def leaveEvent(self, event): - """Mouse left - normal frosted look.""" self.icon_label.setStyleSheet(""" QLabel { - font-size: 18px; - font-weight: bold; - color: rgba(255, 255, 255, 220); background-color: rgba(25, 30, 40, 230); border-radius: 10px; border: 1.5px solid rgba(255, 255, 255, 40); diff --git a/projects/EU-Utility/core/overlay_window.py b/projects/EU-Utility/core/overlay_window.py index 9bfa04c..3898880 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 -Spotlight-style overlay with frosted glass effect and custom icons. +Spotlight-style overlay with frosted glass effect and Phosphor icons. """ import sys @@ -15,19 +15,60 @@ try: QMenu, QApplication, QFrame, QGraphicsDropShadowEffect ) from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QSize - from PyQt6.QtGui import QAction, QIcon, QColor, QFont + from PyQt6.QtGui import QAction, QIcon, QColor, QFont, QPixmap, QPainter + from PyQt6.QtSvg import QSvgRenderer PYQT6_AVAILABLE = True except ImportError: PYQT6_AVAILABLE = False print("PyQt6 not available. Install with: pip install PyQt6") +class IconHelper: + """Helper to load and render SVG icons.""" + + ICONS_DIR = Path(__file__).parent.parent / "assets" / "icons" + + @classmethod + def get_icon(cls, name, size=24, color="white"): + """Get QIcon from SVG.""" + svg_path = cls.ICONS_DIR / f"{name}.svg" + if not svg_path.exists(): + return None + + renderer = QSvgRenderer(str(svg_path)) + pixmap = QPixmap(size, size) + pixmap.fill(Qt.GlobalColor.transparent) + + painter = QPainter(pixmap) + renderer.render(painter) + painter.end() + + return QIcon(pixmap) + + @classmethod + def get_pixmap(cls, name, size=24): + """Get QPixmap from SVG.""" + svg_path = cls.ICONS_DIR / f"{name}.svg" + if not svg_path.exists(): + return None + + renderer = QSvgRenderer(str(svg_path)) + pixmap = QPixmap(size, size) + pixmap.fill(Qt.GlobalColor.transparent) + + painter = QPainter(pixmap) + renderer.render(painter) + painter.end() + + return pixmap + + class OverlayWindow(QMainWindow): """Spotlight-style overlay window.""" visibility_changed = pyqtSignal(bool) - # Plugin icon mapping - white/frosted style icons + # Plugin icon mapping - Phosphor solid icons PLUGIN_ICONS = { "Universal Search": ("search", "#4a9eff"), "Calculator": ("calculator", "#9c27b0"), @@ -37,7 +78,7 @@ class OverlayWindow(QMainWindow): "Skill Scanner": ("skills", "#00bcd4"), } - # Emoji fallbacks for frosted look + # Emoji fallbacks ICONS = { 'search': '🔍', 'calculator': '🧮', @@ -199,7 +240,7 @@ class OverlayWindow(QMainWindow): layout.addWidget(self.container) def _setup_plugin_bar(self, layout): - """Setup circular plugin icon bar at bottom with frosted style.""" + """Setup circular plugin icon bar at bottom with Phosphor icons.""" bar = QWidget() bar.setStyleSheet(""" QWidget { @@ -218,19 +259,26 @@ class OverlayWindow(QMainWindow): btn = QPushButton() # Get icon and color for this plugin - icon_key, accent_color = self.PLUGIN_ICONS.get( + icon_name, accent_color = self.PLUGIN_ICONS.get( plugin.name, - ("menu", "#4a9eff") + ("target", "#4a9eff") ) - icon_emoji = self.ICONS.get(icon_key, '⚡') - btn.setText(icon_emoji) + # Try to load SVG icon + icon = IconHelper.get_icon(icon_name, size=20) + if icon: + btn.setIcon(icon) + btn.setIconSize(QSize(20, 20)) + btn.setText("") # No text, just icon + else: + # Fallback to emoji + emoji = self.ICONS.get(icon_name, '◆') + btn.setText(emoji) + btn.setFixedSize(40, 40) btn.setStyleSheet(f""" QPushButton {{ background-color: rgba(255, 255, 255, 12); - color: white; - font-size: 18px; border: 1px solid rgba(255, 255, 255, 20); border-radius: 20px; }}