module RETerm::NavInput

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.

Attributes

ch_select[RW]

Used internally to specify which movement command we should follow

nav_select[RW]

Used internally to specify component which we should navigate to

Public Instance Methods

focusable() click to toggle source

Return children which are focusabled/activable

# File lib/reterm/mixins/nav_input.rb, line 20
def focusable
  children.select { |c| c.activatable? }
end
focusable?() click to toggle source

Return boolean indicating if any children are focusable

# File lib/reterm/mixins/nav_input.rb, line 25
def focusable?
  !focusable.empty?
end
handle_input(from_parent=false) click to toggle source

Helper to be internally invoked by navigation component on activation

# File lib/reterm/mixins/nav_input.rb, line 37
def handle_input(from_parent=false)
  @focus ||= 0

  # focus on first component
  ch = handle_focused unless nav_select

  # Repeat until quit
  until quit_nav?(ch)

    # Navigate to the specified component (nav_select)
    if self.nav_select 
      # it is a descendent of this one
      if self.contains?(self.nav_select)
        nav_to_selected

      # specified component is not a descendent,
      else
        nav_to_parent
        return nil
      end

    elsif ENTER_CONTROLS.include?(ch)
      focused.activate!

    elsif MOVEMENT_CONTROLS.include?(ch)
      handle_movement(ch, from_parent)

    elsif mev = process_mouse(ch)
      handle_mouse(mev)

    else
      dispatch(:entry, ch)

    end

    return ch unless sanitize_focus!(from_parent)
    ch = handle_focused unless nav_select ||
                               shutdown?  ||
                               deactivate?
  end

  ch
end
valid_input?(ch, from_parent) click to toggle source

May be overridden by subclass to indicate if the specified input / context is valid

# File lib/reterm/mixins/nav_input.rb, line 31
def valid_input?(ch, from_parent)
  true
end

Private Instance Methods

draw_focus!() click to toggle source
# File lib/reterm/mixins/nav_input.rb, line 106
def draw_focus!
  focused.window.border! if !!focused && focused.highlight_focus?
end
focused() click to toggle source
# File lib/reterm/mixins/nav_input.rb, line 101
def focused
  return nil unless !!@focus
  focusable[@focus]
end
handle_focused() click to toggle source

Internal helper, logic invoked when a component gains focus

# File lib/reterm/mixins/nav_input.rb, line 118
def handle_focused
  ch = nil

  focused.dispatch :focused
  update_focus

  if focused.activate_focus?
    focused.activate!

  elsif focused.kind_of?(Layout)
    ch = focused.handle_input(true)

  elsif !deactivate? && !nav_select
    ch = sync_getch
  end

  if self.ch_select
    ch = self.ch_select
    self.ch_select = nil
  end

  ch
end
handle_mouse(mev) click to toggle source
# File lib/reterm/mixins/nav_input.rb, line 199
def handle_mouse(mev)
  child = window.root.child_containing(mev.x, mev.y, mev.z)

  if child
    child = child.component

    if child.activatable?
      if self.contains?(child)
        nav_to_selected

      else
        self.nav_select = child
        nav_to_parent
        return nil
      end
    end
  end
end
handle_movement(ch, from_parent) click to toggle source
# File lib/reterm/mixins/nav_input.rb, line 84
def handle_movement(ch, from_parent)
  remove_focus
  return ch unless valid_input?(ch, from_parent)
  @focus = next_focus(ch)
end
nav_to_parent() click to toggle source

Internal helper, navigate to selected component up heirarchy

nav_to_selected() click to toggle source

Internal helper, navigate to selected component under current

next_focus(ch) click to toggle source
# File lib/reterm/mixins/nav_input.rb, line 90
def next_focus(ch)
  if UP_CONTROLS.include?(ch) ||
     LEFT_CONTROLS.include?(ch)
    @focus - 1

  elsif DOWN_CONTROLS.include?(ch) ||
        RIGHT_CONTROLS.include?(ch)
    @focus + 1
  end
end
remove_focus() click to toggle source

Internal helper, logic invoked when a component loses focus

# File lib/reterm/mixins/nav_input.rb, line 143
def remove_focus
  focused.window.no_border!
  focused.dispatch :unfocused
end
sanitize_focus!(from_parent) click to toggle source

Internal helper, sanitize the focus tracker. Return value indicates if sanity is preseved in the context of this component (else we will return to parent)

# File lib/reterm/mixins/nav_input.rb, line 186
def sanitize_focus!(from_parent)
  if @focus >= focusable.size
    @focus = focusable.size - 1
    return false if from_parent

  elsif @focus < 0
    @focus = 0
    return false if from_parent
  end

  true
end
update_focus() click to toggle source

Internal help, set the visual properties of the focused window

# File lib/reterm/mixins/nav_input.rb, line 111
def update_focus
  draw_focus!
  update_reterm
  window.root.draw!
end