The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Taking Control With Views

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Taking Control With Views Posted: Aug 22, 2007 2:52 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Taking Control With Views
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Travis Griggs - Blog

Advertisement

As you wander around the net and look at what MVC means to different implementors, perhaps the most loosely cast definition is that of "Controller". Many moons ago, when the idea came to ObjectWorks, it was given the role of the object that managed interaction between the user and the view. In those days, there was a control loop that it participated in. Other than the Smaltalk implementation, I've never found another implementation where Controller played the same role (to be fair here, I've actually never seen any implementation of the Controller role where I could liken it to another).

At one point, the control loop was phased out in favor of a new asychronous event architecture. In fact, in recollection, this was a pretty impressive feat, how they evolved an existing architecture and kept all of our apps pretty much working.

Sometimes, it's interesting to look at these old implementations and try and read between the lines where they were headed. In that particular case, that's many generations of architects ago. But I have a hypothesis. I wonder if Controller was on its way out. If one looks closely, they will note that the event stuff all passes through the view tree (the arrangement of VisualParts). The APIs are few:

  • getEventHandler
  • handlerForMouseEvent:
  • handleEvent:
All events pass up and down the tree via these three methods, or rather they should. There are some flaws that have crept into the design over the years, but at its heart, this is the basics of what we need. For historical reasons, in almost all cases, this just defers these APIs to a View's Controller. In theory, this is a fun thing to do. It demos well. Because we can show that Controller's are pluggable. We can put a NoController on any widget and have it become "dead" to the user. In reality though, this is rarely used. The View-Controller couplets are almost always married 1:1 and the richer a widget becomes the more chatty these two objects become. It becomes difficult to separate their roles as we bounce back and forth, because user interaction and display can be very "integrated." And it's not that one would get rid of the approach completely. One can still build a View and set things up so the event handling code was routed through a pluggable/changeable delegate, but that by default, Views would become the all in one ViewController couplet. This is actually how many other widget frameworks do things.

So I decided to play with this hypothesis when I was doing the SUnitToo(ls) interactive overlay. The class of interest is SUnitTooProgressOverlay. It is a subclass of VisualPart. Rather than return a Controller from getEventHandler, it just returns self. Same for handlerForMouseEvent: (normally a VisualPart would check to see if the mouse event is in it's bounds, but in this case, I can exploit the fact that I know the view will be "full window", but if you go look at how Controller normally does this, you'll see even more evidence that the View is the right place for this behavior, because the Controller defers everything back to the View).

The final override is interesting. This view has different "states" it can be in. Normally, either the View or the Controller would hold the state, then the other'd constantly refer to the holder to tune its behavior. If they're folded into one object, we don't have to go back and forth. I took a page from some of the StateMachine ideas Vassili had played with. The state is represented as a symbol. It has 4 states: #inactive, #visible, #overHalt, #haltPending. I can use this state and the names of the Event classes coming in to handleEvent: to concoct a message based state machine. The handleEvent: code just looks like this:

handleEvent: anEvent
	| selector |
	selector := (state , anEvent class name , ':') asSymbol.
	^(self respondsTo: selector)
		ifTrue: [self perform: selector with: anEvent]
		ifFalse: [nil]
This is very fun, because then I can just fill in the state based event transitions as I go. Because of the way the logic flows, I only needed:
  • haltPendingRedButtonReleasedEvent: anEvent
  • overHaltMouseMovedEvent: anEvent
  • overHaltRedButtonPressedEvent: anEvent
  • visibleMouseMovedEvent: anEvent
None of these methods is over 5 lines long. And I define the whole behavior including "activating" the halt area when you hover over it. The view code is privy to the same state variable, so it can adjust the display accordingly. Overall, I found this to be very effective. And easier to model the states of the View, both it's visual behavior and it's interaction. So whether they meant to or not, I certainly think taking control into the views has merits in most, if not all cases.

Read: Taking Control With Views

Topic: Vacation Reading: The First Total War Previous Topic   Next Topic Topic: End of Vacation

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use