Module: Canis::KeyDispatcher

Included in:
ControlPHandler
Defined in:
lib/canis/core/util/rcommandwindow.rb

Overview

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

Instance Method Summary collapse

Instance Method Details

#bind_key(keycode, descr, &block) ⇒ Object

convenience method to bind a key or array /range of keys, or regex to a block TODO test this

Examples:

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 ... }

Parameters:

  • keycode (int, String, #include?, Regexp)

    If the user presses this key, then execute given block

  • descr (String, Action)

    is either a textual description of the key or an Action object

  • unless (block)

    an Action object has been passed, a block is passed for execution



522
523
524
525
526
527
528
# File 'lib/canis/core/util/rcommandwindow.rb', line 522

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_mapObject

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 ??



496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/canis/core/util/rcommandwindow.rb', line 496

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) ⇒ Object

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.

Parameters:

  • ch (Fixnum)

    is key read by window.



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/canis/core/util/rcommandwindow.rb', line 437

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) ⇒ 0, :UNHANDLED

checks the key against @key_map if its set

Parameters:

  • ch (Fixnum)

    character read by Window

Returns:

  • (0, :UNHANDLED)

    0 if processed, :UNHANDLED if not processed so higher level can process



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/canis/core/util/rcommandwindow.rb', line 459

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