Module: Plushie::Event::Specs

Defined in:
lib/plushie/event/specs.rb

Overview

Canonical event specs for all built-in widget event types.

Each spec describes the payload shape a WidgetEvent carries:

  • carrier: :none - no payload (just id/scope)
  • carrier: :value, value_type: :string - scalar in value
  • carrier: :value, fields: {name: type} - Hash in value with declared keys

Used by the canvas widget emit path, protocol decoder, and as the authoritative reference for what each event type carries.

Examples:

Query a spec

Event::Specs.for(:press)
# => {carrier: :value, fields: {x: :float, y: :float, ...}}

Check if an event type exists

Event::Specs.builtin?(:click) # => true

Category predicates on Widget events

event.pointer?  # true for press, release, move, scroll, ...
event.keyboard? # true for key_press, key_release

Constant Summary collapse

NONE =

Carrier for events with no payload (just id, type, scope).

:none
VALUE =

Carrier for events with data in the Widget value field.

:value
POINTER_TYPES =

Returns:

  • (Set<Symbol>)
Set[:press, :release, :move, :scroll, :enter, :exit, :double_click].freeze
KEYBOARD_TYPES =

Returns:

  • (Set<Symbol>)
Set[:key_press, :key_release].freeze
PANE_TYPES =

Returns:

  • (Set<Symbol>)
Set[:pane_resized, :pane_dragged, :pane_clicked, :pane_focus_cycle].freeze
FOCUS_TYPES =

Returns:

  • (Set<Symbol>)
Set[:focused, :blurred].freeze
DRAG_TYPES =

Returns:

  • (Set<Symbol>)
Set[:drag, :drag_end].freeze
BUILTIN =

-- Built-in event specs -----------------------------------------------

{
  # Standard widget events
  status: {carrier: VALUE, value_type: :string},
  click: {carrier: NONE},
  input: {carrier: VALUE, value_type: :string},
  submit: {carrier: VALUE, value_type: :string},
  toggle: {carrier: VALUE, value_type: :boolean},
  select: {carrier: VALUE, value_type: :any},
  slide: {carrier: VALUE, value_type: :float},
  slide_release: {carrier: VALUE, value_type: :float},
  paste: {carrier: VALUE, value_type: :string},
  open: {carrier: NONE},
  close: {carrier: NONE},
  option_hovered: {carrier: VALUE, value_type: :any},
  # steep:ignore:start
  key_binding: {carrier: VALUE, fields: {}},
  # steep:ignore:end
  link_click: {carrier: VALUE, value_type: :string},
  sort: {carrier: VALUE, value_type: :string},
  scrolled: {
    carrier: VALUE,
    fields: {
      absolute_x: :float, absolute_y: :float,
      relative_x: :float, relative_y: :float,
      bounds_width: :float, bounds_height: :float,
      content_width: :float, content_height: :float
    }
  },

  # Focus and blur (generic element events)
  focused: {carrier: NONE},
  blurred: {carrier: NONE},

  # Drag events
  drag: {
    carrier: VALUE,
    fields: {x: :float, y: :float, delta_x: :float, delta_y: :float}
  },
  drag_end: {
    carrier: VALUE,
    fields: {x: :float, y: :float}
  },

  # Widget-scoped key events
  key_press: {
    carrier: VALUE,
    fields: {
      key: :key, modified_key: :string, physical_key: :string,
      location: :string, modifiers: :key_modifiers,
      text: :string, repeat: :boolean
    },
    required: %i[key modifiers]
  },
  key_release: {
    carrier: VALUE,
    fields: {
      key: :key, modified_key: :string, physical_key: :string,
      location: :string, modifiers: :key_modifiers,
      text: :string, repeat: :boolean
    },
    required: %i[key modifiers]
  },

  # Unified pointer events
  press: {
    carrier: VALUE,
    fields: {
      x: :float, y: :float, button: :pointer,
      pointer: :symbol, finger: :float, modifiers: :any
    }
  },
  release: {
    carrier: VALUE,
    fields: {
      x: :float, y: :float, button: :pointer,
      pointer: :symbol, finger: :float, modifiers: :any
    }
  },
  move: {
    carrier: VALUE,
    fields: {x: :float, y: :float, pointer: :symbol, finger: :float, modifiers: :any}
  },
  scroll: {
    carrier: VALUE,
    fields: {
      x: :float, y: :float, delta_x: :float, delta_y: :float,
      pointer: :symbol, modifiers: :any
    }
  },
  # steep:ignore:start
  enter: {carrier: VALUE, fields: {x: :float, y: :float}, required: []},
  exit: {carrier: VALUE, fields: {x: :float, y: :float}, required: []},
  # steep:ignore:end
  double_click: {
    carrier: VALUE,
    fields: {x: :float, y: :float, pointer: :symbol, modifiers: :any}
  },
  resize: {carrier: VALUE, fields: {width: :float, height: :float}},

  # Pane grid events
  pane_resized: {carrier: VALUE, fields: {split: :any, ratio: :float}},
  pane_dragged: {
    carrier: VALUE,
    fields: {pane: :any, target: :any, action: :any, region: :any, edge: :any}
  },
  pane_clicked: {carrier: VALUE, fields: {pane: :any}},
  pane_focus_cycle: {carrier: VALUE, fields: {pane: :any}},

  # Animation events
  transition_complete: {carrier: VALUE, fields: {tag: :any, prop: :string}}
}.each_value { |spec|
  spec.each_value(&:freeze)
  spec.freeze
}.freeze

Class Method Summary collapse

Class Method Details

.allHash{Symbol => Hash}

All built-in event specs.

Returns:

  • (Hash{Symbol => Hash})


173
174
175
# File 'lib/plushie/event/specs.rb', line 173

def self.all
  BUILTIN
end

.builtin?(type) ⇒ Boolean

Check if a type is a recognized built-in event.

Parameters:

  • type (Symbol)

Returns:

  • (Boolean)


181
182
183
# File 'lib/plushie/event/specs.rb', line 181

def self.builtin?(type)
  BUILTIN.key?(type)
end

.fields(type) ⇒ Array<Symbol>?

Return the declared field names for a structured event type. Returns nil for scalar or no-payload events.

Parameters:

  • type (Symbol)

Returns:

  • (Array<Symbol>, nil)


190
191
192
193
194
195
# File 'lib/plushie/event/specs.rb', line 190

def self.fields(type)
  spec = BUILTIN[type]
  return nil unless spec
  fields = spec[:fields]
  fields&.keys
end

.for(type) ⇒ Hash?

Look up the spec for a built-in event type.

Parameters:

  • type (Symbol)

    event type name

Returns:

  • (Hash, nil)

    the spec, or nil if not a built-in type



166
167
168
# File 'lib/plushie/event/specs.rb', line 166

def self.for(type)
  BUILTIN[type]
end

.required_fields(type) ⇒ Array<Symbol>?

Return the required fields for a structured event type. Defaults to all declared fields when :required is not specified.

Parameters:

  • type (Symbol)

Returns:

  • (Array<Symbol>, nil)


202
203
204
205
206
207
208
# File 'lib/plushie/event/specs.rb', line 202

def self.required_fields(type)
  spec = BUILTIN[type]
  return nil unless spec
  fields = spec[:fields]
  return nil unless fields
  spec[:required] || fields.keys
end