Jump to: navigation, search

Clutter on BeagleBone

This is a work in progress!

Toggle uses Clutter for making the GUI. In order to develop or even run the python examples, there are a few packages that need to be present. I will try to get the dependencies right eventually, but for now, these are the packages I think you need:

Prepare the BeagleBone for Clutter

Get the Thing Image

The Thing image has everything you need to get started writing clutter apps on BBB: [link to latest Thing BBB flasher]

Install the required packages

These packages are needed in order to compile Clutter apps written in C:

 opkg install libclutter-1.0-dev libglib-2.0-dev systemd-dev

There is a quirk here causing the libclutter package to fail. Just try running the command again.

If you want to use Python, add these:

 opkg install libgirepository-1.0-1 python-pygobject pango-dev libatk-1.0-dev 

To use MX-widgets add this:

 opkg install libmx-2.0-dev

If you want to load models with Mash, try this:

 opkg install libmash-0.2-dev

Quirks that need to be handled

None at the time.

Hello world using Clutter on BeagleBone Black - Python code

The following example will init the stage, add a red rectangle in the top left corner and enter the main loop. The example has been made has been made for BeagleBone Black without a window manager, so there is no setting of window size or close button etc.

#!/usr/bin/env python2
#! -*- coding: utf-8 -*-

from gi.repository import Clutter
Clutter.init(None)
stage = Clutter.Stage()

rect = Clutter.Rectangle()
rect.set_size(100, 50)
rect.set_position(100, 100)
red = Clutter.Color.get_static(Clutter.StaticColor.RED)
rect.set_color(red)
stage.add_actor(rect)

stage.show()

Clutter.main()

Capture keypress

def on_key_press_event(stage, event):
  print "keyevent ", event.keyval

# key-press-event is for the keyboard
stage.connect("key-press-event", lambda s, e: on_key_press_event(s, e))

Mouse button press

 def on_button_press_event(stage, event):
     print "mouse button %d pressed at (%d, %d)"%(event.button, event.x, event.y)
 
 # mouse-button-press 
 stage.connect("button-press-event", lambda s, e: on_button_press_event(s, e))

Animation

All transformations done after stage.show() has been called will will be animated with a a duration of 250 ms. The default duration of the animation can be changed with actor.set_easing_duration(int) For example, to rotate a rectangle with animation 90 degrees:

 stage.show()
 rect.set_rotation_angle(Clutter.RotateAxis.Z_AXIS, 90.0)

Adding widgets with Mx

Mx is a widget library made for Clutter. Here is a hello world example where a button is added to the stage:

#!/usr/bin/env python2
#! -*- coding: utf-8 -*-

from gi.repository import Clutter, Mx
Clutter.init(None)
stage = Clutter.Stage()

button = Mx.Button()
button.set_label("Hello")
button.set_position(100, 100)
stage.add_actor(button)

stage.show()
Clutter.main()

Building a GUI with ClutterScript

A large part of making a GUI application is the layout of the app. To simplify this, clutter has a plugin called ClutterScript where you can define the GUI using JSON. If you are not familiar with JSON, it's basically a a format for defining datatypes and hierarchies, similar to XML. There are several methods for getting the structure in, here is an example using a separate file:

#!/usr/bin/env python2
#! -*- coding: utf-8 -*-

from gi.repository import Clutter

if __name__ == '__main__':
    Clutter.init(None)

    script = Clutter.Script()
    script.load_from_file("ui.json")
    stage = script.get_object("stage")
    script.connect_signals(stage)

    stage.show()
    Clutter.main()

Here is the ui.json file:

[
  {
    "id" : "stage",
    "type" : "ClutterStage",
    "color" : "#CCC",
    "children" : [ "box" ],
    "signals" : [
      { "name" : "destroy", "handler" : "clutter_main_quit" }
    ]
  },

  {
    "id" : "box",
    "type" : "ClutterBox",
    "width" : 400,
    "height" : 240,
        "color": "red",
    "rotation" : [
        { "z-axis" : 45}
    ],
    "layout-manager" : {
      "type" : "ClutterFixedLayout"
    },

    "children" : [
        {
            "type" : "ClutterText",
            "text" : "Hello",
            "x": 40,
            "y": 60
        }
    ]
  }
]

Using Mx widgets together with ClutterScript

If you want to use Mx widgets with clutterscript, the Mx library has to be loaded before importing the JSON script. Try this:

 mxDummy = Mx.Button()

Then the JSON script can be loaded.

Listing input devices

If you want to list the devices discovered by Clutter, run this example:

#!/usr/bin/env python2

from gi.repository import Clutter                
Clutter.init(None)

dm = Clutter.DeviceManager.get_default()
for inp in dm.list_devices(): 
   print inp.get_device_type()

C example

Here is a hello world using C:

#define COGL_ENABLE_EXPERIMENTAL_2_0_API

#include <clutter/clutter.h>
#include <stdlib.h>

ClutterActor *rect;
gdouble rotation = 0;

void on_timeline_new_frame(ClutterTimeline *timeline, gint frame_num, gpointer data) {
        rotation += 0.3;

        clutter_actor_set_rotation(rect, CLUTTER_Z_AXIS, rotation * 5, 0, 0, 0);
}

int main(int argc, char *argv[]) {
        int ret;
        ret = clutter_init(&argc, &argv);

        ClutterColor stage_color = { 0xFF, 0xFF, 0xFF, 0xFF };
        ClutterColor actor_color = { 0x00, 0xCC, 0x00, 0xFF };

        ClutterActor *stage = clutter_stage_new();
        clutter_actor_set_size(stage, 800, 480);
        clutter_actor_set_background_color(stage, &stage_color);

        /* Add a rectangle to the stage: */
        rect = clutter_actor_new();
        clutter_actor_set_background_color (rect, &actor_color);
        clutter_actor_set_size (rect, 100, 50);
        clutter_actor_set_position (rect, 20, 20);
        clutter_actor_add_child (stage, rect);
        clutter_actor_show (rect);

        ClutterTimeline *timeline = clutter_timeline_new(60);
        g_signal_connect(timeline, "new-frame", G_CALLBACK(on_timeline_new_frame), NULL);
        clutter_timeline_set_loop(timeline, TRUE);
        clutter_timeline_start(timeline);

        clutter_actor_show(stage);

        clutter_main();

        return EXIT_SUCCESS;
}

This can be compiled by writing the following:

 gcc -o example example.c `pkg-config clutter-egl-1.0 --libs --cflags`

Linkses