Source

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 Event press_callbacks = Event()
cdef Event release_callbacks = Event()
cdef Event mouse_move_callbacks = Event()
cdef Event mbpress_callbacks = Event()
cdef Event mbrelease_callbacks = Event()
cdef int previous_keys[256] #TODO: use KC_MAX
cdef int previous_mb[3]
cdef gkVector2 prev_mouse
prev_mouse.x = -1

cdef class Key:
    
    cdef int *key
    cdef Event _press, _release
    
    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._press = Event()
        self._press.data._key = keycode
        self._release = Event()
        self._release.data._key = keycode
        
    def __nonzero__(self):
        return self.key[0] == 1
        
    property onPress:
        
        def __get__(self):
            self._press.check_add_to_list(press_callbacks)
            return self._press
            
        def __set__(self, func):
            self._press.check_add_to_list(press_callbacks)
            del(self._press[:])
            self._press += func
            
    property onRelease:
        
        def __get__(self):
            self._release.check_add_to_list(release_callbacks)
            return self._release
            
        def __set__(self, func):
            self._release.check_add_to_list(release_callbacks)
            del(self._release[:])
            self._release += func

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

cdef class MouseButton:
    
    cdef int *but
    cdef Event _press, _release
    
    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._press = Event()
        self._press.data._key = button
        self._release = Event()
        self._release.data._key = button
    
    def __nonzero__(self):
        return self.but[0] == 1

    property onPress:
        
        def __get__(self):
            self._press.check_add_to_list(mbpress_callbacks)
            return self._press
            
        def __set__(self, func):
            self._press.check_add_to_list(mbpress_callbacks)
            del(self._press[:])
            self._press += func
            
    property onRelease:
        
        def __get__(self):
            self._release.check_add_to_list(mbrelease_callbacks)
            return self._release
            
        def __set__(self, func):
            self._release.check_add_to_list(mbrelease_callbacks)
            del(self._release[:])
            self._release += func

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

cdef class Keyboard:
    
    cdef gkKeyboard *keybd
    cdef Key prueba
    
    def __init__(self):
        self.keybd = getKeyboard()
        
    def getKey(self, code):
        return self.keybd.keys[code] == 1
        
cdef class Mouse:
    
    cdef gkMouse *mouse
    cdef Event _move
    
    def __init__(self):
        self.mouse = getMouse()
        self._move = Event()
        self._move.data._key = -1
        
    @property
    def position(self):
        cdef gkVector2 v = self.mouse.getPosition()
        return v.x, v.y
        
    @property
    def relative(self):
        cdef gkVector2 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()

    property onMouseMove:
        
        def __get__(self):
            self._move.check_add_to_list(mouse_move_callbacks)
            return self._move
            
        def __set__(self, func):
            self._move.check_add_to_list(mouse_move_callbacks)
            del(self._move[:])
            self._move += func
           
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 gkVector2 pos = getMouse().getPosition(), rel
    cdef Event e
    cdef int *mousebuttons = getMouse().buttons
    
    e = press_callbacks
    while e != None:
        k = e.data._key
        if keys[k] == 1 and previous_keys[k] != 1:
            e.execute()
        e = e.next_non_empty()

    e = release_callbacks
    while e != None:
        k = e.data._key
        if keys[k] != 1 and previous_keys[k] == 1:
            e.execute()
        e = e.next_non_empty()

    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():
        e = mouse_move_callbacks
        while e != None:
            if e.data._key==-1 or mousebuttons[e.data._key]:
                e.data._rel[0] = rel
                e.execute()
            e = e.next_non_empty()
    
    prev_mouse = pos
    
    e = mbpress_callbacks
    while e != None:
        k = e.data._key-1
        if mousebuttons[k] == 1 and previous_mb[k] != 1:
            e.execute()
        e = e.next_non_empty()

    e = mbrelease_callbacks
    while e != None:
        k = e.data._key-1
        if mousebuttons[k] == 1 and previous_mb[k] != 1:
            e.execute()
        e = e.next_non_empty()
        
    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.