summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2023-01-09 19:24:36 +0100
committerJuan Linietsky <reduzio@gmail.com>2023-01-10 14:09:24 +0100
commite6a4debede608808d2aac5985a1ad8415d5dc7cd (patch)
tree64411bee30b12b5ba7967bef0a15b69d8aaa7570 /scene
parentf5f7d11ac47244e4cc02cd7336ba86e0ed272dc3 (diff)
Change set_drag_forwarding() to use callables.
* This solution is much cleaner than the one in 3.x thanks to the use of callables. * Works without issues in any language (no need to worry about camel or snake case). * Editor code uses a compatibility function (too much work to redo). Fixes #59899
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/color_picker.cpp2
-rw-r--r--scene/gui/control.cpp66
-rw-r--r--scene/gui/control.h7
-rw-r--r--scene/gui/tab_container.cpp2
4 files changed, 52 insertions, 25 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 944363bcb0..b5846cb692 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -642,7 +642,7 @@ inline int ColorPicker::_get_preset_size() {
void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
ColorPresetButton *btn_preset_new = memnew(ColorPresetButton(p_color, p_size));
btn_preset_new->set_tooltip_text(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1)));
- btn_preset_new->set_drag_forwarding(this);
+ btn_preset_new->set_drag_forwarding_compat(this);
btn_preset_new->set_button_group(preset_group);
preset_container->add_child(btn_preset_new);
btn_preset_new->set_pressed(true);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 8460728448..6e85ae5c0e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1813,33 +1813,53 @@ bool Control::is_focus_owner_in_shortcut_context() const {
// Drag and drop handling.
-void Control::set_drag_forwarding(Object *p_target) {
- if (p_target) {
- data.drag_owner = p_target->get_instance_id();
+void Control::set_drag_forwarding_compat(Object *p_base) {
+ if (p_base != nullptr) {
+ data.forward_drag = Callable(p_base, "_get_drag_data_fw").bind(this);
+ data.forward_can_drop = Callable(p_base, "_can_drop_data_fw").bind(this);
+ data.forward_drop = Callable(p_base, "_drop_data_fw").bind(this);
+
} else {
- data.drag_owner = ObjectID();
+ data.forward_drag = Callable();
+ data.forward_can_drop = Callable();
+ data.forward_drop = Callable();
}
}
+void Control::set_drag_forwarding(const Callable &p_drag, const Callable &p_can_drop, const Callable &p_drop) {
+ data.forward_drag = p_drag;
+ data.forward_can_drop = p_can_drop;
+ data.forward_drop = p_drop;
+}
+
Variant Control::get_drag_data(const Point2 &p_point) {
- if (data.drag_owner.is_valid()) {
- Object *obj = ObjectDB::get_instance(data.drag_owner);
- if (obj) {
- return obj->call("_get_drag_data_fw", p_point, this);
+ Variant ret;
+ if (data.forward_drag.is_valid()) {
+ Variant p = p_point;
+ const Variant *vp[1] = { &p };
+ Callable::CallError ce;
+ data.forward_drag.callp((const Variant **)vp, 1, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(Variant(), "Error calling forwarded method from 'get_drag_data': " + Variant::get_callable_error_text(data.forward_drag, (const Variant **)vp, 1, ce) + ".");
}
+ return ret;
}
- Variant dd;
- GDVIRTUAL_CALL(_get_drag_data, p_point, dd);
- return dd;
+ GDVIRTUAL_CALL(_get_drag_data, p_point, ret);
+ return ret;
}
bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
- if (data.drag_owner.is_valid()) {
- Object *obj = ObjectDB::get_instance(data.drag_owner);
- if (obj) {
- return obj->call("_can_drop_data_fw", p_point, p_data, this);
+ if (data.forward_can_drop.is_valid()) {
+ Variant ret;
+ Variant p = p_point;
+ const Variant *vp[2] = { &p, &p_data };
+ Callable::CallError ce;
+ data.forward_can_drop.callp((const Variant **)vp, 2, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_V_MSG(Variant(), "Error calling forwarded method from 'can_drop_data': " + Variant::get_callable_error_text(data.forward_can_drop, (const Variant **)vp, 2, ce) + ".");
}
+ return ret;
}
bool ret = false;
@@ -1848,12 +1868,16 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
- if (data.drag_owner.is_valid()) {
- Object *obj = ObjectDB::get_instance(data.drag_owner);
- if (obj) {
- obj->call("_drop_data_fw", p_point, p_data, this);
- return;
+ if (data.forward_drop.is_valid()) {
+ Variant ret;
+ Variant p = p_point;
+ const Variant *vp[2] = { &p, &p_data };
+ Callable::CallError ce;
+ data.forward_drop.callp((const Variant **)vp, 2, ret, ce);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_MSG("Error calling forwarded method from 'drop_data': " + Variant::get_callable_error_text(data.forward_drop, (const Variant **)vp, 2, ce) + ".");
}
+ return;
}
GDVIRTUAL_CALL(_drop_data, p_point, p_data);
@@ -3189,7 +3213,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("grab_click_focus"), &Control::grab_click_focus);
- ClassDB::bind_method(D_METHOD("set_drag_forwarding", "target"), &Control::set_drag_forwarding);
+ ClassDB::bind_method(D_METHOD("set_drag_forwarding", "drag_func", "can_drop_func", "drop_func"), &Control::set_drag_forwarding);
ClassDB::bind_method(D_METHOD("set_drag_preview", "control"), &Control::set_drag_preview);
ClassDB::bind_method(D_METHOD("is_drag_successful"), &Control::is_drag_successful);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 9705dd62db..52efe42bd5 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -168,7 +168,9 @@ private:
Control *parent_control = nullptr;
Window *parent_window = nullptr;
CanvasItem *parent_canvas_item = nullptr;
- ObjectID drag_owner;
+ Callable forward_drag;
+ Callable forward_can_drop;
+ Callable forward_drop;
// Positioning and sizing.
@@ -499,7 +501,8 @@ public:
// Drag and drop handling.
- virtual void set_drag_forwarding(Object *p_target);
+ virtual void set_drag_forwarding(const Callable &p_drag, const Callable &p_can_drop, const Callable &p_drop);
+ virtual void set_drag_forwarding_compat(Object *p_base);
virtual Variant get_drag_data(const Point2 &p_point);
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const;
virtual void drop_data(const Point2 &p_point, const Variant &p_data);
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index cd1ebba5d1..3457cfa94f 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -975,7 +975,7 @@ void TabContainer::_bind_methods() {
TabContainer::TabContainer() {
tab_bar = memnew(TabBar);
- tab_bar->set_drag_forwarding(this);
+ tab_bar->set_drag_forwarding_compat(this);
add_child(tab_bar, false, INTERNAL_MODE_FRONT);
tab_bar->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE);
tab_bar->connect("tab_changed", callable_mp(this, &TabContainer::_on_tab_changed));