Merge pull request #37965 from EricEzaM/drag-multiple-resources-onto-array-export

Drag multiple resources onto exported array variable at once
This commit is contained in:
Rémi Verschelde 2020-04-29 09:20:18 +02:00 committed by GitHub
commit fa34b8eda2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 1 deletions

View File

@ -412,8 +412,104 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
update_property(); update_property();
} }
void EditorPropertyArray::_notification(int p_what) { void EditorPropertyArray::_button_draw() {
if (dropping) {
Color color = get_theme_color("accent_color", "Editor");
edit->draw_rect(Rect2(Point2(), edit->get_size()), color, false);
}
} }
bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
String allowed_type = Variant::get_type_name(subtype);
Dictionary drag_data = p_drag_data;
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
Vector<String> files = drag_data["files"];
for (int i = 0; i < files.size(); i++) {
String file = files[i];
String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
for (int j = 0; j < allowed_type.get_slice_count(","); j++) {
String at = allowed_type.get_slice(",", j).strip_edges();
// Fail if one of the files is not of allowed type
if (!ClassDB::is_parent_class(ftype, at)) {
return false;
}
}
}
// If no files fail, drop is valid
return true;
}
return false;
}
bool EditorPropertyArray::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
return _is_drop_valid(p_data);
}
void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
ERR_FAIL_COND(!_is_drop_valid(p_data));
Dictionary drag_data = p_data;
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
Vector<String> files = drag_data["files"];
Variant array = object->get_array();
// Handle the case where array is not initialised yet
if (!array.is_array()) {
Callable::CallError ce;
array = Variant::construct(array_type, nullptr, 0, ce);
}
// Loop the file array and add to existing array
for (int i = 0; i < files.size(); i++) {
String file = files[i];
RES res = ResourceLoader::load(file);
if (res.is_valid()) {
array.call("push_back", res);
}
}
if (array.get_type() == Variant::ARRAY) {
array = array.call("duplicate");
}
emit_changed(get_edited_property(), array, "", false);
object->set_array(array);
update_property();
}
}
void EditorPropertyArray::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAG_BEGIN) {
if (is_visible_in_tree()) {
if (_is_drop_valid(get_viewport()->gui_get_drag_data())) {
dropping = true;
edit->update();
}
}
}
if (p_what == NOTIFICATION_DRAG_END) {
if (dropping) {
dropping = false;
edit->update();
}
}
}
void EditorPropertyArray::_edit_pressed() { void EditorPropertyArray::_edit_pressed() {
Variant array = get_edited_object()->get(get_edited_property()); Variant array = get_edited_object()->get(get_edited_property());
@ -490,6 +586,8 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
} }
void EditorPropertyArray::_bind_methods() { void EditorPropertyArray::_bind_methods() {
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &EditorPropertyArray::can_drop_data_fw);
ClassDB::bind_method(D_METHOD("drop_data_fw"), &EditorPropertyArray::drop_data_fw);
} }
EditorPropertyArray::EditorPropertyArray() { EditorPropertyArray::EditorPropertyArray() {
@ -503,6 +601,8 @@ EditorPropertyArray::EditorPropertyArray() {
edit->set_clip_text(true); edit->set_clip_text(true);
edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_edit_pressed)); edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_edit_pressed));
edit->set_toggle_mode(true); edit->set_toggle_mode(true);
edit->set_drag_forwarding(this);
edit->connect("draw", callable_mp(this, &EditorPropertyArray::_button_draw));
add_child(edit); add_child(edit);
add_focusable(edit); add_focusable(edit);
vbox = nullptr; vbox = nullptr;
@ -524,6 +624,8 @@ EditorPropertyArray::EditorPropertyArray() {
subtype = Variant::NIL; subtype = Variant::NIL;
subtype_hint = PROPERTY_HINT_NONE; subtype_hint = PROPERTY_HINT_NONE;
subtype_hint_string = ""; subtype_hint_string = "";
dropping = false;
} }
///////////////////// DICTIONARY /////////////////////////// ///////////////////// DICTIONARY ///////////////////////////

View File

@ -33,6 +33,7 @@
#include "editor/editor_inspector.h" #include "editor/editor_inspector.h"
#include "editor/editor_spin_slider.h" #include "editor/editor_spin_slider.h"
#include "editor/filesystem_dock.h"
#include "scene/gui/button.h" #include "scene/gui/button.h"
class EditorPropertyArrayObject : public Reference { class EditorPropertyArrayObject : public Reference {
@ -82,6 +83,7 @@ class EditorPropertyArray : public EditorProperty {
PopupMenu *change_type; PopupMenu *change_type;
bool updating; bool updating;
bool dropping;
Ref<EditorPropertyArrayObject> object; Ref<EditorPropertyArrayObject> object;
int page_len; int page_len;
@ -107,6 +109,11 @@ class EditorPropertyArray : public EditorProperty {
void _object_id_selected(const StringName &p_property, ObjectID p_id); void _object_id_selected(const StringName &p_property, ObjectID p_id);
void _remove_pressed(int p_index); void _remove_pressed(int p_index);
void _button_draw();
bool _is_drop_valid(const Dictionary &p_drag_data) const;
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
protected: protected:
static void _bind_methods(); static void _bind_methods();
void _notification(int p_what); void _notification(int p_what);