[언리얼엔진] 슬레이트 위젯 예제

    공용 슬레이트 인수

    다음은 공통 인수이다.

    • IsEnabled - 상호작용(Interation) 가능한 위젯인지를 지정한다. 끄면 회식으로 비활성화 된다.
    • ToolTip - 툴팁에 사용할 커스텀 SToolTip 위젯 종류를 지정한다. 지정되지 않으면 툴팁이 나타나지 않는다.
    • ToolTipText - 간단한 툴팁으로 표시할 텍스트 유형을 지정한다. 지정되지 않거나, ToolTip 특성이 사용된 경우 나타나지 않는다.
    • Cursor - 마우스를 올렸을 때 표시할 커서를 지정합니다.
    • Visibility - 아래 Visibility 부분을 참고.
    • Text - 텍스트가 적용 가능하다면 지정할 문구
    • Content - 콘텐츠가 적용 가능하다면 지정할 위젯
    • ReadOnly - True 면 이 위젯은 수정할 수 없다.
    • Style - 위젯에 사용되는 이미지나 텍스트 스타일을 지정한다. 적용 방식은 위젯마다 다르다.
    • [...]ColorAndOpacity - 위젯이나 지정된 시스템의 색과 불투명도
    • Padding - 위젯의 상하좌우 주변에 패딩으로 댈 Slate 유닛 단위 여백의 양이다.
    • HAlign - 위젯 안 콘텐츠의 가로 정렬 방식
    • VAlign - 위젯 안 콘텐츠의 세로 정렬 방식

    Visibility

    Visibility는 위젯을 표시할 것인지와 상호작용 여부도 결정한다.

    • Visible - 위젯이 보통의 경우 나타난다. (Default)
    • Collapsed - 위젯이 보이지 않으며 레이아웃에서 자리를 차지하지 않는다. 상호작용되지도 않는다.
    • Hidden - 위젯이 보이지는 않으며 레이아웃에서 자리는 차지한다. 상호작용되지는 않는다.
    • HitTestInvisible - 보이지만 상호작용되지는 않는다.
    • SelfHitTestInvisible - HitTestInvisible 와 같지만 자손 위젯에 적용되지 않는다.

    Alignment

    Alignment는 위젯의 부모 안에서 그 위젯의 위치를 결정한다. 위젯 부모 크기가 위젯과 같다면 정렬은 의미가 없다.위젯에 "Fill"을 지정하거나 박스 슬롯에 Fill Size가 지정된 경우, 그 박스 슬롯에 기본으로 적용된다.

    • HAlign_Fill / VAlign_Fill - 가로 세로 가득 채운 정렬
    • HAlign_Left - 왼쪽 정렬
    • VAlign_Top - 위쪽 정렬
    • HAlign_Center / VAlign_Center - 가로 세로 가운데 정렬
    • HAlign_Right - 오른쪽 정렬
    • VAlign_Bottom - 아래쪽 정렬

    Box 패널

    SHorizontalBox, SVerticalBox 는 레이아웃 배치에 있어 가장 흔한 위젯이다. 이 박스 패널은 위젯으로 선언되나, 그 이후 슬롯이 삽입된다. 이 슬롯의 배치 순서는 SHorizontalBox 의 경우 좌에서 우, SVerticalBox 는 위에서 아래다.
    SScrollBox 는 SVerticalBox 와 비슷하게 작동하는데, 자손 슬롯의 세로 스크롤이 가능하다는 점이 다르다.

    Slot 특성

    • Width or Height (폭 또는 높이) 세팅 (다음 옵션은 상호 배제적이다):
      • Auto Size (자동 크기, 기본) - 슬롯에 딱 필요한 만큼만 공간을 지정. 슬롯 내 정렬은 중요치 않음.
      • Fill Size (필 크기) - 필 계수를 지정하면 다른 슬롯의 필 계수에 따라 공간을 채움. 슬롯 정렬은 중요치 않음.
    • Max Size (최대 크기) - 슬롯의 최대 크기를 Slate 유닛 단위로 지정.
    • Padding (패딩) - 패널 네 슬롯의 패딩을 지정.
    • Alignment (정렬) - 슬롯 내 자손 위젯의 정렬 방식을 결정. 이 옵션은 같은 방향의 Fill Size 가 적용되어 있으면 의미가 없다.
    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)
        [
            ...
        ]
    ]

    Uniform Grid Panel

    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)
    [
        ...
    ]

    Warp Box

    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)
    [
        ...
    ]

    Radio Button

    라디오 버튼은 Slate의 체크박스다. 체크 박스는 체크 여부 결정을 위해 델리게이트가 필요하기 때문, 라디오 버튼 시리즈를 만드는 가장 쉬운 방법은 어떤 체크박스가 체크되었는지 결정하는 enum을 만드는 것이다. 현재 선택한 내용을 enum 값으로 저장한다. 그 다음 검사하는 델리게이트에 대해 함수를 전달하고, 파라미터로 같이 전달된 enum값과 현재 선택된 내용을 검사한다. 선택 변경시에는 현재 내용을 업데이트 해줘야 한다.

    ERadioChoice CurrentChoice;
    
    ...
    
    ECheckBoxState::Type IsRadioChecked( ERadioChoice ButtonId ) const
    {
        return (CurrentChoice == ButtonId)
            ? ECheckBoxState::Checked
            : ECheckBoxState::Unchecked;
    }
    
    ...
    
    void OnRadioChanged( ERadioChoice RadioThatChanged, ECheckBoxState::Type NewRadioState )
    {
        if (NewRadioState == ECheckBoxState::Checked)
        {
            CurrentChoice = RadioThatChanged;
        }
    }

    메뉴와 툴바

    메뉴

    메뉴나 툴바를 생성하기 위해 멀티박스를 사용한다. Slate의 UI_COMMAND 시스템을 사용하지만 동적으로 생성된 버튼,컨트롤로는 불가능하다.
    메뉴를 만들려면 FMenuBarBuilder를 생성하여 FUICommandList를 전달한다. 마지막으로 메뉴 바 빌더에서 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").ToString(),
            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 ),
            FString(),
            LOCTEXT("PIEComboToolTip", "Play-In-Editor options").ToString() );
    }
    
    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 )

    문서

    https://docs.unrealengine.com/5.1/ko/slate-ui-widget-examples-for-unreal-engine/

    반응형

    댓글

    Designed by JB FACTORY