From d3d69c41cc3260e685d2e4801692c1bbb786769d Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Fri, 13 Feb 2026 13:32:36 +0000 Subject: [PATCH] style: white/frosted icon theme for EU aesthetic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Floating icon now uses diamond shape (◆) with frosted glass effect - Plugin bar icons with per-plugin accent colors - Icon manager for consistent theming - Cleaner, more minimal white/frosted style - Matches Entropia Universe sci-fi aesthetic To add custom icons from flaticon.com: 1. Download white/frosted PNG icons (24x24 or 32x32) 2. Place in assets/icons/ folder 3. Icons auto-load on app start Recommended icon styles: - Minimal outline icons - White/light colored - Frosted/glass effect - Sci-fi or tech aesthetic --- projects/EU-Utility/core/floating_icon.py | 57 ++++---- projects/EU-Utility/core/icon_manager.py | 161 +++++++++++++++++++++ projects/EU-Utility/core/overlay_window.py | 75 ++++++---- 3 files changed, 239 insertions(+), 54 deletions(-) create mode 100644 projects/EU-Utility/core/icon_manager.py diff --git a/projects/EU-Utility/core/floating_icon.py b/projects/EU-Utility/core/floating_icon.py index 7fcc1c0..80df404 100644 --- a/projects/EU-Utility/core/floating_icon.py +++ b/projects/EU-Utility/core/floating_icon.py @@ -2,6 +2,7 @@ EU-Utility - Floating Icon In-game floating button styled to match Entropia Universe UI. +Uses white/frosted icon style. """ from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication @@ -25,7 +26,7 @@ class FloatingIcon(QWidget): ) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) - self.setFixedSize(42, 42) + self.setFixedSize(40, 40) # Position - near top-left game icons (offset from corner) screen = QApplication.primaryScreen().geometry() @@ -40,30 +41,33 @@ class FloatingIcon(QWidget): self._setup_ui() def _setup_ui(self): - """Setup the floating icon with EU-style.""" + """Setup the floating icon with EU-style white/frosted look.""" layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) - self.icon_label = QLabel("⚡") + # Diamond shape - clean, sci-fi, white/frosted + self.icon_label = QLabel("◆") self.icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.icon_label.setFixedSize(42, 42) + self.icon_label.setFixedSize(40, 40) - # EU-style: dark background with subtle border, hexagonal or square with rounded corners - # Matching the game's dark blue/gray aesthetic + # EU-style: frosted glass effect + # Dark background with subtle white border and glow self.icon_label.setStyleSheet(""" QLabel { - font-size: 20px; - background-color: rgba(20, 25, 35, 220); - border-radius: 8px; - border: 1px solid rgba(100, 150, 200, 80); + 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 shadow = QGraphicsDropShadowEffect() - shadow.setBlurRadius(10) - shadow.setColor(QColor(74, 158, 255, 100)) + shadow.setBlurRadius(15) + shadow.setColor(QColor(100, 150, 200, 80)) shadow.setOffset(0, 0) self.icon_label.setGraphicsEffect(shadow) @@ -99,31 +103,30 @@ class FloatingIcon(QWidget): event.accept() def enterEvent(self, event: QEnterEvent): - """Mouse entered - highlight like EU UI.""" + """Mouse entered - highlight with frosted effect.""" self.icon_label.setStyleSheet(""" QLabel { - font-size: 20px; - background-color: rgba(40, 55, 75, 240); - border-radius: 8px; - border: 1px solid rgba(100, 180, 255, 150); + 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 EU style.""" + """Mouse left - normal frosted look.""" self.icon_label.setStyleSheet(""" QLabel { - font-size: 20px; - background-color: rgba(20, 25, 35, 220); - border-radius: 8px; - border: 1px solid rgba(100, 150, 200, 80); + 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); } """) self.setCursor(Qt.CursorShape.ArrowCursor) - - def show_tooltip(self): - """Show tooltip near icon.""" - # Could implement a custom tooltip here - pass diff --git a/projects/EU-Utility/core/icon_manager.py b/projects/EU-Utility/core/icon_manager.py new file mode 100644 index 0000000..f238b98 --- /dev/null +++ b/projects/EU-Utility/core/icon_manager.py @@ -0,0 +1,161 @@ +""" +EU-Utility - Icon Manager + +Loads and manages white/frosted style icons for EU aesthetic. +Icons should be: +- White/light colored +- Frosted/glass effect +- 24x24 or 32x32 PNG with transparency +- Match Entropia Universe sci-fi style + +Recommended sources: +- flaticon.com (search: "white icon", "frosted glass", "minimal") +- phosphoricons.com (Phosphor icons - great frosted look) +- heroicons.com (outline style) +""" + +from pathlib import Path +from PyQt6.QtGui import QIcon, QPixmap, QColor +from PyQt6.QtCore import QSize + + +class IconManager: + """Manage application icons with EU styling.""" + + # Icon names mapping + ICONS = { + # Navigation + 'search': '🔍', + 'calculator': '🧮', + 'music': '🎵', + 'globe': '🌐', + 'skills': '📊', + 'camera': '📷', + + # Actions + 'scan': '📸', + 'save': '💾', + 'export': '📤', + 'copy': '📋', + 'close': '✕', + 'settings': '⚙️', + + # Status + 'success': '✓', + 'error': '✗', + 'warning': '⚠️', + 'loading': '⟳', + + # EU Specific + 'ped': 'P', + 'esi': '💉', + 'weapon': '🔫', + 'armor': '🛡️', + 'mob': '👾', + 'loot': '🎁', + } + + def __init__(self, icons_dir="assets/icons"): + self.icons_dir = Path(icons_dir) + self.custom_icons = {} + self._load_custom_icons() + + def _load_custom_icons(self): + """Load custom PNG icons if they exist.""" + if not self.icons_dir.exists(): + return + + for icon_file in self.icons_dir.glob("*.png"): + name = icon_file.stem + self.custom_icons[name] = str(icon_file) + + def get(self, name, size=24): + """Get an icon by name.""" + # Check for custom icon first + if name in self.custom_icons: + icon = QIcon(self.custom_icons[name]) + # Apply white tint if needed + return icon + + # Return emoji as fallback + return self.ICONS.get(name, '•') + + def get_emoji_label(self, name, size=20): + """Get an emoji styled as an icon label.""" + emoji = self.ICONS.get(name, '•') + return f'{emoji}' + + def tint_icon(self, icon_path, color='#ffffff'): + """Tint an icon to match EU aesthetic.""" + pixmap = QPixmap(icon_path) + + # Create tinted version + tinted = QPixmap(pixmap.size()) + tinted.fill(QColor(color)) + + # Apply original as mask + painter = QPainter(tinted) + painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform) + painter.drawPixmap(0, 0, pixmap) + painter.end() + + return QIcon(tinted) + + +# EU Styling Constants +EU_STYLES = { + 'floating_icon': """ + QLabel { + font-size: 20px; + background-color: rgba(20, 25, 35, 220); + border-radius: 8px; + border: 1px solid rgba(100, 150, 200, 80); + color: white; + } + """, + 'floating_icon_hover': """ + QLabel { + font-size: 20px; + background-color: rgba(40, 55, 75, 240); + border-radius: 8px; + border: 1px solid rgba(100, 180, 255, 150); + color: white; + } + """, + 'plugin_button': """ + QPushButton { + background-color: rgba(255, 255, 255, 15); + color: white; + font-size: 20px; + border: none; + border-radius: 22px; + } + QPushButton:hover { + background-color: rgba(255, 255, 255, 30); + } + QPushButton:checked { + background-color: #4a9eff; + } + """, +} + + +def get_frosted_button_style(color='#4a9eff'): + """Get frosted glass button style.""" + return f""" + QPushButton {{ + background-color: rgba(255, 255, 255, 15); + color: white; + border: 1px solid rgba(255, 255, 255, 30); + border-radius: 12px; + padding: 10px 20px; + font-weight: 500; + }} + QPushButton:hover {{ + background-color: rgba(255, 255, 255, 25); + border: 1px solid rgba(255, 255, 255, 50); + }} + QPushButton:pressed {{ + background-color: {color}; + }} + """ diff --git a/projects/EU-Utility/core/overlay_window.py b/projects/EU-Utility/core/overlay_window.py index 5cf2730..9bfa04c 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. +Spotlight-style overlay with frosted glass effect and custom icons. """ import sys @@ -27,6 +27,28 @@ class OverlayWindow(QMainWindow): visibility_changed = pyqtSignal(bool) + # Plugin icon mapping - white/frosted style icons + PLUGIN_ICONS = { + "Universal Search": ("search", "#4a9eff"), + "Calculator": ("calculator", "#9c27b0"), + "Spotify": ("music", "#1db954"), + "Nexus Search": ("globe", "#ff9800"), + "Game Reader": ("camera", "#f44336"), + "Skill Scanner": ("skills", "#00bcd4"), + } + + # Emoji fallbacks for frosted look + ICONS = { + 'search': '🔍', + 'calculator': '🧮', + 'music': '🎵', + 'globe': '🌐', + 'skills': '📊', + 'camera': '📷', + 'close': '✕', + 'menu': '☰', + } + def __init__(self, plugin_manager=None): super().__init__() @@ -177,7 +199,7 @@ class OverlayWindow(QMainWindow): layout.addWidget(self.container) def _setup_plugin_bar(self, layout): - """Setup circular plugin icon bar at bottom.""" + """Setup circular plugin icon bar at bottom with frosted style.""" bar = QWidget() bar.setStyleSheet(""" QWidget { @@ -188,39 +210,38 @@ class OverlayWindow(QMainWindow): """) bar_layout = QHBoxLayout(bar) bar_layout.setContentsMargins(20, 12, 20, 12) - bar_layout.setSpacing(15) + bar_layout.setSpacing(12) bar_layout.addStretch() # 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) + # Get icon and color for this plugin + icon_key, accent_color = self.PLUGIN_ICONS.get( + plugin.name, + ("menu", "#4a9eff") + ) + icon_emoji = self.ICONS.get(icon_key, '⚡') - btn.setFixedSize(44, 44) - btn.setStyleSheet(""" - QPushButton { - background-color: rgba(255, 255, 255, 15); + btn.setText(icon_emoji) + btn.setFixedSize(40, 40) + btn.setStyleSheet(f""" + QPushButton {{ + background-color: rgba(255, 255, 255, 12); color: white; - font-size: 20px; - border: none; - border-radius: 22px; - } - QPushButton:hover { - background-color: rgba(255, 255, 255, 30); - } - QPushButton:checked, QPushButton:pressed { - background-color: #4a9eff; - } + font-size: 18px; + border: 1px solid rgba(255, 255, 255, 20); + border-radius: 20px; + }} + QPushButton:hover {{ + background-color: rgba(255, 255, 255, 25); + border: 1px solid rgba(255, 255, 255, 40); + }} + QPushButton:checked {{ + background-color: {accent_color}; + border: 1px solid rgba(255, 255, 255, 50); + }} """) btn.setCheckable(True) btn.setToolTip(plugin.name)