pygamekit / input.pxi

from prerequisites cimport *
from input cimport *
from mathutils cimport *

KEYS = ('NONE', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
'ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 
'CAPSLOCK', 'LEFTCTRL', 'LEFTALT', 'RIGHTALT', 'RIGHTCTRL', 'RIGHTSHIFT', 'LEFTSHIFT', 
'ESC', 'TAB', 'RET', 'SPACE', 'LINEFEED', 'BACKSPACE', 'DEL', 'SEMICOLON', 'PERIOD', 
'COMMA', 'QUOTE', 'ACCENTGRAVE', 'MINUS', 'SLASH', 'BACKSLASH', 'EQUAL', 'LEFTBRACKET', 'RIGHTBRACKET', 
'LEFTARROW', 'DOWNARROW', 'RIGHTARROW', 'UPARROW', 
'PAD0', 'PAD1', 'PAD2', 'PAD3', 'PAD4', 'PAD5', 'PAD6', 'PAD7', 'PAD8', 'PAD9', 
'PADEQUALS', 'PADPERIOD', 'PADSLASH', 'PADASTER', 'PADMINUS', 'PADENTER', 'PADPLUS', 
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'PAUSE', 
'INSERT', 'HOME', 'PAGEUP', 'PAGEDOWN', 'END', 'UNKNOWN', 'COMMAND', 'GRLESS')

class WrongInputError(BaseException):
    pass

cdef list key_callbacks = []
cdef list mouse_move_callbacks = []
cdef list mousebutton_callbacks = []
cdef int previous_keys[256] #TODO: use KC_MAX
cdef int previous_mb[3]
cdef gkmath.Vector2 prev_mouse
prev_mouse.x = -1

cdef class Key(Sensor):
    
    cdef int *key
    cdef int keynum
    
    def __init__(self, keyname):
        cdef int keycode
        try:
            keycode = KEYS.index(keyname)
        except ValueError:
            raise WrongInputError('Key name not in '+str(KEYS))
        self.key = getKeyboard().keys + keycode
        self.keynum = keycode
        self.init_sensor(key_callbacks)
        
    def __nonzero__(self):
        return self.key[0] == 1

    def __str__(self):
        if self.key[0] == 1: return "<Key %s Pressed>" % KEYS[self.keynum]
        else: return "<Key %s>" % KEYS[self.keynum]

cdef class MouseButton(Sensor):
    
    cdef int *but
    cdef int butnum
    
    def __init__(self, button):
        if not 1<=button<=3:
            raise WrongInputError('Button must be between 1 and 3.')
        
        self.but = &getMouse().buttons[button-1]
        self.butnum = button
        self.init_sensor(mousebutton_callbacks)
    
    def __nonzero__(self):
        return self.but[0] == 1

    def __str__(self):
        if self.but[0] == 1: return "<MouseButton Pressed>"
        else: return "<MouseButton>"

cdef class Keyboard:
    
    cdef gkKeyboard *keybd
    
    def __init__(self):
        self.keybd = getKeyboard()
        
    def getKey(self, code):
        return self.keybd.keys[code] == 1
        
cdef class MouseMotion(Sensor):
    
    cdef gkMouse *mouse
    cdef int butnum
    
    def __init__(self, butnum=-1):
        self.mouse = getMouse()
        self.butnum = butnum
        self.init_sensor(mouse_move_callbacks)
        
    @property
    def position(self):
        cdef gkmath.Vector2 v = self.mouse.getPosition()
        return v.x, v.y
        
    @property
    def relative(self):
        cdef gkmath.Vector2 v = self.mouse.getRelative()
        return v.x, v.y
        
    #def isButtonDown(self, button):
        #return self.mouse.isButtonDown(button)
        
    #def mouseMoved(self):
        #return self.mouse.mouseMoved()
           
cdef class Accelerometer:
    cdef Vector v
    cdef gkmath.Vector3 *v3

    def __init__(self):
        self.v = Vector()
        #self.v3 = <gkmath.Vector3 *>
        
    property value:
        def __get__(self):
            if self.v3:
                self.v3.assign((<Vector>self.v).v[0])
            return self.v

cdef void evaluate_input_callbacks() except *:
    global prev_mouse
    cdef int k, *keys = getKeyboard().keys
    cdef gkmath.Vector2 pos = getMouse().getPosition(), rel
    cdef Sensor e
    cdef int *mousebuttons = getMouse().buttons, b
    
    for e in key_callbacks:
        k = (<Key>e).keynum
        if keys[k] != previous_keys[k]:
            e.execute()

    memcpy(previous_keys, keys, sizeof(int)*256) #TODO: use KC_MAX
    
    if prev_mouse.x == -1:
        rel.x = 0
        rel.y = 0
    else:
        rel.x = pos.x - prev_mouse.x
        rel.y = pos.y - prev_mouse.y
        
    if not rel.isZeroLength():
        for e in mouse_move_callbacks:
            b = (<MouseMotion>e).butnum
            if 1 or b==-1 or mousebuttons[b]:
                e.execute()
    
    prev_mouse = pos
    
    for e in mousebutton_callbacks:
        k = (<MouseButton>e).butnum
        if mousebuttons[k] != previous_mb[k]:
            e.execute()
        
    memcpy(previous_mb, mousebuttons, sizeof(int)*3)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.