summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-04-04 14:31:16 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-04-04 14:31:16 +0200
commit1dacd6a5274f51592931743e87908366d4ec0432 (patch)
treef21051060e9e919b2eef88378d99b197f97b77f9 /editor
parentb5369ee3b35af45d6f7a4f50f902ff96563c7bcb (diff)
parent3cd4b2859c9d715459325b070643773b47472324 (diff)
downloadredot-engine-1dacd6a5274f51592931743e87908366d4ec0432.tar.gz
Merge pull request #89179 from groud/expose_tile_map_layer
Expose TileMapLayer
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_node.cpp4
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/icons/TileMapLayer.svg2
-rw-r--r--editor/plugins/tiles/tile_map_layer_editor.cpp586
-rw-r--r--editor/plugins/tiles/tile_map_layer_editor.h32
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp98
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h4
7 files changed, 484 insertions, 243 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 15409edf6e..5c1b14c203 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2506,8 +2506,8 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
editable_info,
info_is_warning);
- Object *editor_owner = is_node ? (Object *)SceneTreeDock::get_singleton() : is_resource ? (Object *)InspectorDock::get_inspector_singleton()
- : (Object *)this;
+ Object *editor_owner = (is_node || current_obj->is_class("MultiNodeEdit")) ? (Object *)SceneTreeDock::get_singleton() : is_resource ? (Object *)InspectorDock::get_inspector_singleton()
+ : (Object *)this;
// Take care of the main editor plugin.
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index ee33e171e3..89580b83b0 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -755,6 +755,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Tiles editor
_initial_set("editors/tiles_editor/display_grid", true);
+ _initial_set("editors/tiles_editor/highlight_selected_layer", true);
_initial_set("editors/tiles_editor/grid_color", Color(1.0, 0.5, 0.2, 0.5));
// Polygon editor
diff --git a/editor/icons/TileMapLayer.svg b/editor/icons/TileMapLayer.svg
index 1903a87e3b..90664dee03 100644
--- a/editor/icons/TileMapLayer.svg
+++ b/editor/icons/TileMapLayer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 7v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#8da5f3"/></svg> \ No newline at end of file
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 2 6.25 3.375 8 4.75l1.75-1.375zm2.624 2.062-1.75 1.375 1.75 1.375 1.75-1.375Zm2.626 2.063L11.5 7.5l1.75 1.375L15 7.5ZM5.376 4.062l-1.75 1.375 1.75 1.375 1.75-1.375zM8 6.124 6.25 7.499 8 8.874l1.75-1.375zm2.626 2.063-1.75 1.375 1.75 1.375 1.75-1.375ZM2.75 6.125 1 7.5l1.75 1.375L4.5 7.5Zm2.624 2.062-1.75 1.375 1.75 1.375 1.75-1.375ZM8 10.25l-1.75 1.375L8 13l1.75-1.375z" fill="#8da5f3"/></svg> \ No newline at end of file
diff --git a/editor/plugins/tiles/tile_map_layer_editor.cpp b/editor/plugins/tiles/tile_map_layer_editor.cpp
index ccadc0643b..ac4708aa06 100644
--- a/editor/plugins/tiles/tile_map_layer_editor.cpp
+++ b/editor/plugins/tiles/tile_map_layer_editor.cpp
@@ -36,9 +36,9 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
+#include "editor/multi_node_edit.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/themes/editor_scale.h"
-
#include "scene/2d/camera_2d.h"
#include "scene/2d/tile_map_layer.h"
#include "scene/gui/center_container.h"
@@ -107,7 +107,7 @@ void TileMapLayerEditorTilesPlugin::_update_transform_buttons() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null() || selection_pattern.is_null()) {
return;
}
@@ -171,7 +171,7 @@ void TileMapLayerEditorTilesPlugin::_update_tile_set_sources_list() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -256,7 +256,7 @@ void TileMapLayerEditorTilesPlugin::_update_source_display() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -302,7 +302,7 @@ void TileMapLayerEditorTilesPlugin::_patterns_item_list_gui_input(const Ref<Inpu
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -348,7 +348,7 @@ void TileMapLayerEditorTilesPlugin::_update_patterns_list() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -380,7 +380,7 @@ void TileMapLayerEditorTilesPlugin::_update_atlas_view() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -401,7 +401,7 @@ void TileMapLayerEditorTilesPlugin::_update_scenes_collection_view() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -459,7 +459,7 @@ void TileMapLayerEditorTilesPlugin::_scenes_list_multi_selected(int p_index, boo
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -538,7 +538,7 @@ bool TileMapLayerEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEven
return false;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return false;
}
@@ -784,7 +784,7 @@ void TileMapLayerEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1021,7 +1021,7 @@ TileMapCell TileMapLayerEditorTilesPlugin::_pick_random_tile(Ref<TileMapPattern>
return TileMapCell();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return TileMapCell();
}
@@ -1073,7 +1073,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_line(Vector2
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -1122,7 +1122,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_rect(Vector2
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -1181,7 +1181,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_bucket_fill(
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -1293,7 +1293,7 @@ void TileMapLayerEditorTilesPlugin::_stop_dragging() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1601,7 +1601,7 @@ void TileMapLayerEditorTilesPlugin::_update_fix_selected_and_hovered() {
selection_pattern.instantiate();
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
hovered_tile.source_id = TileSet::INVALID_SOURCE;
hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
@@ -1688,7 +1688,7 @@ void TileMapLayerEditorTilesPlugin::_update_selection_pattern_from_tilemap_selec
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1709,7 +1709,7 @@ void TileMapLayerEditorTilesPlugin::_update_selection_pattern_from_tileset_tiles
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1783,7 +1783,7 @@ void TileMapLayerEditorTilesPlugin::_update_selection_pattern_from_tileset_patte
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1822,7 +1822,7 @@ void TileMapLayerEditorTilesPlugin::_tile_atlas_control_draw() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -1901,7 +1901,7 @@ void TileMapLayerEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<Inpu
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -2007,7 +2007,7 @@ void TileMapLayerEditorTilesPlugin::_tile_alternatives_control_draw() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -2059,7 +2059,7 @@ void TileMapLayerEditorTilesPlugin::_tile_alternatives_control_gui_input(const R
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -2157,16 +2157,21 @@ void TileMapLayerEditorTilesPlugin::edit(ObjectID p_tile_map_layer_id) {
// Disable sort button if the tileset is read-only
TileMapLayer *edited_layer = _get_edited_layer();
+ Ref<TileSet> tile_set;
if (edited_layer) {
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ tile_set = edited_layer->get_tile_set();
if (tile_set.is_valid()) {
source_sort_button->set_disabled(EditorNode::get_singleton()->is_resource_read_only(tile_set));
}
}
- if (edited_tile_map_layer_id != p_tile_map_layer_id) {
- edited_tile_map_layer_id = p_tile_map_layer_id;
+ TileMapLayer *new_tile_map_layer = Object::cast_to<TileMapLayer>(ObjectDB::get_instance(edited_tile_map_layer_id));
+ Ref<TileSet> new_tile_set;
+ if (new_tile_map_layer) {
+ new_tile_set = new_tile_map_layer->get_tile_set();
+ }
+ if (tile_set.is_valid() && tile_set != new_tile_set) {
// Clear the selection.
tile_set_selection.clear();
patterns_item_list->deselect_all();
@@ -2531,7 +2536,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -2583,7 +2588,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -2630,7 +2635,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_line(Vect
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -2654,7 +2659,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_rect(Vect
return HashMap<Vector2i, TileMapCell>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -2688,7 +2693,7 @@ RBSet<Vector2i> TileMapLayerEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vec
return RBSet<Vector2i>();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return RBSet<Vector2i>();
}
@@ -2799,7 +2804,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_bucket_fi
return HashMap<Vector2i, TileMapCell>();
}
- const Ref<TileSet> &tile_set = edited_layer->get_effective_tile_set();
+ const Ref<TileSet> &tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return HashMap<Vector2i, TileMapCell>();
}
@@ -2827,7 +2832,7 @@ void TileMapLayerEditorTerrainsPlugin::_stop_dragging() {
return;
}
- const Ref<TileSet> &tile_set = edited_layer->get_effective_tile_set();
+ const Ref<TileSet> &tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -2961,7 +2966,7 @@ void TileMapLayerEditorTerrainsPlugin::_update_selection() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3013,7 +3018,7 @@ bool TileMapLayerEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputE
return false;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return false;
}
@@ -3150,7 +3155,7 @@ void TileMapLayerEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3275,7 +3280,7 @@ void TileMapLayerEditorTerrainsPlugin::_update_terrains_cache() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3342,7 +3347,7 @@ void TileMapLayerEditorTerrainsPlugin::_update_terrains_tree() {
const TileMapLayer *edited_layer = _get_edited_layer();
ERR_FAIL_NULL(edited_layer);
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3389,7 +3394,7 @@ void TileMapLayerEditorTerrainsPlugin::_update_tiles_list() {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3627,57 +3632,258 @@ TileMapLayer *TileMapLayerEditor::_get_edited_layer() const {
return Object::cast_to<TileMapLayer>(ObjectDB::get_instance(edited_tile_map_layer_id));
}
+void TileMapLayerEditor::_find_tile_map_layers_in_scene(Node *p_current, const Node *p_owner, Vector<TileMapLayer *> &r_list) const {
+ ERR_FAIL_COND(!p_current || !p_owner);
+ if (p_current != p_owner && p_current->get_owner() != p_owner) {
+ return;
+ }
+ TileMapLayer *layer = Object::cast_to<TileMapLayer>(p_current);
+ if (layer) {
+ r_list.append(layer);
+ }
+ for (int i = 0; i < p_current->get_child_count(); i++) {
+ Node *child = p_current->get_child(i);
+ _find_tile_map_layers_in_scene(child, p_owner, r_list);
+ }
+}
+
+void TileMapLayerEditor::_update_tile_map_layers_in_scene_list_cache() {
+ if (!layers_in_scene_list_cache_needs_update) {
+ return;
+ }
+ EditorNode *en = EditorNode::get_singleton();
+ Node *edited_scene_root = en->get_edited_scene();
+ if (!edited_scene_root) {
+ return;
+ }
+
+ tile_map_layers_in_scene_cache.clear();
+ _find_tile_map_layers_in_scene(edited_scene_root, edited_scene_root, tile_map_layers_in_scene_cache);
+ layers_in_scene_list_cache_needs_update = false;
+}
+
+void TileMapLayerEditor::_node_change(Node *p_node) {
+ if (!layers_in_scene_list_cache_needs_update && p_node->is_part_of_edited_scene() && Object::cast_to<TileMapLayer>(p_node)) {
+ layers_in_scene_list_cache_needs_update = true;
+ }
+}
+
void TileMapLayerEditor::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_READY: {
+ get_tree()->connect("node_added", callable_mp(this, &TileMapLayerEditor::_node_change));
+ get_tree()->connect("node_removed", callable_mp(this, &TileMapLayerEditor::_node_change));
+ } break;
case NOTIFICATION_THEME_CHANGED: {
missing_tile_texture = get_editor_theme_icon(SNAME("StatusWarning"));
warning_pattern_texture = get_editor_theme_icon(SNAME("WarningPattern"));
advanced_menu_button->set_icon(get_editor_theme_icon(SNAME("Tools")));
+ select_previous_layer->set_icon(get_editor_theme_icon(SNAME("MoveUp")));
+ select_next_layer->set_icon(get_editor_theme_icon(SNAME("MoveDown")));
+ select_all_layers->set_icon(get_editor_theme_icon(SNAME("FileList")));
toggle_grid_button->set_icon(get_editor_theme_icon(SNAME("Grid")));
- toggle_grid_button->set_pressed(EDITOR_GET("editors/tiles_editor/display_grid"));
toggle_highlight_selected_layer_button->set_icon(get_editor_theme_icon(SNAME("TileMapHighlightSelected")));
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (is_visible_in_tree() && tileset_changed_needs_update) {
+ if (is_visible_in_tree() && tile_map_layer_changed_needs_update) {
_update_bottom_panel();
- update_layers_selector();
- _update_highlighting_toggle();
+ _update_layers_selector();
tabs_plugins[tabs_bar->get_current_tab()]->tile_set_changed();
CanvasItemEditor::get_singleton()->update_viewport();
- tileset_changed_needs_update = false;
+ tile_map_layer_changed_needs_update = false;
}
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (EditorSettings::get_singleton()->check_changed_settings_in_group("editors/tiles_editor")) {
toggle_grid_button->set_pressed_no_signal(EDITOR_GET("editors/tiles_editor/display_grid"));
+ toggle_highlight_selected_layer_button->set_pressed_no_signal(EDITOR_GET("editors/tiles_editor/highlight_selected_layer"));
}
} break;
}
}
-void TileMapLayerEditor::_bind_methods() {
- ADD_SIGNAL(MethodInfo("change_selected_layer_request", PropertyInfo(Variant::STRING_NAME, "layer_name")));
-}
-
void TileMapLayerEditor::_on_grid_toggled(bool p_pressed) {
EditorSettings::get_singleton()->set("editors/tiles_editor/display_grid", p_pressed);
CanvasItemEditor::get_singleton()->update_viewport();
}
-void TileMapLayerEditor::_layers_selection_item_selected(int p_index) {
- emit_signal("change_selected_layer_request", layers_selection_button->get_item_metadata(p_index));
+void TileMapLayerEditor::_select_previous_layer_pressed() {
+ _layers_select_next_or_previous(false);
}
-void TileMapLayerEditor::_highlight_selected_layer_button_toggled(bool p_pressed) {
+void TileMapLayerEditor::_select_next_layer_pressed() {
+ _layers_select_next_or_previous(true);
+}
+
+void TileMapLayerEditor::_select_all_layers_pressed() {
+ EditorNode *en = EditorNode::get_singleton();
+ Node *edited_scene_root = en->get_edited_scene();
+ ERR_FAIL_NULL(edited_scene_root);
+
+ en->get_editor_selection()->clear();
+ if (tile_map_layers_in_scene_cache.size() == 1) {
+ en->edit_node(tile_map_layers_in_scene_cache[0]);
+ en->get_editor_selection()->add_node(tile_map_layers_in_scene_cache[0]);
+ } else {
+ _update_tile_map_layers_in_scene_list_cache();
+ Ref<MultiNodeEdit> multi_node_edit = memnew(MultiNodeEdit);
+ for (TileMapLayer *layer : tile_map_layers_in_scene_cache) {
+ multi_node_edit->add_node(edited_scene_root->get_path_to(layer));
+ en->get_editor_selection()->add_node(layer);
+ }
+ en->push_item(multi_node_edit.ptr());
+ }
+}
+
+void TileMapLayerEditor::_layers_selection_item_selected(int p_index) {
TileMapLayer *edited_layer = _get_edited_layer();
ERR_FAIL_NULL(edited_layer);
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(edited_layer->get_parent());
- ERR_FAIL_NULL(tile_map_layer_group);
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ ERR_FAIL_NULL(tile_map);
+
+ TileMapLayer *new_edited = Object::cast_to<TileMapLayer>(tile_map->get_child(p_index));
+ edit(new_edited);
+}
+
+void TileMapLayerEditor::_update_layers_selector() {
+ const TileMapLayer *edited_layer = _get_edited_layer();
+
+ // Update the selector.
+ layers_selection_button->clear();
+ layers_selection_button->hide();
+ select_all_layers->show();
+ select_next_layer->set_disabled(false);
+ select_previous_layer->set_disabled(false);
+ advanced_menu_button->get_popup()->set_item_disabled(ADVANCED_MENU_EXTRACT_TILE_MAP_LAYERS, true);
+ if (edited_layer) {
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ if (tile_map && edited_layer->get_index_in_tile_map() >= 0) {
+ // Build the list of layers.
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ const TileMapLayer *layer = Object::cast_to<TileMapLayer>(tile_map->get_child(i));
+ if (layer) {
+ int index = layers_selection_button->get_item_count();
+ layers_selection_button->add_item(layer->get_name());
+ layers_selection_button->set_item_metadata(index, layer->get_name());
+ if (edited_layer == layer) {
+ layers_selection_button->select(index);
+ }
+ }
+ }
+
+ // Disable selector if there's no layer to select.
+ layers_selection_button->set_disabled(false);
+ if (layers_selection_button->get_item_count() == 0) {
+ layers_selection_button->set_disabled(true);
+ layers_selection_button->set_text(TTR("No Layers"));
+ }
+
+ // Disable next/previous if there's one or less layers.
+ if (layers_selection_button->get_item_count() <= 1) {
+ select_next_layer->set_disabled(true);
+ select_previous_layer->set_disabled(true);
+ }
+ layers_selection_button->show();
+ select_all_layers->hide();
+
+ // Enable the "extract as TileMapLayer" option only if we are editing a TleMap.
+ advanced_menu_button->get_popup()->set_item_disabled(ADVANCED_MENU_EXTRACT_TILE_MAP_LAYERS, false);
+ }
+ } else {
+ select_all_layers->hide();
+ select_next_layer->set_disabled(true);
+ select_previous_layer->set_disabled(true);
+ }
+}
+
+void TileMapLayerEditor::_clear_all_layers_highlighting() {
+ // Note: This function might be removed if we remove the TileMap node at some point.
+ // All processing could be done in _update_all_layers_highlighting otherwise.
+ TileMapLayer *edited_layer = _get_edited_layer();
+
+ // Use default mode.
+ if (edited_layer && edited_layer->get_index_in_tile_map() >= 0) {
+ // For the TileMap node.
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ if (tile_map) {
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ TileMapLayer *layer = Object::cast_to<TileMapLayer>(tile_map->get_child(i));
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_DEFAULT);
+ }
+ }
+ } else {
+ // For other TileMapLayer nodes.
+ _update_tile_map_layers_in_scene_list_cache();
+ for (TileMapLayer *layer : tile_map_layers_in_scene_cache) {
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_DEFAULT);
+ }
+ }
+}
+
+void TileMapLayerEditor::_update_all_layers_highlighting() {
+ EditorNode *en = EditorNode::get_singleton();
+ Node *edited_scene_root = en->get_edited_scene();
+ if (!edited_scene_root) {
+ return;
+ }
+
+ // Get selected layer.
+ TileMapLayer *edited_layer = _get_edited_layer();
+
+ bool highlight_selected_layer = EDITOR_GET("editors/tiles_editor/highlight_selected_layer");
+ if (edited_layer && highlight_selected_layer) {
+ int edited_z_index = edited_layer->get_z_index();
+
+ if (edited_layer->get_index_in_tile_map() >= 0) {
+ // For the TileMap node.
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ ERR_FAIL_NULL(tile_map);
+
+ bool passed = false;
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ TileMapLayer *layer = Object::cast_to<TileMapLayer>(tile_map->get_child(i));
+ if (layer == edited_layer) {
+ passed = true;
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_DEFAULT);
+ } else {
+ if (passed || layer->get_z_index() > edited_z_index) {
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_ABOVE);
+ } else {
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_BELOW);
+ }
+ }
+ }
+ } else {
+ // Update highlight mode for independent layers.
+ _update_tile_map_layers_in_scene_list_cache();
+ bool passed = false;
+ for (TileMapLayer *layer : tile_map_layers_in_scene_cache) {
+ if (layer == edited_layer) {
+ passed = true;
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_DEFAULT);
+ } else {
+ if (passed || layer->get_z_index() > edited_z_index) {
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_ABOVE);
+ } else {
+ layer->set_highlight_mode(TileMapLayer::HIGHLIGHT_MODE_BELOW);
+ }
+ }
+ }
+ }
+ }
+}
+
+void TileMapLayerEditor::_highlight_selected_layer_button_toggled(bool p_pressed) {
+ TileMapLayer *edited_layer = _get_edited_layer();
+ if (!edited_layer) {
+ return;
+ }
- tile_map_layer_group->set_highlight_selected_layer(p_pressed);
+ EditorSettings::get_singleton()->set("editors/tiles_editor/highlight_selected_layer", p_pressed);
+ _update_all_layers_highlighting();
}
void TileMapLayerEditor::_advanced_menu_button_id_pressed(int p_id) {
@@ -3686,12 +3892,12 @@ void TileMapLayerEditor::_advanced_menu_button_id_pressed(int p_id) {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
- if (p_id == 0) { // Replace Tile Proxies
+ if (p_id == ADVANCED_MENU_REPLACE_WITH_PROXIES) { // Replace Tile Proxies
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Replace Tiles with Proxies"));
TypedArray<Vector2i> used_cells = edited_layer->get_used_cells();
@@ -3710,31 +3916,74 @@ void TileMapLayerEditor::_advanced_menu_button_id_pressed(int p_id) {
}
undo_redo->commit_action();
+ } else if (p_id == ADVANCED_MENU_EXTRACT_TILE_MAP_LAYERS) { // Transform internal TileMap layers into TileMapLayers.
+ ERR_FAIL_COND(edited_layer->get_index_in_tile_map() < 0);
+
+ EditorNode *en = EditorNode::get_singleton();
+ Node *edited_scene_root = en->get_edited_scene();
+ ERR_FAIL_NULL(edited_scene_root);
+
+ EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+ undo_redo->create_action(TTR("Extract TileMap layers as individual TileMapLayer nodes"));
+
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ undo_redo->add_do_method(tile_map, "remove_layer", 0);
+ }
+
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ TileMapLayer *new_layer = tile_map->duplicate_layer_from_internal(i);
+ undo_redo->add_do_method(tile_map, "add_child", new_layer);
+ undo_redo->add_do_method(new_layer, "set_owner", edited_scene_root);
+ undo_redo->add_do_property(new_layer, "tile_set", tile_map->get_tileset()); // Workaround for a bug: #89947.
+ undo_redo->add_undo_method(tile_map, "remove_child", new_layer);
+ undo_redo->add_do_reference(new_layer);
+ }
+
+ List<PropertyInfo> prop_list;
+ tile_map->get_property_list(&prop_list);
+ for (PropertyInfo &prop : prop_list) {
+ undo_redo->add_undo_property(tile_map, prop.name, tile_map->get(prop.name));
+ }
+ undo_redo->commit_action();
}
}
void TileMapLayerEditor::_update_bottom_panel() {
const TileMapLayer *edited_layer = _get_edited_layer();
- if (!edited_layer) {
- return;
+ Ref<TileSet> tile_set;
+ if (edited_layer) {
+ tile_set = edited_layer->get_tile_set();
+ }
+
+ // Update state labels.
+ if (is_multi_node_edit) {
+ cant_edit_label->set_text(TTR("Can't edit multiple layers at once."));
+ cant_edit_label->show();
+ } else if (!edited_layer) {
+ cant_edit_label->set_text(TTR("The selected TileMap has no layer to edit."));
+ cant_edit_label->show();
+ } else if (!edited_layer->is_enabled() || !edited_layer->is_visible_in_tree()) {
+ cant_edit_label->set_text(TTR("The edited layer is disabled or invisible"));
+ cant_edit_label->show();
+ } else if (tile_set.is_null()) {
+ cant_edit_label->set_text(TTR("The edited TileMap or TileMapLayer node has no TileSet resource.\nCreate or load a TileSet resource in the Tile Set property in the inspector."));
+ cant_edit_label->show();
+ } else {
+ cant_edit_label->hide();
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
-
- // Update the visibility of controls.
- missing_tileset_label->set_visible(tile_set.is_null());
+ // Update tabs visibility.
for (TileMapLayerSubEditorPlugin::TabData &tab_data : tabs_data) {
tab_data.panel->hide();
}
- if (tile_set.is_valid()) {
- tabs_data[tabs_bar->get_current_tab()].panel->show();
- }
+ tabs_data[tabs_bar->get_current_tab()].panel->set_visible(!cant_edit_label->is_visible());
}
Vector<Vector2i> TileMapLayerEditor::get_line(const TileMapLayer *p_tile_map_layer, Vector2i p_from_cell, Vector2i p_to_cell) {
ERR_FAIL_NULL_V(p_tile_map_layer, Vector<Vector2i>());
- Ref<TileSet> tile_set = p_tile_map_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = p_tile_map_layer->get_tile_set();
ERR_FAIL_COND_V(tile_set.is_null(), Vector<Vector2i>());
if (tile_set->get_tile_shape() == TileSet::TILE_SHAPE_SQUARE) {
@@ -3805,7 +4054,7 @@ Vector<Vector2i> TileMapLayerEditor::get_line(const TileMapLayer *p_tile_map_lay
}
void TileMapLayerEditor::_tile_map_layer_changed() {
- tileset_changed_needs_update = true;
+ tile_map_layer_changed_needs_update = true;
}
void TileMapLayerEditor::_tab_changed(int p_tab_id) {
@@ -3825,7 +4074,7 @@ void TileMapLayerEditor::_tab_changed(int p_tab_id) {
TileMapLayer *tile_map_layer = _get_edited_layer();
if (tile_map_layer) {
- if (tile_map_layer->get_effective_tile_set().is_valid()) {
+ if (tile_map_layer->get_tile_set().is_valid()) {
tabs_data[tabs_bar->get_current_tab()].panel->show();
}
}
@@ -3841,36 +4090,38 @@ void TileMapLayerEditor::_layers_select_next_or_previous(bool p_next) {
return;
}
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(edited_layer->get_parent());
- if (!tile_map_layer_group) {
- return;
- }
+ EditorNode *en = EditorNode::get_singleton();
+ Node *edited_scene_root = en->get_edited_scene();
+ ERR_FAIL_NULL(edited_scene_root);
+ TileMapLayer *new_selected_layer = nullptr;
int inc = p_next ? 1 : -1;
- int index = Math::posmod(edited_layer->get_index() + inc, tile_map_layer_group->get_child_count());
- const TileMapLayer *new_selected_layer = Object::cast_to<TileMapLayer>(tile_map_layer_group->get_child(index));
- while (new_selected_layer != edited_layer) {
- if (new_selected_layer && new_selected_layer->is_enabled()) {
- break;
+ if (edited_layer->get_index_in_tile_map() >= 0) {
+ // Part of a TileMap.
+ TileMap *tile_map = Object::cast_to<TileMap>(edited_layer->get_parent());
+ new_selected_layer = Object::cast_to<TileMapLayer>(tile_map->get_child(Math::posmod(edited_layer->get_index_in_tile_map() + inc, tile_map->get_layers_count())));
+ } else {
+ // Individual layer.
+ _update_tile_map_layers_in_scene_list_cache();
+ int edited_index = -1;
+ for (int i = 0; i < tile_map_layers_in_scene_cache.size(); i++) {
+ if (tile_map_layers_in_scene_cache[i] == edited_layer) {
+ edited_index = i;
+ break;
+ }
}
- index = Math::posmod((index + inc), tile_map_layer_group->get_child_count());
- new_selected_layer = Object::cast_to<TileMapLayer>(tile_map_layer_group->get_child(index));
+ new_selected_layer = tile_map_layers_in_scene_cache[Math::posmod(edited_index + inc, tile_map_layers_in_scene_cache.size())];
}
- if (new_selected_layer != edited_layer) {
- emit_signal("change_selected_layer_request", new_selected_layer->get_name());
- }
-}
+ ERR_FAIL_NULL(new_selected_layer);
-void TileMapLayerEditor::_update_highlighting_toggle() {
- const TileMapLayer *edited_layer = _get_edited_layer();
- if (!edited_layer) {
- return;
- }
-
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(edited_layer->get_parent());
- if (tile_map_layer_group) {
- toggle_highlight_selected_layer_button->set_pressed(tile_map_layer_group->is_highlighting_selected_layer());
+ if (edited_layer->get_index_in_tile_map() < 0) {
+ // Only if not part of a TileMap.
+ en->edit_node(new_selected_layer);
+ en->get_editor_selection()->clear();
+ en->get_editor_selection()->add_node(new_selected_layer);
+ } else {
+ edit(new_selected_layer);
}
}
@@ -3966,7 +4217,7 @@ void TileMapLayerEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
return;
}
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_null()) {
return;
}
@@ -3994,29 +4245,25 @@ void TileMapLayerEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
- // Generate a random color from the hashed values of the tiles.
- Array a = tile_set->map_tile_proxy(tile_source_id, tile_atlas_coords, tile_alternative_tile);
- if (int(a[0]) == tile_source_id && Vector2i(a[1]) == tile_atlas_coords && int(a[2]) == tile_alternative_tile) {
- // Only display the pattern if we have no proxy tile.
- Array to_hash;
- to_hash.push_back(tile_source_id);
- to_hash.push_back(tile_atlas_coords);
- to_hash.push_back(tile_alternative_tile);
- uint32_t hash = RandomPCG(to_hash.hash()).rand();
-
- Color color;
- color = color.from_hsv(
- (float)((hash >> 24) & 0xFF) / 256.0,
- Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
- Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
- 0.8);
-
- // Draw the scaled tile.
- Transform2D tile_xform;
- tile_xform.set_origin(tile_set->map_to_local(coords));
- tile_xform.set_scale(tile_shape_size);
- tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture);
- }
+ // Generate a random color from the hashed identifier of the tiles.
+ Array to_hash;
+ to_hash.push_back(tile_source_id);
+ to_hash.push_back(tile_atlas_coords);
+ to_hash.push_back(tile_alternative_tile);
+ uint32_t hash = RandomPCG(to_hash.hash()).rand();
+
+ Color color;
+ color = color.from_hsv(
+ (float)((hash >> 24) & 0xFF) / 256.0,
+ Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
+ Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
+ 0.8);
+
+ // Display the warning pattern.
+ Transform2D tile_xform;
+ tile_xform.set_origin(tile_set->map_to_local(coords));
+ tile_xform.set_scale(tile_shape_size);
+ tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture);
// Draw the warning icon.
Vector2::Axis min_axis = missing_tile_texture->get_size().min_axis_index();
@@ -4092,75 +4339,50 @@ void TileMapLayerEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
tabs_plugins[tabs_bar->get_current_tab()]->forward_canvas_draw_over_viewport(p_overlay);
}
-void TileMapLayerEditor::edit(TileMapLayer *p_tile_map_layer) {
- if (p_tile_map_layer && p_tile_map_layer->get_instance_id() == edited_tile_map_layer_id) {
+void TileMapLayerEditor::edit(Object *p_edited) {
+ if (p_edited && p_edited->get_instance_id() == edited_tile_map_layer_id) {
return;
}
+ _clear_all_layers_highlighting();
+
// Disconnect to changes.
TileMapLayer *tile_map_layer = _get_edited_layer();
if (tile_map_layer) {
tile_map_layer->disconnect("changed", callable_mp(this, &TileMapLayerEditor::_tile_map_layer_changed));
+ tile_map_layer->disconnect("visibility_changed", callable_mp(this, &TileMapLayerEditor::_tile_map_layer_changed));
}
// Update the edited layer.
- if (p_tile_map_layer) {
+ TileMapLayer *new_layer = Object::cast_to<TileMapLayer>(p_edited);
+ if (new_layer) {
// Change the edited object.
- edited_tile_map_layer_id = p_tile_map_layer->get_instance_id();
+ edited_tile_map_layer_id = new_layer->get_instance_id();
tile_map_layer = _get_edited_layer();
// Connect to changes.
if (!tile_map_layer->is_connected("changed", callable_mp(this, &TileMapLayerEditor::_tile_map_layer_changed))) {
tile_map_layer->connect("changed", callable_mp(this, &TileMapLayerEditor::_tile_map_layer_changed));
+ tile_map_layer->connect("visibility_changed", callable_mp(this, &TileMapLayerEditor::_tile_map_layer_changed));
}
} else {
edited_tile_map_layer_id = ObjectID();
}
- update_layers_selector();
- _update_highlighting_toggle();
+ // Check if we are trying to use a MultiNodeEdit.
+ is_multi_node_edit = Object::cast_to<MultiNodeEdit>(p_edited);
- // Call the plugins.
+ // Call the plugins and update everything.
tabs_plugins[tabs_bar->get_current_tab()]->edit(edited_tile_map_layer_id);
+ _update_layers_selector();
+ _update_all_layers_highlighting();
_tile_map_layer_changed();
}
-void TileMapLayerEditor::update_layers_selector() {
- const TileMapLayer *edited_layer = _get_edited_layer();
- if (!edited_layer) {
- return;
- }
-
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(edited_layer->get_parent());
- if (tile_map_layer_group) {
- // Update the selector
- layers_selection_button->show();
- layers_selection_button->clear();
-
- // Build the list of layers.
- for (int i = 0; i < tile_map_layer_group->get_child_count(); i++) {
- const TileMapLayer *layer = Object::cast_to<TileMapLayer>(tile_map_layer_group->get_child(i));
- if (layer) {
- int index = layers_selection_button->get_item_count();
- layers_selection_button->add_item(layer->get_name());
- layers_selection_button->set_item_disabled(index, !layer->is_enabled());
- layers_selection_button->set_item_metadata(index, layer->get_name());
- if (edited_layer == layer) {
- layers_selection_button->select(index);
- }
- }
- }
-
- // Disable the button if there's no layer to select.
- layers_selection_button->set_disabled(false);
- if (layers_selection_button->get_item_count() == 0) {
- layers_selection_button->set_disabled(true);
- layers_selection_button->set_text(TTR("No Layers"));
- }
- } else {
- layers_selection_button->hide();
- }
+void TileMapLayerEditor::set_show_layer_selector(bool p_show_layer_selector) {
+ show_layers_selector = p_show_layer_selector;
+ _update_layers_selector();
}
TileMapLayerEditor::TileMapLayerEditor() {
@@ -4210,13 +4432,36 @@ TileMapLayerEditor::TileMapLayerEditor() {
tile_map_toolbar->add_child(c);
// Layer selector.
+ layer_selection_hbox = memnew(HBoxContainer);
+ tile_map_toolbar->add_child(layer_selection_hbox);
+
layers_selection_button = memnew(OptionButton);
layers_selection_button->set_custom_minimum_size(Size2(200, 0));
layers_selection_button->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
layers_selection_button->set_tooltip_text(TTR("TileMap Layers"));
layers_selection_button->connect("item_selected", callable_mp(this, &TileMapLayerEditor::_layers_selection_item_selected));
- tile_map_toolbar->add_child(layers_selection_button);
-
+ layer_selection_hbox->add_child(layers_selection_button);
+
+ select_previous_layer = memnew(Button);
+ select_previous_layer->set_theme_type_variation("FlatButton");
+ select_previous_layer->set_tooltip_text(TTR("Select previous layer"));
+ select_previous_layer->connect("pressed", callable_mp(this, &TileMapLayerEditor::_select_previous_layer_pressed));
+ layer_selection_hbox->add_child(select_previous_layer);
+
+ select_next_layer = memnew(Button);
+ select_next_layer->set_theme_type_variation("FlatButton");
+ select_next_layer->set_tooltip_text(TTR("Select next layer"));
+ select_next_layer->connect("pressed", callable_mp(this, &TileMapLayerEditor::_select_next_layer_pressed));
+ layer_selection_hbox->add_child(select_next_layer);
+
+ select_all_layers = memnew(Button);
+ select_all_layers->set_theme_type_variation("FlatButton");
+ select_all_layers->set_text(TTR("Select all layers"));
+ select_all_layers->connect("pressed", callable_mp(this, &TileMapLayerEditor::_select_all_layers_pressed));
+ select_all_layers->set_tooltip_text(TTR("Select all TileMapLayers in scene"));
+ layer_selection_hbox->add_child(select_all_layers);
+
+ // Highlighting selected layer.
toggle_highlight_selected_layer_button = memnew(Button);
toggle_highlight_selected_layer_button->set_theme_type_variation("FlatButton");
toggle_highlight_selected_layer_button->set_toggle_mode(true);
@@ -4239,18 +4484,19 @@ TileMapLayerEditor::TileMapLayerEditor() {
advanced_menu_button = memnew(MenuButton);
advanced_menu_button->set_flat(false);
advanced_menu_button->set_theme_type_variation("FlatButton");
- advanced_menu_button->get_popup()->add_item(TTR("Automatically Replace Tiles with Proxies"));
+ advanced_menu_button->get_popup()->add_item(TTR("Automatically Replace Tiles with Proxies"), ADVANCED_MENU_REPLACE_WITH_PROXIES);
+ advanced_menu_button->get_popup()->add_item(TTR("Extract TileMap layers as individual TileMapLayer nodes"), ADVANCED_MENU_EXTRACT_TILE_MAP_LAYERS);
advanced_menu_button->get_popup()->connect("id_pressed", callable_mp(this, &TileMapLayerEditor::_advanced_menu_button_id_pressed));
tile_map_toolbar->add_child(advanced_menu_button);
- missing_tileset_label = memnew(Label);
- missing_tileset_label->set_text(TTR("The edited TileMap node has no TileSet resource.\nCreate or load a TileSet resource in the Tile Set property in the inspector."));
- missing_tileset_label->set_h_size_flags(SIZE_EXPAND_FILL);
- missing_tileset_label->set_v_size_flags(SIZE_EXPAND_FILL);
- missing_tileset_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
- missing_tileset_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
- missing_tileset_label->hide();
- add_child(missing_tileset_label);
+ // A label for editing errors.
+ cant_edit_label = memnew(Label);
+ cant_edit_label->set_h_size_flags(SIZE_EXPAND_FILL);
+ cant_edit_label->set_v_size_flags(SIZE_EXPAND_FILL);
+ cant_edit_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ cant_edit_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
+ cant_edit_label->hide();
+ add_child(cant_edit_label);
for (unsigned int tab_index = 0; tab_index < tabs_data.size(); tab_index++) {
add_child(tabs_data[tab_index].panel);
diff --git a/editor/plugins/tiles/tile_map_layer_editor.h b/editor/plugins/tiles/tile_map_layer_editor.h
index a7fea2abcf..2603261449 100644
--- a/editor/plugins/tiles/tile_map_layer_editor.h
+++ b/editor/plugins/tiles/tile_map_layer_editor.h
@@ -339,10 +339,16 @@ class TileMapLayerEditor : public VBoxContainer {
GDCLASS(TileMapLayerEditor, VBoxContainer);
private:
- bool tileset_changed_needs_update = false;
+ bool tile_map_layer_changed_needs_update = false;
ObjectID edited_tile_map_layer_id;
+ bool is_multi_node_edit = false;
+ Vector<TileMapLayer *> tile_map_layers_in_scene_cache;
+ bool layers_in_scene_list_cache_needs_update = false;
TileMapLayer *_get_edited_layer() const;
+ void _find_tile_map_layers_in_scene(Node *p_current, const Node *p_owner, Vector<TileMapLayer *> &r_list) const;
+ void _update_tile_map_layers_in_scene_list_cache();
+ void _node_change(Node *p_node);
// Vector to keep plugins.
Vector<TileMapLayerSubEditorPlugin *> tile_map_editor_plugins;
@@ -350,20 +356,36 @@ private:
// Toolbar.
HFlowContainer *tile_map_toolbar = nullptr;
+ bool show_layers_selector = false;
+
+ HBoxContainer *layer_selection_hbox = nullptr;
+ Button *select_previous_layer = nullptr;
+ void _select_previous_layer_pressed();
+ Button *select_next_layer = nullptr;
+ void _select_next_layer_pressed();
+ Button *select_all_layers = nullptr;
+ void _select_all_layers_pressed();
OptionButton *layers_selection_button = nullptr;
void _layers_selection_item_selected(int p_index);
+ void _update_layers_selector();
Button *toggle_highlight_selected_layer_button = nullptr;
+ void _clear_all_layers_highlighting();
+ void _update_all_layers_highlighting();
void _highlight_selected_layer_button_toggled(bool p_pressed);
Button *toggle_grid_button = nullptr;
void _on_grid_toggled(bool p_pressed);
+ enum {
+ ADVANCED_MENU_REPLACE_WITH_PROXIES,
+ ADVANCED_MENU_EXTRACT_TILE_MAP_LAYERS,
+ };
MenuButton *advanced_menu_button = nullptr;
void _advanced_menu_button_id_pressed(int p_id);
// Bottom panel.
- Label *missing_tileset_label = nullptr;
+ Label *cant_edit_label = nullptr;
TabBar *tabs_bar = nullptr;
LocalVector<TileMapLayerSubEditorPlugin::TabData> tabs_data;
LocalVector<TileMapLayerSubEditorPlugin *> tabs_plugins;
@@ -379,22 +401,20 @@ private:
// Updates.
void _layers_select_next_or_previous(bool p_next);
- void _update_highlighting_toggle();
// Inspector undo/redo callback.
void _move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, const String &p_array_prefix, int p_from_index, int p_to_pos);
protected:
void _notification(int p_what);
- static void _bind_methods();
void _draw_shape(Control *p_control, Rect2 p_region, TileSet::TileShape p_shape, TileSet::TileOffsetAxis p_offset_axis, Color p_color);
public:
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
- void edit(TileMapLayer *p_tile_map_layer);
- void update_layers_selector();
+ void edit(Object *p_tile_map_layer);
+ void set_show_layer_selector(bool p_show_layer_selector);
TileMapLayerEditor();
~TileMapLayerEditor();
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index ed21a29487..c3141beb1a 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -40,6 +40,7 @@
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"
#include "editor/gui/editor_bottom_panel.h"
+#include "editor/multi_node_edit.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/themes/editor_scale.h"
#include "scene/2d/tile_map.h"
@@ -336,7 +337,7 @@ void TileMapEditorPlugin::_tile_map_layer_removed() {
void TileMapEditorPlugin::_update_tile_map() {
TileMapLayer *edited_layer = Object::cast_to<TileMapLayer>(ObjectDB::get_instance(tile_map_layer_id));
if (edited_layer) {
- Ref<TileSet> tile_set = edited_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = edited_layer->get_tile_set();
if (tile_set.is_valid() && tile_set_id != tile_set->get_instance_id()) {
tile_set_plugin_singleton->edit(tile_set.ptr());
tile_set_plugin_singleton->make_visible(true);
@@ -355,38 +356,25 @@ void TileMapEditorPlugin::_select_layer(const StringName &p_name) {
ERR_FAIL_NULL(edited_layer);
Node *parent = edited_layer->get_parent();
- ERR_FAIL_NULL(parent);
-
- TileMapLayer *new_layer = Object::cast_to<TileMapLayer>(parent->get_node_or_null(String(p_name)));
- edit(new_layer);
+ if (parent) {
+ TileMapLayer *new_layer = Object::cast_to<TileMapLayer>(parent->get_node_or_null(String(p_name)));
+ edit(new_layer);
+ }
}
-void TileMapEditorPlugin::_edit_tile_map_layer(TileMapLayer *p_tile_map_layer) {
+void TileMapEditorPlugin::_edit_tile_map_layer(TileMapLayer *p_tile_map_layer, bool p_show_layer_selector) {
ERR_FAIL_NULL(p_tile_map_layer);
editor->edit(p_tile_map_layer);
-
- // Update the selected layers in the TileMapLayerGroup parent node.
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(p_tile_map_layer->get_parent());
- if (tile_map_layer_group) {
- Vector<StringName> selected;
- selected.push_back(p_tile_map_layer->get_name());
- tile_map_layer_group->set_selected_layers(selected);
- }
+ editor->set_show_layer_selector(p_show_layer_selector);
// Update the object IDs.
tile_map_layer_id = p_tile_map_layer->get_instance_id();
p_tile_map_layer->connect("changed", callable_mp(this, &TileMapEditorPlugin::_tile_map_layer_changed));
p_tile_map_layer->connect("tree_exited", callable_mp(this, &TileMapEditorPlugin::_tile_map_layer_removed));
- if (tile_map_layer_group) {
- tile_map_group_id = tile_map_layer_group->get_instance_id();
- tile_map_layer_group->connect("child_entered_tree", callable_mp(editor, &TileMapLayerEditor::update_layers_selector).unbind(1));
- tile_map_layer_group->connect("child_exiting_tree", callable_mp(editor, &TileMapLayerEditor::update_layers_selector).unbind(1));
- tile_map_layer_group->connect("child_order_changed", callable_mp(editor, &TileMapLayerEditor::update_layers_selector));
- }
// Update the edited tileset.
- Ref<TileSet> tile_set = p_tile_map_layer->get_effective_tile_set();
+ Ref<TileSet> tile_set = p_tile_map_layer->get_tile_set();
if (tile_set.is_valid()) {
tile_set_plugin_singleton->edit(tile_set.ptr());
tile_set_plugin_singleton->make_visible(true);
@@ -397,30 +385,15 @@ void TileMapEditorPlugin::_edit_tile_map_layer(TileMapLayer *p_tile_map_layer) {
}
}
-void TileMapEditorPlugin::_edit_tile_map_layer_group(TileMapLayerGroup *p_tile_map_layer_group) {
- ERR_FAIL_NULL(p_tile_map_layer_group);
-
- Vector<StringName> selected_layers = p_tile_map_layer_group->get_selected_layers();
-
- TileMapLayer *selected_layer = nullptr;
- if (selected_layers.size() > 0) {
- // Edit the selected layer.
- selected_layer = Object::cast_to<TileMapLayer>(p_tile_map_layer_group->get_node_or_null(String(selected_layers[0])));
- }
- if (!selected_layer) {
- // Edit the first layer found.
- for (int i = 0; i < p_tile_map_layer_group->get_child_count(); i++) {
- selected_layer = Object::cast_to<TileMapLayer>(p_tile_map_layer_group->get_child(i));
- if (selected_layer) {
- break;
- }
- }
- }
+void TileMapEditorPlugin::_edit_tile_map(TileMap *p_tile_map) {
+ ERR_FAIL_NULL(p_tile_map);
- if (selected_layer) {
- _edit_tile_map_layer(selected_layer);
+ if (p_tile_map->get_layers_count() > 0) {
+ TileMapLayer *selected_layer = Object::cast_to<TileMapLayer>(p_tile_map->get_child(0));
+ _edit_tile_map_layer(selected_layer, true);
} else {
editor->edit(nullptr);
+ editor->set_show_layer_selector(false);
}
}
@@ -437,36 +410,38 @@ void TileMapEditorPlugin::edit(Object *p_object) {
edited_layer->disconnect("tree_exited", callable_mp(this, &TileMapEditorPlugin::_tile_map_layer_removed));
}
- TileMapLayerGroup *tile_map_group = Object::cast_to<TileMapLayerGroup>(ObjectDB::get_instance(tile_map_group_id));
- if (tile_map_group) {
- tile_map_group->disconnect("child_entered_tree", callable_mp(editor, &TileMapLayerEditor::update_layers_selector).unbind(1));
- tile_map_group->disconnect("child_exiting_tree", callable_mp(editor, &TileMapLayerEditor::update_layers_selector).unbind(1));
- tile_map_group->disconnect("child_order_changed", callable_mp(editor, &TileMapLayerEditor::update_layers_selector));
- }
-
tile_map_group_id = ObjectID();
tile_map_layer_id = ObjectID();
tile_set_id = ObjectID();
- TileMapLayerGroup *tile_map_layer_group = Object::cast_to<TileMap>(p_object);
+ TileMap *tile_map = Object::cast_to<TileMap>(p_object);
TileMapLayer *tile_map_layer = Object::cast_to<TileMapLayer>(p_object);
- if (tile_map_layer_group) {
- _edit_tile_map_layer_group(tile_map_layer_group);
+ MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(p_object);
+ if (tile_map) {
+ _edit_tile_map(tile_map);
} else if (tile_map_layer) {
- _edit_tile_map_layer(tile_map_layer);
+ _edit_tile_map_layer(tile_map_layer, false);
+ } else if (multi_node_edit) {
+ editor->edit(multi_node_edit);
} else {
- // Deselect the layer in the group.
- if (edited_layer) {
- tile_map_layer_group = Object::cast_to<TileMapLayerGroup>(edited_layer->get_parent());
- if (tile_map_layer_group) {
- tile_map_layer_group->set_selected_layers(Vector<StringName>());
- }
- }
+ editor->edit(nullptr);
}
}
bool TileMapEditorPlugin::handles(Object *p_object) const {
- return Object::cast_to<TileMapLayer>(p_object) != nullptr || Object::cast_to<TileMapLayerGroup>(p_object) != nullptr;
+ MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(p_object);
+ Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
+ if (multi_node_edit && edited_scene) {
+ bool only_tile_map_layers = true;
+ for (int i = 0; i < multi_node_edit->get_node_count(); i++) {
+ if (!Object::cast_to<TileMapLayer>(edited_scene->get_node(multi_node_edit->get_node(i)))) {
+ only_tile_map_layers = false;
+ break;
+ }
+ }
+ return only_tile_map_layers;
+ }
+ return Object::cast_to<TileMapLayer>(p_object) != nullptr || Object::cast_to<TileMap>(p_object) != nullptr;
}
void TileMapEditorPlugin::make_visible(bool p_visible) {
@@ -509,7 +484,6 @@ TileMapEditorPlugin::TileMapEditorPlugin() {
editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
- editor->connect("change_selected_layer_request", callable_mp(this, &TileMapEditorPlugin::_select_layer));
editor->hide();
button = EditorNode::get_bottom_panel()->add_item(TTR("TileMap"), editor, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_tile_map_bottom_panel", TTR("Toggle TileMap Bottom Panel")));
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index ac3e8986d6..23a6a52a5c 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -126,8 +126,8 @@ class TileMapEditorPlugin : public EditorPlugin {
void _update_tile_map();
void _select_layer(const StringName &p_name);
- void _edit_tile_map_layer(TileMapLayer *p_tile_map_layer);
- void _edit_tile_map_layer_group(TileMapLayerGroup *p_tile_map_layer_group);
+ void _edit_tile_map_layer(TileMapLayer *p_tile_map_layer, bool p_show_layer_selector);
+ void _edit_tile_map(TileMap *p_tile_map);
protected:
void _notification(int p_notification);