summaryrefslogtreecommitdiffstats
path: root/modules/visual_script/visual_script_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/visual_script/visual_script_editor.cpp')
-rw-r--r--modules/visual_script/visual_script_editor.cpp522
1 files changed, 354 insertions, 168 deletions
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index dfaa873b13..ef40af686c 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -33,8 +33,10 @@
#include "core/script_language.h"
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
+#include "object.h"
#include "os/input.h"
#include "os/keyboard.h"
+#include "variant.h"
#include "visual_script_expression.h"
#include "visual_script_flow_control.h"
#include "visual_script_func_nodes.h"
@@ -527,6 +529,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
GraphNode *gnode = memnew(GraphNode);
gnode->set_title(node->get_caption());
+ gnode->set_offset(pos * EDSCALE);
if (error_line == E->get()) {
gnode->set_overlay(GraphNode::OVERLAY_POSITION);
} else if (node->is_breakpoint()) {
@@ -543,8 +546,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_show_close_button(true);
}
- if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
+ bool has_gnode_text = false;
+ if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
+ has_gnode_text = true;
LineEdit *line_edit = memnew(LineEdit);
line_edit->set_text(node->get_text());
line_edit->set_expand_to_text_length(true);
@@ -552,9 +557,13 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->add_child(line_edit);
line_edit->connect("text_changed", this, "_expression_text_changed", varray(E->get()));
} else {
- Label *text = memnew(Label);
- text->set_text(node->get_text());
- gnode->add_child(text);
+ String text = node->get_text();
+ if (!text.empty()) {
+ has_gnode_text = true;
+ Label *label = memnew(Label);
+ label->set_text(text);
+ gnode->add_child(label);
+ }
}
if (Object::cast_to<VisualScriptComment>(node.ptr())) {
@@ -589,9 +598,21 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
int slot_idx = 0;
bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String();
- gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
- gnode->set_offset(pos * EDSCALE);
- slot_idx++;
+ if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) {
+ // IF has_gnode_text is true BUT we have no sequence ports to draw (in here),
+ // we still draw the disabled default ones to shift up the slots by one,
+ // so the slots DON'T start with the content text.
+
+ // IF has_gnode_text is false, but we DO want to draw default sequence ports,
+ // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly.
+ if (!has_gnode_text) {
+ Label *dummy = memnew(Label);
+ dummy->set_text(" ");
+ gnode->add_child(dummy);
+ }
+ gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
+ slot_idx++;
+ }
int mixed_seq_ports = 0;
@@ -1274,7 +1295,7 @@ void VisualScriptEditor::_on_nodes_duplicate() {
Ref<VisualScriptNode> node = script->get_node(edited_func, F->get());
- Ref<VisualScriptNode> dupe = node->duplicate();
+ Ref<VisualScriptNode> dupe = node->duplicate(true);
int new_id = idc++;
to_select.insert(new_id);
@@ -1308,6 +1329,10 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
}
}
+void VisualScriptEditor::_generic_search() {
+ new_connect_node_select->select_from_visual_script(String(""), false);
+}
+
void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> key = p_event;
@@ -1761,7 +1786,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
call->set_base_type(node->get_class());
n = call;
- method_select->select_method_from_instance(node);
+ method_select->select_from_instance(node);
selecting_method_id = base_id;
}
@@ -1898,7 +1923,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
}
-void VisualScriptEditor::_selected_method(const String &p_method) {
+void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type) {
Ref<VisualScriptFunctionCall> vsfc = script->get_node(edited_func, selecting_method_id);
if (!vsfc.is_valid())
@@ -1943,22 +1968,16 @@ void VisualScriptEditor::_button_resource_previewed(const String &p_path, const
void VisualScriptEditor::apply_code() {
}
-Ref<Script> VisualScriptEditor::get_edited_script() const {
-
+RES VisualScriptEditor::get_edited_resource() const {
return script;
}
-Vector<String> VisualScriptEditor::get_functions() {
-
- return Vector<String>();
-}
-
-void VisualScriptEditor::set_edited_script(const Ref<Script> &p_script) {
+void VisualScriptEditor::set_edited_resource(const RES &p_res) {
- script = p_script;
- signal_editor->script = p_script;
+ script = p_res;
+ signal_editor->script = script;
signal_editor->undo_redo = undo_redo;
- variable_editor->script = p_script;
+ variable_editor->script = script;
variable_editor->undo_redo = undo_redo;
script->connect("node_ports_changed", this, "_node_ports_changed");
@@ -1967,6 +1986,11 @@ void VisualScriptEditor::set_edited_script(const Ref<Script> &p_script) {
_update_available_nodes();
}
+Vector<String> VisualScriptEditor::get_functions() {
+
+ return Vector<String>();
+}
+
void VisualScriptEditor::reload_text() {
}
@@ -2417,33 +2441,19 @@ void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_fro
if (!vsn.is_valid())
return;
- if (p_from_slot < vsn->get_output_sequence_port_count()) {
+ port_action_pos = p_release_pos;
- port_action_popup->clear();
- port_action_popup->add_item(TTR("Condition"), CREATE_COND);
- port_action_popup->add_item(TTR("Sequence"), CREATE_SEQUENCE);
- port_action_popup->add_item(TTR("Switch"), CREATE_SWITCH);
- port_action_popup->add_item(TTR("Iterator"), CREATE_ITERATOR);
- port_action_popup->add_item(TTR("While"), CREATE_WHILE);
- port_action_popup->add_item(TTR("Return"), CREATE_RETURN);
+ if (p_from_slot < vsn->get_output_sequence_port_count()) {
port_action_node = p_from.to_int();
port_action_output = p_from_slot;
-
+ _port_action_menu(CREATE_ACTION);
} else {
- port_action_popup->clear();
- port_action_popup->add_item(TTR("Call"), CREATE_CALL);
- port_action_popup->add_item(TTR("Get"), CREATE_GET);
- port_action_popup->add_item(TTR("Set"), CREATE_SET);
port_action_output = p_from_slot - vsn->get_output_sequence_port_count();
port_action_node = p_from.to_int();
+ _port_action_menu(CREATE_CALL_SET_GET);
}
-
- port_action_pos = p_release_pos;
- port_action_popup->set_size(Size2(1, 1));
- port_action_popup->set_position(graph->get_global_position() + p_release_pos);
- port_action_popup->popup();
}
VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_action_node, int p_port_action_output, Set<int> &visited_nodes) {
@@ -2511,168 +2521,205 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
bool seq_connect = false;
- Ref<VisualScriptNode> vnode;
Set<int> vn;
switch (p_option) {
- case CREATE_CALL: {
-
+ case CREATE_CALL_SET_GET: {
Ref<VisualScriptFunctionCall> n;
n.instance();
- vnode = n;
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
- if (tg.type == Variant::OBJECT) {
- n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
-
- if (tg.gdclass != StringName()) {
- n->set_base_type(tg.gdclass);
- } else {
- n->set_base_type("Object");
- }
+ if (tg.gdclass != StringName()) {
+ n->set_base_type(tg.gdclass);
+ } else {
+ n->set_base_type("Object");
+ }
+ String type_string = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ if (tg.type == Variant::OBJECT) {
if (tg.script.is_valid()) {
- n->set_base_script(tg.script->get_path());
- new_connect_node_select->select_method_from_script(tg.script);
+ new_connect_node_select->select_from_script(tg.script, "");
+ } else if (type_string != String()) {
+ new_connect_node_select->select_from_base_type(type_string);
} else {
- new_connect_node_select->select_method_from_base_type(n->get_base_type());
+ new_connect_node_select->select_from_base_type(n->get_base_type());
}
-
+ } else if (tg.type == Variant::NIL) {
+ new_connect_node_select->select_from_base_type("");
} else {
- n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE);
- n->set_basic_type(tg.type);
- new_connect_node_select->select_method_from_basic_type(tg.type);
+ new_connect_node_select->select_from_basic_type(tg.type);
}
-
} break;
- case CREATE_SET: {
-
- Ref<VisualScriptPropertySet> n;
- n.instance();
- vnode = n;
-
+ case CREATE_ACTION: {
+ seq_connect = true;
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
-
+ PropertyInfo property_info = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output);
if (tg.type == Variant::OBJECT) {
- n->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
-
- if (tg.gdclass != StringName()) {
- n->set_base_type(tg.gdclass);
- } else {
- n->set_base_type("Object");
- }
-
- if (tg.script.is_valid()) {
- n->set_base_script(tg.script->get_path());
- new_connect_node_select->select_property_from_script(tg.script);
+ if (property_info.type == Variant::OBJECT && property_info.hint_string != String()) {
+ new_connect_node_select->select_from_action(property_info.hint_string);
} else {
- new_connect_node_select->select_property_from_base_type(n->get_base_type());
+ new_connect_node_select->select_from_action("");
}
-
+ } else if (tg.type == Variant::NIL) {
+ new_connect_node_select->select_from_action("");
} else {
- n->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE);
- n->set_basic_type(tg.type);
- new_connect_node_select->select_property_from_basic_type(tg.type);
+ new_connect_node_select->select_from_action(Variant::get_type_name(tg.type));
}
} break;
- case CREATE_GET: {
+ }
+}
- Ref<VisualScriptPropertyGet> n;
- n.instance();
- vnode = n;
+void VisualScriptEditor::new_node(Ref<VisualScriptNode> vnode, Vector2 ofs) {
+ Set<int> vn;
+ Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node);
+ int new_id = script->get_available_id();
+ undo_redo->create_action(TTR("Add Node"));
+ undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", edited_func, new_id);
+ undo_redo->add_do_method(this, "_update_graph", new_id);
+ undo_redo->add_undo_method(this, "_update_graph", new_id);
+ undo_redo->commit_action();
- VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ port_action_new_node = new_id;
+}
- if (tg.type == Variant::OBJECT) {
- n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
+void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id) {
+ undo_redo->create_action(TTR("Connect Node Data"));
+ VisualScriptReturn *vnode_return = Object::cast_to<VisualScriptReturn>(vnode.ptr());
+ if (vnode_return != NULL && vnode_old->get_output_value_port_count() > 0) {
+ vnode_return->set_enable_return_value(true);
+ }
+ if (vnode_old->get_output_value_port_count() <= 0) {
+ undo_redo->commit_action();
+ return;
+ }
+ if (vnode->get_input_value_port_count() <= 0) {
+ undo_redo->commit_action();
+ return;
+ }
+ int port = port_action_output;
+ int value_count = vnode_old->get_output_value_port_count();
+ if (port >= value_count) {
+ port = 0;
+ }
+ int count = vnode_old->get_output_value_port_count() + vnode_old->get_output_sequence_port_count();
+ undo_redo->add_do_method(script.ptr(), "data_connect", edited_func, port_action_node, port, new_id, 0);
+ undo_redo->add_undo_method(script.ptr(), "data_disconnect", edited_func, port_action_node, port, new_id, 0);
+ undo_redo->commit_action();
+}
- if (tg.gdclass != StringName()) {
- n->set_base_type(tg.gdclass);
- } else {
- n->set_base_type("Object");
- }
+void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) {
+ Vector2 ofs = graph->get_scroll_ofs() + port_action_pos;
+ if (graph->is_using_snap()) {
+ int snap = graph->get_snap();
+ ofs = ofs.snapped(Vector2(snap, snap));
+ }
+ ofs /= EDSCALE;
- if (tg.script.is_valid()) {
- n->set_base_script(tg.script->get_path());
- new_connect_node_select->select_property_from_script(tg.script);
- } else {
- new_connect_node_select->select_property_from_base_type(n->get_base_type());
- }
+ Set<int> vn;
+ if (p_category == "visualscript") {
+ Ref<VisualScriptNode> vnode_new = VisualScriptLanguage::singleton->create_node_from_name(p_text);
+ Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node);
+ int new_id = script->get_available_id();
+
+ if (Object::cast_to<VisualScriptOperator>(vnode_new.ptr()) && script->get_node(edited_func, port_action_node).is_valid()) {
+ Variant::Type type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).type;
+ Object::cast_to<VisualScriptOperator>(vnode_new.ptr())->set_typed(type);
+ }
+
+ if (Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr()) && script->get_node(edited_func, port_action_node).is_valid()) {
+ Variant::Type type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).type;
+ String hint_name = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+
+ if (type == Variant::OBJECT) {
+ Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())->set_base_type(hint_name);
+ } else if (type == Variant::NIL) {
+ Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())->set_base_type("");
} else {
- n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE);
- n->set_basic_type(tg.type);
- new_connect_node_select->select_property_from_basic_type(tg.type);
+ Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())->set_base_type(Variant::get_type_name(type));
}
+ }
+ undo_redo->create_action(TTR("Add Node"));
+ undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode_new, ofs);
+ if (vnode_old.is_valid() && p_connecting == true) {
+ connect_seq(vnode_old, vnode_new, new_id);
+ connect_data(vnode_old, vnode_new, new_id);
+ }
- } break;
- case CREATE_COND: {
+ undo_redo->add_undo_method(script.ptr(), "remove_node", edited_func, new_id);
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->commit_action();
+ return;
+ }
+
+ Ref<VisualScriptNode> vnode;
+
+ seq_connect = false;
+ if (p_category == String("method")) {
+
+ Ref<VisualScriptFunctionCall> n;
+ n.instance();
+ vnode = n;
+ } else if (p_category == String("set")) {
+
+ Ref<VisualScriptPropertySet> n;
+ n.instance();
+ n->set_property(p_text);
+ vnode = n;
+ } else if (p_category == String("get")) {
+
+ Ref<VisualScriptPropertyGet> n;
+ n.instance();
+ n->set_property(p_text);
+ vnode = n;
+ }
+
+ if (p_category == String("action")) {
+ if (p_text == "VisualScriptCondition") {
Ref<VisualScriptCondition> n;
n.instance();
vnode = n;
seq_connect = true;
+ }
+ if (p_text == "VisualScriptSwitch") {
- } break;
- case CREATE_SEQUENCE: {
-
- Ref<VisualScriptSequence> n;
+ Ref<VisualScriptSwitch> n;
n.instance();
vnode = n;
seq_connect = true;
+ } else if (p_text == "VisualScriptSequence") {
- } break;
- case CREATE_SWITCH: {
-
- Ref<VisualScriptSwitch> n;
+ Ref<VisualScriptSequence> n;
n.instance();
vnode = n;
seq_connect = true;
-
- } break;
- case CREATE_ITERATOR: {
+ } else if (p_text == "VisualScriptIterator") {
Ref<VisualScriptIterator> n;
n.instance();
vnode = n;
seq_connect = true;
-
- } break;
- case CREATE_WHILE: {
+ } else if (p_text == "VisualScriptWhile") {
Ref<VisualScriptWhile> n;
n.instance();
vnode = n;
seq_connect = true;
-
- } break;
- case CREATE_RETURN: {
+ } else if (p_text == "VisualScriptReturn") {
Ref<VisualScriptReturn> n;
n.instance();
vnode = n;
seq_connect = true;
-
- } break;
+ }
}
- int new_id = script->get_available_id();
- undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode, ofs);
- if (seq_connect) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, port_action_node, port_action_output, new_id);
- }
- undo_redo->add_undo_method(script.ptr(), "remove_node", edited_func, new_id);
- undo_redo->add_do_method(this, "_update_graph", new_id);
- undo_redo->add_undo_method(this, "_update_graph", new_id);
- undo_redo->commit_action();
-
- port_action_new_node = new_id;
-}
-
-void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p_text) {
+ new_node(vnode, ofs);
Ref<VisualScriptNode> vsn = script->get_node(edited_func, port_action_new_node);
@@ -2680,28 +2727,152 @@ void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p
Ref<VisualScriptFunctionCall> vsfc = vsn;
vsfc->set_function(p_text);
- script->data_connect(edited_func, port_action_node, port_action_output, port_action_new_node, 0);
+
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ if (tg.type == Variant::OBJECT) {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
+ vsfc->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsfc->set_base_type(tg.gdclass);
+
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsfc->set_base_type(base_type);
+ }
+ if (p_text == "call" || p_text == "call_deferred") {
+ vsfc->set_function(String(""));
+ }
+ }
+ if (tg.script.is_valid()) {
+ vsfc->set_base_script(tg.script->get_path());
+ }
+ } else if (tg.type == Variant::NIL) {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE);
+ vsfc->set_base_type(String(""));
+ } else {
+ vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE);
+ vsfc->set_basic_type(tg.type);
+ }
}
if (Object::cast_to<VisualScriptPropertySet>(vsn.ptr())) {
Ref<VisualScriptPropertySet> vsp = vsn;
- vsp->set_property(p_text);
- script->data_connect(edited_func, port_action_node, port_action_output, port_action_new_node, 0);
+
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ if (tg.type == Variant::OBJECT) {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsp->set_base_type(tg.gdclass);
+
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsp->set_base_type(base_type);
+ }
+ }
+ if (tg.script.is_valid()) {
+ vsp->set_base_script(tg.script->get_path());
+ }
+ } else if (tg.type == Variant::NIL) {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ } else {
+ vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE);
+ vsp->set_basic_type(tg.type);
+ }
}
if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) {
-
Ref<VisualScriptPropertyGet> vsp = vsn;
- vsp->set_property(p_text);
- script->data_connect(edited_func, port_action_node, port_action_output, port_action_new_node, 0);
- }
+ VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
+ if (tg.type == Variant::OBJECT) {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ if (tg.gdclass != StringName()) {
+ vsp->set_base_type(tg.gdclass);
+
+ } else if (script->get_node(edited_func, port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
+ vsp->set_base_type(base_type);
+ }
+ }
+ if (tg.script.is_valid()) {
+ vsp->set_base_script(tg.script->get_path());
+ }
+ } else if (tg.type == Variant::NIL) {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
+ vsp->set_base_type(String(""));
+ } else {
+ vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE);
+ vsp->set_basic_type(tg.type);
+ }
+ }
+ Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node);
+ if (vnode_old.is_valid() && p_connecting == true) {
+ connect_seq(vnode_old, vnode, port_action_new_node);
+ connect_data(vnode_old, vnode, port_action_new_node);
+ }
_update_graph(port_action_new_node);
_update_graph_connections();
}
-void VisualScriptEditor::_selected_new_virtual_method(const String &p_text) {
+void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) {
+ int seq_count = vnode_old->get_output_sequence_port_count();
+ VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(vnode_new.ptr());
+ if (vnode_operator != NULL && vnode_operator->has_input_sequence_port() == false) {
+ return;
+ }
+ VisualScriptConstructor *vnode_constructor = Object::cast_to<VisualScriptConstructor>(vnode_new.ptr());
+ if (vnode_constructor != NULL) {
+ return;
+ }
+ if (vnode_old->get_output_sequence_port_count() <= 0) {
+ return;
+ }
+ if (vnode_new->has_input_sequence_port() == false) {
+ return;
+ }
+ VisualScriptFunction *vnode_function = Object::cast_to<VisualScriptFunction>(vnode_old.ptr());
+ undo_redo->create_action(TTR("Connect Node Sequence"));
+ int pass_port = -vnode_old->get_output_sequence_port_count() + 1;
+ int return_port = port_action_output - 1;
+ if (vnode_old->get_output_value_port_info(port_action_output).name == String("pass") &&
+ !script->get_output_sequence_ports_connected(edited_func, port_action_node).has(pass_port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, port_action_node, pass_port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", edited_func, port_action_node, pass_port, new_id);
+ } else if (vnode_old->get_output_value_port_info(port_action_output).name == String("return") &&
+ !script->get_output_sequence_ports_connected(edited_func, port_action_node).has(return_port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, port_action_node, return_port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", edited_func, port_action_node, return_port, new_id);
+ } else {
+ for (int port = 0; port < vnode_old->get_output_sequence_port_count(); port++) {
+ int count = vnode_old->get_output_sequence_port_count();
+ if (port_action_output < count && !script->get_output_sequence_ports_connected(edited_func, port_action_node).has(port_action_output)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, port_action_node, port_action_output, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", edited_func, port_action_node, port_action_output, new_id);
+ break;
+ } else if (!script->get_output_sequence_ports_connected(edited_func, port_action_node).has(port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", edited_func, port_action_node, port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", edited_func, port_action_node, port, new_id);
+ break;
+ }
+ }
+ }
+
+ undo_redo->commit_action();
+}
+
+void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting) {
String name = p_text;
if (script->has_function(name)) {
@@ -2734,7 +2905,7 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text) {
undo_redo->add_do_method(script.ptr(), "add_function", name);
for (int i = 0; i < minfo.arguments.size(); i++) {
- func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name);
+ func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name, -1, minfo.arguments[i].hint, minfo.arguments[i].hint_string);
}
undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node);
@@ -2758,12 +2929,29 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text) {
_update_graph();
}
-void VisualScriptEditor::_cancel_connect_node_method_or_setget() {
-
- script->remove_node(edited_func, port_action_new_node);
+void VisualScriptEditor::_cancel_connect_node() {
+ // Causes crashes
+ //script->remove_node(edited_func, port_action_new_node);
_update_graph();
}
+void VisualScriptEditor::_create_new_node(const String &p_text, const String &p_category, const Vector2 &p_point) {
+ Vector2 ofs = graph->get_scroll_ofs() + p_point;
+ if (graph->is_using_snap()) {
+ int snap = graph->get_snap();
+ ofs = ofs.snapped(Vector2(snap, snap));
+ }
+ ofs /= EDSCALE;
+ Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(p_text);
+ int new_id = script->get_available_id();
+ undo_redo->create_action(TTR("Add Node"));
+ undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", edited_func, new_id);
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
+ undo_redo->commit_action();
+}
+
void VisualScriptEditor::_default_value_changed() {
Ref<VisualScriptNode> vsn = script->get_node(edited_func, editing_id);
@@ -2961,9 +3149,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_FIND_NODE_TYPE: {
- //popup disappearing grabs focus to owner, so use call deferred
- node_filter->call_deferred("grab_focus");
- node_filter->call_deferred("select_all");
+ _generic_search();
} break;
case EDIT_COPY_NODES:
case EDIT_CUT_NODES: {
@@ -2987,7 +3173,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
return;
}
if (node.is_valid()) {
- clipboard->nodes[id] = node->duplicate();
+ clipboard->nodes[id] = node->duplicate(true);
clipboard->nodes_positions[id] = script->get_node_position(edited_func, id);
}
}
@@ -3267,10 +3453,11 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_comment_node_resized", &VisualScriptEditor::_comment_node_resized);
ClassDB::bind_method("_button_resource_previewed", &VisualScriptEditor::_button_resource_previewed);
ClassDB::bind_method("_port_action_menu", &VisualScriptEditor::_port_action_menu);
- ClassDB::bind_method("_selected_connect_node_method_or_setget", &VisualScriptEditor::_selected_connect_node_method_or_setget);
+ ClassDB::bind_method("_selected_connect_node", &VisualScriptEditor::_selected_connect_node);
ClassDB::bind_method("_selected_new_virtual_method", &VisualScriptEditor::_selected_new_virtual_method);
- ClassDB::bind_method("_cancel_connect_node_method_or_setget", &VisualScriptEditor::_cancel_connect_node_method_or_setget);
+ ClassDB::bind_method("_cancel_connect_node", &VisualScriptEditor::_cancel_connect_node);
+ ClassDB::bind_method("_create_new_node", &VisualScriptEditor::_create_new_node);
ClassDB::bind_method("_expression_text_changed", &VisualScriptEditor::_expression_text_changed);
ClassDB::bind_method("get_drag_data_fw", &VisualScriptEditor::get_drag_data_fw);
@@ -3299,6 +3486,8 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_member_option", &VisualScriptEditor::_member_option);
ClassDB::bind_method("_update_available_nodes", &VisualScriptEditor::_update_available_nodes);
+
+ ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search);
}
VisualScriptEditor::VisualScriptEditor() {
@@ -3370,6 +3559,7 @@ VisualScriptEditor::VisualScriptEditor() {
graph = memnew(GraphEdit);
add_child(graph);
+ graph->set_v_size_flags(Control::SIZE_EXPAND_FILL);
graph->set_anchors_and_margins_preset(Control::PRESET_WIDE);
graph->connect("node_selected", this, "_node_selected");
graph->connect("_begin_node_move", this, "_begin_node_move");
@@ -3460,25 +3650,21 @@ VisualScriptEditor::VisualScriptEditor() {
add_child(default_value_edit);
default_value_edit->connect("variant_changed", this, "_default_value_changed");
- method_select = memnew(PropertySelector);
+ method_select = memnew(VisualScriptPropertySelector);
add_child(method_select);
method_select->connect("selected", this, "_selected_method");
error_line = -1;
- new_connect_node_select = memnew(PropertySelector);
+ new_connect_node_select = memnew(VisualScriptPropertySelector);
add_child(new_connect_node_select);
- new_connect_node_select->connect("selected", this, "_selected_connect_node_method_or_setget");
- new_connect_node_select->get_cancel()->connect("pressed", this, "_cancel_connect_node_method_or_setget");
+ new_connect_node_select->connect("selected", this, "_selected_connect_node");
+ new_connect_node_select->get_cancel()->connect("pressed", this, "_cancel_connect_node");
- new_virtual_method_select = memnew(PropertySelector);
+ new_virtual_method_select = memnew(VisualScriptPropertySelector);
add_child(new_virtual_method_select);
new_virtual_method_select->connect("selected", this, "_selected_new_virtual_method");
new_virtual_method_select->get_cancel()->connect("pressed", this, "_selected_new_virtual_method");
- port_action_popup = memnew(PopupMenu);
- add_child(port_action_popup);
- port_action_popup->connect("id_pressed", this, "_port_action_menu");
-
member_popup = memnew(PopupMenu);
add_child(member_popup);
members->connect("item_rmb_selected", this, "_member_rmb_selected");
@@ -3495,9 +3681,9 @@ VisualScriptEditor::~VisualScriptEditor() {
memdelete(variable_editor);
}
-static ScriptEditorBase *create_editor(const Ref<Script> &p_script) {
+static ScriptEditorBase *create_editor(const RES &p_resource) {
- if (Object::cast_to<VisualScript>(*p_script)) {
+ if (Object::cast_to<VisualScript>(*p_resource)) {
return memnew(VisualScriptEditor);
}