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.

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.

From A Buick 8

It’s been a while since I’ve read some Stephen King fiction. His non-fiction book, On Writing, has been a constant companion of mine this past year. In that book, one of the main tenets he offers is that in order to be a good writer one must “read a lot and write a lot”. Sound advice, I think, and because of it, I decided to spend more time this summer cracking open some previously unread literature.

Concerning this particular tale, the obvious first question everyone asks (even my wife) is: Is it like Christine? The answer is ‘no.’ It’s better.

From a Buick 8 is some of King’s best writing. He’s in total command of his style here, painting vivid pictures of the important things and leaving some of the rougher edges to the reader’s imagination. The dialog is well done and King puts a nifty spin on the flashback mechanism so often employed in fiction writing by splitting up the present day events between different character’s point of view. The chapters concerning the present are titled with the character’s name telling the story (and nearly every character gets a say at some point in time), such as “Now: Sandy”, while the flashback chapters are titled, “Then”, clearly setting the reader in the past. The constantly switching viewpoint gives the book a very conversational feel (and indeed, the setting for the book is a bench at the Pennsylvania State Patrol barracks where the characters have congregated to relay the story of the supernatural Buick to young Ned), and it also gives King an opportunity to have fun putting himself in the shoes of the different participants, making their mannerisms, motivations and speech patterns come alive.

As to the story, it reads a lot less like classic King horror (Carrie, Christine, Pet Cemetery) and a lot more like a really great episode of the Twilight Zone. I particularly like it when King goes down this road; he can do stuff that would have put a Cheshire’s cat grin on Rod Serling. From A Buick 8 reminded me a lot of The Tommyknockers, with its mysterious and inexplicable events, only better.

The car is, naturally, the central figure in the story. It is a mystery to the members of Troop D; some become rather obessed with it while others have a greater sense of fear about the vehicle and it’s strange ways. It fell into the Pennsylvania State Patrol’s hands quite by accident, and it is extremely pecular. It seems to almost be alive and capable of healing/protecting itself: scratch it and the cut is gone the next day; throw dirt on the tires and they clean themselves; throw a tarp over it and somehow the car shrugs it off. Even more bizarre: the car doesn’t actually work. No one can figure out how the original owner managed to drive it to it’s final destination when the battery isn’t connected to anything and none of the dials actually function. And then there’s the light shows…

I won’t give away the really good stuff. You’ll have to read it to find out. But I totally recommend the book. It’s a neat story with a very good setting (King got some nice help from the folks at the PSP; the entire book feels very authentic) and very interesting events. I’m a sucker for tales of the supernatural; things you just can’t completely wrap your head around, and From A Buick 8 falls into that category. There’s also a bit of a social statement in the story, but I’ll leave that for you to discover as well.

There’s a small hitch in the CAB implementation of the WindowWorkspace that can make it problematic to center a WindowWorkspace when using it as a Modal Dialog.

CAB allows you to set properties for a WindowWorkspace using the WindowSmartPartInfo class. You can set things like the Form’s Title, whether to show the Maximize Box or not, the Location of the Form when it shows, and the Modal property. The Location property works fine as long as you don’t set the Modal property to True. Your WindowWorkspace will appear exactly where you define it.

Setting the Modal property to True causes a bit of a problem though; Windows Forms function differently when their Modal property is set to True, relying on a different property to position itself on the screen.

A Windows Form set to be shown as a Modal Dialog will use the FormStartPosition enumeration to determine where to show itself, overriding the Location setting. Thus, if you attempt to set the Location for a Modal WindowWorkspace by setting the Location property, you’ll be a bit confused when it doesn’t show where you think it will show.

The solution to this problem is fix the CAB code. Fortunately we have access to the source code, so a few lines of code fixes our problem :)

The first step is add a new property to the WindowSmartPartInfo class. We need to be able to set the FormStartPosition. Make sure to add a reference here to System.Windows.Forms (thanks John).


private FormStartPosition startPosition = default(FormStartPosition);


///

/// Start position of the Modal form
///

[DefaultValue(false)]
[Category("Layout")]
public FormStartPosition StartPosition
{
  get { return startPosition; }
  set { startPosition = value; }
}

With that out of the way, we can alter the WindowWorkspace class itself to accommodate our changes. The specific method you want to add code to is the SetWindowProperties method, somewhere around line 90. The new code is bold.


///

/// Sets specific properties for the given form.
///

protected void SetWindowProperties(Form form, WindowSmartPartInfo info)
{
  form.Text = info.Title;
  form.Width = info.Width != 0 ? info.Width : form.Width;
  form.Height = info.Height != 0 ? info.Height : form.Height;
  form.ControlBox = info.ControlBox;
  form.MaximizeBox = info.MaximizeBox;
  form.MinimizeBox = info.MinimizeBox;
  form.Icon = info.Icon;
  form.Location = info.Location;
  form.StartPosition = info.StartPosition;
}

Now, when you create a Modal WindowWorkspace, all you have to do is set the StartPosition property to correctly position your WindowWorkspace.


WindowWorkspace workspace = new WindowWorkspace();
WindowSmartPartInfo info = new WindowSmartPartInfo();
info.Modal = true;
info.StartPosition = FormStartPosition.CenterParent;
MyDialog dialog = WorkItem.Items.AddNew<MyDialog>();
workspace.Show(dialog, info);

Hopefully that will alleviate some confusion for people using the WindowWorkspace. It is a great tool for decoupling Modal Dialogs and making testing easier, and now you can center it too!