Tuesday, May 13, 2014

Using a Window Controller

This tutorial is the first practice session for the topic of CPWindows, which is discussed in the overview found here: CPWindow, the start of all View Hierarchies.

Starting From A Previous Project

For this short Window Controller project, we will use the files that you during the Multiple CPWindow Tutorial.  Copy these files to a new directory called "WindowController."

Window Controllers

In the Photo Album tutorial, we are told that Window Controllers control CPWindows, but we have seen that we can manipulate and control CPWindows on our own.

Window Controllers do manipulate CPWindows with a more finesse.  For example, when calling orderFront on the CPWindow, the Window Controller also performs additional checks to determine if the window needs to be marked as the "key" window as well.  The "key" window is the target of keyboard entries.

Converting the Multiple Window Project

We are going to make three simple changes to the Multiple Window project files that you copied.

First, we are going to change the attributes of the AppController object from their current object type to CPWindowController.  Change all three of them.  Even the CPPanel can be controlled by a CPWindowController, because, as we should remember, the CPPanel is a child of CPWindow.

The implementation now looks like this:
@implementation AppController : CPObject
{
        CPWindowController Window1;
        CPWindowController Window2;
        CPWindowController thePanel;
}

Second, we change the assignment of these variables to hold Window Controller objects.  Previously, we assigned the CPWindow objects directly to the variables.  We will still use those CPWindow objects, but now we will pass them to the initWithWindow:(CPWindow)aWindow method of the CPWindowController as we initialize our objects.

The assignment lines should now read:
    Window1 = [[CPWindowController alloc] initWithWindow:theWindow];
    Window2 = [[CPWindowController alloc] initWithWindow:theWindow2];
    thePanel = [[CPWindowController alloc] initWithWindow:theWindow3]; 
 Notice that the CPPanel (theWindow3) is being passed as a CPWindow.  This is because CPPanels are CPWindows.  This is a benefit of the inheritance relationship.

Lastly, we change the functions that were called by the buttons.  CPWindowControllers don't have a visual display, and they therefore don't have an orderFront method.  Instead, Window Controllers have a "showWindow" method.  Like the CPWindow's orderFront: method, we need to pass an object to this method, but the object is truly irrelevant, so we can also pass a nil object.  We should pass the object that is requesting that the window is displayed, which is why it is very common to see "showWindow:self" or "orderFront:self".

The button methods now should look like this:
-(void)showWindow1:(id)aSender
{
    [Window1 showWindow:self];
}
-(void)showWindow2:(id)aSender
{
    [Window2 showWindow:self];
}
-(void)showPanel:(id)aSender
{
    [thePanel showWindow:self];
}
When we run the new application, it looks exactly like the Multiple Windows tutorial.  However, this code now uses Window Controllers to properly handle the CPWindow objects.



No comments:

Post a Comment