godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.05k stars 65 forks source link

Add font_focus_pressed_color on Button #9650

Open Frozenfire92 opened 2 weeks ago

Frozenfire92 commented 2 weeks ago

Describe the project you are working on

A game with a UI that supports both controller/keyboard and mouse to navigate. The UI uses CheckBox, CheckButton, or other toggleable buttons for configuration options.

Describe the problem or limitation you are having in your project

In a design where the button styling does not use the standard StyleBoxFlat for focus, and instead uses StyleBoxEmpty, meaning it does not have the outline on the button. It relies on font colors to indicate pressed or not and highlight/selection. When using mouse there is font_hover_pressed_color allowing the user to differentiate when a pressed button is highlighted/selected. When using controller or keyboard to navigate, there is no equivalent, meaning the controller user visually loses the indicator of which button they have focused (highlighted/selected) when that button is pressed. This is particularly problematic for a page of CheckBox's or CheckButton's used as configuration

Theme

image image

Controller/Keyboard

2024_05_01_0.webm

Mouse

2024_05_01_1.webm

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

This feature has two options that I am proposing

1) Introduce font_focus_pressed_color as a new theme item for the Button 2) Allow the use of font_hover_pressed_color for the scenario of focused and pressed as well

Either option will allow buttons that can be toggled to differentiate "selection" when using a controller or keyboard only for navigation. This will overcome the problem by allowing consistency between mouse and controller/keyboard input for navigating a UI

I like option 1 as it provides the most flexibility and clarity, but in my use case they would be the same color, so option 2 is just as feasible. I suspect most people who would want this feature also intend to have the color be the same between the two

The problem I foresee with option 2 if a name change didn't occur is that it only mentions hover and pressed, but now would be for hover pressed and focus pressed

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

For option 1 I have implemented it in https://github.com/godotengine/godot/pull/91240

For option 2 it should be a simplified version of 1's implementation, where a new theme color is not introduced. It could potentially rename the theme color (which wouldn't be a backward compatible change).

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

I believe it can be worked around with the following gdscript. I don't believe this is particularly convenient because it would need this script on each of the toggleable buttons wanting to override (Button, Checkbox, CheckButton for example). It also would require additional work to tweak any addons that expose UI using toggleable buttons. Where if this was engine/theme provided that additional work is not needed

class_name CheckBoxFocusPressedColor
extends CheckBox

@onready var font_hover_pressed_color = get_theme_color("font_hover_pressed_color")

func _ready():
    focus_entered.connect(on_focus_entered)
    focus_exited.connect(on_focus_exited)
    toggled.connect(on_toggled)

func on_focus_entered():
    if button_pressed:
        add_theme_color_override("font_pressed_color", font_hover_pressed_color)

func on_focus_exited():
    remove_theme_color_override("font_pressed_color")

func on_toggled(toggled_on):
    if has_focus():
        if toggled_on:
            add_theme_color_override("font_pressed_color", font_hover_pressed_color)
        else:
            remove_theme_color_override("font_pressed_color")

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

This gives developers more options when designing the theme for their game without requiring an add-on or custom scripts. It also provides consistency in behaviour when navigating with controller/keyboard as it does with mouse.

An addon would be similar to the script above, with the same issues of requiring additional work to make it fit into other addons that may expose UI