Repository: godotengine/godot (language: cpp)

Issue:
In tileset editor, attempting to paint terrain over alternative tile instead creates a new alternative tile
### Tested versions

- Reproducible for v4.3.stable.official [77dcf97d8]

### System information

Godot v4.3.stable - Windows 10.0.22631 - GLES3 (Compatibility) - AMD Radeon RX 6600M (Advanced Micro Devices, Inc.; 30.0.13024.5001) - AMD Ryzen 7 5800H with Radeon Graphics (16 Threads)

### Issue description

Attempting to paint terrain over an alternative tile instead results with the terrain editor creating a new alternative tile. Which shouldn't happen, as the alternative tile creation is done via "Select" tab of the tileset editor.

### Steps to reproduce

1. Load attached project
2. Open `player.tscn`
3. Open `TileMapLayer` node
4. Switch to tileset editing, `Paint` mode
5. Select property `Terrains` -> `Terrain Set 0` -> `Dots Biome`
6. Attempt to paint this point:
![Image](https://github.com/user-attachments/assets/814c2333-8a5a-4d8e-a20a-06daee32f4ef)
7. Be greeted with this sight:
![Image](https://github.com/user-attachments/assets/c6be7659-d9d3-43e8-8fd7-25ec609d998b)




### Minimal reproduction project (MRP)

[TerrainPainterBug.zip](https://github.com/user-attachments/files/17937477/TerrainPainterBug.zip)


Discussion / hints:
I tracked down the issue to the "create alternative tile" button that's appended to the end of the row.

Here in this pic, it's changed up to use grey background instead of transparent.

For some reason, the button is missing the icon, is sized incorrectly and overlaps nearby squares, intercepting terrain editor input.

![Image](https://github.com/user-attachments/assets/4216c202-1bfb-444b-815a-f2ca6947a227)

Fix patch:
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index ffb5bb5009db..80958b2043fb 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -971,40 +971,44 @@ void TileSetAtlasSourceEditor::_update_atlas_view() {
 		tile_create_help->set_visible(tools_button_group->get_pressed_button() == tool_setup_atlas_source_button);
 	}
 
-	Vector2i pos;
-	Vector2 texture_region_base_size = tile_set_atlas_source->get_texture_region_size();
-	int texture_region_base_size_min = MIN(texture_region_base_size.x, texture_region_base_size.y);
-	for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) {
-		Vector2i tile_id = tile_set_atlas_source->get_tile_id(i);
-		int alternative_count = tile_set_atlas_source->get_alternative_tiles_count(tile_id);
-		if (alternative_count > 1) {
-			// Compute the right extremity of alternative.
-			int y_increment = 0;
-			pos.x = 0;
-			for (int j = 1; j < alternative_count; j++) {
-				int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j);
-				Rect2i rect = tile_atlas_view->get_alternative_tile_rect(tile_id, alternative_id);
-				pos.x = MAX(pos.x, rect.get_end().x);
-				y_increment = MAX(y_increment, rect.size.y);
-			}
-
-			// Create and position the button.
-			Button *button = memnew(Button);
-			button->set_flat(true);
-			button->set_button_icon(get_editor_theme_icon(SNAME("Add")));
-			button->add_theme_style_override(CoreStringName(normal), memnew(StyleBoxEmpty));
-			button->add_theme_style_override(SceneStringName(hover), memnew(StyleBoxEmpty));
-			button->add_theme_style_override("focus", memnew(StyleBoxEmpty));
-			button->add_theme_style_override(SceneStringName(pressed), memnew(StyleBoxEmpty));
-			button->connect(SceneStringName(pressed), callable_mp(tile_set_atlas_source, &TileSetAtlasSource::create_alternative_tile).bind(tile_id, TileSetSource::INVALID_TILE_ALTERNATIVE));
-			button->set_rect(Rect2(Vector2(pos.x, pos.y + (y_increment - texture_region_base_size.y) / 2.0), Vector2(texture_region_base_size_min, texture_region_base_size_min)));
-			button->set_expand_icon(true);
-			alternative_tiles_control->add_child(button);
-
-			pos.y += y_increment;
-		}
-	}
-	tile_atlas_view->set_padding(Side::SIDE_RIGHT, texture_region_base_size_min);
+	if (tools_button_group->get_pressed_button() != tool_paint_button) {
+		Vector2i pos;
+		Vector2 texture_region_base_size = tile_set_atlas_source->get_texture_region_size();
+		int texture_region_base_size_min = MIN(texture_region_base_size.x, texture_region_base_size.y);
+		for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) {
+			Vector2i tile_id = tile_set_atlas_source->get_tile_id(i);
+			int alternative_count = tile_set_atlas_source->get_alternative_tiles_count(tile_id);
+			if (alternative_count > 1) {
+				// Compute the right extremity of alternative.
+				int y_increment = 0;
+				pos.x = 0;
+				for (int j = 1; j < alternative_count; j++) {
+					int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j);
+					Rect2i rect = tile_atlas_view->get_alternative_tile_rect(tile_id, alternative_id);
+					pos.x = MAX(pos.x, rect.get_end().x);
+					y_increment = MAX(y_increment, rect.size.y);
+				}
+
+				// Create and position the button.
+				Button *button = memnew(Button);
+				button->set_flat(true);
+				button->set_button_icon(get_editor_theme_icon(SNAME("Add")));
+				button->add_theme_style_override(CoreStringName(normal), memnew(StyleBoxEmpty));
+				button->add_theme_style_override(SceneStringName(hover), memnew(StyleBoxEmpty));
+				button->add_theme_style_override("focus", memnew(StyleBoxEmpty));
+				button->add_theme_style_override(SceneStringName(pressed), memnew(StyleBoxEmpty));
+				button->add_theme_constant_override("align_to_largest_stylebox", false);
+				button->set_mouse_filter(Control::MOUSE_FILTER_PASS);
+				button->connect(SceneStringName(pressed), callable_mp(this, &TileSetAtlasSourceEditor::_tile_alternatives_create_button_pressed).bind(tile_id));
+				button->set_rect(Rect2(Vector2(pos.x, pos.y + (y_increment - texture_region_base_size.y) / 2.0), Vector2(texture_region_base_size_min, texture_region_base_size_min)));
+				button->set_expand_icon(true);
+				alternative_tiles_control->add_child(button);
+
+				pos.y += y_increment;
+			}
+		}
+		tile_atlas_view->set_padding(Side::SIDE_RIGHT, texture_region_base_size_min);
+	}
 
 	// Redraw everything.
 	tile_atlas_control->queue_redraw();
@@ -2009,6 +2013,17 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() {
 	alternative_tiles_control_unscaled->queue_redraw();
 }
 
+void TileSetAtlasSourceEditor::_tile_alternatives_create_button_pressed(const Vector2i &p_atlas_coords) {
+	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+
+	// FIXME: Doesn't undo changes to `next_alternative_id` counter.
+	undo_redo->create_action(TTR("Create tile alternatives"));
+	int next_id = tile_set_atlas_source->get_next_alternative_tile_id(p_atlas_coords);
+	undo_redo->add_do_method(tile_set_atlas_source, "create_alternative_tile", p_atlas_coords, next_id);
+	undo_redo->add_undo_method(tile_set_atlas_source, "remove_alternative_tile", p_atlas_coords, next_id);
+	undo_redo->commit_action();
+}
+
 void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
 	// Update the hovered alternative tile.
 	if (tools_button_group->get_pressed_button() == tool_select_button) {
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h
index 12a02e6a3980..b729364d1559 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.h
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h
@@ -253,6 +253,7 @@ class TileSetAtlasSourceEditor : public HSplitContainer {
 	PopupMenu *alternative_tile_popup_menu = nullptr;
 	Control *alternative_tiles_control = nullptr;
 	Control *alternative_tiles_control_unscaled = nullptr;
+	void _tile_alternatives_create_button_pressed(const Vector2i &p_atlas_coords);
 	void _tile_alternatives_control_draw();
 	void _tile_alternatives_control_unscaled_draw();
 	void _tile_alternatives_control_mouse_exited();


Test patch: