Skip to content

Improve drag and drop into array property editors#102534

Merged
Repiteo merged 6 commits intogodotengine:masterfrom
ttencate:feature/drag_drop_into_array
Mar 14, 2025
Merged

Improve drag and drop into array property editors#102534
Repiteo merged 6 commits intogodotengine:masterfrom
ttencate:feature/drag_drop_into_array

Conversation

@ttencate
Copy link
Copy Markdown
Contributor

@ttencate ttencate commented Feb 7, 2025

This makes a couple of things work that you'd expect to work:

  • Dragging a node now highlights properties accepting that node's type as valid drop targets. The drop was already possible, it just wasn't indicated like it was for other types of properties.
  • Custom resources can now be dropped onto array property editors that accept that resource.
  • Nodes with a script can now be dropped onto array property editors that accept that type of script.
  • Items can be added to an array property by dropping them on the + Add Element button. The button is highlighted to indicate this.

Further details and rationale for implementation can be found in the individual commit messages.

Fixes godotengine/godot-proposals#6862, which currently has 33 upvotes and no objections.

CC @YuriSizov who brought this up on Mastodon.

Demo video:

dragdrop.mp4

Test project:

dragdroptest.zip

@KoBeWi
Copy link
Copy Markdown
Member

KoBeWi commented Feb 7, 2025

Custom Resource Array gets highlighted for CustomResource.gd, even though it doesn't (and shouldn't) accept it.

O8sr887BVQ.mp4

@ttencate
Copy link
Copy Markdown
Contributor Author

ttencate commented Feb 8, 2025

@KoBeWi Great find! But that bug is also present in the current master, not caused by this PR 😁 In fact, you can also drag CustomResource.gd onto the custom_resource property, which even accepts it despite being the wrong type. (You can also drag it onto resource and resource_array, but that makes sense because Script inherits from Resource.)

I'll see if I can find out why that happens and contribute a fix, but I don't think it needs to block this PR.

@ttencate
Copy link
Copy Markdown
Contributor Author

ttencate commented Feb 8, 2025

Correction: it does need some work in this PR because I copied the faulty logic into EditorPropertyArray for the case of dropping a "resource" type (e.g. from another property) onto the array itself.

The cause is this bit here:

StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res.ptr());
if (_is_type_valid(custom_class, allowed_types)) {
return true;
}

I'm not sure what the purpose of that code is. _is_type_valid already checked whether the type inherits from one of the allowed types, both for built-in and custom classes. But I'll assume that it's good for something, and not just remove it.

The bug happens because EditorNode::get_object_custom_type_name() returns the global_class name of the script set on the object, but also if the object is itself a Script, it returns its global_class. No idea why that is useful; it seems like conflating two different things. This method was introduced in 4f72178 for use in a tooltip in SceneTreeEditor, where it's only called for Nodes so the object can never be a Script anyway. Since then, usage has been added in e8f15f7 for the EditorResourcePicker, where it's explicitly only used to get the global_class of Script objects directly. And this was subsequently changed in d32f270, now calling it with the resource itself rather than the resource's script, introducing the bug.

For now, I'll add another commit to this PR that fixes the bug in the least invasive way possible, and also modify the commit where I copied the bug to the EditorPropertyArray. But I think all this logic is too convoluted and too scattered, and should be cleaned up at some point.

@ttencate ttencate force-pushed the feature/drag_drop_into_array branch from 4e6d4fc to 7e84479 Compare February 8, 2025 10:40
@ttencate
Copy link
Copy Markdown
Contributor Author

ttencate commented Feb 8, 2025

Should all be fixed now, please take another look.

FYI, I would rather not squash these commits together, because each of them can stand on its own. If any regressions are introduced, bisecting and focused reverting is easier this way.

Comment thread editor/editor_properties_array_dict.cpp Outdated
Comment thread editor/editor_properties_array_dict.cpp Outdated
Comment thread editor/editor_properties_array_dict.cpp Outdated
@ttencate ttencate force-pushed the feature/drag_drop_into_array branch 2 times, most recently from 5a09650 to 3ec3d2c Compare February 10, 2025 08:04
ttencate added 6 commits March 8, 2025 19:24
This was already done for Resource properties; this just makes things
consistent.
See discussion on godotengine#102534. Before this fix, it was possible to drag a
file `CustomResource.gd` with `class_name CustomResource` onto a
property of type `CustomResource`. Of course, the intention is that only
`Resource`s with the `CustomResource` script attached are accepted.

(Actually accepting the script, but creating a resource from it
automatically, is left as a future improvement.)
This duplicates some of the logic in EditorResourcePicker, but that's
unavoidable: EditorResourcePicker works on a single, loaded resource,
whereas we'd like this to be efficient and not need to load all
(potentially many) dragged resources. Instead, we use the
EditorFileSystem cache to get the information we need.

Note that EditorResourcePicker also supports some automatic conversions,
such as from Shader to ShaderMaterial. This change does not attempt to
make that work for arrays as well.
For example, an Array[MyScript] property now accepts any node with the
script MyScript on it. This works for Node and NodePath arrays alike,
and also with the @export_node_path annotation.
The most common scenario is dragging a file from the filesystem dock,
which drags it as type "file", not "resource". This already worked. This
change also makes it possible to drag a resource from another property
editor.
Instead of having to first click the button, then drag the item into the
new slot, this allows just dragging the item onto the button directly.
The button is highlighted as a valid drop target to signal this.
@ttencate ttencate force-pushed the feature/drag_drop_into_array branch from 3ec3d2c to 93d342b Compare March 8, 2025 18:34
@ttencate
Copy link
Copy Markdown
Contributor Author

ttencate commented Mar 8, 2025

Rebased onto master, fixed conflicts with b9a6057. Now that the dust has settled on the 4.4 release, I guess this is ready to merge?

@KoBeWi KoBeWi modified the milestones: 4.x, 4.5 Mar 8, 2025
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Mar 13, 2025

Needs squash before this can be merged

@ttencate
Copy link
Copy Markdown
Contributor Author

@Repiteo As mentioned above:

FYI, I would rather not squash these commits together, because each of them can stand on its own. If any regressions are introduced, bisecting and focused reverting is easier this way.

Each of them could even have been a separate PR, but the overhead didn't seem worth it.

Still want me to squash?

Copy link
Copy Markdown
Contributor

@Repiteo Repiteo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, nah. The squashing isn't a hard-rule, and doesn't need to be enforced when you've done such a good job at making atomic commits. We'll ship it as-is!

@Repiteo Repiteo merged commit 409fe3c into godotengine:master Mar 14, 2025
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Mar 14, 2025

Thanks!

@azur-wolve
Copy link
Copy Markdown

adding a red tone on fields that cant accept it would be a plus

@ttencate
Copy link
Copy Markdown
Contributor Author

adding a red tone on fields that cant accept it would be a plus

I think it's better to draw attention to properties that can be interacted with, but you can always open a proposal!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support drag and drop node/Resource directly to array Add Element button to add element and set reference at once

5 participants