MeBox: Canvas System
Let me take a moment to brag about the canvas system I hacked together for MeBox, because it's just too cool. A demo of the canvas library is available if you want to play.
bmovl2 is a video filter for MPlayer and works by storing an arbitrary number bitmaps (YUV with alpha channel) with your standard attributes like visibility and position, but also z-index and alpha level. Each bitmap has an id, and these attributes can be adjusted by issuing commands to bmovl2 over a fifo. So if we had a menu that we wanted to slide in from off screen and fade in, we can do that fairly easily. (This is not actual code, but it's close to the real thing.)
bitmap = make_menu_bitmap()
# Assume 800x600 display, we move the image off screen.
bmovl2.move("menu", (800, 200))
# Set alpha to 0 (make invisible)
# Now transition from off screen, moving left 8 pixels at
# a time, and fading in 2%
for (x, alpha) in zip(range(800, 400, -8), range(0, 255, 5)):
# Tell bmovl2 to do the next sequence of commands
# all in one shot.
bmovl2.move("menu", (x, 200))
You can see that bmovl2 is practically a canvas by itself. All it needs is some classes wrapping all that functionality.
Aside from an object-oriented interface, the main feature the canvas system adds to bmovl2 is container objects. Having a widget as a single bitmap may not be very practical if elements of the widget need to change frequently. In this case, we create a container object and add a bunch of separate bitmaps to it. The same operations that can be done to a bitmap can also be done to a container. The canvas system also abstracts some of the manual labor of bmovl2 away from the programmer.
So, with the canvas system and parts of the GUI built on top of that, the above code looks something like this in MeBox:
from core import gui
menu = make_menu()
# Now the menu is visible to the user
gui.transition(menu, "slide-x", 400)
gui.transition(menu, "fade", 255)
Since a picture is worth a thousand words ...
This one of the prototypes for MeBox's main menu. (It does work insofar as you can move the cursor on the menu, but not much has really been implemented yet.) There are 10 canvas objects in this example: the background image, the menu frame, one object for each of the menu items (including the separator), and one for the blue selection image.
Each object's z-index specifies the order the bitmaps get painted. From the lowest layer to the top, there are: the background, menu frame, menu selector, menu items. So, when we want to select a new item on the menu, it's stupidly easy: just move the menu selector image to the correct location.
The canvas supports real transparency too. The menu frame is a PNG, and the background of the menu is a black background with roughly 50% alpha. If we hide the background image, whatever is underneath (the movie MPlayer is playing) will show through, properly alpha blended. Here's what I mean:
In the shot above, the meu shows the contents of my Lost and Delirious directory. The out-of-place looking image on the upper left corner is a thumbnail of the movie generated by the VFS layer. (I was testing it out when I took this shot.)
By the way, when you hit the menu button, the menu slides and fades on or off the screen with a smooth transition effect like I described earlier. It looks really cool; it's worth getting excited about. :)