载入中...
搜索中...
未找到
Editor.cpp
浏览该文件的文档.
1#include "editor/Editor.h"
2
3#include "common/Capability.h"
6#include "editor/EditorDock.h"
13#include "editor/GizmoManager.h"
17
18
19#include <simplesquirrel/simplesquirrel.hpp>
20
21#include <algorithm>
22#include <cmath>
23#include <cstdint>
24#include <memory>
25#include <stdexcept>
26#include <type_traits>
27#include <utility>
28#include <vector>
29
30namespace eve::editor {
31
33
34namespace {
35
36const char* statusName(EditorStatus status) {
37 switch (status) {
38 case EditorStatus::Ok: return "ok";
39 case EditorStatus::Applied: return "applied";
40 case EditorStatus::Pending: return "pending";
41 case EditorStatus::NoOp: return "no-op";
42 case EditorStatus::Rejected: return "rejected";
43 case EditorStatus::Conflict: return "conflict";
44 case EditorStatus::NotFound: return "not-found";
45 case EditorStatus::Unsupported: return "unsupported";
46 case EditorStatus::Cancelled: return "cancelled";
47 case EditorStatus::Failed: return "failed";
48 }
49 return "failed";
50}
51
52const char* transactionStateName(TransactionState state) {
53 switch (state) {
54 case TransactionState::Planning: return "planning";
55 case TransactionState::Previewing: return "previewing";
56 case TransactionState::PendingAuthority: return "pending-authority";
57 case TransactionState::Committed: return "committed";
58 case TransactionState::RolledBack: return "rolled-back";
59 case TransactionState::Rejected: return "rejected";
60 case TransactionState::Conflicted: return "conflicted";
61 case TransactionState::Failed: return "failed";
62 }
63 return "failed";
64}
65
66bool squirrelToEditorValue(HSQUIRRELVM vm, SQInteger index, EditorValue& out, size_t depth = 0) {
67 if (!vm || depth > 32) return false;
68 const SQInteger absolute = index > 0 ? index : sq_gettop(vm) + index + 1;
69 switch (sq_gettype(vm, absolute)) {
70 case OT_NULL: out = EditorValue{}; return true;
71 case OT_BOOL: {
72 SQBool value = SQFalse;
73 if (SQ_FAILED(sq_getbool(vm, absolute, &value))) return false;
74 out = EditorValue(value != SQFalse);
75 return true;
76 }
77 case OT_INTEGER: {
78 SQInteger value = 0;
79 if (SQ_FAILED(sq_getinteger(vm, absolute, &value))) return false;
80 out = EditorValue(static_cast<int64_t>(value));
81 return true;
82 }
83 case OT_FLOAT: {
84 SQFloat value = 0;
85 if (SQ_FAILED(sq_getfloat(vm, absolute, &value))) return false;
86 out = EditorValue(static_cast<double>(value));
87 return true;
88 }
89 case OT_STRING: {
90 const SQChar* value = nullptr;
91 if (SQ_FAILED(sq_getstring(vm, absolute, &value))) return false;
92 out = EditorValue(value ? value : "");
93 return true;
94 }
95 case OT_ARRAY: {
97 const SQInteger count = sq_getsize(vm, absolute);
98 values.reserve(static_cast<size_t>(count));
99 for (SQInteger i = 0; i < count; ++i) {
100 sq_pushinteger(vm, i);
101 if (SQ_FAILED(sq_get(vm, absolute))) return false;
103 const bool ok = squirrelToEditorValue(vm, -1, value, depth + 1);
104 sq_pop(vm, 1);
105 if (!ok) return false;
106 values.push_back(std::move(value));
107 }
108 out = EditorValue(std::move(values));
109 return true;
110 }
111 case OT_TABLE: {
113 sq_pushnull(vm);
114 while (SQ_SUCCEEDED(sq_next(vm, absolute))) {
115 const SQChar* key = nullptr;
116 const bool keyOk = sq_gettype(vm, -2) == OT_STRING && SQ_SUCCEEDED(sq_getstring(vm, -2, &key)) && key;
117 const std::string stableKey = keyOk ? key : "";
119 const bool valueOk = keyOk && squirrelToEditorValue(vm, -1, value, depth + 1);
120 sq_pop(vm, 2);
121 if (!valueOk) {
122 sq_pop(vm, 1);
123 return false;
124 }
125 values[stableKey] = std::move(value);
126 }
127 sq_pop(vm, 1);
128 out = EditorValue(std::move(values));
129 return true;
130 }
131 default: return false;
132 }
133}
134
135bool objectToEditorValue(const ssq::Object& object, EditorValue& out) {
136 HSQUIRRELVM vm = object.getHandle();
137 if (!vm) return false;
138 const SQInteger top = sq_gettop(vm);
139 sq_pushobject(vm, object.getRaw());
140 const bool ok = squirrelToEditorValue(vm, -1, out);
141 sq_settop(vm, top);
142 return ok;
143}
144
145void pushEditorValue(HSQUIRRELVM vm, const EditorValue& value) {
146 std::visit(
147 [&](const auto& current) {
148 using T = std::decay_t<decltype(current)>;
149 if constexpr (std::is_same_v<T, std::monostate>) {
150 sq_pushnull(vm);
151 } else if constexpr (std::is_same_v<T, bool>) {
152 sq_pushbool(vm, current ? SQTrue : SQFalse);
153 } else if constexpr (std::is_same_v<T, int64_t>) {
154 sq_pushinteger(vm, static_cast<SQInteger>(current));
155 } else if constexpr (std::is_same_v<T, double>) {
156 sq_pushfloat(vm, static_cast<SQFloat>(current));
157 } else if constexpr (std::is_same_v<T, std::string>) {
158 sq_pushstring(vm, current.c_str(), static_cast<SQInteger>(current.size()));
159 } else if constexpr (std::is_same_v<T, EditorValue::Array>) {
160 sq_newarray(vm, 0);
161 for (const EditorValue& entry : current) {
162 pushEditorValue(vm, entry);
163 sq_arrayappend(vm, -2);
164 }
165 } else if constexpr (std::is_same_v<T, EditorValue::Object>) {
166 sq_newtable(vm);
167 for (const auto& [key, entry] : current) {
168 sq_pushstring(vm, key.c_str(), static_cast<SQInteger>(key.size()));
169 pushEditorValue(vm, entry);
170 sq_newslot(vm, -3, SQFalse);
171 }
172 }
173 },
174 value.storage());
175}
176
177void setValue(ssq::Table& table, const char* name, const EditorValue& value) {
178 HSQUIRRELVM vm = table.getHandle();
179 sq_pushobject(vm, table.getRaw());
180 sq_pushstring(vm, name, -1);
181 pushEditorValue(vm, value);
182 sq_newslot(vm, -3, SQFalse);
183 sq_pop(vm, 1);
184}
185
186ssq::Array diagnosticArray(HSQUIRRELVM vm, const std::vector<EditorDiagnostic>& diagnostics) {
187 ssq::Array out(vm);
188 for (const EditorDiagnostic& diagnostic : diagnostics) {
189 ssq::Table item(vm);
190 item.set("rule", editing::diagnosticRule(diagnostic).value());
191 item.set("message", diagnostic.message());
192 item.set("severity", static_cast<int>(diagnostic.severity()));
193 out.push(item);
194 }
195 return out;
196}
197
198template <class T>
199ssq::Table resultTable(HSQUIRRELVM vm, const Result<T>& result) {
200 ssq::Table out(vm);
201 out.set("status", std::string(statusName(result.code())));
202 out.set("accepted", result.ok());
203 out.set("diagnostics", diagnosticArray(vm, result.diagnostics()));
204 return out;
205}
206
207Result<EditorValue> invalidScriptPayload() {
208 return eve::editing::failed<EditorValue>(
209 EditorStatus::Rejected, RuleId("editor.script.invalid-payload"),
210 "Script payload must contain only null, bool, number, string, array, or table values");
211}
212
213bool invokeScriptCommand(const ssq::Object& callback, const EditorValue& payload) {
214 const SQObjectType type = callback.getRaw()._type;
215 if (type != OT_CLOSURE && type != OT_NATIVECLOSURE) return false;
216 HSQUIRRELVM vm = callback.getHandle();
217 SQInteger top = sq_gettop(vm);
218 sq_pushobject(vm, callback.getRaw());
219 sq_pushroottable(vm);
220 pushEditorValue(vm, payload);
221 bool accepted = false;
222 if (SQ_SUCCEEDED(sq_call(vm, 2, SQTrue, SQTrue))) {
223 SQBool result = SQFalse;
224 accepted = SQ_SUCCEEDED(sq_getbool(vm, -1, &result)) && result != SQFalse;
225 }
226 sq_settop(vm, top);
227 return accepted;
228}
229
230bool registerScriptCommand(Editor* editor, const std::string& id, const std::string& displayName,
231 const std::string& category, ssq::Object callback) {
232 if (!editor || id.empty()) return false;
233 const SQObjectType callbackType = callback.getRaw()._type;
234 if (callbackType != OT_CLOSURE && callbackType != OT_NATIVECLOSURE) return false;
235
236 CommandDescriptor descriptor;
237 descriptor.id = CommandId(id);
238 descriptor.ownerModule = "script:" + id;
239 descriptor.displayName = displayName;
240 descriptor.category = category;
241 descriptor.automationAllowed = false;
242 return editor->commandService()
243 .registerPlannedCommand(
245 [id](const CommandRequest& request) {
246 CommandPlan plan;
247 plan.summary = EditorValue::Object{{"command", EditorValue(id)}, {"payload", request.payload}};
249 operation.type = id;
250 operation.payload = request.payload;
251 plan.operations.push_back(std::move(operation));
252 return eve::editing::applied<CommandPlan>(std::move(plan));
253 },
254 [callback = std::move(callback)](const CommandRequest& request, const CommandPlan& plan) {
255 if (!invokeScriptCommand(callback, request.payload))
256 return eve::editing::failed<TransactionReceipt>(
257 EditorStatus::Rejected, RuleId("editor.script.command-rejected"),
258 "Script command callback rejected the planned payload");
259 TransactionReceipt receipt;
260 receipt.id = TransactionId(plan.id.value());
261 receipt.state = TransactionState::Committed;
262 receipt.beforeRevision = plan.baseRevision;
263 receipt.afterRevision = plan.baseRevision + 1;
264 receipt.authorityReceipt = "script:local";
265 return eve::editing::applied<TransactionReceipt>(std::move(receipt));
266 },
267 true)
268 .ok();
269}
270
271} // namespace
272
274 : targets_(std::make_unique<EditorTargetCoordinator>(commandService_)),
275 automation_(std::make_unique<EditorAutomationProvider>(commandService_, *targets_)) {
276 eve::cap::provide<eve::editing::IEditingCommandRegistry>(targets_.get());
277 eve::cap::provide<eve::IEditorAutomation>(automation_.get());
278}
279
281 eve::cap::revoke<eve::IEditorAutomation>(automation_.get());
282 eve::cap::revoke<eve::editing::IEditingCommandRegistry>(targets_.get());
283}
284
286
288 auto result = targets_->unregisterTarget(target);
289 if (result.code() == EditorStatus::Applied) automation_->targetUnregistered(target);
290 return result;
291}
292
296
297std::unique_ptr<TransformGizmo> Editor::newGizmo() { return std::make_unique<TransformGizmo>(); }
298
299std::unique_ptr<GizmoManager> Editor::newGizmoManager() { return std::make_unique<GizmoManager>(); }
300
301std::unique_ptr<EditorToolbar> Editor::newToolbar() { return std::make_unique<EditorToolbar>(); }
302
303std::unique_ptr<EditorInspector> Editor::newInspector() { return std::make_unique<EditorInspector>(); }
304
305std::unique_ptr<EditorDock> Editor::newDock() { return std::make_unique<EditorDock>(); }
306
307std::unique_ptr<EditorSession> Editor::newSession() {
308 auto session = std::make_unique<EditorSession>();
309 session->setCommandService(&commandService_);
310 return session;
311}
312
313Result<std::unique_ptr<EditorWorkspace>> Editor::newWorkspace(const std::string& id, const std::string& title) {
314 if (id.empty())
315 return eve::editing::failed<std::unique_ptr<EditorWorkspace>>(
316 EditorStatus::Rejected, RuleId("editor.workspace.empty-id"), "Workspace id must be non-empty");
317 return eve::editing::applied<std::unique_ptr<EditorWorkspace>>(
318 std::make_unique<EditorWorkspace>(id, title.empty() ? id : title));
319}
320
321std::unique_ptr<ScriptEditorTool> Editor::newScriptTool(const std::string& id, const std::string& label) {
322 return std::make_unique<ScriptEditorTool>(id, label);
323}
324
325std::unique_ptr<ConstantBrushFalloff> Editor::newConstantBrushFalloff() {
326 return std::make_unique<ConstantBrushFalloff>();
327}
328std::unique_ptr<LinearBrushFalloff> Editor::newLinearBrushFalloff() { return std::make_unique<LinearBrushFalloff>(); }
329std::unique_ptr<SmoothBrushFalloff> Editor::newSmoothBrushFalloff() { return std::make_unique<SmoothBrushFalloff>(); }
330std::unique_ptr<CircleBrushKernel> Editor::newCircleBrushKernel() { return std::make_unique<CircleBrushKernel>(); }
331std::unique_ptr<BoxBrushKernel> Editor::newBoxBrushKernel() { return std::make_unique<BoxBrushKernel>(); }
332std::unique_ptr<PaintIntFieldOperation> Editor::newPaintIntFieldOperation(int value) {
333 return std::make_unique<PaintIntFieldOperation>(value);
334}
335std::unique_ptr<AddScalarFieldOperation> Editor::newAddScalarFieldOperation() {
336 return std::make_unique<AddScalarFieldOperation>();
337}
338std::unique_ptr<FieldBrushTool> Editor::newFieldBrushTool(const std::string& id, const std::string& label) {
339 return std::make_unique<FieldBrushTool>(id, label, nullptr, nullptr);
340}
341
342std::unique_ptr<SphereVolumeBrushKernel> Editor::newSphereVolumeBrushKernel() {
343 return std::make_unique<SphereVolumeBrushKernel>();
344}
345std::unique_ptr<BoxVolumeBrushKernel> Editor::newBoxVolumeBrushKernel() {
346 return std::make_unique<BoxVolumeBrushKernel>();
347}
348std::unique_ptr<PaintIntVolumeOperation> Editor::newPaintIntVolumeOperation(int value) {
349 return std::make_unique<PaintIntVolumeOperation>(value);
350}
351std::unique_ptr<VolumeBrushTool> Editor::newVolumeBrushTool(const std::string& id, const std::string& label) {
352 return std::make_unique<VolumeBrushTool>(id, label);
353}
354
355void Editor::expose(ssq::Table& table) {
356 auto cls = table.addClass(name, Editor::create, false);
357 expose(cls);
358
359 auto gizmo = table.addClass<TransformGizmo>(
360 "TransformGizmo", std::function<TransformGizmo*()>([]() -> TransformGizmo* { return nullptr; }), true);
361 gizmo.addFunc("setMode", &TransformGizmo::setMode);
362 gizmo.addFunc("getMode", &TransformGizmo::getMode);
363 gizmo.addFunc("setSpace", &TransformGizmo::setSpace);
364 gizmo.addFunc("getSpace", &TransformGizmo::getSpace);
365 gizmo.addFunc("setSize", &TransformGizmo::setSize);
366 gizmo.addFunc("getSize", &TransformGizmo::getSize);
367 gizmo.addFunc("setPosition", &TransformGizmo::setPosition);
368 gizmo.addFunc("getPositionX", &TransformGizmo::getPositionX);
369 gizmo.addFunc("getPositionY", &TransformGizmo::getPositionY);
370 gizmo.addFunc("getPositionZ", &TransformGizmo::getPositionZ);
371 gizmo.addFunc("setRotationEuler", &TransformGizmo::setRotationEuler);
372 gizmo.addFunc("getRotationX", &TransformGizmo::getRotationX);
373 gizmo.addFunc("getRotationY", &TransformGizmo::getRotationY);
374 gizmo.addFunc("getRotationZ", &TransformGizmo::getRotationZ);
375 gizmo.addFunc("setScale", &TransformGizmo::setScale);
376 gizmo.addFunc("getScaleX", &TransformGizmo::getScaleX);
377 gizmo.addFunc("getScaleY", &TransformGizmo::getScaleY);
378 gizmo.addFunc("getScaleZ", &TransformGizmo::getScaleZ);
379 gizmo.addFunc("setBounds", &TransformGizmo::setBounds);
380 gizmo.addFunc("getBoundsMinX", &TransformGizmo::getBoundsMinX);
381 gizmo.addFunc("getBoundsMinY", &TransformGizmo::getBoundsMinY);
382 gizmo.addFunc("getBoundsMinZ", &TransformGizmo::getBoundsMinZ);
383 gizmo.addFunc("getBoundsMaxX", &TransformGizmo::getBoundsMaxX);
384 gizmo.addFunc("getBoundsMaxY", &TransformGizmo::getBoundsMaxY);
385 gizmo.addFunc("getBoundsMaxZ", &TransformGizmo::getBoundsMaxZ);
386 gizmo.addFunc("setSnapTranslate", &TransformGizmo::setSnapTranslate);
387 gizmo.addFunc("setSnapRotate", &TransformGizmo::setSnapRotate);
388 gizmo.addFunc("setSnapScale", &TransformGizmo::setSnapScale);
389 gizmo.addFunc("getSnapTranslateX", &TransformGizmo::getSnapTranslateX);
390 gizmo.addFunc("getSnapTranslateY", &TransformGizmo::getSnapTranslateY);
391 gizmo.addFunc("getSnapTranslateZ", &TransformGizmo::getSnapTranslateZ);
392 gizmo.addFunc("getSnapRotate", &TransformGizmo::getSnapRotate);
393 gizmo.addFunc("getSnapScale", &TransformGizmo::getSnapScale);
394 gizmo.addFunc("getMatrix", &TransformGizmo::getMatrix);
395 gizmo.addFunc("pick", &TransformGizmo::pick);
396 gizmo.addFunc("beginDrag", &TransformGizmo::beginDrag);
397 gizmo.addFunc("updateDrag", &TransformGizmo::updateDrag);
398 gizmo.addFunc("endDrag", &TransformGizmo::endDrag);
399 gizmo.addFunc("isDragging", &TransformGizmo::isDragging);
400 gizmo.addFunc("isHovered", &TransformGizmo::isHovered);
401 gizmo.addFunc("getActiveAxis", &TransformGizmo::getActiveAxis);
402 gizmo.addFunc("getHoverAxis", &TransformGizmo::getHoverAxis);
403 gizmo.addFunc("rebuildParts", &TransformGizmo::rebuildParts);
404 gizmo.addFunc("getPartCount", &TransformGizmo::getPartCount);
405 gizmo.addFunc("getPartKind", &TransformGizmo::getPartKind);
406 gizmo.addFunc("getPartAxis", &TransformGizmo::getPartAxis);
407 gizmo.addFunc("getPartColorR", &TransformGizmo::getPartColorR);
408 gizmo.addFunc("getPartColorG", &TransformGizmo::getPartColorG);
409 gizmo.addFunc("getPartColorB", &TransformGizmo::getPartColorB);
410 gizmo.addFunc("getPartColorA", &TransformGizmo::getPartColorA);
411 gizmo.addFunc("getPartOriginX", &TransformGizmo::getPartOriginX);
412 gizmo.addFunc("getPartOriginY", &TransformGizmo::getPartOriginY);
413 gizmo.addFunc("getPartOriginZ", &TransformGizmo::getPartOriginZ);
414 gizmo.addFunc("getPartDirX", &TransformGizmo::getPartDirX);
415 gizmo.addFunc("getPartDirY", &TransformGizmo::getPartDirY);
416 gizmo.addFunc("getPartDirZ", &TransformGizmo::getPartDirZ);
417 gizmo.addFunc("getPartLength", &TransformGizmo::getPartLength);
418 gizmo.addFunc("getPartRadius", &TransformGizmo::getPartRadius);
419
420 auto mgr = table.addClass<GizmoManager>(
421 "GizmoManager", std::function<GizmoManager*()>([]() -> GizmoManager* { return nullptr; }), true);
422 mgr.addFunc("getGizmo", &GizmoManager::getGizmo);
423 mgr.addFunc("setPositionEnabled", &GizmoManager::setPositionEnabled);
424 mgr.addFunc("setRotationEnabled", &GizmoManager::setRotationEnabled);
425 mgr.addFunc("setScaleEnabled", &GizmoManager::setScaleEnabled);
426 mgr.addFunc("setBoundEnabled", &GizmoManager::setBoundEnabled);
427 mgr.addFunc("getPositionEnabled", &GizmoManager::getPositionEnabled);
428 mgr.addFunc("getRotationEnabled", &GizmoManager::getRotationEnabled);
429 mgr.addFunc("getScaleEnabled", &GizmoManager::getScaleEnabled);
430 mgr.addFunc("getBoundEnabled", &GizmoManager::getBoundEnabled);
431 mgr.addFunc("attach", &GizmoManager::attach);
432 mgr.addFunc("detach", &GizmoManager::detach);
433 mgr.addFunc("isAttached", &GizmoManager::isAttached);
434 mgr.addFunc("pick", &GizmoManager::pick);
435 mgr.addFunc("beginDrag", &GizmoManager::beginDrag);
436 mgr.addFunc("updateDrag", &GizmoManager::updateDrag);
437 mgr.addFunc("endDrag", &GizmoManager::endDrag);
438 mgr.addFunc("isDragging", &GizmoManager::isDragging);
439 mgr.addFunc("isHovered", &GizmoManager::isHovered);
440
441 auto tb = table.addClass<EditorToolbar>(
442 "EditorToolbar", std::function<EditorToolbar*()>([]() -> EditorToolbar* { return nullptr; }), true);
443 tb.addFunc("clear", &EditorToolbar::clear);
444 tb.addFunc("addTool", &EditorToolbar::addTool);
445 tb.addFunc("setIcon", &EditorToolbar::setIcon);
446 tb.addFunc("setShortcut", &EditorToolbar::setShortcut);
447 tb.addFunc("setActive", &EditorToolbar::setActive);
448 tb.addFunc("getActive", &EditorToolbar::getActive);
449 tb.addFunc("matchShortcut", &EditorToolbar::matchShortcut);
450 tb.addFunc("getToolCount", &EditorToolbar::getToolCount);
451 tb.addFunc("getToolId", &EditorToolbar::getToolId);
452 tb.addFunc("getToolLabel", &EditorToolbar::getToolLabel);
453 tb.addFunc("getToolIcon", &EditorToolbar::getToolIcon);
454 tb.addFunc("getToolShortcut", &EditorToolbar::getToolShortcut);
455
456 auto insp = table.addClass<EditorInspector>(
457 "EditorInspector", std::function<EditorInspector*()>([]() -> EditorInspector* { return nullptr; }), true);
458 insp.addFunc("clear", &EditorInspector::clear);
459 insp.addFunc("addFloat", &EditorInspector::addFloat);
460 insp.addFunc("addFloat3", &EditorInspector::addFloat3);
461 insp.addFunc("addBool", &EditorInspector::addBool);
462 insp.addFunc("addString", &EditorInspector::addString);
463 insp.addFunc("addChoice", &EditorInspector::addChoice);
464 insp.addFunc("getFieldCount", &EditorInspector::getFieldCount);
465 insp.addFunc("getFieldKind", &EditorInspector::getFieldKind);
466 insp.addFunc("getFieldId", &EditorInspector::getFieldId);
467 insp.addFunc("getFieldLabel", &EditorInspector::getFieldLabel);
468 insp.addFunc("getFloat", &EditorInspector::getFloat);
469 insp.addFunc("setFloat", &EditorInspector::setFloat);
470 insp.addFunc("getFloatMin", &EditorInspector::getFloatMin);
471 insp.addFunc("getFloatMax", &EditorInspector::getFloatMax);
472 insp.addFunc("getFloatStep", &EditorInspector::getFloatStep);
473 insp.addFunc("getFloat3X", &EditorInspector::getFloat3X);
474 insp.addFunc("getFloat3Y", &EditorInspector::getFloat3Y);
475 insp.addFunc("getFloat3Z", &EditorInspector::getFloat3Z);
476 insp.addFunc("setFloat3", &EditorInspector::setFloat3);
477 insp.addFunc("getBool", &EditorInspector::getBool);
478 insp.addFunc("setBool", &EditorInspector::setBool);
479 insp.addFunc("getString", &EditorInspector::getString);
480 insp.addFunc("setString", &EditorInspector::setString);
481 insp.addFunc("getChoice", &EditorInspector::getChoice);
482 insp.addFunc("setChoice", &EditorInspector::setChoice);
483 insp.addFunc("getChoicesCsv", &EditorInspector::getChoicesCsv);
484 insp.addFunc("isDirty", &EditorInspector::isDirty);
485 insp.addFunc("clearDirty", &EditorInspector::clearDirty);
486 insp.addFunc("clearAllDirty", &EditorInspector::clearAllDirty);
487 insp.addFunc("pollChangedId", &EditorInspector::pollChangedId);
488
489 auto dock = table.addClass<EditorDock>("EditorDock",
490 std::function<EditorDock*()>([]() -> EditorDock* { return nullptr; }), true);
491 dock.addFunc("setRegionSize", &EditorDock::setRegionSize);
492 dock.addFunc("getRegionSize", &EditorDock::getRegionSize);
493 dock.addFunc("layout", &EditorDock::layout);
494 dock.addFunc("getRegionX", &EditorDock::getRegionX);
495 dock.addFunc("getRegionY", &EditorDock::getRegionY);
496 dock.addFunc("getRegionW", &EditorDock::getRegionW);
497 dock.addFunc("getRegionH", &EditorDock::getRegionH);
498
499 auto constantFalloff = table.addClass<ConstantBrushFalloff>(
500 "ConstantBrushFalloff",
501 std::function<ConstantBrushFalloff*()>([]() -> ConstantBrushFalloff* { return nullptr; }), true);
502 auto linearFalloff = table.addClass<LinearBrushFalloff>(
503 "LinearBrushFalloff", std::function<LinearBrushFalloff*()>([]() -> LinearBrushFalloff* { return nullptr; }),
504 true);
505 auto smoothFalloff = table.addClass<SmoothBrushFalloff>(
506 "SmoothBrushFalloff", std::function<SmoothBrushFalloff*()>([]() -> SmoothBrushFalloff* { return nullptr; }),
507 true);
508 (void)constantFalloff;
509 (void)linearFalloff;
510 (void)smoothFalloff;
511
512 auto circleKernel = table.addClass<CircleBrushKernel>(
513 "CircleBrushKernel", std::function<CircleBrushKernel*()>([]() -> CircleBrushKernel* { return nullptr; }), true);
514 circleKernel.addFunc("setConstantFalloff", [](CircleBrushKernel* self, ConstantBrushFalloff* falloff) {
515 if (self) self->setFalloff(falloff);
516 });
517 circleKernel.addFunc("setLinearFalloff", [](CircleBrushKernel* self, LinearBrushFalloff* falloff) {
518 if (self) self->setFalloff(falloff);
519 });
520 circleKernel.addFunc("setSmoothFalloff", [](CircleBrushKernel* self, SmoothBrushFalloff* falloff) {
521 if (self) self->setFalloff(falloff);
522 });
523
524 auto boxKernel = table.addClass<BoxBrushKernel>(
525 "BoxBrushKernel", std::function<BoxBrushKernel*()>([]() -> BoxBrushKernel* { return nullptr; }), true);
526 boxKernel.addFunc("setConstantFalloff", [](BoxBrushKernel* self, ConstantBrushFalloff* falloff) {
527 if (self) self->setFalloff(falloff);
528 });
529 boxKernel.addFunc("setLinearFalloff", [](BoxBrushKernel* self, LinearBrushFalloff* falloff) {
530 if (self) self->setFalloff(falloff);
531 });
532 boxKernel.addFunc("setSmoothFalloff", [](BoxBrushKernel* self, SmoothBrushFalloff* falloff) {
533 if (self) self->setFalloff(falloff);
534 });
535
536 auto paintOperation = table.addClass<PaintIntFieldOperation>(
537 "PaintIntFieldOperation",
538 std::function<PaintIntFieldOperation*()>([]() -> PaintIntFieldOperation* { return nullptr; }), true);
539 paintOperation.addFunc("setValue", &PaintIntFieldOperation::setValue);
540 paintOperation.addFunc("getValue", &PaintIntFieldOperation::value);
541 auto addScalarOperation = table.addClass<AddScalarFieldOperation>(
542 "AddScalarFieldOperation",
543 std::function<AddScalarFieldOperation*()>([]() -> AddScalarFieldOperation* { return nullptr; }), true);
544 (void)addScalarOperation;
545
546 auto fieldTool = table.addClass<FieldBrushTool>(
547 "FieldBrushTool", std::function<FieldBrushTool*()>([]() -> FieldBrushTool* { return nullptr; }), true);
548 fieldTool.addFunc("setRadius", &FieldBrushTool::setRadius);
549 fieldTool.addFunc("setStrength", &FieldBrushTool::setStrength);
550 fieldTool.addFunc("getRadius", &FieldBrushTool::radius);
551 fieldTool.addFunc("getStrength", &FieldBrushTool::strength);
552 fieldTool.addFunc("setCircleKernel", [](FieldBrushTool* self, CircleBrushKernel* kernel) {
553 if (self) self->setKernel(kernel);
554 });
555 fieldTool.addFunc("setBoxKernel", [](FieldBrushTool* self, BoxBrushKernel* kernel) {
556 if (self) self->setKernel(kernel);
557 });
558 fieldTool.addFunc("setPaintIntOperation", [](FieldBrushTool* self, PaintIntFieldOperation* operation) {
559 if (self) self->setOperation(operation);
560 });
561 fieldTool.addFunc("setAddScalarOperation", [](FieldBrushTool* self, AddScalarFieldOperation* operation) {
562 if (self) self->setOperation(operation);
563 });
564
565 auto sphereVolumeKernel = table.addClass<SphereVolumeBrushKernel>(
566 "SphereVolumeBrushKernel",
567 std::function<SphereVolumeBrushKernel*()>([]() -> SphereVolumeBrushKernel* { return nullptr; }), true);
568 sphereVolumeKernel.addFunc("setConstantFalloff", [](SphereVolumeBrushKernel* self, ConstantBrushFalloff* falloff) {
569 if (self) self->setFalloff(falloff);
570 });
571 sphereVolumeKernel.addFunc("setLinearFalloff", [](SphereVolumeBrushKernel* self, LinearBrushFalloff* falloff) {
572 if (self) self->setFalloff(falloff);
573 });
574 sphereVolumeKernel.addFunc("setSmoothFalloff", [](SphereVolumeBrushKernel* self, SmoothBrushFalloff* falloff) {
575 if (self) self->setFalloff(falloff);
576 });
577
578 auto boxVolumeKernel = table.addClass<BoxVolumeBrushKernel>(
579 "BoxVolumeBrushKernel",
580 std::function<BoxVolumeBrushKernel*()>([]() -> BoxVolumeBrushKernel* { return nullptr; }), true);
581 boxVolumeKernel.addFunc("setConstantFalloff", [](BoxVolumeBrushKernel* self, ConstantBrushFalloff* falloff) {
582 if (self) self->setFalloff(falloff);
583 });
584 boxVolumeKernel.addFunc("setLinearFalloff", [](BoxVolumeBrushKernel* self, LinearBrushFalloff* falloff) {
585 if (self) self->setFalloff(falloff);
586 });
587 boxVolumeKernel.addFunc("setSmoothFalloff", [](BoxVolumeBrushKernel* self, SmoothBrushFalloff* falloff) {
588 if (self) self->setFalloff(falloff);
589 });
590
591 auto paintVolumeOperation = table.addClass<PaintIntVolumeOperation>(
592 "PaintIntVolumeOperation",
593 std::function<PaintIntVolumeOperation*()>([]() -> PaintIntVolumeOperation* { return nullptr; }), true);
594 paintVolumeOperation.addFunc("setValue", &PaintIntVolumeOperation::setValue);
595 paintVolumeOperation.addFunc("getValue", &PaintIntVolumeOperation::value);
596
597 auto volumeTool = table.addClass<VolumeBrushTool>(
598 "VolumeBrushTool", std::function<VolumeBrushTool*()>([]() -> VolumeBrushTool* { return nullptr; }), true);
599 volumeTool.addFunc("setRadius", &VolumeBrushTool::setRadius);
600 volumeTool.addFunc("getRadius", &VolumeBrushTool::radius);
601 volumeTool.addFunc("setSphereKernel", [](VolumeBrushTool* self, SphereVolumeBrushKernel* kernel) {
602 if (self) self->setKernel(kernel);
603 });
604 volumeTool.addFunc("setBoxKernel", [](VolumeBrushTool* self, BoxVolumeBrushKernel* kernel) {
605 if (self) self->setKernel(kernel);
606 });
607 volumeTool.addFunc("setPaintIntOperation", [](VolumeBrushTool* self, PaintIntVolumeOperation* operation) {
608 if (self) self->setOperation(operation);
609 });
610
611 auto session = table.addClass<EditorSession>(
612 "EditorSession", std::function<EditorSession*()>([]() -> EditorSession* { return nullptr; }), true);
613 session.addFunc("addTool", std::function<bool(EditorSession*, ScriptEditorTool*)>(
614 [](EditorSession* self, ScriptEditorTool* tool) { return self->addTool(tool); }));
615 session.addFunc("addFieldTool",
616 [](EditorSession* self, FieldBrushTool* tool) { return self && self->addTool(tool); });
617 session.addFunc("addVolumeTool",
618 [](EditorSession* self, VolumeBrushTool* tool) { return self && self->addTool(tool); });
619 session.addFunc("clearTarget", [](EditorSession* self) {
620 if (self) self->bindTarget(nullptr);
621 });
622 session.addFunc("removeTool", &EditorSession::removeTool);
623 session.addFunc("clearTools", &EditorSession::clearTools);
624 session.addFunc("activateTool", &EditorSession::activateTool);
625 session.addFunc("getToolCount", &EditorSession::getToolCount);
626 session.addFunc("getActiveToolId", &EditorSession::activeToolId);
627 session.addFunc("hasPointerCapture", &EditorSession::hasPointerCapture);
628 session.addFunc("update", &EditorSession::update);
629 session.addFunc("cancelActiveTool", &EditorSession::cancelActiveTool);
630 session.addFunc(
631 "undo", std::function<bool(EditorSession*)>([](EditorSession* self) { return self->transactions().undo(); }));
632 session.addFunc(
633 "redo", std::function<bool(EditorSession*)>([](EditorSession* self) { return self->transactions().redo(); }));
634 session.addFunc("canUndo", [](EditorSession* self) { return self && self->transactions().canUndo(); });
635 session.addFunc("canRedo", [](EditorSession* self) { return self && self->transactions().canRedo(); });
636 session.addFunc("clearHistory", [](EditorSession* self) {
637 if (self) self->transactions().clear();
638 });
639 session.addFunc("getCommandCount",
640 [](EditorSession* self) { return self ? static_cast<int>(self->availableCommands().size()) : 0; });
641 session.addFunc("getCommandId", [](EditorSession* self, int index) {
642 if (!self) return std::string{};
643 const auto commands = self->availableCommands();
644 return index >= 0 && index < static_cast<int>(commands.size()) ? commands[static_cast<size_t>(index)].id.value()
645 : std::string{};
646 });
647 session.addFunc("getCommandName", [](EditorSession* self, int index) {
648 if (!self) return std::string{};
649 const auto commands = self->availableCommands();
650 return index >= 0 && index < static_cast<int>(commands.size())
651 ? commands[static_cast<size_t>(index)].displayName
652 : std::string{};
653 });
654 session.addFunc("getCommandCategory", [](EditorSession* self, int index) {
655 if (!self) return std::string{};
656 const auto commands = self->availableCommands();
657 return index >= 0 && index < static_cast<int>(commands.size()) ? commands[static_cast<size_t>(index)].category
658 : std::string{};
659 });
660 session.addFunc("planCommand", [](EditorSession* self, const std::string& id, ssq::Object payload) -> ssq::Object {
661 HSQUIRRELVM vm = payload.getHandle();
663 if (!self || !objectToEditorValue(payload, value)) return resultTable(vm, invalidScriptPayload());
664 const Result<PlanId> planned = self->retainPlan(CommandId(id), value, CommandSource::Script);
665 ssq::Table out = resultTable(vm, planned);
666 if (planned.ok()) out.set("planId", planned.value().value());
667 return out;
668 });
669 session.addFunc(
670 "executePlan", [](EditorSession* self, const std::string& planId, ssq::Object scriptContext) -> ssq::Object {
671 HSQUIRRELVM vm = scriptContext.getHandle();
672 if (!self)
673 return resultTable(vm, eve::editing::failed<TransactionReceipt>(EditorStatus::Failed,
674 RuleId("editor.script.missing-session"),
675 "Editor session is not available"));
676 const Result<TransactionReceipt> executed =
677 self->executeRetainedPlan(PlanId(planId), CommandSource::Script);
678 ssq::Table out = resultTable(vm, executed);
679 if (executed.ok()) {
680 out.set("transactionId", executed.value().id.value());
681 out.set("transactionState", std::string(transactionStateName(executed.value().state)));
682 out.set("beforeRevision", static_cast<int64_t>(executed.value().beforeRevision));
683 out.set("afterRevision", static_cast<int64_t>(executed.value().afterRevision));
684 out.set("authorityReceipt", executed.value().authorityReceipt);
685 }
686 return out;
687 });
688 session.addFunc("executeCommand",
689 [](EditorSession* self, const std::string& id, ssq::Object payload) -> ssq::Object {
690 HSQUIRRELVM vm = payload.getHandle();
692 if (!self || !objectToEditorValue(payload, value))
693 return resultTable(vm, invalidScriptPayload());
694 const Result<EditorValue> executed =
695 self->executeCommand(CommandId(id), value, CommandSource::Script);
696 ssq::Table out = resultTable(vm, executed);
697 if (executed.ok()) setValue(out, "value", executed.value());
698 return out;
699 });
700 session.addFunc("dispatchPointer",
701 std::function<int(EditorSession*, int, int, int, float, float, float, float, float)>(
702 [](EditorSession* self, int phase, int pointerId, int button, float x, float y, float dx,
703 float dy, float pressure) {
704 EditorPointerEvent event;
705 event.phase = static_cast<EditorPointerEvent::Phase>(phase);
706 event.pointerId = pointerId;
707 event.button = button;
708 event.x = x;
709 event.y = y;
710 event.deltaX = dx;
711 event.deltaY = dy;
712 event.pressure = pressure;
713 const ToolResponse response = self->dispatchPointer(event);
714 return (response.handled ? 1 : 0) | (response.capturePointer ? 2 : 0) |
715 (response.releasePointer ? 4 : 0);
716 }));
717 session.addFunc("dispatchPointer3D",
718 std::function<int(EditorSession*, int, int, int, float, float, float, float, float, float, float)>(
719 [](EditorSession* self, int phase, int pointerId, int button, float x, float y, float z,
720 float dx, float dy, float dz, float pressure) {
721 EditorPointerEvent event;
722 event.phase = static_cast<EditorPointerEvent::Phase>(phase);
723 event.pointerId = pointerId;
724 event.button = button;
725 event.x = x;
726 event.y = y;
727 event.z = z;
728 event.deltaX = dx;
729 event.deltaY = dy;
730 event.deltaZ = dz;
731 event.pressure = pressure;
732 const ToolResponse response = self->dispatchPointer(event);
733 return (response.handled ? 1 : 0) | (response.capturePointer ? 2 : 0) |
734 (response.releasePointer ? 4 : 0);
735 }));
736
737 auto workspace = table.addClass<EditorWorkspace>(
738 "EditorWorkspace", std::function<EditorWorkspace*()>([]() -> EditorWorkspace* { return nullptr; }), true);
739 workspace.addFunc("getId", &EditorWorkspace::getId);
740 workspace.addFunc("getTitle", &EditorWorkspace::getTitle);
741 workspace.addFunc("setTitle", &EditorWorkspace::setTitle);
742 workspace.addFunc("registerPanel",
743 static_cast<bool (EditorWorkspace::*)(const std::string&, const std::string&,
744 const std::string&, int)>(&EditorWorkspace::registerPanel));
745 workspace.addFunc("removePanel",
746 static_cast<bool (EditorWorkspace::*)(const std::string&)>(&EditorWorkspace::removePanel));
747 workspace.addFunc("clearPanels", &EditorWorkspace::clearPanels);
748 workspace.addFunc("movePanel", static_cast<bool (EditorWorkspace::*)(const std::string&, const std::string&, int)>(
750 workspace.addFunc("setPanelCapability", &EditorWorkspace::setPanelCapability);
751 workspace.addFunc("setPanelContext", &EditorWorkspace::setPanelContext);
752 workspace.addFunc("setPanelVisible", &EditorWorkspace::setPanelVisible);
753 workspace.addFunc("setPanelSingleton", &EditorWorkspace::setPanelSingleton);
754 workspace.addFunc("activatePanel",
755 static_cast<bool (EditorWorkspace::*)(const std::string&)>(&EditorWorkspace::activatePanel));
756 workspace.addFunc("getActivePanel", &EditorWorkspace::getActivePanel);
757 workspace.addFunc("getPanelCount", &EditorWorkspace::getPanelCount);
758 workspace.addFunc("getPanelId", &EditorWorkspace::getPanelId);
759 workspace.addFunc("getPanelTitle", &EditorWorkspace::getPanelTitle);
760 workspace.addFunc("getPanelRegion", &EditorWorkspace::getPanelRegion);
761 workspace.addFunc("getPanelCapability", &EditorWorkspace::getPanelCapability);
762 workspace.addFunc("getPanelContext", &EditorWorkspace::getPanelContext);
763 workspace.addFunc("getPanelOrder", &EditorWorkspace::getPanelOrder);
764 workspace.addFunc("getPanelVisible", &EditorWorkspace::getPanelVisible);
765 workspace.addFunc("getPanelSingleton", &EditorWorkspace::getPanelSingleton);
766 workspace.addFunc("setRegionSize", &EditorWorkspace::setRegionSize);
767 workspace.addFunc("layout", &EditorWorkspace::layout);
768 workspace.addFunc("getRegionX", &EditorWorkspace::getRegionX);
769 workspace.addFunc("getRegionY", &EditorWorkspace::getRegionY);
770 workspace.addFunc("getRegionW", &EditorWorkspace::getRegionW);
771 workspace.addFunc("getRegionH", &EditorWorkspace::getRegionH);
772 workspace.addFunc("setMode", &EditorWorkspace::setMode);
773 workspace.addFunc("getMode", &EditorWorkspace::getMode);
774 workspace.addFunc("select", &EditorWorkspace::select);
775 workspace.addFunc("clearSelection", &EditorWorkspace::clearSelection);
776 workspace.addFunc("getSelectionCount", &EditorWorkspace::getSelectionCount);
777 workspace.addFunc("getSelectionItem", &EditorWorkspace::getSelectionItem);
778 workspace.addFunc("getSelectionType", &EditorWorkspace::getSelectionType);
779 workspace.addFunc("getPrimarySelection", &EditorWorkspace::getPrimarySelection);
780 workspace.addFunc("getSelectionSequence", &EditorWorkspace::getSelectionSequence);
781 workspace.addFunc("focus", &EditorWorkspace::focus);
782 workspace.addFunc("getFocusedSurface", &EditorWorkspace::getFocusedSurface);
783 workspace.addFunc("getRevision", &EditorWorkspace::getRevision);
784
785 auto scriptTool = table.addClass<ScriptEditorTool>(
786 "ScriptEditorTool", std::function<ScriptEditorTool*()>([]() -> ScriptEditorTool* { return nullptr; }), true);
787 scriptTool.addFunc("setShortcut", &ScriptEditorTool::setShortcut);
788 scriptTool.addFunc("setActivateCallback", &ScriptEditorTool::setActivateCallback);
789 scriptTool.addFunc("setDeactivateCallback", &ScriptEditorTool::setDeactivateCallback);
790 scriptTool.addFunc("setPointerCallback", &ScriptEditorTool::setPointerCallback);
791 scriptTool.addFunc("setKeyCallback", &ScriptEditorTool::setKeyCallback);
792 scriptTool.addFunc("setUpdateCallback", &ScriptEditorTool::setUpdateCallback);
793 scriptTool.addFunc("setCancelCallback", &ScriptEditorTool::setCancelCallback);
794}
795
796void Editor::expose(ssq::Class& cls) {
797 cls.addFunc("getName", &Editor::getName);
798 cls.addFunc("newGizmo", [](Editor* self) { return self->newGizmo().release(); });
799 cls.addFunc("newGizmoManager", [](Editor* self) { return self->newGizmoManager().release(); });
800 cls.addFunc("newToolbar", [](Editor* self) { return self->newToolbar().release(); });
801 cls.addFunc("newInspector", [](Editor* self) { return self->newInspector().release(); });
802 cls.addFunc("newDock", [](Editor* self) { return self->newDock().release(); });
803 cls.addFunc("newSession", [](Editor* self) { return self->newSession().release(); });
804 cls.addFunc("newWorkspace", [](Editor* self, const std::string& id, const std::string& title) {
805 auto created = self->newWorkspace(id, title);
806 return created.ok() ? std::move(created).takeValue().release() : nullptr;
807 });
808 cls.addFunc("newScriptTool", [](Editor* self, const std::string& id, const std::string& label) {
809 return self->newScriptTool(id, label).release();
810 });
811 cls.addFunc("newConstantBrushFalloff", [](Editor* self) { return self->newConstantBrushFalloff().release(); });
812 cls.addFunc("newLinearBrushFalloff", [](Editor* self) { return self->newLinearBrushFalloff().release(); });
813 cls.addFunc("newSmoothBrushFalloff", [](Editor* self) { return self->newSmoothBrushFalloff().release(); });
814 cls.addFunc("newCircleBrushKernel", [](Editor* self) { return self->newCircleBrushKernel().release(); });
815 cls.addFunc("newBoxBrushKernel", [](Editor* self) { return self->newBoxBrushKernel().release(); });
816 cls.addFunc("newPaintIntFieldOperation", [](Editor* self, int value) {
817 return self->newPaintIntFieldOperation(value).release();
818 });
819 cls.addFunc("newAddScalarFieldOperation",
820 [](Editor* self) { return self->newAddScalarFieldOperation().release(); });
821 cls.addFunc("newFieldBrushTool", [](Editor* self, const std::string& id, const std::string& label) {
822 return self->newFieldBrushTool(id, label).release();
823 });
824 cls.addFunc("newSphereVolumeBrushKernel",
825 [](Editor* self) { return self->newSphereVolumeBrushKernel().release(); });
826 cls.addFunc("newBoxVolumeBrushKernel", [](Editor* self) { return self->newBoxVolumeBrushKernel().release(); });
827 cls.addFunc("newPaintIntVolumeOperation", [](Editor* self, int value) {
828 return self->newPaintIntVolumeOperation(value).release();
829 });
830 cls.addFunc("newVolumeBrushTool", [](Editor* self, const std::string& id, const std::string& label) {
831 return self->newVolumeBrushTool(id, label).release();
832 });
833 cls.addFunc("registerScriptCommand", registerScriptCommand);
834 cls.addFunc("unregisterScriptCommand", [](Editor* self, const std::string& id) {
835 return self && self->commandService().unregisterCommand(CommandId(id), "script:" + id);
836 });
837}
838
839} // namespace eve::editor
LogicalId target
ActionParameterOperation operation
double value
Value::Object payload
SQInteger top
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::string descriptor
float phase
Definition CaveMesh.cpp:58
struct SQVM * HSQUIRRELVM
std::string title
std::string label
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::map< std::string, Var > values
const GltfImportRequest & request
std::uint32_t key
wgpu::PopErrorScopeStatus status
std::string name
float tb
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
std::string id
Definition PlayHost.cpp:108
std::function< eve::Result< void >()> release
Definition Procgen.cpp:86
int created
double current
std::string string
float dz
float dy
float dx
std::uint32_t count
std::optional< InteractionSession > session
Definition Tactics.cpp:39
const char * category
uint32_t index
std::uint32_t depth
std::vector< VegetationPresetCommand > commands
ViewPreparation callback
virtual std::string getName() const =0
Returns the name.
Move-only operation result carrying either a value or Status.
Definition Result.h:155
UUID-backed identifier adapter for legacy textual boundaries.
Definition Identity.h:314
IEditableTarget public API.
std::vector< Value > Array
std::map< std::string, Value > Object
MCP/DevTools adapter over command discovery and target coordination.
float getRegionX(const std::string &region) const
Returns the region x.
void setRegionSize(const std::string &region, float pixels)
Sets the region size.
float getRegionY(const std::string &region) const
Returns the region y.
void layout(float screenW, float screenH)
Layout.
float getRegionW(const std::string &region) const
Returns the region w.
float getRegionH(const std::string &region) const
Returns the region h.
float getRegionSize(const std::string &region) const
Returns the region size.
void addFloat(const std::string &id, const std::string &label, float value, float minV, float maxV, float step)
Adds float.
std::string getFieldKind(int index) const
Returns the field kind.
bool isDirty(const std::string &id) const
True when dirty.
void setFloat3(const std::string &id, float x, float y, float z)
Sets the float 3.
float getFloatStep(const std::string &id) const
Returns the float step.
std::string getFieldLabel(int index) const
Returns the field label.
float getFloat3X(const std::string &id) const
Returns the float 3 x.
void setChoice(const std::string &id, const std::string &value)
Sets the choice.
std::string getString(const std::string &id) const
Returns the string.
void clearDirty(const std::string &id)
Clears dirty.
std::string pollChangedId()
Returns next dirty field id, or "" if none.
void setFloat(const std::string &id, float value)
Sets the float.
std::string getChoice(const std::string &id) const
Returns the choice.
std::string getChoicesCsv(const std::string &id) const
Returns the choices csv.
void addString(const std::string &id, const std::string &label, const std::string &value)
Adds string.
float getFloat(const std::string &id) const
Returns the float.
float getFloat3Z(const std::string &id) const
Returns the float 3 z.
std::string getFieldId(int index) const
Returns the field id.
void setString(const std::string &id, const std::string &value)
Sets the string.
int getFieldCount() const
Returns the field count.
void setBool(const std::string &id, bool value)
Sets the bool.
void addBool(const std::string &id, const std::string &label, bool value)
Adds bool.
float getFloatMax(const std::string &id) const
Returns the float max.
float getFloatMin(const std::string &id) const
Returns the float min.
void addFloat3(const std::string &id, const std::string &label, float x, float y, float z)
Adds float 3.
bool getBool(const std::string &id) const
Returns the bool.
void addChoice(const std::string &id, const std::string &label, const std::string &choicesCsv, const std::string &selected)
Adds choice.
void clearAllDirty()
Clears all dirty.
float getFloat3Y(const std::string &id) const
Returns the float 3 y.
Hosts interchangeable editor tools and routes their lifecycle/input.
bool hasPointerCapture() const
True when pointer capture.
bool removeTool(const std::string &id)
Remove a registered tool by id, deactivating it when necessary.
bool activateTool(const std::string &id)
Activate a registered tool by id. Empty id deactivates all tools.
void update(float dt)
Update the active tool.
void cancelActiveTool()
Cancel its gesture and clear pointer capture.
void clearTools()
Remove all tools and release any pointer capture.
std::string activeToolId() const
Active tool id.
int getToolCount() const
Returns the tool count.
Coordinates editable targets, per-target histories and domain commands.
std::string getToolLabel(int index) const
Returns the tool label.
std::string getToolId(int index) const
Returns the tool id.
void setIcon(const std::string &id, const std::string &icon)
Assigns a backend-neutral semantic icon name to an existing tool.
void addTool(const std::string &id, const std::string &label)
Adds tool.
int getToolCount() const
Returns the tool count.
bool setActive(const std::string &id)
Sets the active.
std::string getActive() const
Returns the active.
void setShortcut(const std::string &id, const std::string &key)
Sets the shortcut.
std::string getToolShortcut(int index) const
Returns the tool shortcut.
bool matchShortcut(const std::string &key)
Match shortcut.
std::string getToolIcon(int index) const
Returns the tool's semantic icon name.
std::string getPrimarySelection(const std::string &channel) const
Primary selected item id for a channel.
std::string getFocusedSurface(const std::string &channel) const
Focused surface id for a channel.
bool getPanelSingleton(int index) const
Panel singleton policy by deterministic index.
std::uint64_t getSelectionSequence(const std::string &channel) const
Monotonic selection sequence for MVVM change detection.
std::string getPanelCapability(int index) const
Panel capability requirement by deterministic index.
std::string getPanelRegion(int index) const
Panel dock region by deterministic index.
float getRegionH(const std::string &region) const
Computed region height.
std::string getPanelContext(int index) const
Panel input context by deterministic index.
Result< WorkspacePanelDescriptor > removePanel(const StableId &id)
Remove a panel and return its final owning descriptor.
std::uint64_t getRevision() const
Monotonic structural revision for cheap ViewModel synchronization.
bool setPanelContext(const std::string &id, const std::string &context)
Attach a semantic input context such as scene, graph, or timeline.
std::string getPanelTitle(int index) const
Panel title by deterministic index.
bool focus(const std::string &channel, const std::string &surface, const std::string &item)
Set UI-toolkit-independent focus for a channel.
std::string getSelectionItem(const std::string &channel, int index) const
Selected stable item id by channel/index.
const std::string & getMode() const
Current project-defined mode.
Result< WorkspacePanelDescriptor > registerPanel(WorkspacePanelDescriptor descriptor)
Register a checked owning panel descriptor.
void setTitle(const std::string &title)
Change the display title without changing workspace identity.
std::string getSelectionType(const std::string &channel, int index) const
Selected item type by channel/index.
bool select(const std::string &channel, const std::string &domain, const std::string &target, const std::string &item, const std::string &type, bool additive)
Select one stable item in a semantic channel.
bool setMode(const std::string &mode)
Set a project-defined mode such as edit, play, material, or animation.
Result< WorkspacePanelDescriptor > activatePanel(const StableId &id)
Activate a visible panel with structured not-found/rejected results.
float getRegionY(const std::string &region) const
Computed region Y coordinate.
int getPanelCount() const
Number of registered panels in deterministic region/order/id order.
Result< WorkspacePanelDescriptor > movePanel(const StableId &id, WorkspaceRegion region, int order)
Move a panel using a strongly typed dock region.
void clearPanels()
Remove every panel descriptor.
bool getPanelVisible(int index) const
Panel visibility by deterministic index.
bool setPanelCapability(const std::string &id, const std::string &capability)
Attach a capability requirement used by the host when filtering panels.
void layout(float width, float height)
Compute standard dock rectangles for the requested host size.
const std::string & getId() const
Stable project-defined workspace id.
int getPanelOrder(int index) const
Panel order by deterministic index.
bool setPanelSingleton(const std::string &id, bool singleton)
Mark whether hosts should allow more than one instance of this panel type.
void setRegionSize(const std::string &region, float pixels)
Configure one standard dock region size in pixels.
std::string getPanelId(int index) const
Panel id by deterministic index.
float getRegionX(const std::string &region) const
Computed region X coordinate.
const std::string & getActivePanel() const
Active panel id, or an empty string.
int getSelectionCount(const std::string &channel) const
Number of selected items in a channel.
bool setPanelVisible(const std::string &id, bool visible)
Show or hide a panel without removing its descriptor.
float getRegionW(const std::string &region) const
Computed region width.
bool clearSelection(const std::string &channel)
Clear one semantic selection channel.
const std::string & getTitle() const
User-facing workspace title.
Editor building blocks — not a shipped 3D/map editor app. Script: editor <- eve.Editor();
Definition Editor.h:46
std::unique_ptr< PaintIntVolumeOperation > newPaintIntVolumeOperation(int value)
Create a byte-range integer paint operation for volume targets. @ownership Unique ownership transfers...
Definition Editor.cpp:348
std::unique_ptr< PaintIntFieldOperation > newPaintIntFieldOperation(int value)
Create an integer-field paint operation. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:332
std::unique_ptr< EditorDock > newDock()
Create a dock model. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:305
std::unique_ptr< BoxVolumeBrushKernel > newBoxVolumeBrushKernel()
Create an axis-aligned box kernel for sparse three-dimensional fields. @ownership Unique ownership tr...
Definition Editor.cpp:345
std::unique_ptr< TransformGizmo > newGizmo()
Create a transform gizmo. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:297
~Editor() override
Editor.
Definition Editor.cpp:280
std::unique_ptr< VolumeBrushTool > newVolumeBrushTool(const std::string &id, const std::string &label)
Create a 3D brush tool whose kernel and operation are supplied separately. @ownership Unique ownershi...
Definition Editor.cpp:351
Result< void > unregisterEditingTarget(const TargetId &target)
Remove a borrowed editing target and its local transaction history.
Definition Editor.cpp:287
std::unique_ptr< ScriptEditorTool > newScriptTool(const std::string &id, const std::string &label)
Create a script-backed implementation of the IEditorTool protocol. @ownership Unique ownership transf...
Definition Editor.cpp:321
std::unique_ptr< BoxBrushKernel > newBoxBrushKernel()
Create a rotatable box brush kernel with a replaceable falloff. @ownership Unique ownership transfers...
Definition Editor.cpp:331
std::unique_ptr< EditorSession > newSession()
Create a host for interchangeable IEditorTool implementations. @ownership Unique ownership transfers ...
Definition Editor.cpp:307
std::unique_ptr< FieldBrushTool > newFieldBrushTool(const std::string &id, const std::string &label)
Create a field brush tool whose kernel and operation are supplied separately.
Definition Editor.cpp:338
std::unique_ptr< SphereVolumeBrushKernel > newSphereVolumeBrushKernel()
Create a spherical kernel for sparse three-dimensional fields. @ownership Unique ownership transfers ...
Definition Editor.cpp:342
std::unique_ptr< ConstantBrushFalloff > newConstantBrushFalloff()
Create a constant brush falloff strategy. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:325
std::unique_ptr< SmoothBrushFalloff > newSmoothBrushFalloff()
Create a smoothstep brush falloff strategy. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:329
std::unique_ptr< EditorToolbar > newToolbar()
Create a toolbar model. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:301
std::unique_ptr< LinearBrushFalloff > newLinearBrushFalloff()
Create a linear brush falloff strategy. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:328
std::unique_ptr< GizmoManager > newGizmoManager()
Create a gizmo manager. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:299
std::unique_ptr< AddScalarFieldOperation > newAddScalarFieldOperation()
Create an additive scalar-field operation. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:335
std::unique_ptr< CircleBrushKernel > newCircleBrushKernel()
Create a circular brush kernel with a replaceable falloff. @ownership Unique ownership transfers to t...
Definition Editor.cpp:330
std::unique_ptr< EditorInspector > newInspector()
Create an inspector model. @ownership Unique ownership transfers to the caller.
Definition Editor.cpp:303
Result< std::unique_ptr< EditorWorkspace > > newWorkspace(const std::string &id, const std::string &title)
Create a UI-neutral composition model for a project-specific editor.
Definition Editor.cpp:313
Result< void > bindEditingTarget(EditorSession &session, const TargetId &target)
Bind a registered target to a host session without exposing the coordinator.
Definition Editor.cpp:293
Result< void > registerEditingTarget(IEditableTarget &target)
Register a borrowed editable target for UI, script and automation access.
Definition Editor.cpp:285
float radius() const
Radius.
float strength() const
Strength.
void setStrength(float strength)
Set the operation strength; negative values are permitted.
void setRadius(float radius)
Set brush radius in target coordinates.
bool getScaleEnabled() const
Returns the scale enabled.
bool isDragging() const
True when dragging.
void setPositionEnabled(bool enabled)
Sets the position enabled.
void setScaleEnabled(bool enabled)
Sets the scale enabled.
void setBoundEnabled(bool enabled)
Sets the bound enabled.
bool getPositionEnabled() const
Returns the position enabled.
bool isHovered() const
True when hovered.
bool isAttached() const
True when attached.
void setRotationEnabled(bool enabled)
Sets the rotation enabled.
TransformGizmo * getGizmo()
Returns the gizmo.
std::string pick(float ox, float oy, float oz, float dx, float dy, float dz)
Pick across enabled modes; sets gizmo mode to the winning tool.
bool getBoundEnabled() const
Returns the bound enabled.
bool getRotationEnabled() const
Returns the rotation enabled.
bool beginDrag(const std::string &axis, float ox, float oy, float oz, float dx, float dy, float dz)
Begins drag.
bool updateDrag(float ox, float oy, float oz, float dx, float dy, float dz)
Updates drag.
int value() const
Return the integer written by this operation.
void setValue(int value)
Change the integer written by subsequent stamps.
void setValue(int value)
Set the value written by subsequent stamps.
int value() const
Return the value written by this operation.
void setActivateCallback(ssq::Object callback)
Set a closure invoked when the tool becomes active.
void setKeyCallback(ssq::Object callback)
Set a closure invoked for normalized key input.
void setUpdateCallback(ssq::Object callback)
Set a closure invoked every active frame with delta time.
void setShortcut(const std::string &shortcut)
Set the shortcut shown by hosts.
void setDeactivateCallback(ssq::Object callback)
Set a closure invoked when the tool becomes inactive.
void setPointerCallback(ssq::Object callback)
Set a closure invoked for normalized pointer input.
void setCancelCallback(ssq::Object callback)
Set a closure invoked when the current gesture is cancelled.
3D transform gizmo (Three.js TransformControls + ImGuizmo style). Owns TRS + optional local bounds; i...
float getPartDirY(int index) const
Returns the part dir y.
float getSnapTranslateY() const
Returns the snap translate y.
std::string getHoverAxis() const
Returns the hover axis.
float getBoundsMinY() const
Returns the bounds min y.
void setSnapScale(float s)
Sets the snap scale.
float getSnapTranslateZ() const
Returns the snap translate z.
void setSnapRotate(float degrees)
Sets the snap rotate.
float getPartColorR(int index) const
Returns the part color r.
float getRotationZ() const
Returns the rotation z.
float getPositionY() const
Returns the position y.
bool isDragging() const
True when dragging.
void rebuildParts()
Rebuild draw parts for current mode/space (call after TRS/mode change).
float getBoundsMinZ() const
Returns the bounds min z.
float getPartDirX(int index) const
Returns the part dir x.
float getSize() const
Returns the size.
std::string pick(float ox, float oy, float oz, float dx, float dy, float dz)
Ray pick against active mode handles. Returns axis id: "x"|"y"|"z"|"xy"|"yz"|"xz"|"xyz"|"bx"|…|"bz"|"...
bool isHovered() const
True when hovered.
float getRotationX() const
Returns the rotation x.
float getPartDirZ(int index) const
Returns the part dir z.
std::string getPartKind(int index) const
Returns the part kind.
float getBoundsMinX() const
Returns the bounds min x.
std::string getMode() const
Returns the mode.
float getPartRadius(int index) const
Returns the part radius.
float getBoundsMaxZ() const
Returns the bounds max z.
float getMatrix(int index) const
Column-major matrix element 0..15 of current TRS.
void setSize(float size)
Sets the size.
float getPartColorG(int index) const
Returns the part color g.
float getSnapRotate() const
Returns the snap rotate.
void setBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
Local AABB extents for bound mode (relative to object origin).
float getPartColorB(int index) const
Returns the part color b.
bool beginDrag(const std::string &axis, float ox, float oy, float oz, float dx, float dy, float dz)
Begins drag.
float getPartOriginY(int index) const
Returns the part origin y.
void setSnapTranslate(float x, float y, float z)
Sets the snap translate.
float getScaleZ() const
Returns the scale z.
float getPositionZ() const
Returns the position z.
std::string getActiveAxis() const
Returns the active axis.
float getScaleX() const
Returns the scale x.
float getPartLength(int index) const
Returns the part length.
float getScaleY() const
Returns the scale y.
void setPosition(float x, float y, float z)
Sets the position.
float getPartColorA(int index) const
Returns the part color a.
bool updateDrag(float ox, float oy, float oz, float dx, float dy, float dz)
Updates drag.
float getSnapTranslateX() const
Returns the snap translate x.
float getPartOriginX(int index) const
Returns the part origin x.
void setRotationEuler(float x, float y, float z)
Euler radians, XYZ order.
void setMode(const std::string &mode)
Sets the mode.
float getBoundsMaxX() const
Returns the bounds max x.
float getRotationY() const
Returns the rotation y.
float getSnapScale() const
Returns the snap scale.
std::string getSpace() const
Returns the space.
void setScale(float x, float y, float z)
Sets the scale.
std::string getPartAxis(int index) const
Returns the part axis.
float getPartOriginZ(int index) const
Returns the part origin z.
float getBoundsMaxY() const
Returns the bounds max y.
int getPartCount() const
Returns the part count.
float getPositionX() const
Returns the position x.
void setSpace(const std::string &space)
Sets the space.
float radius() const
Return radius in target voxel coordinates.
void setRadius(float radius)
Set radius in target voxel coordinates.
RuleId diagnosticRule(const Diagnostic &diagnostic)
Return the projected editing rule, or an empty RuleId when absent.
eve::editing::Value EditorValue
Compatibility alias for the UI-independent authoring value tree.
Definition EditorValue.h:8
eve::editing::PlanId PlanId
Definition EditorIds.h:35
eve::editing::TransactionState TransactionState
eve::editing::CommandId CommandId
Definition EditorIds.h:30
eve::Diagnostic EditorDiagnostic
eve::editing::RuleId RuleId
Definition EditorIds.h:32
eve::editing::TransactionReceipt TransactionReceipt
eve::editing::CommandPlan CommandPlan
eve::editing::DomainOperation DomainOperation
eve::editing::TransactionId TransactionId
Definition EditorIds.h:34
eve::editing::CommandRequest CommandRequest
std::unordered_map< std::string, SkillDefinition > & table()
Definition Skill.cpp:65
std::string_view statusName(BattleStatus status) noexcept
Return the stable protocol spelling of a battle status.
ControlEdit button(const char *label, float width=0.f, float height=0.f)
Shared immediate renderer for retained and EditorHost buttons.
StatusCode
Stable outcome category for an operation.
Definition Status.h:27