Merge pull request #74717 from KoBeWi/tilesetmap_handler_plugin

Add separate editor plugin for TileMap and TileSet
This commit is contained in:
Yuri Sizov 2023-07-27 19:11:37 +02:00 committed by GitHub
commit 6c11fcd01a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 250 additions and 266 deletions

View File

@ -326,6 +326,7 @@
<param index="0" name="object" type="Object" /> <param index="0" name="object" type="Object" />
<description> <description>
Implement this function if your plugin edits a specific type of object (Resource or Node). If you return [code]true[/code], then you will get the functions [method _edit] and [method _make_visible] called when the editor requests them. If you have declared the methods [method _forward_canvas_gui_input] and [method _forward_3d_gui_input] these will be called too. Implement this function if your plugin edits a specific type of object (Resource or Node). If you return [code]true[/code], then you will get the functions [method _edit] and [method _make_visible] called when the editor requests them. If you have declared the methods [method _forward_canvas_gui_input] and [method _forward_3d_gui_input] these will be called too.
[b]Note:[/b] Each plugin should handle only one type of objects at a time. If a plugin handes more types of objects and they are edited at the same time, it will result in errors.
</description> </description>
</method> </method>
<method name="_has_main_screen" qualifiers="virtual const"> <method name="_has_main_screen" qualifiers="virtual const">

View File

@ -109,8 +109,8 @@ void TileMapEditorTilesPlugin::_update_toolbar() {
} }
} }
Vector<TileMapEditorPlugin::TabData> TileMapEditorTilesPlugin::get_tabs() const { Vector<TileMapSubEditorPlugin::TabData> TileMapEditorTilesPlugin::get_tabs() const {
Vector<TileMapEditorPlugin::TabData> tabs; Vector<TileMapSubEditorPlugin::TabData> tabs;
tabs.push_back({ toolbar, tiles_bottom_panel }); tabs.push_back({ toolbar, tiles_bottom_panel });
tabs.push_back({ toolbar, patterns_bottom_panel }); tabs.push_back({ toolbar, patterns_bottom_panel });
return tabs; return tabs;
@ -147,7 +147,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
old_source = -1; old_source = -1;
} }
List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set); List<int> source_ids = TilesEditorUtils::get_singleton()->get_sorted_sources(tile_set);
for (const int &source_id : source_ids) { for (const int &source_id : source_ids) {
TileSetSource *source = *tile_set->get_source(source_id); TileSetSource *source = *tile_set->get_source(source_id);
@ -209,7 +209,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
} }
// Synchronize the lists. // Synchronize the lists.
TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current()); TilesEditorUtils::get_singleton()->set_sources_lists_current(sources_list->get_current());
} }
void TileMapEditorTilesPlugin::_update_source_display() { void TileMapEditorTilesPlugin::_update_source_display() {
@ -322,7 +322,7 @@ void TileMapEditorTilesPlugin::_update_patterns_list() {
int id = patterns_item_list->add_item(""); int id = patterns_item_list->add_item("");
patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i)); patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i));
patterns_item_list->set_item_tooltip(id, vformat(TTR("Index: %d"), i)); patterns_item_list->set_item_tooltip(id, vformat(TTR("Index: %d"), i));
TilesEditorPlugin::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileMapEditorTilesPlugin::_pattern_preview_done)); TilesEditorUtils::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileMapEditorTilesPlugin::_pattern_preview_done));
} }
// Update the label visibility. // Update the label visibility.
@ -354,7 +354,7 @@ void TileMapEditorTilesPlugin::_update_atlas_view() {
ERR_FAIL_COND(!atlas_source); ERR_FAIL_COND(!atlas_source);
tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id); tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id);
TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); TilesEditorUtils::get_singleton()->synchronize_atlas_view(tile_atlas_view);
tile_atlas_control->queue_redraw(); tile_atlas_control->queue_redraw();
} }
@ -1386,7 +1386,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
for (int i = 0; i < sources_list->get_item_count(); i++) { for (int i = 0; i < sources_list->get_item_count(); i++) {
if (int(sources_list->get_item_metadata(i)) == picked_source) { if (int(sources_list->get_item_metadata(i)) == picked_source) {
sources_list->set_current(i); sources_list->set_current(i);
TilesEditorPlugin::get_singleton()->set_sources_lists_current(i); TilesEditorUtils::get_singleton()->set_sources_lists_current(i);
break; break;
} }
} }
@ -1720,7 +1720,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
if (frame > 0) { if (frame > 0) {
color.a *= 0.3; color.a *= 0.3;
} }
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E.get_atlas_coords(), frame), color); TilesEditorUtils::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E.get_atlas_coords(), frame), color);
} }
} }
} }
@ -1729,7 +1729,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) { if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) {
for (int frame = 0; frame < atlas->get_tile_animation_frames_count(hovered_tile.get_atlas_coords()); frame++) { for (int frame = 0; frame < atlas->get_tile_animation_frames_count(hovered_tile.get_atlas_coords()); frame++) {
Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3); Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3);
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(hovered_tile.get_atlas_coords(), frame), color); TilesEditorUtils::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(hovered_tile.get_atlas_coords(), frame), color);
} }
} }
@ -1751,7 +1751,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
} }
} }
for (const Vector2i &E : to_draw) { for (const Vector2i &E : to_draw) {
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E)); TilesEditorUtils::draw_selection_rect(tile_atlas_control, atlas->get_tile_texture_region(E));
} }
} }
} }
@ -1900,7 +1900,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() {
if (E.source_id == source_id && E.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && E.alternative_tile > 0) { if (E.source_id == source_id && E.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && E.alternative_tile > 0) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E.get_atlas_coords(), E.alternative_tile); Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E.get_atlas_coords(), E.alternative_tile);
if (rect != Rect2i()) { if (rect != Rect2i()) {
TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect); TilesEditorUtils::draw_selection_rect(alternative_tiles_control, rect);
} }
} }
} }
@ -1909,7 +1909,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() {
if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) { if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile); Rect2i rect = tile_atlas_view->get_alternative_tile_rect(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile);
if (rect != Rect2i()) { if (rect != Rect2i()) {
TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5)); TilesEditorUtils::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5));
} }
} }
} }
@ -2031,10 +2031,10 @@ void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer
} }
void TileMapEditorTilesPlugin::_set_source_sort(int p_sort) { void TileMapEditorTilesPlugin::_set_source_sort(int p_sort) {
for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) { for (int i = 0; i != TilesEditorUtils::SOURCE_SORT_MAX; i++) {
source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort)); source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort));
} }
TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort); TilesEditorUtils::get_singleton()->set_sorting_option(p_sort);
_update_tile_set_sources_list(); _update_tile_set_sources_list();
EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "tile_source_sort", p_sort); EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "tile_source_sort", p_sort);
} }
@ -2217,11 +2217,11 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
PopupMenu *p = source_sort_button->get_popup(); PopupMenu *p = source_sort_button->get_popup();
p->connect("id_pressed", callable_mp(this, &TileMapEditorTilesPlugin::_set_source_sort)); p->connect("id_pressed", callable_mp(this, &TileMapEditorTilesPlugin::_set_source_sort));
p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorPlugin::SOURCE_SORT_ID); p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorUtils::SOURCE_SORT_ID);
p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorPlugin::SOURCE_SORT_ID_REVERSE); p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorUtils::SOURCE_SORT_ID_REVERSE);
p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorPlugin::SOURCE_SORT_NAME); p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorUtils::SOURCE_SORT_NAME);
p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE); p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorUtils::SOURCE_SORT_NAME_REVERSE);
p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true); p->set_item_checked(TilesEditorUtils::SOURCE_SORT_ID, true);
sources_bottom_actions->add_child(source_sort_button); sources_bottom_actions->add_child(source_sort_button);
sources_list = memnew(ItemList); sources_list = memnew(ItemList);
@ -2233,8 +2233,8 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1)); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1));
sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_source_display).unbind(1)); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_source_display).unbind(1));
sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); sources_list->connect("item_selected", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::set_sources_lists_current));
sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list).bind(sources_list, source_sort_button)); sources_list->connect("visibility_changed", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::synchronize_sources_list).bind(sources_list, source_sort_button));
sources_list->add_user_signal(MethodInfo("sort_request")); sources_list->add_user_signal(MethodInfo("sort_request"));
sources_list->connect("sort_request", callable_mp(this, &TileMapEditorTilesPlugin::_update_tile_set_sources_list)); sources_list->connect("sort_request", callable_mp(this, &TileMapEditorTilesPlugin::_update_tile_set_sources_list));
split_container_left_side->add_child(sources_list); split_container_left_side->add_child(sources_list);
@ -2246,7 +2246,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
tile_atlas_view->set_v_size_flags(Control::SIZE_EXPAND_FILL); tile_atlas_view->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tile_atlas_view->set_texture_grid_visible(false); tile_atlas_view->set_texture_grid_visible(false);
tile_atlas_view->set_tile_shape_grid_visible(false); tile_atlas_view->set_tile_shape_grid_visible(false);
tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_atlas_view_transform)); tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::set_atlas_view_transform));
atlas_sources_split_container->add_child(tile_atlas_view); atlas_sources_split_container->add_child(tile_atlas_view);
tile_atlas_control = memnew(Control); tile_atlas_control = memnew(Control);
@ -2353,8 +2353,8 @@ void TileMapEditorTerrainsPlugin::_update_toolbar() {
} }
} }
Vector<TileMapEditorPlugin::TabData> TileMapEditorTerrainsPlugin::get_tabs() const { Vector<TileMapSubEditorPlugin::TabData> TileMapEditorTerrainsPlugin::get_tabs() const {
Vector<TileMapEditorPlugin::TabData> tabs; Vector<TileMapSubEditorPlugin::TabData> tabs;
tabs.push_back({ toolbar, main_vbox_container }); tabs.push_back({ toolbar, main_vbox_container });
return tabs; return tabs;
} }
@ -3549,7 +3549,7 @@ void TileMapEditor::_update_bottom_panel() {
// Update the visibility of controls. // Update the visibility of controls.
missing_tileset_label->set_visible(!tile_set.is_valid()); missing_tileset_label->set_visible(!tile_set.is_valid());
for (TileMapEditorPlugin::TabData &tab_data : tabs_data) { for (TileMapSubEditorPlugin::TabData &tab_data : tabs_data) {
tab_data.panel->hide(); tab_data.panel->hide();
} }
if (tile_set.is_valid()) { if (tile_set.is_valid()) {
@ -3639,14 +3639,14 @@ void TileMapEditor::_tab_changed(int p_tab_id) {
tabs_plugins[tabs_bar->get_current_tab()]->edit(tile_map_id, tile_map_layer); tabs_plugins[tabs_bar->get_current_tab()]->edit(tile_map_id, tile_map_layer);
// Update toolbar. // Update toolbar.
for (TileMapEditorPlugin::TabData &tab_data : tabs_data) { for (TileMapSubEditorPlugin::TabData &tab_data : tabs_data) {
tab_data.toolbar->hide(); tab_data.toolbar->hide();
} }
tabs_data[p_tab_id].toolbar->show(); tabs_data[p_tab_id].toolbar->show();
// Update visible panel. // Update visible panel.
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
for (TileMapEditorPlugin::TabData &tab_data : tabs_data) { for (TileMapSubEditorPlugin::TabData &tab_data : tabs_data) {
tab_data.panel->hide(); tab_data.panel->hide();
} }
if (tile_map && tile_map->get_tileset().is_valid()) { if (tile_map && tile_map->get_tileset().is_valid()) {
@ -4006,7 +4006,7 @@ TileMapEditor::TileMapEditor() {
tabs_bar = memnew(TabBar); tabs_bar = memnew(TabBar);
tabs_bar->set_clip_tabs(false); tabs_bar->set_clip_tabs(false);
for (int plugin_index = 0; plugin_index < tile_map_editor_plugins.size(); plugin_index++) { for (int plugin_index = 0; plugin_index < tile_map_editor_plugins.size(); plugin_index++) {
Vector<TileMapEditorPlugin::TabData> tabs_vector = tile_map_editor_plugins[plugin_index]->get_tabs(); Vector<TileMapSubEditorPlugin::TabData> tabs_vector = tile_map_editor_plugins[plugin_index]->get_tabs();
for (int tab_index = 0; tab_index < tabs_vector.size(); tab_index++) { for (int tab_index = 0; tab_index < tabs_vector.size(); tab_index++) {
tabs_bar->add_tab(tabs_vector[tab_index].panel->get_name()); tabs_bar->add_tab(tabs_vector[tab_index].panel->get_name());
tabs_data.push_back(tabs_vector[tab_index]); tabs_data.push_back(tabs_vector[tab_index]);
@ -4024,7 +4024,7 @@ TileMapEditor::TileMapEditor() {
tile_map_toolbar->add_child(tabs_bar); tile_map_toolbar->add_child(tabs_bar);
// Tabs toolbars. // Tabs toolbars.
for (TileMapEditorPlugin::TabData &tab_data : tabs_data) { for (TileMapSubEditorPlugin::TabData &tab_data : tabs_data) {
tab_data.toolbar->hide(); tab_data.toolbar->hide();
if (!tab_data.toolbar->get_parent()) { if (!tab_data.toolbar->get_parent()) {
tile_map_toolbar->add_child(tab_data.toolbar); tile_map_toolbar->add_child(tab_data.toolbar);

View File

@ -48,7 +48,7 @@
#include "scene/gui/tab_bar.h" #include "scene/gui/tab_bar.h"
#include "scene/gui/tree.h" #include "scene/gui/tree.h"
class TileMapEditorPlugin : public Object { class TileMapSubEditorPlugin : public Object {
public: public:
struct TabData { struct TabData {
Control *toolbar = nullptr; Control *toolbar = nullptr;
@ -65,8 +65,8 @@ public:
virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer){}; virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer){};
}; };
class TileMapEditorTilesPlugin : public TileMapEditorPlugin { class TileMapEditorTilesPlugin : public TileMapSubEditorPlugin {
GDCLASS(TileMapEditorTilesPlugin, TileMapEditorPlugin); GDCLASS(TileMapEditorTilesPlugin, TileMapSubEditorPlugin);
private: private:
ObjectID tile_map_id; ObjectID tile_map_id;
@ -219,8 +219,8 @@ public:
~TileMapEditorTilesPlugin(); ~TileMapEditorTilesPlugin();
}; };
class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin { class TileMapEditorTerrainsPlugin : public TileMapSubEditorPlugin {
GDCLASS(TileMapEditorTerrainsPlugin, TileMapEditorPlugin); GDCLASS(TileMapEditorTerrainsPlugin, TileMapSubEditorPlugin);
private: private:
ObjectID tile_map_id; ObjectID tile_map_id;
@ -321,7 +321,7 @@ private:
int tile_map_layer = -1; int tile_map_layer = -1;
// Vector to keep plugins. // Vector to keep plugins.
Vector<TileMapEditorPlugin *> tile_map_editor_plugins; Vector<TileMapSubEditorPlugin *> tile_map_editor_plugins;
// Toolbar. // Toolbar.
HFlowContainer *tile_map_toolbar = nullptr; HFlowContainer *tile_map_toolbar = nullptr;
@ -339,8 +339,8 @@ private:
// Bottom panel. // Bottom panel.
Label *missing_tileset_label = nullptr; Label *missing_tileset_label = nullptr;
TabBar *tabs_bar = nullptr; TabBar *tabs_bar = nullptr;
LocalVector<TileMapEditorPlugin::TabData> tabs_data; LocalVector<TileMapSubEditorPlugin::TabData> tabs_data;
LocalVector<TileMapEditorPlugin *> tabs_plugins; LocalVector<TileMapSubEditorPlugin *> tabs_plugins;
void _update_bottom_panel(); void _update_bottom_panel();
// TileMap. // TileMap.

View File

@ -1014,7 +1014,7 @@ void TileSetAtlasSourceEditor::_update_atlas_view() {
tile_atlas_view->queue_redraw(); tile_atlas_view->queue_redraw();
// Synchronize atlas view. // Synchronize atlas view.
TilesEditorPlugin::get_singleton()->synchronize_atlas_view(tile_atlas_view); TilesEditorUtils::get_singleton()->synchronize_atlas_view(tile_atlas_view);
} }
void TileSetAtlasSourceEditor::_update_toolbar() { void TileSetAtlasSourceEditor::_update_toolbar() {
@ -1724,7 +1724,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(selected.tile); frame++) { for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(selected.tile); frame++) {
Color color = Color(0.0, 1.0, 0.0, frame == 0 ? 1.0 : 0.3); Color color = Color(0.0, 1.0, 0.0, frame == 0 ? 1.0 : 0.3);
Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile, frame); Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile, frame);
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, region, color); TilesEditorUtils::draw_selection_rect(tile_atlas_control, region, color);
} }
} }
} }
@ -1766,7 +1766,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
// Draw the tiles to be removed. // Draw the tiles to be removed.
for (const Vector2i &E : drag_modified_tiles) { for (const Vector2i &E : drag_modified_tiles) {
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(E); frame++) { for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(E); frame++) {
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(E, frame), Color(0.0, 0.0, 0.0)); TilesEditorUtils::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(E, frame), Color(0.0, 0.0, 0.0));
} }
} }
} else if (drag_type == DRAG_TYPE_RECT_SELECT || drag_type == DRAG_TYPE_REMOVE_TILES_USING_RECT) { } else if (drag_type == DRAG_TYPE_RECT_SELECT || drag_type == DRAG_TYPE_REMOVE_TILES_USING_RECT) {
@ -1793,7 +1793,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
for (const Vector2i &E : to_paint) { for (const Vector2i &E : to_paint) {
Vector2i coords = E; Vector2i coords = E;
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(coords), color); TilesEditorUtils::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(coords), color);
} }
} else if (drag_type == DRAG_TYPE_CREATE_TILES_USING_RECT) { } else if (drag_type == DRAG_TYPE_CREATE_TILES_USING_RECT) {
// Draw tiles to be created. // Draw tiles to be created.
@ -1810,7 +1810,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i coords = Vector2i(x, y); Vector2i coords = Vector2i(x, y);
if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) {
Vector2i origin = margins + (coords * (tile_size + separation)); Vector2i origin = margins + (coords * (tile_size + separation));
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size)); TilesEditorUtils::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size));
} }
} }
} }
@ -1827,7 +1827,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i separation = tile_set_atlas_source->get_separation(); Vector2i separation = tile_set_atlas_source->get_separation();
Vector2i tile_size = tile_set_atlas_source->get_texture_region_size(); Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
Vector2i origin = margins + (area.position * (tile_size + separation)); Vector2i origin = margins + (area.position * (tile_size + separation));
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, area.size * tile_size)); TilesEditorUtils::draw_selection_rect(tile_atlas_control, Rect2i(origin, area.size * tile_size));
} else { } else {
Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
if (hovered_base_tile_coords.x >= 0 && hovered_base_tile_coords.y >= 0 && hovered_base_tile_coords.x < grid_size.x && hovered_base_tile_coords.y < grid_size.y) { if (hovered_base_tile_coords.x >= 0 && hovered_base_tile_coords.y >= 0 && hovered_base_tile_coords.x < grid_size.x && hovered_base_tile_coords.y < grid_size.y) {
@ -1836,7 +1836,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
// Draw existing hovered tile. // Draw existing hovered tile.
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(hovered_tile); frame++) { for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(hovered_tile); frame++) {
Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3); Color color = Color(1.0, 0.8, 0.0, frame == 0 ? 0.6 : 0.3);
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(hovered_tile, frame), color); TilesEditorUtils::draw_selection_rect(tile_atlas_control, tile_set_atlas_source->get_tile_texture_region(hovered_tile, frame), color);
} }
} else { } else {
// Draw empty tile, only in add/remove tiles mode. // Draw empty tile, only in add/remove tiles mode.
@ -1845,7 +1845,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
Vector2i separation = tile_set_atlas_source->get_separation(); Vector2i separation = tile_set_atlas_source->get_separation();
Vector2i tile_size = tile_set_atlas_source->get_texture_region_size(); Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
Vector2i origin = margins + (hovered_base_tile_coords * (tile_size + separation)); Vector2i origin = margins + (hovered_base_tile_coords * (tile_size + separation));
TilesEditorPlugin::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size)); TilesEditorUtils::draw_selection_rect(tile_atlas_control, Rect2i(origin, tile_size));
} }
} }
} }
@ -2004,7 +2004,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
if (coords != TileSetSource::INVALID_ATLAS_COORDS) { if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, hovered_alternative_tile_coords.z); Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, hovered_alternative_tile_coords.z);
if (rect != Rect2i()) { if (rect != Rect2i()) {
TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5)); TilesEditorUtils::draw_selection_rect(alternative_tiles_control, rect, Color(1.0, 0.8, 0.0, 0.5));
} }
} }
@ -2014,7 +2014,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() {
if (selected.alternative >= 1) { if (selected.alternative >= 1) {
Rect2i rect = tile_atlas_view->get_alternative_tile_rect(selected.tile, selected.alternative); Rect2i rect = tile_atlas_view->get_alternative_tile_rect(selected.tile, selected.alternative);
if (rect != Rect2i()) { if (rect != Rect2i()) {
TilesEditorPlugin::draw_selection_rect(alternative_tiles_control, rect); TilesEditorUtils::draw_selection_rect(alternative_tiles_control, rect);
} }
} }
} }
@ -2580,7 +2580,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_atlas_view->set_h_size_flags(SIZE_EXPAND_FILL); tile_atlas_view->set_h_size_flags(SIZE_EXPAND_FILL);
tile_atlas_view->set_v_size_flags(SIZE_EXPAND_FILL); tile_atlas_view->set_v_size_flags(SIZE_EXPAND_FILL);
tile_atlas_view->set_custom_minimum_size(Size2(200, 0) * EDSCALE); tile_atlas_view->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_atlas_view_transform)); tile_atlas_view->connect("transform_changed", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::set_atlas_view_transform));
tile_atlas_view->connect("transform_changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_atlas_view_transform_changed).unbind(2)); tile_atlas_view->connect("transform_changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_atlas_view_transform_changed).unbind(2));
right_panel->add_child(tile_atlas_view); right_panel->add_child(tile_atlas_view);

View File

@ -149,7 +149,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
sources_list->clear(); sources_list->clear();
// Update the atlas sources. // Update the atlas sources.
List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set); List<int> source_ids = TilesEditorUtils::get_singleton()->get_sorted_sources(tile_set);
for (const int &source_id : source_ids) { for (const int &source_id : source_ids) {
TileSetSource *source = *tile_set->get_source(source_id); TileSetSource *source = *tile_set->get_source(source_id);
@ -221,7 +221,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
_source_selected(sources_list->get_current()); _source_selected(sources_list->get_current());
// Synchronize the lists. // Synchronize the lists.
TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current()); TilesEditorUtils::get_singleton()->set_sources_lists_current(sources_list->get_current());
} }
void TileSetEditor::_texture_file_selected(const String &p_path) { void TileSetEditor::_texture_file_selected(const String &p_path) {
@ -352,8 +352,8 @@ void TileSetEditor::_sources_advanced_menu_id_pressed(int p_id_pressed) {
} }
void TileSetEditor::_set_source_sort(int p_sort) { void TileSetEditor::_set_source_sort(int p_sort) {
TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort); TilesEditorUtils::get_singleton()->set_sorting_option(p_sort);
for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) { for (int i = 0; i != TilesEditorUtils::SOURCE_SORT_MAX; i++) {
source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort)); source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort));
} }
@ -450,7 +450,7 @@ void TileSetEditor::_update_patterns_list() {
int id = patterns_item_list->add_item(""); int id = patterns_item_list->add_item("");
patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i)); patterns_item_list->set_item_metadata(id, tile_set->get_pattern(i));
patterns_item_list->set_item_tooltip(id, vformat(TTR("Index: %d"), i)); patterns_item_list->set_item_tooltip(id, vformat(TTR("Index: %d"), i));
TilesEditorPlugin::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileSetEditor::_pattern_preview_done)); TilesEditorUtils::get_singleton()->queue_pattern_preview(tile_set, tile_set->get_pattern(i), callable_mp(this, &TileSetEditor::_pattern_preview_done));
} }
// Update the label visibility. // Update the label visibility.
@ -854,19 +854,19 @@ TileSetEditor::TileSetEditor() {
PopupMenu *p = source_sort_button->get_popup(); PopupMenu *p = source_sort_button->get_popup();
p->connect("id_pressed", callable_mp(this, &TileSetEditor::_set_source_sort)); p->connect("id_pressed", callable_mp(this, &TileSetEditor::_set_source_sort));
p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorPlugin::SOURCE_SORT_ID); p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorUtils::SOURCE_SORT_ID);
p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorPlugin::SOURCE_SORT_ID_REVERSE); p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorUtils::SOURCE_SORT_ID_REVERSE);
p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorPlugin::SOURCE_SORT_NAME); p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorUtils::SOURCE_SORT_NAME);
p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE); p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorUtils::SOURCE_SORT_NAME_REVERSE);
p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true); p->set_item_checked(TilesEditorUtils::SOURCE_SORT_ID, true);
sources_list = memnew(ItemList); sources_list = memnew(ItemList);
sources_list->set_fixed_icon_size(Size2(60, 60) * EDSCALE); sources_list->set_fixed_icon_size(Size2(60, 60) * EDSCALE);
sources_list->set_h_size_flags(SIZE_EXPAND_FILL); sources_list->set_h_size_flags(SIZE_EXPAND_FILL);
sources_list->set_v_size_flags(SIZE_EXPAND_FILL); sources_list->set_v_size_flags(SIZE_EXPAND_FILL);
sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected)); sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected));
sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); sources_list->connect("item_selected", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::set_sources_lists_current));
sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list).bind(sources_list, source_sort_button)); sources_list->connect("visibility_changed", callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::synchronize_sources_list).bind(sources_list, source_sort_button));
sources_list->add_user_signal(MethodInfo("sort_request")); sources_list->add_user_signal(MethodInfo("sort_request"));
sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list).bind(-1)); sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list).bind(-1));
sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);

View File

@ -38,6 +38,7 @@
#include "editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/editor_scale.h" #include "editor/editor_scale.h"
#include "editor/editor_settings.h" #include "editor/editor_settings.h"
#include "editor/inspector_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/tile_map.h" #include "scene/2d/tile_map.h"
@ -48,23 +49,24 @@
#include "scene/resources/image_texture.h" #include "scene/resources/image_texture.h"
#include "scene/resources/tile_set.h" #include "scene/resources/tile_set.h"
TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr; TilesEditorUtils *TilesEditorUtils::singleton = nullptr;
TileMapEditorPlugin *local_singleton = nullptr;
void TilesEditorPlugin::_preview_frame_started() { void TilesEditorUtils::_preview_frame_started() {
RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_pattern_preview_done)); RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorUtils *>(this), &TilesEditorUtils::_pattern_preview_done));
} }
void TilesEditorPlugin::_pattern_preview_done() { void TilesEditorUtils::_pattern_preview_done() {
pattern_preview_done.post(); pattern_preview_done.post();
} }
void TilesEditorPlugin::_thread_func(void *ud) { void TilesEditorUtils::_thread_func(void *ud) {
TilesEditorPlugin *te = static_cast<TilesEditorPlugin *>(ud); TilesEditorUtils *te = static_cast<TilesEditorUtils *>(ud);
set_current_thread_safe_for_nodes(true); set_current_thread_safe_for_nodes(true);
te->_thread(); te->_thread();
} }
void TilesEditorPlugin::_thread() { void TilesEditorUtils::_thread() {
pattern_thread_exited.clear(); pattern_thread_exited.clear();
while (!pattern_thread_exit.is_set()) { while (!pattern_thread_exit.is_set()) {
pattern_preview_sem.wait(); pattern_preview_sem.wait();
@ -124,7 +126,7 @@ void TilesEditorPlugin::_thread() {
// Add the viewport at the last moment to avoid rendering too early. // Add the viewport at the last moment to avoid rendering too early.
EditorNode::get_singleton()->call_deferred("add_child", viewport); EditorNode::get_singleton()->call_deferred("add_child", viewport);
RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Object::CONNECT_ONE_SHOT); RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorUtils *>(this), &TilesEditorUtils::_preview_frame_started), Object::CONNECT_ONE_SHOT);
pattern_preview_done.wait(); pattern_preview_done.wait();
@ -144,85 +146,7 @@ void TilesEditorPlugin::_thread() {
pattern_thread_exited.set(); pattern_thread_exited.set();
} }
void TilesEditorPlugin::_tile_map_changed() { void TilesEditorUtils::queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback) {
tile_map_changed_needs_update = true;
}
void TilesEditorPlugin::_update_editors() {
// If tile_map is not edited, we change the edited only if we are not editing a tile_set.
if (tile_set.is_valid()) {
tileset_editor->edit(tile_set);
}
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (tile_map) {
tilemap_editor->edit(tile_map);
} else {
tilemap_editor->edit(nullptr);
}
// Update the viewport.
CanvasItemEditor::get_singleton()->update_viewport();
// Make sure the tile set editor is visible if we have one assigned.
tileset_editor_button->set_visible(is_visible && tile_set.is_valid());
tilemap_editor_button->set_visible(is_visible && tile_map);
// Update visibility of bottom panel buttons.
if (tileset_editor_button->is_pressed() && !tile_set.is_valid()) {
if (tile_map) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else {
EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
void TilesEditorPlugin::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
if (tile_map_changed_needs_update) {
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (tile_map) {
tile_set = tile_map->get_tileset();
}
_update_editors();
tile_map_changed_needs_update = false;
}
} break;
}
}
void TilesEditorPlugin::make_visible(bool p_visible) {
if (p_visible || is_tile_map_selected()) {
// Disable and hide invalid editors.
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
tileset_editor_button->set_visible(tile_set.is_valid());
tilemap_editor_button->set_visible(tile_map);
if (tile_map && (!is_editing_tile_set || !p_visible)) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else {
EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor);
}
is_visible = true;
} else {
tileset_editor_button->hide();
tilemap_editor_button->hide();
EditorNode::get_singleton()->hide_bottom_panel();
is_visible = false;
}
}
bool TilesEditorPlugin::is_tile_map_selected() {
TypedArray<Node> selection = EditorInterface::get_singleton()->get_selection()->get_selected_nodes();
if (selection.size() == 1 && Object::cast_to<TileMap>(selection[0])) {
return true;
}
return false;
}
void TilesEditorPlugin::queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback) {
ERR_FAIL_COND(!p_tile_set.is_valid()); ERR_FAIL_COND(!p_tile_set.is_valid());
ERR_FAIL_COND(!p_pattern.is_valid()); ERR_FAIL_COND(!p_pattern.is_valid());
{ {
@ -232,11 +156,11 @@ void TilesEditorPlugin::queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileM
pattern_preview_sem.post(); pattern_preview_sem.post();
} }
void TilesEditorPlugin::set_sources_lists_current(int p_current) { void TilesEditorUtils::set_sources_lists_current(int p_current) {
atlas_sources_lists_current = p_current; atlas_sources_lists_current = p_current;
} }
void TilesEditorPlugin::synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button) { void TilesEditorUtils::synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button) {
ItemList *item_list = Object::cast_to<ItemList>(p_current_list); ItemList *item_list = Object::cast_to<ItemList>(p_current_list);
MenuButton *sorting_button = Object::cast_to<MenuButton>(p_current_sort_button); MenuButton *sorting_button = Object::cast_to<MenuButton>(p_current_sort_button);
ERR_FAIL_COND(!item_list); ERR_FAIL_COND(!item_list);
@ -264,12 +188,12 @@ void TilesEditorPlugin::synchronize_sources_list(Object *p_current_list, Object
} }
} }
void TilesEditorPlugin::set_atlas_view_transform(float p_zoom, Vector2 p_scroll) { void TilesEditorUtils::set_atlas_view_transform(float p_zoom, Vector2 p_scroll) {
atlas_view_zoom = p_zoom; atlas_view_zoom = p_zoom;
atlas_view_scroll = p_scroll; atlas_view_scroll = p_scroll;
} }
void TilesEditorPlugin::synchronize_atlas_view(Object *p_current) { void TilesEditorUtils::synchronize_atlas_view(Object *p_current) {
TileAtlasView *tile_atlas_view = Object::cast_to<TileAtlasView>(p_current); TileAtlasView *tile_atlas_view = Object::cast_to<TileAtlasView>(p_current);
ERR_FAIL_COND(!tile_atlas_view); ERR_FAIL_COND(!tile_atlas_view);
@ -278,11 +202,11 @@ void TilesEditorPlugin::synchronize_atlas_view(Object *p_current) {
} }
} }
void TilesEditorPlugin::set_sorting_option(int p_option) { void TilesEditorUtils::set_sorting_option(int p_option) {
source_sort = p_option; source_sort = p_option;
} }
List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> p_tile_set) const { List<int> TilesEditorUtils::get_sorted_sources(const Ref<TileSet> p_tile_set) const {
SourceNameComparator::tile_set = p_tile_set; SourceNameComparator::tile_set = p_tile_set;
List<int> source_ids; List<int> source_ids;
@ -310,9 +234,9 @@ List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> p_tile_set) c
return source_ids; return source_ids;
} }
Ref<TileSet> TilesEditorPlugin::SourceNameComparator::tile_set; Ref<TileSet> TilesEditorUtils::SourceNameComparator::tile_set;
bool TilesEditorPlugin::SourceNameComparator::operator()(const int &p_a, const int &p_b) const { bool TilesEditorUtils::SourceNameComparator::operator()(const int &p_a, const int &p_b) const {
String name_a; String name_a;
String name_b; String name_b;
@ -359,55 +283,7 @@ bool TilesEditorPlugin::SourceNameComparator::operator()(const int &p_a, const i
return NaturalNoCaseComparator()(name_a, name_b); return NaturalNoCaseComparator()(name_a, name_b);
} }
void TilesEditorPlugin::edit(Object *p_object) { void TilesEditorUtils::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color) {
// Disconnect to changes.
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (tile_map) {
tile_map->disconnect("changed", callable_mp(this, &TilesEditorPlugin::_tile_map_changed));
}
// Update edited objects.
tile_set = Ref<TileSet>();
is_editing_tile_set = false;
if (p_object) {
if (p_object->is_class("TileMap")) {
tile_map_id = p_object->get_instance_id();
tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
tile_set = tile_map->get_tileset();
EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor);
} else if (p_object->is_class("TileSet")) {
tile_set = Ref<TileSet>(p_object);
if (tile_map) {
if (tile_map->get_tileset() != tile_set || !tile_map->is_inside_tree() || !is_tile_map_selected()) {
tile_map = nullptr;
tile_map_id = ObjectID();
}
}
is_editing_tile_set = true;
}
}
// Update the editors.
_update_editors();
// If the tileset is being edited, the visibility function must be called
// here after _update_editors has been called.
if (is_editing_tile_set) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor);
}
// Add change listener.
if (tile_map) {
tile_map->connect("changed", callable_mp(this, &TilesEditorPlugin::_tile_map_changed));
}
}
bool TilesEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("TileMap") || p_object->is_class("TileSet");
}
void TilesEditorPlugin::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color) {
real_t scale = p_ci->get_global_transform().get_scale().x * 0.5; real_t scale = p_ci->get_global_transform().get_scale().x * 0.5;
p_ci->draw_set_transform(p_rect.position, 0, Vector2(1, 1) / scale); p_ci->draw_set_transform(p_rect.position, 0, Vector2(1, 1) / scale);
RS::get_singleton()->canvas_item_add_nine_patch( RS::get_singleton()->canvas_item_add_nine_patch(
@ -416,40 +292,13 @@ void TilesEditorPlugin::draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rec
p_ci->draw_set_transform_matrix(Transform2D()); p_ci->draw_set_transform_matrix(Transform2D());
} }
TilesEditorPlugin::TilesEditorPlugin() { TilesEditorUtils::TilesEditorUtils() {
set_process_internal(true);
// Update the singleton.
singleton = this; singleton = this;
// Tileset editor.
tileset_editor = memnew(TileSetEditor);
tileset_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
tileset_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tileset_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
tileset_editor->hide();
// Tilemap editor.
tilemap_editor = memnew(TileMapEditor);
tilemap_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
tilemap_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tilemap_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
tilemap_editor->hide();
// Pattern preview generation thread. // Pattern preview generation thread.
pattern_preview_thread.start(_thread_func, this); pattern_preview_thread.start(_thread_func, this);
// Bottom buttons.
tileset_editor_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileSet"), tileset_editor);
tileset_editor_button->hide();
tilemap_editor_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileMap"), tilemap_editor);
tilemap_editor_button->hide();
// Initialization.
_update_editors();
} }
TilesEditorPlugin::~TilesEditorPlugin() { TilesEditorUtils::~TilesEditorUtils() {
if (pattern_preview_thread.is_started()) { if (pattern_preview_thread.is_started()) {
pattern_thread_exit.set(); pattern_thread_exit.set();
pattern_preview_sem.post(); pattern_preview_sem.post();
@ -459,4 +308,124 @@ TilesEditorPlugin::~TilesEditorPlugin() {
} }
pattern_preview_thread.wait_to_finish(); pattern_preview_thread.wait_to_finish();
} }
singleton = nullptr;
}
void TileMapEditorPlugin::_tile_map_changed() {
if (tile_map_changed_needs_update) {
return;
}
tile_map_changed_needs_update = true;
callable_mp(this, &TileMapEditorPlugin::_update_tile_map).call_deferred();
}
void TileMapEditorPlugin::_update_tile_map() {
if (tile_map && tile_map->get_tileset().is_valid()) {
EditorNode::get_singleton()->edit_item(tile_map->get_tileset().ptr(), InspectorDock::get_inspector_singleton());
}
tile_map_changed_needs_update = false;
}
void TileMapEditorPlugin::_notification(int p_notification) {
if (p_notification == NOTIFICATION_EXIT_TREE) {
get_tree()->queue_delete(TilesEditorUtils::get_singleton());
}
}
void TileMapEditorPlugin::edit(Object *p_object) {
if (tile_map) {
tile_map->disconnect("changed", callable_mp(this, &TileMapEditorPlugin::_tile_map_changed));
}
tile_map = Object::cast_to<TileMap>(p_object);
editor->edit(tile_map);
if (tile_map) {
tile_map->connect("changed", callable_mp(this, &TileMapEditorPlugin::_tile_map_changed));
if (tile_map->get_tileset().is_valid()) {
EditorNode::get_singleton()->edit_item(tile_map->get_tileset().ptr(), InspectorDock::get_inspector_singleton());
}
}
}
bool TileMapEditorPlugin::handles(Object *p_object) const {
return Object::cast_to<TileMap>(p_object) != nullptr;
}
void TileMapEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
EditorNode::get_singleton()->make_bottom_panel_item_visible(editor);
} else {
button->hide();
if (editor->is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
bool TileMapEditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
return editor->forward_canvas_gui_input(p_event);
}
void TileMapEditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) {
editor->forward_canvas_draw_over_viewport(p_overlay);
}
bool TileMapEditorPlugin::is_editor_visible() const {
return editor->is_visible_in_tree();
}
TileMapEditorPlugin::TileMapEditorPlugin() {
memnew(TilesEditorUtils);
local_singleton = this;
editor = memnew(TileMapEditor);
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->hide();
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileMap"), editor);
button->hide();
}
TileMapEditorPlugin::~TileMapEditorPlugin() {
local_singleton = nullptr;
}
void TileSetEditorPlugin::edit(Object *p_object) {
editor->edit(Ref<TileSet>(p_object));
}
bool TileSetEditorPlugin::handles(Object *p_object) const {
return Object::cast_to<TileSet>(p_object) != nullptr;
}
void TileSetEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
if (!local_singleton->is_editor_visible()) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(editor);
}
} else {
button->hide();
if (editor->is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
}
}
}
TileSetEditorPlugin::TileSetEditorPlugin() {
DEV_ASSERT(local_singleton);
editor = memnew(TileSetEditor);
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->hide();
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileSet"), editor);
button->hide();
} }

View File

@ -38,10 +38,10 @@
#include "tile_map_editor.h" #include "tile_map_editor.h"
#include "tile_set_editor.h" #include "tile_set_editor.h"
class TilesEditorPlugin : public EditorPlugin { class TilesEditorUtils : public Object {
GDCLASS(TilesEditorPlugin, EditorPlugin); GDCLASS(TilesEditorUtils, Object);
static TilesEditorPlugin *singleton; static TilesEditorUtils *singleton;
public: public:
enum SourceSortOption { enum SourceSortOption {
@ -53,28 +53,11 @@ public:
}; };
private: private:
bool is_visible = false;
bool tile_map_changed_needs_update = false;
ObjectID tile_map_id;
Ref<TileSet> tile_set;
bool is_editing_tile_set = false;
Button *tilemap_editor_button = nullptr;
TileMapEditor *tilemap_editor = nullptr;
Button *tileset_editor_button = nullptr;
TileSetEditor *tileset_editor = nullptr;
void _update_editors();
// For synchronization. // For synchronization.
int atlas_sources_lists_current = 0; int atlas_sources_lists_current = 0;
float atlas_view_zoom = 1.0; float atlas_view_zoom = 1.0;
Vector2 atlas_view_scroll; Vector2 atlas_view_scroll;
void _tile_map_changed();
// Source sorting. // Source sorting.
int source_sort = SOURCE_SORT_ID; int source_sort = SOURCE_SORT_ID;
@ -101,16 +84,8 @@ private:
static void _thread_func(void *ud); static void _thread_func(void *ud);
void _thread(); void _thread();
protected:
void _notification(int p_what);
public: public:
_FORCE_INLINE_ static TilesEditorPlugin *get_singleton() { return singleton; } _FORCE_INLINE_ static TilesEditorUtils *get_singleton() { return singleton; }
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return tilemap_editor->forward_canvas_gui_input(p_event); }
virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { tilemap_editor->forward_canvas_draw_over_viewport(p_overlay); }
bool is_tile_map_selected();
// Pattern preview API. // Pattern preview API.
void queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback); void queue_pattern_preview(Ref<TileSet> p_tile_set, Ref<TileMapPattern> p_pattern, Callable p_callback);
@ -126,14 +101,52 @@ public:
void set_sorting_option(int p_option); void set_sorting_option(int p_option);
List<int> get_sorted_sources(const Ref<TileSet> p_tile_set) const; List<int> get_sorted_sources(const Ref<TileSet> p_tile_set) const;
static void draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color = Color(1.0, 1.0, 1.0));
TilesEditorUtils();
~TilesEditorUtils();
};
class TileMapEditorPlugin : public EditorPlugin {
GDCLASS(TileMapEditorPlugin, EditorPlugin);
TileMapEditor *editor = nullptr;
Button *button = nullptr;
TileMap *tile_map = nullptr;
bool tile_map_changed_needs_update = false;
void _tile_map_changed();
void _update_tile_map();
protected:
void _notification(int p_notification);
public:
virtual void edit(Object *p_object) override; virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override; virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override; virtual void make_visible(bool p_visible) override;
static void draw_selection_rect(CanvasItem *p_ci, const Rect2 &p_rect, const Color &p_color = Color(1.0, 1.0, 1.0)); virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override;
virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override;
TilesEditorPlugin(); bool is_editor_visible() const;
~TilesEditorPlugin();
TileMapEditorPlugin();
~TileMapEditorPlugin();
};
class TileSetEditorPlugin : public EditorPlugin {
GDCLASS(TileSetEditorPlugin, EditorPlugin);
TileSetEditor *editor = nullptr;
Button *button = nullptr;
public:
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
TileSetEditorPlugin();
}; };
#endif // TILES_EDITOR_PLUGIN_H #endif // TILES_EDITOR_PLUGIN_H

View File

@ -254,7 +254,8 @@ void register_editor_types() {
EditorPlugins::add_by_type<Cast2DEditorPlugin>(); EditorPlugins::add_by_type<Cast2DEditorPlugin>();
EditorPlugins::add_by_type<Skeleton2DEditorPlugin>(); EditorPlugins::add_by_type<Skeleton2DEditorPlugin>();
EditorPlugins::add_by_type<Sprite2DEditorPlugin>(); EditorPlugins::add_by_type<Sprite2DEditorPlugin>();
EditorPlugins::add_by_type<TilesEditorPlugin>(); EditorPlugins::add_by_type<TileMapEditorPlugin>();
EditorPlugins::add_by_type<TileSetEditorPlugin>();
// For correct doc generation. // For correct doc generation.
GLOBAL_DEF("editor/run/main_run_args", ""); GLOBAL_DEF("editor/run/main_run_args", "");