Archive for July, 2006

Lady In The Water

Few movies ever aspire to be as good as Lady In The Water, the latest film from director M. Night Shyamalan. That is understandable. When someone strives for greatness, it seems as if the rest of the world lies in wait for a chance to tear at it like a pack of wolves surrounding a helpless animal, or in this case, a skrunt waiting in the grass for a chance to kill a narf, the sea nymph character played by Bryce Dallas Howard. Shyamalan understands this, and has laced his film with a variety of subtexts, one of which deals directly with the critical eyes and ears of film critics. It is beautifully done, but it is not the reason why this film is great.

What makes Lady In The Water a truly brilliant film, what elevates it from a simple bedtime story into the realm of historical cinema, is not the subtexts, the acting, the writing, or the directing – all of which are good – but quite simply how well the movie evokes emotion: hope, grief, doubt, love and bravery. The last time I watched a film that inspired such powerful and heartfelt emotions in me I was a child watching Steven Spielberg’s E.T.

I won’t be the first person, or the last, to compare Lady In The Water to E.T. The well-known internet critic for Ain’t It Cool News, Moriarty, already drew that comparison a few weeks ago when he wrote:

If SIGNS was his CLOSE ENCOUNTERS, then LADY IN THE WATER is obviously struggling to be his E.T.

Unlike Moriarty though, I don’t think Lady In The Water struggles at all to be Shyamalan’s E.T. It is equally as brilliant, emotionally charged and powerful. It hits all the right notes and then some.

The poster for Lady In The Water describes it as a bedtime story. It is that – a very good and fanciful tale – but it is so much more. It is a commentary on the War in Iraq, and indeed the stupidity of all wars. It is a commentary on what it means to have hope and to be brave even when we don’t feel like we are. It is a commentary on what it means to be special, to have a gift and to accept our gifts that we’ve been given. It is a commentary on the film critics of the world and their inability to find joy and wonder in the films they critique. It is a commentary on human beings, and how we are truly one entity in this universe even if we feel alone and isolated. It is a commentary on what it means to have purpose in this life, even if we don’t see it in ourselves. And maybe most important (and certainly most touching) it is a commentary on grief and loss. One of the most powerful scenes in the movie deals with a character’s emotions related to a personal loss, and finally reaching the stage of acceptance.

As far as the bedtime story goes, it is fun, new and interesting. I’ve never been a fan of bedtime stories, but Shaymalan’s story has the feel of invention on-the-fly, like a parent making up the story as they go, creating new characters and rules each evening to entertain their child. As a parent I found the story compelling, and I liked the way Shaymalan divulged it in small bits and pieces as the film progressed, thus constantly changing what we (and the characters) know. I felt like a child experiencing this world for the first time as my creative parents invented it along the way, just for me.

Paul Giamatti is wonderful as Cleveland Heap, the superintendant of the building, and a man with a secret in his past. He plays the part with just the right combination of vulnerability and down-to-earth attitude; he is believable the entire way. We forget – in fact we never even consider – that this is a man who has spent his career as a character actor and never carried a film on his own before. He does get some help from Bryce Dallas Howard though, who is perfect in the role of Story, the narf from the Blue World.

Finally, a thought about Shaymalan’s “twists.” He’s made a career of throwing curveballs at his audience toward the end of a film. He started to get away from that practice with Signs and The Village. Here, he abandons the trademark twist completely. Instead, he borrows one of his other tactics to build this movie around – the jigsaw puzzle from Signs. If you recall in that film there were a lot of disparate pieces – clues – that he laid out in the movie, and none of them seemed to be important at all, only existing to define the quirks and traits of the characters. Yet, at the end of the film they all added up and had an important role in the outcome of the story. Shaymalan takes that trick and uses it to great effect in Lady In The Water. The clues are all there for the audience to decipher, and when everything finally comes together it is magic.

I doubt another film this year will be this good. Lady In The Water is a rare film. A special film. It’s probably going to take the film critics of the world a few years to get over the shot that Shaymalan takes at them in this movie; they don’t enjoy taking the criticism that they so often dish out. But if you’re the kind of person who sees the glass as half-full, if you feel hope easily and can imagine wildly, and if you like to have a great filmmaker pull your heartstrings, then this movie is for you.

Go enjoy it.

Day 2 of our NFL Predictions, we take a look at the AFC West. On the surface this looks like a tough division, but look a little deeper and there’s a lot of factors that could add up to some sub-par records. I think only one of these teams is making it to the playoffs.

(1) Denver Broncos: This is the only team in the division with the same head coach and quarterback as last season. Think about that stability and what that means. That will be the number one reason this team gets back to the playoffs while the rest of the AFC West lingers in mediocrity. The Broncos added Jevon Walker during the offseason in a trade that got the disgruntled receiver out of Green Bay. Bad move for Green Bay, great move for Denver. It gives them more offensive firepower during the regular season so they can win the division and get into the playoffs. It also gives Jake “I-Like-To-Throw-Interceptions-At-Crucial-Times” Plummer another target to miss during crunchtime. Their schedule is absolutely brutal, with games on the road against New England and Pittsburgh, plus home games against Indianapolis, Seattle, Cincinnati and Baltimore. Ouch. Still, to get into the playoffs what you really have to do is defeat your division opponents, and considering the amount of change the rest of the teams in this divsion will have to deal with I think there’s a real good chance Denver wins it.

(2) Kansas City Chiefs: One of two teams in this division with a new head coach. Herm Edwards comes over from the Jets, but don’t think for one minute this makes the team any better. They are going to struggle in a big way, especially with the recent announcement that left tackle Willy Roaf is retiring. They struggled last year to a 4-3 mark when he wasn’t in the lineup; his absence definately hurts this team. They’re wide receiver corps is still weak and undersized, and thus far they’ve done nothing to improve it. Tony Gonzalez continues to be the only guy on the field who scares anyone. Larry Johnson looked awesome in the last nine games of the season running the ball and some are predicting he could threaten the 2,000 yard mark, but he’s going to have some problems finding running lanes with a depleted offensive line. I like the recent signing of Ty Law to bolster the secondary, but the front seven of that defense isn’t good enough to stop anyone. The schedule makers were kind to the Chiefs however, who have some very winnable against San Francisco, Arizona, St. Louis, and Cleveland. It won’t be enough to get them into the playoffs, but it should be enough to prevent them from looking worse than they really are.

(3) San Diego Chargers: Folks liked to refer to the 2005 version of the Chargers as the “Best team to not make the playoffs.” The schedule beat them up and they lost a lot of close games against tough opponents. Well, this year the schedule makers might have been slightly kinder, but the front office wasn’t. They let their franchise quarterback, Drew Brees, get away in free agency and now the reigns are being passed to Phillip Rivers, the number one draft pick from two years ago who has virtually no real NFL experience. For all intents and purposes, this team is entering the season with a rookie QB at the helm. They’ve still got some talent at the skilled positions; RB LaDanian Tomlinson and TE Antonio Gates are threats on every down, and the defense should be just as solid as last year. But they’ll only go as far as Rivers can take them, which won’t be very far with Marty Schottenheimer’s history of conservative playcalling and game management.

(4) Oakland Raiders: The other team in the league with a head coaching change. Art Shell returns to the Raiders for tour of duty #2 as the head coach, and brings with him a discipline and attitude that embodies what the Raiders organization is all about. The only problem is he’s got maddeningly inconsistent Aaron Brooks as a QB and a defense that statistically ranked #27 last year out of 32 teams. WR Joey Porter apparently wants out and is creating a distraction by pleading for a trade. It’s never a good sign when one of your best players is trying to get out of town (reference the aforementioned Jevon Walker and Green Bay situation). Teams with new head coaches are automatically handicapped anyway because in the NFL it takes 2-3 years before a new coach is able to implement his system in its entirety. The Raiders not only have to deal with Shell’s new disciplinary style, but a new playbook and terminology as well. Their schedule looks favorable though, with games against San Francisco, Arizona, Cleveland and Houston, along with their AFC West rivals. They should improve on last year’s 4-12 mark, but don’t expect much beyond a .500 record.

Next up: NFC North

Training camps are starting all over the country, so today I start an eight post series predicting the NFL outcome, from here on referred to as the Absurd Pre-Season Predictions. I call these predictions “absurd” because they are; we know far too little at this time of year to be able to predict, with any sort of accuracy, what will really happen this NFL season. Yet everyone is doing it, and not wanting to be left out, so will I.

Injuries are the single largest factor in determining whether a prediction will come true or not. I honestly think, for instance, that the Seattle Seahawks have a great shot to go back to the Super Bowl and win it all. But the huge caveat to that is: if they stay healthy. If Shawn Alexander or Matt Hasselbeck go down with an injury, for instance, all bets are off.

With that thought in mind, let’s jump into the pre-season predictions. Teams are ordered in the manner in which I believe they’ll finish within their division. We start today with the NFC West, so we can get the Homer Call Of The Week prediction out of the way.

NFC West

(1) Seattle Seahawks: They’ll win the division again if they stay healthy and Alexander avoids that impossibly consistent Madden Curse. I actually think they have a great shot to get back to the Super Bowl. They retained most of the key important parts of their team (Shawn Alexander, Rocky Bernard), drafted well (Kelly Jennings) and signed the best player available in free agency (Julian Peterson). Ken Hamlin should also be back from the barfight head injury that sidelined him last year, and he gives them a one-two safety punch with Michael Boulware that could be downright nasty. They’re one of the few teams with legitimate Pro Bowl players at the quarterback and runningback positions and that is crucial in the NFL. They’re defense could be Top 5 this year with a linebacking corps that features Leroy Hill, Lofa Tatupu and Peterson, along with a very deep defensive tackle rotation that should make it difficult for teams to run the ball, as it was last year against the ‘Hawks.

(2) St. Louis Rams: A lot of folks are predicting the Cardinals here, but they’re not paying attention. The Cardinals have a tougher road with a brutal schedule to start the season. By contrasts, the Rams have it easy. They face San Francisco, Arizona, Detroit and Green Bay in the first five weeks. I think offensively they’re going to miss Mike Martz and the vertical playmaking that his scheme brings to the table. Martz’s offense makes defenses worry, and that often lead to situations where the Rams played with a big lead, or they had the ability to come from behind at a moment’s notice. The pledge by new head coach Scott Linehan to use runningback Stephen Jackson more this season sounds smart, but we’ve seen this sort of thing in the past: teams have trouble changing philosophies quickly and it can take a couple years before they’re retooled with the proper personnel to run the new regime’s system correctly. I expect the Rams, with an emphasis on the running game and the loss of Martz’s high-flying attack, to be in more games decided by fewer points. And such games are often decided by defense and special teams, two areas where the Rams are not exceptionally strong.

(3) Arizona Cardinals: They have to be better, right? Not so fast. This team has a tough schedule out of the gate with games against Seattle, Atlanta, Kansas City and Chicago in the first six weeks of play. They could be 2-4 to start the season and out of the playoff hunt before October is half over. And there’s a high probability that Kurt Warner will get clobbered in those first six games and end up on the bench, putting rookie Matt Leinart in charge of the offense, a sure fire way to end the season in disaster (rookie QB’s always struggle unless their name is Marino or Roethlisbuger). I also don’t think Edgerrin James immediately makes them a better running team, like many other pundits predict. For one thing, you have to have a good blocking line to get yards and Arizona hasn’t shown it can do that. I think this is going to be another season of high expectations that aren’t met, which is sad because the Cardinals is opening a new stadium this year.

(4) San Francisco 49ers: They are just not talented enough to compete yet. I really like what head coach Mike Nolan is trying to do with this team; he seems like a very solid coach with a very good plan, but this team is so talent-depleted and cap-strapped that it’s going to take them some years to become competitive again. Also, I don’t think Alex Smith is an NFL calibur QB. Expect Trent Dilfer to take over sometime before October is out when the team starts to fracture under the lack of production, begging the coaching staff to get them a win. Their schedule isn’t too kind either; they get Seattle twice, Philledelphia, Minnesota, Chicago, Denver, Kansas City and San Diego. If they crack five wins this season someone needs to give Nolan a raise.

Tomorrow: The AFC West

Camaro

A few months ago I made a post about Chevy’s concept Camaro. Oddly enough that is one of the most hit posts on this blog. I just started tracking stats with Google Analytics last week and the Camaro post still shows up as a top hit.

In light of that, heres more news (well, pictures really). Chevy has seen fit to create an official page for the Camaro which has some very cool pictures, including a nice shot of the interior:

Camaro

Automobile Mag also has a slew of great photos.

The troubling information comes from InsideLine.com, where they’re saying that the wheel size and even the overall dimensions of the car may change between now and production in 2008. If you’re like me, you like the car just the way it is. It’s the coolest looking muscle car I’ve ever seen. Do us all a favor and contact Chevy and let them know you want to see the concept become reality.

The ToolStrip is a wonderful thing. In a CAB application it is a shared site – a UIExtension site – that any WorkItem from any Module can manipulate. This is a powerful feature of the CAB infrastructure, but it does come with a cost: maintenance of the ToolStrip can be a headache in a complex CAB application.

CAB Application with DeckWorkspaces

Figure 1 shows a typical CAB application with multiple DeckWorkspaces in play. It is not uncommon to have a nested hierarchy of DeckWorkspaces showing various views, some of which contain DeckWorkspaces of their own. This is the natural product of a modular design where WorkItems are managing their own environments and hosting their views in the nearest available DeckWorkspace. By maintaining this sort of hierarchical design, lower level WorkItems never need to know about higher level DeckWorkspaces that may or may not exist. It becomes one less dependency to worry about.

The disadvantage to this scheme is that the ToolStrip is a shared site, and as such can be manipulated by anyone at any time. This can be problematic when trying to show/hide or disable/enable certain ToolStrip items based on the view currently being shown. This becomes even more troublesome when MenuItems are showing/hiding views from different Modules. The problem is one of detection: when is the view being displayed, and who should be responsible for managing the ToolStrip state when that happens?

The solution I’ve employed has two parts: A Service to manage the buttons that will appear on the ToolStrip and a Strategy for notifying DeckWorkspaces of the currently active view. That strategy is the Chain of Responsibility Pattern, and here we’re using it in a hierarchical manner.

Note: I will use the term DeckView to refer to a View with a DeckWorkspace on it and nothing more.

IUIElementExtensionService

The first thing I did was create a class that was responsible for holding references to the buttons that would be shown on the ToolStrip itself. I implemented it as an IDictionary<string, ToolStripMenuItem>. What’s great about this solution is that it uses a string already associated with the button: namely, the CommandHandler commandName.

Every button that does something on the ToolStrip requires a CommandHandler. And if your’e like me, you probably store the commandName strings in a class somewhere as constants, that way you can do compile-time checking and avoid runtime errors due to misspellings. So you have a bunch of const strings already available for use.

The class that implements the IDictionary I call the IUIElementExtensionService. Once the IUIElementExtensionService is available in the service collection we can make use of its capability to store buttons. Since it’s a service, any WorkItem in the chain (and any object that can utilize the ObjectBuilder’s Dependency Injection framework) can use it.


// Fetch reference to the ToolStrip UIExtensionSite
UIExtensionSite toolStrip = RootWorkItem.UIExtensionSites[UIExtensionSiteNames.ShellToolStrip];


// Fetch service
IUIElementExtensionService service = Services.Get<IUIElementExtensionService>();


// Create a button
// I actually do this with a factory class so I can
// standardize things like padding, margins, etc.
ToolStripMenuItem button = new ToolStripMenuItem();
button.Name = CommandNames.SaveEmployee;
button.Text = "Save";
button.Image = Resources.Save;


// Add button to the service using the same CommandName
service.Add(CommandNames.SaveEmployee, button);

So now you have a very simple service that stores your ToolStrip buttons and makes them available to any WorkItem or object that needs to manipulate them. The joy here is that we never have to recreate the buttons every time we need to show them. We just fetch the service and add them to the ToolStrip after clearing it.

Note: Typically what I do is create a UIManagerWorkItem that is responsible soley for creating the buttons when the RootWorkItem for a Module (ModuleController for all you SCSF folks) loads. It’s a one-and-done WorkItem, and it keeps all that creation code out of my other WorkItems (and when you have a lot of WorkItems creating a lot of ToolStrip buttons it can get cluttered and scattered quickly). Clean, neat, and simple.

With the Service out of the way, our next task is to delegate the management of the ToolStrip to the objects that make the most sense. This is where the Chain of Responsibility pattern comes in.

ToolStrip Management Strategy: Chain of Responsibility

The real difficulty with managing the ToolStrip is when you need to reshow a DeckView that is already showing the child SmartPart you really want to see. How do you detect a SmartPart that is already essentially active, just nested on a DeckView somewhere down the chain?

Fortunately, the DeckWorkspaces have a nice Event for this: SmartPartActivated. Utilizing this event your DeckWorkspaces can tell you what SmartPart is active, and you can use that information to propogate a message down the hierarchy informing child DeckViews of the currently active SmartPart above them. Events get chained together until they reach the leaf-node: a SmartPart that is not a DeckView. That’s when the final DeckView in the chain handles the responsibility and manipulates the ToolStrip.

CAB Application with DeckWorkspaces

We start at the top: the Shell (Leaf nodes are SmartParts that are not DeckViews, and are green). In Visual Studio, right-click the event properties for the DeckWorkspace and wire-up the SmartPartActivated event.


private void ShellDeckWorkspace_SmartPartActivated(object sender, WorkspaceEventArgs e)
{
// Do something here
}

The next step is to do something with the event. What we want to do is propogate a chain of WorkspaceEventArgs down the hierarchy so that the next level of DeckViews can respond to it and manipulate the ToolStrip if necessary. So, we use the EventBroker and declare a global event (blue event dots on the diagram):


[EventPublication(ShellEventTopicNames.SmartPartActivated, PublicationScope.Global)]
public event EventHandler SmartPartActivated;

Then we call the EventBroker Event, passing along our WorkspaceEventArgs:


private void ShellDeckWorkspace_SmartPartActivated(object sender, WorkspaceEventArgs e)
{
if (SmartPartActivated != null)
SmartPartActivated(this, e);
}

Somewhere down the chain we have a Module with a WorkItem that contains a DeckView that is showing a SmartPart. The SmartPart itself may be another DeckView, or just a regular UserControl. What the DeckView wants to know is: When is one of my children the currently active view, so that I can manipulate the ToolStrip? To know that, we subscribe to the higher level EventBroker Event.


// This happens in the Presenter for the View IMyDeckView which
// contains the DeckWorkspace.
[EventSubscription(EventTopicNames.SmartPartActivated, ThreadOption.UserInterface)]
public void SmartPartActivated(object sender, WorkspaceEventArgs e)
{
if(e.SmartPart != null && e.SmartPart is IMyDeckView)
{
Control activeSmartPart = view.GetActiveSmartPart();
if (activeSmartPart != null)
ExtendToolStrip(activeSmartPart);
}
}

There are a couple things going on here with this event subscription. First, we’re checking to see if the argument, e.SmartPart, is the same type as the View (IMyDeckView) of the Presenter that is catching this event. If it is, then we’re going to manipulate the ToolStrip. Otherwise we’re going to ignore it because it’s not us, and we’re just going to let someone else on the same tier handle it.

Once we know this is our DeckView that is being shown, the Presenter asks the DeckView to fetch the ActiveSmartPart. That’s a property of the DeckWorkspace: DeckWorkspace.ActiveSmartPart.

Finally, we’re making a call to ExtendToolStrip, which is a local method that will use the IUIElementExtensionService to show/enable/disable the ToolStrip buttons for this view. It will do something like this:


public void ExtendToolStrip(object smartPart)
{
UIExtensionSite toolStrip = RootWorkItem.UIExtensionSites[UIExtensionSiteNames.ToolStrip];
toolStrip.Clear();
ToolStripItem button;
if (smartPart is IView1)
{
button = uiService[CommandNames.Button1];
toolStrip.Add(uiService[CommandNames.Button1]);
ToolStripSeparator separator = new ToolStripSeparator();
toolStrip.Add(separator);
button = uiService[CommandNames.Button2];
toolStrip.Add(button);
}
else if (smartpart is IView2)
{
etc...
}

Thus, based on the individual View we are showing in our DeckView (and there may be several children, so the statement above becomes an if-else or switch), we clear the ToolStrip first and then add various buttons and separators, etc.

At the end of the ExtendToolStrip method we make sure to broadcast a new EventBroker Event, similiar to the one the Shell published. This is where the Chain of Responsibility comes in. It is possible that one of our children is also a DeckView, and we want them to handle the ToolStrip if they are showing the leaf node SmartPart.

This new event is for the second tier of DeckViews. They don’t subscribe to the Shell’s event because they are on a level below and none of their SmartParts will match with what the Shell’s DeckWorkspace reports. So, we fire off a new event and pass along the ActiveSmartPart as the argument (red event dots on diagram):


// Payroll is a Module in my CAB application. This is a 1st-level
// DeckWorkspace propogating its event down the hiearchy.
if (PayrollSmartPartActivated != null)
PayrollSmartPartActivated(this, new WorkspaceEventArgs(smartPart));

The EventBroker publication of PayrollSmartPartActivated looks just like the Shell’s publication.

So now you have a Chain of Responsibility. Each level down the hierarchy you publish a new event and pass along the ActiveSmartPart. Eventually you will reach a DeckView that is showing the leaf-node SmartPart, the end of the chain, and that DeckView will be responsible for manipulating the ToolStrip to match the needs of the view it is showing.

Note: You could delegate the responsibility of the ToolStrip manipulation to the actual SmartPart (or preferably its Presenter) that is the leaf node. However, I have found that having the ToolStrip manipulation code in the DeckView’s Presenter is a good idea because it is a logical place for the responsibility to lie since the SmartPart Presenter is often more concerned with handling the Model and View, and the traffic between the two. The management of the ToolStrip seems to be beyond its intended scope. Plus, it keeps my SmartPart Presenters thin and focused; there’s a clear responsibility. Finally, the DeckViews do nothing anyway, so giving them some logical UI responsibility seems reasonable.

Conclusion

I hope this helps some folks who might have been having trouble trying to manage the ToolStrip. I think the ToolStrip is a great thing to utilize in a GUI application; many users are accustomed to it and since the buttons can utilize icons it creates a better visual experience. But managing it in a CAB application can be troublesome. This sort of approach should help. It’s working wonders for me.