Open digimbyte opened 2 months ago
It would be nice if there was some type of style file that you can write as an actual CSS file, then the engine "compiles" it for proper display. Just like how shaders work, it would be much more straight forward than looking into that clunky theme properties tab.
possibly, but that is an additional layer on top of theme files already. being able to easily edit and transpose components would be a very nice QoL though
Shouldn't this be in Redot proposals?
Shouldn't this be in Redot proposals?
No issues tab over there :)
Just to highlight complexity, CSS is Turing complete, which is a mess to implement. I'd suggest a strict subset.
I had an import script for css somewhere, but this is only ever a topic because the theme editor is abysmal. Fixing that solves the problem.
css isn't enough, this is about inheritance from parent themes but I agree that the theme editor could be enhanced to a better viewport rather than hiding in the debug/log area
css isn't enough, this is about inheritance from parent themes but I agree that the theme editor could be enhanced to a better viewport rather than hiding in the debug/log area
Not that it's hiding, it's just not good.
Having used Godot's Theming system, they already do cascade, the only thing is that you must target the node for theming, when you assign a theme to a node all the node's children and grandchildren also adopt the theme, this does not apply to the node's theme variables you assign to each node because that is not how you're supposed to use them. But if you apply a theme, the parent's theme variable takes control until a child theme overrides the variable and which applies then to all its children afterwards.
In this image, the "big" button text defines a style that the "small" button text inherits, the "small" button has no styles on it but does define an arial black font that looks bold, the "big" button has the blue style, and parent to the "big" button defines both a red style and an arial font that is used by the "big" button:
could you clarify? I don't see a comparison of cascading with before and after as I'm not referring to a whole theme inheritance from parents
Theme overrides are not supposed to apply to children, themes are, if you need cascading themes, you use the theming system, it literally does what you're asking for. I told you what is going on here, you can see the scene tree on the left, two buttons and a control, all of them have themes for a button on them. The control defines a theme with a red style and an arial font for the button node, (this is distinct from the standard font) the first button has a theme that only defines a blue style, and the second button has a theme that only defines the arial black ("bold") font. Neither button's theme defines the full context of their display, the result is a combination of elements of their own and parent themes for both buttons. I literally followed your reproduction steps via the theming system to produce this result.
perhaps there is room for improvement and clarity in the editor as I was using the theme system as it was presented. and making a cascading green text + thick green border was impossible as targeting the node and setting the theme left the remaining content default (gray dead theme)
my current solution is to grab the theme and modify the details on runtime per demand and to apply it as other methods did not preserve the parent styles
I'll need to see your project or a demo to comment specifically on what you're doing, it sounds like you're misunderstanding how it functions.
seems pretty self explanatory, create a base theme, create another theme for selections, and apply selection theme to panel card. the selection theme only has base modifiers set. but when applied as-is, it does not perform a partial inherit. the only way around this is to override each element manually, so there is a clear breakdown in how styles are defined and applied if that is not the 'optimal way' to use the theme system
current code workaround:
# Entry point function to select and apply theme
func select():
var current_node = self # The node this script is attached to
if current_node:
print("Starting node: ", current_node.name)
original_theme = find_theme(current_node)
if original_theme:
# Clone and modify the theme
modified_theme = clone_and_modify_theme(original_theme)
apply_theme(current_node, modified_theme) # Apply to node only
else:
print("Error: No theme found in the tree.")
else:
print("Error: Current node not found.")
# Function to clone and modify the existing theme
func clone_and_modify_theme(source_theme: Theme) -> Theme:
var new_theme = Theme.new()
# Clone all existing styleboxes for Control (including Panels)
var stylebox_names = ["panel"] # List stylebox names you need to clone
for stylebox_name in stylebox_names:
var style_box = source_theme.get_stylebox(stylebox_name, "Panel")
if style_box:
var cloned_style_box = style_box.duplicate() # Duplicate the StyleBox
new_theme.set_stylebox(stylebox_name, "Panel", cloned_style_box)
# Clone all existing colors
var color_names = ["font_color"] # List color names you need to clone
for color_name in color_names:
var color = source_theme.get_color(color_name, "Panel")
if color:
new_theme.set_color(color_name, "Panel", color)
# Clone all existing fonts
var font_names = ["font"] # List font names you need to clone
for font_name in font_names:
var font = source_theme.get_font(font_name, "Panel")
if font:
new_theme.set_font(font_name, "Panel", font)
# Modify specific styleboxes
var modified_style_box = new_theme.get_stylebox("panel", "Panel")
if modified_style_box:
modified_style_box.border_color = Color("01FD91")
modified_style_box.border_width_top = 12
modified_style_box.border_width_bottom = 12
modified_style_box.border_width_left = 12
modified_style_box.border_width_right = 12
new_theme.set_stylebox("panel", "Panel", modified_style_box)
# Modify specific colors for Label nodes
var modified_color = Color("01FD91")
new_theme.set_color("font_color", "Label", modified_color)
return new_theme
if this is natively supported, the usability of this is severely under appreciated as there are plugins online to address cascading and inheritance through various means, including a CSS-like port
Themes "inheriting" through the scene tree is the feature I forgot. That does what OP wants. Don't implement a parallel system for it, just because it's not exactly how OP imagines it should work.
Themes "inheriting" through the scene tree is the feature I forgot. That does what OP wants. Don't implement a parallel system for it, just because it's not exactly how OP imagines it should work.
as I said, if this does exist natively, this needs to be brought forward as a feature. as there are countless requests for theme blending (cascading) from inheritance
this is because currently applying a partially defined theme uses the default theme as a baseline rather than the parent inheritance
this is because currently applying a partially defined theme uses the default theme as a baseline rather than the parent inheritance
Maybe the child theme still contains items from the base theme, so it overrides it with that.
this is because currently applying a partially defined theme uses the default theme as a baseline rather than the parent inheritance
Everything that is defined in a parent's theme will be inherited by all descended node themes unless those descended themes modify the same override, (if it doesn't it will pick the theme type variant's closest relevant parent theme as the basis for that node) node theme overrides are exclusive to the theme type variant they are assigned to, so a font on a button will not inherently apply, by default the node's class name is its theme type variant name, but any node can have a custom theme type variant assigned to it and any theme type variant in a theme can have a base type which will ease the use of picking the theme overrides in the theme editor.
For example if you modify a font_color on a button, (which by default has the theme type variant Button) it doesn't apply to the font_color on a label, (whose default theme type variant is Label) they are segregated concepts unless they are the same theme type variant and the theme override is typed and named the same for both. The engine requires your themes to define each node's theme overrides variables individually for each node, if it didn't then there are actually cases where the engine would be incapable of distinguishing between Styleboxes on certain nodes. (there are a lot of Control nodes that rely on this segregated theme type variant behavior)
You should read through GUI Skinning, Using Theme Editor, and Theme Type Variations.
Reading what you wrote it seems you misunderstand how themes are supposed to work, there is no possible way for the engine to apply theme overrides to every node as even if you could it will literally break both the theming system and nodes themselves if it were to do so.
Also to point out you don't need to replace the font for every theme and node.
Tested versions
always present
System information
windows 10 - godot 4.3 stable
Issue description
The current system in Redot Engine for theme inheritance lacks flexibility when dealing with partial themes. Developers must manually define every element for child themes, which can disrupt visual cohesion when only minor adjustments are needed across different UI panels.
The proposed feature introduces cascading themes, allowing parent themes to cascade or bleed elements to their children. If a child theme has a partially defined theme and lacks certain elements, it will reference its parent theme instead of defaulting to the global theme. This ensures that minor changes like bold fonts or selection borders can be applied to child elements while maintaining consistency with parent panels. This feature will improve synergy between parent and child panels and simplify theme management.
Benefits:
Steps to reproduce
Expected behavior: The child panel should display the custom bold font while inheriting the other elements from the parent theme, such as colors and borders.
Minimal reproduction project (MRP)
N/A