Some temp linux icons I suppose.

This commit is contained in:
DazedAnon 2026-06-13 15:25:21 -05:00
parent 80d203ec06
commit 9ff0a0c2c7
10 changed files with 197 additions and 58 deletions

View file

@ -13,6 +13,7 @@ from PyQt5.QtWidgets import (
)
from PyQt5.QtCore import Qt, pyqtSignal, QTimer, QThread
from PyQt5.QtGui import QIcon
from gui.platform_glyph import platform_glyph
from dotenv import load_dotenv, set_key, dotenv_values
from gui.rpgmaker_tab import RPGMakerTab
@ -95,7 +96,7 @@ class ModelFetchThread(QThread):
def create_section_header(title):
"""Create a clean section header without boxes."""
label = QLabel(title)
label = QLabel(platform_glyph(title))
label.setStyleSheet("""
QLabel {
font-size: 13px;
@ -247,29 +248,13 @@ class ConfigTab(QWidget):
def create_nav_button(self, icon_text, tooltip):
"""Create a navigation button for the top bar."""
from gui.platform_glyph import configure_nav_toolbutton
btn = QToolButton()
btn.setText(icon_text)
btn.setToolTip(tooltip)
btn.setFixedSize(50, 50)
btn.setCheckable(True)
btn.setStyleSheet("""
QToolButton {
background-color: transparent;
border: none;
border-bottom: 3px solid transparent;
color: #cccccc;
font-size: 24px;
padding: 5px;
}
QToolButton:hover {
background-color: #3e3e42;
}
QToolButton:checked {
background-color: #37373d;
border-bottom: 3px solid #007acc;
color: #ffffff;
}
""")
configure_nav_toolbutton(btn, icon_text, horizontal=True)
return btn
def switch_page(self, index):
@ -611,7 +596,7 @@ class ConfigTab(QWidget):
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
reset_button = QPushButton("🔄 Reset to Defaults")
reset_button = QPushButton(platform_glyph("🔄 Reset to Defaults"))
reset_button.clicked.connect(self.reset_to_defaults_with_save)
reset_button.setMinimumHeight(32)

View file

@ -8,6 +8,7 @@ from PyQt5.QtWidgets import (
QPushButton, QLabel, QMessageBox, QSpinBox, QFrame, QComboBox
)
from PyQt5.QtCore import Qt, pyqtSignal
from gui.platform_glyph import platform_glyph
try:
from .config_integration import ConfigIntegration
@ -17,7 +18,7 @@ except ImportError:
def create_section_label(text):
"""Create a section label for grouping settings."""
label = QLabel(text)
label = QLabel(platform_glyph(text))
label.setStyleSheet("""
QLabel {
font-size: 12px;
@ -247,7 +248,7 @@ class CSVTab(QWidget):
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
self.reset_button = QPushButton("🔄 Reset to Defaults")
self.reset_button = QPushButton(platform_glyph("🔄 Reset to Defaults"))
self.reset_button.clicked.connect(self.reset_to_defaults_with_message)
self.reset_button.setMaximumWidth(180)
self.reset_button.setMinimumHeight(32)

View file

@ -7,6 +7,7 @@ from PyQt5.QtWidgets import (
)
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
from PyQt5.QtGui import QTextCursor, QFont, QTextCharFormat
from gui.platform_glyph import platform_glyph
from pathlib import Path
import datetime
import html
@ -34,7 +35,7 @@ class LogViewer(QWidget):
layout.setContentsMargins(0, 0, 0, 0)
# Simple header to match left-side styling (use same look as create_section_header)
header = QLabel("📝 Translation Log")
header = QLabel(platform_glyph("📝 Translation Log"))
header.setStyleSheet("""
QLabel {
font-size: 13px;

View file

@ -455,29 +455,13 @@ class DazedMTLGUI(QMainWindow):
def create_nav_button(self, icon_text, tooltip):
"""Create a navigation button for the sidebar."""
from gui.platform_glyph import configure_nav_toolbutton
btn = QToolButton()
btn.setText(icon_text)
btn.setToolTip(tooltip)
btn.setFixedSize(60, 50)
btn.setCheckable(True)
btn.setStyleSheet("""
QToolButton {
background-color: transparent;
border: none;
border-left: 3px solid transparent;
color: #cccccc;
font-size: 24px;
padding: 5px;
}
QToolButton:hover {
background-color: #3e3e42;
}
QToolButton:checked {
background-color: #37373d;
border-left: 3px solid #007acc;
color: #ffffff;
}
""")
configure_nav_toolbutton(btn, icon_text, horizontal=False)
return btn
def switch_page(self, index):

162
gui/platform_glyph.py Normal file
View file

@ -0,0 +1,162 @@
"""Linux fallbacks for emoji that PyQt5 often cannot render (tofu boxes).
Only replaces glyphs known to fail on typical Linux font stacks.
Windows/macOS get the original strings unchanged.
"""
from __future__ import annotations
import re
import sys
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QColor, QFont, QIcon, QPainter, QPixmap
# Toolbar buttons, section headers, mixed labels
_LINUX_EMOJI_FALLBACKS: dict[str, str] = {
"\U00002795": "+", # add
"\U0001F4C1": "\u2302", # 📁 folder → ⌂
"\U0001F4C2": "\u2302", # 📂 open folder
"\U0001F504": "\u21bb", # 🔄 refresh → ↻
"\U0001F4DD": "", # 📝 memo (section headers)
"\U0001F6D1": "\u25a0", # 🛑 stop → ■
"\U0001F4E5": "\u2193", # 📥 inbox tray → ↓
"\U0001F527": "\u2699", # 🔧 wrench → ⚙
"\U0001F511": "", # 🔑 key (section headers)
"\U0001F310": "", # 🌐 globe (section headers)
"\U0001F5A5": "", # 🖥 desktop (section headers)
"\U00002699\uFE0F": "\u2699", # ⚙️ → ⚙
"\U0000270F\uFE0F": "\u270E", # ✏️ → ✎
}
# Icon-only nav tabs — never empty; BMP symbols so metrics match across the bar
_LINUX_NAV_FALLBACKS: dict[str, str] = {
"\U0001F310": "\u25ce", # 🌐 Translation → ◎
"\U0001F527": "\u2699", # 🔧 General → ⚙
"\U0001F3AE": "\u25c6", # 🎮 MV/MZ → ◆
"\U0001F43A": "\u25c8", # 🐺 Wolf → ◈
"\U0001F4C4": "\u2630", # 📄 CSV → ☰
"\U00002694\uFE0F": "\u2694", # ⚔️ SRPG → ⚔
"\U00002694": "\u2694",
"\U0001F504": "\u21bb", # 🔄 Update → ↻
"\U00002699\uFE0F": "\u2699", # ⚙️ Config → ⚙
"\U0000270F\uFE0F": "\u270E", # ✏️ Rewrite → ✎
"\U000026A1": "\u26a1", # ⚡ Workflow
}
def _apply_fallbacks(text: str, mapping: dict[str, str]) -> str:
out = text
for emoji, replacement in mapping.items():
out = out.replace(emoji, replacement)
out = re.sub(r" +", " ", out)
return out.strip()
def platform_glyph(text: str) -> str:
"""Return UI text with unsupported emoji swapped on Linux only."""
if not sys.platform.startswith("linux") or not text:
return text
return _apply_fallbacks(text, _LINUX_EMOJI_FALLBACKS)
def platform_nav_glyph(icon: str) -> str:
"""Linux fallback for icon-only nav tabs (never returns empty)."""
if not sys.platform.startswith("linux") or not icon:
return icon
out = _apply_fallbacks(icon, _LINUX_NAV_FALLBACKS)
if not out:
out = _apply_fallbacks(icon, _LINUX_EMOJI_FALLBACKS)
return out or icon
def _linux_nav_pixmap(glyph: str, *, size: int, font_px: int, color: QColor) -> QPixmap:
pixmap = QPixmap(size, size)
pixmap.fill(Qt.transparent)
painter = QPainter(pixmap)
font = QFont("DejaVu Sans")
font.setPixelSize(font_px)
painter.setFont(font)
painter.setPen(color)
painter.drawText(pixmap.rect(), Qt.AlignCenter, glyph)
painter.end()
return pixmap
def _linux_nav_icon(icon_text: str, *, size: int, font_px: int) -> QIcon:
"""Render a nav glyph into a fixed-size pixmap so every tab aligns the same."""
glyph = platform_nav_glyph(icon_text)
icon = QIcon()
gray = _linux_nav_pixmap(glyph, size=size, font_px=font_px, color=QColor("#cccccc"))
white = _linux_nav_pixmap(glyph, size=size, font_px=font_px, color=QColor("#ffffff"))
icon.addPixmap(gray, QIcon.Normal, QIcon.Off)
icon.addPixmap(gray, QIcon.Disabled, QIcon.Off)
icon.addPixmap(white, QIcon.Active, QIcon.Off)
icon.addPixmap(white, QIcon.Selected, QIcon.Off)
return icon
def _nav_toolbutton_stylesheet(*, horizontal: bool, icon_only: bool) -> str:
border_prop = "border-bottom" if horizontal else "border-left"
if icon_only:
return f"""
QToolButton {{
background-color: transparent;
border: none;
{border_prop}: 3px solid transparent;
color: #cccccc;
padding: 0px;
margin: 0px;
}}
QToolButton:hover {{
background-color: #3e3e42;
}}
QToolButton:checked {{
background-color: #37373d;
{border_prop}: 3px solid #007acc;
color: #ffffff;
}}
"""
font_size = "18px" if sys.platform.startswith("linux") else "24px"
return f"""
QToolButton {{
background-color: transparent;
border: none;
{border_prop}: 3px solid transparent;
color: #cccccc;
font-size: {font_size};
font-family: 'DejaVu Sans Mono', monospace;
padding: 0px;
margin: 0px;
}}
QToolButton:hover {{
background-color: #3e3e42;
}}
QToolButton:checked {{
background-color: #37373d;
{border_prop}: 3px solid #007acc;
color: #ffffff;
}}
"""
def configure_nav_toolbutton(btn, icon_text: str, *, horizontal: bool = False) -> None:
"""Apply nav icon — on Linux render BMP symbols into fixed pixmaps for alignment."""
if sys.platform.startswith("linux"):
# Scale to the button cell (leave room for the 3px active border).
icon_dim = max(28, min(btn.width(), btn.height()) - 8)
font_px = max(22, int(icon_dim * 0.78))
btn.setIcon(_linux_nav_icon(icon_text, size=icon_dim, font_px=font_px))
btn.setIconSize(QSize(icon_dim, icon_dim))
btn.setText("")
btn.setToolButtonStyle(Qt.ToolButtonIconOnly)
btn.setStyleSheet(_nav_toolbutton_stylesheet(horizontal=horizontal, icon_only=True))
return
btn.setIcon(QIcon())
btn.setText(icon_text)
btn.setToolButtonStyle(Qt.ToolButtonTextOnly)
btn.setStyleSheet(_nav_toolbutton_stylesheet(horizontal=horizontal, icon_only=False))

View file

@ -10,6 +10,7 @@ from PyQt5.QtWidgets import (
QTextEdit, QSpinBox, QFrame, QGridLayout
)
from PyQt5.QtCore import Qt, pyqtSignal
from gui.platform_glyph import platform_glyph
try:
from .config_integration import ConfigIntegration
@ -25,8 +26,8 @@ except Exception:
def create_section_label(text):
"""Create a section label for grouping checkboxes."""
label = QLabel(text)
"""Create a section label for grouping settings."""
label = QLabel(platform_glyph(text))
label.setStyleSheet("""
QLabel {
font-size: 13px;
@ -456,7 +457,7 @@ class RPGMakerTab(QWidget):
# Reset button
button_layout = QHBoxLayout()
self.reset_button = QPushButton("🔄 Reset to Defaults")
self.reset_button = QPushButton(platform_glyph("🔄 Reset to Defaults"))
self.reset_button.clicked.connect(self.reset_to_defaults_with_message)
self.reset_button.setMinimumHeight(32)
self.reset_button.setMaximumWidth(160)

View file

@ -9,6 +9,7 @@ from PyQt5.QtWidgets import (
)
from PyQt5.QtCore import pyqtSignal
import re
from gui.platform_glyph import platform_glyph
try:
import set_defaults
@ -19,7 +20,7 @@ except Exception:
def create_section_label(text):
"""Create a styled section header label."""
label = QLabel(text)
label = QLabel(platform_glyph(text))
label.setStyleSheet("font-size: 12px; font-weight: bold; color: #007acc; padding: 2px 0px;")
return label
@ -83,7 +84,7 @@ class SRPGTab(QWidget):
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
self.reset_btn = QPushButton("🔄 Reset to Defaults")
self.reset_btn = QPushButton(platform_glyph("🔄 Reset to Defaults"))
self.reset_btn.clicked.connect(self.reset_to_defaults_with_message)
self.reset_btn.setMaximumWidth(180)
self.reset_btn.setMinimumHeight(32)

View file

@ -31,6 +31,7 @@ from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QThread, QMutex, QProcess, QEvent, QRect, QSettings
from PyQt5.QtGui import QFont
from gui.log_viewer import LogViewer
from gui.platform_glyph import platform_glyph
def _strip_ansi(text):
@ -41,7 +42,7 @@ def _strip_ansi(text):
def create_section_header(title):
"""Create a clean section header without boxes."""
label = QLabel(title)
label = QLabel(platform_glyph(title))
label.setStyleSheet("""
QLabel {
font-size: 13px;
@ -849,7 +850,7 @@ class TranslationTab(QWidget):
deselect_all_btn.setStyleSheet(icon_button_style)
file_buttons.addWidget(deselect_all_btn)
add_files_btn = QPushButton("")
add_files_btn = QPushButton(platform_glyph(""))
add_files_btn.setToolTip("Add files to translate")
add_files_btn.clicked.connect(self.add_input_files)
add_files_btn.setStyleSheet(icon_button_style)
@ -861,13 +862,13 @@ class TranslationTab(QWidget):
remove_files_btn.setStyleSheet(icon_button_style)
file_buttons.addWidget(remove_files_btn)
open_folder_btn = QPushButton("📁")
open_folder_btn = QPushButton(platform_glyph("📁"))
open_folder_btn.setToolTip("Open files folder in explorer")
open_folder_btn.clicked.connect(self.open_input_folder)
open_folder_btn.setStyleSheet(icon_button_style)
file_buttons.addWidget(open_folder_btn)
refresh_btn = QPushButton("🔄")
refresh_btn = QPushButton(platform_glyph("🔄"))
refresh_btn.setToolTip("Refresh file list")
refresh_btn.clicked.connect(self.refresh_file_lists)
refresh_btn.setStyleSheet(icon_button_style)
@ -1120,12 +1121,12 @@ class TranslationTab(QWidget):
self.reset_view_button.clicked.connect(self.reset_to_file_view)
self.reset_view_button.setVisible(False)
# Button to open the translations (translated) folder - icon-only
self.open_translations_button = QPushButton("📂")
self.open_translations_button = QPushButton(platform_glyph("📂"))
self.open_translations_button.setToolTip("Open the translated files folder")
self.open_translations_button.clicked.connect(self.open_output_folder)
self.open_translations_button.setVisible(False)
# Sync translated/ → files/ (RPG Maker only)
self.sync_translated_button = QPushButton("🔄")
self.sync_translated_button = QPushButton(platform_glyph("🔄"))
self.sync_translated_button.setToolTip("Sync translated/ → files/\nCopy translated files back into files/ so the next phase starts from the latest state")
self.sync_translated_button.clicked.connect(self._sync_translated_to_files)
self.sync_translated_button.setVisible(False)
@ -1195,7 +1196,7 @@ class TranslationTab(QWidget):
# Use a clear stop-sign emoji so the glyph is rendered as a stop icon
# and not as a colored square on some platforms.
self.stop_button = QPushButton("🛑")
self.stop_button = QPushButton(platform_glyph("🛑"))
self.stop_button.setToolTip("Stop Translation")
self.stop_button.clicked.connect(self.stop_translation)
self.stop_button.setStyleSheet(stop_button_style)

View file

@ -9,6 +9,7 @@ from PyQt5.QtWidgets import (
)
from PyQt5.QtCore import pyqtSignal
import re
from gui.platform_glyph import platform_glyph
try:
import set_defaults
CANONICAL_DEFAULTS = getattr(set_defaults, 'DEFAULTS', None)
@ -17,7 +18,7 @@ except Exception:
def create_section_label(text):
"""Create a styled section header label."""
label = QLabel(text)
label = QLabel(platform_glyph(text))
label.setStyleSheet("font-size: 12px; font-weight: bold; color: #007acc; padding: 2px 0px;")
return label
@ -171,7 +172,7 @@ class WolfTab(QWidget):
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
self.reset_btn = QPushButton("🔄 Reset to Defaults")
self.reset_btn = QPushButton(platform_glyph("🔄 Reset to Defaults"))
self.reset_btn.clicked.connect(self.reset_to_defaults_with_message)
self.reset_btn.setMaximumWidth(180)
self.reset_btn.setMinimumHeight(32)

View file

@ -444,7 +444,9 @@ def _make_btn(text: str, color: str = "#007acc") -> QPushButton:
def _make_icon_btn(icon_text: str, tooltip: str = "") -> QPushButton:
"""Compact icon-only button matching the Translation tab action buttons."""
btn = QPushButton(icon_text)
from gui.platform_glyph import platform_glyph
btn = QPushButton(platform_glyph(icon_text))
btn.setToolTip(tooltip)
btn.setFont(QFont("Segoe UI", 12))
btn.setFixedSize(40, 36)