载入中...
搜索中...
未找到
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 (host_) host_->setTree(window("", {}));
19}
20
22 if (!host_) host_ = UIHost::createHost(kSceneHostName);
23 host_->setVisible(true);
24 host_->setLayer(80);
25 refresh();
26}
27
29 if (host_) host_->setVisible(false);
30}
31
32bool ScenePanel::isOpen() const {
33 return host_ && host_->meta()->visible;
34}
35
37 if (host_) host_->setTree(build());
38}
39
40bool ScenePanel::selectNode(const std::string& id) {
42 if (!scene || id.empty()) return false;
44 if (!scene->getNode(id, &info)) return false;
45 selectedId_ = id;
46 rebuildHost();
47 return true;
48}
49
50void ScenePanel::setPickHandler(std::function<void(const std::string&)> handler) {
51 pickHandler_ = std::move(handler);
52}
53
54WidgetDesc ScenePanel::nodeTree(const eve::SceneNodeInfo& node,
55 const std::vector<eve::SceneNodeInfo>& all) {
56 std::vector<WidgetDesc> children;
57 children.push_back(button("select " + node.name + "##sel_" + node.id,
58 "sel_" + node.id,
59 [this, id = node.id]() { selectNode(id); }));
60 for (const std::string& childId : node.children) {
61 const auto found =
62 std::find_if(all.begin(), all.end(),
63 [&](const eve::SceneNodeInfo& n) { return n.id == childId; });
64 if (found == all.end()) continue;
65 children.push_back(nodeTree(*found, all));
66 }
67 return collapsingHeader(
68 node.name + "##hdr_" + node.id, std::move(children), "node_" + node.id,
69 false);
70}
71
73 std::vector<WidgetDesc> children;
75 if (!scene) {
76 children.push_back(text(
77 "Scene module unavailable. This build has no scene support.",
78 "scene_missing"));
79 return window("Scene", std::move(children), "root");
80 }
81
82 const std::vector<eve::SceneNodeInfo> nodes = scene->nodes(512);
83 const std::string hostName = scene->activeHost();
84 children.push_back(row(
85 {
86 text("Scene: " + (hostName.empty() ? std::string("(none)") : hostName),
87 "scene_host"),
88 spacer("scene_spacer"),
89 button("Refresh##scene_refresh", "scene_refresh",
90 [this]() { refresh(); }),
91 },
92 "scene_toolbar"));
93 children.push_back(separator("scene_sep"));
94
95 // Tree roots (nodes without a parent present in the snapshot).
96 for (const eve::SceneNodeInfo& node : nodes) {
97 const bool hasParent =
98 !node.parent.empty() &&
99 std::find_if(nodes.begin(), nodes.end(),
100 [&](const eve::SceneNodeInfo& n) {
101 return n.id == node.parent;
102 }) != nodes.end();
103 if (!hasParent) children.push_back(nodeTree(node, nodes));
104 }
105
106 // Selected node property sheet.
107 if (!selectedId_.empty()) {
109 if (scene->getNode(selectedId_, &info)) {
110 const std::string base = "node_" + info.id;
111 children.push_back(separator("scene_sel_sep"));
112 children.push_back(text("id: " + info.id, base + "_id"));
113 children.push_back(text("path: " + info.path, base + "_path"));
114 children.push_back(row(
115 {
116 text("x", base + "_lx"),
117 inputText("##" + base + "_x", std::to_string(info.x),
118 base + "_x",
119 [id = info.id, scene](const std::string& t) {
120 eve::SceneNodeInfo cur;
121 if (!scene->getNode(id, &cur)) return;
122 cur.x = static_cast<float>(std::atof(t.c_str()));
123 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
124 }),
125 text("y", base + "_ly"),
126 inputText("##" + base + "_y", std::to_string(info.y),
127 base + "_y",
128 [id = info.id, scene](const std::string& t) {
129 eve::SceneNodeInfo cur;
130 if (!scene->getNode(id, &cur)) return;
131 cur.y = static_cast<float>(std::atof(t.c_str()));
132 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
133 }),
134 text("z", base + "_lz"),
135 inputText("##" + base + "_z", std::to_string(info.z),
136 base + "_z",
137 [id = info.id, scene](const std::string& t) {
138 eve::SceneNodeInfo cur;
139 if (!scene->getNode(id, &cur)) return;
140 cur.z = static_cast<float>(std::atof(t.c_str()));
141 scene->setNodeTransform(id, cur.x, cur.y, cur.z);
142 }),
143 },
144 base + "_transform"));
145 children.push_back(row(
146 {
147 checkbox("visible##" + base + "_vis", info.visible,
148 base + "_visible",
149 [id = info.id, scene](bool v) {
150 scene->setNodeVisible(id, v);
151 }),
152 spacer(base + "_vis_spacer"),
153 button("Pick##" + base + "_pick", base + "_pick",
154 [this, id = info.id]() {
155 if (pickHandler_) pickHandler_(id);
156 }),
157 },
158 base + "_actions"));
159 }
160 }
161 return window("Scene", std::move(children), "root");
162}
163
164void ScenePanel::rebuildHost() {
165 if (!host_ || !host_->meta()->visible) return;
166 host_->setTree(build());
167}
168
169} // namespace eve::ui
std::string id
glm::vec3 n
Definition Grass.cpp:64
int v
int children
Definition TreeMesh.cpp:177
Scene graph query/mutation surface (provided by the scene module).
Definition SceneQuery.h:30
virtual std::string activeHost() const =0
Name of the currently selected host, or "" when none.
virtual bool getNode(const std::string &id, SceneNodeInfo *out) const =0
Look up one node in the active host.
virtual std::vector< SceneNodeInfo > nodes(int limit) const =0
Depth-first node list of the active host, capped at limit.
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 UIHost * createHost(const std::string &name="")
Definition UIHost.cpp:11
void setTree(WidgetDesc root)
Full replace.
Definition UIHost.cpp:26
void setLayer(int layer)
Definition UIHost.h:209
void setVisible(bool v)
Host visibility / layer / modality.
Definition UIHost.h:208
I * query()
Definition Capability.h:77
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:439
WidgetDesc text(std::string content, std::string id)
Static text label.
Definition Widget.cpp:235
WidgetDesc checkbox(std::string label, bool checked, std::string id, std::function< void(bool)> onToggle)
Checkbox with a label; fires onToggle.
Definition Widget.cpp:279
WidgetDesc separator(std::string id)
Horizontal separator line.
Definition Widget.cpp:271
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:363
WidgetDesc window(std::string title, std::vector< WidgetDesc > children, std::string id)
Top-level window widget with a title bar.
Definition Widget.cpp:225
WidgetDesc collapsingHeader(std::string label, std::vector< WidgetDesc > children, std::string id, bool defaultOpen)
Collapsible header containing child widgets.
Definition Widget.cpp:375
WidgetDesc button(std::string label, std::string id, std::function< void()> onClick)
Clickable button; fires onClick.
Definition Widget.cpp:244
WidgetDesc row(std::vector< WidgetDesc > children, std::string id)
Horizontal elastic layout row.
Definition Widget.cpp:431
Serializable snapshot of one scene node (value type, no scene types).
Definition SceneQuery.h:17
std::string path
Definition SceneQuery.h:20
std::string id
Definition SceneQuery.h:18
std::string id
Definition NodeDesc.h:16
std::string name
Definition NodeDesc.h:19
Declarative widget description (build once / on dirty → flatten into UIHost::Tree).
Definition Widget.h:13