In this lesson, you will learn how to make your custom Slate widgets interactive by capturing and responding to mouse clicks, keyboard focus, and drag-and-drop operations.
The Input Routing System
In Slate, every widget can "handle" an input event by overriding specific virtual functions. When a user clicks or presses a key, the engine sends an FPointerEvent or FKeyEvent through the widget hierarchy. To respond to these, your custom widget class must override the corresponding function and return a FReply object.
The FReply object is your way of telling the engine what happened: did your widget "consume" the input (so no one else gets it), or did you ignore it, letting it bubble down to widgets beneath yours?
Handling Mouse Clicks
To make a widget clickable, override OnMouseButtonDown. You return FReply::Handled() to signify that you’ve processed the click.
FReply SMyCustomWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
{
// Add your custom logic here
return FReply::Handled();
}
return FReply::Unhandled();
}
Keyboard Focus
For a widget to receive keyboard input, it must first be "focusable." You enable this in your widget’s Construct function by setting bCanSupportFocus = true;. Once enabled, you can override OnKeyDown to listen for specific keys. If you want your widget to react as soon as it appears, you can use FSlateApplication::Get().SetKeyboardFocus(SharedThis(this)); to force focus onto it.
Drag-and-Drop
Drag-and-drop is handled via specialized operations. You initiate a drag by returning an FReply::DragDetected from your OnMouseButtonDown or OnMouseMove functions. This triggers OnDragDetected, where you create an FDragDropOperation class. This class acts as a payload container, holding the data being moved, which other widgets can then "detect" and "drop" into using the OnDrop override.
By chaining these events, you transform static UI elements into dynamic, interactive editor tools that feel integrated into the Unreal Engine workflow.
Key Takeaway: Slate interactivity relies on overriding input functions and returning an FReply to tell the engine whether your widget has consumed the event or passed it along the hierarchy.