Download

[UMG] Disabled buttons always grey

In my UI, I need buttons to periodically be disabled, but can’t seem to get them to style correctly. Whenever I disable a button, it’s always grey, even though the styling doesn’t have any tinting.

Any ideas? I’m seeing this across all buttons types.

Add a Bool to your Widget for that button and do a branch in the onclick event. I dont like the Button Control myself. Did everything with Borderr’s and Images

I may wait for 4.6 to see if that helps. I’m seeing a number of instances where there appears to be some sort of hard coded styling that’s applied to various widgets, which is pretty frustrating and I can’t imagine is the intended functionality. I’m seeing the same thing with scroll bar handles, where they always tint when grabbed & moused over.

Okay here is the trick make an image component or any other component and put it ontop of your button. When you want to disable the button you enable the Visibility of that component to “Visible” and when you want to disable set it to hit test invisible

That’s clever. I’ll try that. Thanks!

Seven months on, this still isn’t fixed in the latest build (4.8.2).

If you are building from source you can patch in the following couple of lines. Changed lines are prefixed with ‘BBB:’.
While I can’t see this breaking anything else, I haven’t done a git pull request as (I am busy/lazy and) Epic has a lot of fallback code to make assets generated with prior builds work with the latest version.
I am still on 4.7.6 as I have a lot of engine mods (and general distrust about making wholesale changes at this stage in the project).
Works for me, your results may vary ™ - AKA use at your own risk.

UnrealEngine\Engine\Source\Runtime\UMG\Private\Components\Button.cpp



...
TSharedRef<SWidget> UButton::RebuildWidget()
{
	MyButton = SNew(SButton)
		.ButtonStyle(&WidgetStyle)
		.ClickMethod(ClickMethod)
		.TouchMethod(TouchMethod)
		.IsFocusable(IsFocusable);		

	// BBB:
	MyButton->SetShowEffectWhenDisabled(false);

	if ( GetChildrenCount() > 0 )
	{
		Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
	}
	
	return MyButton.ToSharedRef();
}
...


UnrealEngine\Engine\Source\Runtime\Slate\Public\Widgets\Input\SButton.h



protected:
...
/** Brush resource that represents a button when it is pressed */
const FSlateBrush* PressedImage;
/** BBB: Brush resource that represents a button when it is disabled */
const FSlateBrush* DisabledImage;
...


UnrealEngine\Engine\Source\Runtime\Slate\Private\Widgets\Input\SButton.cpp



...
void SButton::SetButtonStyle(const FButtonStyle* ButtonStyle)
{
	/* Get pointer to the button style */
	Style = ButtonStyle;

	NormalImage = &Style->Normal;
	HoverImage = &Style->Hovered;
	PressedImage = &Style->Pressed;

	// BBB:
	DisabledImage = &Style->Disabled;

	BorderPadding = Style->NormalPadding;
	PressedBorderPadding = Style->PressedPadding;
}
...
const FSlateBrush* SButton::GetBorder() const
{
	if (IsPressed())
	{
		return PressedImage;
	}
	else if (IsHovered())
	{
		return HoverImage;
	}
	// BBB:
	else if (!IsEnabled())
	{
		return DisabledImage;
	}
	else
	{
		return NormalImage;
	}
}
...


So…
In UE4.8 Epic have solved this problem a different way - by hiding the slate disabled style for buttons entirely.

This means the code above is really now moot (you should just design your screens around using setvisibility hidden).
If you want to continue down the path of rampant customization against the way Epic now does things you will need to add the following.
Note that this will affect every button on every screen (buttons must now have a disabled style if they are to ever be disabled).

UnrealEngine\Engine\Source\Runtime\SlateCore\Public\Styling\SlateTypes.h



...
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Appearance)  // BBB: Was UPROPERTY() to hide from blueprints
FSlateBrush Disabled;
FButtonStyle& SetDisabled( const FSlateBrush& InDisabled ){ Disabled = InDisabled; return *this; }
...