|
|
Line 1: |
Line 1: |
− | {{VersionBadge|0.7}} {{VersionAtLeast|0.7.5}}
| + | Delete me. |
− | <br /><br /><br /><br />
| + | |
− | | + | |
− | == Introduction ==
| + | |
− | This presents the basics of using subscriptions to respond to events. The example retrieves two buttons and defines a method to be called when they are each clicked.
| + | |
− | | + | |
− | == Requirements ==
| + | |
− | * Python 2.6 (untested on Python 3.+)
| + | |
− | * PyCEGUI
| + | |
− | * PyOpenGL (GLU and GLUT, as well)
| + | |
− | | + | |
− | == Notes ==
| + | |
− | The source code uses a modified version of the OpenGL example posted [[User:Crond/sandbox/openglExample|here]].
| + | |
− | | + | |
− | == Source ==
| + | |
− | <source lang="python">
| + | |
− | #!/usr/bin/env python
| + | |
− | #
| + | |
− | #
| + | |
− | # example.py
| + | |
− | | + | |
− | | + | |
− | # Import: std
| + | |
− | import sys
| + | |
− | | + | |
− | # Import: PyOpenGL
| + | |
− | from OpenGL.GL import *
| + | |
− | from OpenGL.GLU import *
| + | |
− | from OpenGL.GLUT import *
| + | |
− | | + | |
− | # Import: PyCEGUI
| + | |
− | import PyCEGUI
| + | |
− | from PyCEGUIOpenGLRenderer import OpenGLRenderer as Renderer
| + | |
− | | + | |
− | # Constants
| + | |
− | PATH_RESOURCES = './'
| + | |
− | | + | |
− | | + | |
− | # Application
| + | |
− | class Application(object):
| + | |
− | | + | |
− | # Constructor
| + | |
− | def __init__(self):
| + | |
− | super(Application, self).__init__()
| + | |
− | self.lastFrameTime = 0
| + | |
− | self.updateFPS = 0
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: OpenGL
| + | |
− | # - A full list of values for `glutInitDisplayMode` can be found in the GLUT
| + | |
− | # documentation.
| + | |
− | def initializeOpenGL(self):
| + | |
− | glutInit()
| + | |
− | glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA)
| + | |
− | glutInitWindowSize(1024, 768)
| + | |
− | glutInitWindowPosition(-1, -1) # Let the windowing system figure it out
| + | |
− | glutCreateWindow("Crazy Eddie's GUI Mk-2 - glut Base Application")
| + | |
− | glutSetCursor(GLUT_CURSOR_NONE)
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: Handlers
| + | |
− | # - Setup the methods which will be called when events happen.
| + | |
− | def initializeHandlers(self):
| + | |
− | glutDisplayFunc(self.handlerDisplay)
| + | |
− | glutReshapeFunc(self.handlerResize)
| + | |
− | glutMouseFunc(self.handlerMouse)
| + | |
− | glutMotionFunc(self.handlerMouseMotion)
| + | |
− | glutPassiveMotionFunc(self.handlerMouseMotion)
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: PyCEGUI
| + | |
− | # - Store some components; saves a lot of typing.
| + | |
− | def initializePyCEGUI(self):
| + | |
− | Renderer.bootstrapSystem()
| + | |
− | self.sys = PyCEGUI.System.getSingleton()
| + | |
− | self.rp = self.sys.getResourceProvider()
| + | |
− | self.scheme = PyCEGUI.SchemeManager.getSingleton()
| + | |
− | self.wm = PyCEGUI.WindowManager.getSingleton()
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: Defaults
| + | |
− | # - Resource locations.
| + | |
− | def initializeDefaults(self):
| + | |
− | self.rp.setResourceGroupDirectory('schemes', './datafiles/schemes')
| + | |
− | self.rp.setResourceGroupDirectory('imagesets', './datafiles/imagesets')
| + | |
− | self.rp.setResourceGroupDirectory('fonts', './datafiles/fonts')
| + | |
− | self.rp.setResourceGroupDirectory('layouts', './datafiles/layouts')
| + | |
− | self.rp.setResourceGroupDirectory('looknfeels', './datafiles/looknfeel')
| + | |
− | self.rp.setResourceGroupDirectory('schemas', './datafiles/xml_schemas')
| + | |
− | PyCEGUI.Imageset.setDefaultResourceGroup('imagesets')
| + | |
− | PyCEGUI.Font.setDefaultResourceGroup('fonts')
| + | |
− | PyCEGUI.Scheme.setDefaultResourceGroup('schemes')
| + | |
− | PyCEGUI.WidgetLookManager.setDefaultResourceGroup('looknfeels')
| + | |
− | PyCEGUI.WindowManager.setDefaultResourceGroup('layouts')
| + | |
− | parser = self.sys.getXMLParser()
| + | |
− | if parser.isPropertyPresent('SchemaDefaultResourceGroup'):
| + | |
− | parser.setProperty('SchemaDefaultResourceGroup', 'schemas')
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: GUI
| + | |
− | # - This is where we are actually setting up the windows we will see.
| + | |
− | def initializeGUI(self):
| + | |
− | self.scheme.create('VanillaSkin.scheme')
| + | |
− | self.scheme.create('TaharezLook.scheme')
| + | |
− | | + | |
− | # GUISheet
| + | |
− | self.rootWindow = self.wm.loadWindowLayout('VanillaWindows.layout')
| + | |
− | self.sys.setGUISheet(self.rootWindow)
| + | |
− | | + | |
− | # Cursor
| + | |
− | self.sys.setDefaultMouseCursor('Vanilla-Images', 'MouseArrow')
| + | |
− | | + | |
− | # An extra window
| + | |
− | w = self.wm.createWindow('TaharezLook/FrameWindow', 'Demo window')
| + | |
− | self.rootWindow.addChildWindow(w)
| + | |
− | return
| + | |
− | | + | |
− | # Initialize: Subscriptions
| + | |
− | def initializeSubscriptions(self):
| + | |
− | | + | |
− | # In order to be able to access the buttons, we need to get a copy of their parent.
| + | |
− | self.windowNewNode = self.rootWindow.getChild('Demo/NewNode')
| + | |
− | | + | |
− | # Now, we get the buttons.
| + | |
− | self.buttonOkay = self.windowNewNode.getChild('Demo/NewNode/Okay')
| + | |
− | self.buttonCancel = self.windowNewNode.getChild('Demo/NewNode/Cancel')
| + | |
− | | + | |
− | # And subscribe to the events, telling PyCEGUI what method it should call when the event happens.
| + | |
− | self.buttonOkay.subscribeEvent(PyCEGUI.PushButton.EventClicked, self, 'buttonOkayClicked')
| + | |
− | self.buttonCancel.subscribeEvent(PyCEGUI.PushButton.EventClicked, self, 'buttonCancelClicked')
| + | |
− | return
| + | |
− | | + | |
− | # Initialize
| + | |
− | def Initialize(self):
| + | |
− | self.initializeOpenGL()
| + | |
− | self.initializeHandlers()
| + | |
− | self.initializePyCEGUI()
| + | |
− | self.initializeDefaults()
| + | |
− | self.initializeGUI()
| + | |
− | self.initializeSubscriptions()
| + | |
− | return
| + | |
− | | + | |
− | # Handler: Display
| + | |
− | def handlerDisplay(self):
| + | |
− | | + | |
− | # Injecting the time allows CEGUI to know how much time has passed, and
| + | |
− | # use that to coordinate certain activities - fading, animation, tooltips,
| + | |
− | # etc.
| + | |
− | now = glutGet(GLUT_ELAPSED_TIME)
| + | |
− | elapsed = (now - self.lastFrameTime) / 1000.0
| + | |
− | self.lastFrameTime = now
| + | |
− | self.updateFPS = self.updateFPS - elapsed
| + | |
− | self.sys.injectTimePulse(elapsed)
| + | |
− | | + | |
− | # Actual rendering
| + | |
− | # - `renderGUI` updates CEGUI's picture of the GUI.
| + | |
− | # - `glutPostRedisplay` is what actually marks the window as needing to
| + | |
− | # be redrawn by OpenGL.
| + | |
− | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
| + | |
− | self.sys.renderGUI()
| + | |
− | glutPostRedisplay()
| + | |
− | glutSwapBuffers()
| + | |
− | return
| + | |
− | | + | |
− | # Handler: Resize
| + | |
− | # - `glViewport` modifies the OpenGL viewport to whatever the window size is.
| + | |
− | def handlerResize(self, width, height):
| + | |
− | glViewport(0, 0, width, height)
| + | |
− | self.sys.notifyDisplaySizeChanged(PyCEGUI.Size(width, height))
| + | |
− | return
| + | |
− | | + | |
− | # Handler: Mouse buttons
| + | |
− | def handlerMouse(self, button, state, x, y):
| + | |
− | if button == GLUT_LEFT_BUTTON:
| + | |
− | if state == GLUT_UP:
| + | |
− | self.sys.injectMouseButtonUp(PyCEGUI.LeftButton)
| + | |
− | else:
| + | |
− | self.sys.injectMouseButtonDown(PyCEGUI.LeftButton)
| + | |
− | elif button == GLUT_RIGHT_BUTTON:
| + | |
− | if state == GLUT_UP:
| + | |
− | self.sys.injectMouseButtonUp(PyCEGUI.RightButton)
| + | |
− | else:
| + | |
− | self.sys.injectMouseButtonDown(PyCEGUI.RightButton)
| + | |
− | return
| + | |
− | | + | |
− | # Handler: Mouse motion
| + | |
− | def handlerMouseMotion(self, x, y):
| + | |
− | self.sys.injectMousePosition(x, y)
| + | |
− | return
| + | |
− | | + | |
− | # Handler: buttonOkayClicked
| + | |
− | def buttonOkayClicked(self, args):
| + | |
− | print('Okay has been clicked.')
| + | |
− | return
| + | |
− | | + | |
− | def buttonCancelClicked(self, args):
| + | |
− | print('Cancel has been clicked.')
| + | |
− | return
| + | |
− | | + | |
− | # Run
| + | |
− | def Run(self):
| + | |
− | self.lastFrameTime = glutGet(GLUT_ELAPSED_TIME)
| + | |
− | glutMainLoop()
| + | |
− | return
| + | |
− | | + | |
− | # Main
| + | |
− | def main():
| + | |
− | app = Application()
| + | |
− | app.Initialize()
| + | |
− | app.Run()
| + | |
− | return 0
| + | |
− | | + | |
− | | + | |
− | # Guard
| + | |
− | if __name__ == '__main__':
| + | |
− | sys.exit(main())
| + | |
− | </source>
| + | |
Delete me.