-
-
Notifications
You must be signed in to change notification settings - Fork 97
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
Consolidate H/V UI nodes into generalized variants #3558
Comments
Merging the horizontal and vertical variants together would make it possible to implement godotengine/godot#36040 without hacks, but reduz was opposed to it last time I asked. |
Did he give a rationale? I wonder if the switch might be more reasonable in this form, as part of a wider improvement/anti-redundancy/composition-over-inheritance measure rather than a specialized use case. |
I like the idea, but it's worth noting that it will add an extra step every time one needs to use whichever orientation is not the default. For example in the editor code, we have:
So whichever is default, the other one will require an extra method call to change the orientation: BoxContainer *hbc = memnew(BoxContainer);
hbc->set_orientation(Orientation::HORIZONTAL); instead of: HBoxContainer *hbc = memnew(HBoxContainer); (Not saying that it makes this proposal problematic, but it's worth being aware of for UI heavy workflows like editor code.) |
This is a perfect illustration that in a given project of a considerable size that has a lot of UI either node is heavily used. As such, unification would make it a worse experience to build such a project. And it also highlights a wrong statement in the OP:
This is not true, because most if not all of them rely on a boolean flag, so one direction is assumed as default. E.g. |
Some additional context for engine and editor code:
So it's mostly |
Well, yes, the other nodes are simply more contextual and less used 🙃 So I think it's fair to judge this based on the box. |
That's a good point. That said, I don't think it's C++ instantiation of these nodes (and hence an extra Is there a reason to stay away from specifying direction in a constructor? I know very little about the codebase's internals, so I don't know if the (custom macro?) |
It does, as sometimes used with Label ( In fact, this should probably be extended to Button/CheckBox/CheckButton nodes as well (and possibly more) 🙂 |
My point doesn't actually change whether we are talking about the editor itself, or creating nodes in GDScript, or creating them in the editor UI. In fact, I'd say that the editor users would have it the worst if we make this change. We would still have to assume one direction is more prevalent than the other (which is provably false), and as such we would make users do extra configurations if they need non-default orientation. While we could use the constructor to make this problem less severe in code, there is no such thing for creating UI in the editor. So this will be a downgrade for the majority of users, because the majority of users create scenes using the editor UI. |
Oh, I see your point now, that makes sense. It seems to me to be a question of which direction to weight convenience. Consolidation makes creating a ton of non-default boxes more tedious but benefits management and modification of existing structures, where keeping them as is makes it easier to instantiate but more tedious to modify and code around afterward. I personally prefer editing rather than instantiation convenience, but that's probably something to get a wider sample size for. |
We have to keep in mind that by consolidating the H/V UI nodes we would lose the ability to theme each variant independently (at least in a conveniant way). I made a small experiment/mockup to demonstrate a different solution which can be seen here: https://github.com/Geometror/godot/tree/h-v-container-solution. (just H/VSplitContainer for now, although this could be applied to other controls) My approach to allow changing the orientation dynamically (e.g. needed for godotengine/godot#36040) is the following:
This allowes us to have dynamically oriented UI controls in some specific cases (like godotengine/godot#36040), while keeping the traditional way of defining orientation. |
Not necessarily, we can use theme type variations. We can have some built into the default theme. We'd have to hack a bit to make it so when the custom type variation is empty (i.e. not set by user) we would smartly take one of the other of the default ones.
I think that for godotengine/godot#36040 specifically we don't even need to expose anything to scripting. A method to change orientation can be public, but engine internal. But if there is user need for such flippable containers as well, then I think your proposal is better, as it adds an option without breaking the good thing that we already have. And the codebase already has those base classes, so it's not an increase in maintenance. |
I have to disagree with some of the supportive points on distinct nodes. While there is a slight upfront cost to change alignment direction, because it is not the default, it is also ingrained in most human languages to read beginning from a certain direction, and as the project and code is written in English primarily, assuming a left-to-right orientation by default is fine. As for the points of users expecting to needing to put in an extra click to change orientation, the opposite side is that during the creative portion of the UI process things aren't set in stone and you typically want to experiment with variations. In cases of left versus right, that would be creating a brand new box of the opposite orientation, having to copy over all of the parameters you have set, and re-parenting the scene nodes, which is a lot more work than using an enum dropdown or a checkbox to set the direction. Additionally, people coming from web developer backgrounds are also familiar with default left-to-right orientation, as well as specifying right alignment manually when needed via e.g. Also, to make UI controls a bit more flexible from a code point of view, the property setters could be improved to be reference-returning. ie: |
@marstaik This has nothing to do with LTR vs RTL. This is about horizontal and vertical direction of some control nodes. |
That was a very small part of my reply, the rest of it does have to do with the direction of control nodes. |
In the meantime this can be "worked around" by using a |
I think this is a good idea I saw this approach in some UI frameworks I worked with, for example Kivy has I think the can be named |
To keep the UI workflow the same in the editor we could have a system to show presets in the Add Node menu after consolidating the nodes. Implementation ideas:
|
This issue is way more complex, it's not about showing 'presets' |
Describe the project you are working on
A puzzle game for Game Off 2021 with a typical middlingly-complex UI.
Describe the problem or limitation you are having in your project
Godot's
HBoxContainer
andVBoxContainer
nodes provide the same functionality except for their direction. The same goes forHSplitContainer
,VSplitContainer
,HSlider
,VSlider
,HSeparator
,VSeparator
,HScrollBar
, andVScrollBar
. All of these classes are subclassed as well from a general, non-directional parent.But subclassing here rather than simply increasing the functionality of the base class seems unnecessary. There are separate node classes for what's really just a configuration value. This leads to not only doc and API redundancy but also several minor issues which, while not insurmountable on their own, are consistently present and pop up every time I do layout:
extends HBoxContainer
or a variant as many times as the direction changes.Describe the feature / enhancement and how it helps to overcome the problem or limitation
The respective functionality that makes them horizontal or vertical (or theoretical further directions, like Flutter's depth-based stacks) could be accessed by a simple enum property instead, slimming down redundancy in the class list, theming, and documentation.
I propose that the H- and V-specified variants of the UI controls be subsumed into their parent classes and switching between the layout methods be done through enum properties. In keeping with the move toward simplicity, clarity, and showing only necessary properties in the UI system, this would turn subclasses' layout direction into a single parameter which could be set on a
SplitContainer
orBoxContainer
(which, in the process, could likely be more clearly namedStackContainer
). Similarly, the H- and V-separator classes would be simplified into a singleSeparator
orStackSeparator
which would adapt as necessary to the direction of its parentStackContainer
.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
HSplitContainer
andVSplitContainer
would becomeSplitContainer
.HBoxContainer
andVBoxContainer
would becomeStackContainer
(althoughBoxContainer
works as well--I think GTK uses "box," but most other frameworks I know of use "stack").HSlider
andVSlider
would becomeSlider
.HSeparator
andVSeparator
would becomeSeparator
, which would fit the direction of their parentStackContainer
, andHScrollBar
andVScrollBar
would becomeScrollBar
.Each of these classes would then expose a
direction
property (or a similar name), one of an enum of layout directions which could then be theoretically expanded in the future should the need arise. This way, we don't lose the flexibility that subclassing currently enables (there'd be less flexibility with a booleanhorizontal
flag) while also not using subclassing further than necessary, a la Swing.If this enhancement will not be used often, can it be worked around with a few lines of script?
As mentioned, it's not a critical issue, but since 4.0 will be making many breaking changes in the interest of more intentionally-designed, clear, and accessible APIs, it seems like a good time for the switch.
Is there a reason why this should be core and not an add-on in the asset library?
It pertains to melting down classes which are part of the core UI system.
The text was updated successfully, but these errors were encountered: