Even more work on visual script editor:

-Added constructor nodes, specialized and conversion ones.
-Cleaned up how unconnected input default values are shown and edited (much cleaner)
-Dragging scene nodes into graph makes a call dialog appear by deault
-Dragging properties into graph is set by default, not get
-fixed dragging internal functions into graph
This commit is contained in:
Juan Linietsky 2016-08-26 17:34:25 -03:00
parent 963ed2d9fa
commit ec49f41e19
7 changed files with 446 additions and 49 deletions

View file

@ -67,6 +67,8 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptCustomNode>(); ObjectTypeDB::register_type<VisualScriptCustomNode>();
ObjectTypeDB::register_type<VisualScriptSubCall>(); ObjectTypeDB::register_type<VisualScriptSubCall>();
ObjectTypeDB::register_type<VisualScriptComment>(); ObjectTypeDB::register_type<VisualScriptComment>();
ObjectTypeDB::register_type<VisualScriptConstructor>();
ObjectTypeDB::register_type<VisualScriptFunctionCall>(); ObjectTypeDB::register_type<VisualScriptFunctionCall>();
ObjectTypeDB::register_type<VisualScriptPropertySet>(); ObjectTypeDB::register_type<VisualScriptPropertySet>();
@ -104,6 +106,8 @@ void register_visual_script_types() {
void unregister_visual_script_types() { void unregister_visual_script_types() {
unregister_visual_script_nodes();
ScriptServer::unregister_language(visual_script_language); ScriptServer::unregister_language(visual_script_language);
if (visual_script_language) if (visual_script_language)

View file

@ -4,6 +4,7 @@
#include "visual_script_flow_control.h" #include "visual_script_flow_control.h"
#include "visual_script_func_nodes.h" #include "visual_script_func_nodes.h"
#include "os/input.h" #include "os/input.h"
#include "tools/editor/editor_resource_preview.h"
#include "os/keyboard.h" #include "os/keyboard.h"
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -494,6 +495,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
String left_name; String left_name;
if (i<node->get_input_value_port_count()) { if (i<node->get_input_value_port_count()) {
PropertyInfo pi = node->get_input_value_port_info(i); PropertyInfo pi = node->get_input_value_port_info(i);
left_ok=true; left_ok=true;
@ -530,6 +532,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
hbc->add_child(memnew(Label(left_name))); hbc->add_child(memnew(Label(left_name)));
if (left_type!=Variant::NIL && !script->is_input_value_port_connected(edited_func,E->get(),i)) { if (left_type!=Variant::NIL && !script->is_input_value_port_connected(edited_func,E->get(),i)) {
PropertyInfo pi = node->get_input_value_port_info(i);
Button *button = memnew( Button ); Button *button = memnew( Button );
Variant value = node->get_default_input_value(i); Variant value = node->get_default_input_value(i);
if (value.get_type()!=left_type) { if (value.get_type()!=left_type) {
@ -540,7 +544,24 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
value = Variant::construct(left_type,&existingp,1,ce,false); value = Variant::construct(left_type,&existingp,1,ce,false);
} }
button->set_text(value); if (left_type==Variant::COLOR) {
button->set_custom_minimum_size(Size2(30,0)*EDSCALE);
button->connect("draw",this,"_draw_color_over_button",varray(button,value));
} else if (left_type==Variant::OBJECT && Ref<Resource>(value).is_valid()) {
Ref<Resource> res = value;
Array arr;
arr.push_back(button->get_instance_ID());
arr.push_back(String(value));
EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_button_resource_previewed",arr);
} else if (pi.type==Variant::INT && pi.hint==PROPERTY_HINT_ENUM){
button->set_text(pi.hint_string.get_slice(",",value));
} else {
button->set_text(value);
}
button->connect("pressed",this,"_default_value_edited",varray(button,E->get(),i)); button->connect("pressed",this,"_default_value_edited",varray(button,E->get(),i));
hbc->add_child(button); hbc->add_child(button);
} }
@ -1412,18 +1433,27 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2& p_point,const Variant& p
if (String(d["type"])=="obj_property") { if (String(d["type"])=="obj_property") {
#ifdef OSX_ENABLED #ifdef OSX_ENABLED
const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Meta to drop a Setter, Shift+Meta to drop a Setter and copy the value."); const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a Getter. Hold Shift to drop a generic signature."));
#else #else
const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Ctrl to drop a Setter, Shift+Ctrl to drop a Setter and copy the value."); const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."));
#endif
}
if (String(d["type"])=="nodes") {
#ifdef OSX_ENABLED
const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a simple reference to the node."));
#else
const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node."));
#endif #endif
} }
if (String(d["type"])=="visual_script_variable_drag") { if (String(d["type"])=="visual_script_variable_drag") {
#ifdef OSX_ENABLED #ifdef OSX_ENABLED
const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Meta to drop a Variable Setter."); const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a Variable Setter."));
#else #else
const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Ctrl to drop a Variable Setter."); const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter."));
#endif #endif
} }
@ -1462,6 +1492,8 @@ static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const R
#endif #endif
void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){
if (p_from==graph) { if (p_from==graph) {
@ -1550,10 +1582,11 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
} }
ofs/=EDSCALE; ofs/=EDSCALE;
#if 0
Ref<VisualScriptScriptCall> vnode; Ref<VisualScriptFunctionCall> vnode;
vnode.instance(); vnode.instance();
vnode->set_call_mode(VisualScriptScriptCall::CALL_MODE_SELF); vnode->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SELF);
vnode->set_base_type(script->get_instance_base_type());
vnode->set_function(d["function"]); vnode->set_function(d["function"]);
int new_id = script->get_available_id(); int new_id = script->get_available_id();
@ -1570,7 +1603,7 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
graph->set_selected(node); graph->set_selected(node);
_node_selected(node); _node_selected(node);
} }
#endif
} }
@ -1613,6 +1646,14 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
return; return;
} }
#ifdef OSX_ENABLED
bool use_node = Input::get_singleton()->is_key_pressed(KEY_META);
#else
bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
Array nodes = d["nodes"]; Array nodes = d["nodes"];
Vector2 ofs = graph->get_scroll_ofs() + p_point; Vector2 ofs = graph->get_scroll_ofs() + p_point;
@ -1626,6 +1667,10 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
undo_redo->create_action(TTR("Add Node(s) From Tree")); undo_redo->create_action(TTR("Add Node(s) From Tree"));
int base_id = script->get_available_id(); int base_id = script->get_available_id();
if (nodes.size()>1) {
use_node=true;
}
for(int i=0;i<nodes.size();i++) { for(int i=0;i<nodes.size();i++) {
NodePath np = nodes[i]; NodePath np = nodes[i];
@ -1634,10 +1679,30 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
continue; continue;
} }
Ref<VisualScriptSceneNode> scene_node; Ref<VisualScriptNode> n;
scene_node.instance();
scene_node->set_node_path(sn->get_path_to(node)); if (use_node) {
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,scene_node,ofs); Ref<VisualScriptSceneNode> scene_node;
scene_node.instance();
scene_node->set_node_path(sn->get_path_to(node));
n=scene_node;
} else {
Ref<VisualScriptFunctionCall> call;
call.instance();
call->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH);
call->set_base_path(sn->get_path_to(node));;
call->set_base_type(node->get_type());
n=call;
method_select->select_method_from_instance(node);
selecting_method_id=base_id;
}
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,n,ofs);
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id); undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
base_id++; base_id++;
@ -1655,9 +1720,9 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script); Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script);
if (!sn) { if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
//EditorNode::get_singleton()->show_warning("Can't drop properties because script '"+get_name()+"' is not used in this scene."); EditorNode::get_singleton()->show_warning("Can't drop properties because script '"+get_name()+"' is not used in this scene.\nDrop holding 'Shift' to just copy the signature.");
//return; return;
} }
Object *obj=d["object"]; Object *obj=d["object"];
@ -1675,36 +1740,33 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
ofs/=EDSCALE; ofs/=EDSCALE;
#ifdef OSX_ENABLED #ifdef OSX_ENABLED
bool use_set = Input::get_singleton()->is_key_pressed(KEY_META); bool use_get = Input::get_singleton()->is_key_pressed(KEY_META);
#else #else
bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL); bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif #endif
bool use_value = Input::get_singleton()->is_key_pressed(KEY_SHIFT); if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
if (!node) {
if (use_set) if (use_get)
undo_redo->create_action(TTR("Add Setter Property"));
else
undo_redo->create_action(TTR("Add Getter Property")); undo_redo->create_action(TTR("Add Getter Property"));
else
undo_redo->create_action(TTR("Add Setter Property"));
int base_id = script->get_available_id(); int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode; Ref<VisualScriptNode> vnode;
if (use_set) { if (!use_get) {
Ref<VisualScriptPropertySet> pset; Ref<VisualScriptPropertySet> pset;
pset.instance(); pset.instance();
pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
pset->set_base_type(obj->get_type()); pset->set_base_type(obj->get_type());
pset->set_property(d["property"]); /*if (use_value) {
if (use_value) {
pset->set_use_builtin_value(true); pset->set_use_builtin_value(true);
pset->set_builtin_value(d["value"]); pset->set_builtin_value(d["value"]);
} }*/
vnode=pset; vnode=pset;
} else { } else {
@ -1712,12 +1774,17 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
pget.instance(); pget.instance();
pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
pget->set_base_type(obj->get_type()); pget->set_base_type(obj->get_type());
pget->set_property(d["property"]);
vnode=pget; vnode=pget;
} }
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs); undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs);
undo_redo->add_do_method(vnode.ptr(),"set_property",d["property"]);
if (!use_get) {
undo_redo->add_do_method(vnode.ptr(),"set_default_input_value",0,d["value"]);
}
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id); undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
undo_redo->add_do_method(this,"_update_graph"); undo_redo->add_do_method(this,"_update_graph");
@ -1728,26 +1795,21 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
if (use_set) if (use_get)
undo_redo->create_action(TTR("Add Setter Property"));
else
undo_redo->create_action(TTR("Add Getter Property")); undo_redo->create_action(TTR("Add Getter Property"));
else
undo_redo->create_action(TTR("Add Setter Property"));
int base_id = script->get_available_id(); int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode; Ref<VisualScriptNode> vnode;
if (use_set) { if (!use_get) {
Ref<VisualScriptPropertySet> pset; Ref<VisualScriptPropertySet> pset;
pset.instance(); pset.instance();
pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH); pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH);
pset->set_base_path(sn->get_path_to(sn)); pset->set_base_path(sn->get_path_to(node));
pset->set_property(d["property"]);
if (use_value) {
pset->set_use_builtin_value(true);
pset->set_builtin_value(d["value"]);
}
vnode=pset; vnode=pset;
} else { } else {
@ -1755,12 +1817,15 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
Ref<VisualScriptPropertyGet> pget; Ref<VisualScriptPropertyGet> pget;
pget.instance(); pget.instance();
pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH); pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH);
pget->set_base_path(sn->get_path_to(sn)); pget->set_base_path(sn->get_path_to(node));
pget->set_property(d["property"]);
vnode=pget; vnode=pget;
} }
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs); undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs);
undo_redo->add_do_method(vnode.ptr(),"set_property",d["property"]);
if (!use_get) {
undo_redo->add_do_method(vnode.ptr(),"set_default_input_value",0,d["value"]);
}
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id); undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
undo_redo->add_do_method(this,"_update_graph"); undo_redo->add_do_method(this,"_update_graph");
@ -1778,6 +1843,50 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
} }
void VisualScriptEditor::_selected_method(const String& p_method) {
Ref<VisualScriptFunctionCall> vsfc = script->get_node(edited_func,selecting_method_id);
if (!vsfc.is_valid())
return;
vsfc->set_function(p_method);
}
void VisualScriptEditor::_draw_color_over_button(Object* obj,Color p_color) {
Button *button = obj->cast_to<Button>();
if (!button)
return;
Ref<StyleBox> normal = get_stylebox("normal","Button" );
button->draw_rect(Rect2(normal->get_offset(),button->get_size()-normal->get_minimum_size()),p_color);
}
void VisualScriptEditor::_button_resource_previewed(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud) {
Array ud=p_ud;
ERR_FAIL_COND(ud.size()!=2);
ObjectID id = ud[0];
Object *obj = ObjectDB::get_instance(id);
if (!obj)
return;
Button *b = obj->cast_to<Button>();
ERR_FAIL_COND(!b);
if (p_preview.is_null()) {
b->set_text(ud[1]);
} else {
b->set_icon(p_preview);
}
}
///////////////////////// /////////////////////////
@ -2312,8 +2421,12 @@ void VisualScriptEditor::_default_value_edited(Node * p_button,int p_id,int p_in
default_value_edit->set_pos(p_button->cast_to<Control>()->get_global_pos()+Vector2(0,p_button->cast_to<Control>()->get_size().y)); default_value_edit->set_pos(p_button->cast_to<Control>()->get_global_pos()+Vector2(0,p_button->cast_to<Control>()->get_size().y));
default_value_edit->set_size(Size2(1,1)); default_value_edit->set_size(Size2(1,1));
if (default_value_edit->edit(NULL,pinfo.name,pinfo.type,existing,pinfo.hint,pinfo.hint_string)) if (default_value_edit->edit(NULL,pinfo.name,pinfo.type,existing,pinfo.hint,pinfo.hint_string)) {
default_value_edit->popup(); if (pinfo.hint==PROPERTY_HINT_MULTILINE_TEXT)
default_value_edit->popup_centered_ratio();
else
default_value_edit->popup();
}
editing_id = p_id; editing_id = p_id;
editing_input=p_input_port; editing_input=p_input_port;
@ -2598,6 +2711,8 @@ void VisualScriptEditor::_bind_methods() {
ObjectTypeDB::bind_method("_graph_ofs_changed",&VisualScriptEditor::_graph_ofs_changed); ObjectTypeDB::bind_method("_graph_ofs_changed",&VisualScriptEditor::_graph_ofs_changed);
ObjectTypeDB::bind_method("_center_on_node",&VisualScriptEditor::_center_on_node); ObjectTypeDB::bind_method("_center_on_node",&VisualScriptEditor::_center_on_node);
ObjectTypeDB::bind_method("_comment_node_resized",&VisualScriptEditor::_comment_node_resized); ObjectTypeDB::bind_method("_comment_node_resized",&VisualScriptEditor::_comment_node_resized);
ObjectTypeDB::bind_method("_button_resource_previewed",&VisualScriptEditor::_button_resource_previewed);
@ -2618,6 +2733,11 @@ void VisualScriptEditor::_bind_methods() {
ObjectTypeDB::bind_method("_update_graph_connections",&VisualScriptEditor::_update_graph_connections); ObjectTypeDB::bind_method("_update_graph_connections",&VisualScriptEditor::_update_graph_connections);
ObjectTypeDB::bind_method("_node_filter_changed",&VisualScriptEditor::_node_filter_changed); ObjectTypeDB::bind_method("_node_filter_changed",&VisualScriptEditor::_node_filter_changed);
ObjectTypeDB::bind_method("_selected_method",&VisualScriptEditor::_selected_method);
ObjectTypeDB::bind_method("_draw_color_over_button",&VisualScriptEditor::_draw_color_over_button);
} }
@ -2788,7 +2908,11 @@ VisualScriptEditor::VisualScriptEditor() {
add_child(default_value_edit); add_child(default_value_edit);
default_value_edit->connect("variant_changed",this,"_default_value_changed"); default_value_edit->connect("variant_changed",this,"_default_value_changed");
method_select = memnew( PropertySelector );
add_child(method_select);
method_select->connect("selected",this,"_selected_method");
error_line=-1; error_line=-1;
} }
VisualScriptEditor::~VisualScriptEditor() { VisualScriptEditor::~VisualScriptEditor() {

View file

@ -6,7 +6,7 @@
#include "tools/editor/property_editor.h" #include "tools/editor/property_editor.h"
#include "scene/gui/graph_edit.h" #include "scene/gui/graph_edit.h"
#include "tools/editor/create_dialog.h" #include "tools/editor/create_dialog.h"
#include "tools/editor/property_selector.h"
class VisualScriptEditorSignalEdit; class VisualScriptEditorSignalEdit;
class VisualScriptEditorVariableEdit; class VisualScriptEditorVariableEdit;
@ -51,6 +51,7 @@ class VisualScriptEditor : public ScriptEditorBase {
AcceptDialog *edit_signal_dialog; AcceptDialog *edit_signal_dialog;
PropertyEditor *edit_signal_edit; PropertyEditor *edit_signal_edit;
PropertySelector *method_select;
VisualScriptEditorVariableEdit *variable_editor; VisualScriptEditorVariableEdit *variable_editor;
@ -163,6 +164,12 @@ class VisualScriptEditor : public ScriptEditorBase {
void _graph_ofs_changed(const Vector2& p_ofs); void _graph_ofs_changed(const Vector2& p_ofs);
void _comment_node_resized(const Vector2& p_new_size,int p_node); void _comment_node_resized(const Vector2& p_new_size,int p_node);
int selecting_method_id;
void _selected_method(const String& p_method);
void _draw_color_over_button(Object* obj,Color p_color);
void _button_resource_previewed(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud);
protected: protected:

View file

@ -2602,6 +2602,156 @@ VisualScriptComment::VisualScriptComment() {
} }
//////////////////////////////////////////
////////////////Constructor///////////
//////////////////////////////////////////
int VisualScriptConstructor::get_output_sequence_port_count() const {
return 1;
}
bool VisualScriptConstructor::has_input_sequence_port() const{
return true;
}
int VisualScriptConstructor::get_input_value_port_count() const{
return constructor.arguments.size();
}
int VisualScriptConstructor::get_output_value_port_count() const{
return 1;
}
String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const {
return "";
}
PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const{
return constructor.arguments[p_idx];
}
PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const{
return PropertyInfo(type,"value");
}
String VisualScriptConstructor::get_caption() const {
return "Construct";
}
String VisualScriptConstructor::get_text() const {
return "new "+Variant::get_type_name(type)+"()";
}
String VisualScriptConstructor::get_category() const {
return "functions";
}
void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) {
if (type==p_type)
return;
type=p_type;
ports_changed_notify();
}
Variant::Type VisualScriptConstructor::get_constructor_type() const {
return type;
}
void VisualScriptConstructor::set_constructor(const Dictionary& p_info) {
constructor=MethodInfo::from_dict(p_info);
}
Dictionary VisualScriptConstructor::get_constructor() const {
return constructor;
}
class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance {
public:
VisualScriptInstance* instance;
Variant::Type type;
int argcount;
//virtual int get_working_memory_size() const { return 0; }
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; };
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
Variant::CallError ce;
*p_outputs[0]=Variant::construct(type,p_inputs,argcount,ce);
if (ce.error!=Variant::CallError::CALL_OK) {
r_error_str="Invalid arguments for constructor";
}
return 0;
}
};
VisualScriptNodeInstance* VisualScriptConstructor::instance(VisualScriptInstance* p_instance) {
VisualScriptNodeInstanceConstructor * instance = memnew(VisualScriptNodeInstanceConstructor );
instance->instance=p_instance;
instance->type=type;
instance->argcount=constructor.arguments.size();
return instance;
}
void VisualScriptConstructor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_constructor_type","type"),&VisualScriptConstructor::set_constructor_type);
ObjectTypeDB::bind_method(_MD("get_constructor_type"),&VisualScriptConstructor::get_constructor_type);
ObjectTypeDB::bind_method(_MD("set_constructor","constructor"),&VisualScriptConstructor::set_constructor);
ObjectTypeDB::bind_method(_MD("get_constructor"),&VisualScriptConstructor::get_constructor);
ADD_PROPERTY( PropertyInfo(Variant::INT,"type",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_constructor_type"),_SCS("get_constructor_type"));
ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"constructor",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_constructor"),_SCS("get_constructor"));
}
VisualScriptConstructor::VisualScriptConstructor() {
type=Variant::NIL;
}
static Map<String,Pair<Variant::Type,MethodInfo> > constructor_map;
static Ref<VisualScriptNode> create_constructor_node(const String& p_name) {
ERR_FAIL_COND_V(!constructor_map.has(p_name),Ref<VisualScriptNode>());
Ref<VisualScriptConstructor> vsc;
vsc.instance();
vsc->set_constructor_type(constructor_map[p_name].first);
vsc->set_constructor(constructor_map[p_name].second);
return vsc;
}
void register_visual_script_nodes() { void register_visual_script_nodes() {
@ -2653,4 +2803,41 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("operators/logic/in",create_op_node<Variant::OP_IN>); VisualScriptLanguage::singleton->add_register_func("operators/logic/in",create_op_node<Variant::OP_IN>);
for(int i=1;i<Variant::VARIANT_MAX;i++) {
List<MethodInfo> constructors;
Variant::get_constructor_list(Variant::Type(i),&constructors);
for(List<MethodInfo>::Element *E=constructors.front();E;E=E->next()) {
if (E->get().arguments.size()>0) {
String name = "functions/constructors/"+Variant::get_type_name(Variant::Type(i))+" ( ";
for(int j=0;j<E->get().arguments.size();j++) {
if (j>0)
name+=", ";
if (E->get().arguments.size()==1)
name+=Variant::get_type_name(E->get().arguments[j].type);
else
name+=E->get().arguments[j].name;
}
name+=") ";
VisualScriptLanguage::singleton->add_register_func(name,create_constructor_node);
Pair<Variant::Type,MethodInfo> pair;
pair.first=Variant::Type(i);
pair.second=E->get();
constructor_map[name]=pair;
}
}
}
} }
void unregister_visual_script_nodes() {
constructor_map.clear();
}

View file

@ -622,7 +622,6 @@ class VisualScriptSubCall: public VisualScriptNode {
protected: protected:
virtual bool _use_builtin_script() const { return true; }
static void _bind_methods(); static void _bind_methods();
public: public:
@ -659,8 +658,6 @@ class VisualScriptComment: public VisualScriptNode {
Size2 size; Size2 size;
protected: protected:
virtual bool _use_builtin_script() const { return true; }
static void _bind_methods(); static void _bind_methods();
public: public:
virtual int get_output_sequence_port_count() const; virtual int get_output_sequence_port_count() const;
@ -695,6 +692,50 @@ public:
VisualScriptComment(); VisualScriptComment();
}; };
class VisualScriptConstructor: public VisualScriptNode {
OBJ_TYPE(VisualScriptConstructor,VisualScriptNode)
Variant::Type type;
MethodInfo constructor;
protected:
virtual bool _use_builtin_script() const { return true; }
static void _bind_methods();
public:
virtual int get_output_sequence_port_count() const;
virtual bool has_input_sequence_port() const;
virtual String get_output_sequence_port_text(int p_port) const;
virtual int get_input_value_port_count() const;
virtual int get_output_value_port_count() const;
virtual PropertyInfo get_input_value_port_info(int p_idx) const;
virtual PropertyInfo get_output_value_port_info(int p_idx) const;
virtual String get_caption() const;
virtual String get_text() const;
virtual String get_category() const;
void set_constructor_type(Variant::Type p_type);
Variant::Type get_constructor_type() const;
void set_constructor(const Dictionary& p_info);
Dictionary get_constructor() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptConstructor();
};
void register_visual_script_nodes(); void register_visual_script_nodes();
void unregister_visual_script_nodes();
#endif // VISUAL_SCRIPT_NODES_H #endif // VISUAL_SCRIPT_NODES_H

View file

@ -84,6 +84,11 @@ void CustomPropertyEditor::_menu_option(int p_which) {
v=val; v=val;
emit_signal("variant_changed"); emit_signal("variant_changed");
} else if (hint==PROPERTY_HINT_ENUM) {
v=p_which;
emit_signal("variant_changed");
} }
} break; } break;
case Variant::OBJECT: { case Variant::OBJECT: {
@ -283,6 +288,16 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
switch(type) { switch(type) {
case Variant::BOOL: {
CheckBox *c=checks20[0];
c->set_text("True");
c->set_pos(Vector2(4,4));
c->set_pressed(v);
c->show();
set_size(checks20[0]->get_pos()+checks20[0]->get_size()+Vector2(4,4)*EDSCALE);
} break;
case Variant::INT: case Variant::INT:
case Variant::REAL: { case Variant::REAL: {
@ -323,9 +338,24 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
set_size(Size2(70,35)*EDSCALE); set_size(Size2(70,35)*EDSCALE);
} }
} else if (hint==PROPERTY_HINT_ENUM) {
menu->clear();
Vector<String> options = hint_text.split(",");
for(int i=0;i<options.size();i++) {
menu->add_item(options[i],i);
}
menu->set_pos(get_pos());
menu->popup();
hide();
updating=false;
return false;
} else if (hint==PROPERTY_HINT_ALL_FLAGS) { } else if (hint==PROPERTY_HINT_ALL_FLAGS) {
checks20[0]->set_text("");
uint32_t flgs = v; uint32_t flgs = v;
for(int i=0;i<2;i++) { for(int i=0;i<2;i++) {
@ -1117,6 +1147,10 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
return; return;
switch(type) { switch(type) {
case Variant::BOOL: {
v=checks20[0]->is_pressed();
emit_signal("variant_changed");
} break;
case Variant::INT: { case Variant::INT: {
if (hint==PROPERTY_HINT_ALL_FLAGS) { if (hint==PROPERTY_HINT_ALL_FLAGS) {

View file

@ -42,12 +42,12 @@ public:
void select_method_from_base_type(const String& p_base,const String& p_current=""); void select_method_from_base_type(const String& p_base,const String& p_current="");
void select_method_from_script(const Ref<Script>& p_script,const String& p_current=""); void select_method_from_script(const Ref<Script>& p_script,const String& p_current="");
void select_method_from_basic_type(Variant::Type p_type,const String& p_current=""); void select_method_from_basic_type(Variant::Type p_type,const String& p_current="");
void select_method_from_instance(Object* p_instance, const String &p_current); void select_method_from_instance(Object* p_instance, const String &p_current="");
void select_property_from_base_type(const String& p_base,const String& p_current=""); void select_property_from_base_type(const String& p_base,const String& p_current="");
void select_property_from_script(const Ref<Script>& p_script,const String& p_current=""); void select_property_from_script(const Ref<Script>& p_script,const String& p_current="");
void select_property_from_basic_type(Variant::Type p_type,InputEvent::Type p_event_type,const String& p_current=""); void select_property_from_basic_type(Variant::Type p_type,InputEvent::Type p_event_type,const String& p_current="");
void select_property_from_instance(Object* p_instance, const String &p_current); void select_property_from_instance(Object* p_instance, const String &p_current="");
PropertySelector(); PropertySelector();
}; };