六、自定义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()函数