Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add expand_mode (see TextureRect) to TextureButton #11624

Open
ch0m5 opened this issue Jan 23, 2025 · 3 comments
Open

Add expand_mode (see TextureRect) to TextureButton #11624

ch0m5 opened this issue Jan 23, 2025 · 3 comments

Comments

@ch0m5
Copy link

ch0m5 commented Jan 23, 2025

Describe the project you are working on

A cRPG with heavy quantities of UI.

Describe the problem or limitation you are having in your project

I want to place Buttons or TextureButtons (featuring an icon) that resize themselves to fit a parent container while keeping a 1:1 ratio. This is currently not possible without using minimum_size (which must be updated manually and is bothersome) or setting the texture file to a very specific size so that it doesn't need resizing at all and is used as is (bothersome too if the UI every changes sizes).

Describe the feature / enhancement and how it helps to overcome the problem or limitation

"expand_mode" is a feature in TextureRect that makes it easy to automatically adjust a Texture's size to a parent container, particularly with the fit_width and fit_height options, therefore making it unnecessary to rely on the Control's minimum_size to achieve desired layouts or having to prepare the image file at the exact desired size to avoid resizing altogether.

Currently the TextureButton (textures) does not feature this, yet it could be a useful and intuitive addition to make buttons that resize their textures according to their width or height. This is particularly useful when you need Buttons to resize their attached texture/icon to the container holding them.

Image

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Exact same behavior from TextureRect's expand_mode would be expected, just applied to TextureButton instead.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Yes. You can set the texture size to the very specific size you need and avoid resizing the image altogether, i.e. set ignore_texture_size to FALSE or set the Button's minimum_size to whichever size is needed.

However, this eliminates automatic-resizing, meaning I have to tweak either the texture or the Buttons min_size every time the UI changes size, which could be somewhat often when making test layouts or iterating on the UI.

Is there a reason why this should be core and not an add-on in the asset library?

Because it would be a somewhat simple added property to a core Node of Godot UI system (TextureButton).

@Jesusemora
Copy link

I want to place Buttons or TextureButtons (featuring an icon) that resize themselves to fit a parent container while keeping a 1:1 ratio. This is currently not possible without using minimum_size (which must be updated manually and is bothersome) or setting the texture file to a very specific size so that it doesn't need resizing at all and is used as is (bothersome too if the UI every changes sizes).

I don't understand what you are asking for. Godot's UI system allows creating any UI. maybe if you showed some picture of what you want to achieve we could help you more.

That said, TextureButton should be avoided, specially since you are making a game with a diegetic UI.
Instead use a theme on the first control node, all controls will inherit from this. To create buttons that have to be different use theme variations on each unique button.
Using a theme you can set a StyleBoxTexture for each state of the button style, and that will allow it to resize and fit better.
for example, you can use expand_margin and texture_margin to create a margin around the text or make the button bigger. You can also make it act as a 9rect and also repeat border and fill patterns.

"expand_mode" is a feature in TextureRect that makes it easy to automatically adjust a Texture's size to a parent container, particularly with the fit_width and fit_height options, therefore making it unnecessary to rely on the Control's minimum_size to achieve desired layouts or having to prepare the image file at the exact desired size to avoid resizing altogether.

all controls have expand in the layout part.
for fitting height and width, that depends on the container, usually we use VBoxContainer or HBoxContainer as parent as it can expand in only one direction.

@ch0m5
Copy link
Author

ch0m5 commented Jan 28, 2025

I don't understand what you are asking for.

To elaborate, TextureRect can resize itself according to the width or height of its holding container, that's what its expand_mode does. This is useful in situations where you would want other items to determine the size of your TextureRect, which seems currently impossible for TextureButtons.

In this example below, the only thing determining the Container's size is the Label. The TextureRect, as it is set to fit_width_proportional, it automatically resizes itself to fit its width to the Container's height.
Image

This allows to place images within a Container without setting a minimum_size and still have them resize appropriately to the Container they're placed in. Most importantly, it "automatically" sets the image's minimum size so the rule set by expand_mode is followed. See how the image's properties force the Container's min_size, I cannot make it smaller:

Resize_1.mp4

This makes the TextureRect's custom_minimum_size and its Texture2D size irrelevant. The image automatically set its min_size of a dimension to match the other's size, in this case, min_size x is determined by the size of y.

In comparison, see TextureButton:

Resize_2.mp4

Due to the lack of expand_mode, TextureButton is unable to "avoid" being made smaller than it should be. If you set its ignore_texture_size to true, the button can't be smaller than the texture, and if it is false, the Container will auto-resize so that its contents occupy the minimum amount of space, which for the button the minimum is 0.

all controls have expand in the layout part

Expand does not help as it makes the image resize to fit the Container's size, but it does not set a minimum_size for the image itself. So when the Container resizes to its minimum size, the image is resized to 0, regardless of expand settings.

A regular Button's icon suffers from the same problem: a custom_minimum_size for the Button must be set in order to prevent parent Containers from resizing it to 0.

Conclusion

Whether or not this is a desirable feature is debatable, as TextureRect's expand_mode member is flagged as "experimental". However, to be able to set an image to effectively resize itself so it keep its Aspect Ratio seems useful, as other dynamic UI elements may change the layout and we want the image to resize appropriately, regardless of its minimum_size or Texture size.

It seems odd to me that TextureRect has such a useful tool, yet Nodes like Button and specially TextureButton, which is meant to be an image you can click, do not feature it.

Note that this issue can be worked around by just setting the Node's custom_minimum_size, but the entire point of this Issue is to not need to do that.

@ch0m5
Copy link
Author

ch0m5 commented Jan 28, 2025

This is an example I made up in a jiffy, but I feel it shows the advantage quite well: I can alter the Container's contents and the TextureRect will appropriately resize to the new height and update its min_width accordingly, therefore making its parent the Container wider automatically.

Resize_3.mp4

The TextureButton and Button, however, either have a custom_minimum_size set manually, its Texture set to "keep_size", or it resizes to 0.
Image

Even if you keep the Texture Size, if the Container becomes bigger, the Texture will just have empty space or have part of itself cut/hidden. The Buttons cannot force their parent Container to be bigger with their stretch_mode settings. They can only do so via custom_minimum_size, which we can use, but what expand_mode offers is automatic and requires no manual updates or custom code. It just works, so to speak.

Resize_4.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants