This tuto­r­ial is out­dated: it refers to ver­sion 0.4 of clut­ter that now is VERY old.

Last time we learned how to have our first stage drawn, so now it’s time to begin to insert some­thing into that stage.

Let do a sum­mary of what we are going to do in this “lesson”:

  • change the stage’s color
  • add a rectangle to the stage
  • add another rectangle to the stage

The first thing we want to do is to change the stage’s color. This can be done by using the set_color() method of the stage object:

    stage.set_color(clutter.color_parse("#00000"))

In this way we have a black stage. But how does it works? The set_color() method needs a Clut­ter­Color object in input, and we can have it by call­ing the color_parse() func­tion. The color_parse() has the same syntax of pango_color_parse() (a built-​in GTK func­tion), so it accepts both hexa­dec­i­mal spec­i­fi­ca­tions of the color (i.e.: #000000 or #000 for black, #FF0000 or #F00 for red) and lit­eral color values like “black” or “red”. Addi­tion­ally, we can spec­ify a pixel alpha value (the object’s opac­ity level) by using a hexa­dec­i­mal spec­i­fi­ca­tion like #000000FF, where FF is the alpha value. We can spec­ify an alpha value for the stage but it won’t work since the stage hasn’t a alpha layer.

After this, our window will look like this:

Example 02: a newly created stage with a specified color

Note that now the window became black as we spec­i­fied. Now that we com­pleted the first goal, it’s time for us to intro­duce a new clut­ter object: the rectangle.

A rec­tan­gle is made up by the rec­tan­gle itself and a border. That said, if we tell clut­ter to draw a 100x100px rec­tan­gle with a 2px border, the result­ing rec­tan­gle will be 2px + 100px + 2px large.

Now that we had enough theory, we can begin to draw our first rectangle:

import clutter

def main():
    stage = clutter.stage_get_default()
    stage.set_size(500, 500)
    stage.set_color(clutter.color_parse("#000000"))

    rect = clutter.Rectangle()
    rect.set_position(20, 20)
    rect.set_size(200, 300)
    rect.set_color(clutter.color_parse("#A02020"))

    stage.add(rect)

    rect.show()
    stage.show()

    stage.connect("key-press-event", clutter.main_quit)
    clutter.main()

if __name__ == '__main__':
    main()

This code will give us this output:

Example 03: a window with a red rectangle

And now it’s time to ana­lyze what we done by look­ing at the code line per line (I’ll skip the lines that we already seen):

    rect = clutter.Rectangle()

In order to draw a rec­tan­gle we need an instance of the rec­tan­gle object, right? We can get this instance by call­ing the Rectangle con­struc­tor function.

Once we have our rec­tan­gle instance, we can make oper­a­tions like posi­tion­ing and col­or­ing on it:

    rect.set_position(20, 20)
    rect.set_size(200, 300)
    rect.set_color(clutter.color_parse("#A02020"))

The first line moves the upper left corner of the rec­tan­gle at posi­tion (20, 20) in the stage. The second and the third line, instead, are func­tions that we have already seen: both the rec­tan­gle’set_size() and set_color() func­tions works exactly as the stage’s one (we’ll see fur­ther in another part of this tuto­r­ial why the name and the imple­men­ta­tion is the same). Indeed, in this way we can spec­ify both a size and a color for our rectangle.

    stage.add(rect)

We drawn our rec­tan­gle, but now we need to tell clut­ter where to put it: this is done by using the add() method of the stage object (if this oper­a­tion looks use­less to you it’s because we still didn’t talked about Groups and Box; we’ll do that another time, now just take this line as is).

The last line of inter­est is this one:

    rect.show()

We’ve already explained in the pre­vi­ous part how the show() method works for the stage: here’s is exactly the same thing.

Now that we have our first rec­tan­gle, is time to draw the second one:

import clutter

def main():
    stage = clutter.stage_get_default()
    stage.set_size(500, 500)
    stage.set_color(clutter.color_parse("#000000"))

    rect1 = clutter.Rectangle()
    rect2 = clutter.Rectangle()

    rect1.set_position(20, 20)
    rect1.set_size(200, 300)
    rect1.set_color(clutter.color_parse("#A02020"))

    rect2.set_position(50, 100)
    rect2.set_size(350, 300)
    rect2.set_color(clutter.color_parse("#FFFFFF50"))
    rect2.set_border_width(20)
    rect2.set_border_color(clutter.color_parse("blue"))

    stage.add(rect1, rect2)

    rect1.show()
    rect2.show()
    stage.show()

    stage.connect("key-press-event", clutter.main_quit)
    clutter.main()

if __name__ == '__main__':
    main()

We’ll obtain this:

Example 04: two rectangles

(if you see the second rectangle’s border par­tially drawn, or not drawn at all, you are prob­a­bly using a ver­sion of clut­ter older than 0.4.2, where a bug in the border gen­er­a­tion deny you from having the rec­tan­gle shown correctly)

We’ve already dis­cussed many of the func­tions in the code above, so I’ll quickly jump to the more com­plex part. First of all, let do a resume of what we do in this script:

  1. we create the first rectangle named rect1
  2. we create the second rectangle named rect2
  3. we set up properties for both rectangles (please note that for the second rectangle we specified a pixel alpha value too)
  4. then we add the rectangle to the stage and show them

The only thing I should explain is the point number four: the add method of a con­tainer (a stage, in this case), can have mul­ti­ple argu­ments. Indeed, we can tell clut­ter to add mul­ti­ple ele­ments to a con­tainer. So in our exam­ple, we added both rect1 and rect2 in a single line of code instead of having two sep­a­rate add statements.

After having the actors added to the stage, we show them by call­ing the show() method on every single actor. This approach works, but some­times could be more useful (and time saving) to call a spe­cial show method on the parent. We’ll dis­cuss this behav­iour better when we’ll talk about groups, but by now on I’ll use the show_all() method on the stage in order to show all its chil­dren in one line of code.

See you for the next part of this tutorial :)