fix(shaders_lab): Output connectable after drop + working color picker
Two bugs: 1. Dropped nodes were pushed to the end of the pipeline, but the Output node already sat there from startup. The cycle validator and the compiler only look for sources at indices strictly lower than the target, so new nodes were invisible to the Output. Fix: insert dropped nodes before the first Output; topo_sort also stable-moves Output nodes to the back. 2. ColorEdit3 with default flags rendered RGB text inputs alongside the swatch; clicking them dragged the node instead of opening the picker. Fix: NoInputs + NoLabel leaves only the swatch (a single item), and ed::Suspend/Resume wraps the call so the popup isn't clipped to the node or captured by the canvas. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -117,6 +117,14 @@ static bool topo_sort(std::vector<DagStep>& pipeline) {
|
||||
std::vector<DagStep> sorted;
|
||||
sorted.reserve(static_cast<size_t>(n));
|
||||
for (int idx : order) sorted.push_back(pipeline[static_cast<size_t>(idx)]);
|
||||
|
||||
// Force Output nodes to the back so all their dependencies live at smaller
|
||||
// indices (compiler and cycle validator search strictly before the target).
|
||||
std::stable_partition(sorted.begin(), sorted.end(), [](const DagStep& s) {
|
||||
const DagNodeDef* d = dag_find(s.name);
|
||||
return !(d && d->kind == DagKind::Output);
|
||||
});
|
||||
|
||||
pipeline = std::move(sorted);
|
||||
return true;
|
||||
}
|
||||
@@ -174,7 +182,15 @@ bool dag_node_editor(std::vector<DagStep>& pipeline) {
|
||||
ImVec2 canvas_pos = ed::ScreenToCanvas(s_pending_add_pos);
|
||||
step.editor_pos_x = canvas_pos.x;
|
||||
step.editor_pos_y = canvas_pos.y;
|
||||
pipeline.push_back(step);
|
||||
// Insert before the Output node so the Output stays at the back;
|
||||
// otherwise new nodes can never be wired into it (compiler and
|
||||
// cycle check only search indices strictly before the target).
|
||||
auto insert_it = pipeline.end();
|
||||
for (auto it = pipeline.begin(); it != pipeline.end(); ++it) {
|
||||
const DagNodeDef* d = dag_find(it->name);
|
||||
if (d && d->kind == DagKind::Output) { insert_it = it; break; }
|
||||
}
|
||||
pipeline.insert(insert_it, step);
|
||||
changed = true;
|
||||
}
|
||||
s_pending_add = false;
|
||||
@@ -246,7 +262,15 @@ bool dag_node_editor(std::vector<DagStep>& pipeline) {
|
||||
} else if (ctrl.kind == DagControl::Kind::Color) {
|
||||
int pr = ctrl.param_idx[0];
|
||||
if (pr >= 0 && pr + 2 < 4) {
|
||||
ImGui::ColorEdit3(uid_lbl, &step.params[static_cast<size_t>(pr)]);
|
||||
// Suspend the node editor while the color picker popup is
|
||||
// open so its clicks don't reach the canvas (and so the
|
||||
// popup isn't clipped to the node bounds).
|
||||
ed::Suspend();
|
||||
ImGui::ColorEdit3(uid_lbl, &step.params[static_cast<size_t>(pr)],
|
||||
ImGuiColorEditFlags_NoInputs |
|
||||
ImGuiColorEditFlags_NoLabel |
|
||||
ImGuiColorEditFlags_AlphaBar);
|
||||
ed::Resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user