diff --git a/imgui.ini b/imgui.ini index 0c0c1e4f..6ed26f3e 100644 --- a/imgui.ini +++ b/imgui.ini @@ -79,7 +79,7 @@ Size=93,65 Collapsed=0 [Window][新建项目] -Pos=724,358 +Pos=725,358 Size=400,300 Collapsed=0 @@ -150,10 +150,9 @@ Size=101,226 Collapsed=0 [Window][LUI编辑器] -Pos=2214,20 +Pos=160,44 Size=346,1331 Collapsed=0 -DockId=0x00000003,1 [Window][LUI测试控制面板] Pos=6,10 diff --git a/ui/LUI/lui_shared.py b/ui/LUI/lui_shared.py index 45dc6181..31aca326 100644 --- a/ui/LUI/lui_shared.py +++ b/ui/LUI/lui_shared.py @@ -1,5 +1,8 @@ """Shared LUI bootstrap and imports.""" +import importlib +import importlib.machinery +import importlib.util import os import sys from pathlib import Path @@ -25,30 +28,142 @@ if hasattr(os, "add_dll_directory"): except Exception as e: print(f"Warning: Failed to add DLL directory: {e}") -try: - import lui - panda3d.lui = lui - sys.modules["panda3d.lui"] = lui +LUI_IMPORT_DETAILS = "" +LUI_MODULE_SOURCE = "" - from Builtin.LUIRegion import LUIRegion - from Builtin.LUIInputHandler import LUIInputHandler - from Builtin.LUIButton import LUIButton - from Builtin.LUILabel import LUILabel - from Builtin.LUIInputField import LUIInputField - from Builtin.LUISlider import LUISlider - from Builtin.LUIFrame import LUIFrame - from Builtin.LUISkin import LUIDefaultSkin - from Builtin.LUISprite import LUISprite - from Builtin.LUIObject import LUIObject - from Builtin.LUICheckbox import LUICheckbox - from Builtin.LUIProgressbar import LUIProgressbar - from Builtin.LUISelectbox import LUISelectbox - from Builtin.LUIScrollableRegion import LUIScrollableRegion - from Builtin.LUITabbedFrame import LUITabbedFrame - from Builtin.LUIVerticalLayout import LUIVerticalLayout - from Builtin.LUIHorizontalLayout import LUIHorizontalLayout -except ImportError as e: - print(f"Error: Failed to import LUI: {e}") + +def _format_import_failure(prefix, error): + error_name = type(error).__name__ + return f"{prefix}: {error_name}: {error}" + + +def _iter_local_lui_binaries(): + seen = set() + for suffix in importlib.machinery.EXTENSION_SUFFIXES: + candidate = UI_DIR / f"lui{suffix}" + if candidate.exists(): + resolved = candidate.resolve() + if resolved not in seen: + seen.add(resolved) + yield resolved + + if os.name == "nt": + patterns = ("lui*.pyd", "lui*.dll") + elif sys.platform == "darwin": + patterns = ("lui*.so", "lui*.dylib") + else: + patterns = ("lui*.so",) + + for pattern in patterns: + for candidate in sorted(UI_DIR.glob(pattern)): + resolved = candidate.resolve() + if resolved not in seen: + seen.add(resolved) + yield resolved + + +def _load_lui_from_binary(binary_path): + spec = importlib.util.spec_from_file_location("lui", str(binary_path)) + if spec is None or spec.loader is None: + raise ImportError(f"无法从二进制创建模块规范: {binary_path}") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def _bootstrap_lui_module(): + failures = [] + + cached = sys.modules.get("lui") or sys.modules.get("panda3d.lui") + if cached is not None: + return cached, "sys.modules" + + module_candidates = [] + env_module = os.environ.get("EG_LUI_MODULE", "").strip() + if env_module: + for name in (part.strip() for part in env_module.split(",")): + if name: + module_candidates.append(name) + + for default_name in ("lui", "panda3d.lui"): + if default_name not in module_candidates: + module_candidates.append(default_name) + + for module_name in module_candidates: + try: + module = importlib.import_module(module_name) + return module, f"module:{module_name}" + except Exception as exc: + failures.append(_format_import_failure(f"import {module_name}", exc)) + + env_binary = os.environ.get("EG_LUI_BINARY", "").strip() + explicit_paths = [] + if env_binary: + raw_path = Path(env_binary).expanduser() + explicit_paths.append(raw_path if raw_path.is_absolute() else (UI_DIR / raw_path)) + explicit_paths.append(raw_path) + + checked = set() + for path_candidate in explicit_paths: + resolved = path_candidate.resolve() + if resolved in checked: + continue + checked.add(resolved) + if not resolved.exists(): + failures.append(f"binary path not found: {resolved}") + continue + try: + module = _load_lui_from_binary(resolved) + return module, f"binary:{resolved}" + except Exception as exc: + failures.append(_format_import_failure(f"load {resolved.name}", exc)) + + for binary_path in _iter_local_lui_binaries(): + try: + module = _load_lui_from_binary(binary_path) + return module, f"binary:{binary_path}" + except Exception as exc: + failures.append(_format_import_failure(f"load {binary_path.name}", exc)) + + return None, " | ".join(failures) + + +lui = None +try: + lui, LUI_MODULE_SOURCE = _bootstrap_lui_module() + if lui is not None: + panda3d.lui = lui + sys.modules["panda3d.lui"] = lui + if "lui" not in sys.modules: + sys.modules["lui"] = lui + + from Builtin.LUIRegion import LUIRegion + from Builtin.LUIInputHandler import LUIInputHandler + from Builtin.LUIButton import LUIButton + from Builtin.LUILabel import LUILabel + from Builtin.LUIInputField import LUIInputField + from Builtin.LUISlider import LUISlider + from Builtin.LUIFrame import LUIFrame + from Builtin.LUISkin import LUIDefaultSkin + from Builtin.LUISprite import LUISprite + from Builtin.LUIObject import LUIObject + from Builtin.LUICheckbox import LUICheckbox + from Builtin.LUIProgressbar import LUIProgressbar + from Builtin.LUISelectbox import LUISelectbox + from Builtin.LUIScrollableRegion import LUIScrollableRegion + from Builtin.LUITabbedFrame import LUITabbedFrame + from Builtin.LUIVerticalLayout import LUIVerticalLayout + from Builtin.LUIHorizontalLayout import LUIHorizontalLayout + else: + raise ImportError(LUI_MODULE_SOURCE or "No available LUI module.") +except Exception as e: + detail = str(LUI_MODULE_SOURCE or "").strip() + if detail: + LUI_IMPORT_DETAILS = detail + print(f"Error: Failed to import LUI: {detail}") + else: + LUI_IMPORT_DETAILS = str(e) + print(f"Error: Failed to import LUI: {e}") lui = None LUIRegion = None LUIInputHandler = None diff --git a/ui/lui.so b/ui/lui.so new file mode 100644 index 00000000..09606a00 Binary files /dev/null and b/ui/lui.so differ diff --git a/ui/lui_manager.py b/ui/lui_manager.py index 49766dc4..034f52b7 100644 --- a/ui/lui_manager.py +++ b/ui/lui_manager.py @@ -17,6 +17,7 @@ from ui.LUI.lui_shared import ( LUIRegion, LUISlider, LUISprite, + LUI_IMPORT_DETAILS, NodePath, Path, lui, @@ -41,7 +42,11 @@ class LUIManager(LUIManagerInteractionMixin, LUIManagerEditorMixin): self._selected_type_index = 0 if not self.lui_enabled: - print("LUI is not available, LUIManager will be disabled.") + details = str(LUI_IMPORT_DETAILS or "").strip() + if details: + print(f"LUI is not available, LUIManager will be disabled. {details}") + else: + print("LUI is not available, LUIManager will be disabled.") return # 1. 优先注册中文字体