|
From: Rowland S. <ro...@we...> - 2001-12-03 23:44:11
|
I thought about some issues with doing a component model today. I'm
thinking ahead to the model requirements that are necessary to support
visual tools.
We need to provide metadata about the attributes and methods of any
PythonCard component, as well as packaging the spec with the class that
it describes, as Jeff Turner suggested. Putting each component in it's
own module is helpful for managing the components ( drop them in a
directory ) as well as for organization - a component's module can
contain the component class itself as well as any support classes and
resources.
We need to add type information to both attribute and method definitions
for visual tool support:
For attributes:
name, type
For methods:
name, # args, <arg-name, arg-type>, <return-type>
For example, right now we have the following in Button's spec.
'label' : { 'presence' : 'mandatory' }
This would become something like
'label' : { 'type' : 'string', 'presence' : 'mandatory' }
We then add a new section called 'methods'. Each method entry contains
the name of the method, followed by an ordered list of args. each arg
specifies the arguments name and type. A 'returns' element specifies the
return type, where None is like void in Java/C.
'SetLabel' : {
'args' : [ { 'name' : 'label', 'type' : 'string' } ],
'returns' : None
}
Also, we might want to think about using XML as the spec format. Kevin
mentioned supporting the wxWindows XML format. I don't know if we could
support it directly, but we could provide a translator that converted a
wxWindows spec to a PythonCard spec.
XML is obviously more verbose, but at least it's self-describing, and
that can be a plus.
I have an alternative framework that i'm using to test component
registration, as well as a component model for PythonCard. Below is an
example for a Button component that extends wxPython and is self contained.
Button inherits component behavior from widget.Widget ( which extends
component.Component, not shown ), and extends a wxPython Button.
A single event is defined, 'mouseClick'.
The component has a single attribute, 'label', of type 'string'.
A new class attribute, 'methods', has been added to define a component's
public interface.
each method is described by name, argument names and types, and return type.
It's not shown below, but it might also be helpful to explicitly define
whether a method is a getter/setter for a particular attribute. This
could be inferred from the method name, but might not work in all cases.
This would be useful for auto-magically binding dot notation for
attributes.
----------
from wxPython.wx import *
import widget
wxCLIP_SIBLINGS = 0x20000000
class Button( widget.Widget, wxButton ) :
"""
A simple push-button with a label.
"""
events = [ 'mouseClick' ]
attributes = {
'label' : { 'type' : 'string', 'presence' : 'mandatory' }
}
methods = {
'SetLabel' : {
'arguments' : [ { 'name' : 'label', 'type' : 'string' } ],
'returns' : None
}
}
def __init__( self, parent, resource ) :
widget.Widget.__init__( self, parent, resource )
r = resource
wxButton.__init__( self,
self.parent,
self.getId(),
r.label,
wxPoint( r.position[ 0 ], r.position[ 1 ] ),
wxSize( r.size[ 0 ], r.size[ 1 ] ),
style = wxCLIP_SIBLINGS,
name = r.name )
self._bindEvents()
def _bindEvents( self ) :
EVT_BUTTON( self.parent, self.getId(), self._dispatchClicked )
def _dispatchClicked( self, event ) :
self.fireEvent( 'mouseClicked', event )
---------------
--
Talk to ya,
Rowland
"The whole problem with the world is
that fools and fanatics are always so
certain of themselves, and wiser people
so full of doubts."
-- Bertrand Russell,
quoted in the book
A Word a Day
|