六、自定义Button控件

自定义一个Button控件

SlAiTypes.h

#pragma once

#include "CoreMinimal.h"

/**
 * 
 */


//语言类型
//可以通过反射获取
UENUM()
enum class ECultureTeam : uint8 {
    
    
	EN = 0,
	ZH
};



//Menu按钮的类型
//通过switch获取
namespace EMenuItem
{
    
    
	enum Type
	{
    
    
		None,
		StartGame,
		GameOption,
		QuitGame,
		NewGame,
		LoadRecord,
		StartGameGoBack,
		GameOptionGoBack,
		NewGameGoBack,
		ChooseRecordGoBack,
		EnterGame,
		EnterRecord
	};
}

SlAiMenuWidgetStyle.h

/*
	* MenuItem的Brush
	*/
	UPROPERTY(EditAnywhere, Category = Menu)
		FSlateBrush MenuItemBrush;

	/*
	* 60号字体
	*/
	UPROPERTY(EditAnywhere, Category = Common)
		FSlateFontInfo Font_60;

	/*
	* 40号字体
	*/
	UPROPERTY(EditAnywhere, Category = Common)
		FSlateFontInfo Font_40;

	/*
	* 30号字体
	*/
	UPROPERTY(EditAnywhere, Category = Common)
		FSlateFontInfo Font_30;

	/*
	* 黑色颜色
	*/
	UPROPERTY(EditAnywhere, Category = Common)
		FLinearColor FontColor_White;

	/*
	* 白色颜色
	*/
	UPROPERTY(EditAnywhere, Category = Common)
		FLinearColor FontColor_Black;

SlAiMenuItemWidget.h

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include"SlAiTypes.h"


DECLARE_DELEGATE_OneParam(FItemClicked, const EMenuItem::Type)

/**
 * 
 */
class SLAICOURSE_API SSlAiMenuItemWidget : public SCompoundWidget
{
    
    
public:
	SLATE_BEGIN_ARGS(SSlAiMenuItemWidget)
	{
    
    }

	//前面变量类型,后面变量名
	SLATE_ATTRIBUTE(FText,ItemText)

		//事件委托
		SLATE_EVENT(FItemClicked,OnClicked)


		SLATE_ATTRIBUTE(EMenuItem::Type,ItemType)

	SLATE_END_ARGS()

	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	//重写组件的OnMouseButtonDown方法
	virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;

	//重写组件的OnMouseButtonUp方法
	virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;

	//鼠标离开
	virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;

private:

	//获取颜色
	FSlateColor GetTintColor() const;

private:

	//按下事件委托
	FItemClicked OnClicked;
	//保存按钮类型
	EMenuItem::Type ItemType;
	//按钮是否已经按下
	bool IsMouseButtonDown;
};

SlAiMenuWidget.h

#pragma once

...
#include"SlAiTypes.h"
...

private:

	void MenuItemOnClicked(EMenuItem::Type ItemType);

private:

...
	//用来保存垂直列表
	TSharedPtr<class SVerticalBox> ContentBox;
};

SlAiMenuWidget.cpp

...
#include "SSlAiMenuItemWidget.h"
#include"SBoxPanel.h"


BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::Construct(const FArguments& InArgs)
{
    
    

	

	...

	+SOverlay::Slot()
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Top)
		.Padding(FMargin(0.f,130.f,0.f,0.f))
		[
			//创建一个SVerticalBox
			SAssignNew(ContentBox,SVerticalBox)
		]
		]
	];

	...
	

	//将SSlAiMenuItemWidget插入ContentBox
	ContentBox->AddSlot()
		[
			SNew(SSlAiMenuItemWidget)

			//SLATE_ATTRIBUTE(FText, ItemText)
		//TAttribute<FText> _ItemText=NSLOCTEXT("SlAiMenu", "StartGame", "StartGame");
			.ItemText(NSLOCTEXT("SlAiMenu", "StartGame", "StartGame"))

		//SLATE_ATTRIBUTE(EMenuItem::Type,ItemType)
		//TAttribute<EMenuItem::Type> _ItemType=EMenuItem::StartGame;
		.ItemType(EMenuItem::StartGame)
		
		//SLATE_EVENT(FItemClicked,OnClicked)
		//TAttribute<FItemClicked> _OnClicked
		.OnClicked(this,&SSlAiMenuWidget::MenuItemOnClicked)
		];
}

END_SLATE_FUNCTION_BUILD_OPTIMIZATION


void SSlAiMenuWidget::MenuItemOnClicked(EMenuItem::Type ItemType)
{
    
    
	
}

SlAiMenuItemWidget.cpp

**#include "SSlAiMenuItemWidget.h"
#include "SlateOptMacros.h"
#include"SlAiStyle.h"
#include "SlAiMenuWidgetStyle.h"
#include"SBox.h"
#include"SImage.h"
#include"STextBlock.h"

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuItemWidget::Construct(const FArguments& InArgs)
{
    
    
	OnClicked = InArgs._OnClicked;
	//InArgs._ItemType是 TAttribute<EMenuItem::Type>
	ItemType = InArgs._ItemType.Get();
	
	ChildSlot
	[
		SNew(SBox)
		.WidthOverride(500.f)
		.HeightOverride(100.f)
		[
			SNew(SOverlay)

			+SOverlay::Slot()
		.VAlign(VAlign_Fill)
		.HAlign(HAlign_Fill)
		[
			SNew(SImage)
			.Image(&SlAiStyle::GetMenuStyle()->MenuItemBrush)
		.ColorAndOpacity(this,&SSlAiMenuItemWidget::GetTintColor)
		]

	+SOverlay::Slot()
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Center)
		[
			SNew(STextBlock)
			.Text(InArgs._ItemText)
		.Font(SlAiStyle::GetMenuStyle()->Font_60)
		]
		]
	];
	
	//初始化
	IsMouseButtonDown = false;
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

FReply SSlAiMenuItemWidget::OnMouseButtonDown(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent)
{
    
    
	IsMouseButtonDown = true;
	return FReply::Handled();
}

FReply SSlAiMenuItemWidget::OnMouseButtonUp(const FGeometry & MyGeometry, const FPointerEvent & MouseEvent)
{
    
    
	//如果按钮按下并且OnClicked委托绑定有方法那就执行
	if (IsMouseButtonDown)
	{
    
    
		IsMouseButtonDown = false;
		OnClicked.ExecuteIfBound(ItemType);
	}
	return FReply::Handled();
}

void SSlAiMenuItemWidget::OnMouseLeave(const FPointerEvent & MouseEvent)
{
    
    
	//如果在按钮外抬起就不会触发委托调用
	IsMouseButtonDown = false;
}

FSlateColor SSlAiMenuItemWidget::GetTintColor() const
{
    
    
	if (IsMouseButtonDown) return FLinearColor(1.f, 0.1f, 0.1f, 0.5f);
	return FLinearColor(1.f, 1.f, 1.f, 1.f);
}
**

在BPSlAiMenuStyle中设置好画刷字体
在这里插入图片描述

注意

DECLARE_DELEGATE_OneParam(FItemClicked, const EMenuItem::Type)

/**
 * 
 */
class SLAICOURSE_API SSlAiMenuItemWidget : public SCompoundWidget
{
    
    
public:
	SLATE_BEGIN_ARGS(SSlAiMenuItemWidget)
	{
    
    }

	//前面变量类型,后面变量名
	SLATE_ATTRIBUTE(FText,ItemText)

		//事件委托
		SLATE_EVENT(FItemClicked,OnClicked)


		SLATE_ATTRIBUTE(EMenuItem::Type,ItemType)

	SLATE_END_ARGS()
SNew(SSlAiMenuItemWidget)

			//SLATE_ATTRIBUTE(FText, ItemText)
		//TAttribute<FText> _ItemText=NSLOCTEXT("SlAiMenu", "StartGame", "StartGame");
		
			.ItemText(NSLOCTEXT("SlAiMenu", "StartGame", "StartGame"))
			//显示的文字  StartGame(开始游戏)

		//SLATE_ATTRIBUTE(EMenuItem::Type,ItemType)
		//TAttribute<EMenuItem::Type> _ItemType=EMenuItem::StartGame;
		
		.ItemType(EMenuItem::StartGame)
		//菜单类型    EMenuItem::StartGame
		
		//SLATE_EVENT(FItemClicked,OnClicked)
		//TAttribute<FItemClicked> _OnClicked
		//FItemClicked类型  需要  TAttribute<FItemClicked>.Get() 获得
		
		.OnClicked(this,&SSlAiMenuWidget::MenuItemOnClicked)
		//在OnClicked被执行时调用MenuItemOnClicked()函数

猜你喜欢

转载自blog.csdn.net/m0_51032168/article/details/121461589