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

Fix accessing editor theme items throughout the UI #81516

Merged

Conversation

YuriSizov
Copy link
Contributor

@YuriSizov YuriSizov commented Sep 10, 2023

Closes #81492 (there may be other cases, but what's reported should be fixed now). Closes #81586.

TL;DR

This PR:

  • Fixes accessing theme items through EditorInterface::get_base_control/EditorNode::get_gui_base, which no longer works in some contexts.
  • Fixes accessing some non-existent editor theme items.
  • Adds EditorIterface::get_editor_theme to be used by user plugins and by our own C# plugin.
  • Adds a warning system for theme misses in the editor theme, which helps a bit but not a lot.

How we got here

#81130 changed some things about when and how it would be appropriate to access the editor theme. Previously, we would set it directly on the GUI base node (as well as on a dedicated theme base node, for some reason, and on the editor's main window). While not incorrect in principle, this setup meant that the editor theme would propagate to each and every control or window node as long as the chain of themable nodes was uninterrupted. This led to theme leaks.

As the goal of #81130 was to fix these leaks, among other things, the approach had to be changed. Now we define theme contexts for the editor UI. This means that the GUI base node no longer holds a theme. Instead, the editor theme is used through a global reference. Unfortunately, throughout our own codebase we would often rely on the get_base_control()->get_theme_* pattern to access icons and whatnot. And this did work before — even during the editor initialization, even before the editor UI was ready. It worked because the node would hold the theme and would be able to provide these theme properties at any given moment.

We even recommended this approach in the documentation to assign editor icons as user plugin icons.

This is pretty bad, because this relies on something that is not guaranteed to be stable. It was fine for the time being, but a GUI rework made it break, as you can see. Preserving compatibility here would be detrimental to our ability to develop the editor. Adding the theme back to the GUI base control would reintroduce the leaks and would also slow down the editor startup.

It's a huge shame that we suggested this approach to users, though this was probably the only alternative at the time. We should've exposed a method to provide editor icons directly, without relying on GUI nodes and their state. Specifically so these icons could be used outside of the GUI code, such as in

func _get_plugin_icon():
    return EditorInterface.get_base_control().get_theme_icon("Node", "EditorIcons")

How I'm addressing this

For our internal code it's solvable with some find and replace, by accessing EditorNode::get_singleton()->get_editor_theme. This resource is ready early on, and can be used by most of the editor code. Some parts of the codebase that rely on this access are GUI elements and should actually be rewritten as dedicated GUI components, so that they can benefit from the NOTIFICATION_THEME_CHANGED signal and correctly update when users change the editor theme. But I left it as is for now, with some TODOs.

Gizmos are a bit trickier, as these icons are used in constructors to pre-populate materials. I haven't worked with gizmos for quite some time, let alone with Godot 4 gizmos, so I don't remember if we could recreate these materials later on, or if it would be a bad idea. For now I left them as is. But it may be sometime to look into (also may want to add some helper methods so that creating materials from editor icons doesn't take over a hundred characters per line).

Then come user plugins, and our own C# editor plugin, which is limited, for the most part, by our public API. For these I'm adding a new method to EditorInterface, which allows fetching the editor theme. I'm not too happy about adding more methods to EditorInterface when my goal is to split its responsibilities between multiple single-purpose classes, but that's the only place available now, so alas.

For the C# editor plugin I recommend reworking it a bit, so the editor run bar icon is correctly updated with the editor theme. Currently it's only set when the plugin is enabled, and ignores theme changes. We've fixed a similar issue in the build panel before. I should've identified this when reviewing #79357. cc @raulsntos

For user plugins #81130 kind of becomes a breaking change, as far as accessing editor icons goes. This doesn't affect plugins that use custom icons, and this doesn't affect GUI code in these plugins, as long is it's written correctly (using theme propagation). Things like _get_plugin_icon() and inopportune accesses to get_base_control would need to be fixed by plugin creators. The new EditorInterface::get_editor_theme method will prove useful here, and it should also be possible to update plugins in a way that works both with 4.1 and 4.2, if that's required.

I think that's an acceptable compromise.

Reporting theme misses

@Calinou suggested:

Can we make it so requesting an unknown icon in the editor always prints an error at least once? This would make it easier to track down those issues in the future.

I like the idea, but I'm not sure there is a good way to implement this without adding editor-specific code to controls and windows, and I don't like that idea. The reason why this approach may be required is that most of these issues are because of trying to access icons and styles before there is the editor theme, or before you can access it in some context. So this can only be checked by the node itself.

For now I've added a new type, EditorTheme which provides warnings for cases when the editor theme is there, but the theme item requested is wrong. This actually caught a few issues, but none of the ones reported in #81492. I fixed them together with others.

The new EditorTheme class is added as a separate independent commit and can be dropped or reverted later. There are some implementation details that I would like to change so it's less of a nuisance to maintain, but that can be done later. Trying to keep changes to the minimum here.

Comment on lines -7156 to -7163
prev_scene = memnew(Button);
prev_scene->set_flat(true);
prev_scene->set_tooltip_text(TTR("Go to previously opened scene."));
prev_scene->set_disabled(true);
prev_scene->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(FILE_OPEN_PREV));
gui_base->add_child(prev_scene);
prev_scene->set_position(Point2(3, 24));
prev_scene->hide();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some old control, but it doesn't appear to be used in any way. It's always hidden, and it's... just floating? I noticed it before, but didn't look further. But now it's removed because it's also requesting a non-existent icon.

Comment on lines -87 to -89
void add_editor_plugin(EditorPlugin *p_plugin);
void remove_editor_plugin(EditorPlugin *p_plugin);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't implemented on EditorInterface.

@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from 143e5b6 to 56b81f5 Compare September 10, 2023 15:44
@YuriSizov
Copy link
Contributor Author

I noticed a couple more issues, one was caught by the new check (so, yay!).

  • Some recent changes to the visual shaders plugin made a typo and were trying to fetch fonts from the icons type.
  • The create node dialog was missing icons because it was requesting them through another node for some reason, and that node didn't have the necessary information yet.

@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from 56b81f5 to 0c2ca76 Compare September 11, 2023 22:23
@YuriSizov YuriSizov requested a review from a team as a code owner September 11, 2023 22:23
@YuriSizov
Copy link
Contributor Author

YuriSizov commented Sep 13, 2023

I went ahead and replaced all remaining get_gui_base()->get_theme_* with get_editor_theme()->get_*. This addresses issues like #81586. In a lot of cases relevant code should likely be reworked to utilize the theme changed notification and correctly set colors and styles when it's received.

(Also rebased to make sure this captures all present cases).

@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from 0c2ca76 to 2fa1c03 Compare September 13, 2023 12:05
@YuriSizov YuriSizov requested review from a team as code owners September 13, 2023 12:05
@KoBeWi
Copy link
Member

KoBeWi commented Sep 13, 2023

Some remaining broken icon in GridMap:
image

@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from 2fa1c03 to a50838f Compare September 14, 2023 12:01
@YuriSizov YuriSizov requested a review from a team as a code owner September 14, 2023 12:01
@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from a50838f to 12de7eb Compare September 14, 2023 12:02
@YuriSizov
Copy link
Contributor Author

Some remaining broken icon in GridMap: image

Right, forgot to include the new get_editor_theme_icon calls when replacing. Adjusted those as well, mostly with a search and replace though in a couple of places I tried to correct the code to avoid calling into the editor node all together.

@YuriSizov YuriSizov force-pushed the editor-theme-access-the-success branch from 12de7eb to 8ecc0c4 Compare September 15, 2023 12:51
@YuriSizov YuriSizov merged commit df6cd37 into godotengine:master Sep 15, 2023
16 checks passed
@YuriSizov
Copy link
Contributor Author

Thanks for reviews!

@YuriSizov YuriSizov deleted the editor-theme-access-the-success branch September 15, 2023 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Theme color for 'error_color' is no longer red Some editor icons are broken in the ui (master branch)
5 participants