[Slate] HitTest callback

Hello everyone,

I’m currently working on a UI using exclusively Slate/C++. My goal is to provide a set of re-shapable windows containing various widgets (I’m not using the SWindow class).

My WindowWidget uses an Overlay, containing a background (Border) and the actual window’s content (VerticalBox).

The problem is that these windows might overlap and an activation process is required to make this interface usable: clicking on a window should put it in the foreground. I can do that when the WindowWidget receive a MouseButtonDown event, but this event is usually grabbed by the Widgets contained by this window (such as Buttons, ComboBox…). As a result, the window is only activated when clicking on some specific areas.

My first attempt at solving the issue is to add a SensorWidget (basically a Box) in front of the window. For the sake of argument, let’s say that my Window is deactivated (i.e. in foreground). The SensorWidget’s visibility is set to Visible. When a MouseButtonDown event is received, the Sensor requests the activation of the window and sets its visibility to Hidden. The visibility is set to Visible again when an other Window is activated.

It works quite fine, but it leads to an un-wanted behaviour: the components are unusable if the Sensor is Hidden (i.e. if the Window is in the background). I’ve tried to avoid that by calling a part of FSlateApplication::ProcessMouseButtonDownEvent in the Sensor OnMouseButtonDown method after modifying the visibility of the Sensor from Visible to Hidden. It leads to an infinite recursive call. The reason is that the HitTest is based on FSlateApplication::HittestGrid, which is filled at each draw call (if I understand correctly). The alteration of the Sensor visibility is therefore not taken into account.

My questions are the following:

  • Is there a better way to perform what I’m trying to achieve? By that I mean inform a parent widget that one of its children is behind called in a certain way (basically telling my Window that the Button it contains just received a MouseButtonDown event).
  • If not, is there a way to force the update of FSlateApplication::HittestGrid?
  • I’ve noticed the SWidget::OnHitTest function, which is deprecated in 4.5. Will it be re-implemented? What would be its behaviour? I thought I might use it to be aware that my Window was positive to HitTest and therefore launch the activation process.

I hope I’ve been clear enough and I thank you in advance for your help,

Regards,

Alex.

Hi,

Take a look at OnPreviewMouseButtonDown . Its a part of SWidget interface.

/**
	 * Just like OnMouseButtonDown, but tunnels instead of bubbling.
	 * If this even is handled, OnMouseButtonDown will not be sent.
	 * 
	 * Use this event sparingly as preview events generally make UIs more
	 * difficult to reason about.
	 */
	virtual FReply OnPreviewMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent );

Override it on your “window” widget, bring it to front whenever this event is recieved and remember to return FReply::Unhandled() !

Hope that helps

Thank you, that solves the problem very nicely! :slight_smile: