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

Reply via email to