module Canis::KeyDispatcher

a generic key dispatcher that can be used in various classes for handling keys, setting key_map and processing keys.

Public Instance Methods

bind_key(keycode, descr, &block) click to toggle source

convenience method to bind a key or array /range of keys, or regex to a block @param [int, String, include?, Regexp] keycode If the user presses this key, then execute given block @param [String, Action] descr is either a textual description of the key

or an Action object

@param [block] unless an Action object has been passed, a block is passed for execution

@example

bind_key '%', 'Do something' {|obj, ch| actions ... }
bind_key [?\C-h.getbyte(0), 127], 'Delete something' {|obj, ch| actions ... }
bind_key Regexp.new('[a-zA-Z_\.]'), 'Append char' {|obj, ch| actions ... }

TODO test this

# File lib/canis/core/util/rcommandwindow.rb, line 526
def bind_key keycode, descr, &block
  if descr.is_a? Action
    @key_map[keycode] = descr
 else
   @key_map[keycode] = Action.new(descr), block
 end
end
default_string_key_map() click to toggle source

setting up some keys This is currently an insertion key map, if you want a String named +@buffer+ updated. Expects buffer_changed and set_buffer to exist as well as +buffer()+. TODO add left and right arrow keys for changing insertion point. And other keys. XXX Why are we trying to duplicate a Field here ??

# File lib/canis/core/util/rcommandwindow.rb, line 500
def default_string_key_map
  require 'canis/core/include/action'
  @key_map ||= {}
  @key_map[ Regexp.new('[a-zA-Z0-9_\.\/]') ] = Action.new("Append to pattern") { |obj, ch|
    obj.buffer << ch.chr
    obj.buffer_changed
  }
  @key_map[ [127, ?\C-h.getbyte(0)] ] = Action.new("Delete Prev Char") { |obj, ch|
    # backspace
    buff = obj.buffer
    buff = buff[0..-2] unless buff == ""
    obj.set_buffer buff
  }
end
handle_key(ch) click to toggle source

key handler of Controlphandler This sets +@keyint+ with the value read by window. This sets +@keychr+ with the chr value of ch if ch between 32 and 127 exclusive. @param [Integer] ch is key read by window.

# File lib/canis/core/util/rcommandwindow.rb, line 441
def handle_key ch
  $log.debug "  KeyDispatcher GOT KEY #{ch} "
  @keyint = ch
  @keychr = nil
  chr = nil
  chr = ch.chr if ch > 32 and ch < 127
  @keychr = chr

  ret = process_key ch
  # revert to the basic handling of key_map and refreshing pad.
  #####
  # NOTE
  # this is being done where we are creating some kind of front for a textpad by using +view+
  # so we steal some keys, and pass the rest to +view+. Otherwise, next line is not needed.
  # +@source+ typically would be handle to textpad yielded by +view+.
  #####
  @source._handle_key(ch) if ret == :UNHANDLED and @source
end
process_key(ch) click to toggle source

checks the key against +@key_map+ if its set @param [Integer] ch character read by Window @return [0, :UNHANDLED] 0 if processed, :UNHANDLED if not processed so higher level can process

# File lib/canis/core/util/rcommandwindow.rb, line 463
def process_key ch
  chr = nil
  if ch > 0 and ch < 256
    chr = ch.chr
  end
  return :UNHANDLED unless @key_map
  @key_map.each_pair do |k,p|
    #$log.debug "KKK:  processing key #{ch}  #{chr} "
    if (k == ch || k == chr)
      #$log.debug "KKK:  checking match == #{k}: #{ch}  #{chr} "
      # compare both int key and chr
      #$log.debug "KKK:  found match 1 #{ch}  #{chr} "
      p.call(self, ch)
      return 0
    elsif k.respond_to? :include?
        #$log.debug "KKK:  checking match include #{k}: #{ch}  #{chr} "
        # this bombs if its a String and we check for include of a ch.
      if !k.is_a?( String ) && (k.include?( ch ) || k.include?(chr))
        #$log.debug "KKK:  found match include #{ch}  #{chr} "
        p.call(self, ch)
        return 0
      end
    elsif k.is_a? Regexp
      if k.match(chr)
        #$log.debug "KKK:  found match regex #{ch}  #{chr} "
        p.call(self, ch)
        return 0
      end
    end
  end
  return :UNHANDLED
end