Author: ArcRiley Date: 2008-05-15 02:18:01 -0400 (Thu, 15 May 2008) New Revision: 1253
Modified: trunk/pysoy/examples/SplitScreen.py trunk/pysoy/include/soy.widgets.pxd trunk/pysoy/src/_core/Window-w32.pym trunk/pysoy/src/_core/Window-x11.pym trunk/pysoy/src/widgets/Canvas.pym trunk/pysoy/src/widgets/Container.pym trunk/pysoy/src/widgets/StackZ.pym trunk/pysoy/src/widgets/Widget.pym trunk/pysoy/src/widgets/__init__.pym Log: No Ticket : * added many comments * removed Widget.topLevel, added actual typedefs in soy.widgets.pxd * added very crude Python callback support for widget resizing * Container now acts more like a list * cleaned up some docs, cdefs should not be documented Modified: trunk/pysoy/examples/SplitScreen.py =================================================================== --- trunk/pysoy/examples/SplitScreen.py 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/examples/SplitScreen.py 2008-05-15 06:18:01 UTC (rev 1253) @@ -49,5 +49,6 @@ wc = soy.controllers.Window(win) wc['close'] = soy.actions.Quit() -while True : - sleep(1) +if __name__ == '__main__' : + while True : + sleep(1) Modified: trunk/pysoy/include/soy.widgets.pxd =================================================================== --- trunk/pysoy/include/soy.widgets.pxd 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/include/soy.widgets.pxd 2008-05-15 06:18:01 UTC (rev 1253) @@ -26,39 +26,46 @@ cimport soy.colors cimport soy.textures +# +# Forward declarations +# +cdef class Widget +cdef class Container(Widget) + cdef class Widget : - cdef soy._core.Window _window - cdef object _parent - cdef int _topLevel - cdef int _xpos - cdef int _ypos - cdef int _width - cdef int _height - cdef float _aspect - cdef int _marginTop - cdef int _marginRight - cdef int _marginBottom - cdef int _marginLeft - cdef int _alignWidth - cdef int _alignHeight + cdef soy._core.Window _window + cdef Container _parent + cdef int _alignWidth + cdef int _alignHeight + cdef float _aspect + cdef int _marginTop + cdef int _marginRight + cdef int _marginBottom + cdef int _marginLeft + cdef soy._internals.AsyncQueue _queue + cdef int _width + cdef int _height + cdef int _xpos + cdef int _ypos + cdef object _resizeCallback # Helper Functions - cdef int _setMargin(self, object) + cdef int _setMargin(self, object) # _coreLoop Functions - cdef void _render(self) - cdef void _resize(self, int, int, int, int) + cdef void _render(self) + cdef void _resize(self, int, int, int, int) -cdef class Container (Widget) : - cdef soy._internals.Children _widgets - cdef class Canvas (Widget) : - cdef object _texture - cdef soy._datatypes.Vert _verts[4] - cdef soy._datatypes.Face _faces[2] + cdef soy.textures.Texture _texture + cdef soy._datatypes.Vert _verts[4] + cdef soy._datatypes.Face _faces[2] +cdef class Container (Widget) : + cdef soy._internals.Children _widgets + cdef class Projector (Widget) : - cdef soy.bodies.Camera _camera - cdef int _connected - cdef float _znear - cdef float _zfar + cdef soy.bodies.Camera _camera + cdef int _connected + cdef float _znear + cdef float _zfar Modified: trunk/pysoy/src/_core/Window-w32.pym =================================================================== --- trunk/pysoy/src/_core/Window-w32.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/_core/Window-w32.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -224,7 +224,7 @@ # Render each top level widget in order self._widgets._iterStart() for _i from 0 <= _i < self._widgets._current : - if (<soy.widgets.Widget> self._widgets._list[_i])._topLevel: + if (<soy.widgets.Widget> self._widgets._list[_i])._parent is None : (<soy.widgets.Widget> self._widgets._list[_i])._render() self._widgets._iterDone() # @@ -252,7 +252,7 @@ # Resize widgets self._widgets._iterStart() for _i from 0 <= _i < self._widgets._current : - if (<soy.widgets.Widget> self._widgets._list[_i])._topLevel : + if (<soy.widgets.Widget> self._widgets._list[_i])._parent is None : (<soy.widgets.Widget> self._widgets._list[_i])._resize(0, 0, _width, _height) self._widgets._iterDone() Modified: trunk/pysoy/src/_core/Window-x11.pym =================================================================== --- trunk/pysoy/src/_core/Window-x11.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/_core/Window-x11.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -46,7 +46,7 @@ self._controllers = soy._internals.Children() self._widgets = soy._internals.Children() self.title = title - self._iconCanvas = soy.widgets.Canvas() + #self._iconCanvas = soy.widgets.Canvas() if icon : self.icon = icon if background : @@ -100,12 +100,12 @@ cdef void _resize(self, int _width, int _height) : # - # Resize _topLevel widgets whenever the window changes size + # Resize top level widgets whenever the window changes size # cdef int _i self._widgets._iterStart() for _i from 0 <= _i < self._widgets._current : - if (<soy.widgets.Widget> self._widgets._list[_i])._topLevel : + if (<soy.widgets.Widget> self._widgets._list[_i])._parent is None : (<soy.widgets.Widget> self._widgets._list[_i])._resize(0, 0, _width, _height) self._widgets._iterDone() @@ -171,7 +171,7 @@ return # # We need a test for if the icon needs to be rendered here - if 1 : #self._iconCanvas._texture != None : + if 0 : #self._iconCanvas._texture != None : glx.glXMakeCurrent(_display, self._windowID, _glxContext) gl.glViewport(0, 0, 16, 16) gl.glClearColor(0.0, 0.0, 0.0, 1.0) @@ -204,7 +204,7 @@ # Render each top level widget in order self._widgets._iterStart() for _i from 0 <= _i < self._widgets._current : - if (<soy.widgets.Widget> self._widgets._list[_i])._topLevel: + if (<soy.widgets.Widget> self._widgets._list[_i])._parent is None : (<soy.widgets.Widget> self._widgets._list[_i])._render() self._widgets._iterDone() # Modified: trunk/pysoy/src/widgets/Canvas.pym =================================================================== --- trunk/pysoy/src/widgets/Canvas.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/widgets/Canvas.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -46,6 +46,29 @@ def __cinit__(self, parent=None, margin=None, aspect=-1.0, texture=None, *args, **keywords) : + ###################################### + # + # Pass arguments to properties + # + self.texture = texture + if aspect < 0.0 : + self._aspect = (<soy.textures.Texture> self._texture)._aspect + # + ###################################### + # + # Static Vertex and Face Array + # + # self._verts[0] = (0,0) - no change needed + # self._verts[1] = (1,0) - change X to 1.0 + # self._verts[2] = (1,1) - change both X and Y to 1.0 + # self._verts[3] = (0,1) - change Y to 1.0 + # + # Thus, these verts form a 1x1 square with 2 tris (A and B) : + # 3----2 + # | B/ | + # | /A | + # 0----1 + # self._verts[1].px = 1.0 self._verts[1].tx = 1.0 self._verts[2].px = 1.0 @@ -60,51 +83,78 @@ self._faces[1].a = 2 self._faces[1].b = 3 self._faces[1].c = 0 - if isinstance(texture, soy.textures.Texture) or texture == None : - self._texture = texture - if aspect < 0.0 : - self._aspect = (<soy.textures.Texture> self._texture)._aspect + # + ###################################### + ############################################################################ # # C functions # cdef void _render(self) : - if not self._texture : + ###################################### + # + # Enable the texture, or don't bother rendering + # + if self._texture is None : return - (<soy.textures.Texture> self._texture)._enable() - - if (<soy.textures.Texture> self._texture)._chans & 1: + self._texture._enable() + # + ###################################### + # + # Enable blending if texture has an alpha channel (LA or RGBA) + # + if self._texture._chans & 1: gl.glDisable(gl.GL_BLEND) else: gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) - + # + ###################################### + # + # Set the viewport to the current Widget position and size + # gl.glViewport(self._xpos, self._ypos, self._width, self._height) + # + ###################################### + # + # Reset the projection and modelview matrix, set ortho rendering + # gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() - + # + ###################################### + # + # VBO-ONLY: Unbind buffers + # if gl.GLEW_ARB_vertex_buffer_object : gl.glBindBufferARB (gl.GL_ELEMENT_ARRAY_BUFFER_ARB, 0) gl.glBindBufferARB (gl.GL_ARRAY_BUFFER_ARB, 0) - + # + ###################################### + # + # Set vertex, normal, and texcoord pointers and draw + # gl.glVertexPointer (3, gl.GL_FLOAT, 48, &self._verts[0].px) gl.glNormalPointer ( gl.GL_FLOAT, 48, &self._verts[0].nx) gl.glTexCoordPointer(3, gl.GL_FLOAT, 48, &self._verts[0].tx) - gl.glDrawElements (gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_SHORT, <unsigned short*> self._faces) - - if (<soy.textures.Texture> self._texture)._chans & 1: - pass - else: + # + ###################################### + # + # Disable blending when using alpha texture, disable texture, and return + # + if not self._texture._chans & 1 : gl.glDisable(gl.GL_BLEND) + self._texture._disable() + # + ###################################### - (<soy.textures.Texture> self._texture)._disable() ############################################################################ # @@ -124,9 +174,8 @@ return None def __set__(self, value) : if isinstance(value, soy.textures.Texture) or value == None : - self._texture = value + self._texture = value else : raise TypeError('that is not a texture') def __del__(self) : self._texture = None - Modified: trunk/pysoy/src/widgets/Container.pym =================================================================== --- trunk/pysoy/src/widgets/Container.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/widgets/Container.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -27,31 +27,6 @@ L{Container} classes manage the positioning of the widgets they contain. They also propogate the C{_render} method calls to their contained L{Widgets}. - - Type Methods - ============ - - __cinit__ - --------- - - This initializes the internal list of L{Widgets} as a new - L{soy._internals.Children}. - - _resize - ------- - - This method should be overridden in subclasses to calculate the - new sizes and positions of the child L{Widgets} within the - region described by the passed position and size. NOTE: The _x - and _y parameters passed are always relative to the origin of - the top-level L{Window} containing the L{Widget}, and not to the - containing L{Widget}. - - _render - ------- - - This should be overridden if necessary to pass the _render call - along to child L{Widget}s. """ ############################################################################ @@ -61,29 +36,80 @@ def __cinit__(self, parent=None, margin=None, aspect=-1.0, *args, **keywords) : + ###################################### + # + # self._widgets holds the ordered Children + # self._widgets = soy._internals.Children() + # + ###################################### - # This is the same resizing method used in StackZ, which - # effectively makes Container the same as StackZ, for now. - # Maybe this should be removed. - cdef void _resize(self, int _x, int _y, int _width, int _height) : - cdef int _i - Widget._resize(self, _x, _y, _width, _height) - self._widgets._iterStart() - for _i from 0 <= _i < self._widgets._current : - (<Widget> self._widgets._list[_i])._resize(self._xpos, self._ypos, - self._width, self._height) - self._widgets._iterDone() + def __getitem__(self, int _index) : + ###################################### + # + # if _index is <0, it's right-aligned, realign to the left + # + if _index < 0 : + _index = _self._widgets._current + _index + # + ###################################### + # + # raise an error if _index is out of range + # + if _index < 0 or _index >= self._widgets._current : + raise IndexError('widget index out of range') + # + ###################################### + # + # return the widget at the specified index + # + return <Widget> self._widgets._list[_index] + # + ###################################### + + def __len__(self) : + ###################################### + # + # return the number of widgets contained + # + return self._widgets._current + # + ###################################### + + + def __repr__(self) : + cdef object _name + ###################################### + # + # use the name of whatever class this is called + # + _name = self.__class__.__name__ + if self._window : + return '<%s in Window #%d with %d children>' % (_name, + self._window._windowID, + self._widgets._current) + else : + return '<%s with %d children>' % (_name, self._widgets._current) + # + ###################################### + + ############################################################################ # - # C functions + # WindowLoop functions # - cdef void _render(self): + cdef void _render(self) : cdef int _i + ###################################### + # + # render each child in sequence + # self._widgets._iterStart() for _i from 0 <= _i < self._widgets._current: (<Widget> self._widgets._list[_i])._render() self._widgets._iterDone() + # + ###################################### Modified: trunk/pysoy/src/widgets/StackZ.pym =================================================================== --- trunk/pysoy/src/widgets/StackZ.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/widgets/StackZ.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -26,6 +26,7 @@ closer children are drawn after farther children. """ + ############################################################################ # # C functions Modified: trunk/pysoy/src/widgets/Widget.pym =================================================================== --- trunk/pysoy/src/widgets/Widget.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/widgets/Widget.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -139,29 +139,41 @@ def __cinit__(self, parent=None, margin=None, aspect=-1.0, *args, **keywords) : + ###################################### + # + # self._queue is a handle to the EventLoop callback queue + # + self._queue = soy._internals._getQueue() + # + ###################################### + # + # default self.resize to None + # + self._resizeCallback = None + # + ###################################### if not self._setMargin(margin) : raise TypeError('margin must be a (int, int, int, int)') if aspect > 0.0 : self._aspect = aspect if parent == None : + self._parent = None self._window = None - self._parent = None self._resize(0, 0, 16, 16) elif isinstance(parent, soy._core.Window) : + self._parent = None self._window = parent - self._parent = None - self._topLevel = 1 self._resize(0, 0, self._window._width, self._window._height) self._window._widgets._append(<void*> self) elif isinstance(parent, Container) : self._parent = parent - self._window = (<Container> self._parent)._window + self._window = self._parent._window self._window._widgets._append(<void*> self) - (<Container> parent)._widgets._append(<void*> self) - (<Container> parent)._resize((<Container> parent)._xpos, - (<Container> parent)._ypos, - (<Container> parent)._width, - (<Container> parent)._height) + self._parent._widgets._append(<void*> self) + 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') @@ -169,18 +181,19 @@ def __dealloc__(self) : if self._window : self._window._widgets._remove(<void*> self) - if self._parent != None : - (<Container> self._parent)._widgets._remove(<void*> self) + if self._parent is not None : + self._parent._widgets._remove(<void*> self) def __repr__(self) : cdef object _name _name = self.__class__.__name__ if self._window : - return '<%s in Window id %d>' % (_name, self._window._windowID) + return '<%s in Window #%d>' % (_name, self._window._windowID) else : return '<%s>' % (_name) + ############################################################################ # # C functions @@ -213,16 +226,28 @@ 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 + cdef int _ml, _mb, _mr, _mt, _alignSpace _ml = _xpos + self._marginLeft _mr = _ml + _width - (self._marginLeft + self._marginRight) _mb = _ypos + self._marginBottom _mt = _mb + _height - (self._marginBottom + self._marginTop) + # + ###################################### + # + # with an aspect ratio, calculate new size to match it + # if self._aspect : - _aspect = <float> (_mr - _ml) / <float> (_mt - _mb) - if _aspect < self._aspect : - # Wide aspect == full width, aligned by height + ################################## + # + # check aspect ratio of available size vs target aspect ratio + # + # if available size is wider, use full width and align within height + # else (it's narrower), align by width and use full height + # + if (<float> (_mr - _ml) / <float> (_mt - _mb)) < self._aspect : + # + # Wide aspect: full width, aligned by height + # self._xpos = _ml self._width = _mr - _ml self._height = <int> (<float> self._width / self._aspect) @@ -235,7 +260,9 @@ else : self._ypos = _mb + _alignSpace else : - # Narrow aspect == full height, aligned by width + # + # Narrow aspect: full height, aligned by width + # self._ypos = _mb self._height = _mt - _mb self._width = <int> (self._aspect * <float> self._height) @@ -247,13 +274,42 @@ self._xpos = _ml + (_alignSpace/2) else : self._xpos = _ml + _alignSpace + # + ###################################### + # + # if there's no aspect ratio, stretch to full available size + # else : - # No aspect ratio, stretch it to full size self._xpos = _ml self._ypos = _mb self._width = _mr - _ml self._height = _mt - _mb + # + ###################################### + # + # if no resize callback has been set, return now + if self._resizeCallback is None : + return + # + ###################################### + # + # manually INCREF the callback since we're passing it as void* + # it'll be DECREF'ed by the EventLoop thread after execution + # + py.Py_INCREF(self._resizeCallback) + # + ###################################### + # + # add self.resize (self._resizeCallback) to EventLoop's callback queue + # In most cases the EventLoop thread is waiting for a function to be + # added to the queue so this will often be executed immediately. + # + self._queue._push(<void*> self._resizeCallback) + # + ###################################### + + ############################################################################ # # Properties @@ -333,6 +389,13 @@ return (self._xpos, self._ypos) + property resize : + def __get__(self) : + return self._resizeCallback + def __set__(self, value) : + self._resizeCallback = value + + property size : """ Dimensions of L{Widget} in pixels. This is calculated internally Modified: trunk/pysoy/src/widgets/__init__.pym =================================================================== --- trunk/pysoy/src/widgets/__init__.pym 2008-05-14 03:17:56 UTC (rev 1252) +++ trunk/pysoy/src/widgets/__init__.pym 2008-05-15 06:18:01 UTC (rev 1253) @@ -23,3 +23,5 @@ '$Date$'[7:-20]+ \ 'by '+'$Author$'[9:-2] __version__ = 'Trunk (r'+'$Rev$'[6:-2]+')' + +cimport py _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn