Class: Tuile::MouseEvent

Inherits:
Object
  • Object
show all
Defined in:
lib/tuile/mouse_event.rb

Overview

A mouse event.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#buttonSymbol? (readonly)

Returns one of ‘:left`, `:middle`, `:right`, `:scroll_up`, `:scroll_down`, `:scroll_left`, `:scroll_right`; `nil` if not known.

Returns:

  • (Symbol, nil)

    one of ‘:left`, `:middle`, `:right`, `:scroll_up`, `:scroll_down`, `:scroll_left`, `:scroll_right`; `nil` if not known.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/tuile/mouse_event.rb', line 13

class MouseEvent < Data.define(:button, :x, :y)
  # @return [Point] the event's position.
  def point = Point.new(x, y)

  # Checks whether given key is a mouse event key. Returns true on the X10
  # `\e[M` prefix regardless of length — {.parse} is the place that
  # validates the full 6-byte shape and raises on malformed input.
  # @param key [String] key read via {Keys.getkey}
  # @return [Boolean] true if it is a mouse event
  def self.mouse_event?(key)
    key.start_with?("\e[M")
  end

  # Parses an X10 mouse report (`\e[M` + 3 bytes: button, x, y).
  #
  # Raises {Tuile::Error} when `key` starts with the mouse prefix but is
  # not exactly 6 bytes long. Both shorter and longer inputs are bugs in
  # the upstream key-reader: a shorter prefix means the tail was lost on
  # the way in, and a longer one means we over-consumed into the next
  # escape sequence. We refuse to silently truncate either case because
  # the trailing `\e` of an over-read corrupts the *next* getkey, and the
  # corruption then surfaces as garbled keystrokes in focused inputs
  # rather than as a parser failure pointing at the actual cause.
  # @param key [String] key read via {Keys.getkey}
  # @return [MouseEvent, nil] `nil` if `key` is not a mouse event
  # @raise [Tuile::Error] if `key` is a malformed mouse event
  def self.parse(key)
    return nil unless mouse_event?(key)
    unless key.bytesize == 6
      raise Tuile::Error,
            "malformed mouse event: expected 6 bytes after \\e[M prefix, got #{key.bytesize}: #{key.inspect}"
    end

    button = key[3].ord - 32
    # XTerm reports coordinates 1-based (column N is encoded as N + 32);
    # subtract 33 so that `x` and `y` are 0-based.
    x = key[4].ord - 33
    y = key[5].ord - 33
    button = case button
             when 0 then :left
             when 2 then :right
             when 1 then :middle
             when 64 then :scroll_up
             when 65 then :scroll_down
             when 66 then :scroll_left
             when 67 then :scroll_right
             end
    MouseEvent.new(button, x, y)
  end

  # @return [String]
  def self.start_tracking = "\e[?1000h"
  # @return [String]
  def self.stop_tracking = "\e[?1000l"
end

#xInteger (readonly)

Returns x coordinate, 0-based.

Returns:

  • (Integer)

    x coordinate, 0-based.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/tuile/mouse_event.rb', line 13

class MouseEvent < Data.define(:button, :x, :y)
  # @return [Point] the event's position.
  def point = Point.new(x, y)

  # Checks whether given key is a mouse event key. Returns true on the X10
  # `\e[M` prefix regardless of length — {.parse} is the place that
  # validates the full 6-byte shape and raises on malformed input.
  # @param key [String] key read via {Keys.getkey}
  # @return [Boolean] true if it is a mouse event
  def self.mouse_event?(key)
    key.start_with?("\e[M")
  end

  # Parses an X10 mouse report (`\e[M` + 3 bytes: button, x, y).
  #
  # Raises {Tuile::Error} when `key` starts with the mouse prefix but is
  # not exactly 6 bytes long. Both shorter and longer inputs are bugs in
  # the upstream key-reader: a shorter prefix means the tail was lost on
  # the way in, and a longer one means we over-consumed into the next
  # escape sequence. We refuse to silently truncate either case because
  # the trailing `\e` of an over-read corrupts the *next* getkey, and the
  # corruption then surfaces as garbled keystrokes in focused inputs
  # rather than as a parser failure pointing at the actual cause.
  # @param key [String] key read via {Keys.getkey}
  # @return [MouseEvent, nil] `nil` if `key` is not a mouse event
  # @raise [Tuile::Error] if `key` is a malformed mouse event
  def self.parse(key)
    return nil unless mouse_event?(key)
    unless key.bytesize == 6
      raise Tuile::Error,
            "malformed mouse event: expected 6 bytes after \\e[M prefix, got #{key.bytesize}: #{key.inspect}"
    end

    button = key[3].ord - 32
    # XTerm reports coordinates 1-based (column N is encoded as N + 32);
    # subtract 33 so that `x` and `y` are 0-based.
    x = key[4].ord - 33
    y = key[5].ord - 33
    button = case button
             when 0 then :left
             when 2 then :right
             when 1 then :middle
             when 64 then :scroll_up
             when 65 then :scroll_down
             when 66 then :scroll_left
             when 67 then :scroll_right
             end
    MouseEvent.new(button, x, y)
  end

  # @return [String]
  def self.start_tracking = "\e[?1000h"
  # @return [String]
  def self.stop_tracking = "\e[?1000l"
end

#yInteger (readonly)

Returns y coordinate, 0-based.

Returns:

  • (Integer)

    y coordinate, 0-based.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/tuile/mouse_event.rb', line 13

class MouseEvent < Data.define(:button, :x, :y)
  # @return [Point] the event's position.
  def point = Point.new(x, y)

  # Checks whether given key is a mouse event key. Returns true on the X10
  # `\e[M` prefix regardless of length — {.parse} is the place that
  # validates the full 6-byte shape and raises on malformed input.
  # @param key [String] key read via {Keys.getkey}
  # @return [Boolean] true if it is a mouse event
  def self.mouse_event?(key)
    key.start_with?("\e[M")
  end

  # Parses an X10 mouse report (`\e[M` + 3 bytes: button, x, y).
  #
  # Raises {Tuile::Error} when `key` starts with the mouse prefix but is
  # not exactly 6 bytes long. Both shorter and longer inputs are bugs in
  # the upstream key-reader: a shorter prefix means the tail was lost on
  # the way in, and a longer one means we over-consumed into the next
  # escape sequence. We refuse to silently truncate either case because
  # the trailing `\e` of an over-read corrupts the *next* getkey, and the
  # corruption then surfaces as garbled keystrokes in focused inputs
  # rather than as a parser failure pointing at the actual cause.
  # @param key [String] key read via {Keys.getkey}
  # @return [MouseEvent, nil] `nil` if `key` is not a mouse event
  # @raise [Tuile::Error] if `key` is a malformed mouse event
  def self.parse(key)
    return nil unless mouse_event?(key)
    unless key.bytesize == 6
      raise Tuile::Error,
            "malformed mouse event: expected 6 bytes after \\e[M prefix, got #{key.bytesize}: #{key.inspect}"
    end

    button = key[3].ord - 32
    # XTerm reports coordinates 1-based (column N is encoded as N + 32);
    # subtract 33 so that `x` and `y` are 0-based.
    x = key[4].ord - 33
    y = key[5].ord - 33
    button = case button
             when 0 then :left
             when 2 then :right
             when 1 then :middle
             when 64 then :scroll_up
             when 65 then :scroll_down
             when 66 then :scroll_left
             when 67 then :scroll_right
             end
    MouseEvent.new(button, x, y)
  end

  # @return [String]
  def self.start_tracking = "\e[?1000h"
  # @return [String]
  def self.stop_tracking = "\e[?1000l"
end

Class Method Details

.mouse_event?(key) ⇒ Boolean

Checks whether given key is a mouse event key. Returns true on the X10 ‘e[M` prefix regardless of length — parse is the place that validates the full 6-byte shape and raises on malformed input.

Parameters:

Returns:

  • (Boolean)

    true if it is a mouse event



22
23
24
# File 'lib/tuile/mouse_event.rb', line 22

def self.mouse_event?(key)
  key.start_with?("\e[M")
end

.parse(key) ⇒ MouseEvent?

Parses an X10 mouse report (‘e[M` + 3 bytes: button, x, y).

Raises Error when ‘key` starts with the mouse prefix but is not exactly 6 bytes long. Both shorter and longer inputs are bugs in the upstream key-reader: a shorter prefix means the tail was lost on the way in, and a longer one means we over-consumed into the next escape sequence. We refuse to silently truncate either case because the trailing `e` of an over-read corrupts the next getkey, and the corruption then surfaces as garbled keystrokes in focused inputs rather than as a parser failure pointing at the actual cause.

Parameters:

Returns:

  • (MouseEvent, nil)

    ‘nil` if `key` is not a mouse event

Raises:



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tuile/mouse_event.rb', line 39

def self.parse(key)
  return nil unless mouse_event?(key)
  unless key.bytesize == 6
    raise Tuile::Error,
          "malformed mouse event: expected 6 bytes after \\e[M prefix, got #{key.bytesize}: #{key.inspect}"
  end

  button = key[3].ord - 32
  # XTerm reports coordinates 1-based (column N is encoded as N + 32);
  # subtract 33 so that `x` and `y` are 0-based.
  x = key[4].ord - 33
  y = key[5].ord - 33
  button = case button
           when 0 then :left
           when 2 then :right
           when 1 then :middle
           when 64 then :scroll_up
           when 65 then :scroll_down
           when 66 then :scroll_left
           when 67 then :scroll_right
           end
  MouseEvent.new(button, x, y)
end

.start_trackingString

Returns:

  • (String)


64
65
# File 'lib/tuile/mouse_event.rb', line 64

def self.start_tracking = "\e[?1000h"
# @return [String]

.stop_trackingString

Returns:

  • (String)


66
# File 'lib/tuile/mouse_event.rb', line 66

def self.stop_tracking = "\e[?1000l"

Instance Method Details

#pointPoint

Returns the event’s position.

Returns:

  • (Point)

    the event’s position.



15
# File 'lib/tuile/mouse_event.rb', line 15

def point = Point.new(x, y)