I'm still loving the new job. As part of it I've been developing a GUI framework which integrates with and uses some of the design patterns from pyglet. GUIs may be defined wholly in Python code or in a combination of Python and XML files. There's the beginnings of a GUI designer tool to create the XML files. A simple, dumb example:
<frame is_transparent="true">
<frame is_transparent="true" id="left-frame" width="50%" height="100%">
<vertical align="top" halign="center" padding="20">
<frame scrollable="true" width="256" height="256" class="draggable">
<image file="kitten.jpg" id="kitten" />
</frame>
<frame scrollable="true" width="128" height="128" class="draggable">
<xhtml>
<h1>Synopsis</h1>
<p style="font-size:12px">Lorem ipsum dolor sit amet consectetuer
adipiscing elit. Suspendisse vel tellus. Nam sem massa, accumsan id,
sollicitudin at, feugiat non, felis. Etiam nunc. Nam augue mauris,
semper in, hendrerit vitae, congue viverra, massa. Suspendisse at lacus.
Proin mollis dui ut sem. Donec auctor, pede nec hendrerit tincidunt,
lacus diam laoreet diam, ut varius odio felis eget enim. Curabitur dui
sem, rutrum sed, mattis eu, rhoncus ultrices, erat. Maecenas eu tellus.
Vivamus bibendum facilisis orci. Aliquam risus. Aliquam erat. Aenean
dignissim fringilla diam. Quisque dapibus, nulla non consectetuer iaculis,
velit urna ornare orci, quis sodales neque sapien id turpis. Etiam urna
lacus, vulputate congue, vulputate in, aliquet vitae, tellus. Maecenas
sem. Ut sed massa. Etiam non ipsum eget nibh cursus placerat.
Vivamus at mauris.
</p>
</xhtml>
</frame>
<button class="draggable" text="Drag me, press me!" id="press-me" />
<textinput value="Enter text" width="128" />
<movie file="/Users/richard/Desktop/movies/Sunshine SD.mov" />
</vertical>
</frame>
<frame class="droppable" width="50%" height="75%" x="512" y="128">
<label>Drop here!</label>
</frame>
</frame>
So this splits the window into two halves. On the left half we have a picture of a kitten (larger than the containing frame and scrollable), some XHMTL (again scrollable), a button to click, a text input field and a movie. Take note of the classes and ids, they're used...
And then some Python code to make this GUI do fun things:
from pyglet.window import *
from pyglet import clock
from pyglet.gl import *
from pyglet import media
import gui
from gui import event, dialog, dragndrop, anim
window = Window(width=1024, height=768, vsync=False)
gui = gui.GUI.fromXML(window, 'test_gui.xml')
window.push_handlers(gui)
@gui.select('frame')
def on_mouse_press(widget, x, y, buttons, modifiers):
if not buttons & mouse.MOUSE_RIGHT_BUTTON: return event.EVENT_UNHANDLED
def _f(*args):
print 'Dialog returned', args
dialog.FileDialog(gui, 'Select file to open', _f).run()
return event.EVENT_HANDLED
gui.push_handlers(dragndrop.DragHandler('.draggable'))
@gui.select('button')
def on_click(widget, x, y, button, modifiers):
print 'BUTTON PRESS', widget
return event.EVENT_UNHANDLED
@gui.select('button#press-me', 'on_click')
def on_press_me(widget, x, y, button, modifiers):
fr = widget.getGUI().getByID('left-frame')
if fr.scale == 1.:
anim.TranslateProperty(fr, 'scale', .5, duration=.5)
else:
anim.TranslateProperty(fr, 'scale', 1., duration=.5)
return event.EVENT_UNHANDLED
@gui.select('.droppable')
def on_drop(widget, x, y, button, modifiers, element):
element.reparent(widget)
widget.bgcolor = (1, 1, 1, 1)
return event.EVENT_HANDLED
@gui.select('.droppable')
def on_drag_enter(widget, x, y, element):
widget.bgcolor = (.8, 1, .8, 1)
return event.EVENT_HANDLED
@gui.select('.droppable')
def on_drag_leave(widget, x, y, element):
widget.bgcolor = (1, 1, 1, 1)
return event.EVENT_HANDLED
while not window.has_exit:
clock.tick()
window.dispatch_events()
media.dispatch_events()
glClearColor(.2, .2, .2, 1)
glClear(GL_COLOR_BUFFER_BIT)
gui.draw()
window.flip()
So the fun bits of this code is where we assign behaviors to gui elements based on the CSS-style selectors. All items that are of class "draggable" are draggable, and the right-hand frame is designated a drop area. The kitten, XHTML and button are draggable into that frame. The frame highlights as you hold a dragged item over it. A right-mouse click will open a file dialog. A click on the "press me" button is fun - it scales the left-hand frame (smoothly animated and still fully interactive even during the animation).
I have permission to release this code, which I will eventually do once I have some spare tuits here at work. The designers here have just handed me some more storyboards to implement :)
Speaking of whom -- when they heard about the addition of "wet floor" to the OS X dock, the reaction was quite fun. They can be quite bitchy about designers over-using the latest cool effect (see also spiral logos suddenly abounding when Illustrator got the spiral tool). "Do Apple designers have a big red 'wet floor' button on their computer or something?"
Wet floor, anyone?