Re #752 (CEGUIDemo) Fixed keyboard management (grabbed from Python port of Falagard console demo by Leftium)
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@5078 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 74f1d3c2c69646fa530553ad90a2b33bd15cec02 Former-commit-id: 0a2d48033409c5f3ffc096f185ff5dc38e4a3b6a
This commit is contained in:
parent
ab74aa48aa
commit
7f915d150b
4 changed files with 166 additions and 21 deletions
|
@ -9,10 +9,14 @@
|
|||
This class sets up input processing by creating handlers for GLUT that inject
|
||||
input into PyCEGUI.
|
||||
|
||||
GLUT to CEGUI keyboard mapping from Leftium's PyCEGUI port of Falagard demo console
|
||||
(http://www.cegui.org.uk/phpBB2/viewtopic.php?f=4&t=5425)
|
||||
|
||||
"""
|
||||
|
||||
# Import: std
|
||||
import sys
|
||||
import string
|
||||
|
||||
# Import: OpenGL
|
||||
from OpenGL.GL import *
|
||||
|
@ -30,11 +34,92 @@ from errors import InitializationError
|
|||
# Input
|
||||
class Input(object):
|
||||
|
||||
# GLUT to CEGUI keyboard mapping.
|
||||
mapping = dict([(ord(c), getattr(PyCEGUI.Key, c.upper()))
|
||||
for c in string.ascii_letters])
|
||||
mapping.update({
|
||||
96: PyCEGUI.Key.Grave, 126: PyCEGUI.Key.Grave,
|
||||
49: PyCEGUI.Key.One, 33: PyCEGUI.Key.One,
|
||||
50: PyCEGUI.Key.Two, 64: PyCEGUI.Key.At,
|
||||
51: PyCEGUI.Key.Three, 35: PyCEGUI.Key.Three,
|
||||
52: PyCEGUI.Key.Four, 36: PyCEGUI.Key.Four,
|
||||
53: PyCEGUI.Key.Five, 37: PyCEGUI.Key.Five,
|
||||
54: PyCEGUI.Key.Six, 94: PyCEGUI.Key.Six,
|
||||
55: PyCEGUI.Key.Seven, 38: PyCEGUI.Key.Seven,
|
||||
56: PyCEGUI.Key.Eight, 42: PyCEGUI.Key.Multiply,
|
||||
57: PyCEGUI.Key.Nine, 40: PyCEGUI.Key.Nine,
|
||||
48: PyCEGUI.Key.Zero, 41: PyCEGUI.Key.Zero,
|
||||
45: PyCEGUI.Key.Minus, 95: PyCEGUI.Key.Underline,
|
||||
61: PyCEGUI.Key.Equals, 43: PyCEGUI.Key.Equals,
|
||||
91: PyCEGUI.Key.LeftBracket, 123: PyCEGUI.Key.LeftBracket,
|
||||
93: PyCEGUI.Key.RightBracket, 125: PyCEGUI.Key.RightBracket,
|
||||
59: PyCEGUI.Key.Semicolon, 58: PyCEGUI.Key.Colon,
|
||||
39: PyCEGUI.Key.Apostrophe, 34: PyCEGUI.Key.Apostrophe,
|
||||
92: PyCEGUI.Key.Backslash, 124: PyCEGUI.Key.Backslash,
|
||||
44: PyCEGUI.Key.Comma, 60: PyCEGUI.Key.Comma,
|
||||
46: PyCEGUI.Key.Period, 62: PyCEGUI.Key.Period,
|
||||
47: PyCEGUI.Key.Slash, 63: PyCEGUI.Key.Slash,
|
||||
13: PyCEGUI.Key.Return,
|
||||
8: PyCEGUI.Key.Backspace,
|
||||
9: PyCEGUI.Key.Tab,
|
||||
32: PyCEGUI.Key.Space,
|
||||
127: PyCEGUI.Key.Delete,
|
||||
27: PyCEGUI.Key.Escape})
|
||||
|
||||
specialKeyMap = {
|
||||
GLUT_KEY_F1: PyCEGUI.Key.F1,
|
||||
GLUT_KEY_F2: PyCEGUI.Key.F2,
|
||||
GLUT_KEY_F3: PyCEGUI.Key.F3,
|
||||
GLUT_KEY_F4: PyCEGUI.Key.F4,
|
||||
GLUT_KEY_F5: PyCEGUI.Key.F5,
|
||||
GLUT_KEY_F6: PyCEGUI.Key.F6,
|
||||
GLUT_KEY_F7: PyCEGUI.Key.F7,
|
||||
GLUT_KEY_F8: PyCEGUI.Key.F8,
|
||||
GLUT_KEY_F9: PyCEGUI.Key.F9,
|
||||
GLUT_KEY_F10: PyCEGUI.Key.F10,
|
||||
GLUT_KEY_F11: PyCEGUI.Key.F11,
|
||||
GLUT_KEY_F12: PyCEGUI.Key.F12,
|
||||
GLUT_KEY_LEFT: PyCEGUI.Key.ArrowLeft,
|
||||
GLUT_KEY_UP: PyCEGUI.Key.ArrowUp,
|
||||
GLUT_KEY_RIGHT: PyCEGUI.Key.ArrowRight,
|
||||
GLUT_KEY_DOWN: PyCEGUI.Key.ArrowDown,
|
||||
GLUT_KEY_PAGE_UP: PyCEGUI.Key.PageUp,
|
||||
GLUT_KEY_PAGE_DOWN: PyCEGUI.Key.PageDown,
|
||||
GLUT_KEY_HOME: PyCEGUI.Key.Home,
|
||||
GLUT_KEY_END: PyCEGUI.Key.End,
|
||||
GLUT_KEY_INSERT: PyCEGUI.Key.Insert }
|
||||
|
||||
def ascii2Scancode(self, a):
|
||||
|
||||
a = ord(a)
|
||||
return self.mapping[a] if (a in self.mapping) else 0
|
||||
|
||||
def special2Scancode(self, c):
|
||||
|
||||
return self.specialKeyMap[c] if (c in self.specialKeyMap) else 0
|
||||
|
||||
# Constructor.
|
||||
def __init__(self):
|
||||
|
||||
self.glut_modifiers = \
|
||||
dict(shift = dict(is_held=False,
|
||||
bit_flag=GLUT_ACTIVE_SHIFT,
|
||||
scancode=PyCEGUI.Key.LeftShift),
|
||||
ctrl = dict(is_held=False,
|
||||
bit_flag=GLUT_ACTIVE_CTRL,
|
||||
scancode=PyCEGUI.Key.LeftControl),
|
||||
alt = dict(is_held=False,
|
||||
bit_flag=GLUT_ACTIVE_ALT,
|
||||
scancode=PyCEGUI.Key.LeftAlt))
|
||||
|
||||
# Initialize: Handlers
|
||||
def initializeHandlers(self):
|
||||
|
||||
glutKeyboardFunc(self.handlerKeyDown)
|
||||
glutMouseFunc(self.handlerMouseButton)
|
||||
glutKeyboardFunc(self.handlerNormalKeyDown)
|
||||
glutSpecialFunc(self.handlerSpecialKeyDown)
|
||||
|
||||
glutKeyboardUpFunc(self.handlerNormalKeyUp)
|
||||
glutSpecialUpFunc(self.handlerSpecialKeyUp)
|
||||
|
||||
# The difference between these two is that the passive one is called when there is
|
||||
# mouse motion while no buttons are pressed, and the other is called when there
|
||||
|
@ -42,6 +127,8 @@ class Input(object):
|
|||
glutMotionFunc(self.handlerMouseMotion)
|
||||
glutPassiveMotionFunc(self.handlerMouseMotion)
|
||||
|
||||
glutMouseFunc(self.handlerMouseButton)
|
||||
|
||||
# Initialize
|
||||
def initialize(self):
|
||||
|
||||
|
@ -50,12 +137,63 @@ class Input(object):
|
|||
except Exception, msg:
|
||||
raise InitializationError(msg)
|
||||
|
||||
# Handler: Key Down
|
||||
# - `ord` is a built-in Python function.
|
||||
def handlerKeyDown(self, key, x, y):
|
||||
def handleModifierKeys(self):
|
||||
|
||||
status = glutGetModifiers()
|
||||
|
||||
for name, key in self.glut_modifiers.items():
|
||||
if (status & key['bit_flag']):
|
||||
if not key['is_held']:
|
||||
key['is_held'] = True
|
||||
PyCEGUI.System.getSingleton().injectKeyDown(key['scancode'])
|
||||
elif key['is_held']:
|
||||
key['is_held'] = False
|
||||
PyCEGUI.System.getSingleton().injectKeyUp(key['scancode'])
|
||||
|
||||
# Handler: Normal Key Down
|
||||
def handlerNormalKeyDown(self, key, x, y):
|
||||
|
||||
key = key.encode('ascii', 'ignore')
|
||||
self.handleModifierKeys()
|
||||
scancode = self.ascii2Scancode(key)
|
||||
if scancode:
|
||||
PyCEGUI.System.getSingleton().injectKeyDown(int(scancode))
|
||||
PyCEGUI.System.getSingleton().injectChar(ord(key))
|
||||
|
||||
return False
|
||||
|
||||
# Handler: Normal Key Up
|
||||
def handlerNormalKeyUp(self, key, x, y):
|
||||
|
||||
key = key.encode('ascii', 'ignore')
|
||||
self.handleModifierKeys()
|
||||
scancode = self.ascii2Scancode(key)
|
||||
if scancode:
|
||||
PyCEGUI.System.getSingleton().injectKeyDown(int(scancode))
|
||||
PyCEGUI.System.getSingleton().injectKeyUp(int(scancode))
|
||||
|
||||
return False
|
||||
|
||||
# Handler: Special Key Down
|
||||
def handlerSpecialKeyDown(self, key, x, y):
|
||||
|
||||
self.handleModifierKeys()
|
||||
scancode = self.special2Scancode(key)
|
||||
if scancode:
|
||||
PyCEGUI.System.getSingleton().injectKeyDown(int(scancode))
|
||||
|
||||
return False
|
||||
|
||||
# Handler: Special Key Up
|
||||
def handlerSpecialKeyUp(self, key, x, y):
|
||||
|
||||
self.handleModifierKeys()
|
||||
scancode = self.special2Scancode(key)
|
||||
if scancode:
|
||||
PyCEGUI.System.getSingleton().injectKeyUp(int(scancode))
|
||||
|
||||
return False
|
||||
|
||||
# Handler: Mouse Button
|
||||
def handlerMouseButton(self, button, state, x, y):
|
||||
|
||||
|
@ -78,9 +216,13 @@ class Input(object):
|
|||
# mouse input; this is left as an exercise for the reader. Instead, we just implicitly
|
||||
# ignore it.
|
||||
|
||||
return False
|
||||
|
||||
# Handler: Mouse Motion
|
||||
# - This might seem arbitrary, but in fact this is required or else the position of the mouse
|
||||
# will never be updated inside the window.
|
||||
def handlerMouseMotion(self, x, y):
|
||||
|
||||
PyCEGUI.System.getSingleton().injectMousePosition(x, y)
|
||||
|
||||
return False
|
||||
|
|
|
@ -103,14 +103,13 @@ class Menu(object):
|
|||
self.txtTitle = window.getChild(name + "/TxtTitle")
|
||||
self.txtFrameRate = window.getChild(name + "/TxtFrameRate")
|
||||
|
||||
# Trace info. about children.
|
||||
#print "Menu: Children (n=%d) :" % self.window.getChildCount()
|
||||
#for chldInd in range(self.window.getChildCount()):
|
||||
# print " #%d : name=%r" % (chldInd, self.window.getChildAtIdx(chldInd).getName())
|
||||
|
||||
return window
|
||||
|
||||
def onKeyDown(self, keyArgs):
|
||||
|
||||
# Nothing special to do here (see derived classes)
|
||||
print "Menu.onKeyDown:", keyArgs
|
||||
return False # Or True ?
|
||||
|
||||
# connectHandlers
|
||||
# - Wrapper method to define the subscription/listener relationships.
|
||||
# - If there are a lot, it may behoove the coder to encapsulate them in methods, then call those methods here.
|
||||
|
@ -118,7 +117,7 @@ class Menu(object):
|
|||
|
||||
# Event subscriptions :
|
||||
# * keyboard : Does not work.
|
||||
self.window.subscribeEvent(PyCEGUI.Window.EventCharacterKey, self, 'onCharacterKey');
|
||||
self.window.subscribeEvent(PyCEGUI.Window.EventKeyDown, self, 'onKeyDown');
|
||||
|
||||
# * window update (for the frame rate indicator).
|
||||
self.window.subscribeEvent(PyCEGUI.Window.EventWindowUpdated, self, 'onUpdate');
|
||||
|
@ -142,6 +141,9 @@ class Menu(object):
|
|||
self.nFrames = 0
|
||||
self.lastTime = glutGet(GLUT_ELAPSED_TIME)
|
||||
|
||||
# Give focus to the root window (needed for EventKeyDown being received).
|
||||
self.window.activate()
|
||||
|
||||
# Return to the previous menu.
|
||||
def back(self):
|
||||
|
||||
|
@ -161,7 +163,8 @@ class Menu(object):
|
|||
self.nFrames = 0
|
||||
self.lastTime = thisTime
|
||||
|
||||
def onCharacterKey(self, keyArgs):
|
||||
|
||||
pass # Just in case not specialised in actual class.
|
||||
def onKeyDown(self, keyArgs):
|
||||
|
||||
# Just in case not specialised in actual class.
|
||||
print "Menu.onKeyDown: sc=", keyArgs.scancode
|
||||
return False # Or True ?
|
||||
|
|
|
@ -104,10 +104,6 @@ class MenuStandard(Menu):
|
|||
# - If there are a lot, it may behoove the coder to encapsulate them in methods, then call those methods here.
|
||||
def connectHandlers(self):
|
||||
|
||||
print "Menu: Children (n=%d) :" % self.window.getChildCount()
|
||||
for chldInd in range(self.window.getChildCount()):
|
||||
print " #%d : name=%r" % (chldInd, self.window.getChildAtIdx(chldInd).getName())
|
||||
|
||||
# Inherited connections.
|
||||
Menu.connectHandlers(self)
|
||||
|
||||
|
@ -145,9 +141,9 @@ class MenuStandard(Menu):
|
|||
print("Exiting (on exit button) ...")
|
||||
sys.exit(0)
|
||||
|
||||
def onCharacterKey(self, keyArgs):
|
||||
def onKeyDown(self, keyArgs):
|
||||
|
||||
print "MenuStandard.onCharacterKey: scan=%d, " % (keyArgs.scancode, )
|
||||
print "MenuStandard.onKeyDown: sc=%d, " % (keyArgs.scancode, )
|
||||
if keyArgs.scancode == PyCEGUI.Key.Escape:
|
||||
|
||||
keyArgs.handled += 1
|
||||
|
|
|
@ -34,6 +34,10 @@ from configuration import TheConfig
|
|||
# Video
|
||||
class Video(object):
|
||||
|
||||
def __del__(self):
|
||||
|
||||
OpenGLRenderer.destroySystem()
|
||||
|
||||
# Initialize: OpenGL
|
||||
def initializeOpenGL(self):
|
||||
|
||||
|
|
Loading…
Reference in a new issue