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

Add theme_custom_type property to Control and Window #47544

Merged
merged 1 commit into from
May 18, 2021

Conversation

YuriSizov
Copy link
Contributor

@YuriSizov YuriSizov commented Apr 1, 2021

Part of godotengine/godot-proposals#2505.

Edit: Property was renamed from theme_type_override to theme_custom_type after Groud's suggestion. Screenshots and clips refer to it by the old name, so be aware.

This introduces a new Control property theme_custom_type which allows users to define a higher priority theme type to be used when Controls fetch their own theme items (e.g. by calling get_theme_color("font_color") without a type specified). By default the class name of the Control is used, and then the class names of all of the parent classes. If theme_custom_type is defined, it is considered before the class names. As before, local theme item overrides are considered first.

This system allows to add subclasses for Controls without creating scripts or manually overriding each property, which means all definitions can be stored inside of a single Theme resource and, for example, can be swapped for an alternative Theme with minimal effort. Overriding types can be partial, and in that case they fallback on the class name definitions.

In the example below AcceptButton and CancelButton have theme_custom_type property set to a value of the same name, while RegularButton has it empty. Theme that is applied to the entire branch defines normal and hover states for Button and overrides normal states for AcceptButton and CancelButton types. Title label also has its own custom type.

godot windows tools 64_2021-04-01_14-35-35
godot windows tools 64_2021-04-01_14-36-46

2021-04-01_14-36-07.mp4

I've tried to make this PR backwards compatible, however current code has at least 2 copy'n'paste errors as well as a big inconsistency to how theming is applied. I had to address those, so the way theming works is a bit different now. It is more correct and consistent, but it may lead to things looking differently if particular features were used.

These issues were addressed in the process of making this PR. To ensure that it is less likely to happen in future I've refactored parts of Control to use the new Theme methods that rely on DataType enum and reduced the number of replicated code snippets between similar methods.

The inconsistency in the current theming process is related to which types are used when looking for theme item definitions. The process currently is as follows:

  1. Take the passed type name and check if the current node has a Theme, and if it has, whether there is an item we seek with that type name.
  2. As the type name is expected to default to class name, we can look for its parent class' name and repeat the check for that (so, for Button we first check if the item exists in the type Button, then BaseButton, then Control).
  3. If nothing was found, move up the tree to the parent node and repeat steps 1-2.
  4. If nothing was found before the chain of Controls has ended we check the Project default Theme and the engine default Theme.

The problem with step 4 is that in those default themes only the base type name is checked (e.g. Button), but parent class' names are not checked. This means that applying your custom Theme to the topmost Control node is not the same as applying it in the Project Settings. This also means that the default Theme works differently than user created Themes. I've tried to work around it, but ultimately to allow custom types which was the goal of this PR I has to address the issue and fix the behavior.

I think this was an incorrect behavior and that the fix should be backported to 3.x, but it is definitely not strictly compatible. So there is that.


Note, that having an custom type like this is a desirable feature and was requested by users in the feedback to godotengine/godot-proposals#2505. This PR is required for that proposal to be implemented fully, but if rejected for whatever reason, some of the related functionality can be omitted. I've decided to put this forward ahead of time to properly evaluate that particular enhancement, as it touches core of the theming system and is not directly related to the Theme editor itself.

Oh, and this also renames node_type arguments to theme_type, as they aren't strictly related to nodes, they just default to class names a lot of time. And custom types can be absolutely abstract, as seen in the editor itself with Editor, EditorIcons, etc.

@YuriSizov YuriSizov added this to the 4.0 milestone Apr 1, 2021
@YuriSizov YuriSizov requested review from a team as code owners April 1, 2021 12:42
@YuriSizov YuriSizov changed the title Add theme_type_override property to Control and Window Add theme_custom_type property to Control and Window Apr 1, 2021
@YuriSizov
Copy link
Contributor Author

Property renamed after Groud's suggestion.

@YuriSizov
Copy link
Contributor Author

YuriSizov commented May 5, 2021

Apparently those issues with theme propagation I've described are documented here:
https://docs.godotengine.org/en/stable/tutorials/gui/gui_skinning.html#theme

So this hopefully improves the overall situation and we can remove that note next 🙂

scene/gui/control.h Outdated Show resolved Hide resolved
Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

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

Code looks ok, some refactoring is always welcome.

As for the custom type feature, it looks handy, but personally I don't see much use for it. Well, maybe it helps to avoid some overrides. Also it's rather small, so it could be ok if some people requested it.

@YeldhamDev
Copy link
Member

@KoBeWi When designing a UI that tries to give hints to the user on the where to go, differently themed elements are a must. And depending on the quantity, it can clutter your scripts quite a lot. This PR could make things far more easier from the get-go.

@akien-mga akien-mga merged commit 66dac8b into godotengine:master May 18, 2021
@akien-mga
Copy link
Member

Thanks!

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.

4 participants