Module: RETerm::NavInput

Included in:
Layout
Defined in:
lib/reterm/mixins/nav_input.rb

Overview

Helper mixin defining standard navigation controls. Used by layouts and top level components this tightly defines keyboard navigation and allows the user to seemlessly move between and activate/decativate components.

Constant Summary collapse

QUIT_CONTROLS =

Key which if pressed causes the navigation component to lose focus / become deactivated

[27, 'q'.ord, 'Q'.ord]
ENTER_CONTROLS =

Key if pressed focuses on / activates a component

[10]
UP_CONTROLS =

Up navigation keys

['k'.ord, 'K'.ord, Ncurses::KEY_UP]
DOWN_CONTROLS =

Down navigation keys

['j'.ord, 'J'.ord, Ncurses::KEY_DOWN]
LEFT_CONTROLS =

Left navigation keys

['h'.ord, 'H'.ord, Ncurses::KEY_BACKSPACE,
Ncurses::KEY_BTAB,
Ncurses::KEY_LEFT]
RIGHT_CONTROLS =

Right navigation keys

['l'.ord, 'L'.ord, "\t".ord, Ncurses::KEY_RIGHT]

Instance Method Summary collapse

Instance Method Details

#focusableObject

Return children which are focusabled/activable



30
31
32
# File 'lib/reterm/mixins/nav_input.rb', line 30

def focusable
  children.select { |c| c.component.activatable? }
end

#focusable?Boolean

Return boolean indicating if any children are focusable

Returns:

  • (Boolean)


35
36
37
# File 'lib/reterm/mixins/nav_input.rb', line 35

def focusable?
  !focusable.empty?
end

#handle_input(from_parent = false) ⇒ Object

Helper to be internally invoked by navigation component on activation



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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/reterm/mixins/nav_input.rb', line 41

def handle_input(from_parent=false)
  @focus ||= 0

  ch = handle_focused

  while(!QUIT_CONTROLS.include?(ch))
    if ENTER_CONTROLS.include?(ch)
      focused.activate!

    elsif UP_CONTROLS.include?(ch)
      focused.no_border!

      return ch if window.component.is_a?(Layouts::Horizontal) &&
                   from_parent &&
                   !window.parent.children.index(window) != 0

      @focus -= 1

    elsif LEFT_CONTROLS.include?(ch)
      focused.no_border!

      return ch if window.component.is_a?(Layouts::Vertical) &&
                   from_parent &&
                   !window.parent.children.index(window) != 0

      @focus -= 1

    elsif DOWN_CONTROLS.include?(ch)
      focused.no_border!

      return ch if window.component.is_a?(Layouts::Horizontal) &&
                   from_parent &&
                   !window.parent.children.index(window) != (window.parent.children.size - 1)

      @focus += 1

    elsif RIGHT_CONTROLS.include?(ch)
      focused.no_border!

      return ch if window.component.is_a?(Layouts::Vertical) &&
                   from_parent &&
                   !window.parent.children.index(window) != (window.parent.children.size - 1)

      @focus += 1
    end

    if @focus >= focusable.size
      @focus = focusable.size - 1
      return ch if from_parent
    end

    if @focus < 0
      @focus = 0
      return ch if from_parent
    end

    ch = handle_focused
  end

  ch
end