style: white/frosted icon theme for EU aesthetic

- 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
This commit is contained in:
LemonNexus 2026-02-13 13:32:36 +00:00
parent ea9a73c8b4
commit d3d69c41cc
3 changed files with 239 additions and 54 deletions

View File

@ -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

View File

@ -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'<span style="font-size: {size}px;">{emoji}</span>'
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};
}}
"""

View File

@ -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)