拖动导入模型帧率异常修复,添加web视图
This commit is contained in:
parent
fe373c0e5d
commit
79b9aa44dc
@ -313,10 +313,15 @@ class ModelDragDropService:
|
||||
if not path.exists() or not self._is_supported_model(path):
|
||||
continue
|
||||
try:
|
||||
model_node = self.app._import_model_for_runtime(str(path), prefer_scene_manager=True)
|
||||
model_node = self.app._import_model_with_menu_logic(
|
||||
str(path),
|
||||
select_model=False,
|
||||
set_origin=True,
|
||||
show_info_message=False,
|
||||
show_success_message=False,
|
||||
)
|
||||
if not model_node:
|
||||
continue
|
||||
self._postprocess_imported_model(model_node)
|
||||
imported_models.append(model_node)
|
||||
except Exception as e:
|
||||
print(f"[外部拖拽] 导入模型失败 {path}: {e}")
|
||||
@ -377,7 +382,13 @@ class ModelDragDropService:
|
||||
if not self._is_supported_model(path):
|
||||
continue
|
||||
try:
|
||||
model_node = self.app._import_model_for_runtime(str(path), prefer_scene_manager=True)
|
||||
model_node = self.app._import_model_with_menu_logic(
|
||||
str(path),
|
||||
select_model=False,
|
||||
set_origin=True,
|
||||
show_info_message=False,
|
||||
show_success_message=False,
|
||||
)
|
||||
if not model_node:
|
||||
continue
|
||||
|
||||
@ -387,7 +398,6 @@ class ModelDragDropService:
|
||||
except Exception:
|
||||
model_node.reparentTo(target_parent)
|
||||
|
||||
self._postprocess_imported_model(model_node)
|
||||
imported_models.append(model_node)
|
||||
except Exception as e:
|
||||
print(f"[拖拽导入] 导入失败 {path}: {e}")
|
||||
@ -446,16 +456,10 @@ class ModelDragDropService:
|
||||
self.app.add_error_message(f"不支持的文件格式: {path.suffix.lower()}")
|
||||
return False
|
||||
|
||||
model_node = self.app._import_model_for_runtime(str(path), prefer_scene_manager=True)
|
||||
model_node = self.app._import_model_with_menu_logic(str(path))
|
||||
if not model_node:
|
||||
self.app.add_error_message(f"导入模型失败: {path}")
|
||||
return False
|
||||
|
||||
self._postprocess_imported_model(model_node, set_origin=True)
|
||||
if getattr(self.app, "selection", None):
|
||||
self.app.selection.updateSelection(model_node)
|
||||
|
||||
self.app.add_success_message(f"成功导入模型: {path.name}")
|
||||
return True
|
||||
except Exception as e:
|
||||
self.app.add_error_message(f"导入模型时发生错误: {e}")
|
||||
|
||||
43
imgui.ini
43
imgui.ini
@ -24,26 +24,26 @@ Size=832,45
|
||||
Collapsed=0
|
||||
|
||||
[Window][工具栏]
|
||||
Pos=327,20
|
||||
Size=1862,32
|
||||
Pos=241,20
|
||||
Size=908,74
|
||||
Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
|
||||
[Window][场景树]
|
||||
Pos=0,20
|
||||
Size=325,854
|
||||
Size=239,468
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][属性面板]
|
||||
Pos=2191,20
|
||||
Size=369,1331
|
||||
Pos=1151,20
|
||||
Size=229,730
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][控制台]
|
||||
Pos=0,876
|
||||
Size=325,475
|
||||
Pos=0,490
|
||||
Size=239,260
|
||||
Collapsed=0
|
||||
DockId=0x00000008,0
|
||||
|
||||
@ -60,7 +60,7 @@ Collapsed=0
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,20
|
||||
Size=2560,1331
|
||||
Size=1380,730
|
||||
Collapsed=0
|
||||
|
||||
[Window][测试窗口1]
|
||||
@ -99,8 +99,8 @@ Size=600,500
|
||||
Collapsed=0
|
||||
|
||||
[Window][资源管理器]
|
||||
Pos=327,1013
|
||||
Size=1862,338
|
||||
Pos=241,464
|
||||
Size=908,286
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@ -200,18 +200,23 @@ Pos=660,304
|
||||
Size=600,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Web面板]
|
||||
Pos=373,98
|
||||
Size=942,580
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=2560,1331 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=1549,989 Split=X
|
||||
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=325,989 Split=Y Selected=0xE0015051
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1380,730 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=1689,989 Split=X
|
||||
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=239,989 Split=Y Selected=0xE0015051
|
||||
DockNode ID=0x00000007 Parent=0x00000009 SizeRef=271,634 Selected=0xE0015051
|
||||
DockNode ID=0x00000008 Parent=0x00000009 SizeRef=271,353 Selected=0x5428E753
|
||||
DockNode ID=0x0000000A Parent=0x00000001 SizeRef=1862,989 Split=Y
|
||||
DockNode ID=0x0000000D Parent=0x0000000A SizeRef=1318,32 HiddenTabBar=1 Selected=0x43A39006
|
||||
DockNode ID=0x0000000E Parent=0x0000000A SizeRef=1318,955 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x0000000E SizeRef=1341,957 CentralNode=1
|
||||
DockNode ID=0x00000006 Parent=0x0000000E SizeRef=1341,338 Selected=0x3A2E05C3
|
||||
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=369,989 Split=Y Selected=0x3188AB8D
|
||||
DockNode ID=0x0000000A Parent=0x00000001 SizeRef=1448,989 Split=Y
|
||||
DockNode ID=0x0000000D Parent=0x0000000A SizeRef=1318,74 HiddenTabBar=1 Selected=0x43A39006
|
||||
DockNode ID=0x0000000E Parent=0x0000000A SizeRef=1318,913 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x0000000E SizeRef=1341,625 CentralNode=1
|
||||
DockNode ID=0x00000006 Parent=0x0000000E SizeRef=1341,286 Selected=0x3A2E05C3
|
||||
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=229,989 Split=Y Selected=0x3188AB8D
|
||||
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=351,390 Selected=0x5DB6FF37
|
||||
DockNode ID=0x00000004 Parent=0x00000002 SizeRef=351,597 Selected=0x1EB923B7
|
||||
|
||||
|
||||
13
main.py
13
main.py
@ -262,6 +262,8 @@ class MyWorld(CoreWorld):
|
||||
self.showScriptPanel = not self.use_ssbo_mouse_picking
|
||||
self.showToolbar = True
|
||||
self.showResourceManager = True
|
||||
self.showWebPanel = False
|
||||
self.webPanelUrl = "https://www.baidu.com"
|
||||
|
||||
# 脚本系统状态变量
|
||||
self.hotReloadEnabled = True
|
||||
@ -770,6 +772,10 @@ class MyWorld(CoreWorld):
|
||||
if self.showPropertyPanel:
|
||||
self._draw_property_panel()
|
||||
|
||||
# Web面板
|
||||
if self.showWebPanel:
|
||||
self._draw_web_panel()
|
||||
|
||||
# 脚本面板
|
||||
if self.showScriptPanel:
|
||||
self._draw_script_panel()
|
||||
@ -876,6 +882,9 @@ class MyWorld(CoreWorld):
|
||||
def _draw_property_panel(self, *args, **kwargs):
|
||||
return self.editor_panels._draw_property_panel(*args, **kwargs)
|
||||
|
||||
def _draw_web_panel(self, *args, **kwargs):
|
||||
return self.editor_panels._draw_web_panel(*args, **kwargs)
|
||||
|
||||
def _draw_node_properties(self, *args, **kwargs):
|
||||
return self.editor_panels._draw_node_properties(*args, **kwargs)
|
||||
|
||||
@ -1306,6 +1315,10 @@ class MyWorld(CoreWorld):
|
||||
|
||||
def _import_model(self, *args, **kwargs):
|
||||
return self.app_actions._import_model(*args, **kwargs)
|
||||
|
||||
def _import_model_with_menu_logic(self, *args, **kwargs):
|
||||
return self.app_actions._import_model_with_menu_logic(*args, **kwargs)
|
||||
|
||||
def _draw_new_project_dialog(self, *args, **kwargs):
|
||||
return self.dialog_panels._draw_new_project_dialog(*args, **kwargs)
|
||||
|
||||
|
||||
@ -1094,6 +1094,82 @@ class AppActions:
|
||||
return self.scene_manager.importModel(file_path)
|
||||
return None
|
||||
|
||||
def _import_model_with_menu_logic(
|
||||
self,
|
||||
file_path,
|
||||
select_model=True,
|
||||
set_origin=True,
|
||||
show_info_message=True,
|
||||
show_success_message=True,
|
||||
):
|
||||
"""统一的单文件导入入口,保持与菜单导入一致的处理流程。"""
|
||||
try:
|
||||
if not file_path:
|
||||
self.add_error_message("请选择要导入的文件")
|
||||
return None
|
||||
|
||||
normalized_path = os.fspath(file_path)
|
||||
if not os.path.exists(normalized_path):
|
||||
self.add_error_message(f"文件不存在: {normalized_path}")
|
||||
return None
|
||||
|
||||
file_ext = os.path.splitext(normalized_path)[1].lower()
|
||||
if file_ext not in self.supported_formats:
|
||||
self.add_error_message(f"不支持的文件格式: {file_ext}")
|
||||
return None
|
||||
|
||||
if not hasattr(self, 'scene_manager') or not self.scene_manager:
|
||||
self.add_error_message("场景管理器未初始化")
|
||||
return None
|
||||
|
||||
file_name = os.path.basename(normalized_path)
|
||||
if show_info_message:
|
||||
self.add_info_message(f"正在导入模型: {file_name}")
|
||||
|
||||
model_node = self._import_model_for_runtime(normalized_path)
|
||||
if not model_node:
|
||||
self.add_error_message("模型导入失败")
|
||||
return None
|
||||
|
||||
if hasattr(self.scene_manager, 'processMaterials'):
|
||||
self.scene_manager.processMaterials(model_node)
|
||||
if show_info_message:
|
||||
self.add_info_message("已应用默认材质")
|
||||
|
||||
try:
|
||||
model_node.clearMaterial()
|
||||
model_node.clearTexture()
|
||||
|
||||
if hasattr(self.scene_manager, 'processMaterials'):
|
||||
self.scene_manager.processMaterials(model_node)
|
||||
|
||||
try:
|
||||
color = model_node.getColor()
|
||||
if color and len(color) >= 4 and color == (1, 1, 1, 1):
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0)
|
||||
elif not color:
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0)
|
||||
except Exception:
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0)
|
||||
except Exception as e:
|
||||
self.add_warning_message(f"材质处理警告: {e}")
|
||||
|
||||
if set_origin:
|
||||
model_node.setPos(0, 0, 0)
|
||||
|
||||
if hasattr(self.scene_manager, 'models'):
|
||||
self.scene_manager.models.append(model_node)
|
||||
|
||||
if select_model and hasattr(self, 'selection') and self.selection:
|
||||
self.selection.updateSelection(model_node)
|
||||
|
||||
if show_success_message:
|
||||
self.add_success_message(f"模型导入成功: {file_name}")
|
||||
return model_node
|
||||
except Exception as e:
|
||||
self.add_error_message(f"导入模型失败: {e}")
|
||||
return None
|
||||
|
||||
def _on_import_model(self):
|
||||
"""处理导入模型菜单项"""
|
||||
self.add_info_message("打开导入模型对话框")
|
||||
@ -1102,77 +1178,6 @@ class AppActions:
|
||||
|
||||
def _import_model(self):
|
||||
"""导入模型的具体实现"""
|
||||
try:
|
||||
if not self.import_file_path:
|
||||
self.add_error_message("请选择要导入的文件")
|
||||
return
|
||||
|
||||
if not os.path.exists(self.import_file_path):
|
||||
self.add_error_message(f"文件不存在: {self.import_file_path}")
|
||||
return
|
||||
|
||||
# 检查文件格式
|
||||
file_ext = os.path.splitext(self.import_file_path)[1].lower()
|
||||
if file_ext not in self.supported_formats:
|
||||
self.add_error_message(f"不支持的文件格式: {file_ext}")
|
||||
return
|
||||
|
||||
# 调用场景管理器导入模型
|
||||
if hasattr(self, 'scene_manager') and self.scene_manager:
|
||||
self.add_info_message(f"正在导入模型: {os.path.basename(self.import_file_path)}")
|
||||
|
||||
# 导入模型
|
||||
model_node = self._import_model_for_runtime(self.import_file_path)
|
||||
|
||||
if model_node:
|
||||
# 添加材质处理确保颜色正常
|
||||
if hasattr(self.scene_manager, 'processMaterials'):
|
||||
self.scene_manager.processMaterials(model_node)
|
||||
self.add_info_message("已应用默认材质")
|
||||
|
||||
# 额外的材质处理,确保颜色正确显示
|
||||
try:
|
||||
# 强制刷新模型显示
|
||||
model_node.clearMaterial()
|
||||
model_node.clearTexture()
|
||||
|
||||
# 重新应用材质
|
||||
if hasattr(self.scene_manager, 'processMaterials'):
|
||||
self.scene_manager.processMaterials(model_node)
|
||||
|
||||
# 设置默认的基础颜色(如果模型没有颜色)
|
||||
try:
|
||||
color = model_node.getColor()
|
||||
if color and len(color) >= 4 and color == (1, 1, 1, 1): # 默认白色
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0) # 设置为中性灰
|
||||
elif not color: # 如果没有颜色
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0) # 设置为中性灰
|
||||
except:
|
||||
# 如果getColor失败,直接设置默认颜色
|
||||
model_node.setColor(0.8, 0.8, 0.8, 1.0) # 设置为中性灰
|
||||
|
||||
except Exception as e:
|
||||
self.add_warning_message(f"材质处理警告: {e}")
|
||||
|
||||
# 设置模型位置
|
||||
model_node.setPos(0, 0, 0)
|
||||
|
||||
# 添加到场景管理器的模型列表
|
||||
if hasattr(self.scene_manager, 'models'):
|
||||
self.scene_manager.models.append(model_node)
|
||||
|
||||
# 选中新导入的模型
|
||||
if hasattr(self, 'selection') and self.selection:
|
||||
self.selection.updateSelection(model_node)
|
||||
|
||||
self.add_success_message(f"模型导入成功: {os.path.basename(self.import_file_path)}")
|
||||
else:
|
||||
self.add_error_message("模型导入失败")
|
||||
else:
|
||||
self.add_error_message("场景管理器未初始化")
|
||||
|
||||
except Exception as e:
|
||||
self.add_error_message(f"导入模型失败: {e}")
|
||||
|
||||
# 清空导入路径
|
||||
model_node = self._import_model_with_menu_logic(self.import_file_path)
|
||||
self.import_file_path = ""
|
||||
return model_node
|
||||
|
||||
@ -204,12 +204,14 @@ class CreateActions:
|
||||
def _on_create_web_panel(self):
|
||||
"""创建Web面板"""
|
||||
try:
|
||||
result = self.createWebPanel()
|
||||
result = self.editor_panels._on_create_web_panel()
|
||||
if result:
|
||||
self.add_success_message("Web面板创建成功")
|
||||
else:
|
||||
self.add_error_message("Web面板创建失败")
|
||||
return result
|
||||
except Exception as e:
|
||||
self.add_error_message(f"创建Web面板失败: {str(e)}")
|
||||
return None
|
||||
|
||||
# ==================== 3D对象和GUI创建方法 ====================
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from imgui_bundle import imgui, imgui_ctx
|
||||
import os
|
||||
from pathlib import Path
|
||||
from panda3d.core import PNMImage, StringStream, Texture
|
||||
|
||||
|
||||
class EditorPanels:
|
||||
@ -19,6 +20,117 @@ class EditorPanels:
|
||||
else:
|
||||
setattr(self.app, name, value)
|
||||
|
||||
def _on_create_web_panel(self):
|
||||
"""创建或激活 ImGui Web 面板。"""
|
||||
self._ensure_web_panel_state()
|
||||
self.app.showWebPanel = True
|
||||
|
||||
webview = getattr(self.app, "_imgui_webview", None)
|
||||
if webview and getattr(webview, "_running", False):
|
||||
return True
|
||||
|
||||
return self._start_imgui_webview(self.app.web_panel_url_input)
|
||||
|
||||
def _ensure_web_panel_state(self):
|
||||
if not hasattr(self.app, "web_panel_url_input") or not self.app.web_panel_url_input:
|
||||
self.app.web_panel_url_input = "https://www.example.com"
|
||||
if not hasattr(self.app, "_imgui_webview"):
|
||||
self.app._imgui_webview = None
|
||||
if not hasattr(self.app, "_imgui_webview_texture"):
|
||||
self.app._imgui_webview_texture = None
|
||||
if not hasattr(self.app, "_imgui_webview_tex_id"):
|
||||
self.app._imgui_webview_tex_id = None
|
||||
|
||||
def _start_imgui_webview(self, url):
|
||||
self._ensure_web_panel_state()
|
||||
self._stop_imgui_webview()
|
||||
try:
|
||||
target_url = (url or "").strip()
|
||||
if not target_url:
|
||||
target_url = "https://www.example.com"
|
||||
if not target_url.startswith(("http://", "https://", "file://")):
|
||||
target_url = "https://" + target_url
|
||||
|
||||
from core.imgui_webview import ImGuiWebView
|
||||
webview = ImGuiWebView(width=1280, height=720)
|
||||
webview.start(target_url)
|
||||
self.app._imgui_webview = webview
|
||||
return True
|
||||
except Exception as e:
|
||||
self.app.add_error_message(f"启动Web视图失败: {e}")
|
||||
return False
|
||||
|
||||
def _stop_imgui_webview(self):
|
||||
webview = getattr(self.app, "_imgui_webview", None)
|
||||
if webview:
|
||||
try:
|
||||
webview.stop()
|
||||
except Exception:
|
||||
pass
|
||||
self.app._imgui_webview = None
|
||||
|
||||
tex_id = getattr(self.app, "_imgui_webview_tex_id", None)
|
||||
if tex_id:
|
||||
try:
|
||||
self.app.imgui.removeTexture(tex_id)
|
||||
except Exception:
|
||||
pass
|
||||
self.app._imgui_webview_tex_id = None
|
||||
self.app._imgui_webview_texture = None
|
||||
|
||||
def _navigate_web_panel(self):
|
||||
self._ensure_web_panel_state()
|
||||
url = (self.app.web_panel_url_input or "").strip()
|
||||
if not url:
|
||||
return
|
||||
|
||||
webview = getattr(self.app, "_imgui_webview", None)
|
||||
if not webview or not getattr(webview, "_running", False):
|
||||
self._start_imgui_webview(url)
|
||||
return
|
||||
|
||||
webview.navigate(url)
|
||||
|
||||
def _update_web_panel_texture(self):
|
||||
webview = getattr(self.app, "_imgui_webview", None)
|
||||
if not webview:
|
||||
return
|
||||
if not webview.tex_dirty:
|
||||
return
|
||||
|
||||
jpeg_bytes = webview.get_screenshot_bytes()
|
||||
if not jpeg_bytes:
|
||||
return
|
||||
|
||||
pnm = PNMImage()
|
||||
if not pnm.read(StringStream(jpeg_bytes), "imgui_webview.png"):
|
||||
webview.tex_dirty = False
|
||||
return
|
||||
# p3dimgui 纹理坐标系与网页截图存在Y轴方向差异,先在像素层修正
|
||||
pnm.flip(False, True, False)
|
||||
|
||||
# 某些后端在“已注册纹理原位更新”时存在稳定性问题。
|
||||
# 改为每次创建新纹理并替换旧纹理ID,避免原位更新导致崩溃。
|
||||
texture = Texture("imgui_web_panel_texture")
|
||||
texture.load(pnm)
|
||||
new_tex_id = self.app.imgui.loadTexture(texture)
|
||||
|
||||
old_tex_id = getattr(self.app, "_imgui_webview_tex_id", None)
|
||||
if old_tex_id:
|
||||
try:
|
||||
self.app.imgui.removeTexture(old_tex_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.app._imgui_webview_texture = texture
|
||||
self.app._imgui_webview_tex_id = new_tex_id
|
||||
|
||||
webview.tex_dirty = False
|
||||
|
||||
@staticmethod
|
||||
def _clamp01(value):
|
||||
return 0.0 if value < 0.0 else 1.0 if value > 1.0 else value
|
||||
|
||||
def draw_menu_bar(self):
|
||||
"""绘制菜单栏"""
|
||||
with imgui_ctx.begin_main_menu_bar() as main_menu:
|
||||
@ -159,6 +271,12 @@ class EditorPanels:
|
||||
_, self.app.showConsole = imgui.menu_item("控制台", "", self.app.showConsole, True)
|
||||
_, self.app.showScriptPanel = imgui.menu_item("脚本管理", "", self.app.showScriptPanel, True)
|
||||
_, self.app.showLUIEditor = imgui.menu_item("LUI编辑器", "", self.app.showLUIEditor, True)
|
||||
prev_show_web_panel = self.app.showWebPanel
|
||||
_, self.app.showWebPanel = imgui.menu_item("Web面板", "", self.app.showWebPanel, True)
|
||||
if prev_show_web_panel and not self.app.showWebPanel:
|
||||
self._stop_imgui_webview()
|
||||
elif (not prev_show_web_panel) and self.app.showWebPanel:
|
||||
self._on_create_web_panel()
|
||||
|
||||
# 工具菜单
|
||||
with imgui_ctx.begin_menu("工具") as tools_menu:
|
||||
@ -926,6 +1044,86 @@ class EditorPanels:
|
||||
self.app.is_dragging = True
|
||||
self.app.show_drag_overlay = True
|
||||
|
||||
def _draw_web_panel(self):
|
||||
"""绘制 Web 面板(ImGui + 后台浏览器截图)。"""
|
||||
self._ensure_web_panel_state()
|
||||
if not self.app.showWebPanel:
|
||||
self._stop_imgui_webview()
|
||||
return
|
||||
|
||||
flags = self.app.style_manager.get_window_flags("panel")
|
||||
with self.app.style_manager.begin_styled_window("Web面板", self.app.showWebPanel, flags) as (_, opened):
|
||||
if not opened:
|
||||
self.app.showWebPanel = False
|
||||
self._stop_imgui_webview()
|
||||
return
|
||||
|
||||
self.app.showWebPanel = True
|
||||
|
||||
changed, self.app.web_panel_url_input = imgui.input_text(
|
||||
"URL", self.app.web_panel_url_input, 1024
|
||||
)
|
||||
if changed:
|
||||
self.app.web_panel_url_input = self.app.web_panel_url_input.strip()
|
||||
|
||||
imgui.same_line()
|
||||
if imgui.button("访问"):
|
||||
self._navigate_web_panel()
|
||||
|
||||
webview = getattr(self.app, "_imgui_webview", None)
|
||||
if not webview:
|
||||
if not self._start_imgui_webview(self.app.web_panel_url_input):
|
||||
imgui.text_colored((1.0, 0.4, 0.4, 1.0), "Web视图启动失败")
|
||||
return
|
||||
webview = self.app._imgui_webview
|
||||
|
||||
imgui.same_line()
|
||||
if imgui.button("后退"):
|
||||
webview.go_back()
|
||||
imgui.same_line()
|
||||
if imgui.button("前进"):
|
||||
webview.go_forward()
|
||||
imgui.same_line()
|
||||
if imgui.button("刷新"):
|
||||
webview.reload()
|
||||
|
||||
current_url = webview.current_url or self.app.web_panel_url_input
|
||||
if current_url:
|
||||
imgui.text_colored((0.7, 0.7, 0.7, 1.0), current_url)
|
||||
if webview.error:
|
||||
imgui.text_colored((1.0, 0.4, 0.4, 1.0), webview.error)
|
||||
|
||||
imgui.separator()
|
||||
|
||||
self._update_web_panel_texture()
|
||||
tex_id = getattr(self.app, "_imgui_webview_tex_id", None)
|
||||
available = imgui.get_content_region_avail()
|
||||
display_w = max(float(available.x), 64.0)
|
||||
display_h = max(float(available.y), 64.0)
|
||||
|
||||
if tex_id:
|
||||
imgui.image(tex_id, (display_w, display_h))
|
||||
|
||||
if imgui.is_item_hovered():
|
||||
mouse_wheel = imgui.get_io().mouse_wheel
|
||||
if abs(mouse_wheel) > 1e-4:
|
||||
webview.scroll(-mouse_wheel * 120.0)
|
||||
|
||||
if imgui.is_mouse_clicked(0):
|
||||
item_min = imgui.get_item_rect_min()
|
||||
item_max = imgui.get_item_rect_max()
|
||||
item_w = max(float(item_max.x - item_min.x), 1.0)
|
||||
item_h = max(float(item_max.y - item_min.y), 1.0)
|
||||
mouse_pos = imgui.get_mouse_pos()
|
||||
|
||||
x_ratio = self._clamp01((float(mouse_pos.x) - float(item_min.x)) / item_w)
|
||||
y_ratio = self._clamp01((float(mouse_pos.y) - float(item_min.y)) / item_h)
|
||||
webview.click(x_ratio, y_ratio)
|
||||
elif webview.is_loading:
|
||||
imgui.text("网页加载中...")
|
||||
else:
|
||||
imgui.text("正在初始化Web视图...")
|
||||
|
||||
|
||||
def _draw_property_panel(self):
|
||||
"""绘制属性面板"""
|
||||
@ -2216,3 +2414,5 @@ class EditorPanels:
|
||||
|
||||
except Exception as e:
|
||||
print(f"绘制着色模型面板失败: {e}")
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user