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:
parent
ea9a73c8b4
commit
d3d69c41cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
}}
|
||||
"""
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue