godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 93 forks source link

Add style transitions to Control nodes #8992

Open PauloVBettio opened 8 months ago

PauloVBettio commented 8 months ago

Describe the project you are working on

A 3D sandbox with an integrated sharing platform

Describe the problem or limitation you are having in your project

Making transitions on Control nodes styleboxes where user input is needed (like buttons, scroll-bars and tabs) can be very cumbersome and needs custom types or workarounds using Panels and unique styleboxes per-node.

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

Add a new method to call Draw with tweening capabilities on Control nodes.

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

This could work by exposing new properties on the Stylebox for the duration and easing, that will be handled by Draw to tween between the current and the next stylebox.

Gravação de tela de 2024-01-30 10-38-29.webm

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

This can be worked around by making a extended class for each one of the Controls with more than one state, making use of a internal Container that holds a Stylebox responsible for handling the transition and shares the same Rect as its parent. However, the parent needs to be marked as flat or have it's styleboxes cleaned to a new StyleboxEmpty with the same content margins, while holding the reference to the original styleboxes.

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

This is a direct improvement to the Control nodes, improving user feedback and the overall feel of the interfaces made with it. Custom nodes made only to allow transitions on nodes will be redundant (TransitionableButton, Button, TransitionableTab, Tab, TransitionableScrollBar, ScrollBar) and will not be used on internal nodes of other engine nodes (ColorPicker)

Calinou commented 8 months ago

The issue is that a StyleBox resource is drawn at a fixed point in time, so if it had transition properties, it would apply to all instances of the StyleBox resource at once. This means you'd have to make every button in your scene use its own StyleBox instance as a theme override, which is a no-go from a performance standpoint.

One way to work around this issue would be to make each Control node have its own timer property that measures the time since the control has started being hovered or pressed, and using this as a basis for transitions.

Also, a different solution is needed for font colors that change over time as these aren't part of the StyleBox resource.

FilthyTaffer commented 7 months ago

Im not a really good programmer but yeah adding a shader property to the stylebox resource would be amazing, if an addon already do this please link it to me

rberends commented 5 months ago

I am finding myself creating custom control classes specifically just so I can tween the styleboxes. Having this supported out of the box within the control theme editor would be ideal.

ZenithStar commented 4 months ago

image (Source)

I'm also strongly interested in this feature, not just for StyleBox, but for all Control nodes. Correct me if I'm wrong, but compared with HTML+CSS, the inherent problem is that the Godot rendering pipeline does not have a DOM+CSSOM layer of abstraction. The values of properties of Nodes in the scene tree is exactly what's being passed to the render engine, which can accept a shader script as a modification layer, and it's currently common practice to use this shader layer as stand-in hack to apply transition modifications, where "Layout" is in the above image. CSS transitions are instead implemented before the render tree.

Spartan322 commented 4 months ago

@ZenithStar I don't think styles map very well to CSS on this chart. So long as you queue_draw on the control for each frame for the animation, there isn't technically anything preventing a StyleBox from being used for animation as a transition to another StyleBox, the onus is more on the Control to handle this behavior. (though granted the current StyleBox classes were not made to expect this either so it would be a little jank if you don't add a new animation Stylebox)

ZenithStar commented 4 months ago

the onus is more on the Control to handle this behavior

I'm saying that the engine Control node layer should just handle transition behaviors for the user, rather than every user having to write their own custom scripts to handle every transition case hacked onto the existing Control node in another layer. In essence: This proposal is grouped with this same family of other proposals of "We want Godot Control+Theme to support all the features that CSS already does.", with transitions being one of the more complicated feature to support. Some examples: #2498 #8404 #9743 #7658. While it is possible to work-around everything with enough custom scripts, I don't think the engine should encourage users to make an entire ecosystem of nodes that involve rewriting an entire third of the built-in classes.

For example, when the position of a Control node changes, be that due to its parents moving in the scene tree or from the user changing anchors or directly setting position parameters, the Control node shouldn't immediately update its internal position cache, but rather, create a tween to transition to the new position over a style/theme-specified duration.

Spartan322 commented 4 months ago

My point was that an animated StyleBox alone could feasibly be made to handle this case, the big issue right now with doing that is that the Control doesn't currently expect such behavior and you'd need to create new StyleBox objects each with unique state. Then again perhaps using StyleBox as the basis for animations would be a hack, but maybe it would be best to make a separated animation system for theming instead of trying to add a bunch of hardcoded functionality into the Control for animations, the RichTextLabel already kinda already demonstrates much having to do that sucks.

Also I don't think the theme system should handle changing of the Control position, just the display of it, theming should be relegated imo to only display and if you need anything more you should be using an AnimationPlayer or a Tween directly. Otherwise the theme system is doing the opposite of its purpose which is supposed to be a decoupled abstraction.