In the new browsers, we've made the tabs a bit more managed. Historically there were three types of players in the "lower half" of the browser.
-
CodeModel - the top level object for the bottom half
- CodeToolSelectionPolicy - the tabs that show up in the code model
- CodeTool - what shows up below a given tab
The names aren't the most telling, in particular the policy one, but you get the picture. The policy objects had an API for determining whether they should be visible or not, what their label was, and what tool should show up below them. This indirection led to some problems though. It turns out that, as you want to make the information shown on the tabs and more informative, you end up wanting to know more and more about what's going on in the tool. But the policy didn't know about it's tool. It just nominated which class of tool should be there. So you ended up instantiating a temporary tool to find out stuff from it, or duplicating lots of logic.
At one point, I decided less might be more. So the new browsers actually just keep a list of tools. The tool classes to be instantiated are registered on the class side with a <tool> tag. These tool objects assume the responsibilities of the old SelectionPolicies. The respond to #isActive to determine if they currently show up. They can nominate any #tabGraphic (with supporting methods to just offer a #tabName and/or a #tabIcon). They can also collaborate with the code model when it's updating the selection and coming up with a default tab to select by responding to #isDefaultSelectionCandidate.
This latter is a good example of being able to do more by having less. One thing the new browser does is make comments more preferrential. Dave Buck gets credit for encouraging me to do this. And in general I really like it. Hopefully we can do some more work to make the comment info shown even more informative. One problem we run into with this approach though, is that not eveyone wants to write comments. If the goal of the browser when it jumps to a class, is to show you the best information it can for that class, but the comment is empty, then it's failed. So by having this kind of logic, the comment tab can be a bit more selective about when it would like to be a default selection. If it finds that the comment it would show really isn't that good (i.e. it's empty), then it can defer selection to the next in line, which is the definition tool.
What about existing extensions that add tools to the browser? Most plugin packages have a 1:1 relationship between a SelectionPolicy subclass and CodeTool subclass. The CodeToolSelectionPolicy class is still there, and it intercepts the addCodeSelectionPolicy and attempts to rewrite the code for you based on that assumption. It can't derive the logic you may have had in your custom SelectionPolicy, but it does point it out, and get you ready to implement the #isActive method. One nice thing about this, is that an extension package, just adds the new APIs. It can keep the SelectionPolicy subclass if it wants, and be loadable in both the old and new.
The upshot of this change, is that I was able to remove a whole class heirarchy (minus leaving the top in there). Get tighter behavior between the code model and tabs, more informative tab lables. And get rid of at least one (maybe two) instance variables in CodeModel.
I am of course intersted in hearing how well loading extension tools goes for others.