Some temp linux icons I suppose.
This commit is contained in:
parent
80d203ec06
commit
9ff0a0c2c7
10 changed files with 197 additions and 58 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
22
gui/main.py
22
gui/main.py
|
|
@ -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
162
gui/platform_glyph.py
Normal 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))
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue