From 3943a5cdf5d8cbc59713971c608d847f7b8cfd81 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Wed, 11 Feb 2026 18:47:35 +0000 Subject: [PATCH] fix: standalone extractor - clean UI and icon support UI Cleanup: - Removed gamepad from header - Removed emojis from footer - Cleaned up group box titles (no emojis in section headers) - Tighter spacing in all boxes for better fit - Shorter path displays with tooltips for full paths - Reduced padding and margins throughout Layout Improvements: - Cache Source: Shows shortened path with tooltip for full path - Output Location: Cleaner display with consistent styling - All boxes now fit content without overflow - Reduced minimum window size slightly Icon Support: - Added header icon placeholder (48x48) - _load_icon() method loads icon.ico or icon.png - Icon appears in window title bar and header - Falls back gracefully if no icon file present To add your icon: Place icon.ico or icon.png in same folder as the script, or in assets/ folder --- standalone_icon_extractor.py | 213 ++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 92 deletions(-) diff --git a/standalone_icon_extractor.py b/standalone_icon_extractor.py index def77d7..61cdce7 100644 --- a/standalone_icon_extractor.py +++ b/standalone_icon_extractor.py @@ -301,6 +301,7 @@ class IconExtractorWindow(QMainWindow): self.settings = QSettings("ImpulsiveFPS", "EUIconExtractor") self._setup_ui() + self._load_icon() self._load_settings() self._detect_subfolders() @@ -312,10 +313,23 @@ class IconExtractorWindow(QMainWindow): layout.setContentsMargins(15, 15, 15, 15) layout.setSpacing(10) - # Header - header = QLabel("🎮 Entropia Universe Icon Extractor") - header.setStyleSheet("font-size: 24px; font-weight: bold; color: #4caf50; padding-bottom: 5px;") - layout.addWidget(header) + # Header with icon + header_layout = QHBoxLayout() + header_layout.setSpacing(15) + + # Icon label (will be set if icon exists) + self.header_icon = QLabel() + self.header_icon.setFixedSize(48, 48) + self.header_icon.setStyleSheet("background: transparent;") + header_layout.addWidget(self.header_icon) + + # Title + header = QLabel("Entropia Universe Icon Extractor") + header.setStyleSheet("font-size: 22px; font-weight: bold; color: #4caf50;") + header_layout.addWidget(header, 1) + header_layout.addStretch() + + layout.addLayout(header_layout) # Description - two lines with clickable link desc_widget = QWidget() @@ -355,45 +369,47 @@ class IconExtractorWindow(QMainWindow): left_layout.setSpacing(10) # Cache folder - cache_group = QGroupBox("📂 Cache Source") + cache_group = QGroupBox("Cache Source") cache_group.setStyleSheet("QGroupBox { font-size: 13px; font-weight: bold; }") cache_layout = QVBoxLayout(cache_group) - cache_layout.setContentsMargins(12, 18, 12, 12) - cache_layout.setSpacing(10) + cache_layout.setContentsMargins(10, 15, 10, 10) + cache_layout.setSpacing(8) - # Base path (hardcoded) - path_display = str(self.base_cache_path).replace("/", "\\") + # Base path (hardcoded) - show just the end part + path_display = "...\\Entropia Universe\\public_users_data\\cache\\icon" + self.cache_path_full = str(self.base_cache_path).replace("/", "\\") self.cache_label = QLabel(path_display) self.cache_label.setStyleSheet( "font-family: Consolas; font-size: 11px; color: #aaa; " - "padding: 8px; background: #252525; border-radius: 4px;" + "padding: 6px 8px; background: #252525; border-radius: 3px;" ) - self.cache_label.setWordWrap(True) + self.cache_label.setToolTip(self.cache_path_full) cache_layout.addWidget(self.cache_label) - # Subfolder selector + # Subfolder selector in one row subfolder_layout = QHBoxLayout() - subfolder_layout.setSpacing(10) - subfolder_label = QLabel("📁 Version:") + subfolder_layout.setSpacing(8) + + subfolder_label = QLabel("Version:") subfolder_label.setStyleSheet("font-size: 12px;") subfolder_layout.addWidget(subfolder_label) self.subfolder_combo = QComboBox() - self.subfolder_combo.setMinimumWidth(200) - self.subfolder_combo.setStyleSheet("font-size: 12px; padding: 4px;") + self.subfolder_combo.setMinimumWidth(180) + self.subfolder_combo.setStyleSheet("font-size: 12px; padding: 3px;") self.subfolder_combo.currentIndexChanged.connect(self._on_subfolder_changed) subfolder_layout.addWidget(self.subfolder_combo, 1) - refresh_btn = QPushButton("🔄 Refresh") - refresh_btn.setMaximumWidth(80) - refresh_btn.setStyleSheet("font-size: 11px; padding: 5px;") + refresh_btn = QPushButton("Refresh") + refresh_btn.setMaximumWidth(70) + refresh_btn.setStyleSheet("font-size: 11px; padding: 4px;") refresh_btn.clicked.connect(self._detect_subfolders) subfolder_layout.addWidget(refresh_btn) cache_layout.addLayout(subfolder_layout) # All subfolders checkbox - self.all_subfolders_check = QCheckBox("☑️ Include ALL version folders") + self.all_subfolders_check = QCheckBox("Include ALL version folders") self.all_subfolders_check.setStyleSheet("font-size: 12px;") self.all_subfolders_check.setToolTip("Merge icons from all game versions") self.all_subfolders_check.stateChanged.connect(self._on_all_subfolders_changed) @@ -402,76 +418,75 @@ class IconExtractorWindow(QMainWindow): left_layout.addWidget(cache_group) # Output folder - output_group = QGroupBox("💾 Output Location") + output_group = QGroupBox("Output Location") output_group.setStyleSheet("QGroupBox { font-size: 13px; font-weight: bold; }") output_layout = QVBoxLayout(output_group) - output_layout.setContentsMargins(12, 18, 12, 12) - output_layout.setSpacing(10) + output_layout.setContentsMargins(10, 15, 10, 10) + output_layout.setSpacing(8) - output_info = QLabel("📁 Icons saved to your Documents folder (same location as chat.log)") + output_info = QLabel("Saved to Documents folder (same location as chat.log)") output_info.setStyleSheet("color: #aaaaaa; font-size: 12px;") - output_info.setWordWrap(True) output_layout.addWidget(output_info) - rel_path = "Documents/Entropia Universe/Icons/" - self.output_label = QLabel(f"📂 {rel_path}") + rel_path = "Documents\\Entropia Universe\\Icons\\" + self.output_label = QLabel(rel_path) self.output_label.setStyleSheet( "font-family: Consolas; font-size: 11px; color: #aaa; " - "padding: 8px; background: #252525; border-radius: 4px;" + "padding: 6px 8px; background: #252525; border-radius: 3px;" ) output_layout.addWidget(self.output_label) - change_btn = QPushButton("📂 Change Output Folder...") - change_btn.setStyleSheet("font-size: 11px; padding: 6px;") + change_btn = QPushButton("Change Output Folder...") + change_btn.setStyleSheet("font-size: 11px; padding: 5px;") change_btn.clicked.connect(self._browse_output) output_layout.addWidget(change_btn) left_layout.addWidget(output_group) # Settings (simplified - just 320x320) - settings_group = QGroupBox("⚙️ Export Settings") + settings_group = QGroupBox("Export Settings") settings_group.setStyleSheet("QGroupBox { font-size: 13px; font-weight: bold; }") settings_layout = QVBoxLayout(settings_group) - settings_layout.setContentsMargins(12, 18, 12, 12) + settings_layout.setContentsMargins(10, 15, 10, 10) settings_info = QLabel( - "🖼️ Format: PNG with transparency\n" - "📐 Canvas: 320x320 pixels (centered)\n" - "📏 Size: Original icon size (no upscaling)" + "Format: PNG with transparency\n" + "Canvas: 320x320 pixels (centered)\n" + "Size: Original icon size (no upscaling)" ) - settings_info.setStyleSheet("color: #aaaaaa; font-size: 12px; line-height: 1.5;") + settings_info.setStyleSheet("color: #aaaaaa; font-size: 12px; line-height: 1.4;") settings_layout.addWidget(settings_info) left_layout.addWidget(settings_group) # Nexus link - nexus_group = QGroupBox("🌐 EntropiaNexus.com") + nexus_group = QGroupBox("EntropiaNexus.com") nexus_group.setStyleSheet("QGroupBox { font-size: 13px; font-weight: bold; color: #4caf50; }") nexus_layout = QVBoxLayout(nexus_group) - nexus_layout.setContentsMargins(12, 18, 12, 12) + nexus_layout.setContentsMargins(10, 15, 10, 10) - nexus_info = QLabel("📤 Submit icons to help complete the item database") + nexus_info = QLabel("Submit icons to help complete the item database") nexus_info.setStyleSheet("color: #cccccc; font-size: 12px;") nexus_layout.addWidget(nexus_info) - nexus_btn = QPushButton("🌐 Open EntropiaNexus.com") - nexus_btn.setMinimumHeight(32) - nexus_btn.setStyleSheet("font-size: 11px; padding: 6px;") + nexus_btn = QPushButton("Open EntropiaNexus.com") + nexus_btn.setMinimumHeight(28) + nexus_btn.setStyleSheet("font-size: 11px; padding: 5px;") nexus_btn.clicked.connect(lambda: self._open_url(WEBSITE)) nexus_layout.addWidget(nexus_btn) left_layout.addWidget(nexus_group) # Convert button - self.convert_btn = QPushButton("▶️ Start Extracting Icons") - self.convert_btn.setMinimumHeight(55) + self.convert_btn = QPushButton("Start Extracting Icons") + self.convert_btn.setMinimumHeight(50) self.convert_btn.setStyleSheet(""" QPushButton { background-color: #1565c0; font-weight: bold; font-size: 14px; - border-radius: 6px; - padding: 12px; + border-radius: 5px; + padding: 10px; color: white; } QPushButton:hover { background-color: #1976d2; } @@ -487,7 +502,7 @@ class IconExtractorWindow(QMainWindow): self.progress_bar.setVisible(False) left_layout.addWidget(self.progress_bar) - self.status_label = QLabel("✅ Ready") + self.status_label = QLabel("Ready") self.status_label.setStyleSheet("color: #888; font-size: 12px; padding: 5px;") self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) left_layout.addWidget(self.status_label) @@ -501,47 +516,47 @@ class IconExtractorWindow(QMainWindow): right_layout = QVBoxLayout(right_panel) right_layout.setContentsMargins(0, 0, 0, 0) - files_group = QGroupBox("📄 Available Icons") + files_group = QGroupBox("Available Icons") files_group.setStyleSheet("QGroupBox { font-size: 13px; font-weight: bold; }") files_layout = QVBoxLayout(files_group) - files_layout.setContentsMargins(12, 18, 12, 12) - files_layout.setSpacing(10) + files_layout.setContentsMargins(10, 15, 10, 10) + files_layout.setSpacing(8) - files_info = QLabel("💡 Double-click an icon to preview. Select icons to extract (or leave blank for all).") + files_info = QLabel("Double-click an icon to preview. Select icons to extract (or leave blank for all).") files_info.setStyleSheet("color: #aaaaaa; font-size: 12px;") files_layout.addWidget(files_info) - self.files_count_label = QLabel("❓ No files found") - self.files_count_label.setStyleSheet("font-weight: bold; font-size: 12px; padding: 5px 0;") + self.files_count_label = QLabel("No files found") + self.files_count_label.setStyleSheet("font-weight: bold; font-size: 12px; padding: 3px 0;") files_layout.addWidget(self.files_count_label) self.files_list = QListWidget() self.files_list.setSelectionMode(QListWidget.SelectionMode.ExtendedSelection) - self.files_list.setStyleSheet("font-size: 12px; padding: 3px;") + self.files_list.setStyleSheet("font-size: 12px; padding: 2px;") self.files_list.doubleClicked.connect(self._on_file_double_clicked) files_layout.addWidget(self.files_list, 1) # Selection buttons sel_layout = QHBoxLayout() - sel_layout.setSpacing(10) + sel_layout.setSpacing(8) - select_all_btn = QPushButton("☑️ Select All") - select_all_btn.setMaximumWidth(110) - select_all_btn.setStyleSheet("font-size: 11px; padding: 5px;") + select_all_btn = QPushButton("Select All") + select_all_btn.setMaximumWidth(90) + select_all_btn.setStyleSheet("font-size: 11px; padding: 4px;") select_all_btn.clicked.connect(self.files_list.selectAll) sel_layout.addWidget(select_all_btn) - select_none_btn = QPushButton("⬜ Select None") - select_none_btn.setMaximumWidth(110) - select_none_btn.setStyleSheet("font-size: 11px; padding: 5px;") + select_none_btn = QPushButton("Select None") + select_none_btn.setMaximumWidth(90) + select_none_btn.setStyleSheet("font-size: 11px; padding: 4px;") select_none_btn.clicked.connect(self.files_list.clearSelection) sel_layout.addWidget(select_none_btn) sel_layout.addStretch() - open_folder_btn = QPushButton("📂 Open Output Folder") - open_folder_btn.setMaximumWidth(140) - open_folder_btn.setStyleSheet("font-size: 11px; padding: 5px;") + open_folder_btn = QPushButton("Open Output Folder") + open_folder_btn.setMaximumWidth(120) + open_folder_btn.setStyleSheet("font-size: 11px; padding: 4px;") open_folder_btn.clicked.connect(self._open_output_folder) sel_layout.addWidget(open_folder_btn) @@ -554,7 +569,7 @@ class IconExtractorWindow(QMainWindow): layout.addWidget(splitter, 1) # Important Information (moved to bottom) - notice_group = QGroupBox("⚠️ Important Information") + notice_group = QGroupBox("Important Information") notice_group.setStyleSheet(""" QGroupBox { font-size: 13px; @@ -563,19 +578,20 @@ class IconExtractorWindow(QMainWindow): } """) notice_layout = QVBoxLayout(notice_group) - notice_layout.setContentsMargins(12, 18, 12, 12) + notice_layout.setContentsMargins(10, 15, 10, 10) notice_text = QTextEdit() notice_text.setReadOnly(True) + notice_text.setMaximumHeight(70) notice_text.setStyleSheet(""" QTextEdit { background-color: #2d2818; color: #ffc107; border: 1px solid #5d4e37; - border-radius: 4px; - font-size: 13px; - padding: 10px; - line-height: 1.5; + border-radius: 3px; + font-size: 12px; + padding: 8px; + line-height: 1.4; } """) notice_text.setText( @@ -586,25 +602,25 @@ class IconExtractorWindow(QMainWindow): notice_layout.addWidget(notice_text) layout.addWidget(notice_group) - # Footer with clickable links + # Footer with clickable links (no emojis) footer_widget = QWidget() footer_layout = QVBoxLayout(footer_widget) footer_layout.setContentsMargins(10, 10, 10, 10) footer_layout.setSpacing(5) - # First line - developer info - footer_line1 = QLabel(f"👨‍💻 Developed by {DEVELOPER} | 💬 Discord: {DISCORD} | 📎 GitHub: (coming soon)") + # First line - developer info (no emojis) + footer_line1 = QLabel(f"Developed by {DEVELOPER} | Discord: {DISCORD} | GitHub: (coming soon)") footer_line1.setStyleSheet("color: #888; font-size: 11px;") footer_line1.setAlignment(Qt.AlignmentFlag.AlignCenter) footer_layout.addWidget(footer_line1) - # Second line - disclaimer with links + # Second line - disclaimer with links (no emojis) disclaimer_widget = QWidget() disclaimer_layout = QHBoxLayout(disclaimer_widget) disclaimer_layout.setContentsMargins(0, 0, 0, 0) disclaimer_layout.setSpacing(0) - label1 = QLabel("📜 Entropia Universe Icon Extractor is a fan-made resource and is not affiliated with ") + label1 = QLabel("Entropia Universe Icon Extractor is a fan-made resource and is not affiliated with ") label1.setStyleSheet("color: #666; font-size: 10px;") label1.setOpenExternalLinks(True) @@ -612,9 +628,6 @@ class IconExtractorWindow(QMainWindow): mindark_link.setStyleSheet("color: #666; font-size: 10px;") mindark_link.setOpenExternalLinks(True) - label2 = QLabel("") - label2.setStyleSheet("color: #666; font-size: 10px;") - eu_link = QLabel('Entropia Universe') eu_link.setStyleSheet("color: #666; font-size: 10px;") eu_link.setOpenExternalLinks(True) @@ -649,12 +662,37 @@ class IconExtractorWindow(QMainWindow): import webbrowser webbrowser.open(url) + def _load_icon(self): + """Load and set the application icon.""" + # Try to load icon from various locations + icon_paths = [ + Path(__file__).parent / "assets" / "icon.ico", + Path(__file__).parent / "assets" / "icon.png", + Path(__file__).parent / "icon.ico", + Path(__file__).parent / "icon.png", + ] + + for icon_path in icon_paths: + if icon_path.exists(): + pixmap = QPixmap(str(icon_path)) + if not pixmap.isNull(): + # Set window icon + self.setWindowIcon(QIcon(pixmap)) + # Set header icon (scaled to 48x48) + header_pixmap = pixmap.scaled(48, 48, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation) + self.header_icon.setPixmap(header_pixmap) + return True + + # Hide header icon if no icon found + self.header_icon.hide() + return False + def _load_settings(self): """Load saved settings.""" # Output folder saved_output = self.settings.value("output_dir", str(self.converter.output_dir)) self.converter.output_dir = Path(saved_output) - self.output_label.setText("Documents/Entropia Universe/Icons/") + self.output_label.setText("Documents\\Entropia Universe\\Icons\\") def _save_settings(self): """Save current settings.""" @@ -862,19 +900,10 @@ class IconExtractorWindow(QMainWindow): def set_app_icon(app: QApplication): - """Set application icon.""" - # Try to load icon from various locations - icon_paths = [ - Path(__file__).parent / "assets" / "icon.ico", - Path(__file__).parent / "assets" / "icon.png", - Path(__file__).parent / "icon.ico", - Path(__file__).parent / "icon.png", - ] - - for icon_path in icon_paths: - if icon_path.exists(): - app.setWindowIcon(QIcon(str(icon_path))) - return + """Set application icon (window icon is set per-window in _load_icon).""" + # Icon is loaded per-window in IconExtractorWindow._load_icon() + # This function is kept for compatibility but doesn't need to do anything + pass def main():