Canonical Voices

Posts tagged with 'quickly'

Michael Hall

UPDATE: A command porting walk-through has beed added to the documentation.

Back around UDS time, I began work on a reboot of Quickly, Ubuntu’s application development tool.  After two months and just short of 4000 lines of code written, I’m pleased to announce that the inner-workings of the new code is very nearly complete!  Now I’ve reached the point where I need your help.

The Recap

First, let me go back to what I said needed to be done last time.  Port from Python 2 to Python 3: Done. Add built-in argument handling: Done. Add meta-data output: Well, not quite.  I’m working on that though, and now I can add it without requiring anything from template authors.

But here are some other things I did get done. Add Bash shell completion: Done.  Added Help command (that works with all other commands): Done.  Created command class decorators: Done.  Support templates installed in any XDG_DATA_DIRS: Done.  Allow template overriding on the command-line: Done.  Started documentation for template authors: Done.

Now it’s your turn

With the core of the Quickly reboot nearly done, focus can now turn to the templates.  At this point I’m reasonably confident that the API used by the templates and commands won’t change (at least not much).  The ‘create’ and ‘run’ commands from the ubuntu-application template have already been ported, I used those to help develop the API.  But that leaves all the rest of the commands that need to be updated (see list at the bottom of this post).  If you want to help make application development in Ubuntu better, this is a great way to contribute.

For now, I want to focus on finishing the port of the ubuntu-application template.  This will reveal any changes that might still need to be made to the new API and code, without disrupting multiple templates.

How to port a Command

The first thing you need to do is understand how the new Quickly handles templates and commands.  I’ve started on some documentation for template developers, with a Getting Started guide that covers the basics.  You can also find me in #quickly in Freenode IRC for help.

Next you’ll need to find the code for the command you want to port.  If you already have the current Quickly installed, you can find them in /usr/share/quickly/templates/ubuntu-application/, or you can bzr branch lp:quickly to get the source.

The commands are already in Python, but they are stand-alone scripts.  You will need to convert them into Python classes, with the code to be executed being called in the run() method.  You can add your class to the ./data/templates/ubuntu-application/commands.py file in the new Quickly branch (lp:quickly/reboot).  Then submit it as a merge proposal against lp:quickly/reboot.

Grab one and go!

So here’s the full list of ubuntu-application template commands.  I’ll update this list with progress as it happens.  If you want to help, grab one of the TODO commands, and start porting.  Email me or ping me on IRC if you need help.

add: TODO
configure: TODO
create: DONE!
debug: TODO
design: TODO
edit: DONE!
license: TODO
package: DONE!
release: TODO
run: DONE!
save: DONE!
share: TODO
submitubuntu: TODO
test: TODO
tutorial: TODO
upgrade: TODO

Read more
Michael Hall

Shortly after the Ubuntu App Showdown earlier this year, Didier Roche and Michael Terry kicked off a series of discussions about a ground-up re-write of Quickly.  Not only would this fix many of the complications app developers experienced during the Showdown competition, but it would also make it easier to write tools around Quickly itself.

Unfortunately, neither Didier nor Michael were going to have much time this cycle to work on the reboot.  We had a UDS session to discuss the initiative, but we were going to need community contributions in order to get it done.

JFDI

I was very excited about the prospects of a Quickly reboot, but knowing that the current maintainers weren’t going to have time to work on it was a bit of a concern.  So much so, that during my 9+ hour flight from Orlando to Copenhagen, I decided to have a go at it myself. Between the flight, a layover in Frankfurt without wifi, and a few late nights in the Bella Sky hotel, I had the start of something promising enough to present during the UDS session.  I was pleased that both Didier and Michael liked my approach, and gave me some very good feedback on where to take it next.  Add another 9+ hour flight home, and I had a foundation on which a reboot can begin.

Where is stands now

My code branch is now a part of the Quickly project on Launchpad, you can grab a copy of it by running bzr branch lp:quickly/reboot.  The code currently provides some basic command-line functionality (including shell completion), as well as base classes for Templates, Projects and Commands.  I’ve begun porting the ubuntu-application template, reusing the current project_root files, but built on the new foundation.  Currently only the ‘create’ and ‘run’ commands have been converted to the new object-oriented command class.

I also have examples showing how this new approach will allow template authors to easily sub-class Templates and Commands, by starting both a port of the ubuntu-cli template, and also creating an ubuntu-git-application template that uses git instead of bzr.

What comes next

This is only the very beginning of the reboot process, and there is still a massive amount of work to be done.  For starters, the whole thing needs to be converted from Python 2 to Python 3, which should be relatively easy except for one area that does some import trickery (to keep Templates as python modules, without having to install them to PYTHON_PATH).  The Command class also needs to gain argument parameters, so they can be easily introspected to see what arguments they can take on the command line.  And the whole thing needs to gain a structured meta-data output mechanism so that non-Python application can still query it for information about available templates, a project’s commands and their arguments.

Where you come in

As I said at the beginning of the post, this reboot can only succeed if it has community contributions.  The groundwork has been laid, but there’s a lot more work to be done than I can do myself.  Our 13.04 goal is to have all of the existing functionality and templates (with the exception of the Flash template) ported to the reboot.  I can use help with the inner-working of Quickly core, but I absolutely need help porting the existing templates.

The new Template and Command classes make this much easier (in my opinion, anyway), so it will mostly be a matter of copy/paste/tweak from the old commands to the new ones. In many cases, it will make sense to sub-class and re-use parts of one Template or Command in another, further reducing the amount of work.

Getting started

If you are interested in helping with this effort, or if you simply want to take the current work for a spin, the first thing you should do is grab the code (bzr branch lp:quickly/reboot).  You can call the quickly binary by running ./bin/quickly from within the project’s root.

Some things you can try are:

./bin/quickly create ubuntu-application /tmp/foo

This will create a new python-gtk project called ‘foo’ in /tmp/foo.  You can then call:

./bin/quickly -p /tmp/foo run

This will run the applicaiton.  Note that you can use -p /path/to/project to make the command run against a specific project, without having to actually be in that directory.  If you are in that directory, you won’t need to use -p (but you will need to give the full path to the new quickly binary).

If you are interested in the templates, they are in ./data/templates/, each folder name corresponds to a template name.  The code will look for a class called Template in the base python namespace for the template (in ubuntu-application/__init__.py for example), which must be a subclass of the BaseTemplate class.  You don’t have to define the class there, but you do need to import it there.  Commands are added to the Template class definition, they can take arguments at the time you define them (see code for examples), and their .run() method will be called when invoked from the command line.  Unlike Templates, Commands can be defined anywhere, with any name, as long as they subclass BaseCommand and are attached to a template.

Read more
Michael Hall

You can watch the App Developer Q&A live stream starting at 1700 UTC (or watch the recording of it afterwards):

Questions should be asked in the #ubuntu-on-air IRC channel on freenode.

You can ask me anything about app development on Ubuntu, getting things into the Software Center, or the recent Ubuntu App Showdown competition.

Read more
Michael Hall

Due to the popularity of the Ubuntu App Showdown Workshops, I plan to start holding a weekly Q&A session for all Ubuntu app developers using the same format: A live Google+ Hangout with IRC chat.

The first of these will be Wednesday of this week, at 1700 UTC (6pm London, 1pm US Eastern, 10am US Pacific).  Because it will be an On-Air hangout, I won’t have a link until I start the session, but I will post it here on my blog before it starts.  For IRC, I plan on using the #ubuntu-on-air channel on Freenode, though again the exact details will be posted the day of the session.

So bring your questions about developing apps for Ubuntu, packaging an submitting them to the Software Center.  If I can’t answer your question myself, I’ll help you find someone who can.

Read more
Michael Hall

As part of the Ubuntu App Showdown I started on a small project to provide a nice GUI frontend to Quickly.  While I was able to get it working and submitted before the contest deadline, I unfortunately didn’t have the time to make it do everything I wanted.  Since the end of the contest, however, I was able to spend a little more time adding some nice features to it.

Project Management

The majority of the work has gone into Quickly-Gtk’s project management.  Some of this was implemented already, such as the ability to switch the “current” project. But internally it was all kind of a mess of code to track that.  So I replaced all of that with a ProjectManager class that will store both the list of projects Quickly-Gtk knows about, but also keeps track of which project is “current”.  This class also implements Observer design pattern to let other parts of the code know about changes to both the list of projects and the current project.  This made it easy to, for example, display a notification on the screen whenever the current project was changed, regardless of whether it was changed in the window, the indicator, or from a Zeitgeist event.

Zeitgeist event monitoring

The other big development was integrating Quickly-Gtk with Zeitgeist.  For those that aren’t familiar with it, Zeitgeist is an event log that tracks all kinds of user activities and system events.  Applications can read past events or monitor them as they happen.  I wanted Quickly-Gtk to be smart enough to switch to a project as soon as the user started working on it, without requiring the user to make the switch themselves.  To do that, I set a Zeitgeist monitor to listen for file system events in any of the saved project directories.  I also set it to watch for the user viewing the project’s Launchpad page.  If any of those events happen, Quickly-Gtk will automatically make that the current project.

The future of Quickly-Gtk

While I was able to get a lot done with Quickly-Gtk, the underlying Quickly API and command line really weren’t designed to support this kind of use.  However, as a result of what we learned during the App Showdown, Didier Roche has begun planning a reboot of Quickly, which will improve both it’s command-line functionality, and it’s ability to be used as a callable library for apps like Quickly-Gtk.  If you are interested in the direction of Quickly’s development, I urge you to join in those planning meetings.

 

Launchpad Project: https://launchpad.net/quickly-gtk

 

Read more
Michael Hall

As you’ve probably heard already, Ubuntu is running an App Developer Showdown competition where contestants have three weeks to build an Ubuntu app from scratch.  The rules are simple: It has to be new code, it has to run on Ubuntu, and it has to be submitted to the Software Center.  The more you use Ubuntu’s tools, the better your chances of winning will be.  This week we ran a series of workshops introducing these tools and how they can be used.  It all seemed like so much fun, that I’ve decided to participate with my own submission!

Now 2 our of the 6 judges for this competition are my immediate co-workers, so let me just start off by saying that I will not be eligible for any of the prizes.  But it’s still a fun and interesting challenge, so I’m going to participate anyway.  But what is my entry going to be?  Well in my typical fashion of building tools for tools, I’ve decided to write a GUI wrapper on to of Quickly, using Quickly.

Before I started on any code, I first wanted to brainstorm some ideas about the interface itself.  For that I went back to my favorite mockup tool: Pencil.  I knew I wanted to cover all of Quickly’s functions, both for creating projects and working on them afterwards.  I also wanted something that would keep track of my projects, so I wouldn’t have to find where they are on my disk whenever I wanted to hack on them.

Now, I’ve never been a fan of GUI builders.  Even back when I was writing Java/Swing apps, and GUI builders were all the rage, I never used them.  I didn’t use one for Hello Unity, and I wasn’t planning on using Glade for this project either.  But after Jono’s fantastic workshop session about Glade, I decided to give it another chance.  I found that I was able to get a basic UI built and running in very little time.  I’m still struggling with some, and there’s a point where you need to switch from Glade to code, but all in all it has saved me a significant amount of time.

Quickly also saved me a large amount of time, both in creating the project and adding things too it.  Being able to add an Application Indicator to your app by just running “quickly add indicator” is amazing.  From there is was a simple matter to build a menu based on available Quickly commands and tie them in with callback functions.

But the part I like the best about this app so far, is that it’s useful even when you’re not using it.  Most of the time you spend developing a Quickly app is going to be in some other application, such as your code editor of choice, Glade or something.  Thanks to Unity’s HUD, and the fact that it’s smart enough to check Indicator menus in addition to the focused application’s menus, you can call your Quickly commands any time, simply by tapping ‘Alt’ and the command you want to run.  It’s like having Quickly integrated into all of your other tools.

And thanks to the developer tools available in Ubuntu, I was able to accomplish all of this in only a few hours of work.

Now it’s very, very far from being complete.  For instance, the “active” project is hard-coded to my quickly-gtk working directory, it can’t start a project yet, or support commands that take optional arguments or user input.  But in a short amount of time I was able to go from a mockup to a working layout and even some functional code.  It even packages successfully, something I found out quite by accident when I selected “Share” from the indicator menu and ended up with a package in my PPA.

Building an app in 4 hours then accidentally building a proper package and uploading it to a PPA, who’d have thought we’d ever make it that easy?  I hope you all are having as much fun and success in your showdown applications as I am.

Read more
David

UDS is here again. Tomorrow another week packed with content that will define the plans for a new Ubuntu LTS release will start, and this time around application development will be a prominent topic.

So for all of you interested in helping and being part of the effort of making Ubuntu a platform of choice for application developers, here’s a quick list with an overview of the sessions we’ve got in store this week.

Remember you can register your interest in sessions you want to attend or keep up to date with by using the Subscribe link on each session’s blueprint. The links in the list below will take you to the blueprints used to define the specifications for each feature or goal. You can also check out the full UDS schedule.

So, without further ado, here’s the list of app development sessions:

Oh, and don’t miss the Application development and the Qt keynotes on Tuesday

See you all there!


Read more
David

Another edition of the Ubuntu App Developer Week and another amazing knowledge sharing fest around everything related to application development in Ubuntu. Brought to you by a range of the best experts in the field, here’s just a sample of the topics they talked about: App Developer Strategy, Bazaar, Bazaar Explorer, Launchpad, Python, Internationalization, Launchpad Translations, Unity, Unity 2D, Gedit Developer Plugins, the MyApps Portal, the App Review Board, the UbuntuSoftware Centre, Unity Mail, Launchpad Daily Builds, Ubuntu One APIs, Rapid App Development, Quickly, GooCanvas, PyGame, Unity Launcher, Vala, the App Developer Site, Indicators, Python Desktop Integration, Libgrip, Multitouch, Unity Lenses, Ubuntu One Files Integration, The Business Side of Apps, Go, Qt Quick… and more. Oh my!

And a pick of what they had to say:

We believe that to get Ubuntu from 20 million to 200 million users, we need more and better apps on Ubuntu
Jonathan Lange on making Ubuntu a target for app developers

Bazaar is the world’s finest revision control system
Jonathan Riddell on Bazaar

So you’ve got your stuff, wherever you are, whichever device you’re on
Stuart Langridge on Ubuntu One

Oneiric’s EOG and Evince will be gesture-enabled out of the box
Jussi Pakkanen on multitouch in Ubuntu 11.10

I control the upper right corner of your screen ;-)
Ted Gould on Indicators

If you happened to miss any of the sessions, you’ll find the logs for all of them on the Ubuntu App Developer Week page, and the summaries for each day on the links below:

Ubuntu App Developer Week – Day 5 Summary

The last day came with a surprise: an extra session for all of those who wanted to know more about Qt Quick and QML. Here are the summaries:

Getting A Grip on Your Apps: Multitouch on GTK apps using Libgrip

By Jussi Pakkanen

In his session, Jussi talked about one of the most interesting technologies where Ubuntu is leading the way in the open source world: multitouch. Walking the audience through the Grip Tutorial, he described how to add gesture support to existing applications based on GTK+ 3. He chose to focus on the higher layer of the uTouch stack, where he explained the concepts on which libgrip, the gesture library, is built upon, such as device types and subscriptions. After having explored in detail the code examples, he then revealed that in Oneiric Eye Of GNOME and Evince, Ubuntu’s default image viewer and default PDF reader, will be gesture-enabled.

Check out the session log.

Creating a Google Docs Lens

By Neil Patel

Neil introduced his session explaining the background behind Lenses: a re-architecture effort of the now superseded Places concept to make them more powerful, provide more features and make it easier to add features through a re-engineered API. Lenses create its own instance, add categories, filters and leave the searching to Scopes. The Lenses/Scopes pairs are purely requests for data, independent of the type of UI, and being provided by the libunity library, they can be written in any of the programming languages supported by GObject Introspection (Python, Javascript, C/C++, Vala, etc.). To illustrate all of this concepts, Neil devoted the rest of the session to a real example of creating a Lens for Google Docs.

Check out the session log.

Practical Ubuntu One Files Integration

By Michael Terry

Another hands-on session from Michael, with a real world example on how to supercharge apps with cloud support. Using his experience in integrating the Ubuntu One Files API to Deja Dup, the default backup application in Ubuntu, he went in detail through the code of a simple program to talk to a user’s personal Ubuntu One file storage area. We liked Michael’s session so much that it will very soon be featured as a tutorial on developer.ubuntu.com!

Check out the session log and Michael’s awesome notes.

Publishing Your Apps in the Software Center: The Business Side

By John Pugh

Ubuntu directly benefits from Canonical becoming a sustainable business to support its development, and that’s exactly what John talked about. Being responsible for business development in the Ubuntu Software Centre, he’s got a privileged  insight on how to make it happen. He started off explaining that the main goal is to present Ubuntu users with a large catalog of apps available for purchase, and then continued concentrating on how to submit paid applications to be published in the Software Centre. A simple 5-step process, the behind-the-scenes work can be summarized in: Canonical helps packaging the app, it hosts the app and provides the payment via pay.ubuntu.com, in a 80%/20% split. Other highlights include the facts that only non-DRM, non-licensed apps cannot be submitted right now, but there is ongoing work to implement license key support, and that MyApps, the online app submission portal, can take any nearly any content: apps with adverts, “free” online game clients and HTML5 apps.

Check out the session log.

Writing an App with Go

By Gustavo Niemeyer

Gustavo’s enthusiasm for Go, the new programming language created by Google shows every time you start a conversation with him on that topic. And it showed as well on this session, in which he created yet another “Hello world” application in a new language -you guessed-: Go. Along the way, he had time to describe all of the features of this new addition of the extensive family of programming languages: statically compiled with good reflection capabilities, structural typing, interfaces and more.

Check out the session log.

Qt Quick At A Pace

By Donald Carr

Closing the week on the last -and surprise- session, we had the luxury of having Donald, from the Nokia Qt team, the makers of Qt itself, to talk about Qt Quick. Using a clear and concise definition, Qt Quick is an umbrella term used to refer to QML and its associated tooling; QML being a declarative markup language with tight bindings to Javascript. A technology equally suited to mobile or to the desktop, QML enables developers to rapidly create animation-rich, pixmap-oriented UIs. Through the qtmediahub and Qt tutorial examples, he explored QML’s capabilities and offered good practices for succesfully developing QML-based projects.

Check out the session log.

Wrapping Up

Finally, if you’ve got any feedback on UADW, on how to make it better, things you enjoyed or things you believe should be improved, your comments will be very appreciated and useful to tailor this event to your needs.

Thanks a lot for participating. I hope you enjoyed it  as much as I did, and see you again in 6 months time for another week full with app development goodness!


Read more
David

Ubuntu App Developer Week – Day 4 Summary

Last day of UADW! While we’re watching the final sessions, here’s what happened yesterday:

Creating an App Developer Website: developer.ubuntu.com

By John Oxton and David Planella

Creating the concept and implementing a site for app developers is no easy task. The Ubuntu App Developer site is meant to be a place for app authors to get started with development, to find the information they need and to be able to publish their apps in the Software Centre. John explained all the research and user testing that happened behind the scenes, highlighting the key findings, while David focused on the purpose of the site, where it fits in the overall developer strategy for Ubuntu and the plans for the future.

Check out the session log here.

Rapid App Development with Quickly

By Michael Terry

Fitting nicely topicwise with the questions about the default choice of tools for Ubuntu development on the previous session, Michael gave an overview of what Quickly is and how to use it. Going through the workflow of creating your first app with Quickly, he demonstrated all the key commands and explained in detail all the bits in between.

Check out the session log here.

Developing with Freeform Design Surfaces: GooCanvas and PyGame

By Rick Spencer

Rick started off the session explaining what GooCanvas and PyGame were good for: providing a 2D surface on which to construct interactive GUIs for users. Beginning with GooCanvas, he showed with a very simple example how to get started playing with 2D composing surfaces, adding images, text and doing other operations such as resizing and calculating coordinates to determine clicks. Next up was PyGame, for the same purpose, but better suited for apps with lots of animation updates without user input. He then wrapped up with three samples of simple games to study.

Check out the session log here.

Making your app appear in the Indicators

By Ted Gould

Ted Gould, the man who controls the upper right corner of our screen, talked all about indicators. The idea was to illustrate how to get the information that comes from applications and handle it to the indicators. First up was the messaging menu, a menu to handle human-to-human communication, next the application indicators, which alllow long-running apps to put statuses on the panel consistently, and finally the sound indicator, taking care of all related to sound. Each one of them explained with code examples. Nice!

Check out the session log here.

Will it Blend? Python Libraries for Desktop Integration

By Marcelo Hashimoto

Marcelo shared his experience acquired with Polly, a Twitter client he developed, on using Python and libraries to let apps provide better integration to the desktop. First explaining the concept of desktop integration, stressing the fact that it’s not only about visuals. The rest of the session was structured around 3 main areas: how to send notifications to the user, where to place files read or written by an app and what to use to store sensitive information. A very clear and solid session, also with example code for easy learning.

Check out the session log here.

The Day Ahead: Upcoming Sessions for Day 4

Check out the first-class lineup for the last day of UADW:

16.00 UTCGetting A Grip on Your Apps: Multitouch on GTK apps using Libgrip

Multitouch is everywhere these days, and now on your desktop as well -brought to you by developers such as Jussi Pakkanen, who’ll guide through using libgrip to add  touch support to your GTK+ apps. Learn how to use this cool new library in your own software!

17:00 UTCCreating a Google Docs Lens

Lenses are ways of presenting data coming from different sources in Unity. Neil Patel knows Lenses inside out and will present a practical example of how to create a Google Docs one. Don’t miss this session on how to put two cool technologies together!

18:00 UTCPractical Ubuntu One Files Integration

Yet again the Deja-dup rockstar and UADW regular Michael Terry will be sharing his deep knowledge on developing apps. This time it’s about adding cloud support to applications: integrating with the Ubuntu One files API.

19:00 UTCPublishing Your Apps in the Software Center: The Business Side

Closing the series of sessions around publishing apps in the Software Centre, we’ll have the luxury of having John Pugh, from the team that brings you commercial apps into the Software Centre and who’ll be talking about the business side of things.

20:00 UTC – Writing an App with Go

Go is the coolest kid around in the world of programming languages. Gustavo Niemeyer is very excited about it and will be showing you how to write an app using this language from Google. Be warned, his enthusiasm is contagious!

20:00 UTC – Qt Quick At A Pace

A last minute and very welcome addition to the schedule. In his session Donald Carr will introduce you to Qt Quick to create applications with Qt Creator and QML, the new declarative language that brings together designers and developers.

Looking forward to seeing you all there!


Read more
Rick Spencer

Cha-ching!



So, today I uploaded a special version of Photobomb to my PPA. It's special because I consider this my first *complete* release. There are some things that I would like to be better in it. For example:

  • I wish you could drag into from the desktop or other apps.
  • I wish that the app didn't block the UI when you click on the Gwibber tab when Gwibber isn't working.
  • I wish the local files view had a watch on the current directory so that it refreshed automatically.
  • I wish inking was smoother.
  • I wish you could choose the size of the image that you are making.
  • I wish that you could multi-select in it.
But alas, if I wait until it has everything and no bugs, I'll never release.

So, I am releasing Photobomb in my PPA. It is a free app. You can use it for free, and it's Free software. So, enjoy.

However, I am *also* releasing it commercially into the software center. That means that you can choose to install from my PPA for free, or you can buy it from the Software Center. I guess the only real difference will be that I could break it in my PPA, and I won't generally plan to provide lots of support, but if you bought it, I'd feel a bit more like I should strive to fix your bugs and stuff.

The code is GPL v3, so people can enhance it, or generally do whatever they think is useful for them (including giving it a way, or using it to make money).

I found it remarkably easy to submit photobomb to the Software Center. I just used the myapps.ubuntu portal, and it all went very smoothly. Really just a matter of filling in some forms. Of course, since I used Quickly to build Photobomb, Quickly took care of the packaging for me, so that simplified it loads.

I'll keep everyone posted on how it goes!

Read more
David

Ubuntu App Developer Week – Day 4 Summary

Ramping up to the end of the week we had another full app development goodness day, and one where the session topics fitted together in a nice workflow as well: creating bling, creating apps with Rapid Prototyping, getting them into Ubuntu, adding indicator support and translating them. Here’s the report of yesterday’s app development journey:

Qt Quick: Elements/Animations/States

By Jürgen Bocklage-Ryannel

The next Qt Quick session was all about creating attractive and usable user interfaces. Jürgen went through the QML tutorial documentation and code examples, showing us how to position elements with anchors, columns, rows and grids. Then onto states and transitions: describing the changes in an element’s properties and how to switch between them. To finalize, the most impressive stuff: QML animations, in which he teached us the different types of animations and how to use them.

Check out the session log here.

Qt Quick: Rapid Prototyping

By Jürgen Bocklage-Ryannel

In Jürgen’s words, Qt Quick was designed to bridge the gap between designers and developers, letting both groups to work with the same technologies and code base. He explained how Qt Creator provides a design mode which allows easy dragging and dropping of UI elements, and separation between code and interface. All through a natural and agile prototyping workflow.

Check out the session log here.

Rapid App Development with Quickly

By Michael Terry

Michael started introducing what Quickly at the heart is: a robust yet simple system of templates with boilerplate code and commands. The available templates are ubuntu-application, ubuntu-cli, ubuntu-pygame and ubuntu-flash-game, and on the Natty version, Quickly will feature the ‘submitubuntu’ command to help getting applications into the Software Center. All that being set straight, he then showed how to use Quickly and what it can do: from creating the first example application, to modifying the UI with ‘quickly design’ and Glade, into debugging and finally packaging.

Check out the session log here.

Getting Your App in the Distro: the Application Review Process

By Allison Randal

Linking from the previous session on how to create an app, Allison explained in a very clear way how to get your applications into Ubuntu, so that they make their way into the OS in a matter of weeks instead of having to wait until the next release. The first step is to submit a ticket to the App Review Board, giving them the essential details for the proposal. They’ll then do the initial review, in which one of the reviewers will volunteer to walk you through the process and help you with suggestions or improvements, to bring the app to a state ready for the final review. There the board will vote in a meeting for the inclusion of the application. After the process description she answered the questions from the audience and wrapped up with some useful tips to application submitters.

Check out the session log here.

Adding Indicator Support to your Apps

By Ted Gould

Ted kicked off with an explanation of what indicators are and their intended use: they should not be used just because they are available – rather as a feature for long running applications, those that are more services to users, to expose that functionality. The next step was to describe how to create indicators through libappindicator, with any language supported by GObject Introspection, such as Python or Javascript, and how to add more features to a basic indicator: accessible labels and attention state. After that he described fallbacks, and how platforms not using Unity can nevertheless use indicators. The final minutes were dedicated to the future of indicators, that for now will focus on API cleanup and stabilization, and introspection improvements.

Check out the session log here.

Using Launchpad to get your application translated -

By Henning Eggers

As a follow up to the talk on how to add native language support to your applications on Monday, Henning described the next step: how to make them translatable in Launchpad and grow a translation community around them. In the first part he showed how to set up a demo project using Launchpad’s staging server, and shared some recommendations on how to make sure the application is correctly set up for translations, followed by an overview on some Gettext concepts Launchpad relies upon. From there, it was straight into business: setting up a translatable project in Launchpad, getting translatable templates imported and exposed to translators, creating a translation community for your project and the workflow for translation. A very detailed overview to get your application to talk any language.

Check out the session log here.

The Day Ahead: Upcoming Sessions for Day 5

The last day and the quality and variety of the sessions is still going strong. Check out the great content we’ve prepared for you today:

16:00 UTC
Qt Quick: Extend with C++ – Jürgen Bocklage-Ryannel
Sometimes you would like to extend Qt Quick with your own native extension. Jürgen will show you some ways how to do it.

17:00 UTC
Phonon: Multimedia in Qt - Harald Sitter
Harald, as the lead developer of the Qt/KDE multimedia library Phoon will tell you about the awesomeness that Phonon provides and how it achieves ultimate portability, so that it can even run on vending machines. He’ll also tell you hos to create a video player with 3 lines of code (or in 30 seconds without any code) and much more.

18:00 UTC
Integrating music applications with the Sound Menu - Conor Curran
So you’ve seen the slick sound menu in Ubuntu, and you’re developing a multimedia application, right? You’re then wondering how to seamlessly integrate it into Ubuntu and use all the nice features from the menu as well? Wonder no more, for Conor is the man behind the sound menu and he’ll be delighted to teach you how.

19:00 UTC
pkgme: Automating The Packaging Of Your Project - James Westby
Once you’ve developed a cool application you’ll want to package it and distribute it to users so that they can easily install it in their favourite platform. James will show you how this can be both easy and fun letting pkgme do all the work for you.

20:00 UTC
Unity Technical Q&A - Jason Smith and Jorge Castro
You’ve heard about Unity, the new UI concept which is going to improve several orders of magnitude how you interact with your computer in Ubuntu. You are probably using it already, and you’ll surely have questions and will want to learn more about the coolness it brings. Jason Smith, from the Unity development team, and Jorge Castro, from the Community team know all about Unity and they’ll be here to chat with you.

21:00 UTC
Lightning Talks - Nigel Babu
As the final treat to close the week, Nigel has organized a series of lightning talks to showcase a medley of cool applications: CLI Companion, Unity Book Lens, Bikeshed, circleoffriends, Algorithm School, Sunflower FM, Tomahawk Player, Classbot – your app could be in this list next time, do check them out!

Looking forward to seeing you all there!


Read more
Rick Spencer

I started working on a chapter for the Ubuntu Developers' Manual. The chapter will be on how to use media in your apps. That chapter will cover:

  • Playing a system sound
  • Showing an picture
  • Playing a sound file
  • Playing a video
  • Playing from a web cam
  • Composing media
I created an app for demonstrating some of these things in that chapter. After I wrote the app, I realized that it shows a lot of different parts of app writing for Ubuntu:
  • Using Quickly to get it all started
  • Using Glade to get the UI laid out
  • Using quickly.prompts.choose_directory() to prompt the user
  • Using os.walk for iterating through a directory
  • Using a dictionary
  • Using DictionaryGrid to display a list
  • Using MediaPlayerBox to play videos or Sounds
  • Using GooCanvas to compose a singe image out of images and text
  • Using some PyGtk trickery to push some UI around
A pretty decent amount of overlap with the chapter, but not a subset or superset. So I am writing a more full tutorial to post here, and then I can pull out the media specific parts for the chapter later. Certain things will change as we progress with Natty, so I will make edits to this posting as those occur. So without Further Ado ...

Simple Player Tutorial
Introduction
In this tutorial you will build a simple media player. It will introduce how to start projects, edit UI, and write the code necessary to play videos and songs in Ubuntu.
The app works by letting the user choose a directory. Simple Player then puts all the media into a list. The user can choose media to play from that list.

This tutorial uses Quickly, which is an easy and fun way to manage application creation, editing, packaging, and distribution using simple commands from the terminal. Don't worry if you are used to using an IDE for writing applications, Quickly is super easy to use.

Requirements
This tutorial is for Ubuntu Natty Narwhal (11.04). There are some key differences between 10.10 and 11.04 versions of Quickly and other tools that will make it hard to do the tutorial if you are not on Natty. So, probably best to make sure you are running 11.04.

You also need Quickly. To install Quickly:

$sudo apt-get install quickly python-quickly.widgets

This tutorial also uses a yet to be merged branch of Quickly Widgets. In a few weeks, you can just install quickly-widgets, but for now, you'll need to get the branch:

$bzr branch lp:~rick-rickspencer3/quidgets/natty-trunk

Note that these are alpha versions, so there may be bugs.

Caution About Copy and Pasting Code

In Python, white space is very significant, especially in terms of indentions. In HTML, white space is not. As a result, Blog postings frequently mangle Python code, no matter how carefully a blogger might format it. So while you're following along, be careful about copying and pasting out of here.

If you're going to copy and paste, you might want to use the code for the tutorial project in launchpad, from this:
Link to Code File in the Launchpad Project

You can also look at the tutorial in text format this:
Link to this tutorial in text for in Launchpad

Creating the Application
You get started by creating a Quickly project using the ubuntu-application template. Run this command in the terminal:
$quickly create ubuntu-application simple-player

This will create and run your application for you.

Notice that the application knows it is called Simple Player, and the menus and everything work.

To edit and run the application, you need to use the terminal from within the simple-player directory that was created. So, change into that directory for running commands:

$cd simple-player

Edit the User Interface
We'll start by the User Interface with the Glade UI editor. We'll be adding a lot of things to the UI from code, so we can't build it all in Glade. But we can do some key things. We can:
  • Layout the HPaned that separates the list from the media playing area
  • Set up the toolbar
Get Started
To run Glade with a Quickly project, you have to use this command from within your project's directory:
$quickly design

If you just try to run Glade directly, it won't work with your project.
Now that Glade is open, we'll start out by deleting some of the stuff that Quickly put in there automatically. Delete items by selecting them and hitting the delete key. So, delete:
  • label1
  • image1
  • label2
This will leave you with a nice blank slate for your app:
Now, we want to make sure the window doesn't open too small when the app runs. Scroll to the top of the TreeView in the upper right of Glade, and select simple_player_window. Then in the editor below, click the common tab, and set the Width Request and Height Request.
There's also a small bug in the quickly-application template, but it's easy to fix. Select statusbar1, then on the packing tab, set "Pack type" to "End".

Save your changes or they won't show up when you try running the app! Then see how your changes worked by using the command:
$quickly run

A nice blank window, ready for us to party on!
Adding in Your Widgets
The main part of the user interface is going to have an area that divides between the list of media and the media when it is playing. There is widget for that called HPaned (Horizontal Paned). Find HPaned on the toolbox on the left, and click on it to active paint mode. Then click into the second open space in the main part of the window. This will put the HPaned in the window for you.

Make sure the HPaned starts out with an appropriate division of space. Do this by going to the General tab, and setting an appropriate number of pixels in Position property.
The user should be able to scroll through the list, so click on ScrolledWindow in the toolbar, and then click in the left hand part of the HPaned to place it in there.

Now add a toolbar. Find the toolbar icon in the toolbox, click on it and click in the top space open space. This will cause that space to collapse, because the toolbar is empty by default.
To add the open button click the edit button (looks like pencil) in Glade's toolbar. This will bring up the toolbar editing dialog. Switch to the Hierarchy tab, and click "Add". This will add a default toolbar button.

To turn this default button into an open button, first, rename the button to openbutton (this will make it easier to refer to in code). Then under Edit Image set Stock Id to "Open". That's all you need to do to make an open button in Glade.

Due to a bug in the current version of Glade, you might need to rename your tool bar button again. When you close the editor, look in the treeview. If the button is still called "toolbutton1", then select it, and use the general tab to change the Name property to "openbutton". Then save again.

Now if you use $quickly run again, you'll see that your toolbar button is there.

Coding the Media List
Making the Open Button Work
The open button will have an important job. It will respond to a click from the user, offer a directory chooser, and then build a list of media in that directory. So, it's time write some code.

You can use:
$quickly edit &

This will open your code Gedit, the default text and code editor for Ubuntu.

Switch to the file called "simple-player". This is the file for your main window, and the file that gets run when users run your app from Ubuntu.
First let's make sure that the open button is hooked up to the code. Create a function to handle the signal that looks like this (and don't forget about proper space indenting in Python!):

def openbutton_clicked_event(self, widget, data=None):
print "OPEN"


Put this function under "finish_initializing", but above "on_preferences_changed". Save the code, run the app, and when you click the button, you should see "OPEN" printed out to the terminal.

How did this work? Your Quickly project used the auto-signals feature to connect the button to the event. To use auto-sginals, simple follow this pattern when you create a signal handlder:

def widgetname_eventname_event(self, widget, data=None):

Sometimes a signal handler will require a different signature, but (self, widget, data=None) is the most common.

Getting the Directory from the User
We'll use a convenience function built into Quickly Widgets to get the directory info from the user. First, go to the import section of the simple-player file, and around line 11 add an import statement:


from quickly import prompts

Then add to your openbutton_clicked_event function the code to prompt the user so it looks like this:

def openbutton_clicked_event(self, widget, data=None):
#let the user choose a path with the directory chooser
response, path = prompts.choose_directory()

#make certain the user said ok before working
if response == gtk.RESPONSE_OK:
#iterate through root directory
for root, dirs, files in os.walk(path):
#iterate through each file
for f in files:
#make a full path to the file
print os.path.join(root,f)

Now when you run the app you can select a directory, and it will print a full path to each file encountered. Nice start, but what the function needs to do is build a list of files that are media files and display those to the user.

Defining Media Files
This app will use a simple system of looking at file extensions to determine if files are media files. Start by specifying what file types are supporting. Add this in finish_initializing to create 2 lists of supported media:

self.supported_video_formats = [".ogv",".avi"]
self.supported_audio_formats = [".ogg",".mp3"]

GStreamer supports a lot of media types so ,of course, you can add more supported types, but this is fine to start with.

Now change the openbutton handler to only look for these file types:

def openbutton_clicked_event(self, widget, data=None):
#let the user choose a path with the directory chooser
response, path = prompts.choose_directory()

#make certain the user said ok before working
if response == gtk.RESPONSE_OK:
#make one list of support formats
formats = self.supported_video_formats + self.supported_audio_formats
#iterate through root directory
for root, dirs, files in os.walk(path):
#iterate through each file
for f in files:
#check if the file is a supported formats
for format in formats:
if f.lower().endswith(format):
#make a full path to the file
print os.path.join(root,f)

This will now only print out files of supported formats.

Build a List of Media Files
Simple Player will create a list of dictionaries. Each dictionary will have all the information that is needed to display and play the file. Simple Player will need to know the File name to display to the user, a URI to the file so that the file can be played, and the type of media. So, we'll create a list and add a dictionary to each support type to it.

def openbutton_clicked_event(self, widget, data=None):
#let the user choose a path with the directory chooser
response, path = prompts.choose_directory()

#make certain the user said ok before working
if response == gtk.RESPONSE_OK:
#make one list of support formats
formats = self.supported_video_formats + self.supported_audio_formats

#make a list of the supported media files
media_files = []
#iterate through root directory
for root, dirs, files in os.walk(path):
#iterate through each file
for f in files:
#check if the file is a supported formats
for format in formats:
if f.lower().endswith(format):
#create a URI in a format gstreamer likes
file_uri = "file://" + os.path.join(root,f)

#add a dictionary to the list of media files
media_files.append({"File":f,"uri":file_uri, "format":format})
print media_files

Display the List to the User
A DictionaryGrid is the easiest way to display the files, and to allow the user to click on them. So import DicationaryGrid at line 12, like this:

from quickly.widgets.dictionary_grid import DictionaryGrid
Starting in Natty, every window has a ui collection. You can use it to access all of the widgets that you have defined in Glade by their names. So, creating the list of media files, you can remove any old grids in the scrolled window like this:

for c in self.ui.scrolledwindow1.get_children():
self.ui.scrolledwindow1.remove(c)
Then create a new DictionaryGrid. We only want one column, to the view the files, so we'll set up the grid like this:

#create the grid with list of dictionaries
#only show the File column
media_grid = DictionaryGrid(media_files, keys=["File"])

#show the grid, and add it to the scrolled window
media_grid.show()
self.ui.scrolledwindow1.add(media_grid)

So now the whole function looks like this:

def openbutton_clicked_event(self, widget, data=None):
#let the user choose a path with the directory chooser
response, path = prompts.choose_directory()

#make certain the user said ok before working
if response == gtk.RESPONSE_OK:
#make one list of support formats
formats = self.supported_video_formats + self.supported_audio_formats

#make a list of the supported media files
media_files = []
#iterate through root directory
for root, dirs, files in os.walk(path):
#iterate through each file
for f in files:
#check if the file is a supported formats
for format in formats:
if f.lower().endswith(format):
#create a URI in a format gstreamer likes
file_uri = "file://" + os.path.join(root,f)

#add a dictionary to the list of media files
media_files.append({"File":f,"uri":file_uri, "format":format})

#remove any children in scrolled window
for c in self.ui.scrolledwindow1.get_children():
self.ui.scrolledwindow1.remove(c)

#create the grid with list of dictionaries
#only show the File column
media_grid = DictionaryGrid(media_files, keys=["File"])

#show the grid, and add it to the scrolled window
media_grid.show()
self.ui.scrolledwindow1.add(media_grid)

Now the list is displayed when the user picks the directory.

Playing the Media
Adding the MediaPlayer
So now that we have the list of media for the users to interact with, we will use MediaPlayerBox to actually play the media. MediaPlayerBox is not yet integrated into Glade, so we'll have to write code to add it in. As usually, start with an import:

from quickly.widgets.media_player_box import MediaPlayerBox

Then, we'll create and show a MediaPlayerBox in the finish_initializing function. By default, a MediaPlayerBox does not show it's own controls, so pass in True to set the "controls_visible" property to True. You can also do things like this:


player.controls_visible = False
player.controls_visible = True

to control the visibility of the controls.

Since we'll be accessing it a lot, we'll create as a member variable in the SimplePlayerWindow class. Then to put it in the right hand part of the HPaned, we use the add2 function (add1() would put it in the left hand part).

self.player = MediaPlayerBox(True)
self.player.show()
self.ui.hpaned1.add2(self.player)


Connecting to the DictionaryGrid Signals
Now we need to connect the dictionary_grid's "selection_changed" event, and play the selected media. So back in the openbutton_clicked_event function, after creating the grid, we can connect to this signal. We'll play a file when selection changes, so we'll connect to a play_file function (which we haven't created yet). This goes at the end of the function:

#hook up to the selection_changed event
media_grid.connect("selection_changed", self.play_file)
Now create that play_file function, it should look like this:

def play_file(self, widget, selected_rows, data=None):
print selected_rows[-1]["uri"]

Notice that the signature for the function is a little different than normal. When the DictionaryGrid fires this signal, it also passes the dictionaries for each row that is now selected. This greatly simplifies things, as typcially you just want to work with the data in the selected rows. If you need to know more about the DictionaryGrid, it passes itself in as the "widget" argument, so you can just work with that.

All the function does now is get the last item in the list of selected rows (in Python, you can use -1 as an index to get the last item in a list. Then it prints the URI for that row that we stored in the dictionary back in openbutton_clicked_event.
Setting the URI and calling play()
Now that we have the URI to play, it's a simple matter to play it. We simply set the uri property of our MediaPlayerBox, and then tell it to stop playing any file it may be playing, and then to play the selected file:

def play_file(self, widget, selected_rows, data=None):
self.player.stop()
self.player.uri = selected_rows[-1]["uri"]
self.player.play()

Now users can click on Videos and movies, and they will play. Since we decided to show the MediaPlayerBox's controls when we created it, we don't need to do any work to enable pausing or stopping. However, if you were creating your own controls, you could use player.pause() and player.stop() to use those functions.


Connecting to the "end-of-file" Signal
When a media files ends, users will expect the next file played automatically. It's easy to find out when a media file ends using the MediaPlayerBox's "end-of-file" signal. Back in finish_initializing, after creating the MediaPlayerBox, connect to that signal:

self.player.connect("end-of-file",self.play_next_file)

Changing the Selection of the DictionaryGrid
Create the play_next_file function in order to respond when a file is done playing:

def play_next_file(self, widget, file_uri):
print file_uri

The file_uri argument is the URI for the file that just finished, so that's not much use in this case. There is no particularly easy way to select the next row in a DictionaryGrid. But every widget in Quickly Widgets is a subclass of another PyGtk class. Therefore, you always have access to full power of PyGtk. A DictionaryGrid is a TreeView, so you can write code to select the next item in a TreeView:

def play_next_file(self, widget, file_uri):
#get a reference to the current grid
grid = self.ui.scrolledwindow1.get_children()[0]

#get a gtk selection object from that grid
selection = grid.get_selection()

#get the selected row, and just return if none are selected
model, rows = selection.get_selected_rows()
if len(rows) == 0:
return

#calculate the next row to be selected by finding
#the last selected row in the list of selected rows
#and incrementing by 1
next_to_select = rows[-1][0] + 1

#if this is not the last row in the last
#unselect all rows, select the next row, and call the
#play_file handle, passing in the now selected row
if next_to_select < len(grid.rows):
selection.unselect_all()
selection.select_path(next_to_select)
self.play_file(self,grid.selected_rows)

Making an Audio File Screen
Notice that when playing a song instead of a video, the media player is blank, or a black box, depending on whether a video has been player before.
It would be nicer to show the user some kind of visualization when a song is playing. The easiest thing to do would be to create a gtk.Image object, and swap it when for the MediaPlayerBox when an audio file is playing. However, there are more powerful tools at our disposal that we can use to create a bit richer of a user experience.

This section will use a GooCanvas to show you how to compose images and text together. A GooCanvas is a very flexible surface on which you can compose and animate all kinds of 2D experiences for users. This tutorial will just scratch the surface, by combining 2 images and some text together. We'll show the Ubuntu logo image that is already built into your project, but a musical note on top of that for some style, and then put the current song playing as some text.

Create a Goo Canvas
Naturally, you need to import the goocanvas module:

import goocanvas

Then, in the finish_initializing function, create and show a goocanvas.Canvas:

self.goocanvas = goocanvas.Canvas()
self.goocanvas.show()

The goocanvas will only be added to the window when there is an audio playing file, so don't pack it into the window yet. But let's an image to the goocanvas so we can make sure that we have the system working.

Add Pictures to the GooCanvas
Add an image to the goocanvas by creating a goocanvas.Image object. First, we'll need to create a gtk.Pixbuf object. You can think of a gtk.Pixbuf as an image stored in memory, but it has a lot of functions to make them easier to work with than just having raw image data. We want to use the file called "background.png". In a quickly project, media files like images and sounds should always go into the data/media directory so that when users install your programs, the files will go to the correct place. There is a helper function called get_media_file built inot quickly projects to get a URI for any media file in the media directory. You should always use this function to get a path to media files, as this function will work even when your program is installed and the files are put into different places on the user's computer. get_media_file returns a URI, but a pixbuf expects a normal path. It's easy to fix this stripping out the beginning of the URI. Since it was created for you, can could also change the way get_media_player works, or create a new function, but this works too:

logo_file = helpers.get_media_file("background.png")
logo_file = logo_file.replace("file:///","")
logo_pb = gtk.gdk.pixbuf_new_from_file(logo_file)


You don't actually pass the goocanvas.Image into the goocanvas.Canvas, rather you tell the goocanvas.Image that it's parent is the rootA_items of the goocanvas. You can also set other properties when you create it, such as the x and y coordinates, and of course the pixbuf to use:

root_item=self.goocanvas.get_root_item()
goocanvas.Image(parent=root_item, pixbuf=logo_pb,x=20,y=20)


Show the GooCanvas When a Song is Playing
So now we want to take the MediaPlayerBox out of the HPaned when a song is playing and show the goocanvas, and also visa versa. We can easily extract the format of the file because we included it in the dictionary for the row when we created the DictionaryGrid in the openbutton_clicked_event function:

format = selected_rows[0]["format"]

We can also get a reference to the visual that is currently in use:

current_visual = self.ui.hpaned1.get_child2()

Knowing those two things, we can then figure out whether to put in the goocanvas.Canvas or the MediaPlayerBox. So the whole function will look like this:

def play_file(self, widget, selected_rows, data=None):
self.player.stop()
format = selected_rows[0]["format"]
current_visual = self.ui.hpaned1.get_child2()

#check if the format of the current file is audio
if format in self.supported_audio_formats:
#if it is audio, see if the current visual is
#the goocanvas, if it's not, do a swapperoo
if current_visual is not self.goocanvas:
self.ui.hpaned1.remove(current_visual)
self.ui.hpaned1.add2(self.goocanvas)
else:
#do the same thing for the player
if current_visual is not self.player:
self.ui.hpaned1.remove(current_visual)
self.ui.hpaned1.add2(self.player)

#go ahead and play the file
self.player.uri = selected_rows[-1]["uri"]
self.player.play()



Add another Image to Canvas
We can add the note image to the goocanvas.Canvas in the same way we added the background image. However, this time we'll play with the scale a bit:


note_file = helpers.get_media_file("note.png")
note_file = note_file.replace("file:///","")
note_pb = gtk.gdk.pixbuf_new_from_file(note_file)
note = goocanvas.Image(parent=root_item, pixbuf=note_pb,x=175,y=255)
note.scale(.75,.6)

Remember for this to work, you have to put a note.png file in the data/media directory for your project. If your image is a different size, you'll need to tweak the x, y, and scale as well.

(BTW, thanks to Daniel Fore for making the artwork used here. If you haven't had the pleasure of working Dan, he is a really great guy, as well as a talented artist and designer. He's also the leader of the #elementary project.)

A goocanvas.Image is a goocanvas.Item. There are different kinds of Items and many of interesting visual things you can do with them. There are items like shapes and paths. You can change things like their scale, rotation, and opacity. You can even animate them!
Add Text to the goocanvas.Canvas
One kind of goocanvas.Item is goocanvas.Text. You create it like a goocanvas.Image. We won't use any text when we create it, because that will be set later when we are playing a song. Since the goocanvas.Text will be accessed from the play_file function, it should be a member variable for the window. So after adding the note image in the finish_initializing function, you can go ahead and add the text.

self.song_text = goocanvas.Text(parent=root_item,text="", x=5, y=5)
self.song_text.set_property("font","Ubuntu")
self.song_text.scale(2,2)

Update the Text
The text property of the goocanvas.Text object should then be set when an audio file is played. Add a line of code to do this in the play_file function, after you've determined the file is an audio file:

self.song_text.set_property("text",selected_rows[0]["File"])

Now when an audio file is playing the title shows.

Moving the Media Player Controls
You've probably noticed a pretty bad bug, when an audio file is playing the user can't access the controls for the media player. Even if that were not the case, are 2 toolbars, one for the controls, and one that only has the openbutton. Also, the controls are shifted over because of the DictionaryGrid, so the time labels are not visible by default.

Fortunately, PyGtk let's you move widgets around really easily. So, it's possible to write a little code that:
  1. Creates the openbutton in code instead of glade
  2. Takes the toolbar for the MediaPlayer controls out of the MediaPlayer
  3. Inserts the openbutton into the controls exactly where we want it
  4. Adds the controls back into the window
To start, go back to Glade, and delete the toolbar you added before. Replace it with an HBox. When prompted, set Number of Items to 1. It should be named hbox1 by default. After adding the HBox choose the packing tab, and set Expand to "No". Otherwise, the HBox will take up all the room it can, making the toolbar huge when you add it back in.
Then, back in finish_initializing, after creating the MediaPlayerBox, remove the controls:

self.player = MediaPlayerBox(True)
self.player.remove(self.player.controls)

Then, create a new openbutton:

open_button = gtk.ToolButton()

We still want the open button to be a stock button. For gtk.ToolButtons, use the set_stock_id function to set the right stock item.

open_button.set_stock_id(gtk.STOCK_OPEN)

Then show the button, and connect it to the existing signal handler.

open_button.show()
open_button.connect("clicked",self.openbutton_clicked_event)

The MediaPlayerBox's controls are a gtk.Toolbar object. So, insert the open_button into the controls using the gtk.Toobar classes insert command. Pass in a zero to tell the gtk.Toolbar to put open_button first. Then you can show the controls, and pack them into the window:

self.player.controls.insert(open_button, 0)
self.ui.hbox1.pack_start(self.player.controls, True)

Now users can use the controls even when audio is playing!
Conclusion
This tutorial demonstrated how to use Quickly, Quickly Widgets, and PyGtk to build a functional and dynamic media player UI, and how to use a goocanvas.Canvas to add interesting visual effects to your program.

The next tutorial will show 2 different ways of implementing play lists, using text files, using pickling, or using desktopcouch for storing files.

API Reference
PyGtk
Quickly Widgets
Reference documentation for Quickly Widgets isn't currently hosted anywhere. However, the code is thoroughly documented, so until the docs are hosted, you can use pydocs to view them locally. To do this, first start pydocs on a local port, such as:
$pydocs -p 1234

Then you can browse the pydocs by opening your web browser and going to http:localhost:1234. Search for quickly, then browse the widgets and prompts libraries.

Since MediaPlayerBox is not installed yet, you can look at the doc comments in the code for the modules in natty-branch/quickly/widgets/media_player_box.py.
GooCanvas
GStreamer
MediaPlayerBox uses a GStreamer playbin to deliver media playing functionality. GStreamer si super powerful, so if you want to do more with it, you can read the docs.

Read more
Rick Spencer

Pithos of Rain

During my normal Sunday morning chill out with a cup of coffee this morning, I saw a tweet from Ken VanDine go by about Pithos, a native Pandora client for Ubuntu. I have a Pandora account, and love to use it on my phone, but on Ubuntu I had to go through the Pandora web interface, so I didn't use it as much.

I'm using it right now, and I'm chuffed. I'd love to see this app go through the ARB process so maverick users can more easily access it. And I'd love to see it I'm psyched to hear that it is in Universe or and even Debian for Natty.

Read more
Rick Spencer



Quickly has started to unlock productivity for me in unexpected ways. I've mentioned about writing my own development tools, like bughugger, and slipcover. Last week I extended this to writing my own productivity apps. In this case, I wrote an app to replace my Tomboy usage to focus specifically on the functions in Tomboy that I actually used. The above video shows that app, "Daily Journal". It's available in my PPA.

In my next posting, I'll show how I used quickly.widgets.text_editor to create Daily Journal.

Read more
Rick Spencer

Go Here to Learn to Program from MIT

I run into folks who want to get started programming, but they "don't know a language". If you are in this camp, I highly recommend the online course from MIT. It's designed for people with no prior programming experience, and it's Python!


After the first few lessons, you'll know enough Python to start a Quickly app!.

Read more
Rick Spencer

A couple of months ago I created a Quickly template with the goal of making it easy and fun to get started my games. The template doesn't have any "add" or "design" commands, but it does have all the other commands. The template creates a functioning arcade-style game, and then you provide you own artwork and start hacking the code to make your own gameplay.


$quickly tutorial ubuntu-pygame is the best way to get a detailed introduction into getting started making your own game, but here's some video of hacking the code. I hope it inspires you to try your hand at creating your own games.

Part 1: Create the game, copy in your artwork, and make the guy work the way you want


Part 2: Program the enemies


Part 3: Create a power up sprite, and manage collisions


Read more
Rick Spencer

Quickly: 90 Seconds to Your PPA




Here's a quick video showing taking a finished Quickly app, setting the desktop and setup.py file, and then uploading to a PPA using $quickly share

Read more
Rick Spencer


On Saturday I received an email from a developer name Ryan. He was using Quickly and Quickly Widgets to create a task list application. CouchGrid seemed to suit, but due to the fact that there are no documents for it, he naturally had some questions about how to proceed. His project is called PyTask, and so far, I like it. It's a very simple set up, and just works in terms of data persistence and syncing across desktops.

Looking at the App, it was clear that there were a few more features that DictionaryGrid needs to really rock, though:
  1. It needs a DateColumn to handle the "due" column. Users would want to set this with a gtk.Calendar widget.
  2. It needs a ComboColumn to handle the "priority" column. Users would want to pick from a list of valid predefined priority values rather than free input text. This will be interesting to create a nice API for. I suppose application developers will want to pass in just a list of strings to the column. I think this is doable, but may take some refactoring as currently there is no intuitive way to get a hold of a column and set a property on it.
  3. Both of these will require new GridFilter functionality. In fact, I have been waiting for a reason to refactor this part of Quickly Widgets, as the GridFilterRows are hard coded to use specific widgets, and this should be flexible.

Anyway, as it is, I am using PyTask, I hope Ryan get's it into a PPA soon. I like the simplicity. Ryan and I are currently collaborating on creating the new functionality in DictionaryGrid that PyTask needs. Open Source FTW!

Read more
Rick Spencer

You probably saw that didrocks released another update for Quickly. It's chock full of bug fixes and tweaks based on the feedback from the last release.

About a week ago I made some updated intro videos to show Quickly in action, and highlight some key changes between Quickly in Karmic and Quickly in Lucid. They are all available in HD, so you switch to that when they start playing, it makes them waaay easier to read.

Part 1: Create a project and use Glade to edit the UI
Here you see that you use "quickly create ubuntu-application" instead of "quickly create ubuntu-project" to create an app. You also use "quickly design" instead of "quickly glade" to design the UI.


Part 2: Using CouchGrid
One of the key differences here is that CouchGrid is now in the quickly.widgets module instead of the desktopcouch module. The CouchGrid moved into quickly.widgets because it now extends the DictionaryGrid class. This brings a lot benefits:
  1. Automatic column type inference
  2. Ability to set column types so you get the correct renderers
  3. Correct sorting (for instance 11 > 9 in IntegerColumn, but "11" < "9" in string columns
And of course you get all the goodness of automatic desktopcouch persistence.


Part 3: Using GridFilter
GridFilter is a new class that provides automatic filtering UI for a DictionaryGrid or descendant such as CouchGrid.

Read more
Rick Spencer

Didrocks released quickly 0.4 yesterday. What a great contribution from didrocks! I suspect he his work will help tons of people have a really fun time writing Ubuntu apps. Read about the release in his detailed blog post.




In the meantime, I made a cheesy video last night, showing some of the changes in quickly, and how the new CouchGrid and GridFilter work.

[Note that it takes blip.tv a bit of time to render out a high def video like this, so if the video is not yet working, you can check back later.]

[D'oh .... stupid blip.tv bailed on encoding my video. I'll try again with smaller files. Stay tuned]

Read more