User Interaction

This topic describes how your application can receive input from a remote control, keyboard, or gamepad.


Related Info


Samples


Remote Control

The remote control is the most common way for users to interact with the TV.

Basic Remote Control Samsung Smart Remote

Table 1. Remote control types

  • Basic remote control
    The basic remote control is a traditional remote control that has, for example, number keys and colored function keys.
  • Samsung Smart Remote
    The Samsung Smart Remote has only the essential keys and some special function keys. The user can access additional virtual keys on the TV screen by clicking the "123" or "..." keys.

Figure 1. Virtual keys accessed from the "123" key

Figure 2. Virtual keys accessed from the "..." key

Detecting Key Events

To detect remote control key clicks:

  1. To detect remote control key clicks, create an event handler for the KeyDown or KeyUp event:

    using ElmSharp;
    
    _keyDown = new EcoreEvent<EcoreKeyEventArgs>(EcoreEventType.KeyDown,  
                                                 EcoreKeyEventArgs.Create);
    _keyDown.On += (s, e) =>
    {
      // Do something
    };
    
  2. Define the event handler.
    When a remote control key is clicked, the KeyDown or KeyUp event passes the clicked key's KeyName value to the event handler as a parameter.

    _keyDown.On += (s, e) =>
    {
      if (e.KeyName.Equals("XF86AudioPlay"))
      {
        // Do something
      }
      else if (e.KeyName.Equals("XF86AudioPause"))
      {
        // Do something
      }
    }
    

Publishing Key Events

If you want to send an event to another view, you can use the Xamarin.Forms MessagingCenter class. The features of the MessagingCenter class enable components to communicate without having to know anything about each other. You can send a key event by publishing it, and all components that have subscribed to the same key event receive it.

  • To publish an event:

    _keyDown = new EcoreEvent<EcoreKeyEventArgs>(EcoreEventType.KeyDown, 
                                                 EcoreKeyEventArgs.Create);
    _keyDown.On += (s, e) =>
    {
      Xamarin.Forms.MessagingCenter.Send<IKeyEventSender, string>(this, "KeyDown", e.KeyName);
    };
    
  • To subscribe to an event:

    MessagingCenter.Subscribe<IKeyEventSender, string>(this, "KeyDown", (s, e) =>
    {
      if (e.Contains("Select"))
      {
          // Do something
      }
    });
    
  • To unsubscribe from an event:

    MessagingCenter.Unsubscribe<IKeyEventSender, string>(this, "KeyDown");
    

Remote Control Keys

The following table lists the basic remote control keys and their corresponding key names.

Key Key Name Key Key Name Key Key Name
1 1 VOL+ XF86AudioRaiseVolume A XF86Red
2 2 VOL- XF86AudioLowerVolume B XF86Green
3 3 Mute XF86AudioMute C XF86Yellow
4 4 CH+ XF86RaiseChannel D XF86Blue
5 5 CH- XF86LowerChannel ◀◀ XF86AudioRewind
6 6 TOOLS XF86SimpleMenu ◀◀
(long press)

XF86PreviousChapter
7 7 INFO XF86Info ▶▶ XF86AudioNext
8 8 Up ▶▶
(long press)

XF86NextChapter
9 9 Down XF86AudioPause
0 0 Left XF86AudioRecord
- Minus Right XF86AudioPlayv
PRE-CH XF86PreviousChannel ENTER Return XF86AudioStop
RETURN XF86Back EXIT XF86Exit

Table 2. Basic remote control keys

The following table lists the Samsung Smart Remote keys and their corresponding key names.

Key Key Name Key Key Name
Up ▷Ⅱ XF86PlayBack
Down VOL XF86AudioMute
Left VOL+ XF86AudioRaiseVolume
Right VOL- XF86AudioLowerVolume
ENTER Return CH XF86ChannelGuide
RETURN XF86Back CH+ XF86RaiseChannel
RETURN
(long press)

XF86Exit CH- XF86LowerChannel

Table 3. Samsung Smart Remote keys

Keyboard/IME

The user can interact with your application by entering text with a virtual keyboard (IME). When an Entry element in your application is focused, the virtual keyboard is shown. When the element loses focus, the keyboard is hidden.

The user can also connect a physical keyboard to the TV to enter text more conveniently. When a physical keyboard is connected, the IME is automatically hidden when any key on the physical keyboard is pressed.

Figure 3. IME

To manage the IME:

  • To handle IME input, create event handlers for the Entry element events:

    • The Focused event is fired when the Entry element is focused.
    • TheUnfocused event is fired when the Entry element loses focus.
    • The TextChanged event is fired when the value of the Entry element changes.
    Entry entry = new Entry();
    
    entry.TextChanged += (s, e) =>
    {
      // Do something
    };
    
    entry.Focused += (s, e) =>
    {
      // Do something
    };
    
    entry.Unfocused += (s, e) =>
    {
      // Do something
    };
    
  • To close the IME when the "Done" or "Cancel" IME key, or the remote control "Back" key, is clicked, create event handlers for the Select and Cancel events. You must also remove focus from the Entry element:

    Entry entry;
    Button button;
    
    StackLayout layout = new StackLayout
    {
      Orientation = StackOrientation.Horizontal,
      HorizontalOptions = LayoutOptions.CenterAndExpand,
      Spacing = 20,
    };
    
    button = new Button
    {
      Text = "OK",
    };
    
    entry = new Entry
    {
      BackgroundColor = Color.White,
      WidthRequest = 600,
    };
    
    entry.Focused += (sender, ev) =>
    {
      MessagingCenter.Subscribe<IKeyEventSender, string>(this, "KeyDown", (s, e) =>
      {
        if (e.Contains("Select") || e.Contains("Cancel"))
        {
          button.Focus();
        }
      });
    };
    
    entry.Unfocused += (senders, ev) =>
    {
      MessagingCenter.Unsubscribe<IKeyEventSender, string>(this, "KeyDown");
    };
    
    layout.Children.Add(entry);
    layout.Children.Add(button);
    

Gamepad

The user can interact with your game application using a gamepad, connected to the TV through USB or Bluetooth. The following figure shows a typical gamepad button mapping for the TizenFX gamepad interface.

Figure 4. Gamepad key mapping

The TizenFX gamepad interface is modeled after the MonoGame gamepad APIs. However, compatibility with MonoGame gamepad APIs is not guaranteed.

Prerequisites

To use the methods and properties of the TizenFX gamepad interface, include the Tizen.TV.Accessory namespace in your application:

using Tizen.TV.Accessory;

Handling Gamepad Input

You can handle gamepad input within a loop:

  1. To retrieve the gamepad state:

    GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
    

    If there is more than 1 connected gamepad, use the PlayerIndex properties to distinguish between them. For example, to retrieve the state of a second gamepad, use the PlayerIndex.Two property.

  2. Check whether the gamepad is connected:

    if (gamePadState.IsConnected)
    {
      // Get input
    }
    
  3. To react to gamepad key presses:

    • Handle button states using the GamePadState.Buttons properties:
      For example, to check whether button A is pressed:

      if (gamePadState.Buttons.A == ButtonState.Pressed)
      {
        // Take some action
      }
      
    • Handle directional pad states using the GamePadState.DPad properties:

      if (gamePadState.DPad.Down == ButtonState.Pressed)
      {
          // Take some action
      }
      
    • Handle thumb stick input using the GamePadState.ThumbSticks properties.
      The property values range from -1 to 1, in both X and Y directions. For the X direction, -1 is the leftmost position, 0 is at center, and 1 is the rightmost position. For the Y direction, -1 is down, 0 is at center, and 1 is up.

      float angularFactor = 0.1f;
      float angularChange = gamePadState.ThumbSticks.Left.X * angularFactor;
      
    • Handle trigger key input using the GamePadState.Triggers properties.
      The property values range from 0 (the trigger key is released) to 1 (the trigger key is fully depressed).

      float leftTriggerValue = gamePadState.Triggers.Left;
      
    • To avoid detecting a continuous button press, detect when the button state changes:

      private GamePadState oldState;
      GamePadState newState = GamePad.GetState(PlayerIndex.One);
      if ((newState.Button.A == ButtonState.Pressed) && 
          (oldState.Button.A == ButtonState.Released))
      {
        // React to button press
      }
      oldState = newState;