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;
}}