For the last two releases, most of the "custom" widgets we've added to the system are done in a way different than classical VisualWorks widgets. Examples are the new comparison tool, the store feedback widgets, the bundle structure tool, and the prerequisite tool. These have served as a testground to try out some different approaches than classically found in VisualWorks. One the questions that comes up from some colleagues is "so, if you're doing widgets a new way, what is that way?"
The rest of this post is about one aspect of that "different" way. As I've wandered far and wide through other widget frameworks, I've learned that a) "MVC" is very popular and b) for every different framework there is a new and unique interpretation of "controller." One of the "different" ways I've been building widgets is without controllers. There are two aspects to deal with in this "controllerless" new world. One is how we deal with mouse interaction, the other keyboard interaction. The aspect of interest here today is keyboard interaction.
The original VisualWorks widget framework based on MVC, sometimes moniker'ed "wrapper," didn't have a keyboard focus concept. What ever widget was below the mouse and was willing, was where your keyboard input went. Round about version 2.0 of VisualWorks (then an add-on product to ObectWorks 4.1), the idea of keyboard focus got added. Which is a long winded way of saying, I didn't design this, I just learned how to work it. To have a controllerless keyboard savvy widget, you should add the following methods to your VisualPart subclass. The example code is what the AbstractComparisonRollupView does with them, as examples.
The last thing you have to do, is make the KeyboardProcessor aware that you are interested in keyboard. This is usually done with a line something like
theWindow keyboardProcessor addKeyboardReceiver: myView
This last requirement in particular I consider the most onerous, and we hope to make this more "snappable" real soon. You shouldn't have to worry about registering your widgets with the window (and subsequently unregistering them when cleanup is required).