summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
authorRémi Verschelde <remi@verschelde.fr>2022-01-04 12:22:46 +0100
committerGitHub <noreply@github.com>2022-01-04 12:22:46 +0100
commit42312f066bd7fc5eb66abb5a2d7161717ceb3c55 (patch)
tree8afb65b7e1f24c8dfde5d4f66c7469bfaee3b592 /editor
parentb74968c2ca6ae70e074fa44ee368b513a62aa309 (diff)
parentcdac60759e931b07811025adf053b1e88495ad80 (diff)
downloadredot-engine-42312f066bd7fc5eb66abb5a2d7161717ceb3c55.tar.gz
Merge pull request #53313 from KoBeWi/debinded_konnekt
Diffstat (limited to 'editor')
-rw-r--r--editor/connections_dialog.cpp98
-rw-r--r--editor/connections_dialog.h49
-rw-r--r--editor/inspector_dock.h1
-rw-r--r--editor/node_dock.cpp1
-rw-r--r--editor/node_dock.h3
-rw-r--r--editor/scene_tree_dock.h1
6 files changed, 106 insertions, 47 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 606be7e154..8f4b677929 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -38,6 +38,7 @@
#include "plugins/script_editor_plugin.h"
#include "scene/gui/label.h"
#include "scene/gui/popup_menu.h"
+#include "scene/gui/spin_box.h"
static Node *_find_first_script(Node *p_root, Node *p_node) {
if (p_node != p_root && p_node->get_owner() != p_root) {
@@ -164,6 +165,20 @@ void ConnectDialog::_tree_node_selected() {
_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.
*/
@@ -305,6 +320,10 @@ void ConnectDialog::set_dst_method(const StringName &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 {
return cdbinds->params;
}
@@ -350,6 +369,8 @@ void ConnectDialog::init(ConnectionData c, bool bEdit) {
deferred->set_pressed(bDeferred);
oneshot->set_pressed(bOneshot);
+ unbind_count->set_value(c.unbinds);
+ _unbind_count_changed(c.unbinds);
cdbinds->params.clear();
cdbinds->params = c.binds;
@@ -449,23 +470,33 @@ ConnectDialog::ConnectDialog() {
type_list->add_item("Transform3D", Variant::TRANSFORM3D);
type_list->add_item("Color", Variant::COLOR);
type_list->select(0);
+ bind_controls.push_back(type_list);
Button *add_bind = memnew(Button);
add_bind->set_text(TTR("Add"));
add_bind_hb->add_child(add_bind);
add_bind->connect("pressed", callable_mp(this, &ConnectDialog::_add_bind));
+ bind_controls.push_back(add_bind);
Button *del_bind = memnew(Button);
del_bind->set_text(TTR("Remove"));
add_bind_hb->add_child(del_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);
bind_editor = memnew(EditorInspector);
+ bind_controls.push_back(bind_editor);
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);
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);
ERR_FAIL_COND(!target);
- ConnectDialog::ConnectionData cToMake;
- cToMake.source = connect_dialog->get_source();
- cToMake.target = target;
- cToMake.signal = connect_dialog->get_signal_name();
- cToMake.method = connect_dialog->get_dst_method_name();
- cToMake.binds = connect_dialog->get_binds();
+ ConnectDialog::ConnectionData connection;
+ connection.source = connect_dialog->get_source();
+ connection.target = target;
+ connection.signal = connect_dialog->get_signal_name();
+ connection.method = connect_dialog->get_dst_method_name();
+ connection.unbinds = connect_dialog->get_unbinds();
+ if (connection.unbinds == 0) {
+ connection.binds = connect_dialog->get_binds();
+ }
bool defer = connect_dialog->get_deferred();
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
// (in the class, the script itself, or inherited).
bool add_script_function = false;
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.
bool found_inherited_function = false;
Ref<Script> inherited_script = script->get_base_script();
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) {
found_inherited_function = true;
break;
@@ -575,23 +609,23 @@ void ConnectionsDock::_make_or_edit_connection() {
if (add_script_function) {
// Pick up args here before "it" is deleted by update_tree.
script_function_args = it->get_metadata(0).operator Dictionary()["args"];
- for (int i = 0; i < cToMake.binds.size(); i++) {
- script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cToMake.binds[i].get_type()));
+ for (int i = 0; i < connection.binds.size(); i++) {
+ script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(connection.binds[i].get_type()));
}
}
if (connect_dialog->is_editing()) {
_disconnect(*it);
- _connect(cToMake);
+ _connect(connection);
} else {
- _connect(cToMake);
+ _connect(connection);
}
// IMPORTANT NOTE: _disconnect and _connect cause an update_tree, which will delete the object "it" is pointing to.
it = nullptr;
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();
}
@@ -601,20 +635,18 @@ void ConnectionsDock::_make_or_edit_connection() {
/*
* Creates single connection w/ undo-redo functionality.
*/
-void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
- Node *source = static_cast<Node *>(cToMake.source);
- Node *target = static_cast<Node *>(cToMake.target);
+void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_connection) {
+ Node *source = Object::cast_to<Node>(p_connection.source);
+ Node *target = Object::cast_to<Node>(p_connection.target);
if (!source || !target) {
return;
}
- undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(cToMake.signal), String(cToMake.method)));
-
- Callable c(target, cToMake.method);
-
- undo_redo->add_do_method(source, "connect", cToMake.signal, c, cToMake.binds, cToMake.flags);
- undo_redo->add_undo_method(source, "disconnect", cToMake.signal, c);
+ Callable callable = p_connection.get_callable();
+ undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_connection.signal), String(p_connection.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(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
@@ -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->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
- undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
+ Callable callable = c.get_callable();
+ 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_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.
@@ -662,8 +695,8 @@ void ConnectionsDock::_disconnect_all() {
while (child) {
Connection cd = child->get_metadata(0);
ConnectDialog::ConnectionData c = cd;
- undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
- 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, c.get_callable());
+ undo_redo->add_undo_method(selectedNode, "connect", c.signal, c.get_callable(), c.binds, c.flags);
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.
*/
void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
- Node *src = static_cast<Node *>(cToEdit.source);
- Node *dst = static_cast<Node *>(cToEdit.target);
+ Node *src = Object::cast_to<Node>(cToEdit.source);
+ Node *dst = Object::cast_to<Node>(cToEdit.target);
if (src && dst) {
const String &signalname = cToEdit.signal;
@@ -1044,7 +1077,9 @@ void ConnectionsDock::update_tree() {
if (c.flags & CONNECT_ONESHOT) {
path += " (oneshot)";
}
- if (c.binds.size()) {
+ if (c.unbinds > 0) {
+ path += " unbinds(" + itos(c.unbinds) + ")";
+ } else if (!c.binds.is_empty()) {
path += " binds(";
for (int i = 0; i < c.binds.size(); i++) {
if (i > 0) {
@@ -1057,8 +1092,7 @@ void ConnectionsDock::update_tree() {
TreeItem *connection_item = tree->create_item(signal_item);
connection_item->set_text(0, path);
- Connection cd = c;
- connection_item->set_metadata(0, cd);
+ connection_item->set_metadata(0, cn);
connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons")));
}
}
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 5154cc90f1..46f92cec2b 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -48,6 +48,7 @@
class PopupMenu;
class ConnectDialogBinds;
+class SpinBox;
class ConnectDialog : public ConfirmationDialog {
GDCLASS(ConnectDialog, ConfirmationDialog);
@@ -59,25 +60,45 @@ public:
StringName signal;
StringName method;
uint32_t flags = 0;
+ int unbinds = 0;
Vector<Variant> binds;
- ConnectionData() {
- }
+ ConnectionData() {}
+
ConnectionData(const Connection &p_connection) {
source = Object::cast_to<Node>(p_connection.signal.get_object());
signal = p_connection.signal.get_name();
target = Object::cast_to<Node>(p_connection.callable.get_object());
- method = p_connection.callable.get_method();
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();
}
- operator Connection() {
- Connection c;
- c.signal = ::Signal(source, signal);
- c.callable = Callable(target, method);
- c.flags = flags;
- c.binds = binds;
- return c;
+
+ 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);
+ }
}
};
@@ -94,11 +115,13 @@ private:
SceneTreeEditor *tree;
AcceptDialog *error;
+ SpinBox *unbind_count;
EditorInspector *bind_editor;
OptionButton *type_list;
CheckBox *deferred;
CheckBox *oneshot;
CheckButton *advanced;
+ Vector<Control *> bind_controls;
Label *error_label;
@@ -107,6 +130,7 @@ private:
void _item_activated();
void _text_submitted(const String &_text);
void _tree_node_selected();
+ void _unbind_count_changed(double p_count);
void _add_bind();
void _remove_bind();
void _advanced_pressed();
@@ -123,6 +147,7 @@ public:
void set_dst_node(Node *p_node);
StringName get_dst_method_name() const;
void set_dst_method(const StringName &p_method);
+ int get_unbinds() const;
Vector<Variant> get_binds() const;
bool get_deferred() const;
@@ -176,7 +201,7 @@ class ConnectionsDock : public VBoxContainer {
void _filter_changed(const String &p_text);
void _make_or_edit_connection();
- void _connect(ConnectDialog::ConnectionData cToMake);
+ void _connect(ConnectDialog::ConnectionData p_connection);
void _disconnect(TreeItem &item);
void _disconnect_all();
diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h
index a20e10005d..94e4f67348 100644
--- a/editor/inspector_dock.h
+++ b/editor/inspector_dock.h
@@ -32,7 +32,6 @@
#define INSPECTOR_DOCK_H
#include "editor/animation_track_editor.h"
-#include "editor/connections_dialog.h"
#include "editor/create_dialog.h"
#include "editor/editor_data.h"
#include "editor/editor_inspector.h"
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 215138a4df..d8f16b367a 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -30,6 +30,7 @@
#include "node_dock.h"
+#include "connections_dialog.h"
#include "editor_node.h"
#include "editor_scale.h"
diff --git a/editor/node_dock.h b/editor/node_dock.h
index cef1561e8e..b35be8de8a 100644
--- a/editor/node_dock.h
+++ b/editor/node_dock.h
@@ -31,9 +31,10 @@
#ifndef NODE_DOCK_H
#define NODE_DOCK_H
-#include "connections_dialog.h"
#include "groups_editor.h"
+class ConnectionsDock;
+
class NodeDock : public VBoxContainer {
GDCLASS(NodeDock, VBoxContainer);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 3dffc9cde7..ffaf34cfdc 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -31,7 +31,6 @@
#ifndef SCENE_TREE_DOCK_H
#define SCENE_TREE_DOCK_H
-#include "editor/connections_dialog.h"
#include "editor/create_dialog.h"
#include "editor/editor_data.h"
#include "editor/groups_editor.h"