[Cuis] How Theme Works

Casey ransberger casey.obrien.r at gmail.com
Fri May 18 19:08:34 CDT 2012


First: a touch of history.

When Squeak development started again in earnest, I wanted to keep Polymorph working. I failed. Polymorph is a big system and it had been absorbed into Pharo, carrying more and more Pharoisms as time progressed. It got harder and harder to keep it working in Squeak.

One of the reasons Polymorph was so big was that it was designed during a period when Squeak wasn't changing much. This meant adding classes that duplicated the functionality of other Morph subclasses but added theming.

A question I arrived at: if theming could be integrated into the core, how much less code would we need to do it? Cuis seemed an ideal place to explore that line of inquiry so I gave it a shot.

Here's what I ended up doing. I scoured the system looking for hard coded colors. At first my focus was just on color. I thought that would be a good test of the idea. So I searched for where colors were represented, starting by looking at class refs to Color. It went from there. I redirected representations to a new class, Theme.

The other work had to do with shout coloring. If I remember right, you can probably find that on Theme as #shout, but don't quote me on that (still haven't got Cuis in front of me.)

The basic idea ended up being this. Theme acts a lot like a singleton, but not quite. IIRC it holds onto a classvar that keeps track of the current theme's class symbol and delegates to the current theme (which by default is Theme.) The methods on Theme (intended to be overridden by subclasses) represent things that used to be scattered willy-nilly all over the UI system in a "hard coded" way. 

Theme is also intended, in another way, to have a selector to describe each and everything that we've made skinnable (except binary assets, which need to be handled differently.) This is in part to make the default skin work at all, and also to provide a reference to what can currently be skinned (read: overridden by a subclass.)

There are in fact probably lots of sends throughout the image still which could make more sense vectoring through Theme, but I stopped looking when I felt I had a good proof of concept, hoping that the community might help out where I left off.

The basic process is, find a theme you like. Subclass it. Override what you want to change, using Theme as a reference to what selectors the rest of the system is looking for, and BEWARE: you're introducing changes to the Morphic render loop when you make your new theme current, so it's a good idea to save the image before doing so. This was a problem with hacking on Polymorph themes as well, FWIW.

When you're ready to take the plunge by trying what you've done, send #beCurrent to your new theme subclass. Some windows will not pick up the changes you made (something I'd like to fix eventually) but new windows should.

I had a lot of fun getting the infrastructure in place, but Theme should be considered neither complete nor ideal. It's a good starting point:)

Let me know if you have any more questions on the subject, and I'll do what I can to help out. Hopefully this will clarify at least the basic idea.




More information about the Cuis mailing list