Slate控件

本页面的内容:

常见的Slate参数

以下参数对于创建的每个控件所共有的。

以下参数不是每个控件上都有,但是大部分控件都具有。

可见性

控件的可见性决定了控件的出现方式及交互性。

对齐

控件的对齐方式决定了它在其父项中的位置。如果控件的父项和该控件的大小(包括填充留白)一样,那么对齐方式就没有什么意义了。当您为控件指定“Fill(填充)”时或者盒体插槽指定了Fill Size(填充大小)时,盒体插槽会自动进行这种处理。

可能的对齐方式如下所示:

方框面板

SHorizontalBox 和 SVerticalBox 是排列布局时最常用的控件。这两个方框面板虽然被声明为控件,但是稍后会将插槽插入到它们内部。SHorizontalBoxes排列这些插槽,让第一个控件位于左侧,最后一个控件位于右侧;而SVerticalBoxes则让这些插槽自上而下排列。

SScrollBox的工作方式和SVerticalBox类似,只不过它允许垂直滚动子插槽。

插槽属性

以下示例是嵌套在一个滚动框中的具有自动大小的水平方框和具有填充大小的水平方框。同时展示了如何结合这些插槽使用对齐方式。

SNew(SScrollBox)
+SScrollBox::Slot() .Padding(10,5)
[
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot() .HAlign(HAlign_Left)
    [
        ...
    ]
    +SHorizontalBox::Slot() .HAlign(HAlign_Center)
    [
        ...
    ]
    +SHorizontalBox::Slot() .HAlign(HAlign_Right)
    [
        ...
    ]
]
+SScrollBox::Slot() .Padding(10,5)
[
    SNew(SHorizontalBox)
    +SHorizontalBox::Slot() .FillWidth(2)
    [
        ...
    ]
    +SHorizontalBox::Slot() .FillWidth(1)
    [
        ...
    ]
    +SHorizontalBox::Slot() .FillWidth(3)
    [
        ...
    ]
]

均匀网格面板

SUniformGridPanel面板在水平方向和垂直方向上均匀地分布其子控件。它的子插槽使用一对整数指定,这两个整数指定了该子项的索引。以下是这样的一个均匀网格面板。

SNew(SUniformGridPanel)
.SlotPadding( FMargin( 5.0f ) )
+SUniformGridPanel::Slot(0,0)
.HAlign(HAlign_Right)
[
    ...
]
+SUniformGridPanel::Slot(0,1)
.HAlign(HAlign_Right)
[
    ...
]
+SUniformGridPanel::Slot(0,2)
.HAlign(HAlign_Center)
[
    ...
]
+SUniformGridPanel::Slot(1,0)
[
    ...
]
+SUniformGridPanel::Slot(1,1)
[
    ...
]

自动换行的方框

SWrapBox是一个方框,它在水平方向上放置控件,直到这些控件超出一定宽度后,便将控件放置到下一行上,以此类推。以下是这样的一个示例。

SNew(SWrapBox)
.PreferredWidth( 300.f )
+SWrapBox::Slot()
.Padding( 5 )
.VAlign(VAlign_Top)
[
    ...
]
+SWrapBox::Slot()
.Padding( 5 )
.VAlign(VAlign_Bottom)
[
    ...
]
+SWrapBox::Slot()
.Padding( FMargin(20, 5, 0, 5) )
.VAlign(VAlign_Center)
[
    ...
]
+SWrapBox::Slot()
.Padding( 0 )
.VAlign(VAlign_Fill)
[
    ...
]

单选按钮

单选按钮在slate中是复选框,因为复选框需要一种如何决定是否选中它们的代理。要想制作一系列的单选按钮,最简单的方法是创建一个枚举值,用该枚举值来决定选中哪个复选框。保存一个决定了当前选项的枚举值的实例。然后,对于检测代理,则传入一个函数,该函数将传入的正确枚举值同当前选项进行比较。在修改选中项时,需要更新当前选中项。

ERadioChoice CurrentChoice;

...

ESlateCheckBoxState::Type IsRadioChecked( ERadioChoice ButtonId ) const
{
    return (CurrentChoice == ButtonId)
        ? ESlateCheckBoxState::Checked
        : ESlateCheckBoxState::Unchecked;
}

...

void OnRadioChanged( ERadioChoice RadioThatChanged, ESlateCheckBoxState::Type NewRadioState )
{
    if (NewRadioState == ESlateCheckBoxState::Checked)
    {
        CurrentChoice = RadioThatChanged;
    }
}

菜单和工具条

菜单

要想创建菜单或工具条,请使用multibox(多框)。虽然这不能通过动态地生成按钮/控件 来完成,但是命令应该使用Slate的UI_COMMAND系统。

要想创建一个菜单,请创建一个传入FUICommandList 的FMenuBarBuilder,您可以在菜单条构建器上调用MakeWidget()来获得一个要放置的控件。

FMenuBarBuilder MenuBarBuilder( CommandList );
{
    MenuBarBuilder.AddPullDownMenu( TEXT("Menu 1"), TEXT("Opens Menu 1"), FNewMenuDelegate::CreateRaw( &FMenus::FillMenu1Entries ) );

    MenuBarBuilder.AddPullDownMenu( TEXT("Menu 2"), TEXT("Opens Menu 2"), FNewMenuDelegate::CreateRaw( &FMenus::FillMenu2Entries ) );
}

return MenuBarBuilder.MakeWidget();

在创建的菜单中,您可以添加菜单头、菜单项、分隔符、子菜单项、可编辑器的文本或者自定义控件。

static void FillMenu1Entries( FMenuBuilder& MenuBuilder )
{
    MenuBuilder.AddEditableText( TEXT( "Editable Item" ), TEXT( "You can edit this item's text" ), NAME_None, TEXT( "Edit Me!" ) );

    MenuBuilder.AddMenuEntry( FMultiBoxTestCommandList::Get().EighthCommandInfo );

    MenuBuilder.AddMenuSeparator();

    MenuBuilder.AddSubMenu( TEXT("Sub Menu"), TEXT("Opens a submenu"), FNewMenuDelegate::CreateRaw( &FMenus::FillSubMenuEntries ) );

    MenuBuilder.AddWidget(SNew(SVolumeControl), TEXT("Volume"));
}

关联菜单

要想调用其中一个菜单作为关联菜单,那么请获得从FMenuBuilder生成的控件,并将其传入到PushMenu函数,如下所示。

FSlateApplication::Get().PushMenu(
    MenuBuilder.MakeWidget(),
    MouseCursorLocation,
    FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu )
    );

工具栏

要想创建一个工具条,请使用FToolBarBuilder。至于子项,您可以添加工具条按钮、组合按钮、普通按钮及下拉菜单。

FToolBarBuilder GameToolBarBuilder( InCommandList );
{
    GameToolBarBuilder.AddToolBarButton( FLevelEditorCommands::Get().Simulate );

    GameToolBarBuilder.AddToolBarButton( 
        FLevelEditorCommands::Get().RepeatLastPlay, 
        LOCTEXT("RepeatLastPlay", "Play"),
        TAttribute< FString >::Create( TAttribute< FString >::FGetter::CreateRaw( &FLevelEditorActionCallbacks::GetRepeatLastPlayToolTip ) ),
        TAttribute< const FSlateBrush* >::Create( TAttribute< const FSlateBrush* >::FGetter::CreateRaw( &FLevelEditorActionCallbacks::GetRepeatLastPlayIconSlateBrush ) )
        );

    GameToolBarBuilder.AddComboButton(
        SpecialPIEOptionsMenuAction,
        FOnGetContent::CreateRaw( &FLevelEditorToolBar::GeneratePIEMenuContent, InCommandList ),
        FText(),
        LOCTEXT("PIEComboToolTip", "Play-In-Editor options") );
}

return GameToolBarBuilder.MakeWidget();

项目视图

这些视图获得一个指向某种数据的共享指针的模板参数。它们由一个TArray或TSharedPtr指向的数据类型进行填充。它们的内部控件通过传入的OnGenerateRow或OnGenerateTile进行动态填充,每栏生成不同的控件。

列表视图

列表视图是存储一个子控件列表的控件。它们通过SListView<...>制作。

SNew( SListView< TSharedPtr<FTestData> > )
.ItemHeight(24)
.ListItemsSource( &Items )
.OnGenerateRow( this, &STableViewTesting::OnGenerateWidgetForList )
.OnContextMenuOpening( this, &STableViewTesting::GetListContextMenu )
.SelectionMode( this, &STableViewTesting::GetSelectionMode )
.HeaderRow
(
    SNew(SHeaderRow)
    + SHeaderRow::Column("Name")
    [
        SNew(SBorder)
        .Padding(5)
        .Content()
        [
            SNew(STextBlock)
            .Text(TEXT("Name"))
        ]
    ]
    + SHeaderRow::Column("Number") .DefaultLabel(TEXT("Number"))
    + SHeaderRow::Column("TextField") .DefaultLabel(TEXT("Text Field"))
    + SHeaderRow::Column("TextBlock") .DefaultLabel(TEXT("Text Block"))
    + SHeaderRow::Column("AddChild") .DefaultLabel(TEXT("Add Child"))
)

树形视图

树形视图,通过STreeView<...>制作,和列表视图类似,但是它支持将控件作为列表中其他控件的子项。要想决定哪个控件位于哪个父项下,那么请使用OnGetChildren 代理来传回传入项的子项。

SNew( STreeView< TSharedPtr<FTestData> > )
.ItemHeight(24)
.TreeItemsSource( &Items )
.OnGenerateRow( this, &STableViewTesting::OnGenerateWidgetForTree )
.OnGetChildren( this, &STableViewTesting::OnGetChildrenForTree )
.OnContextMenuOpening( this, &STableViewTesting::GetTreeContextMenu )
.SelectionMode( this, &STableViewTesting::GetSelectionMode )
.HeaderRow
(
    SNew(SHeaderRow)
    + SHeaderRow::Column("Name") .DefaultLabel(TEXT("Name"))
    + SHeaderRow::Column("Number") .DefaultLabel(TEXT("Number"))
    + SHeaderRow::Column("TextField") .DefaultLabel(TEXT("Text Field"))
    + SHeaderRow::Column("TextBlock") .DefaultLabel(TEXT("Text Block"))
    + SHeaderRow::Column("AddChild") .DefaultLabel(TEXT("Add Child"))
)

平铺视图

平铺视图,使用STileView<...>制作,和列表视图类似,但是子控件位于一个网格中,而不是列表中。由于这个原因,它不支持行标题或列标题。

SNew( STileView< TSharedPtr<FTestData> > )
.ItemWidth(128)
.ItemHeight(64)
.ListItemsSource( &Items )
.OnGenerateTile( this, &STableViewTesting::OnGenerateWidgetForTileView )
.OnContextMenuOpening( this, &STableViewTesting::GetTileViewContextMenu )
.SelectionMode( this, &STableViewTesting::GetSelectionMode )