lanihou
Topic Author
Posts: 7
Joined: 10 Feb 2018, 20:08

Keyboard input

22 Mar 2019, 22:44

Hi, I am trying to move a shape inside a canvas base on player keyboard input. but no matter what i try , the canvas does not receive the KeyDown event.
here is my code
<UserControl x:Class="HelloWorld.MainWindow"
             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:local="clr-namespace:HelloWorld" 
             xmlns:noesis="clr-namespace:Noesis"
             Background="#FF124C7A"  >

    <Canvas x:Name="CanvasContainer"  KeyDown="Canvas_KeyDown"  >
        <Border x:Name="Player"  BorderBrush="Black" BorderThickness="1" CornerRadius="8" Background="red" Margin="4" Padding="0" Width="80" Height="80"/>
    </Canvas>
</UserControl>
here the code behind
#if UNITY_5_3_OR_NEWER
#define NOESIS
using Noesis;
using UnityEngine;
using Canvas = Noesis.Canvas;
using GUI = Noesis.GUI;

#else
using System;
using System.Windows;
using System.Windows.Controls;
#endif


namespace HelloWorld
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : UserControl
    {
        public MainWindow()
        {
            this.Initialized += OnInitialized;
            InitializeComponent();
        }

#if NOESIS
        public  Canvas CanvasContainer;
        public Border Player;

        private void InitializeComponent()
        {
            Noesis.GUI.LoadComponent(this, "Assets/NoesisGUI/Samples/HelloWorld/MainWindow.xaml");

            this.CanvasContainer = (Canvas)FindName("CanvasContainer");
            this.Player = (Border)FindName("Player");
            CanvasContainer.Focus();
            Player.Focus();
        }
#endif
        private void OnInitialized(object sender, EventArgs args)
        {
            CanvasContainer.Focus();
            Player.Focus();
            //this.DataContext = new ViewModel();
        }
        protected override bool ConnectEvent(object source, string eventName, string handlerName)
        {
            if (eventName == "KeyDown" && handlerName == "Canvas_KeyDown")
            {
                ((Noesis.Canvas)source).KeyDown += Canvas_KeyDown;
                return true;
            }

            return false;
        }

        public void Canvas_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Space)
            {
#if NOESIS
                Debug.Log("Canvas_KeyDown " + e.Key);

#else
            Console.WriteLine("Canvas_KeyDown "+e.Key);
#endif
            }
        }


    }
}
neither of the two method work. I am surely missing something. can you please help me ? thank
Last edited by lanihou on 29 Mar 2019, 10:22, edited 1 time in total.
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Keyboard input

25 Mar 2019, 11:55

Hi,

Keyboard events are routed events – meaning that the event is propagated up or down the logical tree. Routed events can either be bubbling events (they propagate up the tree) or tunneling events (they propagate down the tree). When events are paired, the tunneling events will typically fire first, followed by the paired bubbling event.

For example, the KeyDown event (bubbling) has a corresponding PreviewKeyDown event (tunneling).

In the case of keyboard events, they are routed from the UI element with keyboard focus (a TextBox in the following image).
routed-events.png
routed-events.png (8.73 KiB) Viewed 3783 times

So for your Canvas to be called when a key is pressed, the keyboard focus must be set on any UI control inside that canvas. You can call Focus() on any focusable element to set the keyboard focus.
 
lanihou
Topic Author
Posts: 7
Joined: 10 Feb 2018, 20:08

Re: Keyboard input

29 Mar 2019, 10:27

hi . I updated the code, I included the call to Focus(), in initialization, but still not able to receive the event.
can you please provide a minimalist working example i can learn from .
it is the main thing refraining me from using noesis from my game.
thank

ps : using keyttriger works but it is not pratical because i want to listen to any key.
 
lanihou
Topic Author
Posts: 7
Joined: 10 Feb 2018, 20:08

Re: Keyboard input

29 Mar 2019, 10:51

WORK AROUND FOR NOW (intercept key event in unity and call a method in the mainwindow)
using System.Collections;
using System.Collections.Generic;
using HelloWorld;
using Noesis;
using UnityEngine;

public class InputTest : MonoBehaviour
{
    NoesisView gui;
    MainWindow root;

    // Start is called before the first frame update
    void Start()
    {
        gui = GetComponent<NoesisView>();
        root = (MainWindow) gui.Content;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            print("space key was pressed");

            //attempt to send the event to the view or canvas
            gui.KeyDown(Key.Space);
            root.View.KeyDown(Key.Space);

            //TestFunction is defined in MainWindow.xaml.cs
            root.TestFunction(Key.A);
        }
    }
}
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Keyboard input

01 Apr 2019, 20:20

hi . I updated the code, I included the call to Focus(), in initialization, but still not able to receive the event.
can you please provide a minimalist working example i can learn from .
it is the main thing refraining me from using noesis from my game.
thank

ps : using keyttriger works but it is not pratical because i want to listen to any key.
Try with the following xaml and its code-behind:
<UserControl x:Class="TestKey.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
  xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <noesis:SetFocusAction TargetName="CanvasContainer"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Canvas x:Name="CanvasContainer" Focusable="True" KeyDown="Canvas_KeyDown">
        <Border x:Name="Player" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Background="red" Margin="4" Padding="0" Width="80" Height="80"/>
    </Canvas>
</UserControl>
using Noesis;

namespace TestKey
{
    public class MainWindow : UserControl
    {
        protected override bool ConnectEvent(object source, string eventName, string handlerName)
        {
            if (eventName == "KeyDown" && handlerName == "Canvas_KeyDown")
            {
                ((Canvas)source).KeyDown += Canvas_KeyDown;
                return true;
            }

            return false;
        }

        private void Canvas_KeyDown(object sender, KeyEventArgs e)
        {
            UnityEngine.Debug.Log(e.Key);
        }
    }
}
It is important to note that Canvas is made Focusable so it can receive focus when you call Focus on it (as the SetFocusAction is doing).
 
lanihou
Topic Author
Posts: 7
Joined: 10 Feb 2018, 20:08

Re: Keyboard input

09 Apr 2019, 19:42

thank it works now
 
User avatar
sfernandez
Site Admin
Posts: 2991
Joined: 22 Dec 2011, 19:20

Re: Keyboard input

09 Apr 2019, 21:09

Marked as solved.

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 16 guests