This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: DragDrop Part 4
Feed Title: Pollock
Feed URL: http://www.cincomsmalltalk.com/rssBlog/pollock-rss.xml
Feed Description: Pollock - the next VW GUI
We left off with the DragDrop Session sending messages to source and target widgets, and the realization that the widgets themselves can never respond to the messages in any meaningful way. In fact, we realized that the widgets themselves are, in terms of DragDrop, totally mindless.
As hinted in Part 3, the answer to our dilemma is Trigger Events.
Without getting into the whole Trigger Event system, what it is now, what it will be in the future and so on, I'll just describe it simply: A notification system based on the Publish/Subscribe model. In general, an object can choose to trigger an event at any time. Another object, wishing to be informed when that specific event occurs, registers interest in that specific event. It also registers a message that will be executed when that event occurs. When that event is triggered by the publishing object, it looks into it's registry of events, finds all messages that are registered to that specific event, and then executes the message (or messages) associated with that event.
I'm sure that's clear as mud. Without going into multiple parts about the Trigger Event system, which I may do someday, we'll just have to live with that rather opaque description for now.
Back to our story. If you've been following along, you probably note that all widgets will have to respond to/implement the various messages that a DragDrop Session will send. Let's list them all for clarity:
Will You Accept A Drop
Display Drop Emphasis
Hide Drop Emphasis
Drop (aka BombsAway)
Drop Completed, Do Move Action (aka Mission Accomplished)
Since we're going for details here, it is important to point out that there are actually two flavors of "Will You Accept A Drop?". One is "Upon Entering A Widget..." and the other is "Moving Within A Widget...." Here's how they work. The DragDrop Session sends "Upon Entering A Widget, Will You Accept A Drop?" the moment it enters a widget. This message gives the DragDrop Session information about if it should continue to even bother with the rest of the messages. If the answer is yes, then it is quickly followed by two more messages: "Moving Within A Widget, Will You Accept A Drop Here?" If the answer to this is yes, then it sends "Display Drop Emphasis". From then on, as we move around in this widget the following happens: We first determine if the last move resulted in a Display Drop Emphasis message. If it did, then it sends "Hide Drop Emphasis" as explained in Part 2. Then, it sends a "Moving Within A Widget, Will You Accept A Drop Here?", and if the response is yes, then it follows that with a "Display Drop Emphasis"
For the sake of completeness, and knowing our widgets are so brain dead, we follow any "Drop" message with a "Hide Drop Emphasis."
To complete our list of messages, we note one more: "About To Leave Widget". This is sent to a widget as a parting shot, allowing the widget to do any clean up it might need to do. This is NOT sent after a drop, only if a drop does NOT occur in a widget and the focus moves out of the widget. In a way, you can consider this a convenience message, and unlike the two "Will You Accept A Drop..." messages, there is no yes/no response that has any meaning.
Here is our completely fleshed out list of messages:
Upon Entering A Widget, Will You Accept A Drop?
Moving WIthin A Widget, Will You Accept A Drop?
About To Leave Widget
Display Drop Emphasis
Hide Drop Emphasis
Drop
Drop Completed, Do Move Action
That's it, no more, no less. Our full list of messages that every widget has to implement/respond to.
Now we'll put together all the messages along with the trigger events. Each message above, is implemented exactly once in the abstract superclass of all Panes (and Windows). Let's take the first message above, and look at the Smalltalk code that implements it:
As described in earlier parts, the DragDropSession is filled with information about where it is (the mouse location), which widget is being sent the message, and other goodies that the user can query. The user, in their User Interface, can then write code like this:
...
someWidget when: #dragEnterAcceptDrop: send: #someWidgetEnterAcceptDrop: to: anInterestedParty.
...
All that is left is for us to write the #someWidgetEnterAcceptDrop: method:
someWidgetEnterAcceptDrop: aDragDropSession
"I can ask the DragDropSession about what is being dropped, and stuff like that
If I want to accept the drop when I have made up my mind, I just write:"
aDragDropSession enterAcceptDrop: true
We've got an almost complete story here. There are some small details left to go, which I'll get to in the next/last part. But before I go, here is a mapping of the verbose messages to their actual Pollock event names: