UILookPolicy and BuilderSpecs
Return to home page
Comments Loading...
2007-10-06

I thought it might be useful to talk about an idea I've been toying with recently. You may have read Travis's post previously on how to make a View be its own Controller to reduce the chatter between the 1:1 objects (usually 1:1). I've found that pattern to be quite useful and I used it in Gizmo and Searchlight (formerly SmallSpotlight).

But one of the biggest problems with the "Wrapper" UI framework (hence forth I'll just call it "the UI") is that the ability to construct widgets dynamically and change their properties is completely lacking. At one point, somebody courageously set forth to make widget building codified. They make the Spec objects.. you've got your InputFieldSpec and your ComboBoxSpec and your SpinButtonSpec and this is where things get interesting. They don't build widgets themselves - in fact, they're dumb data structures for the UILookPolicy classes.

A UILookPolicy exists for each Look and Feel in the system. This is the nerve center of how widgets and their wrappers are constructed. However, it must use a UIBuilder to construct them. That means there's no easy way to use these things dynamically.

So what we need to do is copy what UILookPolicy, UIBuilder and Spec classes were about and turn them in to widgets. These widgets would:

So essentially we're talking about dynamic specs that live in the widget tree and respond to all the messages you always wished them to respond too.

This isn't as hard as it might sound to some people. The blueprints are laid out in UILookPolicy - if you can decipher the gibberish code. Some of the trickier bits are in ComboBox or SpinButton, where a single view does not exist to build these widgets but a set of composite views are used to construct them with an elaborate wrapper structure with assumptions about 'container container' call changes and the like.

What that means is, the dynamic widget must create underneath it, the correct kinds of wrappers such that it works as if it were spat out of a UIBuilder.

So I've been toying with this, trying it out, building widgets this way. I'm not quite ready to release any code for it yet - since I haven't used the code to build anything real yet - but I'm feeling semi-quietly-optimistic about this.

As an added bonus, in this exercise I also gave each of my "widgets" their own coordinate system, so that you don't have to wrap them in wrappers just to position them on the screen. Each widget can use a block of code (or an object that responds to the protocol) to decide how to layout any children it has and each widget also has another block of code to confine it within the offered space given to it by its container. This idea is again borrowed from Gizmo and Travis's discussion on FunctionalLayouts.

That's not to say that all these ideas are great or right, only time and actual use will tell. But there is a quick and dirty way to test whether an idea has a good grounding or not - look at the competitors. Do widgets know where they are on the screen in other UI paradigms? Yes, just about every UI framework has that. Can widgets use a callback to reposition themselves? Yes, most UI frameworks do that. Can widgets change properties dynamically? Yes, just about all UI frameworks can do that for most properties.

So this may be a much needed programming API face-lift for "the UI" - or it may not be. I'm only working on this stuff part time, as my primary focus is on Seaside. However, I hope to build some simple UI apps over time to see whether these ideas are worth sharing to a wider audience.. heck, if the classes are even worth commenting.

I've only been working on the code for a week and I can already dynamically build and configure input fields, comboboxes, custom widgets, spin boxes, text areas, scrolling areas with dynamically added/moved/removed widgets, object lists. Actually the list is longer than that, but it just goes to show, reusing what we have and know works is easier than we previously thought.

I'll keep my blog posted with updates on how this spike/experiment progresses.