O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

MBS - Keyboard Input

Iniciado por Brandt, 23/01/2015 às 11:03

23/01/2015 às 11:03 Última edição: 22/02/2015 às 16:26 por Masked
[box2 class=titlebg]
MBS - Keyboard Input
[/box2]

[button class=titlebg]por Masked[/button]


[box2 class=titlebg title=Características]O script cria um módulo que verifica se as teclas do teclado estão pressionadas ou não, como um módulo Input, porém mais avançado.
Já existem scripts do gênero, porém esse script em especial tem algumas funções extras, como obter o caractere da tecla pressionada, verificar qual tecla está sendo pressionada e aceitar acentos nos caracteres das teclas.
O principal objetivo do script é permitir a digitação pelo teclado de forma simples de usar.[/box2]

[box2 class=titlebg title=Instruções]No script[/box2]

[box2 class=titlebg title=Script]
#==============================================================================
# MBS - Keyboard Input
#------------------------------------------------------------------------------
# por Masked
#==============================================================================
#==============================================================================
# Instruções
#------------------------------------------------------------------------------
# Para verificar se uma tecla foi pressionada, use os métodos trigger?, repeat?
# e press? do módulo Input, como padrão, usando símbolos (:TECLA), o caractere
# da tecla (a mesma tecla é considerada para maiúsculas e minúsculas) ou o 
# número dela, caso use símbolos, é recomendável usar os métodos de mesmo nome
# do módulo Keyboard
#
# Para obter o código da tecla que está sendo pressionada:
# Keyboard.pressed([modo])
#
# Sendo 'modo' 0 (.press?, se nenhum modo for escolhido esse é utilizado), 
# 1 (.repeat?) ou 2 (.trigger?), E.x:
# Keyboard.pressed(1)
#
# Para obter o caractere da tecla pressionada:
# Keyboard.char([modo])
# O modo comporta-se como no método .pressed
#
# Para obter o caractere da tecla pressionada com acentos:
# Keyboard.utf8([modo])
# Idem .pressed e .char
#==============================================================================
#==============================================================================
# Alterações
#------------------------------------------------------------------------------
# Keyboard
# ├── press?   [novo]
# ├── repeat?  [novo]
# ├── trigger? [novo]
# ├── shift?   [novo]
# ├── key      [novo]
# ├── lowcase  [novo]
# ├── upcase   [novo]
# ├── code     [novo]
# ├── pressed  [novo]
# ├── char     [novo]
# └── utf8     [novo]
#
# Input
# ├── press?
# ├── repeat?
# └── trigger?
#==============================================================================
($imported ||= {})[:mbs_keyboard_input] = true
#==============================================================================
# >> Keyboard
#==============================================================================
module Keyboard
  extend self
#==============================================================================
# Contantes
#==============================================================================
  #----------------------------------------------------------------------------
  # Definição dos códigos das teclas
  #----------------------------------------------------------------------------
  KEYS = {
  
    #-------------------------------------------------------------------------
    # Teclas especiais
    #-------------------------------------------------------------------------
    BACKSPACE: 0x08, TAB:     0x09, ENTER:  0x0D, SHIFT: 0x10, CAPS:    0x14,  
    ESC:       0x1B, SPACE:   0x20, DELETE: 0x2E, CTRL:  0x11, ALT:     0x12,
    END:       0x23, INSERT:  0x2D, PGDN:   0x22, PGUP:  0x21, MOUSE_L: 0x01,
    MOUSE_R:   0x02, MOUSE_M: 0x04, PAUSE:  0x13,
    
    #-------------------------------------------------------------------------
    # Números
    #-------------------------------------------------------------------------
    K0: 0x30, K1: 0x31, K2: 0x32, K3: 0x33, K4: 0x34, K5: 0x35, K6: 0x36, 
    K7: 0x37, K8: 0x38, K9: 0x39,
    
    #-------------------------------------------------------------------------
    # Números (numpad)
    #-------------------------------------------------------------------------
    N0: 0x60, N1: 0x61, N2: 0x62, N3: 0x63, N4: 0x64, N5: 0x65, N6: 0x66, 
    N7: 0x67, N8: 0x68, N9: 0x69,
    
    #-------------------------------------------------------------------------
    # Letras
    #-------------------------------------------------------------------------
    A: 0x41, B: 0x42, C: 0x43, D: 0x44, E: 0x45, F: 0x46, G: 0x47, H: 0x48, 
    I: 0x49, J: 0x4A, K: 0x4B, L: 0x4C, M: 0x4D, N: 0x4E, O: 0x4F, P: 0x50, 
    Q: 0x51, R: 0x52, S: 0x53, T: 0x54, U: 0x55, V: 0x56, W: 0x57, X: 0x58, 
    Y: 0x59, Z: 0x5A, Ç: 0xBA,
    
    #-------------------------------------------------------------------------
    # Símbolos
    #-------------------------------------------------------------------------
    MULTIPLY: 0x6A, ADD:      0x6B, SEPARATOR: 0x6C, SUBTRACT: 0x6D, 
    DECIMAL:  0x6E, DIVIDE:   0x6F, PLUS:      0xBB, COMMA:    0xBC, 
    MINUS:    0xBD, DOT:      0xBE, COLON:     0xBF, LASH:     0xC1,
    ACCUTE:   0xDB, QUOTE:    0xC0, BRACKET:   0xDD, BRACKET2: 0xDC,
    BACKLASH: 0xE2, TIL:      0xDE,
    
    #-------------------------------------------------------------------------
    # F1-F24
    #-------------------------------------------------------------------------
    F1:  0x70, F2:  0x71, F3:  0x72, F4:  0x73, F5:  0x74, F6:  0x75, 
    F7:  0x76, F8:  0x77, F9:  0x78, F10: 0x79, F11: 0x7A, F12: 0x7B, 
    F13: 0x7C, F14: 0x7D, F15: 0x7E, F16: 0x7F, F17: 0x80, F18: 0x81, 
    F19: 0x82, F20: 0x83, F21: 0x84, F22: 0x85, F23: 0x86, F24: 0x87,
  }
  
  #----------------------------------------------------------------------------
  # Representação dos caracteres minúsculos das teclas
  #----------------------------------------------------------------------------
  LOWCASE = {
  
    #-------------------------------------------------------------------------
    # Teclas especiais
    #-------------------------------------------------------------------------
    BACKSPACE: "\b", TAB: "\t", ENTER: "\n", SPACE: ' ',
    
    #-------------------------------------------------------------------------
    # Números
    #-------------------------------------------------------------------------
    K0: '0', K1: '1', K2: '2', K3: '3', K4: '4', K5: '5', K6: '6', 
    K7: '7', K8: '8', K9: '9',
    
    #-------------------------------------------------------------------------
    # Números (numpad)
    #-------------------------------------------------------------------------
    N0: '0', N1: '1', N2: '2', N3: '3', N4: '4', N5: '5', N6: '6', 
    N7: '7', N8: '8', N9: '9',
    
    #-------------------------------------------------------------------------
    # Letras
    #-------------------------------------------------------------------------
    A: 'a', B: 'b', C: 'c', D: 'd', E: 'e', F: 'f', G: 'g', H: 'h', 
    I: 'i', J: 'j', K: 'k', L: 'l', M: 'm', N: 'n', O: 'o', P: 'p', 
    Q: 'q', R: 'r', S: 's', T: 't', U: 'u', V: 'v', W: 'w', X: 'x', 
    Y: 'y', Z: 'z', Ç: 'ç',
    
    #-------------------------------------------------------------------------
    # Símbolos
    #-------------------------------------------------------------------------
    MULTIPLY: '*',  ADD:      '+', SEPARATOR: '.', SUBTRACT: '-', 
    DECIMAL:  ',',  DIVIDE:   '/', PLUS:      '=', COMMA:    ',', 
    MINUS:    '-',  DOT:      '.', COLON:     ';', LASH:     '/',
    ACCUTE:   '´',  QUOTE:    "'", BRACKET:   '[', BRACKET2: ']',
    BACKLASH: '\\', TIL:      '~',
  }
  
  #----------------------------------------------------------------------------
  # Representação dos caracteres maiúsculos das teclas
  #----------------------------------------------------------------------------
  UPCASE = {
  
    #-------------------------------------------------------------------------
    # Teclas especiais
    #-------------------------------------------------------------------------
    BACKSPACE: "\b", TAB: "\t", ENTER: "\n", SPACE: ' ',
    
    #-------------------------------------------------------------------------
    # Números
    #-------------------------------------------------------------------------
    K0: ')', K1: '!', K2: '@', K3: '#', K4: '$', K5: '%', K6: '¨', 
    K7: '&', K8: '*', K9: '(',
    
    #-------------------------------------------------------------------------
    # Números (numpad)
    #-------------------------------------------------------------------------
    N0: '0', N1: '1', N2: '2', N3: '3', N4: '4', N5: '5', N6: '6', 
    N7: '7', N8: '8', N9: '9',
    
    #-------------------------------------------------------------------------
    # Letras
    #-------------------------------------------------------------------------
    A: 'A', B: 'B', C: 'C', D: 'D', E: 'E', F: 'F', G: 'G', H: 'H', 
    I: 'I', J: 'J', K: 'K', L: 'L', M: 'M', N: 'N', O: 'O', P: 'P', 
    Q: 'Q', R: 'R', S: 'S', T: 'T', U: 'U', V: 'V', W: 'W', X: 'X', 
    Y: 'Y', Z: 'Z', Ç: 'Ç',
    
    # Símbolos
    #-------------------------------------------------------------------------
    MULTIPLY: '*', ADD:      '+', SEPARATOR: '.', SUBTRACT: '-', 
    DECIMAL:  ',', DIVIDE:   '/', PLUS:      '+', COMMA:    '<', 
    MINUS:    '_', DOT:      '>', COLON:     ':', LASH:     '?',
    ACCUTE:   '`', QUOTE:    '"', BRACKET:   '{', BRACKET2: '}',
    BACKLASH: '|', TIL:      '^',
  }
  
  #----------------------------------------------------------------------------
  # Acentos
  #----------------------------------------------------------------------------
  
  # Lista de caracteres considerados acentos
  ACCENTS = %w(´ ~ ^ ` ¨)
  
  # Lista de caracteres acentuáveis
  ACCENTABLE = %w(a A e E i I o O u U y Y)
  
  # Lista de caracteres acentuados
  ACCENTED = {
    'a' => %w(á ã â à ä),    'A' => %w(Á Ã Ã À Ä),
    'e' => %w(é ~e ê è ë),   'E' => %w(É ~E Ê È Ë),
    'i' => %w(í ~i î ì ï),   'I' => %w(Í ~I Î Ì Ï),
    'o' => %w(ó õ ô ò ö),    'O' => %w(Ó Õ Ô Ò Ö),
    'u' => %w(ú ~u û ù ü),   'U' => %w(Ú ~U Û Ù Ü),
    'y' => %w(ý ~y ^y `y ÿ), 'Y' => %w(Ý ~Y ^Y `Y ¨Y),
  }
  
#==============================================================================
# Métodos
#==============================================================================
  
  GetAsyncKeyState = Win32API.new('User32', 'GetAsyncKeyState', 'i', 'i')
  @trigger = []
  @counter = []
  @accent  = ''
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def press?(key)
    GetAsyncKeyState.call(code(key)) != 0
  end
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def repeat?(key)
    unless GetAsyncKeyState.call(code(key)) == 0
      @trigger << key unless @trigger.include?(code(key)) 
      index = @trigger.index(code(key))
      @counter[index] = 0 unless @counter[index]
      @counter[index] += 1
      return true if @counter[index] == 1
      return (@counter[index] >= 30 && @counter[index] % 4 == 1)
    else
      index = @trigger.index(code(key)) if @trigger.include?(code(key))
      @counter[index] = nil if index
    end
  end
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def trigger?(key)
    unless GetAsyncKeyState.call(code(key)) == 0
      @trigger.include?(code(key)) ? (return false) : @trigger << code(key)
      return true
    else
      @trigger.delete(code(key)) if @trigger.include?(code(key))
      return false
    end
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição do código de uma chave
  #----------------------------------------------------------------------------
  def code(key)
    if key.is_a?(Symbol)
      return KEYS[key]
    elsif key.is_a?(String)
      keys = LOWCASE.keys + UPCASE.keys
      values = LOWCASE.values + UPCASE.values
      return code(keys[values.index(key)])
    elsif key.is_a?(Integer)
      return key
    else
      raise ArgumentError.new
    end
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição da chave de um código
  #----------------------------------------------------------------------------
  def key(code)
    KEYS.keys[KEYS.values.index code]
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição da representação da tecla maiúscula
  #----------------------------------------------------------------------------
  def upcase(key)
    UPCASE[KEYS.keys[KEYS.values.index code(key)]] || ''
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição da representação da tecla minúscula
  #----------------------------------------------------------------------------
  def lowcase(key)
    LOWCASE[KEYS.keys[KEYS.values.index code(key)]] || ''
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição de se a tecla shift está apertada
  #----------------------------------------------------------------------------
  def shift?
    press?(0x10) || press?(0x14)
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição do código da tecla pressionada
  #----------------------------------------------------------------------------
  def pressed(mode=0)
    k = nil
    KEYS.each_value do |v|
      b = false
      case mode
        when 0
          b = press?(v)
        when 1
          b = repeat?(v)
        else
          b = trigger?(v)
      end
      k = v if b
    end
    k
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição do texto da tecla pressionada
  #----------------------------------------------------------------------------
  def char(mode=0)
    key = pressed(mode)
    return '' unless key
    c = (shift? ? upcase(key) : lowcase(key)) || ''
    return c
  end
  
  #----------------------------------------------------------------------------
  # * Aquisição do texto UTF-8 da tecla pressionada
  #----------------------------------------------------------------------------
  def utf8(mode=0)
    chr = char(mode)
    return chr if chr.empty?
    if ACCENTS.include?(chr) && @accent.empty?
      @accent = chr
      return ''
    else
      if !@accent.empty? && ACCENTABLE.include?(chr)
        acnt = @accent
        @accent = ''
        return ACCENTED[chr][ACCENTS.index(acnt)]
      elsif !@accent.empty?
        acnt = @accent
        @accent = ''
        return acnt + chr
      end
    end
    return chr
  end
end

#==============================================================================
# ** Input
#==============================================================================
class << Input
  
  #----------------------------------------------------------------------------
  # * Alias
  #----------------------------------------------------------------------------
  alias mbskeyboardinput_press press?
  alias mbskeyboardinput_repeat repeat?
  alias mbskeyboardinput_trigger trigger?
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def press?(key)
    begin
      return mbskeyboardinput_press(key) ? mbskeyboardinput_press(key) : Keyboard.press?(key)
    rescue
      return Keyboard.press?(key)
    end
  end
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def repeat?(key)
    begin
      return mbskeyboardinput_repeat(key) ? mbskeyboardinput_repeat(key) : Keyboard.repeat?(key)
    rescue
      return Keyboard.repeat?(key)
    end
  end
  
  #----------------------------------------------------------------------------
  # * Verificação de se uma tecla foi pressionada
  #----------------------------------------------------------------------------
  def trigger?(key)
    begin
      return mbskeyboardinput_trigger(key) ? mbskeyboardinput_trigger(key) : Keyboard.trigger?(key)
    rescue
      return Keyboard.trigger?(key)
    end
  end
end

[/box2]

[box2 class=titlebg title=Créditos e Agradecimentos]- A mim, por criar[/box2]
~ Masked

O script será bem útil, ainda mais pra mim que estava tentando fazer a uns tempos atrás um sisteminha que não tava querendo pegar direito.

Muito bom, vai ajudar muita gente. Parabéns e valeu por trazer :ok:
Prazer, Terror dos Modinha