I’ve created custom button class to have na opportunity to get clicked button reference onclick event. I did it like here
How to pass self-reference to UButton's OnClicked delegate (UMG)? - UI - Epic Developer Community Forums
But UE4 crashes after function RebuildWidget finishes. I have no idea what to do in this case.
GoodButton.h
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonClickedRefDel, UGoodButton*, ButtonRef);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonPressedRefDel, UGoodButton*, ButtonRef);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonReleasedRefDel, UGoodButton*, ButtonRef);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonHoveredRefDel, UGoodButton*, ButtonRef);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonUnhoveredRefDel, UGoodButton*, ButtonRef);
UCLASS()
class TESTPL_API UGoodButton : public UButton
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintAssignable, Category = "Button|Event")
FOnButtonClickedRefDel OnClickedReferenced;
UPROPERTY(BlueprintAssignable, Category = "Button|Event")
FOnButtonPressedRefDel OnPressedReferenced;
UPROPERTY(BlueprintAssignable, Category = "Button|Event")
FOnButtonReleasedRefDel OnReleasedReferenced;
UPROPERTY(BlueprintAssignable, Category = "Button|Event")
FOnButtonHoveredRefDel OnHoveredReferenced;
UPROPERTY(BlueprintAssignable, Category = "Button|Event")
FOnButtonUnhoveredRefDel OnUnhoveredReferenced;
protected:
/** Handle the actual click event from slate and forward it on */
FReply SlateHandleClicked();
void SlateHandlePressed();
void SlateHandleReleased();
void SlateHandleHovered();
void SlateHandleUnhovered();
protected:
//~ Begin UWidget Interface
virtual TSharedRef<SWidget> <b>RebuildWidget()</b> override;
#if WITH_EDITOR
virtual TSharedRef<SWidget> RebuildDesignWidget(TSharedRef<SWidget> Content) override { return Content; }
#endif
//~ End UWidget Interface
protected:
/** Cached pointer to the underlying slate button owned by this UWidget */
TSharedPtr<SButton> MyButton;
};
GoodButton.cpp
FReply UGoodButton::SlateHandleClicked()
{
OnClickedReferenced.Broadcast(this);
return FReply::Handled();
}
void UGoodButton::SlateHandlePressed()
{
OnPressedReferenced.Broadcast(this);
}
void UGoodButton::SlateHandleReleased()
{
OnReleasedReferenced.Broadcast(this);
}
void UGoodButton::SlateHandleHovered()
{
OnHoveredReferenced.Broadcast(this);
}
void UGoodButton::SlateHandleUnhovered()
{
OnUnhoveredReferenced.Broadcast(this);
}
TSharedRef<SWidget> UGoodButton::RebuildWidget()
{
MyButton = SNew(SButton)
.OnClicked(BIND_UOBJECT_DELEGATE(FOnClicked, SlateHandleClicked))
.OnPressed(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandlePressed))
.OnReleased(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandleReleased))
.OnHovered_UObject(this, &UGoodButton::SlateHandleHovered)
.OnUnhovered_UObject(this, &UGoodButton::SlateHandleUnhovered)
.ButtonStyle(&WidgetStyle)
.ClickMethod(ClickMethod)
.TouchMethod(TouchMethod)
.IsFocusable(IsFocusable)
;
if (GetChildrenCount() > 0)
{
Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
}
return MyButton.ToSharedRef();
}