diff options
-rw-r--r-- | .github/workflows/android_builds.yml | 4 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 38 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.h | 4 | ||||
-rw-r--r-- | platform/android/java/app/config.gradle | 2 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 14 | ||||
-rw-r--r-- | scene/gui/spin_box.cpp | 9 | ||||
-rw-r--r-- | scene/gui/spin_box.h | 3 | ||||
-rw-r--r-- | scene/main/canvas_item.cpp | 27 | ||||
-rw-r--r-- | scene/resources/tile_set.cpp | 117 | ||||
-rw-r--r-- | scene/resources/tile_set.h | 3 |
10 files changed, 164 insertions, 57 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index ea97ef023d..495f643e56 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -20,11 +20,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Java 11 + - name: Set up Java 17 uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index f41b1d30d7..01e9eb7a49 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -870,13 +870,10 @@ void SpriteFramesEditor::_sync_animation() { } void SpriteFramesEditor::_select_animation(const String &p_name, bool p_update_node) { - TreeItem *selected = nullptr; - selected = animations->get_item_with_text(p_name); - if (!selected) { + if (!frames->has_animation(p_name)) { return; - }; - - edited_anim = selected->get_text(0); + } + edited_anim = p_name; if (animated_sprite) { if (p_update_node) { @@ -951,6 +948,7 @@ void SpriteFramesEditor::_animation_name_edited() { counter++; name = new_name + "_" + itos(counter); } + edited->set_text(0, name); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(TTR("Rename Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); @@ -958,11 +956,12 @@ void SpriteFramesEditor::_animation_name_edited() { undo_redo->add_undo_method(frames.ptr(), "rename_animation", name, edited_anim); _rename_node_animation(undo_redo, false, edited_anim, name, name); _rename_node_animation(undo_redo, true, edited_anim, edited_anim, edited_anim); + undo_redo->add_do_method(this, "_select_animation", name); + undo_redo->add_undo_method(this, "_select_animation", edited_anim); undo_redo->add_do_method(this, "_update_library"); undo_redo->add_undo_method(this, "_update_library"); undo_redo->commit_action(); - _select_animation(name); animations->grab_focus(); } @@ -1007,11 +1006,12 @@ void SpriteFramesEditor::_animation_add() { undo_redo->create_action(TTR("Add Animation"), UndoRedo::MERGE_DISABLE, EditorNode::get_singleton()->get_edited_scene()); undo_redo->add_do_method(frames.ptr(), "add_animation", name); undo_redo->add_undo_method(frames.ptr(), "remove_animation", name); + undo_redo->add_do_method(this, "_select_animation", name); + undo_redo->add_undo_method(this, "_select_animation", edited_anim); undo_redo->add_do_method(this, "_update_library"); undo_redo->add_undo_method(this, "_update_library"); undo_redo->commit_action(); - _select_animation(name); animations->grab_focus(); } @@ -1057,11 +1057,11 @@ void SpriteFramesEditor::_animation_remove_confirmed() { float duration = frames->get_frame_duration(edited_anim, i); undo_redo->add_undo_method(frames.ptr(), "add_frame", edited_anim, texture, duration); } + undo_redo->add_do_method(this, "_select_animation", new_edited); + undo_redo->add_undo_method(this, "_select_animation", edited_anim); undo_redo->add_do_method(this, "_update_library"); undo_redo->add_undo_method(this, "_update_library"); undo_redo->commit_action(); - - _select_animation(new_edited); } void SpriteFramesEditor::_animation_search_text_changed(const String &p_text) { @@ -1179,6 +1179,20 @@ void SpriteFramesEditor::_zoom_reset() { } void SpriteFramesEditor::_update_library(bool p_skip_selector) { + if (!p_skip_selector) { + animations_dirty = true; + } + + if (pending_update) { + return; + } + pending_update = true; + callable_mp(this, &SpriteFramesEditor::_update_library_impl).call_deferred(); +} + +void SpriteFramesEditor::_update_library_impl() { + pending_update = false; + if (frames.is_null()) { return; } @@ -1187,7 +1201,8 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { frame_duration->set_value_no_signal(1.0); // Default. - if (!p_skip_selector) { + if (animations_dirty) { + animations_dirty = false; animations->clear(); TreeItem *anim_root = animations->create_item(); @@ -1624,6 +1639,7 @@ void SpriteFramesEditor::_autoplay_pressed() { void SpriteFramesEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_library", "skipsel"), &SpriteFramesEditor::_update_library, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("_select_animation", "name", "update_node"), &SpriteFramesEditor::_select_animation, DEFVAL(true)); } void SpriteFramesEditor::_node_removed(Node *p_node) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index ed75be9061..f14c2203df 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -189,6 +189,7 @@ class SpriteFramesEditor : public HSplitContainer { void _down_pressed(); void _frame_duration_changed(double p_value); void _update_library(bool p_skip_selector = false); + void _update_library_impl(); void _update_stop_icon(); void _play_pressed(); @@ -214,6 +215,9 @@ class SpriteFramesEditor : public HSplitContainer { void _zoom_out(); void _zoom_reset(); + bool animations_dirty = false; + bool pending_update = false; + bool updating; bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code. diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index e7c06628c8..a91e7bc7ce 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -9,7 +9,7 @@ ext.versions = [ kotlinVersion : '1.7.0', fragmentVersion : '1.3.6', nexusPublishVersion: '1.1.0', - javaVersion : 11, + javaVersion : 17, // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. ndkVersion : '23.2.8568313' diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 2e4a35e1d3..28f5ed7dfd 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -711,9 +711,9 @@ void PopupMenu::_draw_items() { // Separator item_ofs.x += items[i].indent * theme_cache.indent; if (items[i].separator) { - if (!text.is_empty() || !items[i].icon.is_null()) { + if (!text.is_empty() || items[i].icon.is_valid()) { int content_size = items[i].text_buf->get_size().width + theme_cache.h_separation * 2; - if (!items[i].icon.is_null()) { + if (items[i].icon.is_valid()) { content_size += icon_size.width + theme_cache.h_separation; } @@ -742,7 +742,9 @@ void PopupMenu::_draw_items() { icon_color *= items[i].icon_modulate; // For non-separator items, add some padding for the content. - item_ofs.x += theme_cache.item_start_padding; + if (!items[i].separator) { + item_ofs.x += theme_cache.item_start_padding; + } // Checkboxes if (items[i].checkable_type && !items[i].separator) { @@ -758,7 +760,7 @@ void PopupMenu::_draw_items() { int separator_ofs = (display_width - items[i].text_buf->get_size().width) / 2; // Icon - if (!items[i].icon.is_null()) { + if (items[i].icon.is_valid()) { const Point2 icon_offset = Point2(0, Math::floor((h - icon_size.height) / 2.0)); Point2 icon_pos; @@ -769,6 +771,7 @@ void PopupMenu::_draw_items() { icon_pos = Size2(control->get_size().width - item_ofs.x - separator_ofs - icon_size.width, item_ofs.y); } else { icon_pos = item_ofs + Size2(separator_ofs, 0); + separator_ofs += icon_size.width + theme_cache.h_separation; } } else { if (rtl) { @@ -794,9 +797,6 @@ void PopupMenu::_draw_items() { if (items[i].separator) { if (!text.is_empty()) { Vector2 text_pos = Point2(separator_ofs, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); - if (!rtl && !items[i].icon.is_null()) { - text_pos.x += icon_size.width + theme_cache.h_separation; - } if (theme_cache.font_separator_outline_size > 0 && theme_cache.font_separator_outline_color.a > 0) { items[i].text_buf->draw_outline(ci, text_pos, theme_cache.font_separator_outline_size, theme_cache.font_separator_outline_color); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 26dbe1cb0c..bd549a6e4a 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -40,7 +40,7 @@ Size2 SpinBox::get_minimum_size() const { return ms; } -void SpinBox::_update_text() { +void SpinBox::_update_text(bool p_keep_line_edit) { String value = String::num(get_value(), Math::range_step_decimals(get_step())); if (is_localizing_numeral_system()) { value = TS->format_number(value); @@ -55,7 +55,12 @@ void SpinBox::_update_text() { } } + if (p_keep_line_edit && value == last_updated_text && value != line_edit->get_text()) { + return; + } + line_edit->set_text_with_selection(value); + last_updated_text = value; } void SpinBox::_text_submitted(const String &p_string) { @@ -245,7 +250,7 @@ inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) { void SpinBox::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - _update_text(); + _update_text(true); _adjust_width_for_icon(theme_cache.updown_icon); RID ci = get_canvas_item(); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index bbb1db637a..4d49626d71 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -46,12 +46,13 @@ class SpinBox : public Range { void _range_click_timeout(); void _release_mouse(); - void _update_text(); + void _update_text(bool p_keep_line_edit = false); void _text_submitted(const String &p_string); void _text_changed(const String &p_string); String prefix; String suffix; + String last_updated_text; double custom_arrow_step = 0.0; void _line_edit_input(const Ref<InputEvent> &p_event); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 8f38a6f6c8..a350b97bc8 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -1496,6 +1496,9 @@ CanvasItem::~CanvasItem() { void CanvasTexture::set_diffuse_texture(const Ref<Texture2D> &p_diffuse) { ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_diffuse.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); + if (diffuse_texture == p_diffuse) { + return; + } diffuse_texture = p_diffuse; RID tex_rid = diffuse_texture.is_valid() ? diffuse_texture->get_rid() : RID(); @@ -1508,9 +1511,13 @@ Ref<Texture2D> CanvasTexture::get_diffuse_texture() const { void CanvasTexture::set_normal_texture(const Ref<Texture2D> &p_normal) { ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_normal.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); + if (normal_texture == p_normal) { + return; + } normal_texture = p_normal; RID tex_rid = normal_texture.is_valid() ? normal_texture->get_rid() : RID(); RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_NORMAL, tex_rid); + emit_changed(); } Ref<Texture2D> CanvasTexture::get_normal_texture() const { return normal_texture; @@ -1518,9 +1525,13 @@ Ref<Texture2D> CanvasTexture::get_normal_texture() const { void CanvasTexture::set_specular_texture(const Ref<Texture2D> &p_specular) { ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_specular.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); + if (specular_texture == p_specular) { + return; + } specular_texture = p_specular; RID tex_rid = specular_texture.is_valid() ? specular_texture->get_rid() : RID(); RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_SPECULAR, tex_rid); + emit_changed(); } Ref<Texture2D> CanvasTexture::get_specular_texture() const { @@ -1528,8 +1539,12 @@ Ref<Texture2D> CanvasTexture::get_specular_texture() const { } void CanvasTexture::set_specular_color(const Color &p_color) { + if (specular == p_color) { + return; + } specular = p_color; RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess); + emit_changed(); } Color CanvasTexture::get_specular_color() const { @@ -1537,8 +1552,12 @@ Color CanvasTexture::get_specular_color() const { } void CanvasTexture::set_specular_shininess(real_t p_shininess) { + if (shininess == p_shininess) { + return; + } shininess = p_shininess; RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess); + emit_changed(); } real_t CanvasTexture::get_specular_shininess() const { @@ -1546,16 +1565,24 @@ real_t CanvasTexture::get_specular_shininess() const { } void CanvasTexture::set_texture_filter(CanvasItem::TextureFilter p_filter) { + if (texture_filter == p_filter) { + return; + } texture_filter = p_filter; RS::get_singleton()->canvas_texture_set_texture_filter(canvas_texture, RS::CanvasItemTextureFilter(p_filter)); + emit_changed(); } CanvasItem::TextureFilter CanvasTexture::get_texture_filter() const { return texture_filter; } void CanvasTexture::set_texture_repeat(CanvasItem::TextureRepeat p_repeat) { + if (texture_repeat == p_repeat) { + return; + } texture_repeat = p_repeat; RS::get_singleton()->canvas_texture_set_texture_repeat(canvas_texture, RS::CanvasItemTextureRepeat(p_repeat)); + emit_changed(); } CanvasItem::TextureRepeat CanvasTexture::get_texture_repeat() const { return texture_repeat; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index dce0d87d10..121d29b728 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -4758,30 +4758,18 @@ void TileSetAtlasSource::_queue_update_padded_texture() { call_deferred(SNAME("_update_padded_texture")); } -void TileSetAtlasSource::_update_padded_texture() { - if (!padded_texture_needs_update) { - return; - } - padded_texture_needs_update = false; - padded_texture = Ref<ImageTexture>(); +Ref<ImageTexture> TileSetAtlasSource::_create_padded_image_texture(const Ref<Texture2D> &p_source) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<ImageTexture>()); - if (!texture.is_valid()) { - return; - } - - if (!use_texture_padding) { - return; + Ref<Image> src_image = p_source->get_image(); + if (src_image.is_null()) { + Ref<ImageTexture> ret; + ret.instantiate(); + return ret; } Size2 size = get_atlas_grid_size() * (texture_region_size + Vector2i(2, 2)); - - Ref<Image> src = texture->get_image(); - - if (!src.is_valid()) { - return; - } - - Ref<Image> image = Image::create_empty(size.x, size.y, false, src->get_format()); + Ref<Image> image = Image::create_empty(size.x, size.y, false, src_image->get_format()); for (KeyValue<Vector2i, TileAlternativesData> kv : tiles) { for (int frame = 0; frame < (int)kv.value.animation_frames_durations.size(); frame++) { @@ -4797,24 +4785,89 @@ void TileSetAtlasSource::_update_padded_texture() { Vector2i frame_coords = kv.key + (kv.value.size_in_atlas + kv.value.animation_separation) * ((kv.value.animation_columns > 0) ? Vector2i(frame % kv.value.animation_columns, frame / kv.value.animation_columns) : Vector2i(frame, 0)); Vector2i base_pos = frame_coords * (texture_region_size + Vector2i(2, 2)) + Vector2i(1, 1); - image->blit_rect(*src, src_rect, base_pos); + image->blit_rect(*src_image, src_rect, base_pos); - image->blit_rect(*src, top_src_rect, base_pos + Vector2i(0, -1)); - image->blit_rect(*src, bottom_src_rect, base_pos + Vector2i(0, src_rect.size.y)); - image->blit_rect(*src, left_src_rect, base_pos + Vector2i(-1, 0)); - image->blit_rect(*src, right_src_rect, base_pos + Vector2i(src_rect.size.x, 0)); + image->blit_rect(*src_image, top_src_rect, base_pos + Vector2i(0, -1)); + image->blit_rect(*src_image, bottom_src_rect, base_pos + Vector2i(0, src_rect.size.y)); + image->blit_rect(*src_image, left_src_rect, base_pos + Vector2i(-1, 0)); + image->blit_rect(*src_image, right_src_rect, base_pos + Vector2i(src_rect.size.x, 0)); - image->set_pixelv(base_pos + Vector2i(-1, -1), src->get_pixelv(src_rect.position)); - image->set_pixelv(base_pos + Vector2i(src_rect.size.x, -1), src->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, 0))); - image->set_pixelv(base_pos + Vector2i(-1, src_rect.size.y), src->get_pixelv(src_rect.position + Vector2i(0, src_rect.size.y - 1))); - image->set_pixelv(base_pos + Vector2i(src_rect.size.x, src_rect.size.y), src->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, src_rect.size.y - 1))); + image->set_pixelv(base_pos + Vector2i(-1, -1), src_image->get_pixelv(src_rect.position)); + image->set_pixelv(base_pos + Vector2i(src_rect.size.x, -1), src_image->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, 0))); + image->set_pixelv(base_pos + Vector2i(-1, src_rect.size.y), src_image->get_pixelv(src_rect.position + Vector2i(0, src_rect.size.y - 1))); + image->set_pixelv(base_pos + Vector2i(src_rect.size.x, src_rect.size.y), src_image->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, src_rect.size.y - 1))); } } - if (!padded_texture.is_valid()) { - padded_texture.instantiate(); + return ImageTexture::create_from_image(image); +} + +void TileSetAtlasSource::_update_padded_texture() { + if (!padded_texture_needs_update) { + return; + } + padded_texture_needs_update = false; + + if (padded_texture.is_valid()) { + padded_texture->disconnect_changed(callable_mp(this, &TileSetAtlasSource::_queue_update_padded_texture)); + } + + padded_texture = Ref<CanvasTexture>(); + + if (texture.is_null()) { + return; + } + + if (!use_texture_padding) { + return; + } + + padded_texture.instantiate(); + + Ref<CanvasTexture> src_canvas_texture = texture; + if (src_canvas_texture.is_valid()) { + // Use all textures. + // Diffuse + Ref<Texture2D> src = src_canvas_texture->get_diffuse_texture(); + Ref<ImageTexture> image_texture; + if (src.is_valid()) { + image_texture = _create_padded_image_texture(src); + } else { + image_texture.instantiate(); + } + padded_texture->set_diffuse_texture(image_texture); + + // Normal + src = src_canvas_texture->get_normal_texture(); + image_texture.instantiate(); + if (src.is_valid()) { + image_texture = _create_padded_image_texture(src); + } else { + image_texture.instantiate(); + } + padded_texture->set_normal_texture(image_texture); + + // Specular + src = src_canvas_texture->get_specular_texture(); + image_texture.instantiate(); + if (src.is_valid()) { + image_texture = _create_padded_image_texture(src); + } else { + image_texture.instantiate(); + } + padded_texture->set_specular_texture(image_texture); + + // Other properties. + padded_texture->set_specular_color(src_canvas_texture->get_specular_color()); + padded_texture->set_specular_shininess(src_canvas_texture->get_specular_shininess()); + padded_texture->set_texture_filter(src_canvas_texture->get_texture_filter()); + padded_texture->set_texture_repeat(src_canvas_texture->get_texture_repeat()); + } else { + // Use only diffuse. + Ref<ImageTexture> image_texture = _create_padded_image_texture(texture); + padded_texture->set_diffuse_texture(image_texture); } - padded_texture->set_image(image); + padded_texture->connect_changed(callable_mp(this, &TileSetAtlasSource::_queue_update_padded_texture)); emit_changed(); } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 722d615b09..313c4df65d 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -641,9 +641,10 @@ private: void _create_coords_mapping_cache(Vector2i p_atlas_coords); bool use_texture_padding = true; - Ref<ImageTexture> padded_texture; + Ref<CanvasTexture> padded_texture; bool padded_texture_needs_update = false; void _queue_update_padded_texture(); + Ref<ImageTexture> _create_padded_image_texture(const Ref<Texture2D> &p_source); void _update_padded_texture(); protected: |