Today we talk about some big changes that are pretty much easy to explain, and a bit of history
No Controllers.
That pretty much says it all. Pollock no longer uses Controllers. The original MVC actually stopped being used in VisualWorks a long time ago, and the last vestiges of it were removed by version 2.5. Wrapper hasn't used classic MVC for almost a decade.
The C (Controller) in MVC was always poorly understood, particularly since there hasn't been a real implementor of the original for so long. Originally, the Controller was an object which got and dispatched keyboard and mouse events. It was based on polling. Going back to it's true origin, it had guts that polled the hardware looking for these mouse and keyboard things to happen, then reified them into behaviors that were then dispatched to the various panes. Indeed, the controller was passed from one pane to another as each one needed/wanted to be the focus of these input events.
Once VisualWorks moved from sitting directly on the hardware, a long time ago, to sitting on top of operating systems, this kind of need to interact and poll hardware was no longer needed. The Controller continually morphed, first becoming a polling engine that acted on operating system (vs hardware) events that still passed itself around, then to a subsidiary to an event dispatcher that itself polled, no longer needing to be passed around, and finally, the event dispatcher no longer polled.
In effect, the event dispatcher became the locus of event dispatching, and the Controller simply got hacked to death, carrying more and more cruft.
Even Squeak, which has a version of it's UI which it calls MVC, doesn't implement the original MVC Controller, although it still does have a lot of polling it its guts.
In Pollock, as it evolved, instead of having dozens and dozens of Controllers, one for each pane and some for each look for each pane, the Agent basically replaced them. Just before the removal of the Controllers in Pollock, they became a handful of re-re-dispatchers of events.
So, to finally put the death to Controllers, we added a Pollockized EventDispatcher. Instead of working with Controllers, it works with Panes (and windows). Events are dispatched directly to a pane's Agent. Controllers and Trackers are gone, dead meat, pushing up the daises.
The Agent now has all the goods to forward Pollock event methods.
Common Triggered Events
In older versions of Pollock, and in Wrapper a Button would trigger a "#clicked" event when the mouse was pressed, and then trigger a "#pressed" event when the mouse was released within the bounds of the button.
Anyone else see the inconsistent naming? Vassili did... And while we were talking about it, we came up with a refactored set of events.
So to start off, Buttons are the ONLY widget the trigger the #clicked event, and then ONLY when the mouse is released within the bounds of the same button as it was pressed in.
Now, there are a set of events that ALL panes trigger:
Yes, I do mean ALL. From labels to images, progress bars to dividers, all panes trigger these events.
These events represent the mechanical button presses, not actions. As stated above, if you want to know if a Button pane's action is happening, you want to subscribe to the #clicked event. All other action events remain the same.
Fly By Events
Up till now, when moving an unpressed mouse (flying by or flying over, depending on what terminology you might pick), #paneEnter and #paneExit events were triggered as you moved into or out of a pane. However, that turned out not to be fine grained enough for many panes. What you also need are events to tell you if you are flying into or out of a part of a pane. For instance, individual items in a ListBox, so you might display the item's "full" text if it is partially obscured because the item's text is larger than the width of the pane.
So, now in a List and TreeView, when you fly into an item, a #zoneEnter: event is triggered, with the index of the item as a parameter. Similarly, when you exit an item, a zoneExit: is triggered, with the index of the item exited as a parameter. This will be used by the tools to support the oft requested fly over "full item text" feature.
For a Grid, instead of the "index" per se, the cell index is sent as the parameter, as a point. If there are column headers, flying into or out of one will send X @ 0. If there are row headers, flying into or out of one will send 0 @ Y. If there are both column and row headers, the upper left corner sends 0 @ 0.
For a TabControl, flying over the tabs will send the page number of the tab.
In the future, when we have Do-It Hypertext in the TextEdit, we'll use this event to send the start and end indexes of the hypertext in the text stream.
Trigger Events Pragma
Vassili redid how we declare trigger events for Panes. They are now Pragma based. Here's his comment on that work:
"Changed eventsTriggered declarations to be based on pragmas. This brings two benefits: 1) new events can be easily added by class extensions; 2) events allowed by a class are cached in a class instance variable, eliminating the overhead of rebuilding event collection each time an event is triggered."
Long And Winding Road
Next time we'll look at more small and big changes from previous releases.