Rounded rectangle actor in clutter (introspection version)

by mandel on April 5th, 2011

A while back I posted an example of how to create a rounded rectangle actor with clutter using the Python bindings. Last night I started to write a small UI in which I’m using Clutter and wanted to get the same effect but this time I used gobject introspection. The differences are not huge but nevertheless here you have the example code of the same exercise using gi.

from gi.repository import Cogl, Clutter, GtkClutter
 
class RoundedRectangle(GtkClutter.Actor):
    """Base actor for a rounded retangle."""
 
    def __init__(self, width, height, arc, step, 
                 color=None, border_color=None, border_width=0):
        """Create a new instance."""
        super(RoundedRectangle, self).__init__()
        self._width = width
        self._height = height
        self._arc = arc
        self._step = step
        if color:
            self._color = color
        else:
            self._color = Cogl.Color()
            self._color.init_from_4f(0, 0, 0, 1)
        if border_color:
            self._border_color = border_color
        else:
            self._border_color = Cogl.Color()
            self._border_color.init_from_4f(0, 0, 0, 1)
        self._border_width = border_width
 
    def do_paint(self):
        # Draw a rectangle for the clipping
        Cogl.path_round_rectangle(0, 0, self._width, self._height, self._arc, self._step)
        Cogl.path_close()
        # Start the clip
        Cogl.clip_push_from_path()
        # set color to border color
        Cogl.set_source_color(self._border_color)
        # draw the rectangle for the border which is the same size and the
        # object
        Cogl.path_round_rectangle(0, 0, self._width, self._height, self._arc, self._step)
        Cogl.path_close()
        # color the path usign the border color
        Cogl.path_fill() 
        # draw the content with is the same size minus the wirth of the border
        # finish the clip
        Cogl.path_round_rectangle(self._border_width, self._border_width, 
        self._width - self._border_width, 
        self._height - self._border_width, self._arc, self._step)
        Cogl.path_fill() 
        Cogl.path_close()
        Cogl.clip_pop()
 
    def do_pick(self, color):
        if not self.should_pick_paint():
            return
        # do pick gets a Clutter color but no a Cogl one, we need to convert it
        color = Cogl.Color()
        color.init_from_4f(color.red , color.green , color.blue , color.alpha)
        Cogl.path_round_rectangle(0, 0, self._width, self._height, self._arc, self._step)
        Cogl.path_close()
        # Start the clip
        Cogl.clip_push_from_path()
        # set color to border color
        Cogl.set_source_color(color)
        # draw the rectangle for the border which is the same size and the
        # object
        Cogl.path_round_rectangle(0, 0, self._width, self._height, self._arc, self._step)
        Cogl.path_close()
        Cogl.path_fill() 
        Cogl.clip_pop()

I’ve got to say, that although introspection does bring a great opportunity for Python developers to get to the gobject libraries easiyly, it does make the Python code look very un-pynthonic…