diff options
Diffstat (limited to 'editor/plugins/tiles')
-rw-r--r-- | editor/plugins/tiles/atlas_merging_dialog.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_atlas_view.cpp | 21 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_atlas_view.h | 4 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_data_editors.cpp | 75 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_map_editor.cpp | 100 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_map_editor.h | 2 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_atlas_source_editor.cpp | 12 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_editor.cpp | 56 | ||||
-rw-r--r-- | editor/plugins/tiles/tile_set_editor.h | 2 | ||||
-rw-r--r-- | editor/plugins/tiles/tiles_editor_plugin.cpp | 101 | ||||
-rw-r--r-- | editor/plugins/tiles/tiles_editor_plugin.h | 23 |
11 files changed, 300 insertions, 98 deletions
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index fc4764f61e..677c9759c2 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -81,7 +81,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla } // Copy the properties. - TileData *original_tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id)); + TileData *original_tile_data = atlas_source->get_tile_data(tile_id, alternative_id); List<PropertyInfo> properties; original_tile_data->get_property_list(&properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 24ede3b85e..35496795e0 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -48,7 +48,7 @@ void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) { } } -void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec) { +void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec, bool p_alt) { _pan_callback(-p_scroll_vec * 32); } @@ -58,7 +58,7 @@ void TileAtlasView::_pan_callback(Vector2 p_scroll_vec) { _update_zoom_and_panning(true); } -void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) { +void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { zoom_widget->set_zoom_by_increments(-p_scroll_vec.y * 2); emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning); _update_zoom_and_panning(true); @@ -83,7 +83,7 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() { Size2i texture_region_size = tile_set_atlas_source->get_tile_texture_region(tile_id).size; for (int j = 1; j < alternatives_count; j++) { int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j); - bool transposed = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(tile_id, alternative_id))->get_transpose(); + bool transposed = tile_set_atlas_source->get_tile_data(tile_id, alternative_id)->get_transpose(); line_size.x += transposed ? texture_region_size.y : texture_region_size.x; line_size.y = MAX(line_size.y, transposed ? texture_region_size.x : texture_region_size.y); } @@ -345,7 +345,7 @@ void TileAtlasView::_draw_alternatives() { int alternatives_count = tile_set_atlas_source->get_alternative_tiles_count(atlas_coords); for (int j = 1; j < alternatives_count; j++) { int alternative_id = tile_set_atlas_source->get_alternative_tile_id(atlas_coords, j); - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(atlas_coords, alternative_id)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(atlas_coords, alternative_id); bool transposed = tile_data->get_transpose(); // Update the y to max value. @@ -473,7 +473,7 @@ void TileAtlasView::_update_alternative_tiles_rect_cache() { int line_height = 0; for (int j = 1; j < alternatives_count; j++) { int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j); - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(tile_id, alternative_id)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(tile_id, alternative_id); bool transposed = tile_data->get_transpose(); current.size = transposed ? Vector2i(texture_region_size.y, texture_region_size.x) : texture_region_size; @@ -524,7 +524,7 @@ void TileAtlasView::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: - panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int()); + panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); break; case NOTIFICATION_READY: @@ -540,9 +540,6 @@ void TileAtlasView::_bind_methods() { TileAtlasView::TileAtlasView() { set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); - panner.instantiate(); - panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback)); - Panel *panel = memnew(Panel); panel->set_clip_contents(true); panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); @@ -566,10 +563,16 @@ TileAtlasView::TileAtlasView() { button_center_view->set_tooltip(TTR("Center View")); add_child(button_center_view); + panner.instantiate(); + panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback)); + panner->set_enable_rmb(true); + center_container = memnew(CenterContainer); center_container->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); center_container->set_anchors_preset(Control::PRESET_CENTER); center_container->connect("gui_input", callable_mp(this, &TileAtlasView::gui_input)); + center_container->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); + center_container->set_focus_mode(FOCUS_CLICK); panel->add_child(center_container); missing_source_label = memnew(Label); diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 6a0e0ae820..37ef7d6a2a 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -67,9 +67,9 @@ private: virtual void gui_input(const Ref<InputEvent> &p_event) override; Ref<ViewPanner> panner; - void _scroll_callback(Vector2 p_scroll_vec); + void _scroll_callback(Vector2 p_scroll_vec, bool p_alt); void _pan_callback(Vector2 p_scroll_vec); - void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin); + void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache; void _update_alternative_tiles_rect_cache(); diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index d5c2051f31..12003738e7 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -60,7 +60,7 @@ TileData *TileDataEditor::_get_tile_data(TileMapCell p_cell) { if (atlas_source) { ERR_FAIL_COND_V(!atlas_source->has_tile(p_cell.get_atlas_coords()), nullptr); ERR_FAIL_COND_V(!atlas_source->has_alternative_tile(p_cell.get_atlas_coords(), p_cell.alternative_tile), nullptr); - td = Object::cast_to<TileData>(atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile)); + td = atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile); } return td; @@ -713,20 +713,21 @@ void GenericTilePolygonEditor::set_multiple_polygon_mode(bool p_multiple_polygon void GenericTilePolygonEditor::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: - button_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons"))); - button_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons"))); - button_delete->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons"))); - button_center_view->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons"))); - button_pixel_snap->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Snap"), SNAME("EditorIcons"))); - button_advanced_menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + button_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons"))); + button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons"))); + button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons"))); + button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons"))); + button_pixel_snap->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons"))); + button_advanced_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); PopupMenu *p = button_advanced_menu->get_popup(); p->set_item_icon(p->get_item_index(ROTATE_RIGHT), get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons"))); p->set_item_icon(p->get_item_index(ROTATE_LEFT), get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons"))); p->set_item_icon(p->get_item_index(FLIP_HORIZONTALLY), get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons"))); p->set_item_icon(p->get_item_index(FLIP_VERTICALLY), get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons"))); - break; + } break; } } @@ -837,7 +838,7 @@ Variant TileDataDefaultEditor::_get_painted_value() { } void TileDataDefaultEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Variant value = tile_data->get(property); dummy_object->set(property, value); @@ -847,13 +848,13 @@ void TileDataDefaultEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_at } void TileDataDefaultEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); tile_data->set(property, p_value); } Variant TileDataDefaultEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND_V(!tile_data, Variant()); return tile_data->get(property); } @@ -1269,7 +1270,7 @@ Variant TileDataOcclusionShapeEditor::_get_painted_value() { } void TileDataOcclusionShapeEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer); @@ -1281,7 +1282,7 @@ void TileDataOcclusionShapeEditor::_set_painted_value(TileSetAtlasSource *p_tile } void TileDataOcclusionShapeEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Ref<OccluderPolygon2D> occluder_polygon = p_value; tile_data->set_occluder(occlusion_layer, occluder_polygon); @@ -1290,7 +1291,7 @@ void TileDataOcclusionShapeEditor::_set_value(TileSetAtlasSource *p_tile_set_atl } Variant TileDataOcclusionShapeEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND_V(!tile_data, Variant()); return tile_data->get_occluder(occlusion_layer); } @@ -1412,7 +1413,7 @@ Variant TileDataCollisionEditor::_get_painted_value() { } void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); polygon_editor->clear_polygons(); @@ -1438,7 +1439,7 @@ void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_ } void TileDataCollisionEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Dictionary dict = p_value; @@ -1457,7 +1458,7 @@ void TileDataCollisionEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_so } Variant TileDataCollisionEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND_V(!tile_data, Variant()); Dictionary dict; @@ -1659,7 +1660,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas hovered_coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_pos); hovered_coords = p_tile_set_atlas_source->get_tile_at_coords(hovered_coords); if (hovered_coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(hovered_coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(hovered_coords, 0); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(hovered_coords); Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, 0); @@ -1698,7 +1699,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas for (int i = 0; i < p_tile_set_atlas_source->get_tiles_count(); i++) { Vector2i coords = p_tile_set_atlas_source->get_tile_id(i); if (coords != hovered_coords) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); if (tile_data->get_terrain_set() != int(dummy_object->get("terrain_set"))) { // Dimming p_canvas_item->draw_set_transform_matrix(p_transform); @@ -1772,7 +1773,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas Vector2i coords = Vector2i(x, y); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); if (tile_data->get_terrain_set() == terrain_set) { TileMapCell cell; cell.source_id = 0; @@ -1833,7 +1834,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til hovered_coords = Vector2i(hovered.x, hovered.y); hovered_alternative = hovered.z; if (hovered_coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(hovered_coords, hovered_alternative)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(hovered_coords, hovered_alternative); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(hovered_coords, hovered_alternative); Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, hovered_alternative); @@ -1874,7 +1875,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til for (int j = 1; j < p_tile_set_atlas_source->get_alternative_tiles_count(coords); j++) { int alternative_tile = p_tile_set_atlas_source->get_alternative_tile_id(coords, j); if (coords != hovered_coords || alternative_tile != hovered_alternative) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); if (tile_data->get_terrain_set() != int(dummy_object->get("terrain_set"))) { // Dimming p_canvas_item->draw_set_transform_matrix(p_transform); @@ -1918,7 +1919,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t cell.alternative_tile = 0; // Save the old terrain_set and terrains bits. - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); if (!drag_modified.has(cell)) { Dictionary dict; dict["terrain_set"] = tile_data->get_terrain_set(); @@ -1948,7 +1949,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t cell.set_atlas_coords(coords); cell.alternative_tile = 0; - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); if (tile_data->get_terrain_set() == terrain_set) { // Save the old terrain_set and terrains bits. if (!drag_modified.has(cell)) { @@ -1990,7 +1991,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position()); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); @@ -2014,7 +2015,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t coords = p_tile_set_atlas_source->get_tile_at_coords(coords); TileData *tile_data = nullptr; if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { - tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); } int terrain_set = int(dummy_object->get("terrain_set")); int terrain = int(dummy_object->get("terrain")); @@ -2131,7 +2132,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t undo_redo->create_action(TTR("Painting Terrain Set")); for (Set<TileMapCell>::Element *E = edited.front(); E; E = E->next()) { Vector2i coords = E->get().get_atlas_coords(); - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->get().alternative_tile), tile_data->get_terrain_set()); undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->get().alternative_tile), drag_painted_value); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { @@ -2197,7 +2198,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t Vector2i coords = Vector2i(x, y); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); if (tile_data->get_terrain_set() == terrain_set) { TileMapCell cell; cell.source_id = 0; @@ -2218,7 +2219,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t undo_redo->create_action(TTR("Painting Terrain")); for (Set<TileMapCell>::Element *E = edited.front(); E; E = E->next()) { Vector2i coords = E->get().get_atlas_coords(); - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); @@ -2259,7 +2260,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi cell.source_id = 0; cell.set_atlas_coords(coords); cell.alternative_tile = alternative_tile; - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); if (!drag_modified.has(cell)) { Dictionary dict; dict["terrain_set"] = tile_data->get_terrain_set(); @@ -2291,7 +2292,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi cell.alternative_tile = alternative_tile; // Save the old terrain_set and terrains bits. - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); if (tile_data->get_terrain_set() == terrain_set) { if (!drag_modified.has(cell)) { Dictionary dict; @@ -2333,7 +2334,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi int alternative_tile = tile.z; if (coords != TileSetSource::INVALID_ATLAS_COORDS) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); @@ -2360,7 +2361,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi Vector2i coords = Vector2i(tile.x, tile.y); int alternative_tile = tile.z; - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile); if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) { drag_type = DRAG_TYPE_PAINT_TERRAIN_SET; @@ -2539,7 +2540,7 @@ Variant TileDataNavigationEditor::_get_painted_value() { } void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(navigation_layer); @@ -2553,7 +2554,7 @@ void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set } void TileDataNavigationEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND(!tile_data); Ref<NavigationPolygon> navigation_polygon = p_value; tile_data->set_navigation_polygon(navigation_layer, navigation_polygon); @@ -2562,7 +2563,7 @@ void TileDataNavigationEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_s } Variant TileDataNavigationEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { - TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); + TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile); ERR_FAIL_COND_V(!tile_data, Variant()); return tile_data->get_navigation_polygon(navigation_layer); } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index aa92920722..b878494559 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -124,6 +124,10 @@ void TileMapEditorTilesPlugin::_tab_changed() { void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { // Update the sources. int old_current = sources_list->get_current(); + int old_source = -1; + if (old_current > -1) { + old_source = sources_list->get_item_metadata(old_current); + } sources_list->clear(); TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); @@ -136,9 +140,12 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { return; } - for (int i = 0; i < tile_set->get_source_count(); i++) { - int source_id = tile_set->get_source_id(i); + if (!tile_set->has_source(old_source)) { + old_source = -1; + } + List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set); + for (const int &source_id : source_ids) { TileSetSource *source = *tile_set->get_source(source_id); Ref<Texture2D> texture; @@ -157,7 +164,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { if (texture.is_valid()) { item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id); } else { - item_text = vformat("No Texture Atlas Source (ID: %d)", source_id); + item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id); } } } @@ -180,20 +187,25 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { } sources_list->add_item(item_text, texture); - sources_list->set_item_metadata(i, source_id); + sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id); } if (sources_list->get_item_count() > 0) { - if (old_current > 0) { - // Keep the current selected item if needed. - sources_list->set_current(CLAMP(old_current, 0, sources_list->get_item_count() - 1)); + if (old_source >= 0) { + for (int i = 0; i < sources_list->get_item_count(); i++) { + if ((int)sources_list->get_item_metadata(i) == old_source) { + sources_list->set_current(i); + sources_list->ensure_current_is_visible(); + break; + } + } } else { sources_list->set_current(0); } sources_list->emit_signal(SNAME("item_selected"), sources_list->get_current()); } - // Synchronize + // Synchronize the lists. TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current()); } @@ -439,6 +451,7 @@ void TileMapEditorTilesPlugin::_scenes_list_nothing_selected() { } void TileMapEditorTilesPlugin::_update_theme() { + source_sort_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); select_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons"))); paint_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons"))); line_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons"))); @@ -835,9 +848,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Fade out the border of the grid. float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f); float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); Transform2D tile_xform; @@ -864,7 +877,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { // Get tile data. - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile)); + TileData *tile_data = atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile); // Compute the offset Rect2i source_rect = atlas_source->get_tile_texture_region(E.value.get_atlas_coords()); @@ -936,7 +949,7 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(Ref<TileMapPattern> p_pa TileSetSource *source = *tile_set->get_source(source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile)); + TileData *tile_data = atlas_source->get_tile_data(atlas_coords, alternative_tile); ERR_FAIL_COND_V(!tile_data, TileMapCell()); sum += tile_data->get_probability(); } else { @@ -955,7 +968,7 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(Ref<TileMapPattern> p_pa TileSetSource *source = *tile_set->get_source(source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { - current += Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile))->get_probability(); + current += atlas_source->get_tile_data(atlas_coords, alternative_tile)->get_probability(); } else { current += 1.0; } @@ -1950,6 +1963,14 @@ void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer tile_map_layer = p_tile_map_layer; } +void TileMapEditorTilesPlugin::_set_source_sort(int p_sort) { + for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) { + source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort)); + } + TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort); + _update_tile_set_sources_list(); +} + void TileMapEditorTilesPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("_scene_thumbnail_done"), &TileMapEditorTilesPlugin::_scene_thumbnail_done); ClassDB::bind_method(D_METHOD("_set_tile_map_selection", "selection"), &TileMapEditorTilesPlugin::_set_tile_map_selection); @@ -2106,17 +2127,44 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { atlas_sources_split_container->set_v_size_flags(Control::SIZE_EXPAND_FILL); tiles_bottom_panel->add_child(atlas_sources_split_container); + VBoxContainer *split_container_left_side = memnew(VBoxContainer); + split_container_left_side->set_h_size_flags(Control::SIZE_EXPAND_FILL); + split_container_left_side->set_v_size_flags(Control::SIZE_EXPAND_FILL); + split_container_left_side->set_stretch_ratio(0.25); + split_container_left_side->set_custom_minimum_size(Size2i(70, 0) * EDSCALE); + atlas_sources_split_container->add_child(split_container_left_side); + + HBoxContainer *sources_bottom_actions = memnew(HBoxContainer); + sources_bottom_actions->set_alignment(HBoxContainer::ALIGNMENT_END); + + source_sort_button = memnew(MenuButton); + source_sort_button->set_flat(true); + source_sort_button->set_tooltip(TTR("Sort sources")); + + PopupMenu *p = source_sort_button->get_popup(); + 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 (Descending)"), TilesEditorPlugin::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 (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE); + p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true); + sources_bottom_actions->add_child(source_sort_button); + sources_list = memnew(ItemList); sources_list->set_fixed_icon_size(Size2i(60, 60) * EDSCALE); sources_list->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sources_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); sources_list->set_stretch_ratio(0.25); sources_list->set_custom_minimum_size(Size2i(70, 0) * EDSCALE); 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_source_display).unbind(1)); sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list)); - atlas_sources_split_container->add_child(sources_list); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button)); + sources_list->add_user_signal(MethodInfo("sort_request")); + 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_bottom_actions); // Tile atlas source. tile_atlas_view = memnew(TileAtlasView); @@ -2427,7 +2475,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p Ref<TileSetSource> source = tile_set->get_source(source_cell.source_id); Ref<TileSetAtlasSource> atlas_source = source; if (atlas_source.is_valid()) { - tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(source_cell.get_atlas_coords(), source_cell.alternative_tile)); + tile_data = atlas_source->get_tile_data(source_cell.get_atlas_coords(), source_cell.alternative_tile); } if (!tile_data) { return Set<Vector2i>(); @@ -2458,7 +2506,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p Ref<TileSetSource> source = tile_set->get_source(tile_map->get_cell_source_id(tile_map_layer, coords)); Ref<TileSetAtlasSource> atlas_source = source; if (atlas_source.is_valid()) { - tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords))); + tile_data = atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords)); } if (tile_data) { candidate_pattern = tile_data->get_terrains_pattern(); @@ -2503,7 +2551,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p Ref<TileSetSource> source = tile_set->get_source(tile_map->get_cell_source_id(tile_map_layer, coords)); Ref<TileSetAtlasSource> atlas_source = source; if (atlas_source.is_valid()) { - tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords))); + tile_data = atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords)); } if (tile_data) { candidate_pattern = tile_data->get_terrains_pattern(); @@ -2569,7 +2617,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() { Ref<TileSetSource> source = tile_set->get_source(cell.source_id); Ref<TileSetAtlasSource> atlas_source = source; if (atlas_source.is_valid()) { - tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile)); + tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile); } if (tile_data) { @@ -2948,9 +2996,9 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o // Fade out the border of the grid. float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f); float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); Transform2D tile_xform; @@ -3010,7 +3058,7 @@ void TileMapEditorTerrainsPlugin::_update_terrains_cache() { for (int alternative_index = 0; alternative_index < source->get_alternative_tiles_count(tile_id); alternative_index++) { int alternative_id = source->get_alternative_tile_id(tile_id, alternative_index); - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id)); + TileData *tile_data = atlas_source->get_tile_data(tile_id, alternative_id); int terrain_set = tile_data->get_terrain_set(); if (terrain_set >= 0) { ERR_FAIL_INDEX(terrain_set, (int)per_terrain_terrains_patterns.size()); @@ -3138,7 +3186,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { Ref<TileSetAtlasSource> atlas_source = source; if (atlas_source.is_valid()) { - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile)); + TileData *tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile); if (tile_data->get_probability() > max_probability) { icon = atlas_source->get_texture(); region = atlas_source->get_tile_texture_region(cell.get_atlas_coords()); @@ -3687,7 +3735,7 @@ void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_ String str = pi.name.trim_prefix(p_array_prefix); int to_char_index = 0; while (to_char_index < str.length()) { - if (str[to_char_index] < '0' || str[to_char_index] > '9') { + if (!is_digit(str[to_char_index])) { break; } to_char_index++; @@ -3833,9 +3881,9 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { // Fade out the border of the grid. float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f); float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); Transform2D tile_xform; diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index b1bee03211..6fa0d01612 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -145,6 +145,7 @@ private: Label *invalid_source_label; ItemList *sources_list; + MenuButton *source_sort_button; Ref<Texture2D> missing_atlas_texture_icon; void _update_tile_set_sources_list(); @@ -170,6 +171,7 @@ private: void _tile_alternatives_control_gui_input(const Ref<InputEvent> &p_event); void _update_atlas_view(); + void _set_source_sort(int p_sort); // Scenes collection sources. ItemList *scene_tiles_list; diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index c4cc9745ee..e708b83440 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -274,7 +274,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na const int &alternative = E->get().alternative; bool valid = false; - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); ERR_FAIL_COND_V(!tile_data, false); tile_data->set(p_name, p_value, &valid); @@ -359,7 +359,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_get(const StringName &p_na const Vector2i &coords = E->get().tile; const int &alternative = E->get().alternative; - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); ERR_FAIL_COND_V(!tile_data, false); bool valid = false; @@ -432,7 +432,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro const Vector2i &coords = E->get().tile; const int &alternative = E->get().alternative; - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); ERR_FAIL_COND(!tile_data); List<PropertyInfo> list; @@ -486,7 +486,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(TileSetAtlasSource *p_ const int &alternative = E->get().alternative; if (tile_set_atlas_source && tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) { - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); if (tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { tile_data->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); } @@ -502,7 +502,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(TileSetAtlasSource *p_ const int &alternative = E->get().alternative; if (tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) { - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); if (!tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { tile_data->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); } @@ -2609,7 +2609,7 @@ void EditorPropertyTilePolygon::update_property() { // Set the background Vector2i coords = atlas_tile_proxy_object->get_edited_tiles().front()->get().tile; int alternative = atlas_tile_proxy_object->get_edited_tiles().front()->get().alternative; - TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative)); + TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative); generic_tile_polygon_editor->set_background(tile_set_atlas_source->get_texture(), tile_set_atlas_source->get_tile_texture_region(coords), tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate()); // Reset the polygons. diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index ef8d423724..ab355d4658 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -137,9 +137,8 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { sources_list->clear(); // Update the atlas sources. - for (int i = 0; i < tile_set->get_source_count(); i++) { - int source_id = tile_set->get_source_id(i); - + List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set); + for (const int &source_id : source_ids) { TileSetSource *source = *tile_set->get_source(source_id); Ref<Texture2D> texture; @@ -156,9 +155,9 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { texture = atlas_source->get_texture(); if (item_text.is_empty()) { if (texture.is_valid()) { - item_text = vformat("%s (ID:%d)", texture->get_path().get_file(), source_id); + item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id); } else { - item_text = vformat(TTR("No Texture Atlas Source (ID:%d)"), source_id); + item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id); } } } @@ -168,20 +167,20 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { if (scene_collection_source) { texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); if (item_text.is_empty()) { - item_text = vformat(TTR("Scene Collection Source (ID:%d)"), source_id); + item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id); } } // Use default if not valid. if (item_text.is_empty()) { - item_text = vformat(TTR("Unknown Type Source (ID:%d)"), source_id); + item_text = vformat(TTR("Unknown Type Source (ID: %d)"), source_id); } if (!texture.is_valid()) { texture = missing_texture_texture; } sources_list->add_item(item_text, texture); - sources_list->set_item_metadata(i, source_id); + sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id); } // Set again the current selected item if needed. @@ -189,6 +188,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) { for (int i = 0; i < sources_list->get_item_count(); i++) { if ((int)sources_list->get_item_metadata(i) == to_select) { sources_list->set_current(i); + sources_list->ensure_current_is_visible(); if (old_selected != to_select) { sources_list->emit_signal(SNAME("item_selected"), sources_list->get_current()); } @@ -312,12 +312,29 @@ void TileSetEditor::_sources_advanced_menu_id_pressed(int p_id_pressed) { } } +void TileSetEditor::_set_source_sort(int p_sort) { + TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort); + for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) { + source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort)); + } + + int old_selected = TileSet::INVALID_SOURCE; + if (sources_list->get_current() >= 0) { + int source_id = sources_list->get_item_metadata(sources_list->get_current()); + if (tile_set->has_source(source_id)) { + old_selected = source_id; + } + } + _update_sources_list(old_selected); +} + void TileSetEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: sources_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); sources_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + source_sort_button->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons"))); sources_advanced_menu_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); missing_texture_texture = get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons")); break; @@ -441,7 +458,7 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ String str = pi.name.trim_prefix(p_array_prefix); int to_char_index = 0; while (to_char_index < str.length()) { - if (str[to_char_index] < '0' || str[to_char_index] > '9') { + if (!is_digit(str[to_char_index])) { break; } to_char_index++; @@ -465,7 +482,7 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_ Vector2i tile_id = tas->get_tile_id(j); for (int k = 0; k < tas->get_alternative_tiles_count(tile_id); k++) { int alternative_id = tas->get_alternative_tile_id(tile_id, k); - TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id)); + TileData *tile_data = tas->get_tile_data(tile_id, alternative_id); ERR_FAIL_COND(!tile_data); // Actually saving stuff. @@ -584,7 +601,7 @@ void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p Vector2i tile_id = tas->get_tile_id(j); for (int k = 0; k < tas->get_alternative_tiles_count(tile_id); k++) { int alternative_id = tas->get_alternative_tile_id(tile_id, k); - TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id)); + TileData *tile_data = tas->get_tile_data(tile_id, alternative_id); ERR_FAIL_COND(!tile_data); if (components.size() == 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "mode") { @@ -670,13 +687,27 @@ TileSetEditor::TileSetEditor() { split_container_left_side->set_custom_minimum_size(Size2i(70, 0) * EDSCALE); split_container->add_child(split_container_left_side); + source_sort_button = memnew(MenuButton); + source_sort_button->set_flat(true); + source_sort_button->set_tooltip(TTR("Sort sources")); + + PopupMenu *p = source_sort_button->get_popup(); + 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 (Descending)"), TilesEditorPlugin::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 (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE); + p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true); + sources_list = memnew(ItemList); sources_list->set_fixed_icon_size(Size2i(60, 60) * EDSCALE); sources_list->set_h_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(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current)); - sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list)); + sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button)); + sources_list->add_user_signal(MethodInfo("sort_request")); + sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list), varray(-1)); sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_drag_forwarding(this); split_container_left_side->add_child(sources_list); @@ -704,6 +735,7 @@ TileSetEditor::TileSetEditor() { sources_advanced_menu_button->get_popup()->add_item(TTR("Manage Tile Proxies")); sources_advanced_menu_button->get_popup()->connect("id_pressed", callable_mp(this, &TileSetEditor::_sources_advanced_menu_id_pressed)); sources_bottom_actions->add_child(sources_advanced_menu_button); + sources_bottom_actions->add_child(source_sort_button); atlas_merging_dialog = memnew(AtlasMergingDialog); add_child(atlas_merging_dialog); diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index 98ebbae02f..a21c951c42 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -67,6 +67,7 @@ private: // Sources management. Button *sources_delete_button; MenuButton *sources_add_button; + MenuButton *source_sort_button; MenuButton *sources_advanced_menu_button; ItemList *sources_list; Ref<Texture2D> missing_texture_texture; @@ -74,6 +75,7 @@ private: void _source_delete_pressed(); void _source_add_id_pressed(int p_id_pressed); void _sources_advanced_menu_id_pressed(int p_id_pressed); + void _set_source_sort(int p_sort); AtlasMergingDialog *atlas_merging_dialog; TileProxiesManagerDialog *tile_proxies_manager_dialog; diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index cdde22f5bc..4c644f33d4 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -166,8 +166,6 @@ void TilesEditorPlugin::_update_editors() { editor_node->hide_bottom_panel(); } } - tileset_editor_button->set_visible(tile_set.is_valid()); - tilemap_editor_button->set_visible(tile_map); } void TilesEditorPlugin::_notification(int p_what) { @@ -218,15 +216,29 @@ void TilesEditorPlugin::set_sources_lists_current(int p_current) { atlas_sources_lists_current = p_current; } -void TilesEditorPlugin::synchronize_sources_list(Object *p_current) { - ItemList *item_list = Object::cast_to<ItemList>(p_current); +void TilesEditorPlugin::synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button) { + ItemList *item_list = Object::cast_to<ItemList>(p_current_list); + MenuButton *sorting_button = Object::cast_to<MenuButton>(p_current_sort_button); ERR_FAIL_COND(!item_list); + ERR_FAIL_COND(!sorting_button); + + if (sorting_button->is_visible_in_tree()) { + for (int i = 0; i != SOURCE_SORT_MAX; i++) { + sorting_button->get_popup()->set_item_checked(i, (i == (int)source_sort)); + } + } if (item_list->is_visible_in_tree()) { if (atlas_sources_lists_current < 0 || atlas_sources_lists_current >= item_list->get_item_count()) { item_list->deselect_all(); } else { + // Make sure the selection is not overwritten after sorting. + int atlas_sources_lists_current_mem = atlas_sources_lists_current; + item_list->emit_signal(SNAME("sort_request")); + atlas_sources_lists_current = atlas_sources_lists_current_mem; + item_list->set_current(atlas_sources_lists_current); + item_list->ensure_current_is_visible(); item_list->emit_signal(SNAME("item_selected"), atlas_sources_lists_current); } } @@ -246,6 +258,87 @@ void TilesEditorPlugin::synchronize_atlas_view(Object *p_current) { } } +void TilesEditorPlugin::set_sorting_option(int p_option) { + source_sort = p_option; +} + +List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> tile_set) const { + SourceNameComparator::tile_set = tile_set; + List<int> source_ids; + + for (int i = 0; i < tile_set->get_source_count(); i++) { + source_ids.push_back(tile_set->get_source_id(i)); + } + + switch (source_sort) { + case SOURCE_SORT_ID_REVERSE: + // Already sorted. + source_ids.reverse(); + break; + case SOURCE_SORT_NAME: + source_ids.sort_custom<SourceNameComparator>(); + break; + case SOURCE_SORT_NAME_REVERSE: + source_ids.sort_custom<SourceNameComparator>(); + source_ids.reverse(); + break; + default: // SOURCE_SORT_ID + break; + } + + SourceNameComparator::tile_set.unref(); + return source_ids; +} + +Ref<TileSet> TilesEditorPlugin::SourceNameComparator::tile_set; + +bool TilesEditorPlugin::SourceNameComparator::operator()(const int &p_a, const int &p_b) const { + String name_a; + String name_b; + + { + TileSetSource *source = *tile_set->get_source(p_a); + + if (!source->get_name().is_empty()) { + name_a = source->get_name(); + } + + TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + if (atlas_source) { + Ref<Texture2D> texture = atlas_source->get_texture(); + if (name_a.is_empty() && texture.is_valid()) { + name_a = texture->get_path().get_file(); + } + } + + if (name_a.is_empty()) { + name_a = itos(p_a); + } + } + + { + TileSetSource *source = *tile_set->get_source(p_b); + + if (!source->get_name().is_empty()) { + name_b = source->get_name(); + } + + TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + if (atlas_source) { + Ref<Texture2D> texture = atlas_source->get_texture(); + if (name_b.is_empty() && texture.is_valid()) { + name_b = texture->get_path().get_file(); + } + } + + if (name_b.is_empty()) { + name_b = itos(p_b); + } + } + + return NaturalNoCaseComparator()(name_a, name_b); +} + void TilesEditorPlugin::edit(Object *p_object) { // Disconnect to changes. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index 59eb79480e..487436b98a 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -43,6 +43,15 @@ class TilesEditorPlugin : public EditorPlugin { static TilesEditorPlugin *singleton; +public: + enum SourceSortOption { + SOURCE_SORT_ID = 0, + SOURCE_SORT_ID_REVERSE, + SOURCE_SORT_NAME, + SOURCE_SORT_NAME_REVERSE, + SOURCE_SORT_MAX + }; + private: EditorNode *editor_node; @@ -65,6 +74,14 @@ private: void _tile_map_changed(); + // Source sorting. + int source_sort = SOURCE_SORT_ID; + + struct SourceNameComparator { + static Ref<TileSet> tile_set; + bool operator()(const int &p_a, const int &p_b) const; + }; + // Patterns preview generation. struct QueueItem { Ref<TileSet> tile_set; @@ -97,11 +114,15 @@ public: // To synchronize the atlas sources lists. void set_sources_lists_current(int p_current); - void synchronize_sources_list(Object *p_current); + void synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button); void set_atlas_view_transform(float p_zoom, Vector2 p_scroll); void synchronize_atlas_view(Object *p_current); + // Sorting. + void set_sorting_option(int p_option); + List<int> get_sorted_sources(const Ref<TileSet> tile_set) const; + virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override; |