Ok, PartPort is not my favorite class name. Let me introduce it, and then you can come up with better names.
PartPort is an object I've had in my UI bag for a while, under different names at times. One of the things that was widely appreciate about the Widgetry Tab widget, was that it held on to each of the panes for each tab, and then just switched which one was showing. A common pattern done with a Tab widget in classical VisualWorks, is that you grab the client area (canvas) of the tab control and then use a builder to somehow update the view, when the tab changes. This is for the case where the different tabs are heterogenous. The problem with this is... well, it has many. Getting builders to work the right way, and repeatedly correct, can be hair pulling. Which builder do you use? And what if it caches its components, and reuses them on the wrong page?
So keeping the different view objects is definitely a win in cases like this. You build them up at front (or on demand maybe) and then just switch between them. You don't have to figure out how to save state or anything. The view is still live, just "off screen."
One draw back with this implementation though, is that you have to use it with tabs. There might be other ways to select which view is "on screen." For example, the properties tab for Packages in the browser. It uses a list on the left side to flip between different property views. You might want to use radio buttons somewhere. Or drive them in an indirect way from other changes in your application. This argues for a separation between this "stage" where one view or another plays the lead role, and the actual selection machinery.
That's where PartPort comes in. You can find it in Browser-BaseUI package; in time I intend to move it over into the base UI framework. What does it look like? Here's an example of using it in the RB looks like:
propertyPort
| port |
port := PartPort new.
port
partCreationBlock: [:propertyTool | self newPropertyView: propertyTool].
port selectionSlot: propertiesList selectionHolder.
^port
There's two main parts to the "port". One is a selection slot. This can be either an ObservedValue or ValueModel. It figures out what it needs to do. The other is the partCreationBlock. The partCreationBlock's job is to invoke code that will return a VisualPart for the argument. The port remembers these as they're created. As the selection is changed, the view automatically switches to the subPart associated with the current selection. If there is none associated yet, it invokes the partCreationBlock.
Some don't like to bother with all of these models and stuff. A more direct windget manipulation is preferred. The nice thing is that this scales simply to that kind of scenario. You can just put views in the selectionSlot (you don't even have to know there's a that slot thing in the background, you just send selection: to the port). And then you set yoru partCreationBlock to be:
port partCreationBlock: [:part | part yourself]
This guy is used in the lower half of the browser, at at least two levels. It replaces all of the builder stuff that used to be there. All wrapped up in one nice object. I removed much code in the browser. I may yet use it for the browser's "buffers", but one thing at a time.