Drafter.Event (drafter v0.3.1)

Copy Markdown View Source

The event vocabulary: the tagged tuples an application and a widget receive.

What an application receives

An application module's handle_event(event, state) is called with one of these:

  • {:key, key} — a named key (:enter, :escape, :up, :down, :left, :right, :tab, :backspace, :delete, :insert, :home, :end, :page_up, :page_down, :f1..:f12) or, for printable ASCII, the character itself as an atom (:a, :Z, :"1", :" ").
  • {:key, key, modifiers} — the same with a non-empty modifier list, always a subset of [:ctrl, :alt, :shift] in that order.
  • {:char, codepoint} — an integer codepoint outside printable ASCII.
  • {:mouse, payload} — see "Mouse payloads" below.
  • {:bracketed_paste, text} — pasted text with the delimiters stripped, delivered only while Drafter.Clipboard.paste_enabled?/0 is true.
  • {:timer, timer_id} — a timer the application started has fired.
  • {:app_callback, name, data} — a widget invoked a named application callback.
  • {:theme_updated, theme} — the active theme changed.

Two events never reach handle_event/2: {:key, :q, [:ctrl]} stops the application, and {:resize, {cols, rows}} is consumed by the runtime, which passes the new size to the next render/2 as the screen rect.

A focused widget is offered an event before the application is. When the widget consumes it, handle_event/2 is not called for that event.

Mouse payloads

x and y are zero-based column and row on the screen. modifiers is a subset of [:ctrl, :alt, :shift].

  • %{type: :mouse_down | :mouse_up | :drag, button: button, x: x, y: y, modifiers: mods} with button one of :left, :middle, :right, :scroll, :unknown

  • %{type: :move, x: x, y: y, modifiers: mods}
  • %{type: :scroll, direction: :up | :down | :left | :right, x: x, y: y, modifiers: mods}

Widget lifecycle events

Widgets additionally receive {:focus} and {:blur}, and the hierarchy forms {:focus_in, widget_id}, {:focus_out, widget_id}, {:mount, widget_id}, {:unmount, widget_id}, {:show, widget_id}, {:hide, widget_id} and {:load, widget_id}.

Constructors and accessors

The functions here build and inspect those tuples.

iex> Drafter.Event.key(:q, [:ctrl])
{:key, :q, [:ctrl]}

iex> Drafter.Event.key_event?({:key, :enter})
true

The struct form

Drafter.Event.Object is the same event as a struct carrying dispatch phase and propagation flags. from_tuple/1 and to_tuple/1 convert between the two forms and are delegated to that module, along with prevent_default/1, stop_propagation/1 and stop_immediate_propagation/1.

Summary

Functions

A {:blur, widget_id} event, marking that widget as having lost focus.

A {:custom, data} event carrying an application-defined payload.

A {:focus, widget_id} event, marking that widget as having gained focus.

A {:focus_in, widget_id} event, raised on an ancestor when a descendant gains focus.

A {:focus_out, widget_id} event, raised on an ancestor when a descendant loses focus.

The key and its modifiers as {key, modifiers}, or nil for any other event.

The payload map of a mouse event, or nil for any other event.

The new size as {width, height}, or nil for any other event.

A {:hide, widget_id} event, raised when that widget becomes hidden.

A key event for key, carrying modifiers when the list is non-empty.

Whether event is {:key, _} or {:key, _, _}.

A {:load, widget_id} event, raised when that widget has finished loading.

A {:mount, widget_id} event, raised when that widget enters the hierarchy.

A mouse event as {:mouse, %{action: action, x: x, y: y, button: button}}.

Whether event is {:mouse, _}.

Mark an event object as having had its default action prevented.

A resize event as {:resize, {width, height}}, in cells.

Whether event is {:resize, _}.

A {:show, widget_id} event, raised when that widget becomes visible.

Stop an event object travelling further.

Stop an event object travelling to the next widget in the dispatch path.

A {:timer, timer_id} event, delivered when the timer with that id fires.

An {:unmount, widget_id} event, raised when that widget leaves the hierarchy.

Types

key()

@type key() :: atom()

modifiers()

@type modifiers() :: [atom()]

mouse_action()

@type mouse_action() :: :click | :press | :release | :move | :scroll_up | :scroll_down

resize_info()

@type resize_info() :: {width :: pos_integer(), height :: pos_integer()}

t()

@type t() ::
  {:key, key()}
  | {:key, key(), modifiers()}
  | {:char, char()}
  | {:mouse, map()}
  | {:bracketed_paste, binary()}
  | {:resize, resize_info()}
  | {:focus, widget_id :: term()}
  | {:blur, widget_id :: term()}
  | {:focus_in, widget_id :: term()}
  | {:focus_out, widget_id :: term()}
  | {:mount, widget_id :: term()}
  | {:unmount, widget_id :: term()}
  | {:show, widget_id :: term()}
  | {:hide, widget_id :: term()}
  | {:load, widget_id :: term()}
  | {:timer, timer_id :: term()}
  | {:custom, term()}

Functions

blur(widget_id)

@spec blur(term()) :: t()

A {:blur, widget_id} event, marking that widget as having lost focus.

custom(data)

@spec custom(term()) :: t()

A {:custom, data} event carrying an application-defined payload.

focus(widget_id)

@spec focus(term()) :: t()

A {:focus, widget_id} event, marking that widget as having gained focus.

focus_in(widget_id)

@spec focus_in(term()) :: t()

A {:focus_in, widget_id} event, raised on an ancestor when a descendant gains focus.

focus_out(widget_id)

@spec focus_out(term()) :: t()

A {:focus_out, widget_id} event, raised on an ancestor when a descendant loses focus.

from_tuple(event_tuple)

Wrap an event tuple in a Drafter.Event.Object. See Drafter.Event.Object.from_tuple/1.

get_key(arg1)

@spec get_key(t()) :: {key(), modifiers()} | nil

The key and its modifiers as {key, modifiers}, or nil for any other event.

An unmodified {:key, key} yields an empty modifier list.

Examples

iex> Drafter.Event.get_key({:key, :enter})
{:enter, []}

iex> Drafter.Event.get_key({:key, :q, [:ctrl]})
{:q, [:ctrl]}

iex> Drafter.Event.get_key({:mouse, %{}})
nil

get_mouse(arg1)

@spec get_mouse(t()) :: map() | nil

The payload map of a mouse event, or nil for any other event.

Examples

iex> Drafter.Event.get_mouse({:mouse, %{action: :move, x: 1, y: 2}})
%{action: :move, x: 1, y: 2}

iex> Drafter.Event.get_mouse({:key, :a})
nil

get_resize(arg1)

@spec get_resize(t()) :: resize_info() | nil

The new size as {width, height}, or nil for any other event.

Examples

iex> Drafter.Event.get_resize({:resize, {80, 24}})
{80, 24}

iex> Drafter.Event.get_resize({:key, :a})
nil

hide(widget_id)

@spec hide(term()) :: t()

A {:hide, widget_id} event, raised when that widget becomes hidden.

key(key, modifiers \\ [])

@spec key(key(), modifiers()) :: t()

A key event for key, carrying modifiers when the list is non-empty.

Returns {:key, key} for the default empty modifier list and {:key, key, modifiers} otherwise, so a caller matching on {:key, k} sees unmodified keys only.

Examples

iex> Drafter.Event.key(:enter)
{:key, :enter}

iex> Drafter.Event.key(:q, [:ctrl])
{:key, :q, [:ctrl]}

key_event?(arg1)

@spec key_event?(t()) :: boolean()

Whether event is {:key, _} or {:key, _, _}.

Examples

iex> Drafter.Event.key_event?({:key, :enter})
true

iex> Drafter.Event.key_event?({:key, :q, [:ctrl]})
true

iex> Drafter.Event.key_event?({:mouse, %{}})
false

load(widget_id)

@spec load(term()) :: t()

A {:load, widget_id} event, raised when that widget has finished loading.

mount(widget_id)

@spec mount(term()) :: t()

A {:mount, widget_id} event, raised when that widget enters the hierarchy.

mouse(action, x, y, button \\ :left)

@spec mouse(mouse_action(), non_neg_integer(), non_neg_integer(), atom()) :: t()

A mouse event as {:mouse, %{action: action, x: x, y: y, button: button}}.

x and y are zero-based column and row; button defaults to :left. The payload is keyed by :action and carries no modifiers, unlike the :type-keyed payloads the terminal driver produces and documented in the moduledoc.

Examples

iex> Drafter.Event.mouse(:click, 3, 4)
{:mouse, %{action: :click, x: 3, y: 4, button: :left}}

iex> Drafter.Event.mouse(:press, 0, 0, :right)
{:mouse, %{action: :press, x: 0, y: 0, button: :right}}

mouse_event?(arg1)

@spec mouse_event?(t()) :: boolean()

Whether event is {:mouse, _}.

Examples

iex> Drafter.Event.mouse_event?(Drafter.Event.mouse(:click, 1, 1))
true

iex> Drafter.Event.mouse_event?({:key, :a})
false

prevent_default(event_object)

Mark an event object as having had its default action prevented.

resize(width, height)

@spec resize(pos_integer(), pos_integer()) :: t()

A resize event as {:resize, {width, height}}, in cells.

Examples

iex> Drafter.Event.resize(80, 24)
{:resize, {80, 24}}

resize_event?(arg1)

@spec resize_event?(t()) :: boolean()

Whether event is {:resize, _}.

Examples

iex> Drafter.Event.resize_event?({:resize, {80, 24}})
true

iex> Drafter.Event.resize_event?({:key, :a})
false

show(widget_id)

@spec show(term()) :: t()

A {:show, widget_id} event, raised when that widget becomes visible.

stop_immediate_propagation(event_object)

Stop an event object travelling further.

Stronger than stop_propagation/1: it also prevents the remaining handlers on the current widget from seeing the event.

stop_propagation(event_object)

Stop an event object travelling to the next widget in the dispatch path.

timer(timer_id)

@spec timer(term()) :: t()

A {:timer, timer_id} event, delivered when the timer with that id fires.

Examples

iex> Drafter.Event.timer(:tick)
{:timer, :tick}

to_tuple(event_object)

Unwrap a Drafter.Event.Object back to an event tuple. See Drafter.Event.Object.to_tuple/1.

unmount(widget_id)

@spec unmount(term()) :: t()

An {:unmount, widget_id} event, raised when that widget leaves the hierarchy.