diff options
author | Rémi Verschelde <remi@verschelde.fr> | 2022-01-04 12:22:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-04 12:22:46 +0100 |
commit | 42312f066bd7fc5eb66abb5a2d7161717ceb3c55 (patch) | |
tree | 8afb65b7e1f24c8dfde5d4f66c7469bfaee3b592 /editor | |
parent | b74968c2ca6ae70e074fa44ee368b513a62aa309 (diff) | |
parent | cdac60759e931b07811025adf053b1e88495ad80 (diff) | |
download | redot-engine-42312f066bd7fc5eb66abb5a2d7161717ceb3c55.tar.gz |
Merge pull request #53313 from KoBeWi/debinded_konnekt
Diffstat (limited to 'editor')
-rw-r--r-- | editor/connections_dialog.cpp | 98 | ||||
-rw-r--r-- | editor/connections_dialog.h | 49 | ||||
-rw-r--r-- | editor/inspector_dock.h | 1 | ||||
-rw-r--r-- | editor/node_dock.cpp | 1 | ||||
-rw-r--r-- | editor/node_dock.h | 3 | ||||
-rw-r--r-- | editor/scene_tree_dock.h | 1 |
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" |