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

Redesign how user interface (Controls) scaling is presented to the user #2841

Closed
reduz opened this issue Jun 8, 2021 · 32 comments · Fixed by godotengine/godot#55157
Closed
Milestone

Comments

@reduz
Copy link
Member

reduz commented Jun 8, 2021

Describe the project you are working on

Godot

Describe the problem or limitation you are having in your project

Users often complain that sizing controls (user interfaces) in Godot is complex and very confusing. Too many properties and it's not obvious what each of them does. Among the properties there is a lot of redundancy so it can take a while to correctly understand what is going on.

That said, the user interface system is extremely powerful once you understand how it works, so the goal is not so much to change it but to change how information is presented to the user to make it less confusing.

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

There are currently 3 separate modes for user interface sizing and placement in Godot:

  • Anchors
  • Rect position and size, including rotation, scale, etc.
  • Containers

image

Each serves a different purpose and use case, but all are presented at the same time to users. That said, using all of them at the same time is generally not needed:

  • When containers are used (control is inside a container), anchors and pos/size are ignored.
  • When using anchors, position and size are ignored
  • Even when using containers, the size flags exposed as well as the stretch ratio vary on their availability depending on the parent container.

The idea of this proposal is to hide what is not needed, and to also allow the user to specify better the kind of workflow desired.

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

The first step would be to move everything position related to the top of the list, so the properties are not mixed up with other, unrelated ones.

Containers

The following changes will take place in the inspector:

  • "Size Flags" section will be renamed to "Container Sizing"
  • In this section, the parent container will be asked for which flags are supported (not all support expand, not always in both vertical and horizontal direction, and not all support stretch ratios).
  • If the parent to a node being edited is a container, the "Positioning" (anchors/position/size/transform properties) will be hidden, as they are unused in this workflow. Only "Container Sizing" will be visible and shown on top.
  • "Minimum Size" will be moved to its own section, as its useful for both operation modes (container and regular position) and will appear as second section below "Container Sizing" or "Positioning".

image

Positioning

All positioning related properties will be put in a larger section "Positioning". Also moved to the top. When containers are used this section goes hidden, so on top of the inspector either this or containers will be there.

Positioning will have the following properties and subsections:

  • use_anchors: Anchoring will be enabled only if this property is on. If enabled, the following sub-sections of "Positioning" will be visible:
    • Anchors
    • Margins
      Likewise, the "Rectangle" subsection (showing position and size) will be hidden if anchors are active.
      By default, anchors will not be enabled. To use anchors, you will need to toggle them on.

image

  • If use_anchors is disabled, then the "Rectangle" subsection of "Positioning" will be shown. This displays position and size.

image

  • a "Transform" subsection of "Positioning" will be always visible (And below either "Anchoring or Rectangle"), this will contain rotation, scale, pivot, etc.
  • The Clip Content property will be moved to visibility because it does not belong here. Likely renamed to "Clip to Rect"

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

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

Not possible to do with script, should be core.

@markopolojorgensen
Copy link

I'm glad any time anyone wants to make the ui creation experience better, but I don't like the editor hiding properties automatically. I'd much prefer if they were greyed out or uneditable, and then hovering over them explained why, e.g. "parent container doesn't support expand flag" or similar.

If I expect a property to be there, I will waste time looking for it, and then I'll have to google "Godot container sizing expand options are gone" and then half an hour later I'll finally realize it's because the parent container doesn't support them. I already have this problem with the tileset resource editor automatically hiding snap settings in 3.x. IMO it's easier to learn if properties that are only sometimes relevant are still visible all the time, so users can learn where those properties are and when they're relevant without having to look up a tutorial. Design UIs to be self-teaching, etc etc.

Just my two cents, I'd still rather have this proposal than no change 👍

@groud
Copy link
Member

groud commented Jun 8, 2021

I like the idea, I definitely think the positioning properties should be hidden if children of a container. As said on IRC, my main concern is about the Layout menu (which is used often), made dependent on something in the inspector. We can either activate the "use_anchors" bool automatically (but it's making the menu doing something behind your back), or disable the Layout menu if "use_anchors" is not activated, which is not great for discoverability and ease of use.

Instead, I propose to change the use_anchor bool to an enum with 3 modes, and move the layout options to one of those modes:
better_control_inspector
This would make things a more discoverable (as everything is in the same place), while not making things a lot more complex IMO.

@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@markopolojorgensen Disabled properties add clutter and are still confusing. I prefer to think of workflows where users need something and go look for it, and you try to make it as easy as possible to find it.

@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@groud as mentioned on RC, I like the idea of making anchors an enum, but I would just have a single one that shows: Anchors: [Disabled,Custom,Preset1,Preset2,Preset3,etc]. If custom is selected you edit them (properties visible), otherwise the preset is used and the settings to edit them invisible.

@SilencedPerson
Copy link

I feel like the Anchor could be completely removed from the Control Nodes as value and made into separate Node by itself, usually you just need to set it up on only ONE node anyway.

While we are discussing the controls, could we please change rect_position, rect_size and similar values to just position,size ? I don't see the point of the current distinction, quite frankly it just messes up my code when tweening the UI.

@YeldhamDev
Copy link
Member

YeldhamDev commented Jun 8, 2021

As someone who does heavy UI work on my game, I dislike this idea. That are multiple times that I need to modify anchors, position, and size all at once of certain Control nodes for some more complex UI.

@Calinou Calinou modified the milestone: 4.0 Jun 8, 2021
@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@YeldhamDev Anchors and position/size are redundant so, while I understand that some very rare case you may need to do something strange, this change simplifies workflow for the vast majority of users, so the benefits outweight the cons.

That said, feel free to explain how are you using it currently, and we can see if there is another way to do it (other than probably having to use a script, worst case).

@RandomShaper
Copy link
Member

For those that want or somehow need to see all the properties, there can just be an editor setting (something like always_show_all_layout_properties, off by default).

@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@RandomShaper It could work, but first I think I need to be convinced that the concern exposed by @YeldhamDev can't be solved in a different way, for which it would be useful to have an example of what he needs.

@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@RandomShaper @YeldhamDev I was thinking about it, and I think it will be easier to have a Custom + Rect setting in the anchor mode for the rare cases you need both. IMO that should solve the problem.

@groud
Copy link
Member

groud commented Jun 8, 2021

@RandomShaper @YeldhamDev I was thinking about it, and I think it will be easier to have a Custom + Rect setting in the anchor mode for the rare cases you need both. IMO that should solve the problem.

IMO, the "Custom" mode is likely going to be used so rarely that we could simply display position and size too in that mode. it would be kind of a "power user" mode.

@YeldhamDev
Copy link
Member

@reduz This is a response for the use cases that you asked previously:


Specific Margins for Specific Elements

Complex UI can have a lot of controls that need to be in certain places along the screen, while still following certain corner sides. Of course, margins still need to be applied for those.

Just use MarginContainer then?

That can be used, but it creates other problems:

  • As elements can have different margins and be in different layers, you will end up having to place various MarginContainer nodes, resulting in a quick pollution of the scene tree.
  • If said control elements need to be animated (e.g. entering the screen), those containers start to become a hustle and another thing to keep attention when animating.

Visuals and Animations

Place take a look at the GIF below:

Peek 2021-06-08 12-31

Besides having some of the elements that I discussed above, the main focus here are the gates that animated during the transition. While their vertical position is animated, their horizontal size is anchored to hug both ends. Having the position and size being available while still anchored made the process much more easier.

Could it also be done without it? Probably, but it would've required much more work to achieve the same results. Keep in mind that animation wasn't even as complex as you can see in some game UIs.

@theraot
Copy link

theraot commented Jun 8, 2021

I'll remind people that while you should not use position to place controls in a container, position can be still useful for animation purposes. Thus, for people trying to use AnimationPlayer to animate controls having position related properties hidden (or uneditable) in the inspector panel could be hurdle.

Perhaps that's good? Straight up using an AnimationPlayer to animate a control in a container is rarely what to do, because the control should leave the control where the container wants it to be. Instead:

  • Add another container between the control and the its container, so the AnimationPlayer can move the control relative to the inner container, which would be relative to the position the outer container wants it to be.
  • Edit the coordinates of the AnimationPlayer from a script to make sure it ends where the containers wants the control to be.
  • Use a Tween from script so you can make sure the animation ends where the container wants the control to be.
  • Just move from script, and again, make sure the control ends up where the container wants the control to be.

Personally, I prefer to use Tweens for this purpose. Thus, this is not a problem for me. As far as I'm concerned pushing people into not using AnimationPlayer to move controls is a good thing, but that is only my opinion. I'm aware that the motion that Tweens provide is limited in comparison to what you can do with an AnimationPlayer, thus there can be legitimate cases for using AnimationPlayer to move controls.

@YeldhamDev
Copy link
Member

@theraot The problem of doing such things with a Tween instead with the AnimationPlayer is the lack of direct preview. With the latter, you can see the results on the spot, while former you will need to open the game, navigate to the specific spot that the animation plays, and then you will be able to see it.

@reduz
Copy link
Member Author

reduz commented Jun 8, 2021

@YeldhamDev yeah I see, i guess in some situations you want to animate just from the position. I think as @groud says, the custom mode can probably include position + size too, it wont hurt.

@YuriSizov
Copy link
Contributor

@YeldhamDev @reduz If the use case here is animation, does it matter what "mode" is selected in the Inspector? All properties are still accessible for the animation, and if they can be edited in code, they can be animated. Now if this proposal would affect what properties you can select in the animation editor, then it would present a problem. But otherwise... Or do you use keying from the inspector, @YeldhamDev?

@YeldhamDev
Copy link
Member

@pycbouh Being able to modify the position/size directly from the 2D editor is an immense time saver when making UI animations. As I said before, it would still be possible to do it without that, but it would be much more difficult.

@eon-s
Copy link

eon-s commented Jun 10, 2021

Maybe when the animation player is shown with keys enabled on the inspector, the full view can be active by default (I think that this type of views can be useful on other types of nodes too).

@ArjunNair
Copy link

@markopolojorgensen Disabled properties add clutter and are still confusing. I prefer to think of workflows where users need something and go look for it, and you try to make it as easy as possible to find it.

I too think completely hiding it can cause confusion for new users. Especially, if changing a seemingly harmless property causes a large swatch of options to appear or disappear out of the blue. What about disabling and collapsing said properties with an alert indicator (such as that is used in nodes in the scene window to call attention) next to the label. Hovering over the alert indicator would pop up an info box (just like it does for, say, an Area2D with no Collider2D node) telling the user why the property is disabled. Eg: "Positioning is determined by the parent container and cannot be modified".

That way the user cannot edit properties which have no effect anyway, but at the same time they also know why a particular property is showing up that way. The proposal for collating and renaming some of the properties still applies though.

@aaronfranke
Copy link
Member

@reduz What do you think about this kinda-related proposal? In addition to only showing the relevant properties in the inspector, it would be nice if SizeFlags was more intuitive and fewer combinations were invalid. #299

@golddotasksquestions
Copy link

golddotasksquestions commented Jun 11, 2021

This Proposal is a vital improvement, one I have been desperately waiting for ever since I've discovered Godot years ago! The new structure proposed here makes a lot more sense compared to what we have right now.

However I agree with others, removing properties completely without indication can be just as disorienting and confusing for beginners and intermediate users. Blender does this too and it is horrible. There are so many situations when you know what to look for, you know where to look for it, but you can't find it, just because it is removed without notice and you would have to click some other thing first to make it appear.

Unfortunately Godot has it's fair share of these already (bottom panel and toolbar for example). If this expands onto the Inspector, I can already see the community channels filled with "where is property X?" questions.

It hurts discoverability and the learning process. Maybe there is a way to compromise by automatically collapsing but keeping the greyed out property category. Then if a user tries to expand the collapsed property category, they see the properties greyed out as well (but they can still see the values! - which is important for designing UI). A single line warning underneath explaining what's going on, with a slightly more in depth explanation in the tool tip when hovering above the greyed out properties or warning ⚠️:

image

There is one more thing that has caused me countless sleepless nights, which is the rect Pivot Offset property. I can't find any info in this proposal what would happen with this property, even though it affects positioning greatly. The way this property currently works really absurdly backwards and extremely counter intuitive. It would be nice if there would be a more intuitive option. Personally I would prefer to be able to position the origin directly, see #129

@Killfrra
Copy link

  • I like the idea of turning off fields non-supported by container from the "size flags" / "container flags" section.
  • I'm not sure if we need the flags separately for vertical and horizontal, but if we do, I think it would be logical to have two "stretch ratio" fields immediately under the corresponding "expand" flag, to visually emphasize that without the flag enabled, they do not affect the size of the element.
  • It also probably makes sense to replace two flags "shrink to center" and "shrink to end" with one drop-down menu, similar to "align" with the initial value "start" / "left" / "top", because I have not yet seen a container that would be affected by both of these flags set at the same time

This is how I imagine an inspector view for a node inside a container that supports all size flags:
Screenshot_20210613_205301_edited

@YuriSizov
Copy link
Contributor

YuriSizov commented Jun 13, 2021

It also probably makes sense to replace two flags "shrink to center" and "shrink to end" with one drop-down menu, similar to "align" with the initial value "start" / "left" / "top", because I have not yet seen a container that would be affected by both of these flags set at the same time

The problem is, they don't mix with Fill and Expand or Fill+Expand. Aaron's #299 is much better in that regard.

As for two stretch ratios, it makes sense. I think that we only have one because it only affects BoxContainers and SplitContainers which can only go in one direction. So it does cover all the cases for the built-in containers, but it may be useful to have two of them for custom containers, I guess.

@Zireael07
Copy link

which is the rect Pivot Offset property. I can't find any info in this proposal what would happen with this property, even though it affects positioning greatly

Seconded - I use pivot offset in my projects because rotating from the top left corner is usually NOT what I want.

Since the most common rotation people want is from the center, maybe instead of (indeed often confusing) pivot offset we could get an enum (each of the corners + center)?

@YuriSizov
Copy link
Contributor

Just letting everyone know that I'm working on implementing this proposal. 🙃

@Feniks-Gaming
Copy link

Do you hope this will make it to 4.0 or are we looking past that 4.1

@YuriSizov
Copy link
Contributor

YuriSizov commented Nov 9, 2021

Do you hope this will make it to 4.0 or are we looking past that 4.1

This is not going to take me a year, so yeah, safe to assume it's a part of 4.0. 🙃 It may even get to 3.x in some way, because a lot can be done just from the organizational standpoint, without breaking compat whatsoever.

@Calinou Calinou added this to the 4.0 milestone Nov 9, 2021
@SoloByte
Copy link

As an example when rect properties are useful to see even though the node itself is a child of a container would be the rect_scale. I regularly animate the rect_scale property even though the general layout is dictated by containers to make certain things "pop" when selected/hovered over etc.

godot-ui-overhaul-issue-example01.mp4

The buttons are in a VBoxContainer, the class panel is in VBoxContainer with the prev/next input panels and the items are in a grid container, and all of them use an animated rect_scale.

As a side note because of animating the rect_scale regularly AND using containers the current implementation of the rect_pivot_offset is pretty much useless for me. Using containers makes everything very flexible and therefore I never really know the rect_size of my UI nodes in advance. Because of all of this, it is hard to put the origin where I need it for my animations with the current system.
For instance, animating the stretch_ratio of a node inside a container changes the size of all other nodes dynamically (as it should) but that also means I can not really use the rect_pivot_offset for all the affected nodes, rendering rotation/scaling useless.

Making the rect_pivot_offset relative instead of absolute (between 0 - 1 for instance) would make it much easier to work with. Maybe the absolute value is still better in some situations but as far as I can remember I never needed it.

I hope this helps somewhat ;)

@YuriSizov
Copy link
Contributor

YuriSizov commented Nov 10, 2021

@SoloByte That's a nice example. I think you wouldn't be able to do that same thing in master already, because we disable scale for children of containers (because containers reset the scale to (1, 1) rendering the property useless by default). I works for you because container is not aware of the changes you make during an animation and doesn't correct its children. I think you would need to use an intermediate control to achieve that effect without breaking the container logic, even for a split second animation.

@Calinou
Copy link
Member

Calinou commented Nov 10, 2021

because we disable scale for children of containers (because containers reset the scale to (1, 1) rendering the property useless by default).

Setting the Control scale at run-time should still work, it's just no longer exposed in the editor IIRC.

@YuriSizov
Copy link
Contributor

Setting the Control scale at run-time should still work, it's just no longer exposed in the editor IIRC.

Yes, you can of course change it with code. But you may want to set up animations using the editor GUI 😉

@YuriSizov
Copy link
Contributor

I've submitted my work as godotengine/godot#55157. Please give it a try if you can. Whether you like what it looks like on clips or not, an actual hands-on test is very very valuable!

I've tried to explain the rationale regarding particular implementation details in the OP there as well, in case it doesn't meet the user experience you were looking for.

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

Successfully merging a pull request may close this issue.