from imgui_bundle import imgui, imgui_ctx class ScriptPanels: """Script and console related editor panels.""" def __init__(self, app): self.app = app def __getattr__(self, name): return getattr(self.app, name) def __setattr__(self, name, value): if name == "app" or name in self.__dict__ or hasattr(type(self), name): object.__setattr__(self, name, value) else: setattr(self.app, name, value) def _draw_console(self): """绘制控制台面板""" # 使用面板类型的窗口标志,支持docking flags = self.style_manager.get_window_flags("panel") with self.style_manager.begin_styled_window("控制台", self.app.showConsole, flags) as (_, opened): if not opened: self.app.showConsole = False return self.app.showConsole = opened imgui.text("控制台输出") imgui.separator() # 显示消息系统中的消息 if hasattr(self, 'messages') and self.messages: for message in self.messages: # 显示时间戳 imgui.text_colored((0.7, 0.7, 0.7, 1.0), f"[{message['timestamp']}]") imgui.same_line() # 根据消息类型显示图标 if message['text'].startswith('✓'): if self.icons.get('success'): imgui.image(self.icons['success'], (12, 12)) imgui.same_line() elif message['text'].startswith('✗'): if self.icons.get('delete_fail_icon'): imgui.image(self.icons['delete_fail_icon'], (12, 12)) imgui.same_line() elif message['text'].startswith('⚠'): if self.icons.get('warning'): imgui.image(self.icons['warning'], (12, 12)) imgui.same_line() # 显示消息文本 imgui.text_colored(message['color'], message['text']) else: # 默认消息 imgui.text_colored((0.157, 0.620, 1.0, 1.0), "[系统]") imgui.same_line() imgui.text("引擎已就绪") # 输入框 imgui.separator() submit, new_command = imgui.input_text( ">", self.console_command_input, flags=imgui.InputTextFlags_.enter_returns_true.value, ) if new_command != self.console_command_input: self.console_command_input = new_command imgui.same_line() execute_clicked = imgui.button("执行") if (submit or execute_clicked) and self.console_command_input.strip(): command = self.console_command_input.strip() self.add_info_message(f"执行命令: {command}") self.console_command_input = "" # TODO: 实现命令执行逻辑 imgui.separator() # 视角控制信息 imgui.text("视角控制:") imgui.text(" WASD - 移动") imgui.text(" Q/E - 上下") imgui.text(" 右键拖拽 - 旋转视角") imgui.text(" 滚轮 - 前进/后退") # 相机位置信息 cam_pos = self.camera.getPos() cam_hpr = self.camera.getHpr() imgui.text(f"位置: X={cam_pos.x:.1f}, Y={cam_pos.y:.1f}, Z={cam_pos.z:.1f}") imgui.text(f"旋转: H={cam_hpr.x:.1f}, P={cam_hpr.y:.1f}, R={cam_hpr.z:.1f}") # 控制状态 imgui.checkbox("启用视角控制", self.camera_control_enabled) # 重置按钮 if imgui.button("重置相机"): self.camera.setPos(0, -20, 5) self.camera.setHpr(0, 0, 0) self.add_info_message("相机位置已重置") def _draw_script_panel(self): """绘制脚本管理面板。""" # 使用面板类型的窗口标志,支持docking flags = self.style_manager.get_window_flags("panel") with self.style_manager.begin_styled_window("脚本管理", self.app.showScriptPanel, flags) as (_, opened): if not opened: self.app.showScriptPanel = False return self.app.showScriptPanel = opened # 1. 脚本系统状态组 self._draw_script_status_group() imgui.spacing() # 2. 创建脚本组 self._draw_create_script_group() imgui.spacing() # 3. 可用脚本组 self._draw_available_scripts_group() imgui.spacing() # 4. 脚本挂载组 self._draw_script_mounting_group() def _draw_script_status_group(self): """绘制脚本系统状态组""" if imgui.collapsing_header("脚本系统状态", imgui.TreeNodeFlags_.default_open): # 脚本系统状态 imgui.text("脚本引擎状态:") imgui.same_line() # 检查脚本管理器是否正常工作 if hasattr(self, 'script_manager') and self.script_manager: if hasattr(self.script_manager, 'engine') and self.script_manager.engine: imgui.text_colored((0.0, 1.0, 0.0, 1.0), "✓ 已启动") else: imgui.text_colored((1.0, 0.5, 0.0, 1.0), "⚠ 引擎未初始化") else: imgui.text_colored((1.0, 0.0, 0.0, 1.0), "✗ 未启动") # 热重载状态 imgui.text("热重载状态:") imgui.same_line() hot_reload_enabled = False if hasattr(self, 'script_manager') and self.script_manager: hot_reload_enabled = getattr(self.script_manager, 'hot_reload_enabled', False) if hot_reload_enabled: imgui.text_colored((0.0, 1.0, 0.0, 1.0), "✓ 已启用") else: imgui.text_colored((1.0, 0.5, 0.0, 1.0), "✗ 已禁用") imgui.same_line() if imgui.button("切换热重载##toggle_hot_reload"): self._toggle_hot_reload() def _draw_create_script_group(self): """绘制创建脚本组""" if imgui.collapsing_header("创建脚本"): # 脚本名称输入 imgui.text("脚本名称:") imgui.same_line() # 获取当前脚本名称 if not hasattr(self, '_new_script_name'): self._new_script_name = "new_script" changed, new_name = imgui.input_text("##script_name", self._new_script_name, 256) if changed: self._new_script_name = new_name # 模板选择 imgui.text("脚本模板:") imgui.same_line() if not hasattr(self, '_selected_template'): self._selected_template = 0 templates = ["基础脚本", "移动脚本", "旋转脚本", "缩放脚本", "动画脚本"] changed, selected = imgui.combo("##script_template", self._selected_template, templates) if changed: self._selected_template = selected # 创建按钮 if imgui.button("创建脚本##create_script"): self._create_new_script() imgui.same_line() if imgui.button("从文件创建##create_from_file"): self._on_create_script() def _draw_available_scripts_group(self): """绘制可用脚本组""" if imgui.collapsing_header("可用脚本"): # 刷新脚本列表 if imgui.button("刷新列表##refresh_scripts"): self._refresh_scripts_list() imgui.same_line() if imgui.button("重载全部##reload_all_scripts"): self._reload_all_scripts() imgui.separator() # 获取可用脚本列表 available_scripts = [] if hasattr(self, 'script_manager') and self.script_manager: try: available_scripts = self.script_manager.get_available_scripts() except Exception as e: print(f"获取脚本列表失败: {e}") # 显示脚本列表 if available_scripts: for i, script_name in enumerate(available_scripts): selected, _ = imgui.selectable(f"{script_name}##script_{i}", False) if selected: self._on_script_selected(script_name) # 双击编辑 if imgui.is_item_hovered() and imgui.is_mouse_double_clicked(0): self._edit_script(script_name) else: imgui.text_colored((0.7, 0.7, 0.7, 1.0), "无可用脚本") def _draw_script_mounting_group(self): """绘制脚本挂载组""" if imgui.collapsing_header("脚本挂载"): # 显示当前选中对象 selected_node = self._get_selection_node() if selected_node and not selected_node.isEmpty(): imgui.text("选中对象:") imgui.same_line() imgui.text_colored((0.0, 1.0, 0.0, 1.0), selected_node.getName() or "未命名对象") imgui.spacing() # 脚本选择和挂载 imgui.text("选择脚本:") imgui.same_line() # 获取可用脚本 available_scripts = [] if hasattr(self, 'script_manager') and self.script_manager: try: available_scripts = self.script_manager.get_available_scripts() except Exception as e: print(f"获取脚本列表失败: {e}") if available_scripts: if not hasattr(self, '_mount_script_index'): self._mount_script_index = 0 changed, selected = imgui.combo("##mount_script", self._mount_script_index, available_scripts) if changed: self._mount_script_index = selected imgui.same_line() if imgui.button("挂载##mount_script"): if self._mount_script_index < len(available_scripts): script_name = available_scripts[self._mount_script_index] self._mount_script_to_selected(script_name) else: imgui.text_colored((0.7, 0.7, 0.7, 1.0), "无可用脚本") imgui.spacing() # 显示已挂载的脚本 imgui.text("已挂载脚本:") mounted_scripts = [] if hasattr(self, 'script_manager') and self.script_manager: try: mounted_scripts = self.script_manager.get_scripts_on_object(selected_node) except Exception as e: print(f"获取已挂载脚本失败: {e}") if mounted_scripts: for i, script_component in enumerate(mounted_scripts): # 从ScriptComponent获取脚本名称 script_name = getattr(script_component, 'script_name', None) if not script_name and hasattr(script_component, '__class__'): script_name = script_component.__class__.__name__ if not script_name: script_name = f"Script_{i}" imgui.text(f"• {script_name}") imgui.same_line() if imgui.button(f"卸载##unmount_{i}"): self._unmount_script_from_selected(script_name) imgui.same_line() if imgui.button(f"编辑##edit_mounted_{i}"): self._edit_script(script_name) else: imgui.text_colored((0.7, 0.7, 0.7, 1.0), "无挂载脚本") else: imgui.text_colored((0.7, 0.7, 0.7, 1.0), "请先选择一个对象")