How to block input behind slate widgets

I’m making a custom slate widget to act as a popup dialog in my game. For the most part it works great except that non-input widget components do not block input. If I have an interactive object behind the widget, and I click on the widget, the input registers on the object behind it. Trivially I could just make the entire widget a button to get around this, but that has the undesirable effect of making the entire widget a button.

Here’s the widget code with the button hack.

	ChildSlot
		.VAlign(VAlign_Center)
		.HAlign(HAlign_Center)
		[
			SNew(SButton)//blocks input but otherwise does nothing
			[
				SNew(SBorder)
				.BorderImage(FCoreStyle::Get().GetBrush("ToolPanel.GroupBorder"))
				.BorderBackgroundColor(FSlateColor::UseForeground())
				.Padding(10)
				[
					SNew(SVerticalBox)
					+ SVerticalBox::Slot().Padding(4, 0)
					[
						SNew(SHeader)
						[
							SNew(STextBlock)
							.ShadowColorAndOpacity(FLinearColor::Black)
							.ColorAndOpacity(FLinearColor::White)
							.ShadowOffset(FIntPoint(-1, 1))
							.Font(FSlateFontInfo("Veranda", 18))
							.Text(this, &SDefectWidget::getHeaderText)

						]
					]
					+ SVerticalBox::Slot().Padding(4,0)
					[
						SNew(SNumericEntryBox<int32>)
						.Value(this, &SDefectWidget::GetDefectRadius)
						.OnValueCommitted(this, &SDefectWidget::SetDefectRadius)
						.AllowSpin(false)
						.LabelPadding(0)
						.MinValue(1)
						.MaxValue(16384)
						.Label()
						[
							SNumericEntryBox<int32>::BuildLabel(LOCTEXT("AreaLabel","Area: "), FLinearColor::Black, FLinearColor(.33f, .33f, .33f))
						]
					]
					+ SVerticalBox::Slot().Padding(4,0)
					[
						SNew(SHorizontalBox)
						+ SHorizontalBox::Slot()
						[
							SNew(SButton)
							.OnClicked(this, &SDefectWidget::Close)
							[
								SNew(STextBlock)
								.ShadowColorAndOpacity(FLinearColor::Black)
								.ColorAndOpacity(FLinearColor::Blue)
								.ShadowOffset(FIntPoint(-1, 1))
								.Font(FSlateFontInfo("Veranda", 12))
								.Text(FText::FromString("Close"))
							]
						]
					]
				]
			]
		];

Hi Naremus,

Could you provide the code you were using originally, without the button workaround?

ChildSlot
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
[
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush(“ToolPanel.GroupBorder”))
.BorderBackgroundColor(FSlateColor::UseForeground())
.Padding(10)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot().Padding(4, 0)
[
SNew(SHeader)
[
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo(“Veranda”, 18))
.Text(this, &SDefectWidget::getHeaderText)

						]
					]
					+ SVerticalBox::Slot().Padding(4,0)
					[
						SNew(SNumericEntryBox<int32>)
						.Value(this, &SDefectWidget::GetDefectRadius)
						.OnValueChanged(this, &SDefectWidget::SetDefectRadius)
						.AllowSpin(false)
						.LabelPadding(0)
						.MinValue(1)
						.MaxValue(16384)
						.Label()
						[
							SNumericEntryBox<int32>::BuildLabel(LOCTEXT("AreaLabel","Area: "), FLinearColor::Black, FLinearColor(.33f, .33f, .33f))
						]
					]
					+ SVerticalBox::Slot().Padding(4,0)
					[
						SNew(SHorizontalBox)
						+ SHorizontalBox::Slot()
						[
							SNew(SButton)
							.OnClicked(this, &SDefectWidget::Close)
							[
								SNew(STextBlock)
								.ShadowColorAndOpacity(FLinearColor::Black)
								.ColorAndOpacity(FLinearColor::Blue)
								.ShadowOffset(FIntPoint(-1, 1))
								.Font(FSlateFontInfo("Veranda", 12))
								.Text(FText::FromString("Close"))
							]
						]
					]
				]
		];

Hi Naremus,

What happens if you have your SBorder swallow the mouse button down event? Something like;

.OnMouseButtonDown(this, &SDefectWidget::OnMouseDown)
...
FReply SDefectWidget::OnMouseDown(const FGeometry& Geometry, const FPointerEvent& MouseEvent)
{
	return FReply::Handled();
}

I’m thinking that if you say the border has ‘handled’ the input, it shouldn’t get trickled down to the other widgets(?). This may, however, stop the widgets you want to be interactable (children of the SBorder) from working too, can you give it a try and let me know please? thanks.

Andrew

That actually works: the child widgets still function normally. Thanks!

Excellent, I’ll have to remember that one myself :slight_smile: