cdef class Widget :
'''Widget Class
A Widget is a 2d section/layer in a soy.Window. This is the base class
which all widgets inherit, it has no render functionality of it's own.
'''
def __new__(self, parent, position=(0,0), size=(0,0), *args, **keywords) :
self._window = parent
self._xpos = position[0]
self._ypos = position[1]
self._width = size[0]
self._height = size[1]
self._window._widgets.lock()
self._window._widgets.append(<void *>self)
self._window._widgets.unlock()
def __dealloc__(self) :
self._window._widgets.lock()
self._window._widgets.remove(<void *>self)
self._window._widgets.unlock()
def __repr__(self) :
return '<Widget in Window id %d>' % (self._window._windowID)
cdef void _render(self) :
return
cdef void _resize(self) :
return
property position :
'''Widget's position in the window
This is the position of the widget in respect to the window it's in.
Changing this property will move the widget.
Takes a (x,y) as an argument and defaults to (0,0)
'''
def __get__(self) :
return (self._xpos, self._ypos)
def __set__(self, value) :
if len(value)!=2 or type(value[0])!=int or type(value[1])!=int :
raise TypeError('Must provide an (int,int) for position')
self._window._widgets.lock()
self._xpos = value[0]
self._ypos = value[1]
self._window._widgets.unlock()
property size :
'''Widget size
This is the pixel size of the widget in the window.
Takes an (x,y), defaults to window's full size.
'''
def __get__(self) :
return (self._width, self._height)
def __set__(self, value) :
if len(value)==2 and type(value[0])==int and type(value[1])==int :
self._window._widgets.lock()
self._width = value[0]
self._height = value[1]
self._window._widgets.unlock()
elif value == None :
self._width = self._window._width
self._height = self._window._height
else :
raise TypeError('Must provide an (int,int) for size')
self._resize()
cdef class Projector(Widget) :
def __new__(self, parent, position=(0,0), size=(0,0), camera=None,
*args, **keywords) :
self._camera = camera
if camera : self._connected = 1
else : self._connected = 0
self._aspect = (<float> self._width) / (<float> self._height)
self._znear = 1.0
self._zfar = 100.0
cdef void _render(self) :
if not self._connected :
return
gl.glViewport(self._xpos, self._ypos, self._width, self._height)
gl.glEnable(0x0B71) # GL_DEPTH_TEST
gl.glClear(0x00000100)
gl.glMatrixMode(0x1701) # GL_PROJECTION
gl.glLoadIdentity()
gl.gluPerspective(self._camera._fovy,self._aspect,self._znear,self._zfar)
gl.glMatrixMode(0x1700) # GL_MODELVIEW
gl.glLoadIdentity()
self._camera._project()
gl.glDisable(0x0B71) # GL_DEPTH_TEST
cdef void _resize(self) :
self._aspect = (<float> self._width) / (<float> self._height)
property camera :
'''Projection Camera
This is the camera currently attached to the projector widget. It may be
changed to a different soy.bodies.Camera or None to disable projection.
'''
def __get__(self) :
return self._camera
def __set__(self, value) :
if type(value) == soy.bodies.Camera :
self._camera = Camera
self._connected = 1
else :
raise TypeError('Must provide an instance of soy.bodies.Camera')
def __del__(self) :
self._camera = None
self._connected = 0
cdef class Square(Widget) :
def __new__(self, parent, position=(0,0), size=(0,0),
color=None, *args, **keywords) :
if color :
self._color = color
else :
self._color = soy._core.Color('white')
cdef void _render(self) :
gl.glViewport(self._xpos, self._ypos, self._width, self._height)
gl.glMatrixMode(0x1701) # GL_PROJECTION
gl.glLoadIdentity()
gl.glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1)
gl.glMatrixMode(0x1700) # GL_MODELVIEW
gl.glLoadIdentity()
gl.glColor4ub(self._color._r,self._color._g,self._color._b,self._color._a)
gl.glBegin(0x0007) # 0x0004 = Triangles, 0x0007 = Quads
gl.glVertex2f( 0.0, 0.0)
gl.glVertex2f( 0.0, 1.0)
gl.glVertex2f( 1.0, 1.0)
gl.glVertex2f( 1.0, 0.0)
gl.glEnd()