godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Add support for calculating a Material UI palette from a given color #9210

Open aiaimimi0920 opened 6 months ago

aiaimimi0920 commented 6 months ago

Describe the project you are working on

I am developing a simplified version of the UI control library for my AI pet, which allows players to participate in game creation, the UGC process.

Describe the problem or limitation you are having in your project

Because different UI scenes written by players are combined to form the final UI, it is easy to lead to inconsistent colors and unclear contrast.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I hope to be based on https://m3.material.io/styles/color/dynamic/choosing-a-source Implementing dynamic colors through a solution

image https://m3.material.io/styles/color/system/how-the-system-works

You can generate 29 colors through one based color to get a scheme, Then you can set the color_role of control, the control will get the real color by color_role and scheme

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

MCUSchemeContent

class MCUSchemeContent : public Resource {
    GDCLASS(MCUSchemeContent, Resource);

public:
    SchemeContent scheme = SchemeContent(Hct(0), false, 0);
    Color source_color;
    Ref<Texture2D> source_texture;
    bool is_dark = false;
    float contrast_level = 0;
    enum ColorRole {
        PRIMARY_PALETTE_KEY,
        SECONDARY_PALETTE_KEY,
        TERTIARY_PALETTE_KEY,
        NEUTRAL_PALETTE_KEY,
        NEUTRAL_VARIANT_PALETTE_KEY,
        BACKGROUND,
        ON_BACKGROUND,
        SURFACE,
        SURFACE_DIM,
        SURFACE_BRIGHT,
        ......
    }
}

MCU

MCU::MCU() {
    MCU::singleton = this;
    Ref<MCUSchemeContent> cur_scheme;
    cur_scheme.instantiate();
    cur_scheme->set_source_color(Color("#6750A4"));
    set_default_scheme(cur_scheme);
}

Control

@export var color_role = ColorRole.SURFACE
var show_mode = "dynamic"
@export var scheme = null

func get_scheme():
    if scheme == null:
        return MCU.get_default_scheme()
    return scheme

func _ready():
    var cur_scheme = get_scheme()
    if show_mode == "dynamic":
        color = cur_scheme.get_color(color_role)
    else show_mode == "static":
        pass

If this enhancement will not be used often, can it be worked around with a few lines of script?

You cannot solve this problem with just a few lines of code, as many godot controls have color properties, and many colors are included in the theme item, which is a major change.

Is there a reason why this should be core and not an add-on in the asset library?

  1. Dynamic color takes a single color from a user's wallpaper or in-app content and creates an accessible color scheme assigned to elements in the UI. If the user's wallpaper or the in-app content changes, the colors in the UI will change to match. https://m3.material.io/styles/color/system/how-the-system-works
  2. I think this helps to speed up the process of UI construction, at least by creating colors that are more reasonable

You can use this repository https://github.com/material-foundation/material-color-utilities Implement dynamic colors

You can refer to the plugin I wrote, https://github.com/aiaimimi0920/godot-ui-design. By the way, this plugin also implements elevation and other content, and based on https://m3.material.io/components I have extended the UI control. If this proposal is not adopted, I will consider using C++to re inherit and implement some UI controls in the future, and rename them as CustomiControl, CustomimText

Calinou commented 6 months ago

I feel this is better suited as an add-on, as Godot doesn't follow the Material UI guidelines and has no plans to do so that I know of.

aiaimimi0920 commented 6 months ago

I feel this is better suited as an add-on, as Godot doesn't follow the Material UI guidelines and has no plans to do so that I know of.

I don't want to implement the entire Material UI guidelines, I just want to implement dynamic colors. The goal is to allow players to set a color or a color role when set a control color

As an additional implementation, the biggest issue is that colors are present in various basic UI controls and themes, If it is to be used as an add on, basically all UI controls need to be rewritten

aiaimimi0920 commented 6 months ago

I feel this is better suited as an add-on, as Godot doesn't follow the Material UI guidelines and has no plans to do so that I know of.

If you mean that I hope to obtain the specific values of dynamic colors in some way, then it is indeed very suitable as a plugin.

But I hope this color change can automatically occur in the control. You just need to specify the color role when set the color

Jesusemora commented 6 months ago

This can totally be done in a few lines of code.

aiaimimi0920 commented 6 months ago

@Calinou You can dynamically switch colors based on the content to adapt to the colors of UI controls

like this: https://github.com/godotengine/godot-proposals/assets/153103332/95acdc4c-6903-4b69-ac9d-b58519165ab7

this is the code: https://github.com/aiaimimi0920/godot/tree/dynamic_color

If you need dynamic colors, you can use this code compilation engine.

Note: The default_theme.cpp in it may require some updates, and I have not fully found the most suitable color ratio yet

Shadowblitz16 commented 1 month ago

This can totally be done in a few lines of code.

provide code then don't just claim it's possible.