载入中...
搜索中...
未找到
ScenePanel.cpp
浏览该文件的文档.
1#include "ui/ScenePanel.h"
2
3#include "common/Capability.h"
4#include "common/SceneQuery.h"
5#include "ui/UIHost.h"
6
7#include <algorithm>
8#include <cstdlib>
9
10namespace eve::ui {
11namespace {
12
13constexpr const char* kSceneHostName = "eve_scene";
14
15} // namespace
16
18 if (auto host = UIHost::resolve(host_)) host->get().setTree(window("", {}));
19}
20
22 auto host = UIHost::resolve(host_);
23 if (!host) {
24 host_ = UIHost::createHost(kSceneHostName);
25 host = UIHost::resolve(host_);
26 }
27 if (!host) return;
28 host->get().setVisible(true);
29 host->get().setLayer(80);
30 refresh();
31}
32
34 if (auto host = UIHost::resolve(host_)) host->get().setVisible(false);
35}
36
37bool ScenePanel::isOpen() const {
38 auto host = UIHost::resolve(host_);
39 return host && host->get().meta()->visible;
40}
41
43 if (auto host = UIHost::resolve(host_)) host->get().setTree(build());
44}
45
46bool ScenePanel::selectNode(const std::string& id) {
47 eve::ISceneQuery* scene = eve::cap::query<eve::ISceneQuery>();
48 if (!scene || id.empty()) return false;
50 if (!scene->getNode(id, &info)) return false;
51 selectedId_ = id;
52 rebuildHost();
53 return true;
54}
55
56void ScenePanel::setPickHandler(std::function<void(const std::string&)> handler) {
57 pickHandler_ = std::move(handler);
58}
59
60WidgetDesc ScenePanel::nodeTree(const eve::SceneNodeInfo& node,
61 const std::vector<eve::SceneNodeInfo>& all) {
62 std::vector<WidgetDesc> children;
63 children.push_back(button("select " + node.name + "##sel_" + node.id,
64 "sel_" + node.id,
65 [this, id = node.id]() { selectNode(id); }));
66 for (const std::string& childId : node.children) {
67 const auto found =
68 std::find_if(all.begin(), all.end(),
69 [&](const eve::SceneNodeInfo& n) { return n.id == childId; });
70 if (found == all.end()) continue;
71 children.push_back(nodeTree(*found, all));
72 }
73 return collapsingHeader(
74 node.name + "##hdr_" + node.id, std::move(children), "node_" + node.id,
75 false);
76}
77
79 std::vector<WidgetDesc> children;
80 eve::ISceneQuery* scene = eve::cap::query<eve::ISceneQuery>();
81 if (!scene) {
82 children.push_back(text(
83 "Scene module unavailable. This build has no scene support.",
84 "scene_missing"));
85 return window("Scene", std::move(children), "root");
86 }
87
88 const std::vector<eve::SceneNodeInfo> nodes = scene->nodes(512);
89 const std::string hostName = scene->activeHost();
90 children.push_back(row(
91 {
92 text("Scene: " + (hostName.empty() ? std::string("(none)") : hostName),
93 "scene_host"),
94 spacer("scene_spacer"),
95 button("Refresh##scene_refresh", "scene_refresh",
96 [this]() { refresh(); }),
97 },
98 "scene_toolbar"));
99 children.push_back(separator("scene_sep"));
100
101 // Tree roots (nodes without a parent present in the snapshot).
102 for (const eve::SceneNodeInfo& node : nodes) {
103 const bool hasParent =
104 !node.parent.empty() &&
105 std::find_if(nodes.begin(), nodes.end(),
106 [&](const eve::SceneNodeInfo& n) {
107 return n.id == node.parent;
108 }) != nodes.end();
109 if (!hasParent) children.push_back(nodeTree(node, nodes));
110 }
111
112 // Selected node property sheet.
113 if (!selectedId_.empty()) {
115 if (scene->getNode(selectedId_, &info)) {
116 const std::string base = "node_" + info.id;
117 children.push_back(separator("scene_sel_sep"));
118 children.push_back(text("id: " + info.id, base + "_id"));
119 children.push_back(text("path: " + info.path, base + "_path"));
120 children.push_back(row(
121 {
122 text("x", base + "_lx"),
123 inputText("##" + base + "_x", std::to_string(info.x),
124 base + "_x",
125 [id = info.id, scene](const std::string& t) {
126 eve::SceneNodeInfo cur;
127 if (!scene->getNode(id, &cur)) return;
128 cur.x = static_cast<float>(std::atof(t.c_str()));
129 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
130 }),
131 text("y", base + "_ly"),
132 inputText("##" + base + "_y", std::to_string(info.y),
133 base + "_y",
134 [id = info.id, scene](const std::string& t) {
135 eve::SceneNodeInfo cur;
136 if (!scene->getNode(id, &cur)) return;
137 cur.y = static_cast<float>(std::atof(t.c_str()));
138 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
139 }),
140 text("z", base + "_lz"),
141 inputText("##" + base + "_z", std::to_string(info.z),
142 base + "_z",
143 [id = info.id, scene](const std::string& t) {
144 eve::SceneNodeInfo cur;
145 if (!scene->getNode(id, &cur)) return;
146 cur.z = static_cast<float>(std::atof(t.c_str()));
147 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
148 }),
149 },
150 base + "_transform"));
151 children.push_back(row(
152 {
153 checkbox("visible##" + base + "_vis", info.visible,
154 base + "_visible",
155 [id = info.id, scene](bool v) {
156 scene->setNodeVisible(id, v);
157 }),
158 spacer(base + "_vis_spacer"),
159 button("Pick##" + base + "_pick", base + "_pick",
160 [this, id = info.id]() {
161 if (pickHandler_) pickHandler_(id);
162 }),
163 },
164 base + "_actions"));
165 }
166 }
167 return window("Scene", std::move(children), "root");
168}
169
170void ScenePanel::rebuildHost() {
171 auto host = UIHost::resolve(host_);
172 if (!host || !host->get().meta()->visible) return;
173 host->get().setTree(build());
174}
175
176} // namespace eve::ui
glm::vec3 n
Definition Grass.cpp:63
float v
std::string text
HSQOBJECT handler
std::vector< BvhNode > nodes
std::string id
Definition PlayHost.cpp:108
std::weak_ptr< PrimitiveScene > scene
float t
const RoadNode * node
bool found
int children
Definition TreeMesh.cpp:295
Scene graph query/mutation surface (provided by the scene module).
Definition SceneQuery.h:30
~ScenePanel()
Scene panel.
UIHostHandle host() const noexcept
Returns the mounted scene host handle, or an empty handle until open().
Definition ScenePanel.h:43
WidgetDesc build()
Declarative tree of the current scene state.
void open()
Mounts (or updates) the scene host on the UI ECS world.
void refresh()
Re-queries the scene graph and rebuilds the tree.
void close()
Hides the scene host.
bool isOpen() const
True while the scene host is mounted and visible.
bool selectNode(const std::string &id)
Selects a node by id; false when unknown or no scene module.
void setPickHandler(std::function< void(const std::string &)> handler)
Registers the pick handler for the Pick button.
static UIHostHandle createHost(const std::string &name="")
Creates an ECS-owned UI host.
Definition UIHost.cpp:48
static eve::OptionalRef< UIHost > resolve(UIHostHandle handle) noexcept
Resolves a UI host handle with ECS generation checking.
Definition UIHost.cpp:61
WidgetDesc collapsingHeader(std::string label, std::vector< WidgetDesc > children, std::string id, bool defaultOpen)
Collapsible header containing child widgets.
Definition Widget.cpp:623
WidgetDesc checkbox(std::string label, bool checked, std::string id, std::function< void(bool)> onToggle)
Checkbox with a label; fires onToggle.
Definition Widget.cpp:353
WidgetDesc inputText(std::string label, std::string value, std::string id, std::function< void(const std::string &)> onChange)
Editable text field; fires onTextChange.
Definition Widget.cpp:453
WidgetDesc window(std::string title, std::vector< WidgetDesc > children, std::string id)
Top-level window widget with a title bar.
Definition Widget.cpp:292
WidgetDesc spacer(std::string id, float grow)
Flexible empty space; default flexGrow=1 so it absorbs free space in a Flex parent.
Definition Widget.cpp:697
WidgetDesc button(std::string label, std::string id, std::function< void()> onClick)
Clickable button; fires onClick.
Definition Widget.cpp:311
WidgetDesc row(std::vector< WidgetDesc > children, std::string id)
Horizontal elastic layout row.
Definition Widget.cpp:679
WidgetDesc separator(std::string id)
Horizontal separator line.
Definition Widget.cpp:345
Serializable snapshot of one scene node (value type, no scene types).
Definition SceneQuery.h:17
std::string id
Definition SceneQuery.h:18
Declarative widget description (build once / on dirty → flatten into UIHost::Tree).
Definition Widget.h:15
glm::uvec4 info