-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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 a lifecycle method for manual theme item caching to Control
#65156
Add a lifecycle method for manual theme item caching to Control
#65156
Conversation
1479f6e
to
98de0f7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not tested all the controls, only looked through the code. Everything looks good.
98de0f7
to
3b1aa24
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks excellent. I only checked thoroughly down to Label, but I expect the rest follows the same logic. Tested locally and didn't spot any obvious regression in the editor.
if (rtl && has_theme_stylebox(SNAME("normal_mirrored"))) { | ||
style = get_theme_stylebox(SNAME("normal_mirrored")); | ||
style = theme_cache.normal_mirrored; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see most of this code uses has_theme_*
checks before fetching the theme items, but the new cache doesn't.
Can that lead to issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These checks are kind of iffy to begin with, we normally don't code controls like that. Issues this should not create, after all the cache would simply host default values for each data type. But these has_theme_*
calls are potentially excessive, same as get_theme_*
calls were, and we aren't using any cache for them. I think we could simply use the cached values, or at least the dumb cache.
But I've decided to get back to this later.
|
||
theme_cache.h_separation = get_theme_constant(SNAME("h_separation")); | ||
theme_cache.check_v_adjust = get_theme_constant(SNAME("check_v_adjust")); | ||
theme_cache.normal_style = get_theme_stylebox(SNAME("normal")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be consistant with Button
and the actual theme item name it should likely be normal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or the other way around maybe, the Button
ones could get _style
suffix. I suppose you're already planning to harmonize all this and make theme item names more explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer for the cache items to be explicit at least, so that the code that uses it is clear. Admittedly, in this PR I didn't update everything to a better style, but that's in part because indeed I can do that while harmonizing the names.
Thanks! |
Join me on a journey towards more organized utilization of theme items! In Part 1 we're adding the framework for controls and cover most controls with updated and, hopefully, improved code to utilize said framework.
As we're trying to improve the theme propagation logic and theme utilization in built-in controls and the editor, @AaronRecord made #62845, which unearthed some issues with how some UI elements are currently written. Namely, a significant amount of editor UI elements don't react correctly to theme changes which results in broken visuals. Before #62845 it was hard to spot those issues, as they would only fail to update on theme changes (so when a user messes with editor settings, which is fairly rare). After that PR, the issues became apparent as we no longer have theme immediately upon
NOTIFICATION_ENTER_TREE
, which allowed those controls to behave seemingly correct.On top of that, we have a longstanding code quality issue. The code accessing theme items is disconnected and all over the place. As mentioned above, sometimes controls don't implement handlers for the necessary system events (like
NOTIFICATION_THEME_CHANGED
). Sometimes code is excessively run during each draw call, or at other times where no update to theme happened and thus the complicated execution path is unnecessary. I've partially addressed it with the dumb theme item cache in #64314, so performance-wise we're probably in a good spot.Still, theme items excessively rely on strings, which results in hard-to-maintain error-prone code. I am slowly moving towards solving this completely with
ThemeDB
(godotengine/godot-proposals#4486), but that work is still very much in progress. In the meantime my plan to improve code quality, is as follows:Control
andWindow
a virtual method that would be called automatically at necessary points in time to generate the "not-so-dumb" cache. The cache structure remains a responsibility of each individual control or window class, but for consistency I'm proposing to createThemeCache
struct namedtheme_cache
.get_theme_*
calls to that method and use class properties instead throughout the rest of the methods.This removes the need for contributors to think about when is it correct to update theme items, as there is now a method for it. This also reduces the amount of theme related strings in the codebase, keeping them only in the specific place of each class.
For editor widgets this hopefully makes it harder to write code that would not implement theme support properly, removing the issues uncovered by #62845.
This PR is only the first one of several.
Control::_update_theme_item_cache()
and adds calls to it in the appropriate places to ensure items are valid and up to date.I've omitted
CodeEdit
andTextEdit
for now, because they already have some sort of cache and I wanted to push this as soon as possible.Tree
is in a similar position, but I've already committed to it today, so it was converted to the new system.I've also omitted
RichTextLabel
, as it's big and I don't want to break it right now. The system is optional, so it doesn't really matter if everything is implemented at the same time.And I've also omitted
GraphEdit
/GraphNode
andColorPicker
/ColorPickerButton
/ColorPresetButton
, as those have refactoring PRs in works, and I don't want to introduce major conflicts for now (#61414 and #62910).I will continue tomorrow with Window-based nodes and the reported editor widgets. There are around 3k calls to
get_theme_*
in our codebase, so help is appreciated (if we decide to merge this, of course). Poke me on RC if you want to take a part of this work upon yourself.