- KeldorKatarn
- Posts: 193
- Joined:
Removing and detecting keyboard focus in NoesisView
I'm currently designing a UnityScene which is basically a scenario editor. One way of scrolling along the map are the arrow keys.
This is working fine, except I have a combobox in my Noesis UI, which I use to set which terrain I'm trying to edit. However once that combobox is clicked, it has gained keyboard focus.
Any subsequent arrow keys will now not only be caught by Unity but also still go directly to Noesis. This means I'm now not only scrolling but also constantly changing the selected Terrain.
In WPF I can remove such focus by hitting ESC, but that doesn't work in Unity (and wouldn't be what I want anyway).
I would kind of expect to be able to click onto my map at a screen area without UI, or even on the panel outside the ComboBox to remove the focus from the ComboBox, but that doesn't work.
Is there a best practices workflow to achieve this and switch input states between keyboard focus on UI and keyboard focus on game?
I need both directions, obviously I don't want the map to scroll when I'm using the keys to select a terrain either. So I also need a way to detect such a focus in my Unity code.
The fact that the FocusManager is not implemented makes this even harder and currently I don't know how to solve this.
(Btw this is a topic I would expect to be extensively discussed in the documentation, but it isn't. I'm also very confused I can't anything on this forum about it. Considering the amount of games using this I find a ton of standard workflows that seem to be not documented anywhere? Is this the main communication channel for getting this information or am I missing something. I don't know how the bigger titles solve these problems without it being documented anywhere. I feel there's a ton of hidden knowledge somewhere that isn't written down.)
This is working fine, except I have a combobox in my Noesis UI, which I use to set which terrain I'm trying to edit. However once that combobox is clicked, it has gained keyboard focus.
Any subsequent arrow keys will now not only be caught by Unity but also still go directly to Noesis. This means I'm now not only scrolling but also constantly changing the selected Terrain.
In WPF I can remove such focus by hitting ESC, but that doesn't work in Unity (and wouldn't be what I want anyway).
I would kind of expect to be able to click onto my map at a screen area without UI, or even on the panel outside the ComboBox to remove the focus from the ComboBox, but that doesn't work.
Is there a best practices workflow to achieve this and switch input states between keyboard focus on UI and keyboard focus on game?
I need both directions, obviously I don't want the map to scroll when I'm using the keys to select a terrain either. So I also need a way to detect such a focus in my Unity code.
The fact that the FocusManager is not implemented makes this even harder and currently I don't know how to solve this.
(Btw this is a topic I would expect to be extensively discussed in the documentation, but it isn't. I'm also very confused I can't anything on this forum about it. Considering the amount of games using this I find a ton of standard workflows that seem to be not documented anywhere? Is this the main communication channel for getting this information or am I missing something. I don't know how the bigger titles solve these problems without it being documented anywhere. I feel there's a ton of hidden knowledge somewhere that isn't written down.)
- KeldorKatarn
- Posts: 193
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
I came up with some solutions to this problem as part of a behavior but none of it works in Noesis due to the issues below. Especially the issues with the EventArgs setting the Source property to an incorrect value.
https://www.noesisengine.com/bugs/view.php?id=1981
https://www.noesisengine.com/bugs/view.php?id=1982
https://www.noesisengine.com/bugs/view.php?id=1983
https://www.noesisengine.com/bugs/view.php?id=1984
Without those classes existing / providing the correct data, I currently have no ideas on how to solve this problem.
(This is really fundamental functionality, I'm a bit surprised nobody has reported this yet. Does nobody else use this stuff?)
https://www.noesisengine.com/bugs/view.php?id=1981
https://www.noesisengine.com/bugs/view.php?id=1982
https://www.noesisengine.com/bugs/view.php?id=1983
https://www.noesisengine.com/bugs/view.php?id=1984
Without those classes existing / providing the correct data, I currently have no ideas on how to solve this problem.
(This is really fundamental functionality, I'm a bit surprised nobody has reported this yet. Does nobody else use this stuff?)
- KeldorKatarn
- Posts: 193
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
As I said the above functionality is REALLY limiting what I can do here with a behavior.
For now I'm doing this hacky thing:
Ignoring any game keyboard input as long as NoesisView.EnableKeyboard is true.
However I cannot diable the focus border. (Should that even be rendered if EnableKeyboard is false?)
So I kinda still need Keyboard.ClearFocus()
For now I'm doing this hacky thing:
Code: Select all
private void OnEnable()
{
Observable.EveryUpdate()
.Where(
_ => Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) ||
Input.GetMouseButtonDown(2))
.Where(_ => !NoesisView.IsPointerOverGuiElement())
.Subscribe(_ =>
{
//Keyboard.ClearFocus();
NoesisView.EnableKeyboard = false;
})
.AddTo(Subscriptions);
Observable.EveryUpdate()
.Where(
_ => Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) ||
Input.GetMouseButtonDown(2))
.Where(_ => NoesisView.IsPointerOverGuiElement())
.Subscribe(_ =>
{
NoesisView.EnableKeyboard = true;
})
.AddTo(Subscriptions);
}
public static bool IsPointerOverGuiElement(this NoesisView noesisView)
{
if (noesisView.Ref() is null || !(VisualTreeHelper.GetRoot(noesisView.Content) is Visual root))
{
return false;
}
var point = new Point(Input.mousePosition.x, Screen.height - Input.mousePosition.y);
var hit = VisualTreeHelper.HitTest(root, point);
return hit.VisualHit != null;
}
However I cannot diable the focus border. (Should that even be rendered if EnableKeyboard is false?)
So I kinda still need Keyboard.ClearFocus()
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
We already fixed the missing ClearFocus() on Keyboard for the next release.
If you need to set the focus from xaml you can use our SetFocusAction extension, is this what you are looking for?
If you need to set the focus from xaml you can use our SetFocusAction extension, is this what you are looking for?
- KeldorKatarn
- Posts: 193
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
In this bug report I'm describing my use case.
https://www.noesisengine.com/bugs/view.php?id=1984
I'm not sure if that'll be what I finally do yet, as it doesn't work the other way around, since I cannot do a hittest to detect what control I do a mouse click on, on the Unity side.
Right now all I can do is deactivate Keyboard Input depending on what I clicked on altogether.
I'll be interesting to see how I get this to work. I don't have the full use case yet but I somehow need to figure out how to decide when Noesis should get keyboard input and when the game should get it. RIght now Clearing the Focus seems to at least solve one direction. Once I have the FocusManager I might be able to check it in my input handling system and ignore any inputs if Noesis has a focused element. At least that's my current ideas.
How is this normally handled? This must come up more often? After all noesis GUI and the game itself poll the exact same input. Focus seems to be the only way to decide which one of them should handle it.
Edit:
Also SetFocusAction seems to only be able to set a focus, not remove it altogether. I need the focus to be gone. Not change it. i want to remove all focus from the UI so I can detect that and decide I want to process input in the game instead.
https://www.noesisengine.com/bugs/view.php?id=1984
I'm not sure if that'll be what I finally do yet, as it doesn't work the other way around, since I cannot do a hittest to detect what control I do a mouse click on, on the Unity side.
Right now all I can do is deactivate Keyboard Input depending on what I clicked on altogether.
I'll be interesting to see how I get this to work. I don't have the full use case yet but I somehow need to figure out how to decide when Noesis should get keyboard input and when the game should get it. RIght now Clearing the Focus seems to at least solve one direction. Once I have the FocusManager I might be able to check it in my input handling system and ignore any inputs if Noesis has a focused element. At least that's my current ideas.
How is this normally handled? This must come up more often? After all noesis GUI and the game itself poll the exact same input. Focus seems to be the only way to decide which one of them should handle it.
Edit:
Also SetFocusAction seems to only be able to set a focus, not remove it altogether. I need the focus to be gone. Not change it. i want to remove all focus from the UI so I can detect that and decide I want to process input in the game instead.
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
I'm thinking you can use Keyboard.FocusedElement to detect if UI has focus and Keyboard.Focus(null) to clear the focus from the UI and control the game.
Wouldn't that be an option?
Wouldn't that be an option?
- KeldorKatarn
- Posts: 193
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
I'll check. I thought keyboard.FocusedElement was missing. I'll check again next time I'm working on the project.
Re: Removing and detecting keyboard focus in NoesisView
Sorry to bump this, but how can I access Keyboard.FocusedElement in Noesis? KeldorKatarn's last comment suggests to me that maybe you can't, and I can't find it anywhere in the Noesis docs. Knowing the WPF name doesn't really help when things are often named subtly differently (or are missing entirely) in Noesis.
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: Removing and detecting keyboard focus in NoesisView
The Keyboard device can be accessed from any UIElement connected to the UI tree. Then you can get the FocusedElement like in WPF:
Is this what you are looking for?
Code: Select all
UIElement GetFocusedElement(UIElement element)
{
return element.Keyboard.FocusedElement;
}
Re: Removing and detecting keyboard focus in NoesisView
Yep that's exactly what I'm looking for. It's unexpected to me that the keyboard state is accessed through a UIElement, but at least I know where to look now. Thanks.
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot], Semrush [Bot] and 8 guests