summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/color_picker.cpp2
-rw-r--r--scene/gui/control.cpp76
-rw-r--r--scene/gui/control.h8
-rw-r--r--scene/gui/tab_container.cpp2
-rw-r--r--scene/gui/tree.cpp6
-rw-r--r--scene/main/scene_tree.cpp18
-rw-r--r--scene/main/scene_tree.h1
-rw-r--r--scene/resources/resource_format_text.cpp29
8 files changed, 95 insertions, 47 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..4188946494 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -864,6 +864,14 @@ void Control::_set_layout_mode(LayoutMode p_mode) {
}
}
+void Control::_update_layout_mode() {
+ LayoutMode computed_layout = _get_layout_mode();
+ if (data.stored_layout_mode != computed_layout) {
+ data.stored_layout_mode = computed_layout;
+ notify_property_list_changed();
+ }
+}
+
Control::LayoutMode Control::_get_layout_mode() const {
Node *parent_node = get_parent_control();
// In these modes the property is read-only.
@@ -1813,33 +1821,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 +1876,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);
@@ -2870,6 +2902,8 @@ void Control::_notification(int p_notification) {
data.parent_window = Object::cast_to<Window>(parent_node);
data.theme_owner->assign_theme_on_parented(this);
+
+ _update_layout_mode();
} break;
case NOTIFICATION_UNPARENTED: {
@@ -3189,7 +3223,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..22a37dd89e 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.
@@ -280,6 +282,7 @@ private:
void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]);
void _set_layout_mode(LayoutMode p_mode);
+ void _update_layout_mode();
LayoutMode _get_layout_mode() const;
LayoutMode _get_default_layout_mode() const;
void _set_anchors_layout_preset(int p_preset);
@@ -499,7 +502,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));
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index e76abe57ba..3458b87b8d 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -4850,7 +4850,11 @@ void Tree::_do_incr_search(const String &p_add) {
return;
}
- item->select(col);
+ if (select_mode == SELECT_MULTI) {
+ item->set_as_cursor(col);
+ } else {
+ item->select(col);
+ }
ensure_cursor_is_visible();
}
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index c6bfe5742f..b5c587c0aa 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -1131,11 +1131,11 @@ Error SceneTree::change_scene_to_file(const String &p_path) {
}
Error SceneTree::change_scene_to_packed(const Ref<PackedScene> &p_scene) {
- Node *new_scene = nullptr;
- if (p_scene.is_valid()) {
- new_scene = p_scene->instantiate();
- ERR_FAIL_COND_V(!new_scene, ERR_CANT_CREATE);
- }
+ ERR_FAIL_COND_V_MSG(p_scene.is_null(), ERR_INVALID_PARAMETER, "Can't change to a null scene. Use unload_current_scene() if you wish to unload it.");
+
+ Node *new_scene = p_scene->instantiate();
+ new_scene = p_scene->instantiate();
+ ERR_FAIL_COND_V(!new_scene, ERR_CANT_CREATE);
call_deferred(SNAME("_change_scene"), new_scene);
return OK;
@@ -1147,6 +1147,13 @@ Error SceneTree::reload_current_scene() {
return change_scene_to_file(fname);
}
+void SceneTree::unload_current_scene() {
+ if (current_scene) {
+ memdelete(current_scene);
+ current_scene = nullptr;
+ }
+}
+
void SceneTree::add_current_scene(Node *p_current) {
current_scene = p_current;
root->add_child(p_current);
@@ -1297,6 +1304,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("change_scene_to_packed", "packed_scene"), &SceneTree::change_scene_to_packed);
ClassDB::bind_method(D_METHOD("reload_current_scene"), &SceneTree::reload_current_scene);
+ ClassDB::bind_method(D_METHOD("unload_current_scene"), &SceneTree::unload_current_scene);
ClassDB::bind_method(D_METHOD("_change_scene"), &SceneTree::_change_scene);
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 77cfe0a04a..fc185b4f37 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -361,6 +361,7 @@ public:
Error change_scene_to_file(const String &p_path);
Error change_scene_to_packed(const Ref<PackedScene> &p_scene);
Error reload_current_scene();
+ void unload_current_scene();
Ref<SceneTreeTimer> create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false);
Ref<Tween> create_tween();
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index d80a4004a4..80b9ff3f38 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -601,14 +601,14 @@ Error ResourceLoaderText::load() {
resource_current++;
+ if (progress && resources_total > 0) {
+ *progress = resource_current / float(resources_total);
+ }
+
int_resources[id] = res; //always assign int resources
- if (do_assign) {
- if (cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE) {
- res->set_path(path);
- } else {
- res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE);
- res->set_scene_unique_id(id);
- }
+ if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE);
+ res->set_scene_unique_id(id);
}
Dictionary missing_resource_properties;
@@ -663,10 +663,6 @@ Error ResourceLoaderText::load() {
if (!missing_resource_properties.is_empty()) {
res->set_meta(META_MISSING_RESOURCES, missing_resource_properties);
}
-
- if (progress && resources_total > 0) {
- *progress = resource_current / float(resources_total);
- }
}
while (true) {
@@ -716,8 +712,6 @@ Error ResourceLoaderText::load() {
resource = Ref<Resource>(r);
}
- resource_current++;
-
Dictionary missing_resource_properties;
while (true) {
@@ -770,6 +764,12 @@ Error ResourceLoaderText::load() {
}
}
+ resource_current++;
+
+ if (progress && resources_total > 0) {
+ *progress = resource_current / float(resources_total);
+ }
+
if (missing_resource) {
missing_resource->set_recording_properties(false);
}
@@ -779,9 +779,6 @@ Error ResourceLoaderText::load() {
}
error = OK;
- if (progress && resources_total > 0) {
- *progress = resource_current / float(resources_total);
- }
return error;
}