From ad8f208bdbcd9d3334c4d57d2e5554dfdb3a36d0 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 23 Aug 2016 19:29:07 -0300 Subject: [PATCH] Proper function/property selection in visual script editing for property. This one has an ordered list, built-in description, search, etc. --- core/object.h | 8 + core/script_language.h | 1 + modules/gdscript/gd_script.cpp | 35 + modules/gdscript/gd_script.h | 3 + modules/visual_script/register_types.cpp | 2 +- modules/visual_script/visual_script.cpp | 13 +- modules/visual_script/visual_script.h | 3 +- .../visual_script/visual_script_editor.cpp | 13 +- modules/visual_script/visual_script_editor.h | 4 + .../visual_script_func_nodes.cpp | 662 ++---------------- .../visual_script/visual_script_func_nodes.h | 68 -- .../visual_script_yield_nodes.cpp | 2 +- scene/gui/graph_edit.cpp | 6 + tools/editor/property_editor.cpp | 138 ++++ tools/editor/property_editor.h | 4 + tools/editor/property_selector.cpp | 609 ++++++++++++++++ tools/editor/property_selector.h | 54 ++ 17 files changed, 949 insertions(+), 676 deletions(-) create mode 100644 tools/editor/property_selector.cpp create mode 100644 tools/editor/property_selector.h diff --git a/core/object.h b/core/object.h index 400ab3070ed..6ea794ec71b 100644 --- a/core/object.h +++ b/core/object.h @@ -70,6 +70,14 @@ enum PropertyHint { PROPERTY_HINT_OBJECT_ID, PROPERTY_HINT_TYPE_STRING, ///< a type string, the hint is the base type to choose PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE, ///< so something else can provide this (used in scripts) + PROPERTY_HINT_METHOD_OF_VARIANT_TYPE, ///< a method of a type + PROPERTY_HINT_METHOD_OF_BASE_TYPE, ///< a method of a base type + PROPERTY_HINT_METHOD_OF_INSTANCE, ///< a method of an instance + PROPERTY_HINT_METHOD_OF_SCRIPT, ///< a method of a script & base + PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE, ///< a property of a type + PROPERTY_HINT_PROPERTY_OF_BASE_TYPE, ///< a property of a base type + PROPERTY_HINT_PROPERTY_OF_INSTANCE, ///< a property of an instance + PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base PROPERTY_HINT_MAX, }; diff --git a/core/script_language.h b/core/script_language.h index aac94bb067b..36ed11efec8 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -114,6 +114,7 @@ public: virtual void update_exports() {} //editor tool virtual void get_script_method_list(List *p_list) const=0; + virtual void get_script_property_list(List *p_list) const=0; Script() {} diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 144fbe26269..13fbfb6ec09 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -267,6 +267,41 @@ void GDScript::get_script_method_list(List *p_list) const { } } +void GDScript::get_script_property_list(List *p_list) const { + + const GDScript *sptr=this; + List props; + + while(sptr) { + + Vector<_GDScriptMemberSort> msort; + for(Map::Element *E=sptr->member_info.front();E;E=E->next()) { + + _GDScriptMemberSort ms; + ERR_CONTINUE(!sptr->member_indices.has(E->key())); + ms.index=sptr->member_indices[E->key()].index; + ms.name=E->key(); + msort.push_back(ms); + + } + + msort.sort(); + msort.invert(); + for(int i=0;imember_info[msort[i].name]); + + } + + sptr = sptr->_base; + } + + for (List::Element *E=props.front();E;E=E->next()) { + p_list->push_back(E->get()); + } + +} + bool GDScript::has_method(const StringName& p_method) const { return member_functions.has(p_method); diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 8ec11c1e3ea..856211b2fd4 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -186,6 +186,9 @@ public: virtual bool has_method(const StringName& p_method) const; virtual MethodInfo get_method_info(const StringName& p_method) const; + virtual void get_script_property_list(List *p_list) const; + + virtual ScriptLanguage *get_language() const; GDScript(); diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index 1360e546f32..6e60b6a3143 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -66,7 +66,7 @@ void register_visual_script_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); - ObjectTypeDB::register_type(); +// ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 469ceaac206..82e538d7813 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -656,7 +656,7 @@ Dictionary VisualScript::_get_variable_info(const StringName& p_name) const{ return d; } -void VisualScript::get_variable_list(List *r_variables){ +void VisualScript::get_variable_list(List *r_variables) const{ for (Map::Element *E=variables.front();E;E=E->next()) { @@ -1045,6 +1045,17 @@ MethodInfo VisualScript::get_method_info(const StringName& p_method) const{ return mi; } +void VisualScript::get_script_property_list(List *p_list) const { + + List vars; + get_variable_list(&vars); + + for (List::Element *E=vars.front();E;E=E->next()) { + + p_list->push_back(variables[E->get()].info); + } +} + void VisualScript::_set_data(const Dictionary& p_data) { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 398df95664d..bad50c1cc85 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -275,7 +275,7 @@ public: Variant get_variable_default_value(const StringName& p_name) const; void set_variable_info(const StringName& p_name,const PropertyInfo& p_info); PropertyInfo get_variable_info(const StringName& p_name) const; - void get_variable_list(List *r_variables); + void get_variable_list(List *r_variables) const; void rename_variable(const StringName& p_name,const StringName& p_new_name); @@ -325,6 +325,7 @@ public: virtual bool has_method(const StringName& p_method) const; virtual MethodInfo get_method_info(const StringName& p_method) const; + virtual void get_script_property_list(List *p_list) const; VisualScript(); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 412865fbfe7..3424395d3f9 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -438,6 +438,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->set_modulate(EditorSettings::get_singleton()->get("visual_script_editor/color_"+node->get_category())); } + + gnode->set_meta("__vnode",node); gnode->set_name(itos(E->get())); gnode->connect("dragged",this,"_node_moved",varray(E->get())); @@ -1530,7 +1532,7 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat } ofs/=EDSCALE; - +#if 0 Ref vnode; vnode.instance(); vnode->set_call_mode(VisualScriptScriptCall::CALL_MODE_SELF); @@ -1550,6 +1552,7 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat graph->set_selected(node); _node_selected(node); } +#endif } @@ -2251,6 +2254,11 @@ void VisualScriptEditor::_graph_disconnected(const String& p_from,int p_from_slo } +void VisualScriptEditor::_graph_connect_to_empty(const String& p_from,int p_from_slot,const Vector2& p_release_pos) { + + +} + void VisualScriptEditor::_default_value_changed() { @@ -2410,6 +2418,8 @@ void VisualScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_graph_connected",&VisualScriptEditor::_graph_connected); ObjectTypeDB::bind_method("_graph_disconnected",&VisualScriptEditor::_graph_disconnected); + ObjectTypeDB::bind_method("_graph_connect_to_empty",&VisualScriptEditor::_graph_connect_to_empty); + ObjectTypeDB::bind_method("_update_graph_connections",&VisualScriptEditor::_update_graph_connections); ObjectTypeDB::bind_method("_node_filter_changed",&VisualScriptEditor::_node_filter_changed); @@ -2532,6 +2542,7 @@ VisualScriptEditor::VisualScriptEditor() { graph->connect("connection_request",this,"_graph_connected"); graph->connect("disconnection_request",this,"_graph_disconnected"); + graph->connect("connection_to_empty",this,"_graph_connect_to_empty"); edit_signal_dialog = memnew( AcceptDialog ); edit_signal_dialog->get_ok()->set_text(TTR("Close")); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 252519913d0..1ce7e5a6c7e 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -119,6 +119,8 @@ class VisualScriptEditor : public ScriptEditorBase { void _remove_node(int p_id); void _graph_connected(const String& p_from,int p_from_slot,const String& p_to,int p_to_slot); void _graph_disconnected(const String& p_from,int p_from_slot,const String& p_to,int p_to_slot); + void _graph_connect_to_empty(const String& p_from,int p_from_slot,const Vector2& p_release_pos); + void _node_ports_changed(const String& p_func,int p_id); void _available_node_doubleclicked(); @@ -147,6 +149,8 @@ class VisualScriptEditor : public ScriptEditorBase { void _menu_option(int p_what); void _graph_ofs_changed(const Vector2& p_ofs); + + protected: void _notification(int p_what); diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 14bc0bc8288..12bc3954744 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -372,48 +372,30 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo& property) const } if (property.name=="function/function") { - property.hint=PROPERTY_HINT_ENUM; - - - List methods; if (call_mode==CALL_MODE_BASIC_TYPE) { - if (basic_type==Variant::NIL) { - property.usage=0; - return; //nothing for nil + property.hint=PROPERTY_HINT_METHOD_OF_VARIANT_TYPE; + property.hint_string=Variant::get_type_name(basic_type); + + } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) { + property.hint=PROPERTY_HINT_METHOD_OF_SCRIPT; + property.hint_string=itos(get_visual_script()->get_instance_ID()); + } else if (call_mode==CALL_MODE_INSTANCE) { + property.hint=PROPERTY_HINT_METHOD_OF_BASE_TYPE; + property.hint_string=base_type; + } else if (call_mode==CALL_MODE_NODE_PATH) { + Node *node = _get_base_node(); + if (node) { + property.hint=PROPERTY_HINT_METHOD_OF_INSTANCE; + property.hint_string=itos(node->get_instance_ID()); + } else { + property.hint=PROPERTY_HINT_METHOD_OF_BASE_TYPE; + property.hint_string=get_base_type(); } - Variant::CallError ce; - Variant v = Variant::construct(basic_type,NULL,0,ce); - v.get_method_list(&methods); - - - } else { - - StringName base = _get_base_type(); - ObjectTypeDB::get_method_list(base,&methods); - } - List mstring; - for (List::Element *E=methods.front();E;E=E->next()) { - if (E->get().name.begins_with("_")) - continue; - mstring.push_back(E->get().name.get_slice(":",0)); - } - - mstring.sort(); - - String ml; - for (List::Element *E=mstring.front();E;E=E->next()) { - - if (ml!=String()) - ml+=","; - ml+=E->get(); - } - - property.hint_string=ml; } if (property.name=="function/use_default_args") { @@ -472,7 +454,7 @@ void VisualScriptFunctionCall::_bind_methods() { bt+=Variant::get_type_name(Variant::Type(i)); } - ADD_PROPERTY(PropertyInfo(Variant::INT,"function/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"function/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type"),_SCS("set_call_mode"),_SCS("get_call_mode")); ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type")); ADD_PROPERTY(PropertyInfo(Variant::INT,"function/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type")); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"function/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path")); @@ -577,7 +559,7 @@ VisualScriptNodeInstance* VisualScriptFunctionCall::instance(VisualScriptInstanc } VisualScriptFunctionCall::VisualScriptFunctionCall() { - call_mode=CALL_MODE_INSTANCE; + call_mode=CALL_MODE_SELF; basic_type=Variant::NIL; use_default_args=0; base_type="Object"; @@ -978,61 +960,30 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const { } if (property.name=="property/property") { - property.hint=PROPERTY_HINT_ENUM; - - - List pinfo; - if (call_mode==CALL_MODE_BASIC_TYPE) { - Variant::CallError ce; - Variant v; - if (basic_type==Variant::INPUT_EVENT) { - InputEvent ev; - ev.type=event_type; - v=ev; - } else { - v = Variant::construct(basic_type,NULL,0,ce); - } - v.get_property_list(&pinfo); + property.hint=PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE; + property.hint_string=Variant::get_type_name(basic_type); + + } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) { + property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT; + property.hint_string=itos(get_visual_script()->get_instance_ID()); + } else if (call_mode==CALL_MODE_INSTANCE) { + property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; + property.hint_string=base_type; } else if (call_mode==CALL_MODE_NODE_PATH) { - - Node *n = _get_base_node(); - if (n) { - n->get_property_list(&pinfo); + Node *node = _get_base_node(); + if (node) { + property.hint=PROPERTY_HINT_PROPERTY_OF_INSTANCE; + property.hint_string=itos(node->get_instance_ID()); } else { - ObjectTypeDB::get_property_list(_get_base_type(),&pinfo); + property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; + property.hint_string=get_base_type(); } - } else { - - - ObjectTypeDB::get_property_list(_get_base_type(),&pinfo); } - List mstring; - - for (List::Element *E=pinfo.front();E;E=E->next()) { - - if (E->get().usage&PROPERTY_USAGE_EDITOR) { - mstring.push_back(E->get().name); - } - } - - String ml; - for (List::Element *E=mstring.front();E;E=E->next()) { - - if (ml!=String()) - ml+=","; - ml+=E->get(); - } - - if (ml==String()) { - property.usage=PROPERTY_USAGE_NOEDITOR; //do not show for editing if empty - } else { - property.hint_string=ml; - } } if (property.name=="value/builtin") { @@ -1117,7 +1068,7 @@ void VisualScriptPropertySet::_bind_methods() { } - ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type"),_SCS("set_call_mode"),_SCS("get_call_mode")); ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type")); ADD_PROPERTY(PropertyInfo(Variant::INT,"property/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type")); ADD_PROPERTY(PropertyInfo(Variant::INT,"property/event_type",PROPERTY_HINT_ENUM,et),_SCS("set_event_type"),_SCS("get_event_type")); @@ -1250,7 +1201,7 @@ VisualScriptNodeInstance* VisualScriptPropertySet::instance(VisualScriptInstance VisualScriptPropertySet::VisualScriptPropertySet() { - call_mode=CALL_MODE_INSTANCE; + call_mode=CALL_MODE_SELF; base_type="Object"; basic_type=Variant::NIL; event_type=InputEvent::NONE; @@ -1586,55 +1537,28 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const { } if (property.name=="property/property") { - property.hint=PROPERTY_HINT_ENUM; - - - List pinfo; if (call_mode==CALL_MODE_BASIC_TYPE) { - Variant::CallError ce; - Variant v; - if (basic_type==Variant::INPUT_EVENT) { - InputEvent ev; - ev.type=event_type; - v=ev; - } else { - v = Variant::construct(basic_type,NULL,0,ce); - } - v.get_property_list(&pinfo); + property.hint=PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE; + property.hint_string=Variant::get_type_name(basic_type); + + } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) { + property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT; + property.hint_string=itos(get_visual_script()->get_instance_ID()); + } else if (call_mode==CALL_MODE_INSTANCE) { + property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; + property.hint_string=base_type; } else if (call_mode==CALL_MODE_NODE_PATH) { - - Node *n = _get_base_node(); - if (n) { - n->get_property_list(&pinfo); + Node *node = _get_base_node(); + if (node) { + property.hint=PROPERTY_HINT_PROPERTY_OF_INSTANCE; + property.hint_string=itos(node->get_instance_ID()); } else { - ObjectTypeDB::get_property_list(_get_base_type(),&pinfo); + property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; + property.hint_string=get_base_type(); } - } else { - ObjectTypeDB::get_property_list(_get_base_type(),&pinfo); - } - List mstring; - - for (List::Element *E=pinfo.front();E;E=E->next()) { - - if (E->get().usage&PROPERTY_USAGE_EDITOR) - mstring.push_back(E->get().name); - } - - String ml; - for (List::Element *E=mstring.front();E;E=E->next()) { - - if (ml!=String()) - ml+=","; - ml+=E->get(); - } - - if (ml==String()) { - property.usage=PROPERTY_USAGE_NOEDITOR; //do not show for editing if empty - } else { - property.hint_string=ml; } } @@ -1680,7 +1604,7 @@ void VisualScriptPropertyGet::_bind_methods() { } - ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance"),_SCS("set_call_mode"),_SCS("get_call_mode")); ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type")); ADD_PROPERTY(PropertyInfo(Variant::INT,"property/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type")); ADD_PROPERTY(PropertyInfo(Variant::INT,"property/event_type",PROPERTY_HINT_ENUM,et),_SCS("set_event_type"),_SCS("get_event_type")); @@ -1797,7 +1721,7 @@ VisualScriptNodeInstance* VisualScriptPropertyGet::instance(VisualScriptInstance VisualScriptPropertyGet::VisualScriptPropertyGet() { - call_mode=CALL_MODE_INSTANCE; + call_mode=CALL_MODE_SELF; base_type="Object"; basic_type=Variant::NIL; event_type=InputEvent::NONE; @@ -1814,463 +1738,6 @@ static Ref create_property_get_node(const String& p_name) { } -////////////////////////////////////////// -////////////////SCRIPT CALL////////////////////// -////////////////////////////////////////// - -int VisualScriptScriptCall::get_output_sequence_port_count() const { - - return 1; -} - -bool VisualScriptScriptCall::has_input_sequence_port() const{ - - return true; -} - -Node *VisualScriptScriptCall::_get_base_node() const { - -#ifdef TOOLS_ENABLED - Ref