347 lines
13 KiB
C++
347 lines
13 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Misc/Attribute.h"
|
|
#include "Input/Reply.h"
|
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
|
#include "Styling/SlateColor.h"
|
|
#include "Layout/Margin.h"
|
|
#include "Sound/SlateSound.h"
|
|
#include "Styling/SlateTypes.h"
|
|
#include "Styling/CoreStyle.h"
|
|
#include "Framework/SlateDelegates.h"
|
|
#include "Styling/SlateWidgetStyleAsset.h"
|
|
#include "Widgets/Layout/SBorder.h"
|
|
|
|
class FPaintArgs;
|
|
class FSlateWindowElementList;
|
|
enum class ETextFlowDirection : uint8;
|
|
enum class ETextShapingMethod : uint8;
|
|
|
|
/**
|
|
* Slate's Buttons are clickable Widgets that can contain arbitrary widgets as its Content().
|
|
*/
|
|
class SButton : public SBorder
|
|
{
|
|
SLATE_DECLARE_WIDGET_API(SButton, SBorder, SLATE_API)
|
|
|
|
#if WITH_ACCESSIBILITY
|
|
// Allow the accessible button to "click" this button
|
|
friend class FSlateAccessibleButton;
|
|
#endif
|
|
public:
|
|
|
|
SLATE_BEGIN_ARGS( SButton )
|
|
: _Content()
|
|
, _ButtonStyle( &FCoreStyle::Get().GetWidgetStyle< FButtonStyle >( "Button" ) )
|
|
, _TextStyle( &FCoreStyle::Get().GetWidgetStyle< FTextBlockStyle >("ButtonText") )
|
|
, _HAlign( HAlign_Fill )
|
|
, _VAlign( VAlign_Fill )
|
|
, _ContentPadding(FMargin(4.0, 2.0))
|
|
, _Text()
|
|
, _ClickMethod( EButtonClickMethod::DownAndUp )
|
|
, _TouchMethod( EButtonTouchMethod::DownAndUp )
|
|
, _PressMethod( EButtonPressMethod::DownAndUp )
|
|
, _DesiredSizeScale( FVector2D(1,1) )
|
|
, _ContentScale( FVector2D(1,1) )
|
|
, _ButtonColorAndOpacity(FLinearColor::White)
|
|
, _ForegroundColor(FSlateColor::UseStyle())
|
|
, _IsFocusable( true )
|
|
{
|
|
}
|
|
|
|
/** Slot for this button's content (optional) */
|
|
SLATE_DEFAULT_SLOT( FArguments, Content )
|
|
|
|
/** The visual style of the button */
|
|
SLATE_STYLE_ARGUMENT( FButtonStyle, ButtonStyle )
|
|
|
|
/** The text style of the button */
|
|
SLATE_STYLE_ARGUMENT( FTextBlockStyle, TextStyle )
|
|
|
|
/** Horizontal alignment */
|
|
SLATE_ARGUMENT( EHorizontalAlignment, HAlign )
|
|
|
|
/** Vertical alignment */
|
|
SLATE_ARGUMENT( EVerticalAlignment, VAlign )
|
|
|
|
/** Spacing between button's border and the content. */
|
|
SLATE_ATTRIBUTE( FMargin, ContentPadding )
|
|
|
|
/** If set, overrides the button style's additional spacing between the button's border and the content when not pressed. */
|
|
SLATE_ATTRIBUTE( FMargin, NormalPaddingOverride )
|
|
|
|
/** If set, overrides the button style's additional spacing between the button's border and the content when pressed. */
|
|
SLATE_ATTRIBUTE( FMargin, PressedPaddingOverride )
|
|
|
|
/** The text to display in this button, if no custom content is specified */
|
|
SLATE_ATTRIBUTE( FText, Text )
|
|
|
|
/** Called when the button is clicked */
|
|
SLATE_EVENT( FOnClicked, OnClicked )
|
|
|
|
/** Called when the button is pressed */
|
|
SLATE_EVENT( FSimpleDelegate, OnPressed )
|
|
|
|
/** Called when the button is released */
|
|
SLATE_EVENT( FSimpleDelegate, OnReleased )
|
|
|
|
SLATE_EVENT( FSimpleDelegate, OnHovered )
|
|
|
|
SLATE_EVENT( FSimpleDelegate, OnUnhovered )
|
|
|
|
/** Sets the rules to use for determining whether the button was clicked. This is an advanced setting and generally should be left as the default. */
|
|
SLATE_ARGUMENT( EButtonClickMethod::Type, ClickMethod )
|
|
|
|
/** How should the button be clicked with touch events? */
|
|
SLATE_ARGUMENT( EButtonTouchMethod::Type, TouchMethod )
|
|
|
|
/** How should the button be clicked with keyboard/controller button events? */
|
|
SLATE_ARGUMENT( EButtonPressMethod::Type, PressMethod )
|
|
|
|
SLATE_ATTRIBUTE( FVector2D, DesiredSizeScale )
|
|
|
|
SLATE_ATTRIBUTE( FVector2D, ContentScale )
|
|
|
|
SLATE_ATTRIBUTE( FSlateColor, ButtonColorAndOpacity )
|
|
|
|
SLATE_ATTRIBUTE( FSlateColor, ForegroundColor )
|
|
|
|
/** Sometimes a button should only be mouse-clickable and never keyboard focusable. */
|
|
SLATE_ARGUMENT( bool, IsFocusable )
|
|
|
|
/** The sound to play when the button is pressed */
|
|
SLATE_ARGUMENT( TOptional<FSlateSound>, PressedSoundOverride )
|
|
|
|
/** The sound to play when the button is clicked */
|
|
SLATE_ARGUMENT( TOptional<FSlateSound>, ClickedSoundOverride )
|
|
|
|
/** The sound to play when the button is hovered */
|
|
SLATE_ARGUMENT( TOptional<FSlateSound>, HoveredSoundOverride )
|
|
|
|
/** Which text shaping method should we use? (unset to use the default returned by GetDefaultTextShapingMethod) */
|
|
SLATE_ARGUMENT( TOptional<ETextShapingMethod>, TextShapingMethod )
|
|
|
|
/** Which text flow direction should we use? (unset to use the default returned by GetDefaultTextFlowDirection) */
|
|
SLATE_ARGUMENT( TOptional<ETextFlowDirection>, TextFlowDirection )
|
|
|
|
SLATE_END_ARGS()
|
|
|
|
SLATE_API virtual ~SButton();
|
|
|
|
protected:
|
|
SLATE_API SButton();
|
|
|
|
public:
|
|
/** @return the Foreground color that this widget sets; unset options if the widget does not set a foreground color */
|
|
virtual FSlateColor GetForegroundColor() const final
|
|
{
|
|
return Super::GetForegroundColor();
|
|
}
|
|
|
|
/** @return the Foreground color that this widget sets when this widget or any of its ancestors are disabled; unset options if the widget does not set a foreground color */
|
|
SLATE_API virtual FSlateColor GetDisabledForegroundColor() const final;
|
|
|
|
/**
|
|
* Returns true if this button is currently pressed
|
|
*
|
|
* @return True if pressed, otherwise false
|
|
* @note IsPressed used to be virtual. Use SetAppearPressed to assign an attribute if you need to override the default behavior.
|
|
*/
|
|
bool IsPressed() const
|
|
{
|
|
return bIsPressed || AppearPressedAttribute.Get();
|
|
}
|
|
|
|
/**
|
|
* Construct this widget
|
|
*
|
|
* @param InArgs The declaration data for this widget
|
|
*/
|
|
SLATE_API void Construct( const FArguments& InArgs );
|
|
|
|
/** See ContentPadding attribute */
|
|
SLATE_API void SetContentPadding(TAttribute<FMargin> InContentPadding);
|
|
|
|
/** See HoveredSound attribute */
|
|
SLATE_API void SetHoveredSound(TOptional<FSlateSound> InHoveredSound);
|
|
|
|
/** See PressedSound attribute */
|
|
SLATE_API void SetPressedSound(TOptional<FSlateSound> InPressedSound);
|
|
|
|
/** See ClickedSound attribute */
|
|
SLATE_API void SetClickedSound(TOptional<FSlateSound> InClickedSound);
|
|
|
|
/** See OnClicked event */
|
|
SLATE_API void SetOnClicked(FOnClicked InOnClicked);
|
|
|
|
/** Set OnHovered event */
|
|
SLATE_API void SetOnHovered(FSimpleDelegate InOnHovered);
|
|
|
|
/** Set OnUnhovered event */
|
|
SLATE_API void SetOnUnhovered(FSimpleDelegate InOnUnhovered);
|
|
|
|
/** See ButtonStyle attribute */
|
|
SLATE_API void SetButtonStyle(const FButtonStyle* ButtonStyle);
|
|
|
|
SLATE_API void SetClickMethod(EButtonClickMethod::Type InClickMethod);
|
|
SLATE_API void SetTouchMethod(EButtonTouchMethod::Type InTouchMethod);
|
|
SLATE_API void SetPressMethod(EButtonPressMethod::Type InPressMethod);
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
SLATE_API void SimulateClick();
|
|
#endif // !UE_BUILD_SHIPPING
|
|
|
|
public:
|
|
|
|
//~ SWidget overrides
|
|
SLATE_API virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
|
|
SLATE_API virtual bool SupportsKeyboardFocus() const override;
|
|
SLATE_API virtual void OnFocusLost( const FFocusEvent& InFocusEvent ) override;
|
|
SLATE_API virtual FReply OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent ) override;
|
|
SLATE_API virtual FReply OnKeyUp( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent ) override;
|
|
SLATE_API virtual FReply OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override;
|
|
SLATE_API virtual FReply OnMouseButtonDoubleClick(const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent) override;
|
|
SLATE_API virtual FReply OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override;
|
|
SLATE_API virtual FReply OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override;
|
|
SLATE_API virtual void OnMouseEnter( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) override;
|
|
SLATE_API virtual void OnMouseLeave( const FPointerEvent& MouseEvent ) override;
|
|
SLATE_API virtual void OnMouseCaptureLost(const FCaptureLostEvent& CaptureLostEvent) override;
|
|
SLATE_API virtual bool IsInteractable() const override;
|
|
#if WITH_ACCESSIBILITY
|
|
SLATE_API virtual TSharedRef<FSlateAccessibleWidget> CreateAccessibleWidget() override;
|
|
#endif
|
|
protected:
|
|
SLATE_API virtual FVector2D ComputeDesiredSize(float) const override;
|
|
//~ SWidget
|
|
|
|
protected:
|
|
/** Press the button */
|
|
SLATE_API virtual void Press();
|
|
|
|
/** Release the button */
|
|
SLATE_API virtual void Release();
|
|
|
|
/** Execute the "OnClicked" delegate, and get the reply */
|
|
SLATE_API FReply ExecuteOnClick();
|
|
|
|
/** @return combines the user-specified margin and the button's internal margin. */
|
|
SLATE_API FMargin GetCombinedPadding() const;
|
|
|
|
/** @return True if the disabled effect should be shown. */
|
|
SLATE_API bool GetShowDisabledEffect() const;
|
|
|
|
/** Utility function to translate other input click methods to regular ones. */
|
|
SLATE_API TEnumAsByte<EButtonClickMethod::Type> GetClickMethodFromInputType(const FPointerEvent& MouseEvent) const;
|
|
|
|
/** Utility function to determine if the incoming mouse event is for a precise tap or click */
|
|
SLATE_API bool IsPreciseTapOrClick(const FPointerEvent& MouseEvent) const;
|
|
|
|
/** Play the pressed sound */
|
|
SLATE_API void PlayPressedSound() const;
|
|
|
|
/** Play the clicked sound */
|
|
SLATE_API void PlayClickedSound() const;
|
|
|
|
/** Play the hovered sound */
|
|
SLATE_API void PlayHoverSound() const;
|
|
|
|
/** Set if this button can be focused */
|
|
void SetIsFocusable(bool bInIsFocusable)
|
|
{
|
|
bIsFocusable = bInIsFocusable;
|
|
}
|
|
|
|
SLATE_API void ExecuteHoverStateChanged(bool bPlaySound);
|
|
|
|
protected:
|
|
/** @return the BorderForegroundColor attribute. */
|
|
TSlateAttributeRef<FSlateColor> GetBorderForegroundColorAttribute() const { return TSlateAttributeRef<FSlateColor>(SharedThis(this), BorderForegroundColorAttribute); }
|
|
|
|
/** @return the ContentPadding attribute. */
|
|
TSlateAttributeRef<FMargin> GetContentPaddingAttribute() const { return TSlateAttributeRef<FMargin>(SharedThis(this), ContentPaddingAttribute); }
|
|
|
|
/** Set the AppearPressed look. */
|
|
void SetAppearPressed(TAttribute<bool> InValue)
|
|
{
|
|
AppearPressedAttribute.Assign(*this, MoveTemp(InValue));
|
|
}
|
|
|
|
/** @return the AppearPressed attribute. */
|
|
TSlateAttributeRef<bool> GetAppearPressedAttribute() const { return TSlateAttributeRef<bool>(SharedThis(this), AppearPressedAttribute); }
|
|
|
|
private:
|
|
SLATE_API void UpdatePressStateChanged();
|
|
|
|
SLATE_API void UpdatePadding();
|
|
SLATE_API void UpdateShowDisabledEffect();
|
|
SLATE_API void UpdateBorderImage();
|
|
SLATE_API void UpdateForegroundColor();
|
|
SLATE_API void UpdateDisabledForegroundColor();
|
|
|
|
private:
|
|
/** The location in screenspace the button was pressed */
|
|
FVector2D PressedScreenSpacePosition;
|
|
|
|
/** Style resource for the button */
|
|
const FButtonStyle* Style;
|
|
/** The delegate to execute when the button is clicked */
|
|
FOnClicked OnClicked;
|
|
|
|
/** The delegate to execute when the button is pressed */
|
|
FSimpleDelegate OnPressed;
|
|
|
|
/** The delegate to execute when the button is released */
|
|
FSimpleDelegate OnReleased;
|
|
|
|
/** The delegate to execute when the button is hovered */
|
|
FSimpleDelegate OnHovered;
|
|
|
|
/** The delegate to execute when the button exit the hovered state */
|
|
FSimpleDelegate OnUnhovered;
|
|
|
|
/** The Sound to play when the button is hovered */
|
|
FSlateSound HoveredSound;
|
|
|
|
/** The Sound to play when the button is pressed */
|
|
FSlateSound PressedSound;
|
|
|
|
/** The Sound to play when the button is clicked */
|
|
FSlateSound ClickedSound;
|
|
|
|
/** Sets whether a click should be triggered on mouse down, mouse up, or that both a mouse down and up are required. */
|
|
TEnumAsByte<EButtonClickMethod::Type> ClickMethod;
|
|
|
|
/** How should the button be clicked with touch events? */
|
|
TEnumAsByte<EButtonTouchMethod::Type> TouchMethod;
|
|
|
|
/** How should the button be clicked with keyboard/controller button events? */
|
|
TEnumAsByte<EButtonPressMethod::Type> PressMethod;
|
|
|
|
/** Can this button be focused? */
|
|
uint8 bIsFocusable:1;
|
|
|
|
/** True if this button is currently in a pressed state */
|
|
uint8 bIsPressed:1;
|
|
|
|
/** True if NormalPaddingAttribute is overriding the button style's normal padding */
|
|
uint8 bIsStyleNormalPaddingOverridden:1;
|
|
|
|
/** True if PressedPaddingAttribute is overriding the button style's pressed padding */
|
|
uint8 bIsStylePressedPaddingOverridden:1;
|
|
|
|
private:
|
|
/** Optional foreground color that will be inherited by all of this widget's contents */
|
|
TSlateAttribute<FSlateColor> BorderForegroundColorAttribute;
|
|
/** Padding specified by the user; it will be combind with the button's internal padding. */
|
|
TSlateAttribute<FMargin> ContentPaddingAttribute;
|
|
/** Normal padding override specified by the user, or the button style's normal padding if not being overridden. */
|
|
TSlateAttribute<FMargin> NormalPaddingAttribute;
|
|
/** Pressed padding override specified by the user, or the button style's pressed padding if not being overridden. */
|
|
TSlateAttribute<FMargin> PressedPaddingAttribute;
|
|
/** Optional foreground color that will be inherited by all of this widget's contents */
|
|
TSlateAttribute<bool> AppearPressedAttribute;
|
|
};
|