Slate语法
大概类型关系图
C++中使用时需要包含Slate.h头文件。参考Project Setup
The square brackets define what elements are nested inside a given widget, while periods set the value of the parameters you would see in the Details panel. 参考
加号则用于SXXXWidget::Slot()的添加,返回的是FArguments类型。而SXXXWidget类型里通过SLATE_BEGIN_ARGS宏来定义了FArguments结构体类型,并用SLATE_ATTRIBUTE、SLATE_ARGUMENT等宏来给FArguments类型添加一些属性。
加号则用于SXXXWidget::Slot()的添加,返回的是FArguments类型。而SXXXWidget类型里通过SLATE_BEGIN_ARGS宏来定义了FArguments结构体类型,并用SLATE_ATTRIBUTE、SLATE_ARGUMENT等宏来给FArguments类型添加一些属性。
对SNew或SAssignNew的理解
实际上,SNew或SAssignNew的宏展开可以简略地视为:MakeTDecl<WidgetType>() <<= WidgetType::FArguments()
这里的MakeTDecl模板函数返回的是一个TSlateDecl<WidgetType, xxx>类型的对象。
由于<<运算符的优先级比较低,所以上面宏展开里的WidgetType::FArguments()先和SNew(WidgetType)后面的语句结合,结果就是构造了WidgetType::FArguments对象并对其属性进行了赋值;
即<<=语句的右边是一个WidgetType::FArguments对象,左边是一个TSlateDecl<WidgetType, xxx>对象,而该TSlateDecl对象又重载了<<=运算符,因此对该对象调用其<<=运算,其接受WidgetType::FArguments对象作为运算参数,最终返回一个TSharedRef<WidgetType>对象;
因此SNew(WidgetType)及其紧跟的代码块最终是构造了一个WidgetType对象;
以SOverlay为例,具体示例可以在SScrollBox::ConstructVerticalLayout()函数里找到。
这里的MakeTDecl模板函数返回的是一个TSlateDecl<WidgetType, xxx>类型的对象。
由于<<运算符的优先级比较低,所以上面宏展开里的WidgetType::FArguments()先和SNew(WidgetType)后面的语句结合,结果就是构造了WidgetType::FArguments对象并对其属性进行了赋值;
即<<=语句的右边是一个WidgetType::FArguments对象,左边是一个TSlateDecl<WidgetType, xxx>对象,而该TSlateDecl对象又重载了<<=运算符,因此对该对象调用其<<=运算,其接受WidgetType::FArguments对象作为运算参数,最终返回一个TSharedRef<WidgetType>对象;
因此SNew(WidgetType)及其紧跟的代码块最终是构造了一个WidgetType对象;
以SOverlay为例,具体示例可以在SScrollBox::ConstructVerticalLayout()函数里找到。
结合上面两点,通常+号用于增加Slots,Slots后面的(.)点号与Slot先结合,所以紧跟Slots的(.)点号设置的是Slot的属性,而紧跟SNew的(.)点号设置的是WidgetType::FArguments对象的属性
对TAttribute属性的赋值
以官网例子来说,SNew(SCheckBox).IsChecked(这里需要ECheckBoxState型参数),IsChecked就是一个attribute,赋值如下:.IsChecked(TAttribute<ECheckBoxState>(this, &SQuickStartWindowMenu::IsTestBoxChecked)),更详细的信息参见How to set a slate attribute dynamically?
Padding
The padding of a widget amount of spacing in slate units around the left, top, right, and bottom parts of the widget within its parent. 离父widget的边框的空白,在父边框之内为正值。父边框是指父widget的content区域的范围。参考css box model CSS Box Model
Placemode里添加Category
FPlacementModeModule用于提供这个功能。参考FBspModeModule::StartupModule()的实现。
CSS Box Model
Explanation of the different parts:
- Content - The content of the box, where text and images appear
- Padding - Clears an area around the content. The padding is transparent
- Border - A border that goes around the padding and content
- Margin - Clears an area outside the border. The margin is transparent
The box model allows us to add a border around elements, and to define space between elements.
关于Unreal Engine中Widget的Slot
各种Layouts与Widgets之间可能会有嵌套、组合之类的关系的。
比如,一个Layout引用一个widget,通常C++里可能会引用widget基类指针,UE4对这种使用指针的用法进行了建模,用Slot来代替指针的作用,Slot里比普通的指针提供了额外的一些信息,可以认为是一个强化版的指针,它包含双指针,一个指向这个Slot对应的Widget(C),一个指向该Widget(C)的ParentWidget(通常值就是this)。因此,每一个Widget里都有一个Slot成员(定义在Widget.h里的UPanelSlot* Slot;)。
UPanelSlot* PanelSlot = NewObject<UPanelSlot>(this, GetSlotClass(), NAME_None, NewObjectFlags); PanelSlot->Content = Content; PanelSlot->Parent = this; Content->Slot = PanelSlot;