Rounded rectagle actor in clutter
One of the things I required to re-write the macaco-contacts UI in clutter is a rounded corners rectangle, but there is not one!! Well, here is the code you need to implement to have a rounded rectangle rectangle that with the same methods and properties that the normal rectangle has:
import clutter from clutter import cogl class RoundedRectangle(clutter.Actor): """ Custom actor used to draw a rectangle that can have rounded corners """ __gtype_name__ = 'RoundedRectangle' def __init__(self, width, height, arc, step, color=None, border_color=None, border_width=0): """ Creates a new rounded rectangle """ super(RoundedRectangle, self).__init__() self._width = width self._height = height self._arc = arc self._step = step if color: self._color = color else: self._color = clutter.color_from_string("#000") if border_color: self._border_color = border_color else: self._border_color = clutter.color_from_string("#000") 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() # set the color of the filled area cogl.set_source_color(self._color) # 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 self.should_pick_paint() == False: return 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() def get_color(self): return self._color def set_color(self, color): self._color = color self.queue_redraw() def get_border_width(self): return self._border_width def set_border_width(self, width): self._border_width = width self.queue_redraw() def get_border_color(color): return self._border_color def set_border_color(self, color): self._border_color = color self.queue_redraw() stage = clutter.Stage() stage.set_size(400, 400) rect = RoundedRectangle(200, 200, 5, 0.1) rect.set_color(clutter.color_from_string("#123")) rect.set_border_width(5) rect.set_position(12, 12) stage.add(rect) #show everything in the stage stage.show_all() stage.connect("destroy",clutter.main_quit) #main clutter loop clutter.main() |
In this example you can see the two basic things you have to do to be able to create your own actor, the first is implement the do_paint method. In this method you have to do the drawing of your actor, in this case I am drawing the rounded rectangles for the border and the filling using the cogl API. I will later post an other example to render a rounded image with a border so that I can have an simple actor similar to the group I achieved with Pygoocanvas.
The do_pcik method is implemented to ensure that clutter will be able to know when the different events occur on the actor. In this case is a simple method that draws a rounded rectangle with the passed color.
I also have added the code in the macaco wiki and made a branch of python-snippets and submitted if to merge.





Pingback: Rounded rectagle actor in clutter (introspection version) | Macaque Project