|
@@ -412,8 +412,104 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
|
|
update_property();
|
|
update_property();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+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) {
|
|
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 ///////////////////////////
|