It is possible to create your own node classes in python and insert them into libavg scenes. This is a powerful abstraction mechanism, because it allows you to define reusable visual and user interface elements easily. libavg does this internally in several cases: Several of the more specific node classes like RoundedRect and Keyboard are implemented in pure python.

Basic Example

Node subclassing is very similar to standard python subclassing. Here is a rectangle that contains some text as a class:

 2class TextRect(avg.DivNode):
 3    def __init__(self, text, parent=None, **kwargs):
 4        super(TextRect, self).__init__(**kwargs)
 5        self.registerInstance(self,parent)
 6        self.rect = avg.RectNode(size=self.size, 
 7                fillopacity=1, fillcolor="000000", 
 8                color="FFFFFF", parent=self)
 9        self.words = avg.WordsNode(color="FFFFFF", 
10                text=text, alignment="center", 
11                parent=self)
12        self.words.pos = (self.size-(0,self.words.size.y)) / 2

As you can see, TextRect is derived from DivNode. The constructor takes any arguments specific to TextRect, forwards all other keyword arguments (**kwargs) to the base class and calls registerInstance() on itself to set up the C++ base class properly. It then creates the child nodes, centering the text inside the rectangle.

Node Properties

By default, any attributes of the base class are accessible when using the derived class:

1textRect.size += (10,10)

In this example, however, the result of the call would be that the TextRect itself is resized, but the rect and words nodes inside aren't. To fix this, you need to override the property:

 2class TextRect(avg.DivNode):
 4    def getSize(self):
 5        return self.__divSize
 7    def setSize(self, size):
 8        self.rect.size = size
 9        self.words.pos = (size-(0,self.words.size.y)) / 2
10        self.__divSize = size
11    __divSize = avg.DivNode.size
12    size = property(getSize, setSize)

This is a standard python property definition, with the caveat that the base class property needs to remain accessible - hence the __divSize class variable.