The first in a series of iPad pull requests

Get ready, because this is a mother-load of a commit.

I'll try to break down the new tech being introduced here as much as I can. I'll start with some of the visual components that have recently been added, namely the `TTRootViewController` and `TTSplitViewController`. Before I jump into that, though, I need to cover a new concept: the root container.

Containers
========

There's a new protocol introduced in this pull request called `TTNavigatorRootContainer`. The purpose of a root container is to resolve which navigator a controller should use.

Some background on why this is necessary.

On the iPhone, which navigator to use has always been pretty simple to determine: we only had one global navigator that everything was routed through.

On the iPad, however, it's possible to conceive of a variety of layouts where multiple view controllers can be displayed at once. You might have a split view controller, which contains two view controllers, and there might simultaneously be popover controllers. At any point in this model there might be as many as three independently navigable  view controllers. It's no longer as easy as just having one global navigator. Each visible view controller has its own state and likely its own url map.

This is where the `TTNavigatorRootContainer` protocol comes in. On the iPhone, by default, the navigator treats your app as a single view controller, single global navigator implementation. On the iPad you can do the same thing, but quite often you will want to display multiple view controllers at once. Let's consider a basic split view controller implementation. The new `TTSplitViewController` class implements the `TTNavigatorRootContainer` protocol and is a great case study for this new feature.

Split View Container
-----------------------------

First, let's consider what used to happen when the user wanted to navigate from one view controller to another on the iPhone. The user tapped a link and `TTOpenURL` created a `TTURLAction` object with the URL path. This action was passed to the global navigator via `[TTNavigator navigator]` which then decided to push the new view controller onto the currently visible navigation controller's stack.

Now consider a split view controller. Within this controller are a primary and secondary view controller side-by-side. In the old single, global navigator model, when the user tapped a link in either view controller, the global navigator would be consulted and it would be up to the navigator to somehow decide which of the two view controllers should be updated.

In the new model, our split view controller implements the root container protocol. Now we have a primary and secondary navigator along with the global navigator. Each navigator has its own URL mapping and state. When the user taps a link anywhere in the app now, we traverse the view hierarchy until we hit a container controller, at which point we ask it for the navigator that corresponds to that view controller via `navigatorForRootController:`. If we tap a link on the left view controller, we walk up the view hierarchy until we reach the split view controller (which is a container), ask it for the navigator that belongs to the left view controller, and then ask that navigator to execute the `TTURLAction`. We use the new TTOpenURLFromView short-hand to use the navigator for a given view. By contrast, TTOpenURL will always use the global navigator.

Below is an ASCII-art representation of the split view hierarchy:

               global
              navigator
               ^^^^^^^
    --------Root container---------
          Split View Controller    
    -------------------------------
    |         self.view           |
    |  -------------------------  |
    |             |               |
    |  secondary  |    primary    |
    |  controller |   controller  |
    |    view     |     view      |
    |             |               |
    -------------------------------
        vvvvvvv        vvvvvvv
       secondary       primary
       navigator      navigator

Root view controllers
===============

It can be useful to swap out the root view controller with an animation at certain points during your app's execution. In the Facebook app, for example, when the user is successfully logged in we flip the login controller out and the facebook view controller in. In the past, this was done by simply adding and removing the view from the window. This led to a number of subtle bugs in device orientation changes and layout calculations.

This problem can be solved by setting a permanently fixed root view controller within which all of your app's contents are displayed. A skeleton root view controller is now provided as `TTRootViewController`. It allows you to present a view controller, as well as push a view controller and pop it back. Switching to a root view controller implementation has many benefits and is easy to do. Check out TTCatalog for an example of `TTRootViewController` in action.

Popover Controllers
==============

Popovers are created by setting properties on a TTURLAction object before passing it off to a navigator to open. Let's look at an example:

    - (void)showMealListFromButton:(UIButton*)button {
      TTURLAction* action = [TTURLAction actionWithURLPath:@"tt://meals"];
      action.sourceView = button;
      action.animated = YES;
      [[TTNavigator navigator] openURLAction:action];
    }

Setting the sourceView will instruct Three20 to open the URL path as a popover. In the absence of a provided sourceRect, Three20 will use the sourceView's screen frame as the sourceRect. You can also present a popover from a UIBarButtonItem.

TTCatalog
========

The sample app has been updated, but it is hardly a good example of an iPad app. It lays the most basic foundation possible.

More to come
==========

I will flesh out this document and place it on Three20.info once we merge these changes into Three20. This request is slated for version 1.1 of Three20. We'll have to figure out an effective merge strategy for 1.1. Perhaps if we create the 1.1 release branch when we're ready to merge these changes into development and then merge development into 1.1 regularly, we can still release 1.0 bugfixes and hotfixes while we review more changes down the line.