Improve Visual Script editor to suggest the proper visual script nodes.
This commit is contained in:
parent
324dca57af
commit
3a82f66974
|
@ -1366,7 +1366,7 @@ void VisualScriptEditor::_create_function() {
|
|||
}
|
||||
|
||||
void VisualScriptEditor::_add_node_dialog() {
|
||||
_generic_search(script->get_instance_base_type(), graph->get_global_position() + Vector2(55, 80), true);
|
||||
_generic_search(graph->get_global_position() + Vector2(55, 80), true);
|
||||
}
|
||||
|
||||
void VisualScriptEditor::_add_func_input() {
|
||||
|
@ -1442,7 +1442,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
|
|||
if (p_button == 1) {
|
||||
// Ensure script base exists otherwise use custom base type.
|
||||
ERR_FAIL_COND(script.is_null());
|
||||
new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), String(), true);
|
||||
new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), true);
|
||||
return;
|
||||
} else if (p_button == 0) {
|
||||
String name = _validate_name("new_function");
|
||||
|
@ -1948,14 +1948,14 @@ void VisualScriptEditor::_on_nodes_duplicate() {
|
|||
}
|
||||
}
|
||||
|
||||
void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool node_centered) {
|
||||
void VisualScriptEditor::_generic_search(Vector2 pos, bool node_centered) {
|
||||
if (node_centered) {
|
||||
port_action_pos = graph->get_size() / 2.0f;
|
||||
} else {
|
||||
port_action_pos = graph->get_viewport()->get_mouse_position() - graph->get_global_position();
|
||||
}
|
||||
|
||||
new_connect_node_select->select_from_visual_script(p_base_type, false, false); // neither connecting nor reset text
|
||||
new_connect_node_select->select_from_visual_script(script, false); // do not reset text
|
||||
|
||||
// Ensure that the dialog fits inside the graph.
|
||||
Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size();
|
||||
|
@ -1992,7 +1992,7 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
}
|
||||
if (is_empty_selection && clipboard->nodes.is_empty()) {
|
||||
_generic_search(script->get_instance_base_type(), mouse_up_position);
|
||||
_generic_search();
|
||||
} else {
|
||||
popup_menu->set_item_disabled(int(EDIT_CUT_NODES), is_empty_selection);
|
||||
popup_menu->set_item_disabled(int(EDIT_COPY_NODES), is_empty_selection);
|
||||
|
@ -2446,7 +2446,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
|
|||
drop_position = pos;
|
||||
drop_node = node;
|
||||
drop_path = sn->get_path_to(node);
|
||||
new_connect_node_select->select_from_instance(node, "", false, node->get_class());
|
||||
new_connect_node_select->select_from_instance(node, false);
|
||||
}
|
||||
undo_redo->add_do_method(this, "_update_graph");
|
||||
undo_redo->add_undo_method(this, "_update_graph");
|
||||
|
@ -3234,19 +3234,34 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
|
|||
n->set_base_type("Object");
|
||||
}
|
||||
String type_string;
|
||||
String base_script = "";
|
||||
if (script->get_node(port_action_node)->get_output_value_port_count() > 0) {
|
||||
type_string = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
|
||||
VisualScriptFunctionCall *vsfc = Object::cast_to<VisualScriptFunctionCall>(*script->get_node(port_action_node));
|
||||
if (vsfc) {
|
||||
base_script = vsfc->get_base_script();
|
||||
} else {
|
||||
VisualScriptPropertyGet *vspg = Object::cast_to<VisualScriptPropertyGet>(*script->get_node(port_action_node));
|
||||
if (vspg) {
|
||||
base_script = vspg->get_base_script();
|
||||
} else {
|
||||
VisualScriptPropertySet *vsps = Object::cast_to<VisualScriptPropertySet>(*script->get_node(port_action_node));
|
||||
if (vsps) {
|
||||
base_script = vsps->get_base_script();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tg.type == Variant::OBJECT) {
|
||||
if (tg.script.is_valid()) {
|
||||
new_connect_node_select->select_from_script(tg.script, "");
|
||||
} else if (!type_string.is_empty()) {
|
||||
new_connect_node_select->select_from_base_type(type_string);
|
||||
new_connect_node_select->select_from_script(tg.script);
|
||||
} else if (type_string != String()) {
|
||||
new_connect_node_select->select_from_base_type(type_string, base_script);
|
||||
} else {
|
||||
new_connect_node_select->select_from_base_type(n->get_base_type());
|
||||
new_connect_node_select->select_from_base_type(n->get_base_type(), base_script);
|
||||
}
|
||||
} else if (tg.type == Variant::NIL) {
|
||||
new_connect_node_select->select_from_base_type("");
|
||||
new_connect_node_select->select_from_base_type("", base_script);
|
||||
} else {
|
||||
new_connect_node_select->select_from_basic_type(tg.type);
|
||||
}
|
||||
|
@ -3309,66 +3324,54 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua
|
|||
}
|
||||
|
||||
void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) {
|
||||
#ifdef OSX_ENABLED
|
||||
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META);
|
||||
#else
|
||||
bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL);
|
||||
#endif
|
||||
Vector2 pos = _get_pos_in_graph(port_action_pos);
|
||||
|
||||
Set<int> vn;
|
||||
bool port_node_exists = true;
|
||||
|
||||
if (drop_position != Vector2()) {
|
||||
pos = drop_position;
|
||||
}
|
||||
drop_position = Vector2();
|
||||
|
||||
bool port_node_exists = true;
|
||||
Ref<VisualScriptNode> vnode;
|
||||
Ref<VisualScriptNode> vnode_old;
|
||||
if (port_node_exists && p_connecting) {
|
||||
vnode_old = script->get_node(port_action_node);
|
||||
}
|
||||
|
||||
// if (func == StringName()) {
|
||||
// func = default_func;
|
||||
// port_node_exists = false;
|
||||
// }
|
||||
if (p_category.begins_with("VisualScriptNode")) {
|
||||
Ref<VisualScriptNode> n = VisualScriptLanguage::singleton->create_node_from_name(p_text);
|
||||
|
||||
if (p_category == "visualscript") {
|
||||
Ref<VisualScriptNode> vnode_new = VisualScriptLanguage::singleton->create_node_from_name(p_text);
|
||||
Ref<VisualScriptNode> vnode_old;
|
||||
if (port_node_exists && p_connecting) {
|
||||
vnode_old = script->get_node(port_action_node);
|
||||
}
|
||||
int new_id = script->get_available_id();
|
||||
|
||||
if (Object::cast_to<VisualScriptOperator>(vnode_new.ptr()) && vnode_old.is_valid()) {
|
||||
Variant::Type type = vnode_old->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()) && vnode_old.is_valid()) {
|
||||
if (Object::cast_to<VisualScriptTypeCast>(n.ptr()) && vnode_old.is_valid()) {
|
||||
Variant::Type type = vnode_old->get_output_value_port_info(port_action_output).type;
|
||||
String hint_name = vnode_old->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);
|
||||
Object::cast_to<VisualScriptTypeCast>(n.ptr())->set_base_type(hint_name);
|
||||
} else if (type == Variant::NIL) {
|
||||
Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())->set_base_type("");
|
||||
Object::cast_to<VisualScriptTypeCast>(n.ptr())->set_base_type("");
|
||||
} else {
|
||||
Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())->set_base_type(Variant::get_type_name(type));
|
||||
Object::cast_to<VisualScriptTypeCast>(n.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", new_id, vnode_new, pos);
|
||||
if (vnode_old.is_valid() && p_connecting) {
|
||||
connect_seq(vnode_old, vnode_new, new_id);
|
||||
connect_data(vnode_old, vnode_new, new_id);
|
||||
}
|
||||
|
||||
undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
|
||||
undo_redo->add_do_method(this, "_update_graph");
|
||||
undo_redo->add_undo_method(this, "_update_graph");
|
||||
undo_redo->commit_action();
|
||||
return;
|
||||
vnode = n;
|
||||
}
|
||||
|
||||
Ref<VisualScriptNode> vnode;
|
||||
Ref<VisualScriptPropertySet> script_prop_set;
|
||||
|
||||
if (p_category == String("method")) {
|
||||
if (p_category == String("Class") && !p_connecting) {
|
||||
Ref<VisualScriptFunctionCall> n;
|
||||
n.instantiate();
|
||||
n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SINGLETON);
|
||||
n->set_singleton("ClassDB");
|
||||
n->set_function("instantiate");
|
||||
// Did not find a way to edit the input port value
|
||||
vnode = n;
|
||||
} else if (p_category == String("class_method")) {
|
||||
Ref<VisualScriptFunctionCall> n;
|
||||
n.instantiate();
|
||||
if (!drop_path.is_empty()) {
|
||||
|
@ -3386,96 +3389,151 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
|
|||
}
|
||||
}
|
||||
vnode = n;
|
||||
} else if (p_category == String("set")) {
|
||||
Ref<VisualScriptPropertySet> n;
|
||||
} else if (p_category == String("class_property")) {
|
||||
Vector<String> property_path = p_text.split(":");
|
||||
if (held_ctrl) {
|
||||
Ref<VisualScriptPropertySet> n;
|
||||
n.instantiate();
|
||||
n->set_property(property_path[1]);
|
||||
if (!drop_path.is_empty()) {
|
||||
if (drop_path == ".") {
|
||||
n->set_call_mode(VisualScriptPropertySet::CALL_MODE_SELF);
|
||||
} else {
|
||||
n->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH);
|
||||
n->set_base_path(drop_path);
|
||||
}
|
||||
}
|
||||
if (drop_node) {
|
||||
n->set_base_type(drop_node->get_class());
|
||||
if (drop_node->get_script_instance()) {
|
||||
n->set_base_script(drop_node->get_script_instance()->get_script()->get_path());
|
||||
}
|
||||
}
|
||||
vnode = n;
|
||||
} else {
|
||||
Ref<VisualScriptPropertyGet> n;
|
||||
n.instantiate();
|
||||
n->set_property(property_path[1]);
|
||||
if (!drop_path.is_empty()) {
|
||||
if (drop_path == ".") {
|
||||
n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_SELF);
|
||||
} else {
|
||||
n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH);
|
||||
n->set_base_path(drop_path);
|
||||
}
|
||||
}
|
||||
if (drop_node) {
|
||||
n->set_base_type(drop_node->get_class());
|
||||
if (drop_node->get_script_instance()) {
|
||||
n->set_base_script(drop_node->get_script_instance()->get_script()->get_path());
|
||||
}
|
||||
}
|
||||
vnode = n;
|
||||
}
|
||||
} else if (p_category == String("class_constant")) {
|
||||
Vector<String> property_path = p_text.split(":");
|
||||
if (ClassDB::class_exists(property_path[0])) {
|
||||
Ref<VisualScriptClassConstant> n;
|
||||
n.instantiate();
|
||||
n->set_base_type(property_path[0]);
|
||||
n->set_class_constant(property_path[1]);
|
||||
vnode = n;
|
||||
} else {
|
||||
Ref<VisualScriptBasicTypeConstant> n;
|
||||
n.instantiate();
|
||||
if (property_path[0] == "Nil") {
|
||||
n->set_basic_type(Variant::NIL);
|
||||
} else if (property_path[0] == "bool") {
|
||||
n->set_basic_type(Variant::BOOL);
|
||||
} else if (property_path[0] == "int") {
|
||||
n->set_basic_type(Variant::INT);
|
||||
} else if (property_path[0] == "float") {
|
||||
n->set_basic_type(Variant::FLOAT);
|
||||
} else if (property_path[0] == "String") {
|
||||
n->set_basic_type(Variant::STRING);
|
||||
} else if (property_path[0] == "Vector2") {
|
||||
n->set_basic_type(Variant::VECTOR2);
|
||||
} else if (property_path[0] == "Vector2i") {
|
||||
n->set_basic_type(Variant::VECTOR2I);
|
||||
} else if (property_path[0] == "Rect2") {
|
||||
n->set_basic_type(Variant::RECT2);
|
||||
} else if (property_path[0] == "Rect2i") {
|
||||
n->set_basic_type(Variant::RECT2I);
|
||||
} else if (property_path[0] == "Transform2D") {
|
||||
n->set_basic_type(Variant::TRANSFORM2D);
|
||||
} else if (property_path[0] == "Vector3") {
|
||||
n->set_basic_type(Variant::VECTOR3);
|
||||
} else if (property_path[0] == "Vector3i") {
|
||||
n->set_basic_type(Variant::VECTOR3I);
|
||||
} else if (property_path[0] == "Plane") {
|
||||
n->set_basic_type(Variant::PLANE);
|
||||
} else if (property_path[0] == "ABB") {
|
||||
n->set_basic_type(Variant::AABB);
|
||||
} else if (property_path[0] == "Quaternion") {
|
||||
n->set_basic_type(Variant::QUATERNION);
|
||||
} else if (property_path[0] == "Basis") {
|
||||
n->set_basic_type(Variant::BASIS);
|
||||
} else if (property_path[0] == "Transform3D") {
|
||||
n->set_basic_type(Variant::TRANSFORM3D);
|
||||
} else if (property_path[0] == "Color") {
|
||||
n->set_basic_type(Variant::COLOR);
|
||||
} else if (property_path[0] == "RID") {
|
||||
n->set_basic_type(Variant::RID);
|
||||
} else if (property_path[0] == "Object") {
|
||||
n->set_basic_type(Variant::OBJECT);
|
||||
} else if (property_path[0] == "Callable") {
|
||||
n->set_basic_type(Variant::CALLABLE);
|
||||
} else if (property_path[0] == "Signal") {
|
||||
n->set_basic_type(Variant::SIGNAL);
|
||||
} else if (property_path[0] == "StringName") {
|
||||
n->set_basic_type(Variant::STRING_NAME);
|
||||
} else if (property_path[0] == "NodePath") {
|
||||
n->set_basic_type(Variant::NODE_PATH);
|
||||
} else if (property_path[0] == "Dictionary") {
|
||||
n->set_basic_type(Variant::DICTIONARY);
|
||||
} else if (property_path[0] == "Array") {
|
||||
n->set_basic_type(Variant::ARRAY);
|
||||
} else if (property_path[0] == "PackedByteArray") {
|
||||
n->set_basic_type(Variant::PACKED_BYTE_ARRAY);
|
||||
} else if (property_path[0] == "PackedInt32Array") {
|
||||
n->set_basic_type(Variant::PACKED_INT32_ARRAY);
|
||||
} else if (property_path[0] == "PackedInt64Array") {
|
||||
n->set_basic_type(Variant::PACKED_INT64_ARRAY);
|
||||
} else if (property_path[0] == "PackedFloat32Array") {
|
||||
n->set_basic_type(Variant::PACKED_FLOAT32_ARRAY);
|
||||
} else if (property_path[0] == "PackedStringArray") {
|
||||
n->set_basic_type(Variant::PACKED_STRING_ARRAY);
|
||||
} else if (property_path[0] == "PackedVector2Array") {
|
||||
n->set_basic_type(Variant::PACKED_VECTOR2_ARRAY);
|
||||
} else if (property_path[0] == "PackedVector3Array") {
|
||||
n->set_basic_type(Variant::PACKED_VECTOR3_ARRAY);
|
||||
} else if (property_path[0] == "PackedColorArray") {
|
||||
n->set_basic_type(Variant::PACKED_COLOR_ARRAY);
|
||||
}
|
||||
n->set_basic_type_constant(property_path[1]);
|
||||
vnode = n;
|
||||
}
|
||||
|
||||
} else if (p_category == String("class_signal")) {
|
||||
Vector<String> property_path = p_text.split(":");
|
||||
ERR_FAIL_COND(!(script->has_custom_signal(property_path[1]) || ClassDB::has_signal(script->get_instance_base_type(), property_path[1])));
|
||||
|
||||
Ref<VisualScriptEmitSignal> n;
|
||||
n.instantiate();
|
||||
if (!drop_path.is_empty()) {
|
||||
if (drop_path == ".") {
|
||||
n->set_call_mode(VisualScriptPropertySet::CALL_MODE_SELF);
|
||||
} else {
|
||||
n->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH);
|
||||
n->set_base_path(drop_path);
|
||||
}
|
||||
}
|
||||
if (drop_node) {
|
||||
n->set_base_type(drop_node->get_class());
|
||||
if (drop_node->get_script_instance()) {
|
||||
n->set_base_script(drop_node->get_script_instance()->get_script()->get_path());
|
||||
}
|
||||
}
|
||||
vnode = n;
|
||||
script_prop_set = n;
|
||||
} else if (p_category == String("get")) {
|
||||
Ref<VisualScriptPropertyGet> n;
|
||||
n.instantiate();
|
||||
n->set_property(p_text);
|
||||
if (!drop_path.is_empty()) {
|
||||
if (drop_path == ".") {
|
||||
n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_SELF);
|
||||
} else {
|
||||
n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH);
|
||||
n->set_base_path(drop_path);
|
||||
}
|
||||
}
|
||||
if (drop_node) {
|
||||
n->set_base_type(drop_node->get_class());
|
||||
if (drop_node->get_script_instance()) {
|
||||
n->set_base_script(drop_node->get_script_instance()->get_script()->get_path());
|
||||
}
|
||||
}
|
||||
n->set_signal(property_path[1]);
|
||||
vnode = n;
|
||||
}
|
||||
drop_path = String();
|
||||
drop_node = nullptr;
|
||||
|
||||
if (p_category == String("action")) {
|
||||
if (p_text == "VisualScriptCondition") {
|
||||
Ref<VisualScriptCondition> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
}
|
||||
if (p_text == "VisualScriptSwitch") {
|
||||
Ref<VisualScriptSwitch> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
} else if (p_text == "VisualScriptSequence") {
|
||||
Ref<VisualScriptSequence> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
} else if (p_text == "VisualScriptIterator") {
|
||||
Ref<VisualScriptIterator> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
} else if (p_text == "VisualScriptWhile") {
|
||||
Ref<VisualScriptWhile> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
} else if (p_text == "VisualScriptReturn") {
|
||||
Ref<VisualScriptReturn> n;
|
||||
n.instantiate();
|
||||
vnode = n;
|
||||
}
|
||||
if (vnode == nullptr) {
|
||||
print_error("Category not handled: " + p_category.quote());
|
||||
}
|
||||
|
||||
int new_id = script->get_available_id();
|
||||
undo_redo->create_action(TTR("Add Node"));
|
||||
undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos);
|
||||
undo_redo->add_undo_method(script.ptr(), "remove_node", 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();
|
||||
if (Object::cast_to<VisualScriptFunctionCall>(vnode.ptr()) && p_category != "Class") {
|
||||
Vector<String> property_path = p_text.split(":");
|
||||
String class_of_method = property_path[0];
|
||||
String method_name = property_path[1];
|
||||
|
||||
if (script_prop_set.is_valid()) {
|
||||
script_prop_set->set_property(p_text);
|
||||
}
|
||||
|
||||
port_action_new_node = new_id;
|
||||
|
||||
Ref<VisualScriptNode> vsn = script->get_node(port_action_new_node);
|
||||
|
||||
if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) {
|
||||
Ref<VisualScriptFunctionCall> vsfc = vsn;
|
||||
vsfc->set_function(p_text);
|
||||
Ref<VisualScriptFunctionCall> vsfc = vnode;
|
||||
vsfc->set_function(method_name);
|
||||
|
||||
if (port_node_exists && p_connecting) {
|
||||
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
|
||||
|
@ -3492,7 +3550,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
|
|||
if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) {
|
||||
vsfc->set_base_type(base_type);
|
||||
}
|
||||
if (p_text == "call" || p_text == "call_deferred") {
|
||||
if (method_name == "call" || method_name == "call_deferred") {
|
||||
vsfc->set_function(String(""));
|
||||
}
|
||||
}
|
||||
|
@ -3510,8 +3568,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
|
|||
}
|
||||
|
||||
if (port_node_exists && p_connecting) {
|
||||
if (Object::cast_to<VisualScriptPropertySet>(vsn.ptr())) {
|
||||
Ref<VisualScriptPropertySet> vsp = vsn;
|
||||
if (Object::cast_to<VisualScriptPropertySet>(vnode.ptr())) {
|
||||
Ref<VisualScriptPropertySet> vsp = vnode;
|
||||
|
||||
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
|
||||
if (tg.type == Variant::OBJECT) {
|
||||
|
@ -3540,8 +3598,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
|
|||
}
|
||||
}
|
||||
|
||||
if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) {
|
||||
Ref<VisualScriptPropertyGet> vsp = vsn;
|
||||
if (Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())) {
|
||||
Ref<VisualScriptPropertyGet> vsp = vnode;
|
||||
|
||||
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
|
||||
if (tg.type == Variant::OBJECT) {
|
||||
|
@ -3569,13 +3627,85 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
|
|||
}
|
||||
}
|
||||
}
|
||||
if (vnode == nullptr) {
|
||||
print_error("Not able to create node from category: \"" + p_category + "\" and text \"" + p_text + "\" Not created");
|
||||
return;
|
||||
}
|
||||
|
||||
int new_id = script->get_available_id();
|
||||
undo_redo->create_action(TTR("Add Node"));
|
||||
undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos);
|
||||
undo_redo->add_undo_method(script.ptr(), "remove_node", 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;
|
||||
|
||||
String base_script = "";
|
||||
String base_type = "";
|
||||
if (port_node_exists) {
|
||||
Ref<VisualScriptNode> vnode_old = script->get_node(port_action_node);
|
||||
if (vnode_old.is_valid()) {
|
||||
if (Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())) {
|
||||
base_type = Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())->get_base_type();
|
||||
base_script = Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())->get_base_script();
|
||||
} else if (Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())) {
|
||||
base_type = Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())->get_base_type();
|
||||
base_script = Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())->get_base_script();
|
||||
} else if (Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())) {
|
||||
base_type = Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())->get_base_type();
|
||||
base_script = Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())->get_base_script();
|
||||
} else if (Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())) {
|
||||
base_type = Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())->get_base_type();
|
||||
base_script = Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())->get_base_script();
|
||||
}
|
||||
}
|
||||
|
||||
Vector<String> property_path = p_text.split(":");
|
||||
if (ClassDB::is_parent_class(script->get_instance_base_type(), property_path[0]) || script->get_path().ends_with(property_path[0].unquote())) {
|
||||
if (!p_connecting) {
|
||||
base_type = script->get_instance_base_type();
|
||||
base_script = script->get_path();
|
||||
}
|
||||
} else {
|
||||
base_type = property_path[0];
|
||||
base_script = "";
|
||||
}
|
||||
|
||||
if (drop_node) {
|
||||
Ref<Script> script = drop_node->get_script();
|
||||
if (script != nullptr) {
|
||||
base_script = script->get_path();
|
||||
}
|
||||
}
|
||||
|
||||
if (vnode_old.is_valid() && p_connecting) {
|
||||
if (base_type == "") {
|
||||
base_type = property_path[0];
|
||||
} else if (ClassDB::is_parent_class(property_path[0], base_type)) {
|
||||
base_type = property_path[0];
|
||||
}
|
||||
connect_seq(vnode_old, vnode, port_action_new_node);
|
||||
connect_data(vnode_old, vnode, port_action_new_node);
|
||||
}
|
||||
}
|
||||
if (Object::cast_to<VisualScriptTypeCast>(vnode.ptr())) {
|
||||
Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_type(base_type);
|
||||
Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_script(base_script);
|
||||
} else if (Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())) {
|
||||
Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_type(base_type);
|
||||
Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_script(base_script);
|
||||
} else if (Object::cast_to<VisualScriptPropertySet>(vnode.ptr())) {
|
||||
Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_type(base_type);
|
||||
Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_script(base_script);
|
||||
} else if (Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())) {
|
||||
Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())->set_base_type(base_type);
|
||||
Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())->set_base_script(base_script);
|
||||
}
|
||||
|
||||
drop_path = String();
|
||||
drop_node = nullptr;
|
||||
|
||||
_update_graph(port_action_new_node);
|
||||
}
|
||||
|
||||
|
@ -3625,7 +3755,7 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual
|
|||
}
|
||||
|
||||
void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting) {
|
||||
String name = p_text;
|
||||
String name = p_text.substr(p_text.find_char(':') + 1);
|
||||
if (script->has_function(name)) {
|
||||
EditorNode::get_singleton()->show_warning(vformat(TTR("Script already has function '%s'"), name));
|
||||
return;
|
||||
|
@ -3901,7 +4031,7 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_
|
|||
void VisualScriptEditor::_menu_option(int p_what) {
|
||||
switch (p_what) {
|
||||
case EDIT_ADD_NODE: {
|
||||
_generic_search(script->get_instance_base_type(), mouse_up_position);
|
||||
_generic_search();
|
||||
} break;
|
||||
case EDIT_DELETE_NODES: {
|
||||
_on_nodes_delete();
|
||||
|
@ -3931,7 +4061,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
|
|||
|
||||
} break;
|
||||
case EDIT_FIND_NODE_TYPE: {
|
||||
_generic_search(script->get_instance_base_type());
|
||||
_generic_search();
|
||||
} break;
|
||||
case EDIT_COPY_NODES: {
|
||||
_on_nodes_copy();
|
||||
|
|
|
@ -85,55 +85,55 @@ class VisualScriptEditor : public ScriptEditorBase {
|
|||
MEMBER_SIGNAL
|
||||
};
|
||||
|
||||
VBoxContainer *members_section;
|
||||
MenuButton *edit_menu;
|
||||
VBoxContainer *members_section = nullptr;
|
||||
MenuButton *edit_menu = nullptr;
|
||||
|
||||
Ref<VisualScript> script;
|
||||
|
||||
Button *base_type_select;
|
||||
Button *base_type_select = nullptr;
|
||||
|
||||
LineEdit *func_name_box;
|
||||
ScrollContainer *func_input_scroll;
|
||||
VBoxContainer *func_input_vbox;
|
||||
ConfirmationDialog *function_create_dialog;
|
||||
LineEdit *func_name_box = nullptr;
|
||||
ScrollContainer *func_input_scroll = nullptr;
|
||||
VBoxContainer *func_input_vbox = nullptr;
|
||||
ConfirmationDialog *function_create_dialog = nullptr;
|
||||
|
||||
GraphEdit *graph;
|
||||
HBoxContainer *status_bar;
|
||||
Button *toggle_scripts_button;
|
||||
GraphEdit *graph = nullptr;
|
||||
HBoxContainer *status_bar = nullptr;
|
||||
Button *toggle_scripts_button = nullptr;
|
||||
|
||||
VisualScriptEditorSignalEdit *signal_editor;
|
||||
VisualScriptEditorSignalEdit *signal_editor = nullptr;
|
||||
|
||||
AcceptDialog *edit_signal_dialog;
|
||||
EditorInspector *edit_signal_edit;
|
||||
AcceptDialog *edit_signal_dialog = nullptr;
|
||||
EditorInspector *edit_signal_edit = nullptr;
|
||||
|
||||
VisualScriptPropertySelector *method_select;
|
||||
VisualScriptPropertySelector *new_connect_node_select;
|
||||
VisualScriptPropertySelector *new_virtual_method_select;
|
||||
VisualScriptPropertySelector *method_select = nullptr;
|
||||
VisualScriptPropertySelector *new_connect_node_select = nullptr;
|
||||
VisualScriptPropertySelector *new_virtual_method_select = nullptr;
|
||||
|
||||
VisualScriptEditorVariableEdit *variable_editor;
|
||||
VisualScriptEditorVariableEdit *variable_editor = nullptr;
|
||||
|
||||
AcceptDialog *edit_variable_dialog;
|
||||
EditorInspector *edit_variable_edit;
|
||||
AcceptDialog *edit_variable_dialog = nullptr;
|
||||
EditorInspector *edit_variable_edit = nullptr;
|
||||
|
||||
CustomPropertyEditor *default_value_edit;
|
||||
CustomPropertyEditor *default_value_edit = nullptr;
|
||||
|
||||
UndoRedo *undo_redo;
|
||||
UndoRedo *undo_redo = nullptr;
|
||||
|
||||
Tree *members;
|
||||
AcceptDialog *function_name_edit;
|
||||
LineEdit *function_name_box;
|
||||
Tree *members = nullptr;
|
||||
AcceptDialog *function_name_edit = nullptr;
|
||||
LineEdit *function_name_box = nullptr;
|
||||
|
||||
Label *hint_text;
|
||||
Timer *hint_text_timer;
|
||||
Label *hint_text = nullptr;
|
||||
Timer *hint_text_timer = nullptr;
|
||||
|
||||
Label *select_func_text;
|
||||
Label *select_func_text = nullptr;
|
||||
|
||||
bool updating_graph = false;
|
||||
|
||||
void _show_hint(const String &p_hint);
|
||||
void _hide_timer();
|
||||
|
||||
CreateDialog *select_base_type;
|
||||
CreateDialog *select_base_type = nullptr;
|
||||
|
||||
struct VirtualInMenu {
|
||||
String name;
|
||||
|
@ -241,7 +241,7 @@ class VisualScriptEditor : public ScriptEditorBase {
|
|||
|
||||
bool node_has_sequence_connections(int p_id);
|
||||
|
||||
void _generic_search(String p_base_type = "", Vector2 pos = Vector2(), bool node_centered = false);
|
||||
void _generic_search(Vector2 pos = Vector2(), bool node_centered = false);
|
||||
|
||||
virtual void input(const Ref<InputEvent> &p_event) override;
|
||||
void _graph_gui_input(const Ref<InputEvent> &p_event);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,7 @@
|
|||
#ifndef VISUALSCRIPT_PROPERTYSELECTOR_H
|
||||
#define VISUALSCRIPT_PROPERTYSELECTOR_H
|
||||
|
||||
#include "../visual_script.h"
|
||||
#include "editor/editor_help.h"
|
||||
#include "editor/property_editor.h"
|
||||
#include "scene/gui/rich_text_label.h"
|
||||
|
@ -38,15 +39,56 @@
|
|||
class VisualScriptPropertySelector : public ConfirmationDialog {
|
||||
GDCLASS(VisualScriptPropertySelector, ConfirmationDialog);
|
||||
|
||||
enum SearchFlags {
|
||||
SEARCH_CLASSES = 1 << 0,
|
||||
SEARCH_CONSTRUCTORS = 1 << 1,
|
||||
SEARCH_METHODS = 1 << 2,
|
||||
SEARCH_OPERATORS = 1 << 3,
|
||||
SEARCH_SIGNALS = 1 << 4,
|
||||
SEARCH_CONSTANTS = 1 << 5,
|
||||
SEARCH_PROPERTIES = 1 << 6,
|
||||
SEARCH_THEME_ITEMS = 1 << 7,
|
||||
SEARCH_VISUAL_SCRIPT_NODES = 1 << 8,
|
||||
SEARCH_ALL = SEARCH_CLASSES | SEARCH_CONSTRUCTORS | SEARCH_METHODS | SEARCH_OPERATORS | SEARCH_SIGNALS | SEARCH_CONSTANTS | SEARCH_PROPERTIES | SEARCH_THEME_ITEMS,
|
||||
SEARCH_CASE_SENSITIVE = 1 << 29,
|
||||
SEARCH_SHOW_HIERARCHY = 1 << 30,
|
||||
};
|
||||
|
||||
enum ScopeFlags {
|
||||
SCOPE_BASE = 1 << 0,
|
||||
SCOPE_INHERITERS = 1 << 1,
|
||||
SCOPE_UNRELATED = 1 << 2,
|
||||
SCOPE_RELATED = SCOPE_BASE | SCOPE_INHERITERS,
|
||||
SCOPE_ALL = SCOPE_BASE | SCOPE_INHERITERS | SCOPE_UNRELATED
|
||||
};
|
||||
|
||||
LineEdit *search_box;
|
||||
Tree *search_options;
|
||||
|
||||
void _text_changed(const String &p_newtext);
|
||||
Button *case_sensitive_button;
|
||||
Button *hierarchy_button;
|
||||
|
||||
Button *search_visual_script_nodes;
|
||||
Button *search_classes;
|
||||
Button *search_operators;
|
||||
|
||||
Button *search_methods;
|
||||
Button *search_signals;
|
||||
Button *search_constants;
|
||||
Button *search_properties;
|
||||
Button *search_theme_items;
|
||||
|
||||
OptionButton *scope_combo;
|
||||
Tree *results_tree;
|
||||
|
||||
class SearchRunner;
|
||||
Ref<SearchRunner> search_runner;
|
||||
|
||||
void _update_icons();
|
||||
|
||||
void _sbox_input(const Ref<InputEvent> &p_ie);
|
||||
void _update_search();
|
||||
|
||||
void create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text);
|
||||
void get_visual_node_names(const String &root_filter, const Set<String> &p_modifiers, bool &found, TreeItem *const root, LineEdit *const search_box);
|
||||
void _update_results_i(int p_int);
|
||||
void _update_results_s(String p_string);
|
||||
void _update_results();
|
||||
|
||||
void _confirmed();
|
||||
void _item_selected();
|
||||
|
@ -60,32 +102,118 @@ class VisualScriptPropertySelector : public ConfirmationDialog {
|
|||
String selected;
|
||||
Variant::Type type;
|
||||
String base_type;
|
||||
String base_script;
|
||||
ObjectID script;
|
||||
Object *instance;
|
||||
bool virtuals_only;
|
||||
bool seq_connect;
|
||||
VBoxContainer *vbc;
|
||||
|
||||
Vector<Variant::Type> type_filter;
|
||||
VBoxContainer *vbox;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void select_method_from_base_type(const String &p_base, const String &p_current = "", const bool p_virtuals_only = false, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false, bool p_seq_connect = false, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_script(const Ref<Script> &p_script, const String &p_current = "", const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_basic_type(Variant::Type p_type, const String &p_current = "", const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_action(const String &p_type, const String &p_current = "", const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_instance(Object *p_instance, const String &p_current = "", const bool p_connecting = true, const String &p_basetype = "", bool clear_text = true);
|
||||
void select_from_visual_script(const String &p_base, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_method_from_base_type(const String &p_base, const bool p_virtuals_only = false, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_base_type(const String &p_base, const String &p_base_script = "", bool p_virtuals_only = false, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_script(const Ref<Script> &p_script, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_basic_type(Variant::Type p_type, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_action(const String &p_type, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_instance(Object *p_instance, const bool p_connecting = true, bool clear_text = true);
|
||||
void select_from_visual_script(const Ref<Script> &p_script, bool clear_text = true);
|
||||
|
||||
void show_window(float p_screen_ratio);
|
||||
|
||||
void set_type_filter(const Vector<Variant::Type> &p_type_filter);
|
||||
|
||||
VisualScriptPropertySelector();
|
||||
};
|
||||
|
||||
class VisualScriptPropertySelector::SearchRunner : public RefCounted {
|
||||
enum Phase {
|
||||
PHASE_INIT,
|
||||
PHASE_MATCH_CLASSES_INIT,
|
||||
PHASE_NODE_CLASSES_INIT,
|
||||
PHASE_NODE_CLASSES_BUILD,
|
||||
PHASE_MATCH_CLASSES,
|
||||
PHASE_CLASS_ITEMS_INIT,
|
||||
PHASE_CLASS_ITEMS,
|
||||
PHASE_MEMBER_ITEMS_INIT,
|
||||
PHASE_MEMBER_ITEMS,
|
||||
PHASE_SELECT_MATCH,
|
||||
PHASE_MAX
|
||||
};
|
||||
int phase = 0;
|
||||
|
||||
struct ClassMatch {
|
||||
DocData::ClassDoc *doc;
|
||||
bool name = false;
|
||||
String category = "";
|
||||
Vector<DocData::MethodDoc *> constructors;
|
||||
Vector<DocData::MethodDoc *> methods;
|
||||
Vector<DocData::MethodDoc *> operators;
|
||||
Vector<DocData::MethodDoc *> signals;
|
||||
Vector<DocData::ConstantDoc *> constants;
|
||||
Vector<DocData::PropertyDoc *> properties;
|
||||
Vector<DocData::ThemeItemDoc *> theme_properties;
|
||||
|
||||
bool required() {
|
||||
return name || methods.size() || signals.size() || constants.size() || properties.size() || theme_properties.size();
|
||||
}
|
||||
};
|
||||
|
||||
VisualScriptPropertySelector *selector_ui;
|
||||
Control *ui_service;
|
||||
Tree *results_tree;
|
||||
String term;
|
||||
int search_flags;
|
||||
int scope_flags;
|
||||
|
||||
Ref<Texture2D> empty_icon;
|
||||
Color disabled_color;
|
||||
|
||||
Map<String, DocData::ClassDoc>::Element *iterator_doc = nullptr;
|
||||
Map<String, ClassMatch> matches;
|
||||
Map<String, ClassMatch>::Element *iterator_match = nullptr;
|
||||
TreeItem *root_item = nullptr;
|
||||
Map<String, TreeItem *> class_items;
|
||||
TreeItem *matched_item = nullptr;
|
||||
float match_highest_score = 0;
|
||||
|
||||
Map<String, DocData::ClassDoc> combined_docs;
|
||||
List<String> vs_nodes;
|
||||
|
||||
bool _is_class_disabled_by_feature_profile(const StringName &p_class);
|
||||
bool _is_class_disabled_by_scope(const StringName &p_class);
|
||||
|
||||
bool _slice();
|
||||
bool _phase_init();
|
||||
bool _phase_match_classes_init();
|
||||
bool _phase_node_classes_init();
|
||||
bool _phase_node_classes_build();
|
||||
bool _phase_match_classes();
|
||||
bool _phase_class_items_init();
|
||||
bool _phase_class_items();
|
||||
bool _phase_member_items_init();
|
||||
bool _phase_member_items();
|
||||
bool _phase_select_match();
|
||||
|
||||
bool _match_string(const String &p_term, const String &p_string) const;
|
||||
bool _match_visual_script(DocData::ClassDoc &class_doc);
|
||||
bool _match_is_hidden(DocData::ClassDoc &class_doc);
|
||||
void _match_item(TreeItem *p_item, const String &p_text);
|
||||
void _add_class_doc(String class_name, String inherits, String category);
|
||||
DocData::MethodDoc _get_method_doc(MethodInfo method_info);
|
||||
TreeItem *_create_class_hierarchy(const ClassMatch &p_match);
|
||||
TreeItem *_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray);
|
||||
TreeItem *_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const String &p_text, const DocData::MethodDoc *p_doc);
|
||||
TreeItem *_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc);
|
||||
TreeItem *_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc);
|
||||
TreeItem *_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc);
|
||||
TreeItem *_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ThemeItemDoc *p_doc);
|
||||
TreeItem *_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_text, const String &p_type, const String &p_metatype, const String &p_tooltip, const String &p_description);
|
||||
|
||||
public:
|
||||
bool work(uint64_t slot = 100000);
|
||||
|
||||
SearchRunner(VisualScriptPropertySelector *p_selector_ui, Tree *p_results_tree);
|
||||
};
|
||||
|
||||
#endif // VISUALSCRIPT_PROPERTYSELECTOR_H
|
||||
|
|
Loading…
Reference in New Issue