diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 8836eac936a0..7262e9f5c3ac 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1672,6 +1672,8 @@ void TileSetAtlasSourceEditor::_menu_option(int p_option) { _update_tile_id_label(); } break; case ADVANCED_AUTO_CREATE_TILES: { + atlases_to_auto_create_tiles.clear(); + atlases_to_auto_create_tiles.append(tile_set_atlas_source); _auto_create_tiles(); } break; case ADVANCED_AUTO_REMOVE_TILES: { @@ -2096,6 +2098,8 @@ void TileSetAtlasSourceEditor::_tile_proxy_object_changed(String p_what) { void TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed(String p_what) { if (p_what == "texture" && !atlas_source_proxy_object->get("texture").is_null()) { + atlases_to_auto_create_tiles.clear(); + atlases_to_auto_create_tiles.append(tile_set_atlas_source); confirm_auto_create_tiles->popup_centered(); } else if (p_what == "id") { emit_signal(SNAME("source_id_changed"), atlas_source_proxy_object->get_id()); @@ -2242,54 +2246,61 @@ void TileSetAtlasSourceEditor::edit(Ref p_tile_set, TileSetAtlasSource _update_current_tile_data_editor(); } -void TileSetAtlasSourceEditor::init_source() { +void TileSetAtlasSourceEditor::init_new_atlases(const Vector> &p_atlases) { tool_setup_atlas_source_button->set_pressed(true); + atlases_to_auto_create_tiles = p_atlases; confirm_auto_create_tiles->popup_centered(); } void TileSetAtlasSourceEditor::_auto_create_tiles() { - if (!tile_set_atlas_source) { - return; - } + for (Ref &atlas_source : atlases_to_auto_create_tiles) { + if (atlas_source.is_valid()) { + Ref texture = atlas_source->get_texture(); + if (texture.is_valid()) { + Vector2i margins = atlas_source->get_margins(); + Vector2i separation = atlas_source->get_separation(); + Vector2i texture_region_size = atlas_source->get_texture_region_size(); + Size2i grid_size = atlas_source->get_atlas_grid_size(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Create tiles in non-transparent texture regions")); + for (int y = 0; y < grid_size.y; y++) { + for (int x = 0; x < grid_size.x; x++) { + // Check if we have a tile at the coord. + Vector2i coords = Vector2i(x, y); + if (atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { + // Check if the texture is empty at the given coords. + Rect2i region = Rect2i(margins + (coords * (texture_region_size + separation)), texture_region_size); + bool is_opaque = false; + for (int region_x = region.get_position().x; region_x < region.get_end().x; region_x++) { + for (int region_y = region.get_position().y; region_y < region.get_end().y; region_y++) { + if (texture->is_pixel_opaque(region_x, region_y)) { + is_opaque = true; + break; + } + } + if (is_opaque) { + break; + } + } - Ref texture = tile_set_atlas_source->get_texture(); - if (texture.is_valid()) { - Vector2i margins = tile_set_atlas_source->get_margins(); - Vector2i separation = tile_set_atlas_source->get_separation(); - Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size(); - Size2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Create tiles in non-transparent texture regions")); - for (int y = 0; y < grid_size.y; y++) { - for (int x = 0; x < grid_size.x; x++) { - // Check if we have a tile at the coord - Vector2i coords = Vector2i(x, y); - if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { - // Check if the texture is empty at the given coords. - Rect2i region = Rect2i(margins + (coords * (texture_region_size + separation)), texture_region_size); - bool is_opaque = false; - for (int region_x = region.get_position().x; region_x < region.get_end().x; region_x++) { - for (int region_y = region.get_position().y; region_y < region.get_end().y; region_y++) { - if (texture->is_pixel_opaque(region_x, region_y)) { - is_opaque = true; - break; + // If we do have opaque pixels, create a tile. + if (is_opaque) { + undo_redo->add_do_method(*atlas_source, "create_tile", coords); + undo_redo->add_undo_method(*atlas_source, "remove_tile", coords); } } - if (is_opaque) { - break; - } - } - - // If we do have opaque pixels, create a tile. - if (is_opaque) { - undo_redo->add_do_method(tile_set_atlas_source, "create_tile", coords); - undo_redo->add_undo_method(tile_set_atlas_source, "remove_tile", coords); } } + undo_redo->commit_action(); } } - undo_redo->commit_action(); } + + _cancel_auto_create_tiles(); +} + +void TileSetAtlasSourceEditor::_cancel_auto_create_tiles() { + atlases_to_auto_create_tiles.clear(); } void TileSetAtlasSourceEditor::_auto_remove_tiles() { @@ -2644,6 +2655,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { confirm_auto_create_tiles->set_ok_button_text(TTR("Yes")); confirm_auto_create_tiles->add_cancel_button()->set_text(TTR("No")); confirm_auto_create_tiles->connect("confirmed", callable_mp(this, &TileSetAtlasSourceEditor::_auto_create_tiles)); + confirm_auto_create_tiles->connect("canceled", callable_mp(this, &TileSetAtlasSourceEditor::_cancel_auto_create_tiles)); add_child(confirm_auto_create_tiles); // Inspector plugin. diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h index ff928ab2eb8d..f964848907a4 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.h +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h @@ -270,7 +270,9 @@ class TileSetAtlasSourceEditor : public HSplitContainer { // -- Misc -- void _auto_create_tiles(); void _auto_remove_tiles(); + void _cancel_auto_create_tiles(); AcceptDialog *confirm_auto_create_tiles = nullptr; + Vector> atlases_to_auto_create_tiles; Vector2i _get_drag_offset_tile_coords(const Vector2i &p_offset) const; void _tile_set_changed(); @@ -288,7 +290,7 @@ class TileSetAtlasSourceEditor : public HSplitContainer { public: void edit(Ref p_tile_set, TileSetAtlasSource *p_tile_set_source, int p_source_id); - void init_source(); + void init_new_atlases(const Vector> &p_atlases); TileSetAtlasSourceEditor(); ~TileSetAtlasSourceEditor(); diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 3aace96b5e51..eb645d1d3fd7 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -57,35 +57,9 @@ void TileSetEditor::_drop_data_fw(const Point2 &p_point, const Variant &p_data, if (p_from == sources_list) { // Handle dropping a texture in the list of atlas resources. - int source_id = TileSet::INVALID_SOURCE; - int added = 0; Dictionary d = p_data; Vector files = d["files"]; - for (int i = 0; i < files.size(); i++) { - Ref resource = ResourceLoader::load(files[i]); - if (resource.is_valid()) { - // Retrieve the id for the next created source. - source_id = tile_set->get_next_source_id(); - - // Actually create the new source. - Ref atlas_source = memnew(TileSetAtlasSource); - atlas_source->set_texture(resource); - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Add a new atlas source")); - undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); - undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); - undo_redo->add_undo_method(*tile_set, "remove_source", source_id); - undo_redo->commit_action(); - added += 1; - } - } - - if (added == 1) { - tile_set_atlas_source_editor->init_source(); - } - - // Update the selected source (thus triggering an update). - _update_sources_list(source_id); + _load_texture_files(files); } } @@ -126,6 +100,43 @@ bool TileSetEditor::_can_drop_data_fw(const Point2 &p_point, const Variant &p_da return false; } +void TileSetEditor::_load_texture_files(const Vector &p_paths) { + int source_id = TileSet::INVALID_SOURCE; + Vector> atlases; + + for (const String &p_path : p_paths) { + Ref texture = ResourceLoader::load(p_path); + + if (texture.is_null()) { + EditorNode::get_singleton()->show_warning(TTR("Invalid texture selected.")); + continue; + } + + // Retrieve the id for the next created source. + source_id = tile_set->get_next_source_id(); + + // Actually create the new source. + Ref atlas_source = memnew(TileSetAtlasSource); + atlas_source->set_texture(texture); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Add a new atlas source")); + undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); + undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); + undo_redo->add_undo_method(*tile_set, "remove_source", source_id); + undo_redo->commit_action(); + + atlases.append(atlas_source); + } + + if (!atlases.is_empty()) { + tile_set_atlas_source_editor->init_new_atlases(atlases); + } + + // Update the selected source (thus triggering an update). + _update_sources_list(source_id); +} + void TileSetEditor::_update_sources_list(int force_selected_id) { if (tile_set.is_null()) { return; @@ -226,30 +237,6 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { TilesEditorUtils::get_singleton()->set_sources_lists_current(sources_list->get_current()); } -void TileSetEditor::_texture_file_selected(const String &p_path) { - Ref texture = ResourceLoader::load(p_path); - if (texture.is_null()) { - EditorNode::get_singleton()->show_warning(TTR("Invalid texture selected.")); - return; - } - - int source_id = tile_set->get_next_source_id(); - - Ref atlas_source = memnew(TileSetAtlasSource); - atlas_source->set_texture(texture); - - // Add a new source. - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Add atlas source")); - undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); - undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); - undo_redo->add_undo_method(*tile_set, "remove_source", source_id); - undo_redo->commit_action(); - - _update_sources_list(source_id); - tile_set_atlas_source_editor->init_source(); -} - void TileSetEditor::_source_selected(int p_source_index) { ERR_FAIL_COND(!tile_set.is_valid()); @@ -308,8 +295,8 @@ void TileSetEditor::_source_add_id_pressed(int p_id_pressed) { if (!texture_file_dialog) { texture_file_dialog = memnew(EditorFileDialog); add_child(texture_file_dialog); - texture_file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - texture_file_dialog->connect("file_selected", callable_mp(this, &TileSetEditor::_texture_file_selected)); + texture_file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES); + texture_file_dialog->connect("files_selected", callable_mp(this, &TileSetEditor::_load_texture_files)); List extensions; ResourceLoader::get_recognized_extensions_for_type("Texture2D", &extensions); diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index 86cd70d19ec4..755b940db2a0 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -68,6 +68,7 @@ class TileSetEditor : public Control { void _drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); bool _can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void _load_texture_files(const Vector &p_paths); void _update_sources_list(int force_selected_id = -1); @@ -78,7 +79,6 @@ class TileSetEditor : public Control { MenuButton *sources_advanced_menu_button = nullptr; ItemList *sources_list = nullptr; Ref missing_texture_texture; - void _texture_file_selected(const String &p_path); void _source_selected(int p_source_index); void _source_delete_pressed(); void _source_add_id_pressed(int p_id_pressed);