View Source Scenic.ViewPort.Input (Scenic v0.11.2)

The low-level interface for working in input into and out of a ViewPort.

You will typically use the input related functions in Scenic.Scene, which wrap this module and make them easy to use from a Scene module.

If you wanted monitor input from some other GenServer, or inject input into a ViewPort, then this is the API to use.

Input events begin when a driver sends an event to the ViewPort it is attached to. In order to keep scenes simple, and to reduce the amount of work and data transferred when input is created (for example, a moving mouse...), events are only sent to any scenes that have indicated that they are listening.

There are two ways a scene indicates that it is interested in an input event.

requested-input

Requested Input

Normally, a scene "requests" input. This will route any keyboard or other location independent events to the scene. However, any positional input, such as :cursor_button will only be received it if is over an item in a graph managed by a scene that has the input: true style.

graph
  |> rect( {20, 40}, t: {10, 10}, id: :rect_in, input: true, fill: :blue )
  |> rect( {20, 40}, t: {10, 50}, id: :rect_other, fill: :blue )

In the above example, the scene would only receive :cursor_button events if the :rect_in rect is clicked. This is because it is the only rect that has the input: true style on it.

Cursor clicks over the :rect_other rect, are not delivered to the scene.

captured-input

Captured Input

If you look at the code behind components such as Button or Slider, you will see that when the button is clicked, it "captures" the :cursor_button input type.

This causes the caller to receive all input events of that type, regardless of the :input style. This means that even :cursor_button events that would be otherwise be routed to some other scene are sent only to the scene that has captured the input. The other scene that has only "requested" the event does not receive it.

If multiple scenes have captured an input type, the most recent call wins. When scene releases the capture, the event type remains captured but is now sent to the second scene that had been overridden.

sending-input

Sending Input

When a driver (or any other caller, but it is typically a Scenic.Driver) wants to send an input event to the ViewPort, it creates a message and sends it to it's ViewPort with the Scenic.ViewPort.Input.send/2 function.

Drivers have no knowledge of the running scenes. The ViewPort takes care of that routing.

Input events are validated against Scenic.ViewPort.Input.validate/1 function.

Link to this section Summary

Functions

Capture one or more types of input.

Retrieve a list of input captured by the caller.

Retrieve a list of input captured by all processes.

Retrieve a list of input requested by the caller or the process requested_by.

Retrieve a list of input requested by all processes.

Release the captured inputs from the calling process.

Release the captured inputs from ALL processes

Request one or more types of input.

Send raw input to a viewport.

Unrequest the captured inputs from the calling process.

Validate an input message.

Link to this section Types

@type class() ::
  :cursor_button
  | :cursor_scroll
  | :cursor_pos
  | :codepoint
  | :key
  | :viewport
  | :relative
  | :led
  | :switch
@type positional() :: :cursor_button | :cursor_scroll | :cursor_pos | :relative
@type t() ::
  {:codepoint,
   {codepoint :: String.t(), mods :: Scenic.Driver.KeyMap.mod_keys()}}
  | {:key,
     {key :: atom(), value :: integer(),
      mods :: Scenic.Driver.KeyMap.mod_keys()}}
  | {:cursor_button,
     {button :: atom(), value :: integer(),
      mods :: Scenic.Driver.KeyMap.mod_keys(), position :: Scenic.Math.point()}}
  | {:cursor_scroll,
     {offset :: Scenic.Math.point(), position :: Scenic.Math.point()}}
  | {:cursor_pos, position :: Scenic.Math.point()}
  | {:viewport, {:enter | :exit | :reshape, xy :: Scenic.Math.point()}}
  | {:relative, vector :: Scenic.Math.point()}
  | {:led, {id :: atom(), value :: integer()}}
  | {:switch, {id :: atom(), value :: integer()}}

Link to this section Functions

Link to this function

capture(viewport, inputs, opts \\ [])

View Source
@spec capture(
  viewport :: Scenic.ViewPort.t(),
  inputs :: class() | [class()],
  opts :: Keyword.t()
) :: :ok

Capture one or more types of input.

Returns :ok or an error

options

Options

  • :pid - Send input to the specified pid instead of the caller process.
Link to this function

fetch_captures(viewport, captured_by \\ nil)

View Source
@spec fetch_captures(
  viewport :: Scenic.ViewPort.t(),
  captured_by :: nil | pid()
) :: {:ok, list()}

Retrieve a list of input captured by the caller.

Returns: { :ok, list }

Link to this function

fetch_captures!(viewport)

View Source
@spec fetch_captures!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}

Retrieve a list of input captured by all processes.

Returns: { :ok, list }

Link to this function

fetch_requests(viewport, requested_by \\ nil)

View Source
@spec fetch_requests(
  viewport :: Scenic.ViewPort.t(),
  requested_by :: nil | pid()
) :: {:ok, list()}

Retrieve a list of input requested by the caller or the process requested_by.

Returns: { :ok, inputs }

Link to this function

fetch_requests!(viewport)

View Source
@spec fetch_requests!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}

Retrieve a list of input requested by all processes.

Returns: { :ok, inputs }

Link to this function

release(viewport, inputs \\ :all, opts \\ [])

View Source
@spec release(
  viewport :: Scenic.ViewPort.t(),
  input_class :: class() | [class()] | :all,
  opts :: Keyword.t()
) :: :ok

Release the captured inputs from the calling process.

options

Options

  • :pid - Release from the specified pid instead of the caller process.
Link to this function

release!(viewport, inputs)

View Source
@spec release!(
  viewport :: Scenic.ViewPort.t(),
  input_class :: class() | [class()] | :all
) :: :ok

Release the captured inputs from ALL processes

Link to this function

request(viewport, inputs, opts \\ [])

View Source
@spec request(
  viewport :: Scenic.ViewPort.t(),
  inputs :: class() | [class()],
  opts :: Keyword.t()
) :: :ok

Request one or more types of input.

Returns :ok or an error

options

Options

  • :pid - Send input to the specified pid instead of the caller process.
@spec send(
  viewport :: Scenic.ViewPort.t(),
  input :: t()
) :: :ok | {:error, atom()}

Send raw input to a viewport.

This is used primarily by drivers to send raw user input to the viewport. Having said that, nothing stops a scene or any other process from using it to send input into the system. There are a few cases where that is useful.

See the input types for the input formats you can send.

Link to this function

unrequest(viewport, inputs \\ :all, opts \\ [])

View Source
@spec unrequest(
  viewport :: Scenic.ViewPort.t(),
  input_class :: class() | [class()] | :all,
  opts :: Keyword.t()
) :: :ok

Unrequest the captured inputs from the calling process.

options

Options

  • :pid - Unrequest from the specified pid instead of the caller process.
@spec validate(input :: t()) :: :ok | {:error, :invalid}

Validate an input message.

Returns :ok if the message is valid.

Returns {:error, :invalid} if the message is not valid.