by Greg DeKoenigsberg

Last time, we talked about installing Sugar so that you could emulate the OLPC environment on your system. Now it’s time to explore how activities work on the XO.

Finding your activities

Let’s assume that you’ve installed Sugar on your system in /tmp/SUGAR. One level down, you’ll find a directory called build, which replicates much of the file system of the XO — or at least the parts that Sugar needs to work. The activities themselves would be found in /tmp/SUGAR/build/share/activities. This corresponds to the path /usr/share/activities on an actual XO.

Activities are structured very simply. That’s by design. The simpler the activity structure, the more likely it is that kids will be able to modify existing activities and create new ones. Let’s take a quick look at the simplest of all activities: HelloWorld.

This is the basic structure of an activity. There’s the activity code itself, in this case HelloWorldActivity.py; there’s a boilerplate setup.py script that bundles the activity for redistribution; and then there’s the activity directory, where all metadata about the activity is stored. Looking into the activity, we see:

service_name uniquely identifies this activity with a namespace identifier, which should be particularly familiar to Java developers. One should also perhaps expect to find the latest version of the activity at the listed namespace, but this has not yet been formalized.

class refers to the class that will be invoked when the activity is started from the frame; in this case, we see that Sugar will look in HelloWorldActivity.py for the Python class HelloWorldActivity.

icon specifies the icon file to be used: in this case, the activity-helloworld.svg file we saw previously.

For simplicity’s sake, activity_version will always be an integer. If two activities are trying to share, and one has a greater activity version, the old activity should simply be able to replace itself with the new activity.

show_launcher specifies whether or not the activity will be available in the Sugar frame. As we see here, HelloWorld is available.

Next, let’s examine the activity code itself from HelloWorldActivity.py, with lots of comments inline in the code. If you’re familiar with PyGTK — and if you want to write Sugar activities, you should be — then a lot of this code will look familiar. To learn more about PyGTK, check out the excellent tutorial at pygtk.org.

def __init__(self, handle):
activity.Activity.__init__(self, handle)
# Creates a new button with the label "Hello World".
self.button = gtk.Button("Hello World")
# When the button receives the "clicked" signal, it will call the
# function hello() passing it None as its argument. The hello()
# function is defined above.
self.button.connect("clicked", self.hello, None)
# This packs the button into ourselves (a Sugar window).
self.add(self.button)
# The final step is to display this newly created widget.
self.button.show()
self.set_title('Hello World')

HelloWorld activity with frame view. The whole screen is a clickable button.

Note that logs can be viewed in the developer console (Alt-0 opens it). The developer console is very useful, with all logs kept in one place. We can see the entry for the button push in the HelloWorld log:

Developer console for Sugar.

It’s useful to have access to the logs after your Sugar session is over, though. Logs are kept in the .sugar directory in your homedir:

So what’s the difference, then, between writing a Sugar activity and a PyGTK desktop application? Not a lot of difference, really — but there are a couple of key points to remember.

First of all, a Sugar activity has no dependencies on other activities. None. At all. As any user of RPM and/or dpkg knows, dependencies bring bloat. At a svelte 128M of memory, bloat is a luxury that the XO cannot afford. Besides, dependency resolution is an unwelcome bump in the user experience. If a kid wants to run that cool music activity right now, the last thing he should have to see is a dialogue that says, “coolmusicactivity requires sdl and csound-devel: download now?”

There are some tradeoffs to this approach. It means that the activity developer is strongly tied to the libraries that ship with the XO by default; if particular libraries are not available, the developer must ship them as part of the activity. One might argue that this approach causes bloat as well, since the same library might be present in a whole bunch of different activities. Ideally, that shouldn’t be much of a problem; it should be simple to discard activities that aren’t being used, and then download them again when they are needed. That’s the goal, anyway.

The second thing to consider is the fundamental interactivity requirement for activities. Activities should be designed to be shared, and the process for sharing should be trivial. If a child sees a friend playing a neat new game, she should be able to click on that friend in her neighborhood view, receive her game code, and join in the game, immediately. In fact, Sugar practically demands this “share-ability”, as we see from the following graphic:

Share HelloWorld with a friend (even though the code doesn’t know how.)

Our version of HelloWorld can not currently be shared. There’s no code in it that allows sharing. But the “share” link is still present, and will always be present — which means that, ultimately, a good “HelloWorld” example will include sharing.

We’re not quite there yet. A lot of the details around activity sharing are still being hammered out, but when those details are worked out, we’ll bring them to you.

Next time, we’ll look at an activity with a bit more meat. Until then, happy hacking. In the meantime, here’s some great reading about Sugar from the OLPC wiki:

This entry was posted by Greg DeKoenigsberg
on Monday, March 26th, 2007 at 7:48 am and is filed under One Laptop per Child.
You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.

I haven’t played much with QEMU myself, so I don’t know much about moving files between guest and host — but from the cursory research I’ve done, it ain’t exactly simple. Does networking work in your QEMU instance? There should be an ssh client in build 303.

I found a way, maybe not the most elegant, but it works and it’s fairly easy. I do all my development in the host, then I post it in my webserver. I then download it with the browser in sugar, and I used it from there….

I have been trying to create an Activity on my XO laptop. What I want this activity to do is be launched from the Journal, just like the Read activity is. I’ll associate files in the Journal with a MIME type so that when the user resumes files of this type my application will be launched. That part I have working. I also have a Python script that works standalone from the terminal window, so that’s working. I’ve adapted the script so that it is a launchable activity. What I’m missing is a way to get the path of the file that I used to launch the activity. With that path I can open the file and do what I need to do; without it I’m stuck.

This seems like such an obvious question I thought there must be a tutorial somewhere explaining it but I’ve searched and searched and found nothing. Every damned tutorial assumes you will never read or write a file.