Merge pull request #119418 from KoBeWi/what_even_is_this
Improve 2D editor dropping code
This commit is contained in:
@@ -6290,42 +6290,59 @@ bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String &p_targe
|
||||
return false;
|
||||
}
|
||||
|
||||
void CanvasItemEditorViewport::_add_node_to_scene(Node *p_parent, Node *p_child, const Vector2 &p_target_position) {
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
if (p_parent) {
|
||||
undo_redo->add_do_method(p_parent, "add_child", p_child, true);
|
||||
undo_redo->add_do_method(p_child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
|
||||
undo_redo->add_do_reference(p_child);
|
||||
undo_redo->add_undo_method(p_parent, "remove_child", p_child);
|
||||
|
||||
const String new_name = p_parent->validate_child_name(p_child);
|
||||
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
|
||||
undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent), p_child->get_class(), new_name);
|
||||
undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent)) + "/" + new_name));
|
||||
} else { // If no parent is selected, set as root node of the scene.
|
||||
undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", p_child);
|
||||
undo_redo->add_do_reference(p_child);
|
||||
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
|
||||
}
|
||||
// There's nothing to be used as source position, so snapping will work as absolute if enabled.
|
||||
Vector2 target_position = canvas_item_editor->snap_point(p_target_position);
|
||||
CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_parent);
|
||||
// Set position via undo_redo for proper live editing support.
|
||||
undo_redo->add_do_method(p_child, "set_position", parent_ci ? parent_ci->get_global_transform().affine_inverse().xform(target_position) : target_position);
|
||||
|
||||
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
|
||||
undo_redo->add_do_method(editor_selection, "add_node", p_child);
|
||||
}
|
||||
|
||||
void CanvasItemEditorViewport::_create_texture_node(Node *p_parent, Node *p_child, const String &p_path, const Point2 &p_point) {
|
||||
// Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
|
||||
const String &node_name = Node::adjust_name_casing(p_path.get_file().get_basename());
|
||||
if (!node_name.is_empty()) {
|
||||
p_child->set_name(node_name);
|
||||
}
|
||||
// Compute the global position.
|
||||
Transform2D xform = canvas_item_editor->get_canvas_transform();
|
||||
Point2 target_position = xform.affine_inverse().xform(p_point);
|
||||
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
// Adjust position for Control and TouchScreenButton.
|
||||
Ref<Texture2D> texture = ResourceCache::get_ref(p_path);
|
||||
|
||||
if (p_parent) {
|
||||
undo_redo->add_do_method(p_parent, "add_child", p_child, true);
|
||||
undo_redo->add_do_method(p_child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
|
||||
undo_redo->add_do_reference(p_child);
|
||||
undo_redo->add_undo_method(p_parent, "remove_child", p_child);
|
||||
} else { // If no parent is selected, set as root node of the scene.
|
||||
undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", p_child);
|
||||
undo_redo->add_do_method(p_child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
|
||||
undo_redo->add_do_reference(p_child);
|
||||
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
|
||||
}
|
||||
|
||||
if (p_parent) {
|
||||
String new_name = p_parent->validate_child_name(p_child);
|
||||
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
|
||||
undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent), p_child->get_class(), new_name);
|
||||
undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent)) + "/" + new_name));
|
||||
if (Object::cast_to<Control>(p_child) || Object::cast_to<TouchScreenButton>(p_child) || Object::cast_to<Polygon2D>(p_child)) {
|
||||
target_position -= texture->get_size() / 2;
|
||||
}
|
||||
_add_node_to_scene(p_parent, p_child, target_position);
|
||||
|
||||
// Use undo_redo for properties to support live editing.
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
if (Object::cast_to<TouchScreenButton>(p_child) || Object::cast_to<TextureButton>(p_child)) {
|
||||
undo_redo->add_do_property(p_child, "texture_normal", texture);
|
||||
} else {
|
||||
undo_redo->add_do_property(p_child, "texture", texture);
|
||||
}
|
||||
|
||||
// make visible for certain node type
|
||||
// Make visible for certain node type.
|
||||
if (Object::cast_to<Control>(p_child)) {
|
||||
Size2 texture_size = texture->get_size();
|
||||
undo_redo->add_do_property(p_child, "size", texture_size);
|
||||
@@ -6339,28 +6356,10 @@ void CanvasItemEditorViewport::_create_texture_node(Node *p_parent, Node *p_chil
|
||||
};
|
||||
undo_redo->add_do_property(p_child, "polygon", list);
|
||||
}
|
||||
|
||||
// Compute the global position
|
||||
Transform2D xform = canvas_item_editor->get_canvas_transform();
|
||||
Point2 target_position = xform.affine_inverse().xform(p_point);
|
||||
|
||||
// Adjust position for Control and TouchScreenButton
|
||||
if (Object::cast_to<Control>(p_child) || Object::cast_to<TouchScreenButton>(p_child)) {
|
||||
target_position -= texture->get_size() / 2;
|
||||
}
|
||||
|
||||
// There's nothing to be used as source position, so snapping will work as absolute if enabled.
|
||||
target_position = canvas_item_editor->snap_point(target_position);
|
||||
|
||||
CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_parent);
|
||||
Point2 local_target_pos = parent_ci ? parent_ci->get_global_transform().affine_inverse().xform(target_position) : target_position;
|
||||
|
||||
undo_redo->add_do_method(p_child, "set_position", local_target_pos);
|
||||
}
|
||||
|
||||
void CanvasItemEditorViewport::_create_audio_node(Node *p_parent, const String &p_path, const Point2 &p_point) {
|
||||
AudioStreamPlayer2D *child = memnew(AudioStreamPlayer2D);
|
||||
child->set_stream(ResourceCache::get_ref(p_path));
|
||||
|
||||
// Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
|
||||
const String &node_name = Node::adjust_name_casing(p_path.get_file().get_basename());
|
||||
@@ -6368,41 +6367,14 @@ void CanvasItemEditorViewport::_create_audio_node(Node *p_parent, const String &
|
||||
child->set_name(node_name);
|
||||
}
|
||||
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
|
||||
if (p_parent) {
|
||||
undo_redo->add_do_method(p_parent, "add_child", child, true);
|
||||
undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
|
||||
undo_redo->add_do_reference(child);
|
||||
undo_redo->add_undo_method(p_parent, "remove_child", child);
|
||||
} else { // If no parent is selected, set as root node of the scene.
|
||||
undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child);
|
||||
undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
|
||||
undo_redo->add_do_reference(child);
|
||||
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
|
||||
}
|
||||
|
||||
if (p_parent) {
|
||||
String new_name = p_parent->validate_child_name(child);
|
||||
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
|
||||
undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent), child->get_class(), new_name);
|
||||
undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent)) + "/" + new_name));
|
||||
}
|
||||
|
||||
// Compute the global position
|
||||
Transform2D xform = canvas_item_editor->get_canvas_transform();
|
||||
Point2 target_position = xform.affine_inverse().xform(p_point);
|
||||
|
||||
// There's nothing to be used as source position, so snapping will work as absolute if enabled.
|
||||
target_position = canvas_item_editor->snap_point(target_position);
|
||||
_add_node_to_scene(p_parent, child, target_position);
|
||||
|
||||
CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_parent);
|
||||
Point2 local_target_pos = parent_ci ? parent_ci->get_global_transform().affine_inverse().xform(target_position) : target_position;
|
||||
|
||||
undo_redo->add_do_method(child, "set_position", local_target_pos);
|
||||
|
||||
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
|
||||
undo_redo->add_do_method(editor_selection, "add_node", child);
|
||||
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||
undo_redo->add_do_property(child, "stream", ResourceCache::get_ref(p_path));
|
||||
}
|
||||
|
||||
bool CanvasItemEditorViewport::_create_instance(Node *p_parent, const String &p_path, const Point2 &p_point) {
|
||||
@@ -6512,7 +6484,6 @@ void CanvasItemEditorViewport::_perform_drop_data() {
|
||||
if (texture.is_valid()) {
|
||||
Node *child = Object::cast_to<Node>(ClassDB::instantiate(default_texture_node_type));
|
||||
_create_texture_node(target_node, child, path, drop_pos);
|
||||
undo_redo->add_do_method(editor_selection, "add_node", child);
|
||||
}
|
||||
|
||||
Ref<AudioStream> audio = res;
|
||||
@@ -6567,9 +6538,9 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
|
||||
|
||||
String error_message;
|
||||
for (const String &path : files) {
|
||||
const String &res_type = ResourceLoader::get_resource_type(path);
|
||||
const StringName res_type = ResourceLoader::get_resource_type(path);
|
||||
|
||||
if (ClassDB::is_parent_class(res_type, "PackedScene")) {
|
||||
if (ClassDB::is_parent_class(res_type, SNAME("PackedScene"))) {
|
||||
Ref<PackedScene> scn = ResourceLoader::load(path);
|
||||
ERR_CONTINUE(scn.is_null());
|
||||
|
||||
@@ -6583,11 +6554,9 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
|
||||
}
|
||||
memdelete(instantiated_scene);
|
||||
instantiate_type |= SCENE;
|
||||
}
|
||||
if (ClassDB::is_parent_class(res_type, "Texture2D")) {
|
||||
} else if (ClassDB::is_parent_class(res_type, SNAME("Texture2D"))) {
|
||||
instantiate_type |= TEXTURE;
|
||||
}
|
||||
if (ClassDB::is_parent_class(res_type, "AudioStream")) {
|
||||
} else if (ClassDB::is_parent_class(res_type, SNAME("AudioStream"))) {
|
||||
instantiate_type |= AUDIO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,6 +685,7 @@ class CanvasItemEditorViewport : public Control {
|
||||
|
||||
bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) const;
|
||||
bool _is_any_texture_selected() const;
|
||||
void _add_node_to_scene(Node *p_parent, Node *p_child, const Vector2 &p_target_position);
|
||||
void _create_texture_node(Node *p_parent, Node *p_child, const String &p_path, const Point2 &p_point);
|
||||
void _create_audio_node(Node *p_parent, const String &p_path, const Point2 &p_point);
|
||||
bool _create_instance(Node *p_parent, const String &p_path, const Point2 &p_point);
|
||||
|
||||
Reference in New Issue
Block a user