summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/android_builds.yml4
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp38
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h4
-rw-r--r--platform/android/java/app/config.gradle2
-rw-r--r--scene/gui/popup_menu.cpp14
-rw-r--r--scene/gui/spin_box.cpp9
-rw-r--r--scene/gui/spin_box.h3
-rw-r--r--scene/main/canvas_item.cpp27
-rw-r--r--scene/resources/tile_set.cpp117
-rw-r--r--scene/resources/tile_set.h3
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: