KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Removing and detecting keyboard focus in NoesisView

27 Apr 2021, 00:39

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.)
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Removing and detecting keyboard focus in NoesisView

27 Apr 2021, 01:29

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?)
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Removing and detecting keyboard focus in NoesisView

27 Apr 2021, 02:33

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:
	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;
        }
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()
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Removing and detecting keyboard focus in NoesisView

27 Apr 2021, 21:46

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?
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Removing and detecting keyboard focus in NoesisView

27 Apr 2021, 21:58

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.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Removing and detecting keyboard focus in NoesisView

30 Apr 2021, 19:41

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?
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Removing and detecting keyboard focus in NoesisView

30 Apr 2021, 19:49

I'll check. I thought keyboard.FocusedElement was missing. I'll check again next time I'm working on the project.
 
clysmic
Posts: 4
Joined: 14 Jan 2022, 17:51

Re: Removing and detecting keyboard focus in NoesisView

14 Jan 2022, 20:23

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.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Removing and detecting keyboard focus in NoesisView

17 Jan 2022, 11:00

The Keyboard device can be accessed from any UIElement connected to the UI tree. Then you can get the FocusedElement like in WPF:
UIElement GetFocusedElement(UIElement element)
{
  return element.Keyboard.FocusedElement;
}
Is this what you are looking for?
 
clysmic
Posts: 4
Joined: 14 Jan 2022, 17:51

Re: Removing and detecting keyboard focus in NoesisView

18 Jan 2022, 16:20

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: Google [Bot] and 59 guests