Daki
Topic Author
Posts: 57
Joined: 16 Aug 2013, 00:48

Tab Order / Focus

01 Sep 2013, 23:43

Are there directions anywhere for setting up navigating between elements using the keyboard? I'm just trying to get something simple working with tabbing to move the focus the between a few buttons.

When I manually call Focus on an element it gets focused, but when I try using SetIsTabStop, SetTabIndex and moving the focus with MoveFocus I am not seeing anything. MoveFocus returns false when I call it on the currently focused item.

I'm using a test xaml file which is very simple:
<Grid
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
	xmlns:noesis="clr-namespace:NoesisGUIExtensions">
	
	<Grid.Resources>
		<Storyboard x:Name="AnimInFromSplash">
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonPlay" d:IsOptimized="True"/>
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonEdit" d:IsOptimized="True"/>
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonOptions" d:IsOptimized="True"/>
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LogoBorder" d:IsOptimized="True"/>
		</Storyboard>
		<Storyboard x:Name="AnimIn">
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonPlay" d:IsOptimized="True"/>
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonEdit" d:IsOptimized="True"/>
			<DoubleAnimation Duration="0:0:1" From="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ButtonOptions" d:IsOptimized="True"/>
		</Storyboard>
	</Grid.Resources>
	
	<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
		<Border x:Name="LogoBorder" BorderBrush="Black" BorderThickness="1" Margin="5,0" HorizontalAlignment="Center" VerticalAlignment="Center">
			<Image Source="main_menu_logo.png" Stretch="None"/>
		</Border>
		<Button x:Name="ButtonPlay" Content="Play" Width="120" Height="40" FontFamily="fonts/#meiryo"/>
		<Button x:Name="ButtonEdit" Content="Edit" Width="120" Height="40" FontFamily="fonts/#meiryo"/>
		<Button x:Name="ButtonOptions" Content="Options" Width="120" Height="40" FontFamily="fonts/#meiryo"/>
	</StackPanel>
</Grid>
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Tab Order / Focus

03 Sep 2013, 01:10

SetIsTabStop and SetTabIndex values are taken into account when changing focus with the TAB key or ARROW keys. Do not working? :?

MoveFocus is not implemented, if you require it we can add this feature to a next release because most of the code is already there for keyboard navigation.
 
Daki
Topic Author
Posts: 57
Joined: 16 Aug 2013, 00:48

Re: Tab Order / Focus

03 Sep 2013, 02:02

Right, the tab and arrow keys are not doing anything, which is why I tried to do it manually with MoveFocus. I don't really need MoveFocus to work if it would work normally.

I just tried playing around with it a little more. I am using Ogre. I noticed that in one of the Noesis Ogre samples the OIS::KeyListener keyPressed and keyReleased functions are returning true whereas mine were returning false, since this is stressed in the OIS integration guide (http://www.ogre3d.org/tikiwiki/tiki-ind ... =Using+OIS). I tried returning true but this doesn't have any effect.

I think keyboard input isn't working at all actually because using space or enter to select a button does not appear to work either.

I also noticed a more worrisome issue which is that if I have some ui up with a few buttons and repeatedly tap the tab and arrow keys, then the moment I move my mouse cursor over one of the buttons Noesis crashes with an unhandled exception in the Noesis::Main thread. There is nothing of note in the log.

This crash is only happening for me in the following case. I have two screens (two xaml files) each with their own root and renderer. They both have a few buttons on them. One button on the first screen brings the user to the second screen. I have a delegate for that button's OnClick event which I use to play some transition animations. When the animation is complete I use SetVisibility and SetIsEnabled on the roots of the screens to control which is present. I only route input to the renderer of the screen which is present. Both screens are loaded all the time. When I spam tab and the arrow keys on the first screen and then move the cursor over a button, nothing out of the ordinary happens. When I do it on the second screen however it crashes.

This may be related to something else I noticed. When I move my cursor over a button on the first screen the button becomes highlighted. Then I press it and I am brought to the second screen. I move my mouse over a button on this screen and it highlights. Then I press that and I am taken back to the original screen. At this point the first button I pressed, which is now visible again, is still highlighted as if the cursor were over it. The moment I move my cursor the highlight goes away.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Tab Order / Focus

04 Sep 2013, 01:13

I was looking at the Ogre Bindings code and now I understand why keyboard focus is not working. Tab and directional focus are notified to the IRenderer via virtual events, and Ogre Bindings are not generating them.

You said you compile the bindings yourself, so I think you could add the following hot fix while we update the bindings.

In OgreNsGuiBindings.cpp, change the function Noesis_KeyDown for this one:
extern "C" NS_DLL_EXPORT void Noesis_KeyDown(void* uiRenderer, int key)
{
	IRenderer* renderer = static_cast<IRenderer*>(uiRenderer);

        Keyboard* keyboard = renderer->GetContent()->GetKeyboard();
        NS_ASSERT(keyboard);

        NsUInt32 keyModifiers = keyboard->GetModifiers();
        NsBool isCtrlPressed = (keyModifiers & ModifierKeys_Control) != 0;
        NsBool isShiftPressed = (keyModifiers & ModifierKeys_Shift) != 0;

        Key key = static_cast<Key>(k);

        // Notify of key event to the renderer
        renderer->KeyDown(key);

        // Virtual events
        if (key == Gui::Key_Tab)
        {
            renderer->VirtualEvent(isCtrlPressed ?
                (isShiftPressed ? VirtualEvent_ControlTabPrev : VirtualEvent_ControlTabNext) :
                (isShiftPressed ? VirtualEvent_DirectionalTabPrev : VirtualEvent_DirectionalTabNext));
        }
        else if (key == Gui::Key_Left)
        {
            renderer->VirtualEvent(VirtualEvent_DirectionalLeft);
        }
        else if (key == Gui::Key_Right)
        {
            renderer->VirtualEvent(VirtualEvent_DirectionalRight);
        }
        else if (key == Gui::Key_Up)
        {
            renderer->VirtualEvent(VirtualEvent_DirectionalUp);
        }
        else if (key == Gui::Key_Down)
        {
            renderer->VirtualEvent(VirtualEvent_DirectionalDown);
        }
}
Let me know if this fix is working for you.
 
Daki
Topic Author
Posts: 57
Joined: 16 Aug 2013, 00:48

Re: Tab Order / Focus

04 Sep 2013, 02:17

Hey, thanks for the quick investigation. :D

I've integrated your code but there is still one small issue. It appears the key mappings are off between Noesis and OIS. When I hit left tab OIS represents that with 0x0F in their KeyCode enumeration. 0x0F maps to Key_Left in the Noesis Key enumeration however and the logic you provided is just casting one to the other.

For example when I press "1" (which maps to tab in Noesis) I see the focus moving between my buttons as expected. Then when I hit "9" (which maps to space) the focused button is pressed. So it looks like it is fixed except for that mapping issue.

Also (minor issue which I'm sure you'd catch when compiling), in this line:
 Key key = static_cast<Key>(k);
k should be 'key' as that is the argument and the Key variable should have different name.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Tab Order / Focus

04 Sep 2013, 03:46

Before calling renderer->KeyDown() (or KeyUp), Ogre own key code needs to be translated to the corresponding Noesis::Gui::Key value.

Looking at the code of the samples provided with Ogre Bindings I'm quite sure key events never worked, because no translation is performed, OIS::KeyEvent::key it's being used directly. There should be a map to make that conversion easier:
IRenderer* renderer = static_cast<IRenderer*>(uiRenderer);
Noesis::Gui::Key noesisKey = mOISKeyToNoesis[key];
renderer->KeyDown(noesisKey);
We have to add this to the Ogre Bindings too.

k should be 'key' as that is the argument and the Key variable should have different name.
You are right, I was just copy-pasting that code from another place ;)
 
Daki
Topic Author
Posts: 57
Joined: 16 Aug 2013, 00:48

Re: Tab Order / Focus

04 Sep 2013, 04:09

Where should that mOISKeyToNoesis array be defined? I'd like to put it in my code unless you guys plan on releasing an update to the bindings soon in which case I'll just grab the update.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Tab Order / Focus

04 Sep 2013, 04:21

I think that if keys are always coming from OIS::KeyEvent, then it will be fine to define this map inside Ogre Bindings, and you could just grab it when we update (during this week).

But if your application feeds ogre bindings with other key codes (for example, VK_ codes from Win32 API), then the translation to a Noesis key code should be done in your application logic, before calling Noesis_KeyDown/KeyUp functions.
 
Daki
Topic Author
Posts: 57
Joined: 16 Aug 2013, 00:48

Re: Tab Order / Focus

04 Sep 2013, 04:30

Yeah, I would put it in the OgreBindings logic.

I was mainly curious if Noesis already had that array defined so that I could paste it into my version of the bindings as a hot-fix (as opposed to me writing it by hand). If you don't already have it written though I can wait until the update goes out. :)
 
User avatar
jsantos
Site Admin
Posts: 2899
Joined: 20 Jan 2012, 17:18
Contact:

Re: Tab Order / Focus

04 Sep 2013, 20:49

I also noticed a more worrisome issue which is that if I have some ui up with a few buttons and repeatedly tap the tab and arrow keys, then the moment I move my mouse cursor over one of the buttons Noesis crashes with an unhandled exception in the Noesis::Main thread. There is nothing of note in the log.
Could you send us a minidump for this crash? Minidumps (*.dmp) files can be generated from our Unhandled Exception Dialog.

Thanks.

Who is online

Users browsing this forum: No registered users and 1 guest