Scenic.ViewPort.Input (Scenic v0.11.0-beta.0) View Source
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
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
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
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
Specs
class() :: :cursor_button | :cursor_scroll | :cursor_pos | :codepoint | :key | :viewport | :relative | :led | :switch
Specs
positional() :: :cursor_button | :cursor_scroll | :cursor_pos | :relative
Specs
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
Specs
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
:pid
- Send input to the specified pid instead of the caller process.
Specs
fetch_captures(viewport :: Scenic.ViewPort.t(), captured_by :: nil | pid()) :: {:ok, list()}
Retrieve a list of input captured by the caller.
Returns: { :ok, list }
Specs
fetch_captures!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}
Retrieve a list of input captured by all processes.
Returns: { :ok, list }
Specs
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 }
Specs
fetch_requests!(viewport :: Scenic.ViewPort.t()) :: {:ok, list()}
Retrieve a list of input requested by all processes.
Returns: { :ok, inputs }
Specs
release( viewport :: Scenic.ViewPort.t(), input_class :: class() | [class()] | :all, opts :: Keyword.t() ) :: :ok
Release the captured inputs from the calling process.
Options
:pid
- Release from the specified pid instead of the caller process.
Specs
release!( viewport :: Scenic.ViewPort.t(), input_class :: class() | [class()] | :all ) :: :ok
Release the captured inputs from ALL processes
Specs
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
:pid
- Send input to the specified pid instead of the caller process.
Specs
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.
Specs
unrequest( viewport :: Scenic.ViewPort.t(), input_class :: class() | [class()] | :all, opts :: Keyword.t() ) :: :ok
Unrequest the captured inputs from the calling process.
Options
:pid
- Unrequest from the specified pid instead of the caller process.
Specs
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.