Tuesday, March 30, 2010

My Lucid Quickly Task List

I'm seeing if I can just recycle this post instead of create a whole new ones ...

Finished my last bit of Quickly related coding for Lucid just now. Got the quickly-widgets tests passing. I fixed a bug here and there along the way. Changes are pushed into trunk, next I'll ask didrocks to update universe.

Of course, I still have 2 weeks to fix bugs if you find 'em ...

We have entered the Lucid end-game. Which is great. Sadly, there were a whole mess of things for Quickly that I wanted to get done this cycle. I know I won't get to everything, but I can still do a lot. I decided to set out a list of goals, and to work on the list each night, hopefully picking one item off per evening.

I always consider work on Quickly to be related to, but not actually part of, my day job. Thus I enjoy working on it in my free time, but don't typically commit to accomplishing anything specific, because it is my free time, after all. However, let's see how this works.

Here is my tentative list (completed ones are crossed out):

  1. Finish fixing pygame template indentation and comments.

  2. Refactor pygame template to put screen size in the configuration file.

  3. Create my own sample sounds for pygtame template.

  4. Make pygtame template actually a template (add the string replacement functions and derive from ubuntu-application commands).

  5. Remove CameraButton from quickly-widgets.

  6. Finish quickly-widgets documentation.

  7. Make quickly-widgets tests work (test apps currently work, but some of the tests fail erroneously).

  8. Fix the ubuntu-application template tutorial to use quickly.widgets.couch_grid instead of desktopouch.couch_grid.

  9. Update ubuntu-application tutorial to use new Quickly commands

  10. Update ubuntu-application tutorial screenshots

  11. Add PPA section to ubuntu-application tutorial.

  12. Write PyGame template tutorial

  13. Make new videos for ubuntu-application.

  14. Make videos for PyGame.

Those 10+ things seem like good goals to start. If I missed something, etc... please provide a comment.

Saturday, March 27, 2010

My "Just Works" Audio Experience in Lucid

I've been doing a lot of desktop based VOIP calls lately, so decided to invest in a slightly nice set of headphones. I noticed that when my computer's fan is running, it adds a lot of noise to my normal audio card input, so I decided to go with a USB headset. I booted up, plugged into a USB port, and pick "Sound Preferencecs..." from the Sound Menu, and there was my new headphones an mic. A couple of tests, and yes, it works perfectly. First time, no configuration. Sweeeeet.

Sunday, March 21, 2010

sfxr for the blam.wav

I posted on some of the work I want to knock out for Quickly, and specifically regarding the PyGame template, there was this comment:

Michael said...

These look good. I just wanted to point out that if you haven't heard of it, sfxr (http://code.google.com/p/sfxr/) is often used in the indie game community and could help out with #3!

So, yeah, sfxr is quite cool. Just took a bit of Googling to find the dependencies needed to "make" it. I jammed out some sound effects in a matter of minutes. Thanks sfxr dev(s)!

Saturday, March 20, 2010

XML Copy-Editor FTW

Picking up where Fagan left off on the Quickly ubuntu-application tutorial, I'm writing a ubuntu-pygame tutorial using docbook format. The last time I tried available XML editors, the ones I found were crashy, or didn't offer much above and beyond Gedit, so I ended up editing XML in Gedit.

I tried again in Lucid, and found XML Copy-Editor in software-center. I love it! I'm getting statement completion for the schema currently in use (see screenshot above), and error highlighting when I make mistakes. It's also fast and rock solid on my mini 10v!

Interesting that it's built in wxWidgets. I wonder if they target this to be Cross Platform?

Monday, March 15, 2010

Beyond Release Blockers (also a bit on bughugger and f-spot)

Release Blockers and Beyond
Every release the various ubuntu teams focus on "release blocker bugs". These are bugs that are "High" or "Critical" in importance, and are targeted to the release. Of course they also have to be assigned so that someone knows about them and can work on them.

Of course, every release the desktop team fixes lots of bugs that are not release blockers. seb128 is leading an effort to organize the team to focus on the "right" set of these non-release blockers to fix. These are personal goals that the desktop team members sets for itself.

seb128 is combing through bugs that he considers addressable, and assigning the ones that he thinks will be most valuable to users if fixed to canonical-desktop-team. He sets the importants and targets to Lucid as well. pitti will then assign to specific engineers as needed. Of course, anyone is free to fix these bugs.

I am using bugger to watch this project. The version of bughugger that is currently packaged in universe calculates gravity and looks for attached patches. Unfortunately this makes the queries take so long, that it is basically impossible to use. (I've fixed this in my local copy, but haven't pushed the changes yet. By "fix" I mean removed the slow features.)

However, the JSON searches are working very well. From the bughugger search menu, choose JSON Searches, and you'll get a list of searches that run on a cron job on bdmurray's server.

After the results load, I can look for bugs assigned to the Canonical Desktop Team.

Because we worked in three iterations for Lucid, and minimized work for the third iteration, I am hopeful that we have a bit more time for bug fixing this cycle. However, even if the amount of bug fixing stays the same, I expect that having seb128 on point for choosing the highest impact bugs organized in a single list will help the best set of bugs get fixed by the desktop team, enhancing the general community quality efforts.

On a side note, RAOF has recently joined the desktop team as a Canonical supported employee! One of his first tasks was to implement the f-spot features required for the default application selection blueprint. F-spot now handles in situ editing of files. Which means no need to load images into the library to edit them, and no need to load up the gimp just do a quick crop! I cropped these screen captures using f-spot and it worked swimmingly. Thanks RAOF!

Sunday, March 14, 2010

Ink Scape + PyGame = Fun

Dropped in some new image files while working on the PyGame template tutorial

Wednesday, March 10, 2010

Quickly Task List Progress

Well, Monday night I went out for beer with my wife. Last night I cooked dinner and spent time with my kids. So, good nights, but no progress on my Quickly Task List.
However, I made some good progress #5 and #6 today.

Well, #6 was just: $bzr rm camera_button.py, so not much accomplishment there.
However, I made solid inroads for #5, documentation for #quickly-widgets. I got PressAndHoldButton totally documented, and did the module documentation for grid_column.py, which included a bit of work to document how to create a custom column for a DictionaryGrid.

Speaking of DictionaryGrid, I got a question from a developer using it about how to respond to edits in the DictionaryGrid. I realized that I did not make this easy. It's easy to enable the UI for editing, but in order to receive a signal when a change occurred required iterating though the columns and attaching to each column's edited (or toggled) event. So I fixed this by adding a "cell-edited" signal and that's in trunk now.

It's so important to be getting feedback from users. Otherwise, you don't know the right use cases, and you can miss obvious things like this.

Sunday, March 7, 2010

New Themes Looking Nice with UNE

I posted about running UNE on my desktop a week or so ago. This morning due to some East -> West jet lag I ended up waking up a bit early, so I dist-upgraded my desktop while drinking my coffee.

Since I had tinkered with the theme previously, it was not automatically applied. I chose Radiance since it is sunny in my office in the mornings. I changed to the new desktop wallpaper as well.

I like how the wallpaper suffuses the launcher with the new color scheme. And I am finding the new window decorators and colors to be quite nice as well.

Funny how I currently liking UNE on my desktop computer, and the desktop on my Dell mini 10v.

Wednesday, March 3, 2010

Photobomb Featured App for Opp. Dev. Week

Jono asked me to do an Opportunistic Developer Week session "Application Showcase: Photobomb".

So I prepared a little retrospective of Photobomb development to walk through in the session, taking questions as I go. Fortunately I was blogging daily as I added features, so it was easy to pull out images to jog my memory.

This posting is the notes for the session, which is later today.

I wrote the first iteration of Photobomb one Saturday afternoon. I used Quickly to get the project started, so it was just a matter of laying out some UI in Glade, and then figuring out how to manipulate images. I used Python Imaging Library (PIL) to create a cropped version of that little squirrel, and to paste it onto the picture. PIL is a complete and power library. It was a bit tough figuring out the masking to crop the squirrel image as desired, but I eventually managed.
Creating a File Dialog Widget

It turned out to be tedious to write code to open an image file. Also, a lot of copy and pasting. So I added a prompt to quickly.widgets to handle opening files. Having your own library of reusable widgets is quite a luxury. Note that I didn't know the gtk.FileChooser API that well, so made a couple of early mistakes, such as handling the existing file replace functionality myself. Didn't realize that the API could handle it.

Switch from PIL to GooCanvas

When I tried to implement some captioning and other features, I came to realize that PIL was just not designed for the kind of stuff I wanted to do with it. When I switched to GooCanvas, it became much easier to add features.

I was able to add resizing, rotation, and drag to move in a matter of an hour or so. A couple of days later I fixed an issue with dragging rotated items that resulted from

Ink in GoogCanvas

For example, I could then go and the ability for users to use a pen tool in photobomb. This required managing mouse events and creating a PolyLine object from the collected mouse points. Later I found that a Path worked better than a PolyLine for creating the Ink. I still have not figured out how to add points to an existing Path. As a result, Photobomb recreates the Path with each mouse move. This gets slow if the Path is not short.

SVG Icons with Inkscape

I used Inkscape to create svg files for the custom icons. I simply sized the documents how I wanted, and told the toolbar buttons to load the icons from the path. The delete icon used gtk.STOCK_DELETE.

I used the gtk.ColorChooserDialog for color selection.

I also added color button and ink width button. These hosted a goocanvas, and I just added a path to each and set the properties of the Path to display the selected color and width. I had already created quickly.prompts to make it easy to collect a line width from the user. (quickly.prompts.integer()).

I could handle this with a GooCanvas.Widget object embedded in situ, but that's a lot of work and using quickly.prompts.string() is a one-liner.


I added a gtk.STOCK_EDIT button to collect text from the user. I used a quickly.prompts.string() to collect the string to display from the user.


To display selection, I simply used a GooCanvas.Rect with a bit of buffer around the selected object. I could have added stock selection points from gtk, but that sounded like a lot of work.

Opacity and Directory Iteration

I added a bit of opacity to the selection box. This works better.

Then I added opacity to other selectable items. I sniped some code from segphault's grabbersnap app to figure out how to set up rgba colors. It's a bit of a hack, but seems to work well.

At this point in the project I also switched from having the user open individual images to add, to iterating through the Pictures directory and adding a button for each encountered image.

Web Cam

Web Cam support is an important feature for Photobomb, but the available APIs were daunting. That is, until I discovered that Pygame had a simplified web cam interface. I created a quickly.widget to handle web cam integration and added that widget to Photobomb. Note that this means quickly.widgets depends on PyGame. I think I shall move the webcam widget out of the default install and make it available in some other manner.

Having another source of images meant that I needed to add a gtk.Notebook to handle switching between the two sources.
Image Searching

I used the Yahoo! API to do image searching. I chose Yahoo! only because the API was quite easy to figure out.

Press and Hold

Changing size, rotation, and opacity required the user to click the button once for each increment. So rotating something to be upside required the user to go "click click click click", etc...

What I wanted was the user to click the button, and hold it down as the image rotated, and then to stop when it was positioned as desired.

Sadly, there is no "key-down" event on gtk.Toolbars. So I had to switch Photobomb from using toolbars to using regular gtk.Button. I also created a new quickly.widget.PressAndHold widget to handle this.

I accomplish the asynch behavior with gobject.timeout_add(250, self.__tick). At each tick the button emits a signal telling the consuming app to do something.

Gwibber Integration

Because Gwibber uses desktopcouch to store messages in Lucid, I could add the feature to grovel through the messages and extract images coming from social feeds to display. I also sniped Gwibber's fb credentials from desktopcouch, and used that and some FML to get images from Facebook.


I used the Gwibber API to add broadcasting Photobomb images. The GooCanvas renders a png that is saved to a temp location. Then pycurl uploads the image to imgur.com, which returns a url. Gwibber's GwibberPosterVBox to broadcast the URL.

Fun and Easy Game Programming with PyGame

As part of opportunistic developer week later today, I will be doing a session on PyGame. PyGame makes it really easy and fun to write a game.

I've been wanting to create a PyGame template for Quickly, so I used this opportunity for motivation to take a game that I wrote a couple of years ago, and simplify it into boiler plate. With the addition of template command inheritance, I think that it will be easy to make this a functional template for Quickly 4.0.

In the meantime, I pushed the code to a project. Feel to grab it and start modifying it to make your own game. Note, however, that the code is not formatted in a standard way, nor is it commented yet. I will fix those issues as I get a chance.

Anyway, maybe I'll see you at the session.