155 lines
5.1 KiB
Python
155 lines
5.1 KiB
Python
"""
|
|
Icon manager compatibility layer for the ImGui-only runtime.
|
|
|
|
This module keeps the legacy public API so older imports do not break
|
|
immediately.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Dict, Optional, Tuple
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class IconHandle:
|
|
"""Lightweight icon placeholder used by legacy call sites."""
|
|
|
|
path: str = ""
|
|
|
|
def isNull(self) -> bool:
|
|
return not self.path
|
|
|
|
def pixmap(self, _size: Optional[Tuple[int, int]] = None) -> "IconHandle":
|
|
return self
|
|
|
|
|
|
class IconManager:
|
|
def __init__(self):
|
|
self.icon_cache: Dict[str, IconHandle] = {}
|
|
self.icon_directory = self._get_icon_directory()
|
|
self.default_icon = IconHandle("")
|
|
|
|
self.icon_map = {
|
|
"app_logo": "logo.png",
|
|
"select_tool": "select_tool.png",
|
|
"move_tool": "move_tool.png",
|
|
"rotate_tool": "rotate_tool.png",
|
|
"scale_tool": "scale_tool.png",
|
|
"new_file": "new_file.png",
|
|
"open_file": "open_file.png",
|
|
"save_file": "save_file.png",
|
|
"exit": "exit.png",
|
|
"object_3d": "object_3d.png",
|
|
"light": "light.png",
|
|
"camera": "camera.png",
|
|
"terrain": "terrain.png",
|
|
"script": "script.png",
|
|
"success": "success.png",
|
|
"warning": "warning.png",
|
|
"error": "error.png",
|
|
"info": "info.png",
|
|
"up_arrow": "up_arrows.png",
|
|
"down_arrow": "down_arrows.png",
|
|
"left_arrow": "left_arrows.png",
|
|
"right_arrow": "right_arrows.png",
|
|
"solid_down_arrows": "solid_down_arrows.png",
|
|
"solid_right_arrows": "solid_right_arrows.png",
|
|
"minimize_icon": "minimize_icon.png",
|
|
"windowing_icon": "windowing_icon.png",
|
|
"close_icon": "close_icon.png",
|
|
"success_icon": "success_icon.png",
|
|
"warning_icon": "warning_icon.png",
|
|
"fail_icon": "delete_fail_icon.png",
|
|
"property_select_image": "property_select_image.png",
|
|
}
|
|
|
|
def _get_icon_directory(self) -> str:
|
|
current_dir = Path(__file__).resolve().parent
|
|
project_root = current_dir.parent
|
|
icon_dir = project_root / "icons"
|
|
return str(icon_dir)
|
|
|
|
def _resolve_icon_path(self, icon_name: str) -> Path:
|
|
if icon_name in self.icon_map:
|
|
file_name = self.icon_map[icon_name]
|
|
else:
|
|
file_name = icon_name
|
|
if not file_name.lower().endswith((".png", ".jpg", ".jpeg", ".svg", ".ico")):
|
|
file_name += ".png"
|
|
return Path(self.icon_directory) / file_name
|
|
|
|
def get_icon(self, icon_name: str, _size: Optional[Tuple[int, int]] = None) -> IconHandle:
|
|
if icon_name in self.icon_cache:
|
|
return self.icon_cache[icon_name]
|
|
|
|
icon_path = self._resolve_icon_path(icon_name)
|
|
if icon_path.exists():
|
|
icon = IconHandle(str(icon_path))
|
|
self.icon_cache[icon_name] = icon
|
|
return icon
|
|
return self.default_icon
|
|
|
|
def get_icon_path(self, icon_name: str) -> str:
|
|
icon_path = self._resolve_icon_path(icon_name)
|
|
return str(icon_path) if icon_path.exists() else ""
|
|
|
|
def has_icon(self, icon_name: str) -> bool:
|
|
return bool(self.get_icon_path(icon_name))
|
|
|
|
def add_icon(self, icon_name: str, icon_path: str) -> bool:
|
|
path_obj = Path(icon_path)
|
|
if not path_obj.exists():
|
|
return False
|
|
self.icon_cache[icon_name] = IconHandle(str(path_obj))
|
|
return True
|
|
|
|
def refresh_cache(self):
|
|
self.icon_cache.clear()
|
|
|
|
def get_available_icons(self) -> list:
|
|
available_icons = sorted(self.icon_map.keys())
|
|
icon_dir = Path(self.icon_directory)
|
|
if icon_dir.exists():
|
|
for p in icon_dir.iterdir():
|
|
if p.suffix.lower() in {".png", ".jpg", ".jpeg", ".svg", ".ico"}:
|
|
name = p.stem
|
|
if name not in available_icons:
|
|
available_icons.append(name)
|
|
return sorted(available_icons)
|
|
|
|
def get_cache_info(self) -> dict:
|
|
return {
|
|
"cached_icons": len(self.icon_cache),
|
|
"icon_directory": self.icon_directory,
|
|
"available_icons": len(self.get_available_icons()),
|
|
"cache_keys": list(self.icon_cache.keys()),
|
|
}
|
|
|
|
def debug_info(self):
|
|
info = self.get_cache_info()
|
|
print(f"icon_directory: {info['icon_directory']}")
|
|
print(f"cached_icons: {info['cached_icons']}")
|
|
print(f"available_icons: {info['available_icons']}")
|
|
|
|
|
|
_icon_manager: Optional[IconManager] = None
|
|
|
|
|
|
def get_icon_manager() -> IconManager:
|
|
global _icon_manager
|
|
if _icon_manager is None:
|
|
_icon_manager = IconManager()
|
|
return _icon_manager
|
|
|
|
|
|
def get_icon(icon_name: str, size: Optional[Tuple[int, int]] = None) -> IconHandle:
|
|
return get_icon_manager().get_icon(icon_name, size)
|
|
|
|
|
|
def get_icon_path(icon_name: str) -> str:
|
|
return get_icon_manager().get_icon_path(icon_name)
|
|
|
|
|
|
def has_icon(icon_name: str) -> bool:
|
|
return get_icon_manager().has_icon(icon_name)
|