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
@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.
@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 }
@spec fetch_captures!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}
Retrieve a list of input captured by all processes.
Returns: { :ok, list }
@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 }
@spec fetch_requests!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}
Retrieve a list of input requested by all processes.
Returns: { :ok, inputs }
@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.
@spec release!( viewport :: Scenic.ViewPort.t(), input_class :: class() | [class()] | :all ) :: :ok
Release the captured inputs from ALL processes
@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.
@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.