mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
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
This commit is contained in:
parent
f5f7d11ac4
commit
e6a4debede
@ -780,67 +780,13 @@
|
||||
</method>
|
||||
<method name="set_drag_forwarding">
|
||||
<return type="void" />
|
||||
<param index="0" name="target" type="Object" />
|
||||
<param index="0" name="drag_func" type="Callable" />
|
||||
<param index="1" name="can_drop_func" type="Callable" />
|
||||
<param index="2" name="drop_func" type="Callable" />
|
||||
<description>
|
||||
Forwards the handling of this control's drag and drop to [param target] object.
|
||||
Forwarding can be implemented in the target object similar to the methods [method _get_drag_data], [method _can_drop_data], and [method _drop_data] but with two differences:
|
||||
1. The function name must be suffixed with [b]_fw[/b]
|
||||
2. The function must take an extra argument that is the control doing the forwarding
|
||||
[codeblocks]
|
||||
[gdscript]
|
||||
# ThisControl.gd
|
||||
extends Control
|
||||
export(Control) var target_control
|
||||
|
||||
func _ready():
|
||||
set_drag_forwarding(target_control)
|
||||
|
||||
# TargetControl.gd
|
||||
extends Control
|
||||
|
||||
func _can_drop_data_fw(position, data, from_control):
|
||||
return true
|
||||
|
||||
func _drop_data_fw(position, data, from_control):
|
||||
my_handle_data(data) # Your handler method.
|
||||
|
||||
func _get_drag_data_fw(position, from_control):
|
||||
set_drag_preview(my_preview)
|
||||
return my_data()
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
// ThisControl.cs
|
||||
public class ThisControl : Control
|
||||
{
|
||||
[Export]
|
||||
public Control TargetControl { get; set; }
|
||||
public override void _Ready()
|
||||
{
|
||||
SetDragForwarding(TargetControl);
|
||||
}
|
||||
}
|
||||
|
||||
// TargetControl.cs
|
||||
public class TargetControl : Control
|
||||
{
|
||||
public void CanDropDataFw(Vector2 position, object data, Control fromControl)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DropDataFw(Vector2 position, object data, Control fromControl)
|
||||
{
|
||||
MyHandleData(data); // Your handler method.
|
||||
}
|
||||
|
||||
public void GetDragDataFw(Vector2 position, Control fromControl)
|
||||
{
|
||||
SetDragPreview(MyPreview);
|
||||
return MyData();
|
||||
}
|
||||
}
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
Forwards the handling of this control's [method _get_drag_data], [method _can_drop_data] and [method _drop_data] virtual functions to delegate callables.
|
||||
For each argument, if not empty, the delegate callable is used, otherwise the local (virtual) function is used.
|
||||
The function format for each callable should be exactly the same as the virtual functions described above.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_drag_preview">
|
||||
|
@ -578,7 +578,7 @@ ActionMapEditor::ActionMapEditor() {
|
||||
action_tree->connect("button_clicked", callable_mp(this, &ActionMapEditor::_tree_button_pressed));
|
||||
main_vbox->add_child(action_tree);
|
||||
|
||||
action_tree->set_drag_forwarding(this);
|
||||
action_tree->set_drag_forwarding_compat(this);
|
||||
|
||||
// Adding event dialog
|
||||
event_config_dialog = memnew(InputEventConfigurationDialog);
|
||||
|
@ -754,7 +754,7 @@ CreateDialog::CreateDialog() {
|
||||
favorites->connect("cell_selected", callable_mp(this, &CreateDialog::_favorite_selected));
|
||||
favorites->connect("item_activated", callable_mp(this, &CreateDialog::_favorite_activated));
|
||||
favorites->add_theme_constant_override("draw_guides", 1);
|
||||
favorites->set_drag_forwarding(this);
|
||||
favorites->set_drag_forwarding_compat(this);
|
||||
fav_vb->add_margin_child(TTR("Favorites:"), favorites, true);
|
||||
|
||||
VBoxContainer *rec_vb = memnew(VBoxContainer);
|
||||
|
@ -903,7 +903,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
|
||||
effects->connect("item_edited", callable_mp(this, &EditorAudioBus::_effect_edited));
|
||||
effects->connect("cell_selected", callable_mp(this, &EditorAudioBus::_effect_selected));
|
||||
effects->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
|
||||
effects->set_drag_forwarding(this);
|
||||
effects->set_drag_forwarding_compat(this);
|
||||
effects->connect("item_mouse_selected", callable_mp(this, &EditorAudioBus::_effect_rmb));
|
||||
effects->set_allow_rmb_select(true);
|
||||
effects->set_focus_mode(FOCUS_CLICK);
|
||||
|
@ -935,7 +935,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
|
||||
tree->set_select_mode(Tree::SELECT_MULTI);
|
||||
tree->set_allow_reselect(true);
|
||||
|
||||
tree->set_drag_forwarding(this);
|
||||
tree->set_drag_forwarding_compat(this);
|
||||
|
||||
tree->set_columns(4);
|
||||
tree->set_column_titles_visible(true);
|
||||
|
@ -2065,7 +2065,7 @@ void EditorInspectorArray::_setup() {
|
||||
ae.panel = memnew(PanelContainer);
|
||||
ae.panel->set_focus_mode(FOCUS_ALL);
|
||||
ae.panel->set_mouse_filter(MOUSE_FILTER_PASS);
|
||||
ae.panel->set_drag_forwarding(this);
|
||||
ae.panel->set_drag_forwarding_compat(this);
|
||||
ae.panel->set_meta("index", begin_array_index + i);
|
||||
ae.panel->set_tooltip_text(vformat(TTR("Element %d: %s%d*"), i, array_element_prefix, i));
|
||||
ae.panel->connect("focus_entered", callable_mp((CanvasItem *)ae.panel, &PanelContainer::queue_redraw));
|
||||
|
@ -569,7 +569,7 @@ EditorPropertyPath::EditorPropertyPath() {
|
||||
HBoxContainer *path_hb = memnew(HBoxContainer);
|
||||
add_child(path_hb);
|
||||
path = memnew(LineEdit);
|
||||
path->set_drag_forwarding(this);
|
||||
path->set_drag_forwarding_compat(this);
|
||||
path->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE);
|
||||
path_hb->add_child(path);
|
||||
path->connect("text_submitted", callable_mp(this, &EditorPropertyPath::_path_selected));
|
||||
@ -3686,7 +3686,7 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
|
||||
assign->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
assign->set_clip_text(true);
|
||||
assign->connect("pressed", callable_mp(this, &EditorPropertyNodePath::_node_assign));
|
||||
assign->set_drag_forwarding(this);
|
||||
assign->set_drag_forwarding_compat(this);
|
||||
hbc->add_child(assign);
|
||||
|
||||
clear = memnew(Button);
|
||||
|
@ -715,7 +715,7 @@ EditorPropertyArray::EditorPropertyArray() {
|
||||
edit->set_clip_text(true);
|
||||
edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_edit_pressed));
|
||||
edit->set_toggle_mode(true);
|
||||
edit->set_drag_forwarding(this);
|
||||
edit->set_drag_forwarding_compat(this);
|
||||
edit->connect("draw", callable_mp(this, &EditorPropertyArray::_button_draw));
|
||||
add_child(edit);
|
||||
add_focusable(edit);
|
||||
|
@ -950,7 +950,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
|
||||
assign_button->set_flat(true);
|
||||
assign_button->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
assign_button->set_clip_text(true);
|
||||
assign_button->set_drag_forwarding(this);
|
||||
assign_button->set_drag_forwarding_compat(this);
|
||||
add_child(assign_button);
|
||||
assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected));
|
||||
assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw));
|
||||
|
@ -793,7 +793,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
|
||||
shortcuts->connect("item_activated", callable_mp(this, &EditorSettingsDialog::_shortcut_cell_double_clicked));
|
||||
tab_shortcuts->add_child(shortcuts);
|
||||
|
||||
shortcuts->set_drag_forwarding(this);
|
||||
shortcuts->set_drag_forwarding_compat(this);
|
||||
|
||||
// Adding event dialog
|
||||
shortcut_editor = memnew(InputEventConfigurationDialog);
|
||||
|
@ -1023,7 +1023,7 @@ ProjectExportDialog::ProjectExportDialog() {
|
||||
mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
presets = memnew(ItemList);
|
||||
// TODO: Must reimplement drag forwarding.
|
||||
//presets->set_drag_forwarding(this);
|
||||
//presets->set_drag_forwarding_compat(this);
|
||||
mc->add_child(presets);
|
||||
presets->connect("item_selected", callable_mp(this, &ProjectExportDialog::_edit_preset));
|
||||
duplicate_preset = memnew(Button);
|
||||
|
@ -3116,7 +3116,7 @@ FileSystemDock::FileSystemDock() {
|
||||
tree = memnew(Tree);
|
||||
|
||||
tree->set_hide_root(true);
|
||||
tree->set_drag_forwarding(this);
|
||||
tree->set_drag_forwarding_compat(this);
|
||||
tree->set_allow_rmb_select(true);
|
||||
tree->set_select_mode(Tree::SELECT_MULTI);
|
||||
tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE));
|
||||
@ -3153,7 +3153,7 @@ FileSystemDock::FileSystemDock() {
|
||||
files = memnew(ItemList);
|
||||
files->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
files->set_select_mode(ItemList::SELECT_MULTI);
|
||||
files->set_drag_forwarding(this);
|
||||
files->set_drag_forwarding_compat(this);
|
||||
files->connect("item_clicked", callable_mp(this, &FileSystemDock::_file_list_item_clicked));
|
||||
files->connect("gui_input", callable_mp(this, &FileSystemDock::_file_list_gui_input));
|
||||
files->connect("multi_selected", callable_mp(this, &FileSystemDock::_file_multi_selected));
|
||||
|
@ -4921,7 +4921,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
|
||||
|
||||
c->add_child(viewport);
|
||||
surface = memnew(Control);
|
||||
surface->set_drag_forwarding(this);
|
||||
surface->set_drag_forwarding_compat(this);
|
||||
add_child(surface);
|
||||
surface->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
||||
surface->set_clip_contents(true);
|
||||
|
@ -379,7 +379,7 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
|
||||
tree->set_column_expand(1, true);
|
||||
tree->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
tree->set_drag_forwarding(this);
|
||||
tree->set_drag_forwarding_compat(this);
|
||||
vbc->add_child(tree);
|
||||
|
||||
dialog = memnew(AcceptDialog);
|
||||
|
@ -3669,7 +3669,7 @@ ScriptEditor::ScriptEditor() {
|
||||
_sort_list_on_update = true;
|
||||
script_list->connect("item_clicked", callable_mp(this, &ScriptEditor::_script_list_clicked), CONNECT_DEFERRED);
|
||||
script_list->set_allow_rmb_select(true);
|
||||
script_list->set_drag_forwarding(this);
|
||||
script_list->set_drag_forwarding_compat(this);
|
||||
|
||||
context_menu = memnew(PopupMenu);
|
||||
add_child(context_menu);
|
||||
|
@ -2167,7 +2167,7 @@ ScriptTextEditor::ScriptTextEditor() {
|
||||
|
||||
connection_info_dialog = memnew(ConnectionInfoDialog);
|
||||
|
||||
code_editor->get_text_editor()->set_drag_forwarding(this);
|
||||
code_editor->get_text_editor()->set_drag_forwarding_compat(this);
|
||||
}
|
||||
|
||||
ScriptTextEditor::~ScriptTextEditor() {
|
||||
|
@ -451,7 +451,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
|
||||
vb->add_child(shader_list);
|
||||
shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected));
|
||||
shader_list->connect("item_clicked", callable_mp(this, &ShaderEditorPlugin::_shader_list_clicked));
|
||||
shader_list->set_drag_forwarding(this);
|
||||
shader_list->set_drag_forwarding_compat(this);
|
||||
|
||||
main_split->add_child(vb);
|
||||
vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE);
|
||||
|
@ -813,7 +813,7 @@ void Skeleton3DEditor::create_editors() {
|
||||
joint_tree->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
joint_tree->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
joint_tree->set_allow_rmb_select(true);
|
||||
joint_tree->set_drag_forwarding(this);
|
||||
joint_tree->set_drag_forwarding_compat(this);
|
||||
s_con->add_child(joint_tree);
|
||||
|
||||
pose_editor = memnew(BoneTransformEditor(skeleton));
|
||||
|
@ -1408,7 +1408,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
|
||||
frame_list->set_max_columns(0);
|
||||
frame_list->set_icon_mode(ItemList::ICON_MODE_TOP);
|
||||
frame_list->set_max_text_lines(2);
|
||||
frame_list->set_drag_forwarding(this);
|
||||
frame_list->set_drag_forwarding_compat(this);
|
||||
frame_list->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_frame_list_gui_input));
|
||||
frame_list->connect("item_selected", callable_mp(this, &SpriteFramesEditor::_frame_list_item_selected));
|
||||
|
||||
|
@ -650,7 +650,7 @@ TextEditor::TextEditor() {
|
||||
goto_line_dialog = memnew(GotoLineDialog);
|
||||
add_child(goto_line_dialog);
|
||||
|
||||
code_editor->get_text_editor()->set_drag_forwarding(this);
|
||||
code_editor->get_text_editor()->set_drag_forwarding_compat(this);
|
||||
}
|
||||
|
||||
TextEditor::~TextEditor() {
|
||||
|
@ -2236,7 +2236,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
|
||||
scene_tiles_list = memnew(ItemList);
|
||||
scene_tiles_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
scene_tiles_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
scene_tiles_list->set_drag_forwarding(this);
|
||||
scene_tiles_list->set_drag_forwarding_compat(this);
|
||||
scene_tiles_list->set_select_mode(ItemList::SELECT_MULTI);
|
||||
scene_tiles_list->connect("multi_selected", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_multi_selected));
|
||||
scene_tiles_list->connect("empty_clicked", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_lmb_empty_clicked));
|
||||
|
@ -728,7 +728,7 @@ TileSetEditor::TileSetEditor() {
|
||||
sources_list->add_user_signal(MethodInfo("sort_request"));
|
||||
sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list).bind(-1));
|
||||
sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
|
||||
sources_list->set_drag_forwarding(this);
|
||||
sources_list->set_drag_forwarding_compat(this);
|
||||
split_container_left_side->add_child(sources_list);
|
||||
|
||||
HBoxContainer *sources_bottom_actions = memnew(HBoxContainer);
|
||||
|
@ -509,7 +509,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
|
||||
scene_tiles_list = memnew(ItemList);
|
||||
scene_tiles_list->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
scene_tiles_list->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
scene_tiles_list->set_drag_forwarding(this);
|
||||
scene_tiles_list->set_drag_forwarding_compat(this);
|
||||
scene_tiles_list->connect("item_selected", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_tile_inspector).unbind(1));
|
||||
scene_tiles_list->connect("item_selected", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_action_buttons).unbind(1));
|
||||
scene_tiles_list->connect("item_activated", callable_mp(this, &TileSetScenesCollectionSourceEditor::_scenes_list_item_activated));
|
||||
|
@ -4915,7 +4915,7 @@ VisualShaderEditor::VisualShaderEditor() {
|
||||
graph->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
graph->set_show_zoom_label(true);
|
||||
add_child(graph);
|
||||
graph->set_drag_forwarding(this);
|
||||
graph->set_drag_forwarding_compat(this);
|
||||
float graph_minimap_opacity = EDITOR_GET("editors/visual_editors/minimap_opacity");
|
||||
graph->set_minimap_opacity(graph_minimap_opacity);
|
||||
float graph_lines_curvature = EDITOR_GET("editors/visual_editors/lines_curvature");
|
||||
@ -5146,7 +5146,7 @@ VisualShaderEditor::VisualShaderEditor() {
|
||||
|
||||
members = memnew(Tree);
|
||||
members_vb->add_child(members);
|
||||
members->set_drag_forwarding(this);
|
||||
members->set_drag_forwarding_compat(this);
|
||||
members->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
members->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
members->set_hide_root(true);
|
||||
|
@ -1415,7 +1415,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
|
||||
|
||||
add_child(tree);
|
||||
|
||||
tree->set_drag_forwarding(this);
|
||||
tree->set_drag_forwarding_compat(this);
|
||||
if (p_can_rename) {
|
||||
tree->set_allow_rmb_select(true);
|
||||
tree->connect("item_mouse_selected", callable_mp(this, &SceneTreeEditor::_rmb_select));
|
||||
|
@ -250,7 +250,7 @@ ReplicationEditor::ReplicationEditor() {
|
||||
tree->add_child(drop_label);
|
||||
drop_label->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
|
||||
|
||||
tree->set_drag_forwarding(this);
|
||||
tree->set_drag_forwarding_compat(this);
|
||||
}
|
||||
|
||||
void ReplicationEditor::_bind_methods() {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user