Updating Slate UI Layout On Click (Plugin code)

Hi everyone,

I’ve been trying to implement the UI for a plugin I’m making using Slate. However, I haven’t been able to figure out how I can change the layout itself when a button is clicked. Since the button click should change the layout itself, I imagine there is a way to redraw the UI on demand, but I don’t know how to do it.

In OnSpawnPluginTab, I bind a lambda expression to my button click. The expression simply turns a boolean flag to true (initially false). SpawnFLVBox() is the layout segment that I want to change. The code for it follows.

OnSpawnPluginTab:

TSharedRef<SDockTab> FPickActsModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
    return SNew(SDockTab)
        .TabRole(ETabRole::NomadTab)
        [
            SNew(SVerticalBox)
            + SVerticalBox::Slot()
            .HAlign(HAlign_Center)
            .VAlign(VAlign_Center)
            .AutoHeight()
            [
                SNew(STextBlock)
                .Text(WidgetText)
            ]
            + SVerticalBox::Slot()
            .HAlign(HAlign_Fill)
            .VAlign(VAlign_Top)
            [
                SNew(SButton)
                .OnClicked_Lambda([this]()->FReply { _testFlag = true; return FReply::Handled(); })
            ]
            + SVerticalBox::Slot()
            .HAlign(HAlign_Fill)
            .VAlign(VAlign_Top)
            [
                SpawnFLVBox()
            ]
        ];
}

SpawnFLVBox:

TSharedRef<SHorizontalBox> FPickActsModule::SpawnFLVBox()
{
    TSharedRef<SHorizontalBox> horizontalBox = _testFlag ?
        // if true
        SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        [
            SNew(SEditableTextBox)
            .HintText(FText::FromString(TEXT("0")))
        ]
        + SHorizontalBox::Slot()
        [
            SNew(SEditableTextBox)
            .HintText(FText::FromString(TEXT("0")))
        ]:
        // if false
        SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        [
            SNew(SEditableTextBox)
            .HintText(FText::FromString(TEXT("0")))
        ]
        + SHorizontalBox::Slot()
        [
            SNew(SEditableTextBox)
            .HintText(FText::FromString(TEXT("0")))
        ]
        + SHorizontalBox::Slot()
        [
            SNew(SEditableTextBox)
            .HintText(FText::FromString(TEXT("0")))
        ];

    return horizontalBox;
}

We can see in SpawnFLVBox that I simply check the flag, and draw 2 editable text boxes instead of 3 if the flag is true. However, when I click the button, the layout is not re-drawn, which makes sense because OnSpawnPluginTab is only called at the beginning. So my question is: how do I request a UI re-draw? How do I refresh the view? I seem to understand that Slate doesn’t work by updating the UI every frame. But then I don’t know what to do to solve my problem. Any help would be greatly appreciated.

Two options:

  1. Wrap the contents of your slots in an SBox and bind its visibility to something that returns EVisibility::Collapsed or EVisibility::Visible depending on the state of your bool.
  2. Keep your horizontalBox variable around, and ClearChildren and AddSlot for the children you need when the button is pressed.

I don’t know. I just GEngine->AddOnScreenDebugMessage to print hint texts. Have you figured it out?