Author: ArcRiley
Date: 2007-07-06 16:45:07 -0400 (Fri, 06 Jul 2007)
New Revision: 379
Added:
trunk/pysoy/src/widgets/StackZ.pxi
Modified:
trunk/pysoy/src/_core-x11/Window.pxi
trunk/pysoy/src/widgets/Canvas.pxi
trunk/pysoy/src/widgets/Projector.pxi
trunk/pysoy/src/widgets/Widget.pxi
trunk/pysoy/src/widgets/soy.widgets.pxd
trunk/pysoy/tests/lit_pyramid.py
trunk/pysoy/tests/tex_canvas.py
trunk/pysoy/tests/tex_pyramid.py
Log:
working on ticket #270, containers are (somewhat) implemented, aspect ratio
calculation on resize doesn't respect maximum sizes
Modified: trunk/pysoy/src/_core-x11/Window.pxi
===================================================================
--- trunk/pysoy/src/_core-x11/Window.pxi 2007-07-06 06:45:47 UTC (rev
378)
+++ trunk/pysoy/src/_core-x11/Window.pxi 2007-07-06 20:45:07 UTC (rev
379)
@@ -130,7 +130,7 @@
# Resize widgets
self._widgets.lock()
for i from 0 <= i < self._widgets.current :
- (<soy.widgets.Widget> self._widgets.list[i])._resize()
+ (<soy.widgets.Widget> self._widgets.list[i])._resize(0,0,_width,_height)
self._widgets.unlock()
Modified: trunk/pysoy/src/widgets/Canvas.pxi
===================================================================
--- trunk/pysoy/src/widgets/Canvas.pxi 2007-07-06 06:45:47 UTC (rev 378)
+++ trunk/pysoy/src/widgets/Canvas.pxi 2007-07-06 20:45:07 UTC (rev 379)
@@ -22,8 +22,9 @@
This is a simple widget used to display a texture.
'''
- def __new__(self, parent, position=(0,0), size=(0,0),
- texture=None, *args, **keywords) :
+ def __new__(self, parent, margin=None, aspect=0.0,
+ texture=None,
+ *args, **keywords) :
self._verts[1].px = 1.0
self._verts[1].tx = 1.0
self._verts[2].px = 1.0
Modified: trunk/pysoy/src/widgets/Projector.pxi
===================================================================
--- trunk/pysoy/src/widgets/Projector.pxi 2007-07-06 06:45:47 UTC (rev
378)
+++ trunk/pysoy/src/widgets/Projector.pxi 2007-07-06 20:45:07 UTC (rev
379)
@@ -18,26 +18,31 @@
# $Id$
cdef class Projector(Widget) :
- def __new__(self, parent, position=(0,0), size=(0,0), camera=None,
+ def __new__(self, parent, margin=None, aspect=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) :
cdef float bright[4]
+ cdef float _aspect
if not self._connected :
return
+ if self._aspectRatio :
+ _aspect = self._aspectRatio
+ else :
+ _aspect = (<float> self._width) / (<float> self._height)
gl.glViewport(self._xpos, self._ypos, self._width, self._height)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
- gl.gluPerspective(self._camera._fovy,self._aspect,self._znear,self._zfar)
+ gl.gluPerspective(self._camera._fovy, _aspect, self._znear, self._zfar)
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity()
gl.glEnable(gl.GL_DEPTH_TEST)
@@ -54,9 +59,6 @@
gl.glDisable(gl.GL_DEPTH_TEST)
- cdef void _resize(self) :
- self._aspect = (<float> self._width) / (<float> self._height)
-
property camera :
'''Projection Camera
Copied: trunk/pysoy/src/widgets/StackZ.pxi (from rev 378,
trunk/pysoy/src/widgets/Widget.pxi)
===================================================================
--- trunk/pysoy/src/widgets/StackZ.pxi (rev 0)
+++ trunk/pysoy/src/widgets/StackZ.pxi 2007-07-06 20:45:07 UTC (rev 379)
@@ -0,0 +1,32 @@
+# PySoy widgets.StackZ class
+#
+# Copyright (C) 2007 Team PySoy
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see http://www.gnu.org/licenses
+#
+# $Id$
+
+cdef class StackZ (Widget) :
+ '''PySoy widgets.StackZ Class
+
+ This stacking widget overlaps children as "layers". This behavior is
+ identical to how a soy.Window stacks top-level widgets.
+ '''
+ def __new__(self, parent, margin=None, aspect=0.0,
+ *args, **keywords) :
+ self._widgets = soy._internals.Children()
+
+
+ def __repr__(self) :
+ return '<StackX Widget in Window id %d>' % (self._window._windowID)
Modified: trunk/pysoy/src/widgets/Widget.pxi
===================================================================
--- trunk/pysoy/src/widgets/Widget.pxi 2007-07-06 06:45:47 UTC (rev 378)
+++ trunk/pysoy/src/widgets/Widget.pxi 2007-07-06 20:45:07 UTC (rev 379)
@@ -23,67 +23,156 @@
A Widget is a 2d section/layer in a soy.window.Window. This is the base
class which all widgets inherit, it has no render functionality.
'''
-
- 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]
+ def __new__(self, parent, margin=None, aspect=0.0,
+ *args, **keywords) :
+ if margin :
+ if type(margin) == int :
+ margin = (margin, margin, margin, margin)
+ if len(margin)!=4 or type(margin[0])!=int or type(margin[1])!=int \
+ or type(margin[2])!=int or type(margin[3])!=int :
+ raise TypeError('margin must be a (int, int, int, int)')
+ self._marginTop = margin[0]
+ self._marginRight = margin[1]
+ self._marginBottom = margin[2]
+ self._marginLeft = margin[3]
+ if aspect > 0.0 :
+ self._aspectRatio = aspect
+ if isinstance(parent, soy._core.Window) :
+ self._window = parent
+ self._parent = None
+ self._xpos = 0
+ self._ypos = 0
+ self._width = self._window._width
+ self._height = self._window._height
+ elif isinstance(parent, StackZ) :
+ self._parent = parent
+ self._window = (<StackZ> self._parent)._window
+ (<StackZ> self._parent)._widgets.lock()
+ (<StackZ> self._parent)._widgets.append(<void *>self)
+ (<StackZ> self._parent)._widgets.unlock()
+ (<StackZ> self._parent)._resize(self._parent._xpos, self._parent._ypos,
+ self._parent._width,
self._parent._height)
+ else :
+ raise TypeError('parent must be either a soy.Window or stacking widget')
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
+ cdef void _resize(self, int _xpos, int _ypos, int _width, int _height) :
+ # _ml = marginLeft, _mb = marginBottom, _mr=marginRight, _mt=marginTop
+ cdef int _ml, _mb, _mr, _mt, _alignSpace
+ cdef float _aspect
+ _ml = _xpos + self._marginLeft
+ _mr = _ml + _width - (self._marginLeft + self._marginRight)
+ _mb = _ypos + self._marginBottom
+ _mt = _mb + _height - (self._marginBottom + self._marginTop)
+ if self._aspectRatio :
+ _aspect = <float> (_mr - _ml) / <float> (_mt - _mb)
+ if _aspect > self._aspectRatio :
+ # Wide aspect == full width, aligned by height
+ self._xpos = _ml
+ self._width = _mr - _ml
+ self._height = <int> (<float> self._width / self._aspectRatio)
+ if self._alignHeight < 0 :
+ self._ypos = _mb
+ else :
+ _alignSpace = (_mt - _mb) - self._height
+ if self._alignHeight == 0 :
+ self._ypos = _mb + (_alignSpace/2)
+ else :
+ self._ypos = _mb + _alignSpace
+ else :
+ # Narrow aspect == full height, aligned by width
+ self._ypos = _mb
+ self._height = _mt - _mb
+ self._width = <int> (self._aspectRatio * <float> self._height)
+ if self._alignWidth < 0 :
+ self._xpos = _ml
+ else :
+ _alignSpace = (_mr - _ml) - self._width
+ if self._alignWidth == 0 :
+ self._xpos = _ml + (_alignSpace/2)
+ else :
+ self._xpos = _ml + _alignSpace
+ else :
+ # No aspect ratio, stretch it to full size
+ self._xpos = _ml
+ self._ypos = _mb
+ self._width = _mr - _ml
+ self._height = _mt - _mb
- 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)
+ property margin :
+ '''Widget's margin
+
+ These are the four margins of the widget respective to it's parent.
+ Values are for the top, right, bottom, and left (as with CSS margin:)
+
+ Defaults to (0, 0, 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')
+ return (self._marginTop, self._marginRight,
+ self._marginBottom, self._marginLeft)
+ def __set__(self, margin) :
+ if type(margin) == int :
+ margin = (margin, margin, margin, margin)
+ if len(margin)!=4 or type(margin[0])!=int or type(margin[1])!=int \
+ or type(margin[2])!=int or type(margin[3])!=int :
+ raise TypeError('margin must be a (int, int, int, int)')
self._window._widgets.lock()
- self._xpos = value[0]
- self._ypos = value[1]
+ self._marginTop = margin[0]
+ self._marginRight = margin[1]
+ self._marginBottom = margin[2]
+ self._marginLeft = margin[3]
self._window._widgets.unlock()
+
- property size :
- '''Widget size
+ property aspect :
+ '''Widget's aspect ratio
- This is the pixel size of the widget in the window.
+ This is the ratio of width:height which, if set, will be maintained.
- Takes an (x,y), defaults to window's full size.
+ Defaults to disabled (0.0)
'''
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()
+ def __set__(self, aspect) :
+ if aspect < 0.0 :
+ raise ValueError('aspect cannot be negetive')
+ self._aspectRatio = aspect
+ def __del__(self) :
+ self._aspectRatio = 0.0
+
+
+ property position :
+ '''Widget's position
+
+ This is the position of the widget reletive to the window.
+ Use the parent, margin, and aspect properties to change this value.
+ '''
+ def __get__(self) :
+ return (self._xpos, self._ypos)
+
+
+ property size :
+ '''Widget's size
+
+ This is the pixel size of the widget. It cannot be set.
+ '''
+ def __get__(self) :
+ return (self._width, self._height)
Modified: trunk/pysoy/src/widgets/soy.widgets.pxd
===================================================================
--- trunk/pysoy/src/widgets/soy.widgets.pxd 2007-07-06 06:45:47 UTC (rev
378)
+++ trunk/pysoy/src/widgets/soy.widgets.pxd 2007-07-06 20:45:07 UTC (rev
379)
@@ -26,15 +26,26 @@
cimport soy._internals
cdef class Widget :
- cdef soy._core.Window _window
- cdef int _xpos
- cdef int _ypos
- cdef int _width
- cdef int _height
- cdef void _render(self)
- cdef void _resize(self)
+ cdef soy._core.Window _window
+ cdef object _parent
+ cdef int _xpos
+ cdef int _ypos
+ cdef int _width
+ cdef int _height
+ cdef int _marginTop
+ cdef int _marginRight
+ cdef int _marginBottom
+ cdef int _marginLeft
+ cdef float _aspectRatio
+ cdef int _alignWidth
+ cdef int _alignHeight
+ cdef void _render(self)
+ cdef void _resize(self, int, int, int, int)
+cdef class StackZ (Widget) :
+ cdef soy._internals.Children _widgets
+
cdef class Canvas (Widget) :
cdef object _texture
cdef soy.bodies._bodies.Vert _verts[4]
@@ -46,5 +57,4 @@
cdef int _connected
cdef float _znear
cdef float _zfar
- cdef float _aspect
Modified: trunk/pysoy/tests/lit_pyramid.py
===================================================================
--- trunk/pysoy/tests/lit_pyramid.py 2007-07-06 06:45:47 UTC (rev 378)
+++ trunk/pysoy/tests/lit_pyramid.py 2007-07-06 20:45:07 UTC (rev 379)
@@ -12,7 +12,7 @@
sce = soy.Scene()
cam = soy.bodies.Camera(sce)
cam.position = (0.0, 0.0, 5.0)
-pro = soy.widgets.Projector(win, size=(320, 240), camera=cam)
+pro = soy.widgets.Projector(win, camera=cam)
pyr = soy.bodies.Pyramid(sce, tex)
pyr.rotation = (1.0, 0.0, 0.0)
lig = soy.bodies.lights.Light(sce)
Modified: trunk/pysoy/tests/tex_canvas.py
===================================================================
--- trunk/pysoy/tests/tex_canvas.py 2007-07-06 06:45:47 UTC (rev 378)
+++ trunk/pysoy/tests/tex_canvas.py 2007-07-06 20:45:07 UTC (rev 379)
@@ -10,8 +10,8 @@
scr = soy.Screen()
win = soy.Window(scr, 'Textured Canvas')
win.background.hex = '#fff'
-can = soy.widgets.Canvas(win, size=(300,220), position=(10,10), texture=tex)
-ca2 = soy.widgets.Canvas(win, size=(280,200), position=(20,20), texture=tex)
+can = soy.widgets.Canvas(win, margin=10, texture=tex)
+ca2 = soy.widgets.Canvas(win, margin=20, texture=tex)
if __name__ == '__main__' :
while True:
Modified: trunk/pysoy/tests/tex_pyramid.py
===================================================================
--- trunk/pysoy/tests/tex_pyramid.py 2007-07-06 06:45:47 UTC (rev 378)
+++ trunk/pysoy/tests/tex_pyramid.py 2007-07-06 20:45:07 UTC (rev 379)
@@ -20,9 +20,9 @@
cam = soy.bodies.Camera(sce)
cam.position = (0.0, 0.0, 5.0)
-ca1 = soy.widgets.Canvas(win, size=(300,220), position=(10,10), texture=lava)
-pro = soy.widgets.Projector(win, size=(280, 200), position=(20,20), camera=cam)
-ca2 = soy.widgets.Canvas(win, size=(64,96), position=(25,25), texture=face)
+ca1 = soy.widgets.Canvas(win, margin=10, texture=lava)
+pro = soy.widgets.Projector(win, camera=cam)
+ca2 = soy.widgets.Canvas(win, aspect=64.0/96.0, texture=face)
pyr = soy.bodies.Pyramid(sce, luma)
pyr.rotation = (1.0, 1.0, 0.0)
_______________________________________________
PySoy-SVN mailing list
[email protected]
http://www.pysoy.org/mailman/listinfo/pysoy-svn