I’ve got an editor window that shows a bunch of VisualElements in a grid. I want to know if the user presses “b” with the mouse over one of the elements, and if they do, I want to know which VisualElement it is.
I wanted to add a KeyDownEvent to the VisualElements themselves, but that only fires if they have “focus”, which isn’t applicable at all here. So my current hack is:
// in the specific visual elements:
RegisterCallback<MouseEnterEvent>(evt => window.mousedOver = this);
RegisterCallback<MouseLeaveEvent>(evt => window.mousedOver = null);
// in OnEnable() on the window itself:
if (rootVisualElement.parent == null) // this is null in OnEnable... sometimes
EditorApplication.delayCall += SubscribeKeyDownEvent;
else
SubscribeKeyDownEvent();
...
private void SubscribeKeyDownEvent() {
var keyDownReceiver = rootVisualElement;
while (keyDownReceiver.parent != null) {
keyDownReceiver = keyDownReceiver.parent;
}
keyDownReceiver.RegisterCallback<KeyDownEvent>(KeyDown);
}
...
private void KeyDown(KeyDownEvent evt) {
if (evt.keyCode == KeyCode.B && mousedOver != null) {
HandleBPressedOver(mousedOver);
}
}
This is just painful. It will also probably break if stuff starts having focus? idk. There’s gotta be a better way to handle this! In imgui I’d check if Event.Current was a keydown event with the b keyCode, and then I’d painstakingly figure out the mouse position vs. the element positions. The “what is the mouse over” thing has become a lot easier, but getting a notif when the key is down only being available for focused things seems like a very silly restriction.