Merge pull request #53313 from KoBeWi/debinded_konnekt
This commit is contained in:
commit
42312f066b
11 changed files with 184 additions and 60 deletions
|
@ -51,6 +51,9 @@ public:
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
||||||
virtual const Callable *get_base_comparator() const;
|
virtual const Callable *get_base_comparator() const;
|
||||||
|
|
||||||
|
Callable get_callable() { return callable; }
|
||||||
|
Vector<Variant> get_binds() { return binds; }
|
||||||
|
|
||||||
CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds);
|
CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds);
|
||||||
virtual ~CallableCustomBind();
|
virtual ~CallableCustomBind();
|
||||||
};
|
};
|
||||||
|
@ -72,6 +75,9 @@ public:
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const;
|
||||||
virtual const Callable *get_base_comparator() const;
|
virtual const Callable *get_base_comparator() const;
|
||||||
|
|
||||||
|
Callable get_callable() { return callable; }
|
||||||
|
int get_unbinds() { return argcount; }
|
||||||
|
|
||||||
CallableCustomUnbind(const Callable &p_callable, int p_argcount);
|
CallableCustomUnbind(const Callable &p_callable, int p_argcount);
|
||||||
virtual ~CallableCustomUnbind();
|
virtual ~CallableCustomUnbind();
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,13 @@
|
||||||
Returns the path to the node that owns the method connected to the signal at [code]idx[/code], relative to the root node.
|
Returns the path to the node that owns the method connected to the signal at [code]idx[/code], relative to the root node.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_connection_unbinds" qualifiers="const">
|
||||||
|
<return type="int" />
|
||||||
|
<argument index="0" name="idx" type="int" />
|
||||||
|
<description>
|
||||||
|
Returns the number of unbound parameters for the signal at [code]idx[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_node_count" qualifiers="const">
|
<method name="get_node_count" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "plugins/script_editor_plugin.h"
|
#include "plugins/script_editor_plugin.h"
|
||||||
#include "scene/gui/label.h"
|
#include "scene/gui/label.h"
|
||||||
#include "scene/gui/popup_menu.h"
|
#include "scene/gui/popup_menu.h"
|
||||||
|
#include "scene/gui/spin_box.h"
|
||||||
|
|
||||||
static Node *_find_first_script(Node *p_root, Node *p_node) {
|
static Node *_find_first_script(Node *p_root, Node *p_node) {
|
||||||
if (p_node != p_root && p_node->get_owner() != p_root) {
|
if (p_node != p_root && p_node->get_owner() != p_root) {
|
||||||
|
@ -164,6 +165,20 @@ void ConnectDialog::_tree_node_selected() {
|
||||||
_update_ok_enabled();
|
_update_ok_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectDialog::_unbind_count_changed(double p_count) {
|
||||||
|
for (Control *control : bind_controls) {
|
||||||
|
BaseButton *b = Object::cast_to<BaseButton>(control);
|
||||||
|
if (b) {
|
||||||
|
b->set_disabled(p_count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorInspector *e = Object::cast_to<EditorInspector>(control);
|
||||||
|
if (e) {
|
||||||
|
e->set_read_only(p_count > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a new parameter bind to connection.
|
* Adds a new parameter bind to connection.
|
||||||
*/
|
*/
|
||||||
|
@ -305,6 +320,10 @@ void ConnectDialog::set_dst_method(const StringName &p_method) {
|
||||||
dst_method->set_text(p_method);
|
dst_method->set_text(p_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ConnectDialog::get_unbinds() const {
|
||||||
|
return int(unbind_count->get_value());
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Variant> ConnectDialog::get_binds() const {
|
Vector<Variant> ConnectDialog::get_binds() const {
|
||||||
return cdbinds->params;
|
return cdbinds->params;
|
||||||
}
|
}
|
||||||
|
@ -350,6 +369,8 @@ void ConnectDialog::init(ConnectionData c, bool bEdit) {
|
||||||
|
|
||||||
deferred->set_pressed(bDeferred);
|
deferred->set_pressed(bDeferred);
|
||||||
oneshot->set_pressed(bOneshot);
|
oneshot->set_pressed(bOneshot);
|
||||||
|
unbind_count->set_value(c.unbinds);
|
||||||
|
_unbind_count_changed(c.unbinds);
|
||||||
|
|
||||||
cdbinds->params.clear();
|
cdbinds->params.clear();
|
||||||
cdbinds->params = c.binds;
|
cdbinds->params = c.binds;
|
||||||
|
@ -449,23 +470,33 @@ ConnectDialog::ConnectDialog() {
|
||||||
type_list->add_item("Transform3D", Variant::TRANSFORM3D);
|
type_list->add_item("Transform3D", Variant::TRANSFORM3D);
|
||||||
type_list->add_item("Color", Variant::COLOR);
|
type_list->add_item("Color", Variant::COLOR);
|
||||||
type_list->select(0);
|
type_list->select(0);
|
||||||
|
bind_controls.push_back(type_list);
|
||||||
|
|
||||||
Button *add_bind = memnew(Button);
|
Button *add_bind = memnew(Button);
|
||||||
add_bind->set_text(TTR("Add"));
|
add_bind->set_text(TTR("Add"));
|
||||||
add_bind_hb->add_child(add_bind);
|
add_bind_hb->add_child(add_bind);
|
||||||
add_bind->connect("pressed", callable_mp(this, &ConnectDialog::_add_bind));
|
add_bind->connect("pressed", callable_mp(this, &ConnectDialog::_add_bind));
|
||||||
|
bind_controls.push_back(add_bind);
|
||||||
|
|
||||||
Button *del_bind = memnew(Button);
|
Button *del_bind = memnew(Button);
|
||||||
del_bind->set_text(TTR("Remove"));
|
del_bind->set_text(TTR("Remove"));
|
||||||
add_bind_hb->add_child(del_bind);
|
add_bind_hb->add_child(del_bind);
|
||||||
del_bind->connect("pressed", callable_mp(this, &ConnectDialog::_remove_bind));
|
del_bind->connect("pressed", callable_mp(this, &ConnectDialog::_remove_bind));
|
||||||
|
bind_controls.push_back(del_bind);
|
||||||
|
|
||||||
vbc_right->add_margin_child(TTR("Add Extra Call Argument:"), add_bind_hb);
|
vbc_right->add_margin_child(TTR("Add Extra Call Argument:"), add_bind_hb);
|
||||||
|
|
||||||
bind_editor = memnew(EditorInspector);
|
bind_editor = memnew(EditorInspector);
|
||||||
|
bind_controls.push_back(bind_editor);
|
||||||
|
|
||||||
vbc_right->add_margin_child(TTR("Extra Call Arguments:"), bind_editor, true);
|
vbc_right->add_margin_child(TTR("Extra Call Arguments:"), bind_editor, true);
|
||||||
|
|
||||||
|
unbind_count = memnew(SpinBox);
|
||||||
|
unbind_count->set_tooltip(TTR("Allows to drop arguments sent by signal emitter."));
|
||||||
|
unbind_count->connect("value_changed", callable_mp(this, &ConnectDialog::_unbind_count_changed));
|
||||||
|
|
||||||
|
vbc_right->add_margin_child(TTR("Unbind Signal Arguments:"), unbind_count);
|
||||||
|
|
||||||
HBoxContainer *dstm_hb = memnew(HBoxContainer);
|
HBoxContainer *dstm_hb = memnew(HBoxContainer);
|
||||||
vbc_left->add_margin_child(TTR("Receiver Method:"), dstm_hb);
|
vbc_left->add_margin_child(TTR("Receiver Method:"), dstm_hb);
|
||||||
|
|
||||||
|
@ -541,26 +572,29 @@ void ConnectionsDock::_make_or_edit_connection() {
|
||||||
Node *target = selectedNode->get_node(dst_path);
|
Node *target = selectedNode->get_node(dst_path);
|
||||||
ERR_FAIL_COND(!target);
|
ERR_FAIL_COND(!target);
|
||||||
|
|
||||||
ConnectDialog::ConnectionData cToMake;
|
ConnectDialog::ConnectionData connection;
|
||||||
cToMake.source = connect_dialog->get_source();
|
connection.source = connect_dialog->get_source();
|
||||||
cToMake.target = target;
|
connection.target = target;
|
||||||
cToMake.signal = connect_dialog->get_signal_name();
|
connection.signal = connect_dialog->get_signal_name();
|
||||||
cToMake.method = connect_dialog->get_dst_method_name();
|
connection.method = connect_dialog->get_dst_method_name();
|
||||||
cToMake.binds = connect_dialog->get_binds();
|
connection.unbinds = connect_dialog->get_unbinds();
|
||||||
|
if (connection.unbinds == 0) {
|
||||||
|
connection.binds = connect_dialog->get_binds();
|
||||||
|
}
|
||||||
bool defer = connect_dialog->get_deferred();
|
bool defer = connect_dialog->get_deferred();
|
||||||
bool oshot = connect_dialog->get_oneshot();
|
bool oshot = connect_dialog->get_oneshot();
|
||||||
cToMake.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
|
connection.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
|
||||||
|
|
||||||
// Conditions to add function: must have a script and must not have the method already
|
// Conditions to add function: must have a script and must not have the method already
|
||||||
// (in the class, the script itself, or inherited).
|
// (in the class, the script itself, or inherited).
|
||||||
bool add_script_function = false;
|
bool add_script_function = false;
|
||||||
Ref<Script> script = target->get_script();
|
Ref<Script> script = target->get_script();
|
||||||
if (!target->get_script().is_null() && !ClassDB::has_method(target->get_class(), cToMake.method)) {
|
if (!target->get_script().is_null() && !ClassDB::has_method(target->get_class(), connection.method)) {
|
||||||
// There is a chance that the method is inherited from another script.
|
// There is a chance that the method is inherited from another script.
|
||||||
bool found_inherited_function = false;
|
bool found_inherited_function = false;
|
||||||
Ref<Script> inherited_script = script->get_base_script();
|
Ref<Script> inherited_script = script->get_base_script();
|
||||||
while (!inherited_script.is_null()) {
|
while (!inherited_script.is_null()) {
|
||||||
int line = inherited_script->get_language()->find_function(cToMake.method, inherited_script->get_source_code());
|
int line = inherited_script->get_language()->find_function(connection.method, inherited_script->get_source_code());
|
||||||
if (line != -1) {
|
if (line != -1) {
|
||||||
found_inherited_function = true;
|
found_inherited_function = true;
|
||||||
break;
|
break;
|
||||||
|
@ -575,23 +609,23 @@ void ConnectionsDock::_make_or_edit_connection() {
|
||||||
if (add_script_function) {
|
if (add_script_function) {
|
||||||
// Pick up args here before "it" is deleted by update_tree.
|
// Pick up args here before "it" is deleted by update_tree.
|
||||||
script_function_args = it->get_metadata(0).operator Dictionary()["args"];
|
script_function_args = it->get_metadata(0).operator Dictionary()["args"];
|
||||||
for (int i = 0; i < cToMake.binds.size(); i++) {
|
for (int i = 0; i < connection.binds.size(); i++) {
|
||||||
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cToMake.binds[i].get_type()));
|
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(connection.binds[i].get_type()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect_dialog->is_editing()) {
|
if (connect_dialog->is_editing()) {
|
||||||
_disconnect(*it);
|
_disconnect(*it);
|
||||||
_connect(cToMake);
|
_connect(connection);
|
||||||
} else {
|
} else {
|
||||||
_connect(cToMake);
|
_connect(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT NOTE: _disconnect and _connect cause an update_tree, which will delete the object "it" is pointing to.
|
// IMPORTANT NOTE: _disconnect and _connect cause an update_tree, which will delete the object "it" is pointing to.
|
||||||
it = nullptr;
|
it = nullptr;
|
||||||
|
|
||||||
if (add_script_function) {
|
if (add_script_function) {
|
||||||
editor->emit_signal(SNAME("script_add_function_request"), target, cToMake.method, script_function_args);
|
editor->emit_signal(SNAME("script_add_function_request"), target, connection.method, script_function_args);
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,20 +635,18 @@ void ConnectionsDock::_make_or_edit_connection() {
|
||||||
/*
|
/*
|
||||||
* Creates single connection w/ undo-redo functionality.
|
* Creates single connection w/ undo-redo functionality.
|
||||||
*/
|
*/
|
||||||
void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
|
void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_connection) {
|
||||||
Node *source = static_cast<Node *>(cToMake.source);
|
Node *source = Object::cast_to<Node>(p_connection.source);
|
||||||
Node *target = static_cast<Node *>(cToMake.target);
|
Node *target = Object::cast_to<Node>(p_connection.target);
|
||||||
|
|
||||||
if (!source || !target) {
|
if (!source || !target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(cToMake.signal), String(cToMake.method)));
|
Callable callable = p_connection.get_callable();
|
||||||
|
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_connection.signal), String(p_connection.method)));
|
||||||
Callable c(target, cToMake.method);
|
undo_redo->add_do_method(source, "connect", p_connection.signal, callable, varray(), p_connection.flags);
|
||||||
|
undo_redo->add_undo_method(source, "disconnect", p_connection.signal, callable);
|
||||||
undo_redo->add_do_method(source, "connect", cToMake.signal, c, cToMake.binds, cToMake.flags);
|
|
||||||
undo_redo->add_undo_method(source, "disconnect", cToMake.signal, c);
|
|
||||||
undo_redo->add_do_method(this, "update_tree");
|
undo_redo->add_do_method(this, "update_tree");
|
||||||
undo_redo->add_undo_method(this, "update_tree");
|
undo_redo->add_undo_method(this, "update_tree");
|
||||||
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
|
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
|
||||||
|
@ -634,8 +666,9 @@ void ConnectionsDock::_disconnect(TreeItem &item) {
|
||||||
|
|
||||||
undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), c.signal, c.method));
|
undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), c.signal, c.method));
|
||||||
|
|
||||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
|
Callable callable = c.get_callable();
|
||||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
|
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, callable);
|
||||||
|
undo_redo->add_undo_method(selectedNode, "connect", c.signal, callable, c.binds, c.flags);
|
||||||
undo_redo->add_do_method(this, "update_tree");
|
undo_redo->add_do_method(this, "update_tree");
|
||||||
undo_redo->add_undo_method(this, "update_tree");
|
undo_redo->add_undo_method(this, "update_tree");
|
||||||
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree.
|
undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree.
|
||||||
|
@ -662,8 +695,8 @@ void ConnectionsDock::_disconnect_all() {
|
||||||
while (child) {
|
while (child) {
|
||||||
Connection cd = child->get_metadata(0);
|
Connection cd = child->get_metadata(0);
|
||||||
ConnectDialog::ConnectionData c = cd;
|
ConnectDialog::ConnectionData c = cd;
|
||||||
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
|
undo_redo->add_do_method(selectedNode, "disconnect", c.signal, c.get_callable());
|
||||||
undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
|
undo_redo->add_undo_method(selectedNode, "connect", c.signal, c.get_callable(), c.binds, c.flags);
|
||||||
child = child->get_next();
|
child = child->get_next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,8 +785,8 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
|
||||||
* Open connection dialog with Connection data to EDIT an existing connection.
|
* Open connection dialog with Connection data to EDIT an existing connection.
|
||||||
*/
|
*/
|
||||||
void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
|
void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
|
||||||
Node *src = static_cast<Node *>(cToEdit.source);
|
Node *src = Object::cast_to<Node>(cToEdit.source);
|
||||||
Node *dst = static_cast<Node *>(cToEdit.target);
|
Node *dst = Object::cast_to<Node>(cToEdit.target);
|
||||||
|
|
||||||
if (src && dst) {
|
if (src && dst) {
|
||||||
const String &signalname = cToEdit.signal;
|
const String &signalname = cToEdit.signal;
|
||||||
|
@ -1044,7 +1077,9 @@ void ConnectionsDock::update_tree() {
|
||||||
if (c.flags & CONNECT_ONESHOT) {
|
if (c.flags & CONNECT_ONESHOT) {
|
||||||
path += " (oneshot)";
|
path += " (oneshot)";
|
||||||
}
|
}
|
||||||
if (c.binds.size()) {
|
if (c.unbinds > 0) {
|
||||||
|
path += " unbinds(" + itos(c.unbinds) + ")";
|
||||||
|
} else if (!c.binds.is_empty()) {
|
||||||
path += " binds(";
|
path += " binds(";
|
||||||
for (int i = 0; i < c.binds.size(); i++) {
|
for (int i = 0; i < c.binds.size(); i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
@ -1057,8 +1092,7 @@ void ConnectionsDock::update_tree() {
|
||||||
|
|
||||||
TreeItem *connection_item = tree->create_item(signal_item);
|
TreeItem *connection_item = tree->create_item(signal_item);
|
||||||
connection_item->set_text(0, path);
|
connection_item->set_text(0, path);
|
||||||
Connection cd = c;
|
connection_item->set_metadata(0, cn);
|
||||||
connection_item->set_metadata(0, cd);
|
|
||||||
connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
|
connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
class PopupMenu;
|
class PopupMenu;
|
||||||
class ConnectDialogBinds;
|
class ConnectDialogBinds;
|
||||||
|
class SpinBox;
|
||||||
|
|
||||||
class ConnectDialog : public ConfirmationDialog {
|
class ConnectDialog : public ConfirmationDialog {
|
||||||
GDCLASS(ConnectDialog, ConfirmationDialog);
|
GDCLASS(ConnectDialog, ConfirmationDialog);
|
||||||
|
@ -59,25 +60,45 @@ public:
|
||||||
StringName signal;
|
StringName signal;
|
||||||
StringName method;
|
StringName method;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
int unbinds = 0;
|
||||||
Vector<Variant> binds;
|
Vector<Variant> binds;
|
||||||
|
|
||||||
ConnectionData() {
|
ConnectionData() {}
|
||||||
}
|
|
||||||
ConnectionData(const Connection &p_connection) {
|
ConnectionData(const Connection &p_connection) {
|
||||||
source = Object::cast_to<Node>(p_connection.signal.get_object());
|
source = Object::cast_to<Node>(p_connection.signal.get_object());
|
||||||
signal = p_connection.signal.get_name();
|
signal = p_connection.signal.get_name();
|
||||||
target = Object::cast_to<Node>(p_connection.callable.get_object());
|
target = Object::cast_to<Node>(p_connection.callable.get_object());
|
||||||
method = p_connection.callable.get_method();
|
|
||||||
flags = p_connection.flags;
|
flags = p_connection.flags;
|
||||||
binds = p_connection.binds;
|
|
||||||
|
Callable base_callable;
|
||||||
|
if (p_connection.callable.is_custom()) {
|
||||||
|
CallableCustomBind *ccb = dynamic_cast<CallableCustomBind *>(p_connection.callable.get_custom());
|
||||||
|
if (ccb) {
|
||||||
|
binds = ccb->get_binds();
|
||||||
|
base_callable = ccb->get_callable();
|
||||||
|
}
|
||||||
|
|
||||||
|
CallableCustomUnbind *ccu = dynamic_cast<CallableCustomUnbind *>(p_connection.callable.get_custom());
|
||||||
|
if (ccu) {
|
||||||
|
unbinds = ccu->get_unbinds();
|
||||||
|
base_callable = ccu->get_callable();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base_callable = p_connection.callable;
|
||||||
|
}
|
||||||
|
method = base_callable.get_method();
|
||||||
|
}
|
||||||
|
|
||||||
|
Callable get_callable() {
|
||||||
|
if (unbinds > 0) {
|
||||||
|
return Callable(target, method).unbind(unbinds);
|
||||||
|
} else if (!binds.is_empty()) {
|
||||||
|
const Variant *args = binds.ptr();
|
||||||
|
return Callable(target, method).bind(&args, binds.size());
|
||||||
|
} else {
|
||||||
|
return Callable(target, method);
|
||||||
}
|
}
|
||||||
operator Connection() {
|
|
||||||
Connection c;
|
|
||||||
c.signal = ::Signal(source, signal);
|
|
||||||
c.callable = Callable(target, method);
|
|
||||||
c.flags = flags;
|
|
||||||
c.binds = binds;
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,11 +115,13 @@ private:
|
||||||
|
|
||||||
SceneTreeEditor *tree;
|
SceneTreeEditor *tree;
|
||||||
AcceptDialog *error;
|
AcceptDialog *error;
|
||||||
|
SpinBox *unbind_count;
|
||||||
EditorInspector *bind_editor;
|
EditorInspector *bind_editor;
|
||||||
OptionButton *type_list;
|
OptionButton *type_list;
|
||||||
CheckBox *deferred;
|
CheckBox *deferred;
|
||||||
CheckBox *oneshot;
|
CheckBox *oneshot;
|
||||||
CheckButton *advanced;
|
CheckButton *advanced;
|
||||||
|
Vector<Control *> bind_controls;
|
||||||
|
|
||||||
Label *error_label;
|
Label *error_label;
|
||||||
|
|
||||||
|
@ -107,6 +130,7 @@ private:
|
||||||
void _item_activated();
|
void _item_activated();
|
||||||
void _text_submitted(const String &_text);
|
void _text_submitted(const String &_text);
|
||||||
void _tree_node_selected();
|
void _tree_node_selected();
|
||||||
|
void _unbind_count_changed(double p_count);
|
||||||
void _add_bind();
|
void _add_bind();
|
||||||
void _remove_bind();
|
void _remove_bind();
|
||||||
void _advanced_pressed();
|
void _advanced_pressed();
|
||||||
|
@ -123,6 +147,7 @@ public:
|
||||||
void set_dst_node(Node *p_node);
|
void set_dst_node(Node *p_node);
|
||||||
StringName get_dst_method_name() const;
|
StringName get_dst_method_name() const;
|
||||||
void set_dst_method(const StringName &p_method);
|
void set_dst_method(const StringName &p_method);
|
||||||
|
int get_unbinds() const;
|
||||||
Vector<Variant> get_binds() const;
|
Vector<Variant> get_binds() const;
|
||||||
|
|
||||||
bool get_deferred() const;
|
bool get_deferred() const;
|
||||||
|
@ -176,7 +201,7 @@ class ConnectionsDock : public VBoxContainer {
|
||||||
void _filter_changed(const String &p_text);
|
void _filter_changed(const String &p_text);
|
||||||
|
|
||||||
void _make_or_edit_connection();
|
void _make_or_edit_connection();
|
||||||
void _connect(ConnectDialog::ConnectionData cToMake);
|
void _connect(ConnectDialog::ConnectionData p_connection);
|
||||||
void _disconnect(TreeItem &item);
|
void _disconnect(TreeItem &item);
|
||||||
void _disconnect_all();
|
void _disconnect_all();
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#define INSPECTOR_DOCK_H
|
#define INSPECTOR_DOCK_H
|
||||||
|
|
||||||
#include "editor/animation_track_editor.h"
|
#include "editor/animation_track_editor.h"
|
||||||
#include "editor/connections_dialog.h"
|
|
||||||
#include "editor/create_dialog.h"
|
#include "editor/create_dialog.h"
|
||||||
#include "editor/editor_data.h"
|
#include "editor/editor_data.h"
|
||||||
#include "editor/editor_inspector.h"
|
#include "editor/editor_inspector.h"
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "node_dock.h"
|
#include "node_dock.h"
|
||||||
|
|
||||||
|
#include "connections_dialog.h"
|
||||||
#include "editor_node.h"
|
#include "editor_node.h"
|
||||||
#include "editor_scale.h"
|
#include "editor_scale.h"
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,10 @@
|
||||||
#ifndef NODE_DOCK_H
|
#ifndef NODE_DOCK_H
|
||||||
#define NODE_DOCK_H
|
#define NODE_DOCK_H
|
||||||
|
|
||||||
#include "connections_dialog.h"
|
|
||||||
#include "groups_editor.h"
|
#include "groups_editor.h"
|
||||||
|
|
||||||
|
class ConnectionsDock;
|
||||||
|
|
||||||
class NodeDock : public VBoxContainer {
|
class NodeDock : public VBoxContainer {
|
||||||
GDCLASS(NodeDock, VBoxContainer);
|
GDCLASS(NodeDock, VBoxContainer);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#ifndef SCENE_TREE_DOCK_H
|
#ifndef SCENE_TREE_DOCK_H
|
||||||
#define SCENE_TREE_DOCK_H
|
#define SCENE_TREE_DOCK_H
|
||||||
|
|
||||||
#include "editor/connections_dialog.h"
|
|
||||||
#include "editor/create_dialog.h"
|
#include "editor/create_dialog.h"
|
||||||
#include "editor/editor_data.h"
|
#include "editor/editor_data.h"
|
||||||
#include "editor/groups_editor.h"
|
#include "editor/groups_editor.h"
|
||||||
|
|
|
@ -353,6 +353,10 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Callable callable(cto, snames[c.method]);
|
||||||
|
if (c.unbinds > 0) {
|
||||||
|
callable = callable.unbind(c.unbinds);
|
||||||
|
} else if (!c.binds.is_empty()) {
|
||||||
Vector<Variant> binds;
|
Vector<Variant> binds;
|
||||||
if (c.binds.size()) {
|
if (c.binds.size()) {
|
||||||
binds.resize(c.binds.size());
|
binds.resize(c.binds.size());
|
||||||
|
@ -361,7 +365,11 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags);
|
const Variant *args = binds.ptr();
|
||||||
|
callable = callable.bind(&args, binds.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Node *s = ret_nodes[0];
|
//Node *s = ret_nodes[0];
|
||||||
|
@ -652,6 +660,26 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<Variant> binds;
|
||||||
|
int unbinds = 0;
|
||||||
|
Callable base_callable;
|
||||||
|
|
||||||
|
if (c.callable.is_custom()) {
|
||||||
|
CallableCustomBind *ccb = dynamic_cast<CallableCustomBind *>(c.callable.get_custom());
|
||||||
|
if (ccb) {
|
||||||
|
binds = ccb->get_binds();
|
||||||
|
base_callable = ccb->get_callable();
|
||||||
|
}
|
||||||
|
|
||||||
|
CallableCustomUnbind *ccu = dynamic_cast<CallableCustomUnbind *>(c.callable.get_custom());
|
||||||
|
if (ccu) {
|
||||||
|
unbinds = ccu->get_unbinds();
|
||||||
|
base_callable = ccu->get_callable();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base_callable = c.callable;
|
||||||
|
}
|
||||||
|
|
||||||
//find if this connection already exists
|
//find if this connection already exists
|
||||||
Node *common_parent = target->find_common_parent_with(p_node);
|
Node *common_parent = target->find_common_parent_with(p_node);
|
||||||
|
|
||||||
|
@ -677,7 +705,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
||||||
NodePath signal_from = common_parent->get_path_to(p_node);
|
NodePath signal_from = common_parent->get_path_to(p_node);
|
||||||
NodePath signal_to = common_parent->get_path_to(target);
|
NodePath signal_to = common_parent->get_path_to(target);
|
||||||
|
|
||||||
if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, c.callable.get_method())) {
|
if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, base_callable.get_method())) {
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -708,7 +736,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
||||||
|
|
||||||
if (from_node >= 0 && to_node >= 0) {
|
if (from_node >= 0 && to_node >= 0) {
|
||||||
//this one has state for this node, save
|
//this one has state for this node, save
|
||||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
|
if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) {
|
||||||
exists2 = true;
|
exists2 = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -726,7 +754,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
||||||
|
|
||||||
if (from_node >= 0 && to_node >= 0) {
|
if (from_node >= 0 && to_node >= 0) {
|
||||||
//this one has state for this node, save
|
//this one has state for this node, save
|
||||||
if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) {
|
if (state->is_connection(from_node, c.signal.get_name(), to_node, base_callable.get_method())) {
|
||||||
exists2 = true;
|
exists2 = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -773,12 +801,16 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
|
||||||
ConnectionData cd;
|
ConnectionData cd;
|
||||||
cd.from = src_id;
|
cd.from = src_id;
|
||||||
cd.to = target_id;
|
cd.to = target_id;
|
||||||
cd.method = _nm_get_string(c.callable.get_method(), name_map);
|
cd.method = _nm_get_string(base_callable.get_method(), name_map);
|
||||||
cd.signal = _nm_get_string(c.signal.get_name(), name_map);
|
cd.signal = _nm_get_string(c.signal.get_name(), name_map);
|
||||||
cd.flags = c.flags;
|
cd.flags = c.flags;
|
||||||
for (int i = 0; i < c.binds.size(); i++) {
|
cd.unbinds = unbinds;
|
||||||
|
for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now.
|
||||||
cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
|
cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < binds.size(); i++) {
|
||||||
|
cd.binds.push_back(_vm_get_variant(binds[i], variant_map));
|
||||||
|
}
|
||||||
connections.push_back(cd);
|
connections.push_back(cd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1390,6 +1422,11 @@ int SceneState::get_connection_flags(int p_idx) const {
|
||||||
return connections[p_idx].flags;
|
return connections[p_idx].flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SceneState::get_connection_unbinds(int p_idx) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_idx, connections.size(), -1);
|
||||||
|
return connections[p_idx].unbinds;
|
||||||
|
}
|
||||||
|
|
||||||
Array SceneState::get_connection_binds(int p_idx) const {
|
Array SceneState::get_connection_binds(int p_idx) const {
|
||||||
ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
|
ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
|
||||||
Array binds;
|
Array binds;
|
||||||
|
@ -1494,7 +1531,7 @@ void SceneState::set_base_scene(int p_idx) {
|
||||||
base_scene_idx = p_idx;
|
base_scene_idx = p_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
|
void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds) {
|
||||||
ERR_FAIL_INDEX(p_signal, names.size());
|
ERR_FAIL_INDEX(p_signal, names.size());
|
||||||
ERR_FAIL_INDEX(p_method, names.size());
|
ERR_FAIL_INDEX(p_method, names.size());
|
||||||
|
|
||||||
|
@ -1507,6 +1544,7 @@ void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method
|
||||||
c.signal = p_signal;
|
c.signal = p_signal;
|
||||||
c.method = p_method;
|
c.method = p_method;
|
||||||
c.flags = p_flags;
|
c.flags = p_flags;
|
||||||
|
c.unbinds = p_unbinds;
|
||||||
c.binds = p_binds;
|
c.binds = p_binds;
|
||||||
connections.push_back(c);
|
connections.push_back(c);
|
||||||
}
|
}
|
||||||
|
@ -1549,6 +1587,7 @@ void SceneState::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_connection_method", "idx"), &SceneState::get_connection_method);
|
ClassDB::bind_method(D_METHOD("get_connection_method", "idx"), &SceneState::get_connection_method);
|
||||||
ClassDB::bind_method(D_METHOD("get_connection_flags", "idx"), &SceneState::get_connection_flags);
|
ClassDB::bind_method(D_METHOD("get_connection_flags", "idx"), &SceneState::get_connection_flags);
|
||||||
ClassDB::bind_method(D_METHOD("get_connection_binds", "idx"), &SceneState::get_connection_binds);
|
ClassDB::bind_method(D_METHOD("get_connection_binds", "idx"), &SceneState::get_connection_binds);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_connection_unbinds", "idx"), &SceneState::get_connection_unbinds);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||||
|
|
|
@ -77,6 +77,7 @@ class SceneState : public RefCounted {
|
||||||
int signal = 0;
|
int signal = 0;
|
||||||
int method = 0;
|
int method = 0;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
int unbinds = 0;
|
||||||
Vector<int> binds;
|
Vector<int> binds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,6 +164,7 @@ public:
|
||||||
NodePath get_connection_target(int p_idx) const;
|
NodePath get_connection_target(int p_idx) const;
|
||||||
StringName get_connection_method(int p_idx) const;
|
StringName get_connection_method(int p_idx) const;
|
||||||
int get_connection_flags(int p_idx) const;
|
int get_connection_flags(int p_idx) const;
|
||||||
|
int get_connection_unbinds(int p_idx) const;
|
||||||
Array get_connection_binds(int p_idx) const;
|
Array get_connection_binds(int p_idx) const;
|
||||||
|
|
||||||
bool has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method);
|
bool has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method);
|
||||||
|
@ -178,7 +180,7 @@ public:
|
||||||
void add_node_property(int p_node, int p_name, int p_value);
|
void add_node_property(int p_node, int p_name, int p_value);
|
||||||
void add_node_group(int p_node, int p_group);
|
void add_node_group(int p_node, int p_group);
|
||||||
void set_base_scene(int p_idx);
|
void set_base_scene(int p_idx);
|
||||||
void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds);
|
void add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, int p_unbinds, const Vector<int> &p_binds);
|
||||||
void add_editable_instance(const NodePath &p_path);
|
void add_editable_instance(const NodePath &p_path);
|
||||||
|
|
||||||
virtual void set_last_modified_time(uint64_t p_time) { last_modified_time = p_time; }
|
virtual void set_last_modified_time(uint64_t p_time) { last_modified_time = p_time; }
|
||||||
|
|
|
@ -313,6 +313,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
||||||
StringName method = next_tag.fields["method"];
|
StringName method = next_tag.fields["method"];
|
||||||
StringName signal = next_tag.fields["signal"];
|
StringName signal = next_tag.fields["signal"];
|
||||||
int flags = Object::CONNECT_PERSIST;
|
int flags = Object::CONNECT_PERSIST;
|
||||||
|
int unbinds = 0;
|
||||||
Array binds;
|
Array binds;
|
||||||
|
|
||||||
if (next_tag.fields.has("flags")) {
|
if (next_tag.fields.has("flags")) {
|
||||||
|
@ -323,6 +324,10 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
||||||
binds = next_tag.fields["binds"];
|
binds = next_tag.fields["binds"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next_tag.fields.has("unbinds")) {
|
||||||
|
unbinds = next_tag.fields["unbinds"];
|
||||||
|
}
|
||||||
|
|
||||||
Vector<int> bind_ints;
|
Vector<int> bind_ints;
|
||||||
for (int i = 0; i < binds.size(); i++) {
|
for (int i = 0; i < binds.size(); i++) {
|
||||||
bind_ints.push_back(packed_scene->get_state()->add_value(binds[i]));
|
bind_ints.push_back(packed_scene->get_state()->add_value(binds[i]));
|
||||||
|
@ -334,6 +339,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
|
||||||
packed_scene->get_state()->add_name(signal),
|
packed_scene->get_state()->add_name(signal),
|
||||||
packed_scene->get_state()->add_name(method),
|
packed_scene->get_state()->add_name(method),
|
||||||
flags,
|
flags,
|
||||||
|
unbinds,
|
||||||
bind_ints);
|
bind_ints);
|
||||||
|
|
||||||
error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser);
|
error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &parser);
|
||||||
|
@ -1909,6 +1915,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
|
||||||
connstr += " flags=" + itos(flags);
|
connstr += " flags=" + itos(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int unbinds = state->get_connection_unbinds(i);
|
||||||
|
if (unbinds > 0) {
|
||||||
|
connstr += " unbinds=" + itos(unbinds);
|
||||||
|
}
|
||||||
|
|
||||||
Array binds = state->get_connection_binds(i);
|
Array binds = state->get_connection_binds(i);
|
||||||
f->store_string(connstr);
|
f->store_string(connstr);
|
||||||
if (binds.size()) {
|
if (binds.size()) {
|
||||||
|
|
Loading…
Reference in a new issue