diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml index 348b4a58376..460ffbbb80a 100644 --- a/doc/classes/TextureRect.xml +++ b/doc/classes/TextureRect.xml @@ -10,15 +10,15 @@ https://godotengine.org/asset-library/asset/676 + + Defines how minimum size is determined based on the texture's size. See [enum ExpandMode] for options. + If [code]true[/code], texture is flipped horizontally. If [code]true[/code], texture is flipped vertically. - - If [code]true[/code], the size of the texture won't be considered for minimum size calculation, so the [TextureRect] can be shrunk down past the texture size. Useful for preventing [TextureRect]s from breaking GUI layout regardless of their texture size. - Controls the texture's behavior when resizing the node's bounding rectangle. See [enum StretchMode]. @@ -28,6 +28,24 @@ + + The minimum size will be equal to texture size, i.e. [TextureRect] can't be smaller than the texture. + + + The size of the texture won't be considered for minimum size calculation, so the [TextureRect] can be shrunk down past the texture size. + + + The height of the texture will be ignored. Minimum width will be equal to the current height. Useful for horizontal layouts, e.g. inside [HBoxContainer]. + + + Same as [constant EXPAND_FIT_WIDTH], but keeps texture's aspect ratio. + + + The width of the texture will be ignored. Minimum height will be equal to the current width. Useful for vertical layouts, e.g. inside [VBoxContainer]. + + + Same as [constant EXPAND_FIT_HEIGHT], but keeps texture's aspect ratio. + Scale to fit the node's bounding rectangle. diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 38934ae8a5d..e4730faf381 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -670,7 +670,7 @@ EditorProfiler::EditorProfiler() { variables->connect("item_edited", callable_mp(this, &EditorProfiler::_item_edited)); graph = memnew(TextureRect); - graph->set_ignore_texture_size(true); + graph->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); graph->set_mouse_filter(MOUSE_FILTER_STOP); graph->connect("draw", callable_mp(this, &EditorProfiler::_graph_tex_draw)); graph->connect("gui_input", callable_mp(this, &EditorProfiler::_graph_tex_input)); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 91d9204863b..1a06e85f900 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -798,7 +798,7 @@ EditorVisualProfiler::EditorVisualProfiler() { variables->connect("cell_selected", callable_mp(this, &EditorVisualProfiler::_item_selected)); graph = memnew(TextureRect); - graph->set_ignore_texture_size(true); + graph->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); graph->set_mouse_filter(MOUSE_FILTER_STOP); graph->connect("draw", callable_mp(this, &EditorVisualProfiler::_graph_tex_draw)); graph->connect("gui_input", callable_mp(this, &EditorVisualProfiler::_graph_tex_input)); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 6b733e11f73..81b2fff97ac 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -958,7 +958,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) { if (!p_hide_assign_button_controls) { preview_rect = memnew(TextureRect); - preview_rect->set_ignore_texture_size(true); + preview_rect->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); preview_rect->set_anchors_and_offsets_preset(PRESET_FULL_RECT); preview_rect->set_offset(SIDE_TOP, 1); preview_rect->set_offset(SIDE_BOTTOM, -1); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index c2dac83416d..9f2cfc8d9cb 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -293,7 +293,7 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() { preview = memnew(TextureRect); previews_vbox->add_child(preview); - preview->set_ignore_texture_size(true); + preview->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE)); preview->set_v_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index dfcf9256c41..c913a9b0ab1 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -316,7 +316,7 @@ void BoneMapper::create_editor() { profile_texture = memnew(TextureRect); profile_texture->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); - profile_texture->set_ignore_texture_size(true); + profile_texture->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); profile_texture->set_h_size_flags(Control::SIZE_FILL); profile_texture->set_v_size_flags(Control::SIZE_FILL); bone_mapper_field->add_child(profile_texture); diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.cpp b/editor/plugins/gradient_texture_2d_editor_plugin.cpp index 703a44403d7..e03353a67bf 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.cpp +++ b/editor/plugins/gradient_texture_2d_editor_plugin.cpp @@ -178,7 +178,7 @@ void GradientTexture2DEditorRect::_notification(int p_what) { GradientTexture2DEditorRect::GradientTexture2DEditorRect() { checkerboard = memnew(TextureRect); checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE); - checkerboard->set_ignore_texture_size(true); + checkerboard->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); checkerboard->set_draw_behind_parent(true); add_child(checkerboard, false, INTERNAL_MODE_FRONT); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 7603a5e55d2..f4ec026504f 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1551,7 +1551,7 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_vb->add_child(split_sheet_panel); split_sheet_preview = memnew(TextureRect); - split_sheet_preview->set_ignore_texture_size(true); + split_sheet_preview->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); split_sheet_preview->set_mouse_filter(MOUSE_FILTER_PASS); split_sheet_preview->connect("draw", callable_mp(this, &SpriteFramesEditor::_sheet_preview_draw)); split_sheet_preview->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_preview_input)); diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp index 2dab3fa2783..2fb624b7130 100644 --- a/editor/plugins/texture_editor_plugin.cpp +++ b/editor/plugins/texture_editor_plugin.cpp @@ -128,7 +128,7 @@ TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) { texture_display->set_texture(p_texture); texture_display->set_anchors_preset(TextureRect::PRESET_FULL_RECT); texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); - texture_display->set_ignore_texture_size(true); + texture_display->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); add_child(texture_display); if (p_show_metadata) { diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index 7edf6e3a309..deb1df42d35 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -300,7 +300,7 @@ AtlasMergingDialog::AtlasMergingDialog() { preview = memnew(TextureRect); preview->set_h_size_flags(Control::SIZE_EXPAND_FILL); preview->set_v_size_flags(Control::SIZE_EXPAND_FILL); - preview->set_ignore_texture_size(true); + preview->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); preview->hide(); preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); atlas_merging_right_panel->add_child(preview); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index b4ffc7d78dd..f3c607dabb2 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1233,7 +1233,7 @@ void ProjectList::load_project_icon(int p_index) { // The default project icon is 128×128 to look crisp on hiDPI displays, // but we want the actual displayed size to be 64×64 on loDPI displays. - item.control->icon->set_ignore_texture_size(true); + item.control->icon->set_expand_mode(TextureRect::EXPAND_IGNORE_SIZE); item.control->icon->set_custom_minimum_size(Size2(64, 64) * EDSCALE); item.control->icon->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index ac6d0cd453f..5a3f4af106f 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -110,22 +110,45 @@ void TextureRect::_notification(int p_what) { draw_texture_rect(texture, Rect2(offset, size), tile); } } break; + case NOTIFICATION_RESIZED: { + update_minimum_size(); + } break; } } Size2 TextureRect::get_minimum_size() const { - if (!ignore_texture_size && !texture.is_null()) { - return texture->get_size(); - } else { - return Size2(); + if (!texture.is_null()) { + switch (expand_mode) { + case EXPAND_KEEP_SIZE: { + return texture->get_size(); + } break; + case EXPAND_IGNORE_SIZE: { + return Size2(); + } break; + case EXPAND_FIT_WIDTH: { + return Size2(get_size().y, 0); + } break; + case EXPAND_FIT_WIDTH_PROPORTIONAL: { + real_t ratio = real_t(texture->get_width()) / texture->get_height(); + return Size2(get_size().y * ratio, 0); + } break; + case EXPAND_FIT_HEIGHT: { + return Size2(0, get_size().x); + } break; + case EXPAND_FIT_HEIGHT_PROPORTIONAL: { + real_t ratio = real_t(texture->get_height()) / texture->get_width(); + return Size2(0, get_size().x * ratio); + } break; + } } + return Size2(); } void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TextureRect::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &TextureRect::get_texture); - ClassDB::bind_method(D_METHOD("set_ignore_texture_size", "ignore"), &TextureRect::set_ignore_texture_size); - ClassDB::bind_method(D_METHOD("get_ignore_texture_size"), &TextureRect::get_ignore_texture_size); + ClassDB::bind_method(D_METHOD("set_expand_mode", "expand_mode"), &TextureRect::set_expand_mode); + ClassDB::bind_method(D_METHOD("get_expand_mode"), &TextureRect::get_expand_mode); ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureRect::set_flip_h); ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureRect::is_flipped_h); ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureRect::set_flip_v); @@ -134,11 +157,18 @@ void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_texture_size"), "set_ignore_texture_size", "get_ignore_texture_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "expand_mode", PROPERTY_HINT_ENUM, "Keep Size,Ignore Size,Fit Width,Fit Width Proportional,Fit Height,Fit Height Proportional"), "set_expand_mode", "get_expand_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); + BIND_ENUM_CONSTANT(EXPAND_KEEP_SIZE); + BIND_ENUM_CONSTANT(EXPAND_IGNORE_SIZE); + BIND_ENUM_CONSTANT(EXPAND_FIT_WIDTH); + BIND_ENUM_CONSTANT(EXPAND_FIT_WIDTH_PROPORTIONAL); + BIND_ENUM_CONSTANT(EXPAND_FIT_HEIGHT); + BIND_ENUM_CONSTANT(EXPAND_FIT_HEIGHT_PROPORTIONAL); + BIND_ENUM_CONSTANT(STRETCH_SCALE); BIND_ENUM_CONSTANT(STRETCH_TILE); BIND_ENUM_CONSTANT(STRETCH_KEEP); @@ -178,18 +208,18 @@ Ref TextureRect::get_texture() const { return texture; } -void TextureRect::set_ignore_texture_size(bool p_ignore) { - if (ignore_texture_size == p_ignore) { +void TextureRect::set_expand_mode(ExpandMode p_mode) { + if (expand_mode == p_mode) { return; } - ignore_texture_size = p_ignore; + expand_mode = p_mode; queue_redraw(); update_minimum_size(); } -bool TextureRect::get_ignore_texture_size() const { - return ignore_texture_size; +TextureRect::ExpandMode TextureRect::get_expand_mode() const { + return expand_mode; } void TextureRect::set_stretch_mode(StretchMode p_mode) { diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index c56fee91e1b..6f17ebd87fa 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -37,6 +37,15 @@ class TextureRect : public Control { GDCLASS(TextureRect, Control); public: + enum ExpandMode { + EXPAND_KEEP_SIZE, + EXPAND_IGNORE_SIZE, + EXPAND_FIT_WIDTH, + EXPAND_FIT_WIDTH_PROPORTIONAL, + EXPAND_FIT_HEIGHT, + EXPAND_FIT_HEIGHT_PROPORTIONAL, + }; + enum StretchMode { STRETCH_SCALE, STRETCH_TILE, @@ -48,10 +57,10 @@ public: }; private: - bool ignore_texture_size = false; bool hflip = false; bool vflip = false; Ref texture; + ExpandMode expand_mode = EXPAND_KEEP_SIZE; StretchMode stretch_mode = STRETCH_SCALE; void _texture_changed(); @@ -65,8 +74,8 @@ public: void set_texture(const Ref &p_tex); Ref get_texture() const; - void set_ignore_texture_size(bool p_ignore); - bool get_ignore_texture_size() const; + void set_expand_mode(ExpandMode p_mode); + ExpandMode get_expand_mode() const; void set_stretch_mode(StretchMode p_mode); StretchMode get_stretch_mode() const; @@ -81,6 +90,7 @@ public: ~TextureRect(); }; +VARIANT_ENUM_CAST(TextureRect::ExpandMode); VARIANT_ENUM_CAST(TextureRect::StretchMode); #endif // TEXTURE_RECT_H