godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.33k stars 21.06k forks source link

focus layer is covering up pressed, hover, and disable #30856

Closed Shadowblitz16 closed 4 years ago

Shadowblitz16 commented 5 years ago

Godot Version: 3.1.1 OS: Windows 7 home 64 bit

the gui focus style should be drawn in place of other styles instead on top of them. it makes it extremely hard to not only understand but make a pixel art style theme when it drawn ontop.

if anything disabled, pressed, and hover should take priority over the focus style and be drawn on top of it in that order.

It doesn't really make sense when you press a control and its stuck looking focused because the order is not correct.

CowThing commented 5 years ago

This is intentional. The focus style is not meant to replace any other style, because it just indicates which button currently has focus. A button can be in a normal, pressed, or hover state while still having focus. The default focus style is just a blue outline with a transparent center, so it outlines the button which is rendering another style.

Shadowblitz16 commented 5 years ago

@CowThing yes but in the case that people don't want to use a blue outline and want to use a solid texture or solid color this breaks things. and most styles no longer work because they are drawn under the focus.

CowThing commented 5 years ago

Do you have an example? It wouldn't make sense to have a solid color for the focus style because the focus style is only meant to highlight the GUI element that currently has focus. This isn't just exclusive to buttons either, other GUI nodes have focus styles as well.

TheDuriel commented 5 years ago

It does not break things if you use the Focus style as intended. As an overlay. However, even a solid rect will function as a Focus style, since it is simply drawn on top of the current style. So i don't see the issue. Unless your focus is smaller than the base, in which case thats a problem with your assets. (All of this is in fact.)

Calinou commented 5 years ago

@Shadowblitz16 You could use a translucent filled overlay if you want to affect the interior of the focused StyleBox :wink:

Shadowblitz16 commented 5 years ago

I don't want to use transparent overlay.

why do you guys even need focus to be drawn on top of pressed and hovered and disabled? it should just be drawn when idle. your not going to need to know if it focused while pressing, hovering, or it being disabled

it's the most confusing thing. if anything the order of styles drawn should be a option.

Calinou commented 5 years ago

why do you guys even need focus to be drawn on top of pressed and hovered and disabled? it should just be drawn when idle.

It'd look strange if the focus outline suddenly disappeared as you hover or click UI elements.

it's the most confusing thing. if anything the order of styles drawn should be a option.

It works in a similar way in CSS, so I'd say many people are familiar with it :slightly_smiling_face:

MuffinManKen commented 5 years ago

If you provided an example of what you're trying to do it might help others understand your need. Otherwise it just sounds like you're saying "this didn't work how I thought it would, so it's wrong".

Shadowblitz16 commented 5 years ago

@MuffinManKen for example if you don't want to use a overlay for focus and want to use a opaque texture that looks as if the pixel colors are changing then hover and pressed don't work because the opaque focus style is drawn over it.

this completely defeats the point in having a full texture or opaque color in the first place.

if there was some sort of theme option maybe in the style constants to draw focus behind disabled, pressed, and hovered and documentation on how the focus style actually worked.

both problem would be solved. the user could use a overlay for the focus style for transparent colors and textures and use my suggested overlay for opaque textures and colors

TheDuriel commented 5 years ago

Can you just... Like... upload of screenshots of the textures, and how they are meant to look when used?

Shadowblitz16 commented 5 years ago

gui

GIF

this is what I mean first image is my my textures second is a gif of me clicking on it but nothing happens because the focus is drawn over it

simply making everything a overlay and allowing the user to reorder the draw layers would work. then everybody can be happy

this would allow things like pressed, hover, disabled, and normal be transparent overlays for buttons, AND I could just make the focus rectangle be drawn behind everything but the normal layer and then use opaque textures and colors.

this could be done with every control in which styles are just draw layers that can be customized to fit the users needs

TheDuriel commented 5 years ago

Speaking as a UX artist what you are asking does not seem very useful.

Adding the ability to change the focus style to replace instead of draw over could be useful in allowing existing non Godot conform assets to be more easily implemented however.

Shadowblitz16 commented 5 years ago

I don't see how setting the focus to replace is more useful than allowing the user to completely have control over what draws first

TheDuriel commented 5 years ago

All control styles except for focus are exclusive. There would be no point in "changing the order."

MuffinManKen commented 5 years ago

What are you trying to achieve with the focus texture? From your example, that wasn't clear to me.

This seems like it would add complexity to the code, potentially hurt performance, and only solve a very niche need. I don't see why that should be added to the engine.

Either way, you should be able to override the drawing of your button and get what you want.

Shadowblitz16 commented 5 years ago

@TheDuriel I just explained how it would not be pointless it would also allow people to use transparent textures for all styles not just focus

@MuffinManKen It would not add complexity it would just be a list of styles in which the c++ code would draw first to last ontop of eachother which would be rearrangeable

TheDuriel commented 5 years ago

You can already do that. Styles are exclusive. The only one that renders on top is the focus style. Your problem literally can not exist with the others.

Shadowblitz16 commented 5 years ago

yes but having them all render on top AND be rearrangeable would make the gui system much more customizable. you could literally have all your layers transparent if you wanted to and it more be more consistent

groud commented 5 years ago

Sorry, but this is unlikely to happen. The design philosophy behind Godot is to keep things simple (API and usability wise) for the most common use cases. Here, the current system covers the most common use case, which is having a focus rectangle drawn on top of the other styles. So any more complex system is unlikely to be added.

If you have a more specific use case, you should use a script for that. You can use either the _draw method, or even dynamically change the button style to fit your use case.

MuffinManKen commented 5 years ago

@Shadowblitz16 I'm not sure how you think that adds no complexity and couldn't hurt performance.

And it has been mentioned multiple times now that you can do this yourself in GDScript, but you've ignored every mention.

Shadowblitz16 commented 5 years ago

the current gui system has a ton of flaws, namely when it comes to paletted pixel art. if you guys aren't going to listen to how other people want to use godot, it will never be the best engine out there.

what it comes down to is that it's already really confusing when people don't know why their control styles are not working because some styles are overlays while others are not. this is what I think is complex.

it should be one or the other to make it more clear and making everything a rearrangeable overlay would do this while not sacrificing useability.

TheDuriel commented 5 years ago

what it comes down to is that it's already really confusing when people don't know why their control styles are not working because some styles are overlays while others are not. this is what I think is complex.

We've been telling you. Literally only the focus style does this. This is expected behavior. You can tell how and why it does this by simple looking at the godot editor, where it is used everywhere.

Shadowblitz16 commented 5 years ago

so what about what @TheDuriel said?

Adding the ability to change the focus style to replace instead of draw over could be useful in allowing existing non Godot conform assets to be more easily implemented however.

what would be the point of this if it always is replacing pressed, disabled, and hover?

MuffinManKen commented 5 years ago

The way Focus works now is the way most people would expect it to. For those who want the behaviour that you do, this is easy to do this without any changes to the engine, so for those who want to do it, they can.

Shadowblitz16 commented 5 years ago

I mean it wouldn't make sense to have a replace option if pressed, hovered, and disabled didn't have priority.

it would just be focus all the time.

Calinou commented 4 years ago

I'll close this issue, as the current behavior is the behavior expected in most cases. Moreover, changing this would break compatibility with existing projects for little gain (if any).

Shadowblitz16 commented 3 years ago

please reopen this @Calinou I strongly think that the godot devs are overlooking the basics of gui states.

The following states should be rendered in order..

A focus rectangle is not the same as a focus style. A focus rectangle is what should be rendered on top of everything and if thats your intention then it should be renamed and we should have the ability to apply a actual focus style too.

If there is a need to overlay something over pressed and hovered you can usually get around it make it transparent or adding it to the texture.

Disabled style is the only exception but most of the time your not disabling something that the user is focused on and even then a focus rectangle gets around this.

Calinou commented 3 years ago

@Shadowblitz16 This should be discussed in a proposal.

JaboDLJ commented 3 years ago

I know this is an old thread and it sounds like I might be in the minority here but I can understand where @Shadowblitz16 is coming from.

For instance in my use case the menu has a stained glass theme where the button lights up when hovered and when clicked the color scheme changes. This works just fine with Hover but not with Focused since it over draws everything rending the other states meaningless.

I think having an option to make Focused render the same way that Hover does would be hugely valuable. The blue outline description makes sense from a software UI/UX design standpoint but part of what makes game menus fun is they can take a lot of artistic liberty in how they draw user attention to the current interaction point.

Not even having the option to use this functionality in a different way means that designers wanting to use Godot have to pick between supporting accessibility, compromising their presentation, or looking for a solution besides Godot which seems like a bummer to me.

That being said I'm fairly new to Godot so I'm hoping this has been addressed in some way and I just haven't found it yet.

JaboDLJ commented 3 years ago

So I did some tinkering today and I think I have a reasonable solution.

As it turns out in Godot 3.3.3.stable at least if no Focused texture is set but the button receives focus then the Hover texture is actually applied.

So for my game menu I did two things: First I defined all the applicable focus transition settings (Under Control>Focus in the inspector) Second I added this to my main loop along with a var noButtonsPressed set to true at run:

if noButtonsPressed and (Input.is_action_just_pressed("ui_up") or Input.is_action_just_pressed("ui_down")): newGameBut.grab_focus() noButtonsPressed = false

This way the menu functions as expected with a mouse but the first time the user presses up or down on the keyboard or gamepad it assigns focus to the first item in the list. After that the menu can be navigated by button presses, the Hover texture is applied to whatever has focus and the pressed texture is still displayed when the button is activated.

This could be tailored to other inputs too for menus more complicated than just a vertical layout like mine.

Hope that helps! Also if anyone has a more elegant solution please sound off! I don't know about others but this thread was one of the first hits for me when I googled this issue.

jackcasey commented 2 years ago

This is a problem IMO.

I am just trying to have a button that is dark normally. Has an outline when hovered or focused, and moves down a pixel when pressed (the whole button 'clicks' down, so the outline should follow). IE using 3 different images and clicked being priority. blue blue_focused blue_pressed

Here is what I've figured out:

  1. Use the hover image as the focused image. Godot_v3 4 2-stable_win64_3c7USBESpe This is obviously no good as when the button is clicked it is also "focused" so the clicked image is always hidden behind the focus "overlay". This made the most sense to me. I assumed clicked would "overrule" focused as as higher priority style.

  2. Use a transparent overlay as the focus image as god(ot) intended. blue_focus_overlay Godot_v3 4 2-stable_win64_TJwEwhrNp0 The focus overlay can't move with the button or text when it gets pressed down :(

  3. Clear the focused image in the theme, or leave it as empty: image image Godot_v3 4 2-stable_win64_jIO11dHKEX Now Godot is automatically applying a blurry outline for the focus. Not good.

  4. Use a StyleBoxEmpty as the focus style and just do without focus effects. image Godot_v3 4 2-stable_win64_f0Gh1eueKd This works ok for mouse driven games as focus isn't important as you always hover and click. But it means you have to make do with font color etc as a focus if you want to use a gamepad or keyboard to navigate the UI.

Basically if you want an image focus effect to change when clicked (eg move, or change color) you're out of luck? Or am I missing something?

TheDuriel commented 2 years ago

You are when it comes to built in nodes. But, making your own button is very very easy. You simply subscribe to the same events in a TextureRect node as a button would. Implement the same signals.

Ultimately: A Button Node is just a Control Node with a few lines of code to change the image. Literally all the behavior for focusing, pressing, hovering, is found in Control.

jackcasey commented 2 years ago

Ah, that's good to know. Thanks for the tip.

Shadowblitz16 commented 2 years ago

@TheDuriel @Calinou This is dumb ran into the issue today again with 4.0. Can you at least show me a example of when focus should overlap the pressed style? I see absolutely no reason to. When you press something you want to get visual feedback that your pressing it, If the focus layer is opaque which it is in pixel art 99% of the time there is no way to tell if what state it is in.

Focus font color and style should only show when it is focused and in normal state.

The use case I am trying to use it for CANNOT be replicated in Godot with the current system. Your use case CAN be represented in the way I am proposing it should be.

All you would have to do for your use case is draw a separate sprite per style.

Here is a layout of how the current system and my suggested system differ...

|-Overall Represented state-|-Current-Style--|-Suggested-Style--|
| Not Focused & Normal      | Normal         | Normal           |
| Not Focused & Hovered     | Hovered        | Hovered          |
| Not Focused & Disabled    | Disabled       | Disabled         |
| Not Focused & Pressed     | Pressed        | Pressed          |
| Focused & Normal          | Focused        | Focused          |
| Focused & Hovered         | Focused        | Hovered          |
| Focused & Disabled        | Focused        | Disabled         |
| Focused & Pressed         | Focused        | Pressed          |
Shadowblitz16 commented 2 years ago

made a issue here that would cover all users cases... https://github.com/godotengine/godot-proposals/issues/4869