From 1c5376ae5951a4e47b972244cd2ec47760469b0c Mon Sep 17 00:00:00 2001
From: Juan Linietsky <reduzio@gmail.com>
Date: Tue, 12 Sep 2017 07:58:18 -0300
Subject: Many fixes to visual script, changed virtuals override for a proper
 selector.

---
 modules/visual_script/visual_script_editor.cpp | 177 ++++++++++---------------
 modules/visual_script/visual_script_editor.h   |   7 +-
 modules/visual_script/visual_script_nodes.cpp  |  20 +--
 3 files changed, 82 insertions(+), 122 deletions(-)

(limited to 'modules/visual_script')

diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 37bd730d08..dfec1eea60 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -506,7 +506,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
 			gnode->set_show_close_button(true);
 		}
 
-		if (Object::cast_to<VisualScriptExpression>(*node)) {
+		if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
 
 			LineEdit *line_edit = memnew(LineEdit);
 			line_edit->set_text(node->get_text());
@@ -520,7 +520,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
 			gnode->add_child(text);
 		}
 
-		if (Object::cast_to<VisualScriptExpression>(*node)) {
+		if (Object::cast_to<VisualScriptComment>(node.ptr())) {
 			Ref<VisualScriptComment> vsc = node;
 			gnode->set_comment(true);
 			gnode->set_resizable(true);
@@ -926,48 +926,6 @@ void VisualScriptEditor::_member_edited() {
 	}
 }
 
-void VisualScriptEditor::_override_pressed(int p_id) {
-
-	//override a virtual function or method from base type
-
-	ERR_FAIL_COND(!virtuals_in_menu.has(p_id));
-
-	VirtualInMenu vim = virtuals_in_menu[p_id];
-
-	String name = _validate_name(vim.name);
-	selected = name;
-	edited_func = selected;
-	Ref<VisualScriptFunction> func_node;
-	func_node.instance();
-	func_node->set_name(vim.name);
-
-	undo_redo->create_action(TTR("Add Function"));
-	undo_redo->add_do_method(script.ptr(), "add_function", name);
-	for (int i = 0; i < vim.args.size(); i++) {
-		func_node->add_argument(vim.args[i].first, vim.args[i].second);
-	}
-
-	undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node);
-	if (vim.ret != Variant::NIL || vim.ret_variant) {
-		Ref<VisualScriptReturn> ret_node;
-		ret_node.instance();
-		ret_node->set_return_type(vim.ret);
-		ret_node->set_enable_return_value(true);
-		ret_node->set_name(vim.name);
-		undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, Vector2(500, 0));
-	}
-
-	undo_redo->add_undo_method(script.ptr(), "remove_function", name);
-	undo_redo->add_do_method(this, "_update_members");
-	undo_redo->add_undo_method(this, "_update_members");
-	undo_redo->add_do_method(this, "_update_graph");
-	undo_redo->add_undo_method(this, "_update_graph");
-
-	undo_redo->commit_action();
-
-	_update_graph();
-}
-
 void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_button) {
 
 	TreeItem *ti = Object::cast_to<TreeItem>(p_item);
@@ -980,64 +938,9 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
 			//add function, this one uses menu
 
 			if (p_button == 1) {
-				new_function_menu->clear();
-				new_function_menu->set_size(Size2(0, 0));
-				int idx = 0;
-
-				virtuals_in_menu.clear();
-
-				List<MethodInfo> mi;
-				ClassDB::get_method_list(script->get_instance_base_type(), &mi);
-				for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
-					MethodInfo mi = E->get();
-					if (mi.flags & METHOD_FLAG_VIRTUAL) {
-
-						VirtualInMenu vim;
-						vim.name = mi.name;
-						vim.ret = mi.return_val.type;
-						if (mi.return_val.name != String())
-							vim.ret_variant = true;
-						else
-							vim.ret_variant = false;
-
-						String desc;
-
-						if (mi.return_val.type == Variant::NIL)
-							desc = "var";
-						else
-							desc = Variant::get_type_name(mi.return_val.type);
-						desc += " " + mi.name + " ( ";
-
-						for (int i = 0; i < mi.arguments.size(); i++) {
-
-							if (i > 0)
-								desc += ", ";
-
-							if (mi.arguments[i].type == Variant::NIL)
-								desc += "var ";
-							else
-								desc += Variant::get_type_name(mi.arguments[i].type) + " ";
-
-							desc += mi.arguments[i].name;
-
-							Pair<Variant::Type, String> p;
-							p.first = mi.arguments[i].type;
-							p.second = mi.arguments[i].name;
-							vim.args.push_back(p);
-						}
 
-						desc += " )";
+				new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), String(), true);
 
-						virtuals_in_menu[idx] = vim;
-
-						new_function_menu->add_item(desc, idx);
-						idx++;
-					}
-				}
-
-				Rect2 pos = members->get_item_rect(ti);
-				new_function_menu->set_position(members->get_global_position() + pos.position + Vector2(0, pos.size.y));
-				new_function_menu->popup();
 				return;
 			} else if (p_button == 0) {
 
@@ -2686,21 +2589,21 @@ void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p
 
 	Ref<VisualScriptNode> vsn = script->get_node(edited_func, port_action_new_node);
 
-	if (Object::cast_to<VisualScriptFunctionCall>(*vsn)) {
+	if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) {
 
 		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);
 	}
 
-	if (Object::cast_to<VisualScriptPropertySet>(*vsn)) {
+	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);
 	}
 
-	if (Object::cast_to<VisualScriptPropertyGet>(*vsn)) {
+	if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) {
 
 		Ref<VisualScriptPropertyGet> vsp = vsn;
 		vsp->set_property(p_text);
@@ -2711,6 +2614,63 @@ void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p
 	_update_graph_connections();
 }
 
+void VisualScriptEditor::_selected_new_virtual_method(const String &p_text) {
+
+	String name = p_text;
+	if (script->has_function(name)) {
+		EditorNode::get_singleton()->show_warning(vformat(TTR("Script already has function '%s'"), name));
+		return;
+	}
+
+	MethodInfo minfo;
+	{
+		List<MethodInfo> methods;
+		bool found = false;
+		ClassDB::get_virtual_methods(script->get_instance_base_type(), &methods);
+		for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
+			if (E->get().name == name) {
+				minfo = E->get();
+				found = true;
+			}
+		}
+
+		ERR_FAIL_COND(!found);
+	}
+
+	selected = name;
+	edited_func = selected;
+	Ref<VisualScriptFunction> func_node;
+	func_node.instance();
+	func_node->set_name(name);
+
+	undo_redo->create_action(TTR("Add Function"));
+	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);
+	}
+
+	undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node);
+	if (minfo.return_val.type != Variant::NIL || minfo.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+		Ref<VisualScriptReturn> ret_node;
+		ret_node.instance();
+		ret_node->set_return_type(minfo.return_val.type);
+		ret_node->set_enable_return_value(true);
+		ret_node->set_name(name);
+		undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, Vector2(500, 0));
+	}
+
+	undo_redo->add_undo_method(script.ptr(), "remove_function", name);
+	undo_redo->add_do_method(this, "_update_members");
+	undo_redo->add_undo_method(this, "_update_members");
+	undo_redo->add_do_method(this, "_update_graph");
+	undo_redo->add_undo_method(this, "_update_graph");
+
+	undo_redo->commit_action();
+
+	_update_graph();
+}
+
 void VisualScriptEditor::_cancel_connect_node_method_or_setget() {
 
 	script->remove_node(edited_func, port_action_new_node);
@@ -3147,7 +3107,6 @@ void VisualScriptEditor::_bind_methods() {
 	ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
 	ClassDB::bind_method("_change_base_type", &VisualScriptEditor::_change_base_type);
 	ClassDB::bind_method("_change_base_type_callback", &VisualScriptEditor::_change_base_type_callback);
-	ClassDB::bind_method("_override_pressed", &VisualScriptEditor::_override_pressed);
 	ClassDB::bind_method("_node_selected", &VisualScriptEditor::_node_selected);
 	ClassDB::bind_method("_node_moved", &VisualScriptEditor::_node_moved);
 	ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node);
@@ -3166,6 +3125,8 @@ void VisualScriptEditor::_bind_methods() {
 	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_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("_expression_text_changed", &VisualScriptEditor::_expression_text_changed);
 
@@ -3344,9 +3305,6 @@ VisualScriptEditor::VisualScriptEditor() {
 
 	undo_redo = EditorNode::get_singleton()->get_undo_redo();
 
-	new_function_menu = memnew(PopupMenu);
-	new_function_menu->connect("id_pressed", this, "_override_pressed");
-	add_child(new_function_menu);
 	updating_members = false;
 
 	set_process_input(true); //for revert on drag
@@ -3366,6 +3324,11 @@ VisualScriptEditor::VisualScriptEditor() {
 	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_virtual_method_select = memnew(PropertySelector);
+	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");
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index dd051ef8e4..5b8c3ea74e 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -103,6 +103,7 @@ class VisualScriptEditor : public ScriptEditorBase {
 
 	PropertySelector *method_select;
 	PropertySelector *new_connect_node_select;
+	PropertySelector *new_virtual_method_select;
 
 	VisualScriptEditorVariableEdit *variable_editor;
 
@@ -135,10 +136,6 @@ class VisualScriptEditor : public ScriptEditorBase {
 		Vector<Pair<Variant::Type, String> > args;
 	};
 
-	Map<int, VirtualInMenu> virtuals_in_menu;
-
-	PopupMenu *new_function_menu;
-
 	StringName edited_func;
 
 	void _update_graph_connections();
@@ -177,6 +174,7 @@ class VisualScriptEditor : public ScriptEditorBase {
 	void _port_action_menu(int p_option);
 	void _selected_connect_node_method_or_setget(const String &p_text);
 	void _cancel_connect_node_method_or_setget();
+	void _selected_new_virtual_method(const String &p_text);
 
 	int error_line;
 
@@ -188,7 +186,6 @@ class VisualScriptEditor : public ScriptEditorBase {
 	void _change_base_type();
 	void _member_selected();
 	void _member_edited();
-	void _override_pressed(int p_id);
 
 	void _begin_node_move();
 	void _end_node_move();
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 1decc004ab..093f01c49f 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -1493,7 +1493,7 @@ void VisualScriptGlobalConstant::_bind_methods() {
 			cc += ",";
 		cc += GlobalConstants::get_global_constant_name(i);
 	}
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant");
 }
 
 VisualScriptGlobalConstant::VisualScriptGlobalConstant() {
@@ -1622,7 +1622,7 @@ void VisualScriptClassConstant::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptClassConstant::get_base_type);
 
 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
-	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant");
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant");
 }
 
 VisualScriptClassConstant::VisualScriptClassConstant() {
@@ -1760,7 +1760,7 @@ void VisualScriptBasicTypeConstant::_bind_methods() {
 	}
 
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type");
-	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant");
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant");
 }
 
 VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() {
@@ -1881,7 +1881,7 @@ void VisualScriptMathConstant::_bind_methods() {
 			cc += ",";
 		cc += const_name[i];
 	}
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant");
 }
 
 VisualScriptMathConstant::VisualScriptMathConstant() {
@@ -2002,7 +2002,7 @@ void VisualScriptEngineSingleton::_bind_methods() {
 		cc += E->get().name;
 	}
 
-	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton");
+	ADD_PROPERTY(PropertyInfo(Variant::STRING, "/constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton");
 }
 
 VisualScriptEngineSingleton::VisualScriptEngineSingleton() {
@@ -3727,11 +3727,11 @@ void register_visual_script_nodes() {
 	VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>);
 	VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>);
 
-	VisualScriptLanguage::singleton->add_register_func("constant/constants/constant", create_node_generic<VisualScriptConstant>);
-	VisualScriptLanguage::singleton->add_register_func("constant/constants/math_constant", create_node_generic<VisualScriptMathConstant>);
-	VisualScriptLanguage::singleton->add_register_func("constant/constants/class_constant", create_node_generic<VisualScriptClassConstant>);
-	VisualScriptLanguage::singleton->add_register_func("constant/constants/global_constant", create_node_generic<VisualScriptGlobalConstant>);
-	VisualScriptLanguage::singleton->add_register_func("constant/constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>);
+	VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>);
+	VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>);
+	VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>);
+	VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>);
+	VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>);
 
 	VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>);
 	VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>);
-- 
cgit v1.2.3