"""
Icon registry for JD-Xi Editor.
Provides centralized icon definitions and retrieval with fallback support.
"""
import qtawesome as qta
from decologr import Decologr as log
from PySide6.QtGui import QIcon
from jdxi_editor.jdxi.style import JDXiStyle
[docs]
class IconRegistry:
"""Centralized icon definitions and retrieval"""
# Action icons
[docs]
SETTINGS = "msc.settings"
[docs]
EXPORT = "fa5s.file-export"
[docs]
HELP = "mdi.help-rhombus-outline"
[docs]
HELP_RHOMBUS = "mdi6.help-rhombus-outline"
[docs]
QUIT = "mdi6.exit-to-app"
# File icons
[docs]
FOLDER = "ph.folders-light"
[docs]
FOLDER_OPENED = "msc.folder-opened"
[docs]
FOLDER_NOTCH_OPEN = "ph.folder-notch-open-fill"
[docs]
FILE_TEXT = "ph.file-text-light"
[docs]
FILE_TABLE1 = "mdi.book-information-variant"
[docs]
FILE_DOCUMENT = "mdi6.file-document-check-outline"
[docs]
FILE_SEARCH = "ph.file-search"
[docs]
EXCEL = "mdi.microsoft-excel"
[docs]
FILE_MTZ = "mdi.data-matrix-edit"
[docs]
FILE_MOLECULE = "mdi.molecule"
[docs]
FLOPPY_DISK = "ph.floppy-disk-fill"
# MIDI icons
[docs]
MIDI_PORT = "mdi.midi-port"
# Playback icons
[docs]
PAUSE = "ri.pause-line"
# Instrument icons
# Tab icons
[docs]
SEARCH_WEB = "mdi6.search-web"
[docs]
DATASET_PROCESSING = "mdi.database"
[docs]
PROCESSED_DATASETS = "mdi.database-check"
[docs]
MODELLED_STRUCTURES = "mdi.molecule"
[docs]
RHOFIT_PIPELINE = "mdi.pipe"
# Navigation icons
[docs]
BACK = "ri.arrow-go-back-fill"
[docs]
FORWARD = "ri.arrow-go-forward-fill"
# Control icons
[docs]
CPU = "mdi6.cpu-64-bit"
[docs]
DATASETS = "mdi.image-edit-outline"
[docs]
DATABASE = "mdi.database"
[docs]
SHIELD = "mdi.shield-account"
[docs]
TRASH_FILL = "ph.trash-fill"
[docs]
PLUS_CIRCLE = "ph.plus-circle-fill"
[docs]
PAUSE_ICON = "mdi.pause"
[docs]
SERVER_PROCESS = "msc.server-process"
# Waveform/Synth icons
[docs]
TRIANGLE_WAVE = "mdi.triangle-wave"
[docs]
SINE_WAVE = "mdi.sine-wave"
[docs]
FILTER = "ri.filter-3-fill"
[docs]
AMPLIFIER = "mdi.amplifier"
@staticmethod
[docs]
def get_icon(
icon_name: str, color: str = None, size: int = None, fallback: str = None
) -> QIcon:
"""
Get icon with fallback support.
:param icon_name: Icon identifier (e.g., "msc.run")
:param color: Optional color string (e.g., "#FF0000" or JDXiStyle.FOREGROUND)
:param size: Optional size in pixels (defaults to JDXiStyle.ICON_SIZE)
:param fallback: Fallback icon if primary fails
:return: QIcon or None if both fail
"""
try:
kwargs = {}
if color:
kwargs["color"] = color
icon = qta.icon(icon_name, **kwargs)
if icon.isNull():
raise ValueError(f"Icon {icon_name} is null")
return icon
except Exception as ex:
log.debug(f"Failed to load icon {icon_name}: {ex}")
if fallback:
try:
kwargs = {}
if color:
kwargs["color"] = color
icon = qta.icon(fallback, **kwargs)
if not icon.isNull():
log.info(f"Using fallback icon {fallback} for {icon_name}")
return icon
except Exception as fallback_ex:
log.debug(f"Failed to load fallback icon {fallback}: {fallback_ex}")
log.warning(f"Could not load icon {icon_name}")
return None
@staticmethod
[docs]
def get_icon_pixmap(
icon_name: str, color: str = None, size: int = None, fallback: str = None
):
"""
Get icon as QPixmap with fallback support.
:param icon_name: Icon identifier
:param color: Optional color string
:param size: Optional size in pixels (defaults to JDXiStyle.ICON_SIZE)
:param fallback: Fallback icon if primary fails
:return: QPixmap or None if all fail
"""
icon = IconRegistry.get_icon(icon_name, color=color, fallback=fallback)
if icon is None:
return None
icon_size = size or JDXiStyle.ICON_SIZE
return icon.pixmap(icon_size, icon_size)
@staticmethod
[docs]
def get_icon_safe(
icon_name: str, color: str = None, size: int = None, fallback: str = None
) -> QIcon:
"""
Get icon with fallback support, returns empty QIcon if all fail.
This version always returns a QIcon object (may be empty).
:param icon_name: Icon identifier
:param color: Optional color string
:param size: Optional size in pixels (unused, kept for compatibility)
:param fallback: Fallback icon if primary fails
:return: QIcon (may be empty if all fail)
"""
icon = IconRegistry.get_icon(icon_name, color=color, fallback=fallback)
if icon is None:
# Return empty icon
return qta.icon("")
return icon