Show expression code in the node's title
This commit is contained in:
parent
092fc6db9e
commit
0629566330
@ -21,6 +21,12 @@ const char *VoxelGraphEditor::SIGNAL_NODE_SELECTED = "node_selected";
|
||||
const char *VoxelGraphEditor::SIGNAL_NOTHING_SELECTED = "nothing_selected";
|
||||
const char *VoxelGraphEditor::SIGNAL_NODES_DELETED = "nodes_deleted";
|
||||
|
||||
static NodePath to_node_path(StringName sn) {
|
||||
Vector<StringName> path;
|
||||
path.push_back(sn);
|
||||
return NodePath(path, false);
|
||||
}
|
||||
|
||||
VoxelGraphEditor::VoxelGraphEditor() {
|
||||
VBoxContainer *vbox_container = memnew(VBoxContainer);
|
||||
vbox_container->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
|
||||
@ -174,15 +180,14 @@ void VoxelGraphEditor::_process(float delta) {
|
||||
}
|
||||
}
|
||||
|
||||
// When an input is left unconnected, it picks a default value. Input hints show this value.
|
||||
// It is otherwise shown in the inspector when the node is selected, but seeing them at a glance helps.
|
||||
// I decided to do by polling so all the code is here and there is no faffing around with signals.
|
||||
// I decided to do by polling to display some things on graph nodes, so all the code is here and there is no faffing
|
||||
// around with signals.
|
||||
if (_graph.is_valid() && is_visible_in_tree()) {
|
||||
for (int child_node_index = 0; child_node_index < _graph_edit->get_child_count(); ++child_node_index) {
|
||||
Node *node = _graph_edit->get_child(child_node_index);
|
||||
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(node);
|
||||
if (node_view != nullptr) {
|
||||
node_view->poll_default_inputs(**_graph);
|
||||
node_view->poll(**_graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,6 +241,7 @@ void VoxelGraphEditor::build_gui_from_graph() {
|
||||
ERR_FAIL_COND(to_node_view == nullptr);
|
||||
const Error err = _graph_edit->connect_node(
|
||||
from_node_name, con.src.port_index, to_node_view->get_name(), con.dst.port_index);
|
||||
|
||||
ERR_FAIL_COND(err != OK);
|
||||
}
|
||||
}
|
||||
@ -268,12 +274,6 @@ void remove_connections_from_and_to(GraphEdit &graph_edit, StringName node_name)
|
||||
}
|
||||
}
|
||||
|
||||
static NodePath to_node_path(StringName sn) {
|
||||
Vector<StringName> path;
|
||||
path.push_back(sn);
|
||||
return NodePath(path, false);
|
||||
}
|
||||
|
||||
void VoxelGraphEditor::remove_node_gui(StringName gui_node_name) {
|
||||
// Remove connections from the UI, because GraphNode doesn't do it...
|
||||
remove_connections_from_and_to(*_graph_edit, gui_node_name);
|
||||
@ -312,7 +312,7 @@ void VoxelGraphEditor::update_node_layout(uint32_t node_id) {
|
||||
|
||||
for (List<GraphEdit::Connection>::Element *e = old_connections.front(); e; e = e->next()) {
|
||||
const GraphEdit::Connection &con = e->get();
|
||||
NodePath to = to_node_path(con.to);
|
||||
const NodePath to = to_node_path(con.to);
|
||||
const VoxelGraphEditorNode *to_view = Object::cast_to<VoxelGraphEditorNode>(graph_edit.get_node(to));
|
||||
if (to_view == nullptr) {
|
||||
continue;
|
||||
@ -334,8 +334,10 @@ void VoxelGraphEditor::update_node_layout(uint32_t node_id) {
|
||||
// TODO Optimize: the graph stores an adjacency list, we could use that
|
||||
std::vector<ProgramGraph::Connection> connections;
|
||||
_graph->get_connections(connections);
|
||||
|
||||
for (size_t i = 0; i < connections.size(); ++i) {
|
||||
const ProgramGraph::Connection &con = connections[i];
|
||||
|
||||
if (con.dst.node_id == node_id) {
|
||||
graph_edit.connect_node(node_to_gui_name(con.src.node_id), con.src.port_index,
|
||||
node_to_gui_name(con.dst.node_id), con.dst.port_index);
|
||||
@ -653,7 +655,7 @@ void VoxelGraphEditor::update_range_analysis_previews() {
|
||||
// Highlight only nodes that will actually run
|
||||
Span<const uint32_t> execution_map = VoxelGeneratorGraph::get_last_execution_map_debug_from_current_thread();
|
||||
for (unsigned int i = 0; i < execution_map.size(); ++i) {
|
||||
String node_view_path = node_to_gui_name(execution_map[i]);
|
||||
const String node_view_path = node_to_gui_name(execution_map[i]);
|
||||
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_node(node_view_path));
|
||||
node_view->set_modulate(Color(1, 1, 1));
|
||||
}
|
||||
@ -693,7 +695,7 @@ void VoxelGraphEditor::update_slice_previews() {
|
||||
|
||||
// Gather preview nodes
|
||||
for (int i = 0; i < _graph_edit->get_child_count(); ++i) {
|
||||
VoxelGraphEditorNode *node = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_child(i));
|
||||
const VoxelGraphEditorNode *node = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_child(i));
|
||||
if (node == nullptr || node->get_preview() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@ -817,7 +819,9 @@ void VoxelGraphEditor::_on_graph_node_name_changed(int node_id) {
|
||||
VoxelGraphEditorNode *node_view = Object::cast_to<VoxelGraphEditorNode>(_graph_edit->get_node(ui_node_name));
|
||||
ERR_FAIL_COND(node_view == nullptr);
|
||||
|
||||
if (node_type_id != VoxelGeneratorGraph::NODE_EXPRESSION) {
|
||||
node_view->update_title(node_name, node_type_name);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditor::_on_update_previews_button_pressed() {
|
||||
|
@ -20,7 +20,9 @@ VoxelGraphEditorNode *VoxelGraphEditorNode::create(const VoxelGeneratorGraph &gr
|
||||
node_view->update_title(node_name, node_type.name);
|
||||
|
||||
node_view->_node_id = node_id;
|
||||
//node_view.resizable = true
|
||||
// Some nodes can have variable size title and layout. The node can get larger automatically, but doesn't shrink.
|
||||
// So for now we make them resizable so users can adjust them.
|
||||
node_view->set_resizable(node_type_id == VoxelGeneratorGraph::NODE_EXPRESSION);
|
||||
//node_view.rect_size = Vector2(200, 100)
|
||||
|
||||
node_view->update_layout(graph);
|
||||
@ -30,9 +32,17 @@ VoxelGraphEditorNode *VoxelGraphEditorNode::create(const VoxelGeneratorGraph &gr
|
||||
node_view->add_child(node_view->_preview);
|
||||
}
|
||||
|
||||
if (node_view->is_resizable()) {
|
||||
node_view->connect("resize_request", callable_mp(node_view, &VoxelGraphEditorNode::_on_resize_request));
|
||||
}
|
||||
|
||||
return node_view;
|
||||
}
|
||||
|
||||
void VoxelGraphEditorNode::_on_resize_request(Vector2 new_size) {
|
||||
set_size(new_size);
|
||||
}
|
||||
|
||||
void VoxelGraphEditorNode::update_layout(const VoxelGeneratorGraph &graph) {
|
||||
const uint32_t node_type_id = graph.get_node_type_id(_node_id);
|
||||
const VoxelGraphNodeDB::NodeType &node_type = VoxelGraphNodeDB::get_singleton()->get_type(node_type_id);
|
||||
@ -87,16 +97,16 @@ void VoxelGraphEditorNode::update_layout(const VoxelGeneratorGraph &graph) {
|
||||
_input_hints.clear();
|
||||
|
||||
// Add inputs and outputs
|
||||
for (unsigned int i = 0; i < row_count; ++i) {
|
||||
const bool has_left = i < inputs.size();
|
||||
const bool has_right = (i < outputs.size()) && !hide_outputs;
|
||||
for (unsigned int slot_index = 0; slot_index < row_count; ++slot_index) {
|
||||
const bool has_left = slot_index < inputs.size();
|
||||
const bool has_right = (slot_index < outputs.size()) && !hide_outputs;
|
||||
|
||||
HBoxContainer *property_control = memnew(HBoxContainer);
|
||||
property_control->set_custom_minimum_size(Vector2(0, 24 * EDSCALE));
|
||||
|
||||
if (has_left) {
|
||||
Label *label = memnew(Label);
|
||||
label->set_text(inputs[i].name);
|
||||
label->set_text(inputs[slot_index].name);
|
||||
property_control->add_child(label);
|
||||
|
||||
Label *hint_label = memnew(Label);
|
||||
@ -119,7 +129,7 @@ void VoxelGraphEditorNode::update_layout(const VoxelGeneratorGraph &graph) {
|
||||
}
|
||||
|
||||
Label *label = memnew(Label);
|
||||
label->set_text(outputs[i].name);
|
||||
label->set_text(outputs[slot_index].name);
|
||||
// Pass filter is required to allow tooltips to work
|
||||
label->set_mouse_filter(Control::MOUSE_FILTER_PASS);
|
||||
property_control->add_child(label);
|
||||
@ -128,7 +138,7 @@ void VoxelGraphEditorNode::update_layout(const VoxelGeneratorGraph &graph) {
|
||||
}
|
||||
|
||||
add_child(property_control);
|
||||
set_slot(i, has_left, Variant::FLOAT, port_color, has_right, Variant::FLOAT, port_color);
|
||||
set_slot(slot_index, has_left, Variant::FLOAT, port_color, has_right, Variant::FLOAT, port_color);
|
||||
_rows.push_back(property_control);
|
||||
}
|
||||
|
||||
@ -146,6 +156,13 @@ void VoxelGraphEditorNode::update_title(StringName node_name, String node_type_n
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorNode::poll(const VoxelGeneratorGraph &graph) {
|
||||
poll_default_inputs(graph);
|
||||
poll_params(graph);
|
||||
}
|
||||
|
||||
// When an input is left unconnected, it picks a default value. Input hints show this value.
|
||||
// It is otherwise shown in the inspector when the node is selected, but seeing them at a glance helps.
|
||||
void VoxelGraphEditorNode::poll_default_inputs(const VoxelGeneratorGraph &graph) {
|
||||
ProgramGraph::PortLocation src_loc_unused;
|
||||
const String prefix = ": ";
|
||||
@ -173,6 +190,13 @@ void VoxelGraphEditorNode::poll_default_inputs(const VoxelGeneratorGraph &graph)
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorNode::poll_params(const VoxelGeneratorGraph &graph) {
|
||||
if (graph.get_node_type_id(_node_id) == VoxelGeneratorGraph::NODE_EXPRESSION) {
|
||||
const String code = graph.get_node_param(_node_id, 0);
|
||||
set_title(code);
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelGraphEditorNode::update_range_analysis_tooltips(
|
||||
const VoxelGeneratorGraph &graph, const VoxelGraphRuntime::State &state) {
|
||||
for (unsigned int port_index = 0; port_index < _output_labels.size(); ++port_index) {
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
static VoxelGraphEditorNode *create(const VoxelGeneratorGraph &graph, uint32_t node_id);
|
||||
|
||||
void update_title(StringName node_name, String node_type_name);
|
||||
void poll_default_inputs(const VoxelGeneratorGraph &graph);
|
||||
void poll(const VoxelGeneratorGraph &graph);
|
||||
|
||||
void update_range_analysis_tooltips(const VoxelGeneratorGraph &graph, const VoxelGraphRuntime::State &state);
|
||||
void clear_range_analysis_tooltips();
|
||||
@ -33,11 +33,15 @@ public:
|
||||
return _node_id;
|
||||
}
|
||||
|
||||
inline VoxelGraphEditorNodePreview *get_preview() {
|
||||
inline VoxelGraphEditorNodePreview *get_preview() const {
|
||||
return _preview;
|
||||
}
|
||||
|
||||
private:
|
||||
void poll_default_inputs(const VoxelGeneratorGraph &graph);
|
||||
void poll_params(const VoxelGeneratorGraph &graph);
|
||||
void _on_resize_request(Vector2 new_size);
|
||||
|
||||
uint32_t _node_id = 0;
|
||||
VoxelGraphEditorNodePreview *_preview = nullptr;
|
||||
std::vector<Control *> _output_labels;
|
||||
|
Loading…
x
Reference in New Issue
Block a user