Tab Order / Focus
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:
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:
Code: Select all
<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>
-
sfernandez
Site Admin
- Posts: 3093
- Joined:
Re: Tab Order / Focus
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.
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.
Re: Tab Order / Focus
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.
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.
-
sfernandez
Site Admin
- Posts: 3093
- Joined:
Re: Tab Order / Focus
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:
Let me know if this fix is working for you.
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:
Code: Select all
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);
}
}
Re: Tab Order / Focus
Hey, thanks for the quick investigation.
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:
k should be 'key' as that is the argument and the Key variable should have different name.
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:
Code: Select all
Key key = static_cast<Key>(k);
-
sfernandez
Site Admin
- Posts: 3093
- Joined:
Re: Tab Order / Focus
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:
We have to add this to the Ogre Bindings too.
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:
Code: Select all
IRenderer* renderer = static_cast<IRenderer*>(uiRenderer);
Noesis::Gui::Key noesisKey = mOISKeyToNoesis[key];
renderer->KeyDown(noesisKey);
You are right, I was just copy-pasting that code from another placek should be 'key' as that is the argument and the Key variable should have different name.
Re: Tab Order / Focus
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.
-
sfernandez
Site Admin
- Posts: 3093
- Joined:
Re: Tab Order / Focus
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.
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.
Re: Tab Order / Focus
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.
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.
Re: Tab Order / Focus
Could you send us a minidump for this crash? Minidumps (*.dmp) files can be generated from our Unhandled Exception Dialog.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.
Thanks.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 3 guests