Add sticky tree item support#115697
Conversation
|
tested it on Android, I am having a problem when use multiple nested node: az_recorder_20260201_082540_edited.mp4 |
|
Ah right. It currently sticks at an unlimited depth. Maybe I can just hard cap it to the last few elements. Or maybe up to like half of the full height Edit: looks like it's not horizontally scrolling either. I'll have to fix that |
|
if you cap the depth and that depth is reached, will from that point on the sticky headers also scroll again as if normal? because if they remain sticky, that might be very confusing… |
|
I think they could show another scroll hint shadow at the top, to indicate there's more sticky elements. Or maybe have like a Edit: nvm I realize the issue with capping to the last elements. It would make items jump to the top. It's probably better to cap to the first few elements instead |
f68a535 to
d818429
Compare
|
Ok I changed the setting to enable sticky items to an int, providing the maximum number of sticky elements. Horizontal scrolling should also work now. 2026-02-01.10-20-54.mp4 |
d818429 to
8f6ee21
Compare
| @@ -6847,6 +6923,9 @@ void Tree::_bind_methods() { | |||
| ClassDB::bind_method(D_METHOD("set_auto_tooltip", "enable"), &Tree::set_auto_tooltip); | |||
| ClassDB::bind_method(D_METHOD("is_auto_tooltip_enabled"), &Tree::is_auto_tooltip_enabled); | |||
|
|
|||
| ClassDB::bind_method(D_METHOD("set_max_sticky_items", "enable"), &Tree::set_max_sticky_items); | |||
There was a problem hiding this comment.
| ClassDB::bind_method(D_METHOD("set_max_sticky_items", "enable"), &Tree::set_max_sticky_items); | |
| ClassDB::bind_method(D_METHOD("set_max_sticky_items", "count"), &Tree::set_max_sticky_items); |
| @@ -383,6 +383,9 @@ | |||
| <member name="hide_root" type="bool" setter="set_hide_root" getter="is_root_hidden" default="false"> | |||
| If [code]true[/code], the tree's root is hidden. | |||
| </member> | |||
| <member name="max_sticky_items" type="int" setter="set_max_sticky_items" getter="get_max_sticky_items" default="0"> | |||
| The maximum number of tree items allowed to stick to the top while its children are still in view. | |||
There was a problem hiding this comment.
If setting this to 0 is to imply the feature is disabled, there should be a note and/or sentence here that indicates calling the method with 0 disables the feature, and the Tree works as it did prior to this feature being added, particularly for EditorPlugin authors who may not want this to be enabled.
There was a problem hiding this comment.
I agree that it could be nice to specify that explicitly. However, unless I'm misunderstanding, I think that would be the implied result of this being 0 anyways? As in, zero tree items would be allowed to stick to the top while children are in view?
8f6ee21 to
7f407d7
Compare
|
pushed the changes and explicitly mentioned that a max of 0 disables sticking, just in case |
Naros
left a comment
There was a problem hiding this comment.
I'll defer to AThousandShips on the language, but LGTM.
|
Tested the latest version and it works as expected. |
There was a problem hiding this comment.
Played around with this and think this is a great feature in general. A few notes:
-
I was unable to raise the sticky count above 6. Why not? IMO it should be able to go to a large number just because it will enable this UX improvement on various specific workflows. Even in Rift Riff's settings screen I easily hit 6 layers of organization deep and it wasn't enough. I suggest having a maximum of 16.
-
Looking at the trees in my commercial-game-grade projects, I think the default maximum sticky items of 3 is too low making the sticky headers less useful than they can be. The point of that number is to avoid infinite sticky items and filling the entire panel with stickies making the panel unusable.
-- It's not trivial to land on a better number without making assumptions about some sort of median height of Godot user's scene panel.
-- ... but making assumptions based on my experience with the editor,5would be a better default. -
I'm not sure yet whether this should be improved and how it even could be improved, but at the core of the sticky header is that it 'hides' all the in-between nodes that are not the shortest path to root. However, there is currently no visual indication of when there are nodes in between the sticky ones or not. For example, in the video below, there is no visual indication that Control1 exists when Control2 sticks to the top:
Screen.Recording.2026-02-27.at.10.57.21.mp4
But like I said, I'm not sure we can and should address this. My first thought would be to add a tiny indicator like this one
and stick it in between all the edges that hide nodes... but it'll very soon can crammed with all those icons, so I don't even like that solution much.
- And finally, here's a few screenshots of a bunch of trees in Rift Riff showing how much more readable the tree becomes after this change – as well as notice that a few more stickied items above 6 would have been convenient for us:
7f407d7 to
3756d07
Compare
|
I pushed the suggestions. As for indicating when it reached its sticking limit, I feel like the difference in indentation between the normal and stuck content kind of does that already. Though there might be some cases / configurations that make it less clear, not sure |
|
hey yeah sorry i was unclear! see the image below, an annotated screencap of my video above: i was talking about the nodes hidden at the red arrow, while you’re talking about the itens hidden by the orange arrow. i agree that the items hidden by the orange item are fine as the indentation plus the drop shadow are a clear giveaway. however, nothing indicates there are nodes in between Control and Control2, where the red arrow is. again, i’m still not sure if we could even fix or address this. |
|
Ah that makes sense. Maybe it could add shadows there too. It might look weird if there's a lot of shadows, but I can try it |
|
adding another shadow will make it unclear where the scroll container starts, so that’s probably not gonna work… hmm yeah idk. |
KoBeWi
left a comment
There was a problem hiding this comment.
The implementation looks mostly alright.
Not a fan how it makes Tree even more complex (especially the longer parameter lists), but this class is already beyond saving 🤷♂️
|
@KoBeWi If it's any better, I can make those flags just members of the Tree itself, instead of extra parameters at the end |
70b5e29 to
e5d159b
Compare
|
Ok I pushed the suggested changes. I changed max_sticky_items to a theme_constant, to avoid editor code in Tree. I also added an extra check to make sure the sticky header size never exceeds 40% of the Tree's, which is the same as vscode |
|
Crash: Search in CreateDialog while mouse is near the top of the Tree. |
| EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/docks/dock_tab_style", 0, "Text Only,Icon Only,Text and Icon") | ||
| EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/docks/bottom_dock_tab_style", 0, "Text Only,Icon Only,Text and Icon") | ||
| EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/localization/ui_layout_direction", 0, "Based on Application Locale,Left-to-Right,Right-to-Left,Based on System Locale", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED) | ||
| EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/max_sticky_tree_items", 6, "0,16") |
There was a problem hiding this comment.
Needs to be in some sub-group, e.g.
| EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/max_sticky_tree_items", 6, "0,16") | |
| EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/appearance/max_sticky_tree_items", 6, "0,16") |
e5d159b to
6b5dbe5
Compare
| "name": "category/property_name", | ||
| "type": TYPE_INT, | ||
| "hint": PROPERTY_HINT_ENUM, | ||
| "hint_string": "one,two,three" |
There was a problem hiding this comment.
These changes are unrelated and incorrect, please restore
Why did you make these?
| { "name", "category/propertyName" }, | ||
| { "type", Variant.Type.Int }, | ||
| { "hint", PropertyHint.Enum }, | ||
| { "hint_string", "one,two,three" }, |
| [codeblock] | ||
| func untyped(param): | ||
| param.print() # Will resolve to the global print method for e.g. hover hints. | ||
| param.print() # Will resolve to the global print method for e.g. hover hints. |
There was a problem hiding this comment.
Not sure how these happened. I'll check. (Ignore the latest push, that was to fix merge conflicts)
There was a problem hiding this comment.
You didn't notice when you added changes to the commit? Are you using some tools or AI to make changes? These kinds of changes don't just happen
There was a problem hiding this comment.
No I'm using visual studio. Maybe I accidentally formatted it and it did that. And visual studio isn't showing changes for spaces so I didn't notice
There was a problem hiding this comment.
That's what I meant by tools, good to turn that off, but it shouldn't do that anyway, but good to turn off as it seems to not work
6b5dbe5 to
24d782b
Compare
|
Also this PR is made using a different account so you're not linked to your GitHub profile, you'll need to fix your commit author |
24d782b to
dc9c0be
Compare
|
Ok I pushed it again. Also is the commit author fixed, I'm not sure where it shows that here |
|
It previously had no icon and listed this PR as "first time contributor" |
|
Oh ok thanks. I updated visual studio recently, maybe that messed some stuff up |
|
Turns out this was actually the account you made all your previous contributions with, and it's "invalid", i.e. it's not actually linked to your GitHub profile, so you're still a first time contributor, this being merged would make you count as a contributor (no contributions to this repo has been counted because you didn't use a proper account to sign the commit) |
|
Lol a lot of weirdness going on today. Thanks for letting me know, and sorry for the trouble |
|
It seems #118733 added a new canvas item |
dc9c0be to
f0fcfd2
Compare
|
Ok bugs should be fixed now |
f0fcfd2 to
6211f83
Compare
KoBeWi
left a comment
There was a problem hiding this comment.
Other than the above (which is a minor thing tbh) looks fine.
6211f83 to
452783c
Compare
|
That should fix it |



addresses godotengine/godot-proposals#13998 for Trees
Video demo:
2026-01-31.20-06-23.mp4