From ea448cb779c9268f6213a8e741cfc793704ca2fe Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sat, 29 Aug 2015 21:09:11 -0300 Subject: [PATCH] Edit default values. WARNING!!! Do not merge these changes, default values are not compiled into shaders yet! --- core/object.h | 64 +- .../resources/default_theme/default_theme.cpp | 8 +- .../default_theme/graph_node_default.png | Bin 0 -> 289 bytes .../graph_node_default_focus.png | Bin 0 -> 408 bytes scene/resources/default_theme/theme_data.h | 10 + scene/resources/shader_graph.cpp | 150 +++-- scene/resources/shader_graph.h | 9 +- .../plugins/shader_graph_editor_plugin.cpp | 437 ++++++++++++-- .../plugins/shader_graph_editor_plugin.h | 6 + tools/editor/property_editor.cpp | 561 ++++++++++-------- tools/editor/property_editor.h | 46 +- 11 files changed, 890 insertions(+), 401 deletions(-) create mode 100644 scene/resources/default_theme/graph_node_default.png create mode 100644 scene/resources/default_theme/graph_node_default_focus.png diff --git a/core/object.h b/core/object.h index eb0e78a8c3d..981a83958cb 100644 --- a/core/object.h +++ b/core/object.h @@ -49,7 +49,7 @@ enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. - PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step" + PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step,slider; //slider is optional" PROPERTY_HINT_EXP_RANGE, ///< hint_text = "min,max,step", exponential edit PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease) @@ -58,12 +58,12 @@ enum PropertyHint { PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_ALL_FLAGS, - PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," + PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_DIR, ///< a directort path must be passed PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type - PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines + PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, @@ -71,7 +71,7 @@ enum PropertyHint { }; enum PropertyUsageFlags { - + PROPERTY_USAGE_STORAGE=1, PROPERTY_USAGE_EDITOR=2, PROPERTY_USAGE_NETWORK=4, @@ -102,15 +102,15 @@ enum PropertyUsageFlags { #define ADD_PROPERTYINO( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter, m_index ) struct PropertyInfo { - - Variant::Type type; + + Variant::Type type; String name; PropertyHint hint; - String hint_string; + String hint_string; uint32_t usage; _FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const { PropertyInfo pi=*this; pi.usage|=p_fl; return pi; } - + PropertyInfo() { type=Variant::NIL; hint=PROPERTY_HINT_NONE; usage = PROPERTY_USAGE_DEFAULT; } PropertyInfo( Variant::Type p_type, const String p_name, PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_string="",uint32_t p_usage=PROPERTY_USAGE_DEFAULT) { type=p_type; name=p_name; hint=p_hint; hint_string=p_hint_string; usage=p_usage; @@ -125,23 +125,23 @@ struct PropertyInfo { Array convert_property_list(const List * p_list); struct MethodInfo { - + String name; List arguments; Vector default_arguments; PropertyInfo return_val; uint32_t flags; int id; - + inline bool operator<(const MethodInfo& p_method) const { return id==p_method.id?(name < p_method.name):(id *p_list,bool p_reversed) const {}; virtual void _notificationv(int p_notification,bool p_reversed) {}; - + static String _get_category() { return ""; } static void _bind_methods(); bool _set(const StringName& p_name,const Variant &p_property) { return false; }; bool _get(const StringName& p_name,Variant &r_property) const { return false; }; void _get_property_list(List *p_list) const {}; void _notification(int p_notification) {}; - + _FORCE_INLINE_ static void (*_get_bind_methods())() { return &Object::_bind_methods; } @@ -431,13 +431,13 @@ protected: } _FORCE_INLINE_ void (Object::* (_get_get_property_list() const))(List *p_list) const{ return &Object::_get_property_list; - } + } _FORCE_INLINE_ void (Object::* (_get_notification() const))(int){ return &Object::_notification; - } + } static void get_valid_parents_static(List *p_parents); static void _get_valid_parents_static(List *p_parents); - + void cancel_delete(); @@ -485,7 +485,7 @@ public: void add_change_receptor( Object *p_receptor ); void remove_change_receptor( Object *p_receptor ); - + template T *cast_to() { @@ -500,7 +500,7 @@ public: return NULL; #endif } - + template const T *cast_to() const { @@ -517,11 +517,11 @@ public: } enum { - + NOTIFICATION_POSTINITIALIZE=0, NOTIFICATION_PREDELETE=1 }; - + /* TYPE API */ static void get_inheritance_list_static(List* p_inheritance_list) { p_inheritance_list->push_back("Object"); } @@ -545,7 +545,7 @@ public: return *_type_ptr; } } - + /* IAPI */ // void set(const String& p_name, const Variant& p_value); // Variant get(const String& p_name) const; @@ -554,7 +554,7 @@ public: Variant get(const StringName& p_name, bool *r_valid=NULL) const; void get_property_list(List *p_list,bool p_reversed=false) const; - + bool has_method(const StringName& p_method) const; void get_method_list(List *p_list) const; Variant callv(const StringName& p_method,const Array& p_args); @@ -564,14 +564,14 @@ public: Variant call(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper void call_multilevel(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper - void notification(int p_notification,bool p_reversed=false); + void notification(int p_notification,bool p_reversed=false); //used mainly by script, get and set all INCLUDING string virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const; virtual void setvar(const Variant& p_key, const Variant& p_value,bool *r_valid=NULL); /* SCRIPT */ - + void set_script(const RefPtr& p_script); RefPtr get_script() const; @@ -614,14 +614,14 @@ public: StringName tr(const StringName& p_message) const; //translate message (alternative) bool _is_queued_for_deletion; // set to true by SceneTree::queue_delete() - bool is_queued_for_deletion() const; + bool is_queued_for_deletion() const; _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } void clear_internal_resource_paths(); - Object(); + Object(); virtual ~Object(); }; @@ -649,13 +649,13 @@ class ObjectDB { static HashMap instance_checks; static uint32_t instance_counter; -friend class Object; +friend class Object; friend void unregister_core_types(); static void cleanup(); static uint32_t add_instance(Object *p_object); static void remove_instance(Object *p_object); -public: +public: typedef void (*DebugFunc)(Object *p_obj); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 819d0a5cb94..3ee4da59747 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -556,12 +556,16 @@ void make_default_theme() { // GraphNode - Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5); - Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5); + Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,3,24,16,5); + Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,3,24,16,5); + Ref graphsbdefault = make_stylebox(graph_node_default_png,4,4,4,4,6,4,4,4); + Ref graphsbdeffocus = make_stylebox(graph_node_default_focus_png,4,4,4,4,6,4,4,4); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); t->set_stylebox("frame","GraphNode", graphsb ); t->set_stylebox("selectedframe","GraphNode", graphsbselected ); + t->set_stylebox("defaultframe", "GraphNode", graphsbdefault ); + t->set_stylebox("defaultfocus", "GraphNode", graphsbdeffocus ); t->set_constant("separation","GraphNode", 1 ); t->set_icon("port","GraphNode", make_icon( graph_port_png ) ); t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) ); diff --git a/scene/resources/default_theme/graph_node_default.png b/scene/resources/default_theme/graph_node_default.png new file mode 100644 index 0000000000000000000000000000000000000000..ea6ec52828f2402912c19549eb84392359e1c754 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~hm^P;ug`W17NC%9W=KSdbAE1aYF-JD%fR4Vl$uzQ znxasiS(2gP?&%wlqL<1J6mRu(aSX9I{dTe;SF?kN%l%zT6&wu|SXMhIu%FC)Q{*>$ zf!skYCxNEjN6T}41U(*a_k5Vmwyff64`W`#!`U02tiQ+Xzkr!-a{BTETrMd^bvfzopr070{0m;e9( literal 0 HcmV?d00001 diff --git a/scene/resources/default_theme/graph_node_default_focus.png b/scene/resources/default_theme/graph_node_default_focus.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c38ae481714a79ae20277bc40dcf5e7b071d71 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~hcqLnOw3gw6QGc6W=KSdbAE1aYF-JD%fR4Vl$uzQ znxasiS(2gP?&%wlqL<1J6#wJt;uvCadhcXMFBV50*ZNagB2M~8TG>C?+*`EA@%o~L z39k~?#k`WdbKPnBQy!t$yEB)zymXZP=*-dbM0b+>L8VDd2Xq_t>Q|KR?Brl{@Q5or zyEeO|`W4%QQchvPQzpJg%uRU?f41n`{@La}!wp7*2`rvZ<_J1DXr_t=c3G{nKxA zU&S+8h+X(6rl7=bd!gFVWm~uQ?ALicQ-sdsl-@XVY|5p{tM2KS<=JoA)bS?dYvSgc vG0YW=3CC@Mg(sT7oO|QtmjjRX?fGo&xuA1@;jyzapaAl8^>bP0l+XkKget().param2; Array conns; - conns.resize(E->get().connections.size()*3); + conns.resize(E->get().connections.size()*3+E->get().defaults.size()*3); int idx2=0; for(Map::Element*F=E->get().connections.front();F;F=F->next()) { @@ -123,6 +126,14 @@ Dictionary ShaderGraph::_get_data() const { conns[idx2+2]=F->get().slot; idx2+=3; } + for(Map::Element*F=E->get().defaults.front();F;F=F->next()) { + + conns[idx2+0]=SLOT_DEFAULT_VALUE; + conns[idx2+1]=F->key(); + conns[idx2+2]=F->get(); + idx2+=3; + } + data[idx+5]=conns; idx+=6; } @@ -164,6 +175,9 @@ void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_node_list","shader_type"),&ShaderGraph::_get_node_list); + ObjectTypeDB::bind_method(_MD("default_set_value","shader_type","id","param_id","value"), &ShaderGraph::default_set_value); + ObjectTypeDB::bind_method(_MD("default_get_value","shader_type","id","param_id"), &ShaderGraph::default_get_value); + ObjectTypeDB::bind_method(_MD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value); ObjectTypeDB::bind_method(_MD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_set_value); @@ -546,7 +560,7 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material) case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material) - case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) + case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) case NODE_DEFAULT_TEXTURE: {}; break; case NODE_OUTPUT: {} break; // output (shader type dependent) case NODE_COMMENT: {} break; // comment @@ -692,6 +706,18 @@ void ShaderGraph::get_node_connections(ShaderType p_type,List *p_con } } +bool ShaderGraph::is_slot_connected(ShaderGraph::ShaderType p_type, int p_dst_id, int slot_id) +{ + for(const Map::Element *E=shader[p_type].node_map.front();E;E=E->next()) { + for (const Map::Element *F=E->get().connections.front();F;F=F->next()) { + + if (p_dst_id == E->key() && slot_id==F->key()) + return true; + } + } + return false; +} + void ShaderGraph::clear(ShaderType p_type) { @@ -1005,6 +1031,33 @@ ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_ return ScalarFunc(func); } +void ShaderGraph::default_set_value(ShaderGraph::ShaderType p_which, int p_id, int p_param, const Variant &p_value) +{ + ERR_FAIL_INDEX(p_which,3); + ERR_FAIL_COND(!shader[p_which].node_map.has(p_id)); + Node& n = shader[p_which].node_map[p_id]; + if(p_value.get_type()==Variant::NIL) + n.defaults.erase(n.defaults.find(p_param)); + else + n.defaults[p_param]=p_value; + + _request_update(); + +} + +Variant ShaderGraph::default_get_value(ShaderGraph::ShaderType p_which, int p_id, int p_param) +{ + ERR_FAIL_INDEX_V(p_which,3,Variant()); + ERR_FAIL_COND_V(!shader[p_which].node_map.has(p_id),Variant()); + const Node& n = shader[p_which].node_map[p_id]; + + if (!n.defaults.has(p_param)) + return Variant(); + return n.defaults[p_param]; +} + + + void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){ ERR_FAIL_INDEX(p_type,3); @@ -1030,52 +1083,52 @@ ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const DVector& p_colors, const DVector& p_offsets){ - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_colors; - n.param2=p_offsets; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_colors; + n.param2=p_offsets; + _request_update(); } DVector ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } DVector ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param2; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param2; } void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const DVector& p_points) { - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_points; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_points; + _request_update(); } DVector ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } @@ -1265,6 +1318,12 @@ Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const { s["pos"]=n.pos; s["param1"]=n.param1; s["param2"]=n.param2; + Array keys; + for (Map::Element *E=n.defaults.front();E;E=E->next()) { + keys.append(E->key()); + s[E->key()]=E->get(); + } + s["default_keys"]=keys; return s; } @@ -1277,10 +1336,15 @@ void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_sta ERR_FAIL_COND(!d.has("pos")); ERR_FAIL_COND(!d.has("param1")); ERR_FAIL_COND(!d.has("param2")); + ERR_FAIL_COND(!d.has("default_keys")); + n.pos=d["pos"]; n.param1=d["param1"]; n.param2=d["param2"]; - + Array keys = d["default_keys"]; + for(int i=0;i defaults; int id; mutable int order; // used for sorting int sort_order; @@ -318,6 +320,9 @@ public: VEC_MAX_FUNC }; + void default_set_value(ShaderType p_which,int p_id,int p_param, const Variant& p_value); + Variant default_get_value(ShaderType p_which,int p_id,int p_param); + void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func); VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const; @@ -358,6 +363,8 @@ public: void get_node_connections(ShaderType p_which,List *p_connections) const; + bool is_slot_connected(ShaderType p_which,int p_dst_id,int slot_id); + void clear(ShaderType p_which); Variant node_get_state(ShaderType p_type, int p_node) const; diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index b2de10ca201..12a9dce6b73 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -29,6 +29,7 @@ #include "shader_graph_editor_plugin.h" +#include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "spatial_editor_plugin.h" @@ -840,6 +841,7 @@ void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); ped_popup->popup(); @@ -850,6 +852,7 @@ void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); ped_popup->popup(); @@ -879,6 +882,35 @@ void ShaderGraphView::_cube_input_change(int p_id){ void ShaderGraphView::_variant_edited() { + if (edited_def != -1) { + + Variant v = ped_popup->get_variant(); + Variant v2 = graph->default_get_value(type,edited_id,edited_def); + if (v2.get_type() == Variant::NIL) + switch (v.get_type()) { + case Variant::VECTOR3: + v2=Vector3(); + break; + case Variant::REAL: + v2=0.0; + break; + case Variant::TRANSFORM: + v2=Transform(); + break; + case Variant::COLOR: + v2=Color(); + break; + } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change default value"); + ur->add_do_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v); + ur->add_undo_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v2); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + return; + } + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); @@ -1043,6 +1075,7 @@ void ShaderGraphView::_tex_edited(int p_id,Node* p_button) { ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); } @@ -1052,6 +1085,7 @@ void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); } @@ -1260,6 +1294,97 @@ void ShaderGraphView::_delete_nodes_request() } +void ShaderGraphView::_default_changed(int p_id, Node *p_button, int p_param, int v_type, String p_hint) +{ + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + edited_def=p_param; + Variant::Type vt = (Variant::Type)v_type; + Variant v = graph->default_get_value(type,p_id,edited_def); + int h=PROPERTY_HINT_NONE; + if (v.get_type() == Variant::NIL) + switch (vt) { + case Variant::VECTOR3: + v=Vector3(); + break; + case Variant::REAL: + h=PROPERTY_HINT_RANGE; + v=0.0; + break; + case Variant::TRANSFORM: + v=Transform(); + break; + case Variant::COLOR: + h=PROPERTY_HINT_COLOR_NO_ALPHA; + v=Color(); + break; + } + + ped_popup->edit(NULL,"",vt,v,h,p_hint); + + ped_popup->popup(); +} + +ToolButton *ShaderGraphView::make_label(String text, Variant::Type v_type) { + ToolButton *l = memnew( ToolButton ); + l->set_text(text); + l->set_text_align(ToolButton::ALIGN_LEFT); + l->add_style_override("hover", l->get_stylebox("normal", "ToolButton")); + l->add_style_override("pressed", l->get_stylebox("normal", "ToolButton")); + l->add_style_override("focus", l->get_stylebox("normal", "ToolButton")); + switch (v_type) { + case Variant::REAL: + l->set_icon(ped_popup->get_icon("Real", "EditorIcons")); + break; + case Variant::VECTOR3: + l->set_icon(ped_popup->get_icon("Vector", "EditorIcons")); + break; + case Variant::TRANSFORM: + l->set_icon(ped_popup->get_icon("Matrix", "EditorIcons")); + break; + case Variant::COLOR: + l->set_icon(ped_popup->get_icon("Color", "EditorIcons")); + } + return l; +} + +ToolButton *ShaderGraphView::make_editor(String text,GraphNode* gn,int p_id,int param,Variant::Type v_type, String p_hint) { + ToolButton *edit = memnew( ToolButton ); + edit->set_text(text); + edit->set_text_align(ToolButton::ALIGN_LEFT); + edit->set_flat(false); + edit->add_style_override("normal", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("hover", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("pressed", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("focus", gn->get_stylebox("defaultfocus", "GraphNode")); + edit->connect("pressed",this,"_default_changed",varray(p_id,edit,param,v_type,p_hint)); + + switch (v_type) { + case Variant::REAL: + edit->set_icon(ped_popup->get_icon("Real", "EditorIcons")); + break; + case Variant::VECTOR3: + edit->set_icon(ped_popup->get_icon("Vector", "EditorIcons")); + break; + case Variant::TRANSFORM: + edit->set_icon(ped_popup->get_icon("Matrix", "EditorIcons")); + break; + case Variant::COLOR: + Image icon_color = Image(15,15,false,Image::FORMAT_RGB); + Color c = graph->default_get_value(type,p_id,param); + for (int x=1;x<14;x++) + for (int y=1;y<14;y++) + icon_color.put_pixel(x,y,c); + Ref t; + t.instance(); + t->create_from_image(icon_color); + edit->set_icon(t); + break; + } + return edit; +} void ShaderGraphView::_create_node(int p_id) { @@ -1273,6 +1398,9 @@ void ShaderGraphView::_create_node(int p_id) { Color(0,1,1) }; + const String hint_spin = "-65536,65535,0.001"; + const String hint_slider = "0.0,1.0,0.01,slider"; + switch(graph->node_get_type(type,p_id)) { @@ -1377,7 +1505,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("ScreenTex"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (!graph->is_slot_connected(type,p_id,0)) { + Vector3 v = graph->default_get_value(type, p_id, 0); + hbc->add_child(make_editor("UV: " + v,gn,p_id,0,Variant::VECTOR3)); + } else { + hbc->add_child(make_label("UV",Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("RGB"))); gn->add_child(hbc); @@ -1411,11 +1544,21 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1449,11 +1592,21 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1481,12 +1634,22 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1519,11 +1682,19 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::COLOR)); + } else { + hbc->add_child(make_editor(String("a: "),gn,p_id,0,Variant::COLOR)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::COLOR)); + } else { + gn->add_child(make_editor(String("b: "),gn,p_id,1,Variant::COLOR)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1533,11 +1704,19 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFMult"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("a: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::TRANSFORM)); + } else { + gn->add_child(make_editor(String("b: edit..."),gn,p_id,1,Variant::TRANSFORM)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); @@ -1548,8 +1727,7 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFVecMult"); - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); + CheckBox *button = memnew (CheckBox("RotOnly")); button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); @@ -1557,13 +1735,22 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("xf",Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l = memnew(Label("out")); l->set_align(Label::ALIGN_RIGHT); hbc->add_child( l); gn->add_child(hbc); - gn->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("a: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1574,17 +1761,25 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFVecInvMult"); - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); + CheckBox *button = memnew( CheckBox("RotOnly")); button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); gn->add_child(button); - gn->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 0)) { + gn->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + gn->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 1)) { + hbc->add_child(make_label("xf", Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,1,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l = memnew(Label("out")); l->set_align(Label::ALIGN_RIGHT); @@ -1633,7 +1828,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->add_child(ob); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); @@ -1668,7 +1868,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); @@ -1679,7 +1884,12 @@ void ShaderGraphView::_create_node(int p_id) { case ShaderGraph::NODE_VEC_LEN: { gn->set_title("VecLength"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("len"))); gn->add_child(hbc); @@ -1692,11 +1902,21 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("DotProduct"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("dp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1707,7 +1927,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Vec2Scalar"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("vec", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("vec: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("x")); l->set_align(Label::ALIGN_RIGHT); @@ -1732,12 +1957,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Scalar2Vec"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("x"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("x", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("x: ")+Variant(v),gn,p_id,0,Variant::REAL)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("vec"))); gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("y", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("y: ")+Variant(v),gn,p_id,1,Variant::REAL)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("in", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,2,Variant::REAL)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1749,13 +1989,33 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Vec2XForm"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("x"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("x", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("x: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("xf"))); gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - gn->add_child( memnew(Label("ofs"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("y", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("y: ")+v,gn,p_id,1,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("z", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("z: ")+v,gn,p_id,2,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 3)) { + gn->add_child(make_label("ofs", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,3); + gn->add_child(make_editor(String("ofs: ")+v,gn,p_id,3,Variant::VECTOR3)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1769,7 +2029,11 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("fx", Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("fx: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l=memnew(Label("x")); l->set_align(Label::ALIGN_RIGHT); @@ -1796,12 +2060,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("ScalarInterp"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("interp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1813,12 +2092,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("VecInterp"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("interp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1857,7 +2151,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider)); + } hbc->add_spacer(); Label *l=memnew(Label("rgb")); l->set_align(Label::ALIGN_RIGHT); @@ -1902,7 +2201,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider)); + } hbc->add_spacer(); Label *l=memnew(Label("cmap")); l->set_align(Label::ALIGN_RIGHT); @@ -2016,7 +2320,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2047,7 +2356,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2067,7 +2381,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("CanvasItemTex"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2091,15 +2410,34 @@ void ShaderGraphView::_create_node(int p_id) { List si; ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + Array colors; + colors.push_back("Color"); + colors.push_back("LightColor"); + Array reals; + reals.push_back("Alpha"); + reals.push_back("NormapMapDepth"); + reals.push_back("LightAlpha"); + reals.push_back("PointSize"); + Array vectors; + vectors.push_back("Normal"); + vectors.push_back("NormalMap"); + vectors.push_back("Vertex"); + vectors.push_back("UV"); + vectors.push_back("Var1"); + vectors.push_back("Var2"); + int idx=0; for (List::Element *E=si.front();E;E=E->next()) { ShaderGraph::SlotInfo& s=E->get(); if (s.dir==ShaderGraph::SLOT_OUT) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_LEFT); - gn->add_child(l); + Variant::Type v; + if (colors.find(s.name)>=0) + v=Variant::COLOR; + else if (reals.find(s.name)>=0) + v=Variant::REAL; + else if (vectors.find(s.name)>=0) + v=Variant::VECTOR3; + gn->add_child(make_label(s.name, v)); gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); idx++; } @@ -2256,6 +2594,7 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes); ObjectTypeDB::bind_method("_delete_nodes_request", &ShaderGraphView::_delete_nodes_request); + ObjectTypeDB::bind_method("_default_changed",&ShaderGraphView::_default_changed); ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 36443efeb05..800fdf1fea1 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -129,6 +129,7 @@ class ShaderGraphView : public Node { GraphEdit *graph_edit; Ref graph; int edited_id; + int edited_def; ShaderGraph::ShaderType type; @@ -136,6 +137,8 @@ class ShaderGraphView : public Node { void _create_node(int p_id); + ToolButton *make_label(String text, Variant::Type v_type = Variant::NIL); + ToolButton *make_editor(String text, GraphNode* gn, int p_id, int param, Variant::Type type, String p_hint=""); void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); @@ -149,6 +152,9 @@ class ShaderGraphView : public Node { void _duplicate_nodes(Array &p_nodes); void _delete_nodes_request(); + + void _default_changed(int p_id, Node* p_button, int p_param, int v_type, String p_hint); + void _scalar_const_changed(double p_value,int p_id); void _vec_const_changed(double p_value, int p_id, Array p_arr); void _rgb_const_changed(const Color& p_color, int p_id); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 78a1f0ad15c..ae0975c8967 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -42,15 +42,15 @@ #include "multi_node_edit.h" void CustomPropertyEditor::_notification(int p_what) { - + if (p_what==NOTIFICATION_DRAW) { - + RID ci = get_canvas_item(); - get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); + get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); /* if (v.get_type()==Variant::COLOR) { - + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( 10,10,60, get_size().height-20 ), v ); }*/ } @@ -211,11 +211,11 @@ void CustomPropertyEditor::_menu_option(int p_which) { } Variant CustomPropertyEditor::get_variant() const { - - return v; + + return v; } String CustomPropertyEditor::get_name() const { - + return name; } @@ -233,9 +233,11 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty inheritors_array.clear(); text_edit->hide(); easing_draw->hide(); - + spinbox->hide(); + slider->hide(); + for (int i=0;ihide(); value_label[i]->hide(); if (i<4) @@ -243,8 +245,8 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } for (int i=0;ihide(); + + action_buttons[i]->hide(); } for(int i=0;i<20;i++) @@ -254,11 +256,49 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty switch(type) { - + case Variant::INT: case Variant::REAL: { - if (hint==PROPERTY_HINT_ALL_FLAGS) { + if (hint==PROPERTY_HINT_RANGE) { + + int c = hint_text.get_slice_count(","); + float min=0,max=100,step=1; + if (c>=1) { + + if (!hint_text.get_slice(",",0).empty()) + min=hint_text.get_slice(",",0).to_double(); + } + if (c>=2) { + + if (!hint_text.get_slice(",",1).empty()) + max=hint_text.get_slice(",",1).to_double(); + } + + if (type==Variant::REAL && c>=3) { + + if (!hint_text.get_slice(",",2).empty()) + step= hint_text.get_slice(",",2).to_double(); + } + + if (c>=4 && hint_text.get_slice(",",3)=="slider") { + slider->set_min(min); + slider->set_max(max); + slider->set_step((type==Variant::REAL) ? step : 1); + slider->set_val(v); + slider->show(); + set_size(Size2(110,30)); + } else { + spinbox->set_min(min); + spinbox->set_max(max); + spinbox->set_step((type==Variant::REAL) ? step : 1); + spinbox->set_val(v); + spinbox->show(); + set_size(Size2(70,35)); + } + + + } else if (hint==PROPERTY_HINT_ALL_FLAGS) { uint32_t flgs = v; for(int i=0;i<2;i++) { @@ -406,7 +446,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[3]->set_text( String::num( r.size.y) ); } break; case Variant::VECTOR3: { - + List names; names.push_back("x"); names.push_back("y"); @@ -418,7 +458,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[2]->set_text( String::num( vec.z) ); } break; case Variant::PLANE: { - + List names; names.push_back("x"); names.push_back("y"); @@ -430,10 +470,10 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[1]->set_text( String::num( plane.normal.y ) ); value_editor[2]->set_text( String::num( plane.normal.z ) ); value_editor[3]->set_text( String::num( plane.d ) ); - + } break; case Variant::QUAT: { - + List names; names.push_back("x"); names.push_back("y"); @@ -448,7 +488,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::_AABB: { - + List names; names.push_back("px"); names.push_back("py"); @@ -457,7 +497,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("sy"); names.push_back("sz"); config_value_editors(6,3,16,names); - + AABB aabb=v; value_editor[0]->set_text( String::num( aabb.pos.x ) ); value_editor[1]->set_text( String::num( aabb.pos.y ) ); @@ -465,7 +505,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[3]->set_text( String::num( aabb.size.x ) ); value_editor[4]->set_text( String::num( aabb.size.y ) ); value_editor[5]->set_text( String::num( aabb.size.z ) ); - + } break; case Variant::MATRIX32: { @@ -486,7 +526,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::MATRIX3: { - + List names; names.push_back("xx"); names.push_back("xy"); @@ -498,17 +538,17 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("zy"); names.push_back("zz"); config_value_editors(9,3,16,names); - + Matrix3 basis=v; for(int i=0;i<9;i++) { - + value_editor[i]->set_text( String::num( basis.elements[i/3][i%3] ) ); } - + } break; case Variant::TRANSFORM: { - - + + List names; names.push_back("xx"); names.push_back("xy"); @@ -523,20 +563,20 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("zz"); names.push_back("zo"); config_value_editors(12,4,16,names); - + Transform tr=v; for(int i=0;i<9;i++) { - + value_editor[(i/3)*4+i%3]->set_text( String::num( tr.basis.elements[i/3][i%3] ) ); } - + value_editor[3]->set_text( String::num( tr.origin.x ) ); value_editor[7]->set_text( String::num( tr.origin.y ) ); value_editor[11]->set_text( String::num( tr.origin.z ) ); - + } break; case Variant::COLOR: { - + color_picker->show(); color_picker->set_edit_alpha(hint!=PROPERTY_HINT_COLOR_NO_ALPHA); @@ -550,13 +590,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty float values[4]={c.r,c.g,c.b,c.a}; for (int i=0;i<4;i++) { int y=m+i*h; - + value_editor[i]->show(); - value_label[i]->show(); + value_label[i]->show(); value_label[i]->set_pos(Point2(ofs,y)); scroll[i]->set_min(0); scroll[i]->set_max(1.0); - scroll[i]->set_page(0); + scroll[i]->set_page(0); scroll[i]->set_pos(Point2(ofs+15,y+Math::floor((h-scroll[i]->get_minimum_size().height)/2.0))); scroll[i]->set_val(values[i]); scroll[i]->set_size(Size2(120,1)); @@ -564,30 +604,30 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[i]->set_pos(Point2(ofs+140,y)); value_editor[i]->set_size(Size2(40,h)); value_editor[i]->set_text( String::num(values[i],2 )); - + } - + value_label[0]->set_text("R"); value_label[1]->set_text("G"); value_label[2]->set_text("B"); value_label[3]->set_text("A"); - + Size2 new_size = value_editor[3]->get_pos() + value_editor[3]->get_size() + Point2(10,10); set_size( new_size ); */ - + } break; case Variant::IMAGE: { - + List names; names.push_back("New"); names.push_back("Load"); names.push_back("Clear"); config_action_buttons(names); - + } break; case Variant::NODE_PATH: { - + List names; names.push_back("Assign"); names.push_back("Clear"); @@ -595,7 +635,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::OBJECT: { - + if (hint!=PROPERTY_HINT_RESOURCE_TYPE) break; @@ -701,40 +741,40 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::INPUT_EVENT: { - - + + } break; case Variant::DICTIONARY: { - - + + } break; case Variant::RAW_ARRAY: { - - + + } break; case Variant::INT_ARRAY: { - - + + } break; case Variant::REAL_ARRAY: { - - + + } break; case Variant::STRING_ARRAY: { - - + + } break; case Variant::VECTOR3_ARRAY: { - - + + } break; case Variant::COLOR_ARRAY: { - - + + } break; default: {} - } - + } + updating=false; return true; } @@ -742,7 +782,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty void CustomPropertyEditor::_file_selected(String p_file) { switch(type) { - + case Variant::STRING: { if (hint==PROPERTY_HINT_FILE || hint==PROPERTY_HINT_DIR) { @@ -880,9 +920,9 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) { void CustomPropertyEditor::_action_pressed(int p_which) { - if (updating) + if (updating) return; - + switch(type) { case Variant::INT: { @@ -965,7 +1005,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } break; case Variant::NODE_PATH: { - + if (p_which==0) { @@ -976,60 +1016,60 @@ void CustomPropertyEditor::_action_pressed(int p_which) { v=NodePath(); emit_signal("variant_changed"); - } + } } break; case Variant::OBJECT: { - + if (p_which==0) { - + ERR_FAIL_COND( inheritors_array.empty() ); String intype=inheritors_array[0]; - + if (hint==PROPERTY_HINT_RESOURCE_TYPE) { - + Object *obj = ObjectTypeDB::instance(intype); ERR_BREAK( !obj ); Resource *res=obj->cast_to(); ERR_BREAK( !res ); - + v=Ref(res).get_ref_ptr(); emit_signal("variant_changed"); hide(); - + } } else if (p_which==1) { - + file->set_access(EditorFileDialog::ACCESS_RESOURCES); file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List extensions; String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String(); - + ResourceLoader::get_recognized_extensions_for_type(type,&extensions); file->clear_filters(); for (List::Element *E=extensions.front();E;E=E->next()) { - + file->add_filter("*."+E->get()+" ; "+E->get().to_upper() ); - + } - + file->popup_centered_ratio(); - + } else if (p_which==2) { - + RefPtr RefPtr=v; if (!RefPtr.is_null()) { emit_signal("resource_edit_request"); - hide(); + hide(); } - + } else if (p_which==3) { - - + + v=Variant(); emit_signal("variant_changed"); hide(); @@ -1072,7 +1112,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { emit_signal("variant_changed"); hide(); } - + } break; case Variant::IMAGE: { @@ -1111,16 +1151,16 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } void CustomPropertyEditor::_scroll_modified(double p_value) { - - if (updating) + + if (updating) return; /* switch(type) { - + case Variant::COLOR: { - + for (int i=0;i<4;i++) { - + value_editor[i]->set_text( String::num(scroll[i]->get_val(),2) ); } Color c; @@ -1145,7 +1185,7 @@ void CustomPropertyEditor::_drag_easing(const InputEvent& p_ev) { float rel = p_ev.mouse_motion.relative_x; if (rel==0) - return; + return; bool flip=hint_text=="attenuation"; @@ -1228,7 +1268,7 @@ void CustomPropertyEditor::_text_edit_changed() { } void CustomPropertyEditor::_modified(String p_string) { - + if (updating) return; updating=true; @@ -1269,17 +1309,17 @@ void CustomPropertyEditor::_modified(String p_string) { } break; case Variant::VECTOR3: { - + Vector3 vec; vec.x=value_editor[0]->get_text().to_double(); vec.y=value_editor[1]->get_text().to_double(); vec.z=value_editor[2]->get_text().to_double(); v=vec; emit_signal("variant_changed"); - + } break; case Variant::PLANE: { - + Plane pl; pl.normal.x=value_editor[0]->get_text().to_double(); pl.normal.y=value_editor[1]->get_text().to_double(); @@ -1287,10 +1327,10 @@ void CustomPropertyEditor::_modified(String p_string) { pl.d=value_editor[3]->get_text().to_double(); v=pl; emit_signal("variant_changed"); - + } break; case Variant::QUAT: { - + Quat q; q.x=value_editor[0]->get_text().to_double(); q.y=value_editor[1]->get_text().to_double(); @@ -1298,10 +1338,10 @@ void CustomPropertyEditor::_modified(String p_string) { q.w=value_editor[3]->get_text().to_double(); v=q; emit_signal("variant_changed"); - + } break; case Variant::_AABB: { - + Vector3 pos; pos.x=value_editor[0]->get_text().to_double(); pos.y=value_editor[1]->get_text().to_double(); @@ -1310,10 +1350,10 @@ void CustomPropertyEditor::_modified(String p_string) { size.x=value_editor[3]->get_text().to_double(); size.y=value_editor[4]->get_text().to_double(); size.z=value_editor[5]->get_text().to_double(); - + v=AABB(pos,size); emit_signal("variant_changed"); - + } break; case Variant::MATRIX32: { @@ -1328,39 +1368,39 @@ void CustomPropertyEditor::_modified(String p_string) { } break; case Variant::MATRIX3: { - + Matrix3 m; for(int i=0;i<9;i++) { - + m.elements[i/3][i%3]=value_editor[i]->get_text().to_double(); } - + v=m; emit_signal("variant_changed"); - + } break; case Variant::TRANSFORM: { - + Matrix3 basis; for(int i=0;i<9;i++) { - + basis.elements[i/3][i%3]=value_editor[(i/3)*4+i%3]->get_text().to_double(); } - + Vector3 origin; origin.x=value_editor[3]->get_text().to_double(); origin.y=value_editor[7]->get_text().to_double(); origin.z=value_editor[11]->get_text().to_double(); - + v=Transform(basis,origin); emit_signal("variant_changed"); - - + + } break; case Variant::COLOR: { /* for (int i=0;i<4;i++) { - + scroll[i]->set_val( value_editor[i]->get_text().to_double() ); } Color c; @@ -1374,51 +1414,57 @@ void CustomPropertyEditor::_modified(String p_string) { */ } break; case Variant::IMAGE: { - - + + } break; case Variant::NODE_PATH: { - - - } break; + + + } break; case Variant::INPUT_EVENT: { - - + + } break; case Variant::DICTIONARY: { - - + + } break; case Variant::RAW_ARRAY: { - - + + } break; case Variant::INT_ARRAY: { - - + + } break; case Variant::REAL_ARRAY: { - - + + } break; case Variant::STRING_ARRAY: { - - + + } break; case Variant::VECTOR3_ARRAY: { - - + + } break; case Variant::COLOR_ARRAY: { - - + + } break; default: {} - } - + } + updating=false; } +void CustomPropertyEditor::_range_modified(double p_value) +{ + v=p_value; + emit_signal("variant_changed"); +} + void CustomPropertyEditor::_focus_enter() { switch(type) { case Variant::REAL: @@ -1475,10 +1521,10 @@ void CustomPropertyEditor::config_action_buttons(const List& p_strings) set_size( Size2( w, m*2+(h+m)*p_strings.size() ) ); for (int i=0;ishow(); - action_buttons[i]->set_text(p_strings[i]); + action_buttons[i]->set_text(p_strings[i]); action_buttons[i]->set_pos( Point2( m, m+i*(h+m) )); action_buttons[i]->set_size( Size2( w-m*2, h ) ); action_buttons[i]->set_flat(true); @@ -1486,29 +1532,29 @@ void CustomPropertyEditor::config_action_buttons(const List& p_strings) action_buttons[i]->hide(); } } - - + + } void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int p_label_w,const List& p_strings) { - + int w=80; int h=20; int m=10; - + int rows=((p_amount-1)/p_columns)+1; - + set_size( Size2( m*(1+p_columns)+(w+p_label_w)*p_columns, m*(1+rows)+h*rows ) ); - + for (int i=0;ishow(); value_label[i]->show(); - value_label[i]->set_text(iset_text(iset_pos( Point2( m+p_label_w+c*(w+m+p_label_w), m+r*(h+m) )); value_editor[i]->set_size( Size2( w, h ) ); value_label[i]->set_pos( Point2( m+c*(w+m+p_label_w), m+r*(h+m) ) ); @@ -1518,16 +1564,17 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int value_label[i]->hide(); } } - - - + + + } void CustomPropertyEditor::_bind_methods() { - + ObjectTypeDB::bind_method("_focus_enter", &CustomPropertyEditor::_focus_enter); ObjectTypeDB::bind_method("_focus_exit", &CustomPropertyEditor::_focus_exit); ObjectTypeDB::bind_method("_modified",&CustomPropertyEditor::_modified); + ObjectTypeDB::bind_method("_range_modified", &CustomPropertyEditor::_range_modified); ObjectTypeDB::bind_method("_scroll_modified",&CustomPropertyEditor::_scroll_modified); ObjectTypeDB::bind_method("_action_pressed",&CustomPropertyEditor::_action_pressed); ObjectTypeDB::bind_method("_file_selected",&CustomPropertyEditor::_file_selected); @@ -1544,13 +1591,13 @@ void CustomPropertyEditor::_bind_methods() { ADD_SIGNAL( MethodInfo("resource_edit_request") ); } CustomPropertyEditor::CustomPropertyEditor() { - - + + read_only=false; updating=false; - + for (int i=0;iconnect("focus_enter", this, "_focus_enter"); value_editor[i]->connect("focus_exit", this, "_focus_exit"); } - + for(int i=0;i<4;i++) { - + scroll[i] = memnew( HScrollBar ); scroll[i]->hide(); scroll[i]->set_min(0); scroll[i]->set_max(1.0); - scroll[i]->set_step(0.01); + scroll[i]->set_step(0.01); add_child(scroll[i]); scroll[i]->connect("value_changed", this,"_scroll_modified"); - + } for(int i=0;i<20;i++) { @@ -1595,15 +1642,15 @@ CustomPropertyEditor::CustomPropertyEditor() { text_edit->connect("text_changed",this,"_text_edit_changed"); for (int i=0;ihide(); + action_buttons[i]->hide(); add_child(action_buttons[i]); Vector binds; binds.push_back(i); action_buttons[i]->connect("pressed", this,"_action_pressed",binds); } - + color_picker = memnew( ColorPicker ); add_child(color_picker); color_picker->hide(); @@ -1616,7 +1663,7 @@ CustomPropertyEditor::CustomPropertyEditor() { file = memnew ( EditorFileDialog ); add_child(file); file->hide(); - + file->connect("file_selected", this,"_file_selected"); file->connect("dir_selected", this,"_file_selected"); @@ -1624,12 +1671,12 @@ CustomPropertyEditor::CustomPropertyEditor() { error->set_title("Error!"); add_child(error); //error->get_cancel()->hide(); - + type_button = memnew( MenuButton ); add_child(type_button); type_button->hide(); type_button->get_popup()->connect("item_pressed", this,"_type_create_selected"); - + scene_tree = memnew( SceneTreeDialog ); add_child(scene_tree); @@ -1651,6 +1698,16 @@ CustomPropertyEditor::CustomPropertyEditor() { menu = memnew(PopupMenu); add_child(menu); menu->connect("item_pressed",this,"_menu_option"); + + spinbox = memnew ( SpinBox ); + add_child(spinbox); + spinbox->set_area_as_parent_rect(5); + spinbox->connect("value_changed",this,"_range_modified"); + + slider = memnew ( HSlider ); + add_child(slider); + slider->set_area_as_parent_rect(5); + slider->connect("value_changed",this,"_range_modified"); } @@ -1675,28 +1732,28 @@ Node *PropertyEditor::get_instanced_node() { } TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) { - - + + if (!p_item) return NULL; - + String name = p_item->get_metadata(1); - + if (name==p_name) { - + return p_item; } - + TreeItem *c=p_item->get_children(); - + while (c) { - + TreeItem *found = find_item(c,p_name); if (found) return found; c=c->get_next(); } - + return NULL; } @@ -1719,9 +1776,9 @@ void PropertyEditor::_changed_callbacks(Object *p_changed,const String& p_prop) if (p_prop==String()) update_tree_pending=true; else { - + pending[p_prop]=p_prop; - + } } @@ -1733,7 +1790,7 @@ void PropertyEditor::update_property(const String& p_prop) { void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint, const String& p_hint_text) { - + switch( p_type ) { case Variant::BOOL: { @@ -1826,7 +1883,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } break; case Variant::IMAGE: { - + Image img = obj->get( p_name ); if (img.empty()) p_item->set_text(1,"[Image (empty)]"); @@ -1905,7 +1962,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } break; default: {}; } - + } void PropertyEditor::_notification(int p_what) { @@ -1920,10 +1977,10 @@ void PropertyEditor::_notification(int p_what) { edit(NULL); } - + if (p_what==NOTIFICATION_FIXED_PROCESS) { - - + + if (refresh_countdown>0) { refresh_countdown-=get_fixed_process_delta_time(); if (refresh_countdown<=0) { @@ -1933,21 +1990,21 @@ void PropertyEditor::_notification(int p_what) { } changing=true; - + if (update_tree_pending) { update_tree(); update_tree_pending=false; - + } else { - - const String *k=NULL; + + const String *k=NULL; while ((k=pending.next(k))) { - + TreeItem * item = find_item(tree->get_root(),*k); if (!item) continue; - + if (get_instanced_node()) { Dictionary d = get_instanced_node()->get_instance_state(); @@ -1981,15 +2038,15 @@ void PropertyEditor::_notification(int p_what) { } } - Dictionary d=item->get_metadata(0); + Dictionary d=item->get_metadata(0); set_item_text(item,d["type"],d["name"],d["hint"],d["hint_text"]); - } + } } - + pending.clear(); - + changing=false; - + } } @@ -2271,20 +2328,20 @@ void PropertyEditor::update_tree() { d["type"]=(int)p.type; d["hint"]=(int)p.hint; d["hint_text"]=p.hint_string; - + item->set_metadata( 0, d ); item->set_metadata( 1, p.name ); if (draw_red) item->set_custom_color(0,Color(0.8,0.4,0.20)); - + if (p.name==selected_property) { item->select(1); } - + //printf("property %s type %i\n",p.name.ascii().get_data(),p.type); switch( p.type ) { @@ -2365,8 +2422,8 @@ void PropertyEditor::update_tree() { if (p.type==Variant::REAL && c>=3) { step= p.hint_string.get_slice(",",2).to_double(); - } - + } + item->set_range_config(1,min,max,step,p.hint==PROPERTY_HINT_EXP_RANGE); } else if (p.hint==PROPERTY_HINT_ENUM) { @@ -2549,7 +2606,7 @@ void PropertyEditor::update_tree() { } break; case Variant::IMAGE: { - + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); item->set_editable( 1, !read_only ); Image img = obj->get( p.name ); @@ -2558,7 +2615,7 @@ void PropertyEditor::update_tree() { else item->set_text(1,"[Image "+itos(img.get_width())+"x"+itos(img.get_height())+"]"); item->set_icon( 0,get_icon("Image","EditorIcons") ); - + } break; case Variant::NODE_PATH: { @@ -2709,10 +2766,10 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { void PropertyEditor::_item_edited() { - - TreeItem * item = tree->get_edited(); + + TreeItem * item = tree->get_edited(); Dictionary d = item->get_metadata(0); - + String name=d["name"]; if (tree->get_edited_column()==0) { @@ -2741,12 +2798,12 @@ void PropertyEditor::_item_edited() { int hint= d["hint"]; String hint_text=d["hint_text"]; switch(type) { - + case Variant::NIL: { - - } break; + + } break; case Variant::BOOL: { - + _edit_set(name,item->is_checked(1)); } break; case Variant::INT: @@ -2765,7 +2822,7 @@ void PropertyEditor::_item_edited() { _edit_set(name,item->get_range(1)); } break; case Variant::STRING: { - + if (hint==PROPERTY_HINT_ENUM) { int idx= item->get_range(1); @@ -2783,64 +2840,64 @@ void PropertyEditor::_item_edited() { } } break; // math types - + case Variant::VECTOR3: { - + } break; case Variant::PLANE: { - + } break; case Variant::QUAT: { - + } break; case Variant::_AABB: { - + } break; case Variant::MATRIX3: { - + } break; case Variant::TRANSFORM: { - + } break; - + case Variant::COLOR: { //_edit_set(name,item->get_custom_bg_color(0)); } break; case Variant::IMAGE: { - + } break; case Variant::NODE_PATH: { - + } break; case Variant::INPUT_EVENT: { - + } break; case Variant::DICTIONARY: { - + } break; - + // arrays case Variant::RAW_ARRAY: { - + } break; case Variant::INT_ARRAY: { - + } break; case Variant::REAL_ARRAY: { - + } break; case Variant::STRING_ARRAY: { - + } break; case Variant::VECTOR3_ARRAY: { - + } break; case Variant::COLOR_ARRAY: { - + } break; - - + + }; } @@ -2891,24 +2948,24 @@ void PropertyEditor::_custom_editor_request(bool p_arrow) { } void PropertyEditor::edit(Object* p_object) { - + if (obj==p_object) return; if (obj) { - + obj->remove_change_receptor(this); } obj=p_object; update_tree(); - + if (obj) { - + obj->add_change_receptor(this); } - - + + } void PropertyEditor::_set_range_def(Object *p_item, String prop,float p_frame) { @@ -3003,9 +3060,9 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { void PropertyEditor::_node_removed(Node *p_node) { - + if (p_node==obj) { - + edit(NULL); } } @@ -3065,9 +3122,9 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_item_edited",&PropertyEditor::_item_edited); ObjectTypeDB::bind_method( "_item_selected",&PropertyEditor::_item_selected); ObjectTypeDB::bind_method( "_custom_editor_request",&PropertyEditor::_custom_editor_request); - ObjectTypeDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); - ObjectTypeDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); - ObjectTypeDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); + ObjectTypeDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); + ObjectTypeDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); + ObjectTypeDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); ObjectTypeDB::bind_method( "_changed_callback",&PropertyEditor::_changed_callbacks); ObjectTypeDB::bind_method( "_draw_flags",&PropertyEditor::_draw_flags); @@ -3127,29 +3184,29 @@ void PropertyEditor::set_show_categories(bool p_show) { } PropertyEditor::PropertyEditor() { - + _prop_edited="property_edited"; _prop_edited_name.push_back(String()); undo_redo=NULL; obj=NULL; changing=false; update_tree_pending=false; - + top_label = memnew( Label ); top_label->set_text("Properties:"); top_label->set_anchor( MARGIN_RIGHT, ANCHOR_END ); top_label->set_begin( Point2( 10,0) ); - top_label->set_end( Point2( 0,12) ); - - add_child(top_label); + top_label->set_end( Point2( 0,12) ); + + add_child(top_label); + - tree = memnew( Tree ); tree->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); + tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); tree->set_begin( Point2(0,19 )); tree->set_end( Point2(0,0 )); - + tree->set_columns(2); tree->set_column_expand(0,true); tree->set_column_min_width(0,30); @@ -3157,21 +3214,21 @@ PropertyEditor::PropertyEditor() { tree->set_column_min_width(1,18); //tree->set_hide_root(true); - add_child( tree ); - + add_child( tree ); + tree->connect("item_edited", this,"_item_edited",varray(),CONNECT_DEFERRED); tree->connect("cell_selected", this,"_item_selected"); - + set_fixed_process(true); - + custom_editor = memnew( CustomPropertyEditor ); add_child(custom_editor); - + tree->connect("custom_popup_edited", this,"_custom_editor_request"); tree->connect("button_pressed", this,"_edit_button"); custom_editor->connect("variant_changed", this,"_custom_editor_edited"); custom_editor->connect("resource_edit_request", this,"_resource_edit_request",make_binds(),CONNECT_DEFERRED); - + capitalize_paths=true; autoclear=false; tree->set_column_title(0,"Property"); @@ -3182,7 +3239,7 @@ PropertyEditor::PropertyEditor() { read_only=false; show_categories=false; refresh_countdown=0; - + } diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index de5cac87110..f6e2dfcf509 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -46,9 +46,9 @@ */ class CustomPropertyEditor : public Popup { - + OBJ_TYPE( CustomPropertyEditor, Popup ); - + enum { MAX_VALUE_EDITORS=12, MAX_ACTION_BUTTONS=5, @@ -93,7 +93,8 @@ class CustomPropertyEditor : public Popup { TextEdit *text_edit; bool read_only; Button *checks20[20]; - + SpinBox *spinbox; + HSlider *slider; Control *easing_draw; @@ -105,6 +106,7 @@ class CustomPropertyEditor : public Popup { void _file_selected(String p_file); void _scroll_modified(double p_value); void _modified(String p_string); + void _range_modified(double p_value); void _focus_enter(); void _focus_exit(); void _action_pressed(int p_which); @@ -113,7 +115,7 @@ class CustomPropertyEditor : public Popup { void _color_changed(const Color& p_color); void _draw_easing(); void _menu_option(int p_which); - + void _drag_easing(const InputEvent& p_ev); void _node_path_selected(NodePath p_path); @@ -123,23 +125,23 @@ class CustomPropertyEditor : public Popup { protected: void _notification(int p_what); - static void _bind_methods(); - -public: + static void _bind_methods(); + +public: Variant get_variant() const; String get_name() const; - + void set_read_only(bool p_read_only) { read_only=p_read_only; } bool edit(Object* p_owner,const String& p_name,Variant::Type p_type, const Variant& p_variant,int p_hint,String p_hint_text); - + CustomPropertyEditor(); }; class PropertyEditor : public Control { - + OBJ_TYPE( PropertyEditor, Control ); - + Tree *tree; Label *top_label; //Object *object; @@ -160,27 +162,27 @@ class PropertyEditor : public Control { HashMap pending; String selected_property; - + CustomPropertyEditor *custom_editor; - + void _resource_edit_request(); void _custom_editor_edited(); void _custom_editor_request(bool p_arrow); - + void _item_selected(); void _item_edited(); TreeItem *get_parent_node(String p_path,HashMap& item_paths,TreeItem *root); - + void set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint=PROPERTY_HINT_NONE, const String& p_hint_text=""); - + TreeItem *find_item(TreeItem *p_item,const String& p_name); - - + + virtual void _changed_callback(Object *p_changed,const char * p_what); virtual void _changed_callbacks(Object *p_changed,const String& p_callback); void _edit_button(Object *p_item, int p_column, int p_button); - + void _node_removed(Node *p_node); void _edit_set(const String& p_name, const Variant& p_value); void _draw_flags(Object *ti,const Rect2& p_rect); @@ -191,7 +193,7 @@ class PropertyEditor : public Control { UndoRedo *undo_redo; protected: - + void _notification(int p_what); static void _bind_methods(); public: @@ -217,8 +219,8 @@ public: void set_autoclear(bool p_enable); void set_show_categories(bool p_show); - - PropertyEditor(); + + PropertyEditor(); ~PropertyEditor(); };