More visual script work

-Block switches to 2d/3d editor if editing visual script
-Added cast node in flow control
-Added ability to do RPC in visual script
-Comment nodes
-Fix bug with inverted cable in connecting backwards
-Copy and paste nodes, including from different scripts
This commit is contained in:
Juan Linietsky 2016-08-25 17:45:20 -03:00
parent 41a58f7935
commit 9c6175db11
35 changed files with 1707 additions and 252 deletions

View file

@ -59,30 +59,112 @@ struct _ObjectDebugLock {
#endif
PropertyInfo::operator Dictionary() const {
Dictionary d;
d["name"]=name;
d["type"]=type;
d["hint"]=hint;
d["hint_string"]=hint_string;
d["usage"]=usage;
return d;
}
PropertyInfo PropertyInfo::from_dict(const Dictionary& p_dict) {
PropertyInfo pi;
if (p_dict.has("type"))
pi.type=Variant::Type(int(p_dict["type"]));
if (p_dict.has("name"))
pi.name=p_dict["name"];
if (p_dict.has("hint"))
pi.hint=PropertyHint(int(p_dict["hint"]));
if (p_dict.has("hint_string"))
pi.hint_string=p_dict["hint_string"];
if (p_dict.has("usage"))
pi.usage=p_dict["usage"];
return pi;
}
Array convert_property_list(const List<PropertyInfo> * p_list) {
Array va;
for (const List<PropertyInfo>::Element *E=p_list->front();E;E=E->next()) {
const PropertyInfo &pi = E->get();
Dictionary d;
d["name"]=pi.name;
d["type"]=pi.type;
d["hint"]=pi.hint;
d["hint_string"]=pi.hint_string;
d["usage"]=pi.usage;
va.push_back(d);
va.push_back(Dictionary(E->get()));
}
return va;
}
MethodInfo::operator Dictionary() const {
Dictionary d;
d["name"]=name;
d["args"]=convert_property_list(&arguments);
Array da;
for(int i=0;i<default_arguments.size();i++)
da.push_back(default_arguments[i]);
d["default_args"]=da;
d["flags"]=flags;
d["id"]=id;
Dictionary r = return_val;
d["return"]=r;
return d;
}
MethodInfo::MethodInfo() {
id=0;
flags=METHOD_FLAG_NORMAL;
}
MethodInfo MethodInfo::from_dict(const Dictionary& p_dict) {
MethodInfo mi;
if (p_dict.has("name"))
mi.name=p_dict["name"];
Array args;
if (p_dict.has("args")) {
args=p_dict["args"];
}
for(int i=0;i<args.size();i++) {
Dictionary d = args[i];
mi.arguments.push_back(PropertyInfo::from_dict(d));
}
Array defargs;
if (p_dict.has("default_args")) {
defargs=p_dict["default_args"];
}
for(int i=0;i<defargs.size();i++) {
mi.default_arguments.push_back(defargs[i]);
}
if (p_dict.has("return")) {
mi.return_val=PropertyInfo::from_dict(p_dict["return"]);
}
if (p_dict.has("flags"))
mi.flags=p_dict["flags"];
return mi;
}
MethodInfo::MethodInfo(const String& p_name) {
id=0;
@ -1012,25 +1094,6 @@ Array Object::_get_property_list_bind() const {
}
static Dictionary _get_dict_from_method(const MethodInfo &mi) {
Dictionary d;
d["name"]=mi.name;
d["args"]=convert_property_list(&mi.arguments);
Array da;
for(int i=0;i<mi.default_arguments.size();i++)
da.push_back(mi.default_arguments[i]);
d["default_args"]=da;
d["flags"]=mi.flags;
d["id"]=mi.id;
Dictionary r;
r["type"]=mi.return_val.type;
r["hint"]=mi.return_val.hint;
r["hint_string"]=mi.return_val.hint_string;
d["return_type"]=r;
return d;
}
Array Object::_get_method_list_bind() const {
@ -1040,7 +1103,7 @@ Array Object::_get_method_list_bind() const {
for(List<MethodInfo>::Element *E=ml.front();E;E=E->next()) {
Dictionary d = _get_dict_from_method(E->get());
Dictionary d = E->get();
//va.push_back(d);
ret.push_back(d);
}
@ -1305,7 +1368,7 @@ Array Object::_get_signal_list() const{
Array ret;
for (List<MethodInfo>::Element *E=signal_list.front();E;E=E->next()) {
ret.push_back(_get_dict_from_method(E->get()));
ret.push_back(Dictionary(E->get()));
}
return ret;

View file

@ -126,6 +126,11 @@ struct PropertyInfo {
_FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const { PropertyInfo pi=*this; pi.usage|=p_fl; return pi; }
operator Dictionary() const;
static PropertyInfo from_dict(const Dictionary& p_dict);
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;
@ -150,6 +155,9 @@ struct MethodInfo {
inline bool operator<(const MethodInfo& p_method) const { return id==p_method.id?(name < p_method.name):(id<p_method.id); }
operator Dictionary() const;
static MethodInfo from_dict(const Dictionary& p_dict);
MethodInfo();
MethodInfo(const String& p_name);
MethodInfo(const String& p_name, const PropertyInfo& p_param1);

View file

@ -642,7 +642,7 @@ void ObjectTypeDB::get_property_list(StringName p_type, List<PropertyInfo> *p_li
TypeInfo *check=type;
while(check) {
for(List<PropertyInfo>::Element *E=type->property_list.front();E;E=E->next()) {
for(List<PropertyInfo>::Element *E=check->property_list.front();E;E=E->next()) {
if (p_validator) {

View file

@ -33,6 +33,7 @@ int ScriptServer::_language_count=0;
bool ScriptServer::scripting_enabled=true;
bool ScriptServer::reload_scripts_on_save=false;
ScriptEditRequestFunction ScriptServer::edit_request_func=NULL;
void Script::_notification( int p_what) {

View file

@ -38,6 +38,8 @@
class ScriptLanguage;
typedef void (*ScriptEditRequestFunction)(const String& p_path);
class ScriptServer {
enum {
@ -50,6 +52,8 @@ class ScriptServer {
static bool reload_scripts_on_save;
public:
static ScriptEditRequestFunction edit_request_func;
static void set_scripting_enabled(bool p_enabled);
static bool is_scripting_enabled();
static int get_language_count();
@ -88,6 +92,8 @@ public:
virtual bool can_instance() const=0;
virtual Ref<Script> get_base_script() const=0; //for script inheritance
virtual StringName get_instance_base_type() const=0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance* instance_create(Object *p_this)=0;
virtual bool instance_has(const Object *p_this) const=0;

View file

@ -179,6 +179,15 @@ bool GDScript::can_instance() const {
}
Ref<Script> GDScript::get_base_script() const {
if (_base) {
return Ref<GDScript>( _base );
} else {
return Ref<Script>();
}
}
StringName GDScript::get_instance_base_type() const {
if (native.is_valid())

View file

@ -162,6 +162,8 @@ public:
Variant _new(const Variant** p_args,int p_argcount,Variant::CallError& r_error);
virtual bool can_instance() const;
virtual Ref<Script> get_base_script() const;
virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so
virtual ScriptInstance* instance_create(Object *p_this);
virtual bool instance_has(const Object *p_this) const;

View file

@ -43,6 +43,10 @@ VisualScriptLanguage *visual_script_language=NULL;
void register_visual_script_types() {
visual_script_language=memnew( VisualScriptLanguage );
//script_language_gd->init();
ScriptServer::register_language(visual_script_language);
ObjectTypeDB::register_type<VisualScript>();
ObjectTypeDB::register_virtual_type<VisualScriptNode>();
ObjectTypeDB::register_virtual_type<VisualScriptFunctionState>();
@ -62,6 +66,7 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptSelf>();
ObjectTypeDB::register_type<VisualScriptCustomNode>();
ObjectTypeDB::register_type<VisualScriptSubCall>();
ObjectTypeDB::register_type<VisualScriptComment>();
ObjectTypeDB::register_type<VisualScriptFunctionCall>();
ObjectTypeDB::register_type<VisualScriptPropertySet>();
@ -82,9 +87,6 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptBuiltinFunc>();
visual_script_language=memnew( VisualScriptLanguage );
//script_language_gd->init();
ScriptServer::register_language(visual_script_language);
register_visual_script_nodes();
register_visual_script_func_nodes();

View file

@ -1,7 +1,7 @@
#include "visual_script.h"
#include "visual_script_nodes.h"
#include "scene/main/node.h"
#include "os/os.h"
#include "globals.h"
#define SCRIPT_VARIABLES_PREFIX "script_variables/"
@ -31,11 +31,13 @@ void VisualScriptNode::_notification(int p_what) {
void VisualScriptNode::ports_changed_notify(){
default_input_values.resize( MAX(default_input_values.size(),get_input_value_port_count()) ); //let it grow as big as possible, we don't want to lose values on resize
emit_signal("ports_changed");
}
void VisualScriptNode::set_default_input_value(int p_port,const Variant& p_value) {
void VisualScriptNode::set_default_input_value(int p_port,const Variant& p_value) {
ERR_FAIL_INDEX(p_port,default_input_values.size());
@ -54,35 +56,40 @@ void VisualScriptNode::_set_default_input_values(Array p_values) {
default_input_values=p_values;
}
Array VisualScriptNode::_get_default_input_values() const {
//validate on save, since on load there is little info about this
void VisualScriptNode::validate_input_default_values() {
Array saved_values;
default_input_values.resize(get_input_value_port_count());
//actually validate on save
for(int i=0;i<get_input_value_port_count();i++) {
Variant::Type expected = get_input_value_port_info(i).type;
if (i>=default_input_values.size()) {
if (expected==Variant::NIL || expected==default_input_values[i].get_type()) {
continue;
} else {
//not the same, reconvert
Variant::CallError ce;
saved_values.push_back(Variant::construct(expected,NULL,0,ce,false));
} else {
if (expected==Variant::NIL || expected==default_input_values[i].get_type()) {
saved_values.push_back(default_input_values[i]);
} else {
//not the same, reconvert
Variant::CallError ce;
Variant existing = default_input_values[i];
const Variant *existingp=&existing;
saved_values.push_back( Variant::construct(expected,&existingp,1,ce,false) );
Variant existing = default_input_values[i];
const Variant *existingp=&existing;
default_input_values[i] = Variant::construct(expected,&existingp,1,ce,false);
if (ce.error!=Variant::CallError::CALL_OK) {
//could not convert? force..
default_input_values[i] = Variant::construct(expected,NULL,0,ce,false);
}
}
}
return saved_values;
}
Array VisualScriptNode::_get_default_input_values() const {
//validate on save, since on load there is little info about this
return default_input_values;
}
@ -224,6 +231,7 @@ int VisualScript::get_function_node_id(const StringName& p_name) const {
void VisualScript::_node_ports_changed(int p_id) {
StringName function;
for (Map<StringName,Function>::Element *E=functions.front();E;E=E->next()) {
@ -239,6 +247,10 @@ void VisualScript::_node_ports_changed(int p_id) {
Function &func = functions[function];
Ref<VisualScriptNode> vsn = func.nodes[p_id].node;
if (OS::get_singleton()->get_main_loop() && OS::get_singleton()->get_main_loop()->cast_to<SceneTree>() && OS::get_singleton()->get_main_loop()->cast_to<SceneTree>()->is_editor_hint()) {
vsn->validate_input_default_values(); //force validate default values when editing on editor
}
//must revalidate all the functions
{
@ -836,6 +848,10 @@ StringName VisualScript::get_instance_base_type() const {
return base_type;
}
Ref<Script> VisualScript::get_base_script() const {
return Ref<Script>(); // no inheritance in visual script
}
#ifdef TOOLS_ENABLED
void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
@ -1884,8 +1900,23 @@ Ref<Script> VisualScriptInstance::get_script() const{
ScriptInstance::RPCMode VisualScriptInstance::get_rpc_mode(const StringName& p_method) const {
const Map<StringName,VisualScript::Function>::Element *E = script->functions.find(p_method);
if (!E) {
return RPC_MODE_DISABLED;
}
if (E->get().function_id>=0 && E->get().nodes.has(E->get().function_id)) {
Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
if (vsf.is_valid()) {
return vsf->get_rpc_mode();
}
}
return RPC_MODE_DISABLED;
}
ScriptInstance::RPCMode VisualScriptInstance::get_rset_mode(const StringName& p_variable) const {
return RPC_MODE_DISABLED;

View file

@ -20,6 +20,8 @@ friend class VisualScript;
void _set_default_input_values(Array p_values);
Array _get_default_input_values() const;
void validate_input_default_values();
protected:
virtual bool _use_builtin_script() const { return false; }
@ -300,6 +302,7 @@ public:
virtual bool can_instance() const;
virtual Ref<Script> get_base_script() const;
virtual StringName get_instance_base_type() const;
virtual ScriptInstance* instance_create(Object *p_this);
virtual bool instance_has(const Object *p_this) const;

View file

@ -347,6 +347,8 @@ void VisualScriptEditor::_update_graph_connections() {
void VisualScriptEditor::_update_graph(int p_only_id) {
if (updating_graph)
return;
updating_graph=true;
@ -451,10 +453,21 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_show_close_button(true);
}
Label *text = memnew( Label );
text->set_text(node->get_text());
gnode->add_child(text);
if (node->cast_to<VisualScriptComment>()) {
Ref<VisualScriptComment> vsc=node;
gnode->set_comment(true);
gnode->set_resizeable(true);
gnode->set_custom_minimum_size(vsc->get_size()*EDSCALE);
gnode->connect("resize_request",this,"_comment_node_resized",varray(E->get()));
}
int slot_idx=0;
bool single_seq_output = node->get_output_sequence_port_count()==1 && node->get_output_sequence_port_text(0)==String();
@ -480,6 +493,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Variant::Type left_type=Variant::NIL;
String left_name;
if (i<node->get_input_value_port_count()) {
PropertyInfo pi = node->get_input_value_port_info(i);
left_ok=true;
@ -563,6 +577,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
graph->add_child(gnode);
if (gnode->is_comment()) {
graph->move_child(gnode,0);
}
}
_update_graph_connections();
@ -2340,6 +2358,39 @@ void VisualScriptEditor::_graph_ofs_changed(const Vector2& p_ofs) {
updating_graph=false;
}
void VisualScriptEditor::_comment_node_resized(const Vector2& p_new_size,int p_node) {
if (updating_graph)
return;
Ref<VisualScriptComment> vsc = script->get_node(edited_func,p_node);
if (vsc.is_null())
return;
Node *node = graph->get_node(itos(p_node));
if (!node)
return;
GraphNode *gn = node->cast_to<GraphNode>();
if (!gn)
return;
updating_graph=true;
graph->set_block_minimum_size_adjust(true); //faster resize
undo_redo->create_action("Resize Comment",true);
undo_redo->add_do_method(vsc.ptr(),"set_size",p_new_size/EDSCALE);
undo_redo->add_undo_method(vsc.ptr(),"set_size",vsc->get_size());
undo_redo->commit_action();
gn->set_custom_minimum_size(p_new_size); //for this time since graph update is blocked
gn->set_size(Size2(1,1));
graph->set_block_minimum_size_adjust(false);
updating_graph=false;
}
void VisualScriptEditor::_menu_option(int p_what) {
switch(p_what) {
@ -2375,7 +2426,150 @@ void VisualScriptEditor::_menu_option(int p_what) {
//popup disappearing grabs focus to owner, so use call deferred
node_filter->call_deferred("grab_focus");
node_filter->call_deferred("select_all");
} break;
case EDIT_COPY_NODES:
case EDIT_CUT_NODES: {
if (!script->has_function(edited_func))
break;
clipboard.nodes.clear();
clipboard.data_connections.clear();
clipboard.sequence_connections.clear();
for(int i=0;i<graph->get_child_count();i++) {
GraphNode *gn = graph->get_child(i)->cast_to<GraphNode>();
if (gn) {
if (gn->is_selected()) {
int id = String(gn->get_name()).to_int();
Ref<VisualScriptNode> node = script->get_node(edited_func,id);
if (node->cast_to<VisualScriptFunction>()) {
EditorNode::get_singleton()->show_warning("Can't copy the function node.");
return;
}
if (node.is_valid()) {
clipboard.nodes[id]=node->duplicate();
clipboard.nodes_positions[id]=script->get_node_pos(edited_func,id);
}
}
}
}
if (clipboard.nodes.empty())
break;
List<VisualScript::SequenceConnection> sequence_connections;
script->get_sequence_connection_list(edited_func,&sequence_connections);
for (List<VisualScript::SequenceConnection>::Element *E=sequence_connections.front();E;E=E->next()) {
if (clipboard.nodes.has(E->get().from_node) && clipboard.nodes.has(E->get().to_node)) {
clipboard.sequence_connections.insert(E->get());
}
}
List<VisualScript::DataConnection> data_connections;
script->get_data_connection_list(edited_func,&data_connections);
for (List<VisualScript::DataConnection>::Element *E=data_connections.front();E;E=E->next()) {
if (clipboard.nodes.has(E->get().from_node) && clipboard.nodes.has(E->get().to_node)) {
clipboard.data_connections.insert(E->get());
}
}
if (p_what==EDIT_CUT_NODES) {
_on_nodes_delete(); // oh yeah, also delete on cut
}
} break;
case EDIT_PASTE_NODES: {
if (!script->has_function(edited_func))
break;
if (clipboard.nodes.empty()) {
EditorNode::get_singleton()->show_warning("Clipboard is empty!");
break;
}
Map<int,int> remap;
undo_redo->create_action("Paste VisualScript Nodes");
int idc=script->get_available_id()+1;
Set<int> to_select;
Set<Vector2> existing_positions;
{
List<int> nodes;
script->get_node_list(edited_func,&nodes);
for (List<int>::Element *E=nodes.front();E;E=E->next()) {
Vector2 pos = script->get_node_pos(edited_func,E->get()).snapped(Vector2(2,2));
existing_positions.insert(pos);
}
}
for (Map<int,Ref<VisualScriptNode> >::Element *E=clipboard.nodes.front();E;E=E->next()) {
Ref<VisualScriptNode> node = E->get()->duplicate();
int new_id = idc++;
to_select.insert(new_id);
remap[E->key()]=new_id;
Vector2 paste_pos = clipboard.nodes_positions[E->key()];
while(existing_positions.has(paste_pos.snapped(Vector2(2,2)))) {
paste_pos+=Vector2(20,20)*EDSCALE;
}
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,new_id,node,paste_pos);
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,new_id);
}
for (Set<VisualScript::SequenceConnection>::Element *E=clipboard.sequence_connections.front();E;E=E->next()) {
undo_redo->add_do_method(script.ptr(),"sequence_connect",edited_func,remap[E->get().from_node],E->get().from_output,remap[E->get().to_node]);
undo_redo->add_undo_method(script.ptr(),"sequence_disconnect",edited_func,remap[E->get().from_node],E->get().from_output,remap[E->get().to_node]);
}
for (Set<VisualScript::DataConnection>::Element *E=clipboard.data_connections.front();E;E=E->next()) {
undo_redo->add_do_method(script.ptr(),"data_connect",edited_func,remap[E->get().from_node],E->get().from_port,remap[E->get().to_node],E->get().to_port);
undo_redo->add_undo_method(script.ptr(),"data_disconnect",edited_func,remap[E->get().from_node],E->get().from_port,remap[E->get().to_node],E->get().to_port);
}
undo_redo->add_do_method(this,"_update_graph");
undo_redo->add_undo_method(this,"_update_graph");
undo_redo->commit_action();
for(int i=0;i<graph->get_child_count();i++) {
GraphNode *gn = graph->get_child(i)->cast_to<GraphNode>();
if (gn) {
int id = gn->get_name().operator String().to_int();
gn->set_selected(to_select.has(id));
}
}
} break;
}
}
@ -2403,6 +2597,7 @@ void VisualScriptEditor::_bind_methods() {
ObjectTypeDB::bind_method("_menu_option",&VisualScriptEditor::_menu_option);
ObjectTypeDB::bind_method("_graph_ofs_changed",&VisualScriptEditor::_graph_ofs_changed);
ObjectTypeDB::bind_method("_center_on_node",&VisualScriptEditor::_center_on_node);
ObjectTypeDB::bind_method("_comment_node_resized",&VisualScriptEditor::_comment_node_resized);
@ -2437,6 +2632,11 @@ VisualScriptEditor::VisualScriptEditor() {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/delete_selected"), EDIT_DELETE_NODES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/copy_nodes"), EDIT_COPY_NODES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/cut_nodes"), EDIT_CUT_NODES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/paste_nodes"), EDIT_PASTE_NODES);
edit_menu->get_popup()->connect("item_pressed",this,"_menu_option");
main_hsplit = memnew( HSplitContainer );
@ -2619,7 +2819,10 @@ static void register_editor_callback() {
ED_SHORTCUT("visual_script_editor/delete_selected", TTR("Delete Selected"));
ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Tyoe"), KEY_MASK_CMD+KEY_F);
ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KEY_MASK_CMD+KEY_F);
ED_SHORTCUT("visual_script_editor/copy_nodes", TTR("Copy Nodes"), KEY_MASK_CMD+KEY_C);
ED_SHORTCUT("visual_script_editor/cut_nodes", TTR("Cut Nodes"), KEY_MASK_CMD+KEY_X);
ED_SHORTCUT("visual_script_editor/paste_nodes", TTR("Paste Nodes"), KEY_MASK_CMD+KEY_V);
}

View file

@ -27,6 +27,9 @@ class VisualScriptEditor : public ScriptEditorBase {
EDIT_DELETE_NODES,
EDIT_TOGGLE_BREAKPOINT,
EDIT_FIND_NODE_TYPE,
EDIT_COPY_NODES,
EDIT_CUT_NODES,
EDIT_PASTE_NODES,
};
MenuButton *edit_menu;
@ -98,6 +101,15 @@ class VisualScriptEditor : public ScriptEditorBase {
String _validate_name(const String& p_name) const;
struct Clipboard {
Map<int,Ref<VisualScriptNode> > nodes;
Map<int,Vector2 > nodes_positions;
Set<VisualScript::SequenceConnection> sequence_connections;
Set<VisualScript::DataConnection> data_connections;
} clipboard;
int error_line;
@ -149,6 +161,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _menu_option(int p_what);
void _graph_ofs_changed(const Vector2& p_ofs);
void _comment_node_resized(const Vector2& p_new_size,int p_node);
protected:
@ -179,6 +192,7 @@ public:
virtual void set_debugger_active(bool p_active);
virtual void set_tooltip_request_func(String p_method,Object* p_obj);
virtual Control *get_edit_menu();
virtual bool can_lose_focus_on_node_selection() { return false; }
static void register_editor();

View file

@ -2,6 +2,7 @@
#include "os/keyboard.h"
#include "globals.h"
//////////////////////////////////////////
////////////////RETURN////////////////////
//////////////////////////////////////////
@ -1660,6 +1661,197 @@ VisualScriptInputFilter::VisualScriptInputFilter() {
}
//////////////////////////////////////////
////////////////EVENT TYPE FILTER///////////
//////////////////////////////////////////
int VisualScriptTypeCast::get_output_sequence_port_count() const {
return 2;
}
bool VisualScriptTypeCast::has_input_sequence_port() const{
return true;
}
int VisualScriptTypeCast::get_input_value_port_count() const{
return 1;
}
int VisualScriptTypeCast::get_output_value_port_count() const{
return 1;
}
String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const {
return p_port==0 ? "yes" : "no";
}
PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const{
return PropertyInfo(Variant::OBJECT,"instance");
}
PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const{
return PropertyInfo(Variant::OBJECT,"");
}
String VisualScriptTypeCast::get_caption() const {
return "TypeCast";
}
String VisualScriptTypeCast::get_text() const {
if (script!=String())
return "Is "+script.get_file()+"?";
else
return "Is "+base_type+"?";
}
void VisualScriptTypeCast::set_base_type(const StringName& p_type) {
if (base_type==p_type)
return;
base_type=p_type;
_change_notify();
ports_changed_notify();
}
StringName VisualScriptTypeCast::get_base_type() const{
return base_type;
}
void VisualScriptTypeCast::set_base_script(const String& p_path){
if (script==p_path)
return;
script=p_path;
_change_notify();
ports_changed_notify();
}
String VisualScriptTypeCast::get_base_script() const{
return script;
}
class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance {
public:
VisualScriptInstance* instance;
StringName base_type;
String script;
//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) {
Object *obj = *p_inputs[0];
*p_outputs[0]=Variant();
if (!obj) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str="Instance is null";
return 0;
}
if (script!=String()) {
Ref<Script> obj_script = obj->get_script();
if (!obj_script.is_valid()) {
return 1; //well, definitely not the script because object we got has no script.
}
if (!ResourceCache::has(script)) {
//if the script is not in use by anyone, we can safely assume whathever we got is not casting to it.
return 1;
}
Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
if (!cast_script.is_valid()) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str="Script path is not a script: "+script;
return 1;
}
while(obj_script.is_valid()) {
if (cast_script==obj_script) {
*p_outputs[0]=*p_inputs[0]; //copy
return 0; // it is the script, yey
}
obj_script=obj_script->get_base_script();
}
return 1; //not found sorry
}
if (ObjectTypeDB::is_type(obj->get_type_name(),base_type)) {
*p_outputs[0]=*p_inputs[0]; //copy
return 0;
} else
return 1;
}
};
VisualScriptNodeInstance* VisualScriptTypeCast::instance(VisualScriptInstance* p_instance) {
VisualScriptNodeInstanceTypeCast * instance = memnew(VisualScriptNodeInstanceTypeCast );
instance->instance=p_instance;
instance->base_type=base_type;
instance->script=script;
return instance;
}
void VisualScriptTypeCast::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_type","type"),&VisualScriptTypeCast::set_base_type);
ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptTypeCast::get_base_type);
ObjectTypeDB::bind_method(_MD("set_base_script","path"),&VisualScriptTypeCast::set_base_script);
ObjectTypeDB::bind_method(_MD("get_base_script"),&VisualScriptTypeCast::get_base_script);
List<String> script_extensions;
for(int i=0;i>ScriptServer::get_language_count();i++) {
ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
}
String script_ext_hint;
for (List<String>::Element *E=script_extensions.front();E;E=E->next()) {
if (script_ext_hint!=String())
script_ext_hint+=",";
script_ext_hint+="*."+E->get();
}
ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_script",PROPERTY_HINT_FILE,script_ext_hint),_SCS("set_base_script"),_SCS("get_base_script"));
}
VisualScriptTypeCast::VisualScriptTypeCast() {
base_type="Object";
}
void register_visual_script_flow_control_nodes() {
@ -1672,6 +1864,7 @@ void register_visual_script_flow_control_nodes() {
VisualScriptLanguage::singleton->add_register_func("flow_control/sequence",create_node_generic<VisualScriptSequence>);
VisualScriptLanguage::singleton->add_register_func("flow_control/input_select",create_node_generic<VisualScriptInputSelector>);
VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter",create_node_generic<VisualScriptInputFilter>);
VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast",create_node_generic<VisualScriptTypeCast>);

View file

@ -273,6 +273,53 @@ public:
VisualScriptInputFilter();
};
class VisualScriptTypeCast : public VisualScriptNode {
OBJ_TYPE(VisualScriptTypeCast,VisualScriptNode)
StringName base_type;
String script;
protected:
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 { return "flow_control"; }
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
void set_base_script(const String& p_path);
String get_base_script() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptTypeCast();
};
void register_visual_script_flow_control_nodes();

File diff suppressed because it is too large Load diff

View file

@ -14,19 +14,36 @@ public:
CALL_MODE_INSTANCE,
CALL_MODE_BASIC_TYPE,
};
enum RPCCallMode {
RPC_DISABLED,
RPC_RELIABLE,
RPC_UNRELIABLE,
RPC_RELIABLE_TO_ID,
RPC_UNRELIABLE_TO_ID
};
private:
CallMode call_mode;
StringName base_type;
String base_script;
Variant::Type basic_type;
NodePath base_path;
StringName function;
int use_default_args;
RPCCallMode rpc_call_mode;
Node *_get_base_node() const;
StringName _get_base_type() const;
void _update_defargs();
MethodInfo method_cache;
void _update_method_cache();
void _set_argument_cache(const Dictionary& p_args);
Dictionary _get_argument_cache() const;
protected:
virtual void _validate_property(PropertyInfo& property) const;
@ -58,6 +75,9 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
void set_base_script(const String& p_path);
String get_base_script() const;
void set_function(const StringName& p_type);
StringName get_function() const;
@ -70,12 +90,16 @@ public:
void set_use_default_args(int p_amount);
int get_use_default_args() const;
void set_rpc_call_mode(RPCCallMode p_mode);
RPCCallMode get_rpc_call_mode() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptFunctionCall();
};
VARIANT_ENUM_CAST(VisualScriptFunctionCall::CallMode );
VARIANT_ENUM_CAST(VisualScriptFunctionCall::RPCCallMode );
class VisualScriptPropertySet : public VisualScriptNode {
@ -92,9 +116,12 @@ public:
};
private:
PropertyInfo type_cache;
CallMode call_mode;
Variant::Type basic_type;
StringName base_type;
String base_script;
NodePath base_path;
StringName property;
bool use_builtin_value;
@ -106,6 +133,12 @@ private:
void _update_base_type();
void _update_cache();
void _set_type_cache(const Dictionary& p_type);
Dictionary _get_type_cache() const;
protected:
virtual void _validate_property(PropertyInfo& property) const;
@ -134,6 +167,9 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
void set_base_script(const String& p_path);
String get_base_script() const;
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
@ -171,14 +207,17 @@ public:
CALL_MODE_SELF,
CALL_MODE_NODE_PATH,
CALL_MODE_INSTANCE,
CALL_MODE_BASIC_TYPE
CALL_MODE_BASIC_TYPE,
};
private:
Variant::Type type_cache;
CallMode call_mode;
Variant::Type basic_type;
StringName base_type;
String base_script;
NodePath base_path;
StringName property;
InputEvent::Type event_type;
@ -187,6 +226,10 @@ private:
Node *_get_base_node() const;
StringName _get_base_type() const;
void _update_cache();
void _set_type_cache(Variant::Type p_type);
Variant::Type _get_type_cache() const;
protected:
virtual void _validate_property(PropertyInfo& property) const;
@ -216,6 +259,9 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
void set_base_script(const String& p_path);
String get_base_script() const;
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;

View file

@ -62,6 +62,12 @@ bool VisualScriptFunction::_set(const StringName& p_name, const Variant& p_valu
stack_size=p_value;
return true;
}
if (p_name=="rpc/mode") {
rpc_mode=ScriptInstance::RPCMode(int(p_value));
return true;
}
return false;
}
@ -99,6 +105,11 @@ bool VisualScriptFunction::_get(const StringName& p_name,Variant &r_ret) const
return true;
}
if (p_name=="rpc/mode") {
r_ret=rpc_mode;
return true;
}
return false;
}
void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) const {
@ -118,6 +129,7 @@ void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::INT,"stack/size",PROPERTY_HINT_RANGE,"1,100000"));
}
p_list->push_back(PropertyInfo(Variant::BOOL,"stack/stackless"));
p_list->push_back(PropertyInfo(Variant::INT,"rpc/mode",PROPERTY_HINT_ENUM,"Disabled,Remote,Sync,Master,Slave"));
}
@ -224,6 +236,16 @@ int VisualScriptFunction::get_argument_count() const {
return arguments.size();
}
void VisualScriptFunction::set_rpc_mode(ScriptInstance::RPCMode p_mode) {
rpc_mode=p_mode;
}
ScriptInstance::RPCMode VisualScriptFunction::get_rpc_mode() const {
return rpc_mode;
}
class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance {
public:
@ -272,6 +294,7 @@ VisualScriptFunction::VisualScriptFunction() {
stack_size=256;
stack_less=false;
rpc_mode=ScriptInstance::RPC_MODE_DISABLED;
}
@ -2432,6 +2455,153 @@ VisualScriptSubCall::VisualScriptSubCall() {
}
//////////////////////////////////////////
////////////////Comment///////////
//////////////////////////////////////////
int VisualScriptComment::get_output_sequence_port_count() const {
return 0;
}
bool VisualScriptComment::has_input_sequence_port() const{
return false;
}
int VisualScriptComment::get_input_value_port_count() const{
return 0;
}
int VisualScriptComment::get_output_value_port_count() const{
return 0;
}
String VisualScriptComment::get_output_sequence_port_text(int p_port) const {
return String();
}
PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const{
return PropertyInfo();
}
PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const{
return PropertyInfo();
}
String VisualScriptComment::get_caption() const {
return title;
}
String VisualScriptComment::get_text() const {
return description;
}
void VisualScriptComment::set_title(const String& p_title) {
if (title==p_title)
return;
title=p_title;
ports_changed_notify();
}
String VisualScriptComment::get_title() const{
return title;
}
void VisualScriptComment::set_description(const String& p_description){
if (description==p_description)
return;
description=p_description;
ports_changed_notify();
}
String VisualScriptComment::get_description() const{
return description;
}
void VisualScriptComment::set_size(const Size2& p_size){
if (size==p_size)
return;
size=p_size;
ports_changed_notify();
}
Size2 VisualScriptComment::get_size() const{
return size;
}
String VisualScriptComment::get_category() const {
return "data";
}
class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance {
public:
VisualScriptInstance* instance;
//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) {
return 0;
}
};
VisualScriptNodeInstance* VisualScriptComment::instance(VisualScriptInstance* p_instance) {
VisualScriptNodeInstanceComment * instance = memnew(VisualScriptNodeInstanceComment );
instance->instance=p_instance;
return instance;
}
void VisualScriptComment::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_title","title"),&VisualScriptComment::set_title);
ObjectTypeDB::bind_method(_MD("get_title"),&VisualScriptComment::get_title);
ObjectTypeDB::bind_method(_MD("set_description","description"),&VisualScriptComment::set_description);
ObjectTypeDB::bind_method(_MD("get_description"),&VisualScriptComment::get_description);
ObjectTypeDB::bind_method(_MD("set_size","size"),&VisualScriptComment::set_size);
ObjectTypeDB::bind_method(_MD("get_size"),&VisualScriptComment::get_size);
ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title"));
ADD_PROPERTY( PropertyInfo(Variant::STRING,"description",PROPERTY_HINT_MULTILINE_TEXT),_SCS("set_description"),_SCS("get_description"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"size"),_SCS("set_size"),_SCS("get_size"));
}
VisualScriptComment::VisualScriptComment() {
title="Comment";
size=Size2(150,150);
}
void register_visual_script_nodes() {
@ -2447,6 +2617,7 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("data/self",create_node_generic<VisualScriptSelf>);
VisualScriptLanguage::singleton->add_register_func("custom/custom_node",create_node_generic<VisualScriptCustomNode>);
VisualScriptLanguage::singleton->add_register_func("custom/sub_call",create_node_generic<VisualScriptSubCall>);
VisualScriptLanguage::singleton->add_register_func("data/comment",create_node_generic<VisualScriptComment>);
VisualScriptLanguage::singleton->add_register_func("index/get_index",create_node_generic<VisualScriptIndexGet>);

View file

@ -17,6 +17,7 @@ class VisualScriptFunction : public VisualScriptNode {
bool stack_less;
int stack_size;
ScriptInstance::RPCMode rpc_mode;
protected:
@ -60,6 +61,9 @@ public:
void set_stack_size(int p_size);
int get_stack_size() const;
void set_rpc_mode(ScriptInstance::RPCMode p_mode);
ScriptInstance::RPCMode get_rpc_mode() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptFunction();
@ -645,6 +649,51 @@ public:
VisualScriptSubCall();
};
class VisualScriptComment: public VisualScriptNode {
OBJ_TYPE(VisualScriptComment,VisualScriptNode)
String title;
String description;
Size2 size;
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_title(const String& p_title);
String get_title() const;
void set_description(const String& p_description);
String get_description() const;
void set_size(const Size2& p_size);
Size2 get_size() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptComment();
};
void register_visual_script_nodes();

View file

@ -45,12 +45,13 @@ PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const{
String VisualScriptYield::get_caption() const {
return "Wait";
return yield_mode==YIELD_RETURN?"Yield":"Wait";
}
String VisualScriptYield::get_text() const {
switch (yield_mode) {
case YIELD_RETURN: return ""; break;
case YIELD_FRAME: return "Next Frame"; break;
case YIELD_FIXED_FRAME: return "Next Fixed Frame"; break;
case YIELD_WAIT: return rtos(wait_time)+" sec(s)"; break;
@ -88,8 +89,10 @@ public:
Ref<VisualScriptFunctionState> state;
state.instance();
int ret = STEP_YIELD_BIT;
switch(mode) {
case VisualScriptYield::YIELD_RETURN: ret=STEP_EXIT_FUNCTION_BIT; break; //return the yield
case VisualScriptYield::YIELD_FRAME: state->connect_to_signal(tree,"idle_frame",Array()); break;
case VisualScriptYield::YIELD_FIXED_FRAME: state->connect_to_signal(tree,"fixed_frame",Array()); break;
case VisualScriptYield::YIELD_WAIT: state->connect_to_signal(tree->create_timer(wait_time).ptr(),"timeout",Array()); break;
@ -98,7 +101,7 @@ public:
*p_working_mem=state;
return STEP_YIELD_BIT;
return ret;
}
}
@ -487,7 +490,7 @@ void VisualScriptYieldSignal::_bind_methods() {
bt+=Variant::get_type_name(Variant::Type(i));
}
ADD_PROPERTY(PropertyInfo(Variant::INT,"signal/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"signal/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance"),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"signal/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"signal/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"signal/signal"),_SCS("set_signal"),_SCS("get_signal"));
@ -615,8 +618,8 @@ void register_visual_script_yield_nodes() {
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_fixed_frame",create_yield_node<VisualScriptYield::YIELD_FIXED_FRAME>);
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_time",create_yield_node<VisualScriptYield::YIELD_WAIT>);
VisualScriptLanguage::singleton->add_register_func("functions/yield/instance_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_INSTANCE>);
VisualScriptLanguage::singleton->add_register_func("functions/yield/self_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_SELF>);
VisualScriptLanguage::singleton->add_register_func("functions/yield/node_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_NODE_PATH>);
VisualScriptLanguage::singleton->add_register_func("functions/yield",create_yield_node<VisualScriptYield::YIELD_RETURN>);
VisualScriptLanguage::singleton->add_register_func("functions/yield_signal",create_node_generic<VisualScriptYieldSignal>);
}

View file

@ -9,6 +9,7 @@ class VisualScriptYield : public VisualScriptNode {
public:
enum YieldMode {
YIELD_RETURN,
YIELD_FRAME,
YIELD_FIXED_FRAME,
YIELD_WAIT

View file

@ -2214,7 +2214,7 @@ void Control::grab_click_focus() {
void Control::minimum_size_changed() {
if (!is_inside_tree())
if (!is_inside_tree() || data.block_minimum_size_adjust)
return;
if (data.pending_min_size_update)
@ -2374,8 +2374,14 @@ Control *Control::get_root_parent_control() const {
return const_cast<Control*>(root);
}
void Control::set_block_minimum_size_adjust(bool p_block) {
data.block_minimum_size_adjust=p_block;
}
bool Control::is_minimum_size_adjust_blocked() const {
return data.block_minimum_size_adjust;
}
void Control::_bind_methods() {
@ -2603,6 +2609,7 @@ Control::Control() {
data.scale=Vector2(1,1);
data.drag_owner=0;
data.modal_frame=0;
data.block_minimum_size_adjust=false;
for (int i=0;i<4;i++) {

View file

@ -128,6 +128,8 @@ private:
bool ignore_mouse;
bool stop_mouse;
bool block_minimum_size_adjust;
Control *parent;
ObjectID drag_owner;
bool modal;
@ -396,6 +398,10 @@ public:
Control *get_root_parent_control() const;
void set_block_minimum_size_adjust(bool p_block);
bool is_minimum_size_adjust_blocked() const;
Control();
~Control();

View file

@ -193,6 +193,9 @@ void GraphEdit::_graph_node_raised(Node* p_gn) {
GraphNode *gn=p_gn->cast_to<GraphNode>();
ERR_FAIL_COND(!gn);
gn->raise();
if (gn->is_comment()) {
move_child(gn,0);
}
top_layer->raise();
emit_signal("node_selected",p_gn);
@ -261,6 +264,7 @@ void GraphEdit::_notification(int p_what) {
}
if (p_what==NOTIFICATION_DRAW) {
draw_style_box( get_stylebox("bg"),Rect2(Point2(),get_size()) );
VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
@ -712,6 +716,10 @@ void GraphEdit::_top_layer_draw() {
col.g+=0.4;
col.b+=0.4;
}
if (!connecting_out) {
SWAP(pos,topos);
}
_draw_cos_line(top_layer,pos,topos,col,col);
}
@ -856,6 +864,10 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
gn=get_child(i)->cast_to<GraphNode>();
if (gn) {
if (gn->is_resizing())
continue;
Rect2 r = gn->get_rect();
r.size*=zoom;
if (r.has_point(get_local_mouse_pos()))

View file

@ -133,6 +133,7 @@ private:
bool lines_on_bg;
struct ConnType {
union {
@ -205,6 +206,7 @@ public:
int get_snap() const;
void set_snap(int p_snap);
GraphEdit();
};

View file

@ -188,11 +188,13 @@ void GraphNode::_notification(int p_what) {
if (p_what==NOTIFICATION_DRAW) {
Ref<StyleBox> sb=get_stylebox(selected ? "selectedframe" : "frame");
Ref<StyleBox> sb=get_stylebox(comment? "comment": (selected ? "selectedframe" : "frame"));
sb=sb->duplicate();
sb->call("set_modulate",modulate);
Ref<Texture> port =get_icon("port");
Ref<Texture> close =get_icon("close");
Ref<Texture> resizer =get_icon("resizer");
int close_offset = get_constant("close_offset");
Ref<Font> title_font = get_font("title_font");
int title_offset = get_constant("title_offset");
@ -258,6 +260,11 @@ void GraphNode::_notification(int p_what) {
}
}
if (resizeable) {
draw_texture(resizer,get_size()-resizer->get_size());
}
}
if (p_what==NOTIFICATION_SORT_CHILDREN) {
@ -594,19 +601,49 @@ void GraphNode::_input_event(const InputEvent& p_ev) {
ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node.");
ERR_FAIL_COND(get_parent_control() == NULL);
get_parent_control()->grab_focus();
if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) {
Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y);
if (close_rect.size!=Size2() && close_rect.has_point(mpos)) {
emit_signal("close_request");
accept_event();
return;
}
Ref<Texture> resizer =get_icon("resizer");
if (resizeable && mpos.x > get_size().x-resizer->get_width() && mpos.y > get_size().y-resizer->get_height()) {
resizing=true;
resizing_from=mpos;
resizing_from_size=get_size();
accept_event();
return;
}
//send focus to parent
emit_signal("raise_request");
get_parent_control()->grab_focus();
}
if(!p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) {
resizing=false;
}
}
if (resizing && p_ev.type==InputEvent::MOUSE_MOTION) {
Vector2 mpos = Vector2(p_ev.mouse_motion.x,p_ev.mouse_motion.y);
Vector2 diff = mpos - resizing_from;
emit_signal("resize_request",resizing_from_size+diff);
}
}
void GraphNode::set_modulate(const Color &p_color) {
@ -630,6 +667,30 @@ GraphNode::Overlay GraphNode::get_overlay() const{
return overlay;
}
void GraphNode::set_comment(bool p_enable) {
comment=p_enable;
update();
}
bool GraphNode::is_comment() const{
return comment;
}
void GraphNode::set_resizeable(bool p_enable) {
resizeable=p_enable;
update();
}
bool GraphNode::is_resizeable() const{
return resizeable;
}
void GraphNode::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_title","title"),&GraphNode::set_title);
@ -649,6 +710,12 @@ void GraphNode::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset);
ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset);
ObjectTypeDB::bind_method(_MD("set_comment","comment"),&GraphNode::set_comment);
ObjectTypeDB::bind_method(_MD("is_comment"),&GraphNode::is_comment);
ObjectTypeDB::bind_method(_MD("set_resizeable","resizeable"),&GraphNode::set_resizeable);
ObjectTypeDB::bind_method(_MD("is_resizeable"),&GraphNode::is_resizeable);
ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count);
ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count);
@ -675,6 +742,7 @@ void GraphNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to")));
ADD_SIGNAL(MethodInfo("raise_request"));
ADD_SIGNAL(MethodInfo("close_request"));
ADD_SIGNAL(MethodInfo("resize_request",PropertyInfo(Variant::VECTOR2,"new_minsize")));
BIND_CONSTANT( OVERLAY_DISABLED );
BIND_CONSTANT( OVERLAY_BREAKPOINT );
@ -688,4 +756,7 @@ GraphNode::GraphNode() {
connpos_dirty=true;
set_stop_mouse(false);
modulate=Color(1,1,1,1);
comment=false;
resizeable=false;
resizing=false;
}

View file

@ -60,6 +60,12 @@ private:
String title;
bool show_close;
Vector2 offset;
bool comment;
bool resizeable;
bool resizing;
Vector2 resizing_from;
Vector2 resizing_from_size;
Rect2 close_rect;
@ -144,8 +150,16 @@ public:
void set_overlay(Overlay p_overlay);
Overlay get_overlay() const;
void set_comment(bool p_enable);
bool is_comment() const;
void set_resizeable(bool p_enable);
bool is_resizeable() const;
virtual Size2 get_minimum_size() const;
bool is_resizing() const { return resizing; }
GraphNode();
};

View file

@ -627,6 +627,7 @@ void fill_default_theme(Ref<Theme>& t,const Ref<Font> & default_font,const Ref<F
// GraphNode
Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5);
Ref<StyleBoxTexture> graphsbcomment = make_stylebox(graph_node_comment_png,6,24,6,5,16,24,16,5);
Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5);
Ref<StyleBoxTexture> graphsbdefault = make_stylebox(graph_node_default_png,4,4,4,4,6,4,4,4);
Ref<StyleBoxTexture> graphsbdeffocus = make_stylebox(graph_node_default_focus_png,4,4,4,4,6,4,4,4);
@ -639,11 +640,13 @@ void fill_default_theme(Ref<Theme>& t,const Ref<Font> & default_font,const Ref<F
t->set_stylebox("selectedframe","GraphNode", graphsbselected );
t->set_stylebox("defaultframe", "GraphNode", graphsbdefault );
t->set_stylebox("defaultfocus", "GraphNode", graphsbdeffocus );
t->set_stylebox("comment", "GraphNode", graphsbcomment );
t->set_stylebox("breakpoint", "GraphNode", graph_bpoint );
t->set_stylebox("position", "GraphNode", graph_position );
t->set_constant("separation","GraphNode", 1 *scale);
t->set_icon("port","GraphNode", make_icon( graph_port_png ) );
t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) );
t->set_icon("resizer","GraphNode", make_icon( window_resizer_png ) );
t->set_font("title_font","GraphNode", default_font );
t->set_color("title_color","GraphNode", Color(0,0,0,1));
t->set_constant("title_offset","GraphNode", 20 *scale);

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

View file

@ -114,6 +114,11 @@ static const unsigned char graph_node_close_png[]={
};
static const unsigned char graph_node_comment_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0x13,0x7d,0xf7,0x96,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x8,0x19,0x11,0x2a,0x1d,0xd6,0x78,0x8b,0x40,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x1,0x74,0x49,0x44,0x41,0x54,0x58,0xc3,0xed,0x97,0xbf,0x4e,0xc2,0x50,0x14,0xc6,0x7f,0x6d,0x91,0x56,0x1b,0x90,0x80,0x2c,0x44,0xc2,0xa0,0x2e,0xe,0x3e,0x3,0x89,0x93,0xf1,0x1d,0x4c,0x18,0x4d,0x1c,0x7c,0xb,0x57,0x7,0x13,0x47,0x13,0x77,0x46,0xe3,0xc4,0x4b,0x98,0x60,0x4c,0xd4,0x81,0x60,0x58,0x94,0xff,0x22,0x2d,0xd0,0xd6,0xe5,0xde,0x88,0x8,0x2,0x35,0x6e,0xf7,0x5b,0x6e,0x9a,0x9c,0xef,0x77,0xee,0x39,0x37,0x1d,0x3e,0x8d,0x2f,0x69,0x80,0xe,0x18,0xe2,0xd4,0xf8,0xae,0x0,0xf0,0x1,0x4f,0x9c,0x1,0x63,0x45,0x3a,0xb0,0x6,0x24,0x81,0x34,0x10,0x7,0x56,0x26,0x0,0x43,0xa0,0x3,0xbc,0x2,0xd,0xe0,0x3,0xf0,0x65,0x57,0x1b,0xd8,0x5e,0x8f,0x25,0x8e,0x2d,0xd3,0x3a,0x88,0x46,0xcd,0x4d,0xa6,0x68,0x30,0x70,0x5f,0x1c,0xd7,0xb9,0x6d,0x77,0x5b,0x97,0xc0,0x13,0xd0,0xd3,0x44,0xa7,0x5c,0x32,0x91,0x3a,0xdf,0xca,0xed,0x1c,0x16,0x52,0xdd,0x2a,0xbf,0xe8,0xaa,0x1e,0xcb,0x3e,0x57,0x1e,0x6f,0x1a,0xad,0xfa,0x29,0x50,0x91,0x33,0xa7,0x4d,0xd3,0xca,0xcf,0x33,0x3,0x14,0x52,0xdd,0xaa,0x69,0x5a,0x79,0x31,0xaa,0x21,0x97,0x65,0x47,0x8c,0x88,0xcd,0x82,0x12,0xb5,0x36,0xa0,0x49,0x80,0xc1,0xf2,0x32,0x24,0x20,0x90,0x4f,0x12,0x46,0x3a,0x7f,0x94,0x2,0x28,0x80,0x2,0x88,0x5f,0x7b,0xfc,0xe3,0xec,0xe1,0x3d,0x1b,0x1a,0x30,0x1a,0x7a,0x1c,0x65,0xd8,0x5f,0xc4,0x74,0x5d,0xa3,0xa4,0x5e,0x41,0x1,0x14,0x40,0x1,0x14,0x40,0x1,0x14,0x40,0x1,0xfe,0x15,0xa0,0x4d,0xc9,0x88,0x4b,0xdf,0xc0,0xf,0xe1,0xf5,0x25,0xc0,0x7,0x1c,0xcf,0xf3,0xdc,0x45,0x9d,0xa2,0xd6,0x1,0x7c,0x5d,0x44,0xd9,0xba,0xe3,0xf6,0xcb,0xc5,0xa6,0x5d,0x9a,0x67,0x2e,0x36,0xed,0x92,0xe3,0xf6,0xcb,0x40,0x1d,0xf0,0x64,0x72,0x5d,0x7,0xf6,0xe2,0x76,0xe2,0xc2,0x32,0x57,0x77,0xd,0xc3,0xd0,0x67,0x74,0xf6,0x1d,0xb7,0x7f,0xdf,0xe9,0xb5,0x4e,0x80,0x3b,0xa0,0xad,0x8d,0x45,0xb8,0x38,0x90,0x1,0x36,0x0,0x73,0x46,0xf8,0x76,0x81,0x37,0xa0,0x26,0x72,0xb4,0xa7,0x4d,0x2c,0x34,0x22,0xf3,0xe0,0x8c,0x9,0x2,0x31,0xf2,0x28,0xe4,0xe2,0x7f,0xea,0x13,0x64,0x47,0x6c,0x83,0x36,0x6d,0xd2,0x40,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
static const unsigned char graph_node_default_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x3,0x0,0x0,0x0,0x28,0x2d,0xf,0x53,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x26,0x0,0x0,0x80,0x84,0x0,0x0,0xfa,0x0,0x0,0x0,0x80,0xe8,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x70,0x9c,0xba,0x51,0x3c,0x0,0x0,0x0,0x39,0x50,0x4c,0x54,0x45,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x16,0x12,0x19,0xe,0xb,0x10,0xe,0xb,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x16,0x12,0x19,0x0,0x0,0x0,0x19,0x15,0x1c,0x24,0x1e,0x27,0x16,0x12,0x19,0xff,0xff,0xff,0x2b,0x4d,0xfd,0x66,0x0,0x0,0x0,0xf,0x74,0x52,0x4e,0x53,0x0,0x46,0x47,0x3f,0x2b,0x11,0x3,0xfd,0xd3,0xcd,0x2a,0x73,0x45,0xf8,0x3d,0x3f,0x57,0xda,0x84,0x0,0x0,0x0,0x1,0x62,0x4b,0x47,0x44,0x12,0x7b,0xbc,0x6c,0x0,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x6,0x16,0x12,0x2b,0x4,0x4e,0x1d,0x2,0xaf,0x0,0x0,0x0,0x38,0x49,0x44,0x41,0x54,0x18,0xd3,0x63,0x60,0x64,0x2,0x2,0x46,0x8,0xc9,0xcc,0xc2,0xca,0xc6,0xc0,0x8f,0x4,0xd8,0x39,0x98,0x59,0x19,0x50,0x80,0x0,0x27,0x17,0xaa,0x0,0x83,0x20,0x37,0x9a,0x0,0x3f,0xd3,0xc0,0x8,0xf0,0xa0,0x9,0xf0,0xf2,0x61,0x3a,0x1d,0xc3,0x73,0xe8,0xde,0x7,0x0,0x89,0x4d,0x2,0xf2,0x16,0xd3,0x74,0x45,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x63,0x72,0x65,0x61,0x74,0x65,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xc9,0xad,0xc8,0x52,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x6d,0x6f,0x64,0x69,0x66,0x79,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xb8,0xf0,0x70,0xee,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
@ -544,6 +549,11 @@ static const unsigned char vsplitter_png[]={
};
static const unsigned char window_resizer_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x8,0x19,0x11,0x33,0x13,0xaa,0xc0,0xf,0x5f,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0x2f,0x49,0x44,0x41,0x54,0x38,0xcb,0x63,0x60,0x18,0x5,0x24,0x81,0x17,0x2f,0x5e,0xf4,0xa3,0x8b,0x31,0x91,0xa2,0xb9,0xb9,0xb9,0x99,0x7c,0x9b,0xb3,0xb3,0xb3,0xfb,0x87,0x81,0x66,0x6c,0x81,0x48,0x92,0x66,0xa2,0x5c,0x43,0x91,0xe6,0x11,0xa,0x0,0x73,0x5b,0x34,0x19,0x10,0xa0,0xb6,0x7d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View file

@ -1673,7 +1673,7 @@ void EditorNode::_edit_current() {
if (main_plugin) {
if (main_plugin!=editor_plugin_screen) {
if (main_plugin!=editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible() || ScriptEditor::get_singleton()->can_take_away_focus())) {
// update screen main_plugin

View file

@ -987,6 +987,20 @@ void ScriptEditor::_notification(int p_what) {
}
bool ScriptEditor::can_take_away_focus() const {
int selected = tab_container->get_current_tab();
if (selected<0 || selected>=tab_container->get_child_count())
return true;
ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>();
if (!current)
return true;
return current->can_lose_focus_on_node_selection();
}
void ScriptEditor::close_builtin_scripts_from_scene(const String& p_scene) {
@ -1397,7 +1411,7 @@ void ScriptEditor::_update_script_names() {
void ScriptEditor::edit(const Ref<Script>& p_script) {
void ScriptEditor::edit(const Ref<Script>& p_script, bool p_grab_focus) {
if (p_script.is_null())
return;
@ -1471,7 +1485,9 @@ void ScriptEditor::edit(const Ref<Script>& p_script) {
}
_go_to_tab(tab_container->get_tab_count()-1);
if (p_grab_focus) {
_go_to_tab(tab_container->get_tab_count()-1);
}
@ -1932,6 +1948,13 @@ void ScriptEditor::_help_search(String p_text) {
help_search_dialog->popup(p_text);
}
void ScriptEditor::_open_script_request(const String& p_path) {
Ref<Script> script = ResourceLoader::load(p_path);
if (script.is_valid()) {
script_editor->edit(script,false);
}
}
int ScriptEditor::script_editor_func_count=0;
CreateScriptEditorFunc ScriptEditor::script_editor_funcs[ScriptEditor::SCRIPT_EDITOR_FUNC_MAX];
@ -2208,6 +2231,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
edit_pass=0;
trim_trailing_whitespace_on_save = false;
ScriptServer::edit_request_func=_open_script_request;
}

View file

@ -101,6 +101,7 @@ public:
virtual void add_callback(const String& p_function,StringArray p_args)=0;
virtual void update_settings()=0;
virtual void set_debugger_active(bool p_active)=0;
virtual bool can_lose_focus_on_node_selection() { return true; }
virtual void set_tooltip_request_func(String p_method,Object* p_obj)=0;
virtual Control *get_edit_menu()=0;
@ -285,6 +286,8 @@ class ScriptEditor : public VBoxContainer {
int file_dialog_option;
void _file_dialog_action(String p_file);
static void _open_script_request(const String& p_path);
static ScriptEditor *script_editor;
protected:
void _notification(int p_what);
@ -297,7 +300,7 @@ public:
void apply_scripts() const;
void ensure_select_current();
void edit(const Ref<Script>& p_script);
void edit(const Ref<Script>& p_script,bool p_grab_focus=true);
Dictionary get_state() const;
void set_state(const Dictionary& p_state);
@ -322,6 +325,8 @@ public:
void goto_help(const String& p_desc) { _help_class_goto(p_desc); }
bool can_take_away_focus() const;
ScriptEditorDebugger *get_debugger() { return debugger; }
void set_live_auto_reload_running_scripts(bool p_enabled);

View file

@ -1151,6 +1151,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
file->clear_filters();
if (hint_text!="") {
Vector<String> extensions=hint_text.split(",");
for(int i=0;i<extensions.size();i++) {

View file

@ -508,6 +508,7 @@ void PropertySelector::select_property_from_base_type(const String& p_base,const
void PropertySelector::select_property_from_script(const Ref<Script>& p_script,const String& p_current){
ERR_FAIL_COND( p_script.is_null() );
base_type=p_script->get_instance_base_type();
selected=p_current;
type=Variant::NIL;