Original URL: http://www.theregister.co.uk/2008/08/19/poking_the_prokit/

Spice up your Apple applications

Splash of Aqua

By Dave Jewell

Posted in Developer, 19th August 2008 15:02 GMT

Mac Secrets Apple's "Professional" range of applications such as Final Cut Studio, Aperture or Logic Express have a completely different look to the standard Aqua color scheme. This comes courtesy of a private framework called ProKit.framework, intended to make Apple's professional software stand out from the crowd.

And stand out it does. Personally, I'm not a huge fan. The relentlessly grey color scheme is drab and I find the default font small and fiddly. From a visual perspective, I hate the cramped little dialogs that appear in Aperture, such as at the Preferences dialog.

A standard Aqua look would have been much cleaner, in my view. If any other developer had come up with this, they'd be roundly castigated for his non-standard user interface but, being Apple, they get away with it.

With that in mind, I'm going to show you how to use the ProKit library to customize your applications.

Framework uncovered

First, create yourself a new Xcode Cocoa application in the usual way and then add ProKit.framework to the list of linked frameworks by dragging it from its hiding place in /System/Library/PrivateFrameworks/. You should find that the app will still build and run just fine.

On background, I believe that ProKit.framework is installed as standard under Leopard, so if you're adventurous enough to use the techniques described here in a production app, then you'd be wise to specifically target Leopard. If you need to support Tiger, direct your users here.

Now go into Interface Builder, select the application window, bring up the Inspector and change its class name from NSWindow to NSProWindow. Also be sure to select the "Textured" checkbox before saving and returning to Xcode. If you now rerun the app, a wondrous sight will meet your eyes: your program will sport the same monochrome look as Apple's pro-level tools.

This is cool, but what we really want to do is use some of those ProKit controls, right? Before you can do this, you need to make one small change to your main.m source file. Just open the file and change the call to NSApplicationMain into a call to NSProApplicationMain. You might also want to add an extern reference to the new call so as to stop the compiler from whinging. When you're done, things should look like this:

extern int NSProApplicationMain (int argc, const char *argv[]);

int main (int argc, char *argv[])
{
        return NSProApplicationMain (argc,  (const char **) argv);
}

With that small change, various parts of the ProKit framework get initialised behind the scenes, so we're now ready to use those new controls.

Take control

Most of the ProKit controls are designed to work just like their "regular" counterparts, but with enhanced functionality and/or appearance. To try this out, just drop (for example) an NSButton onto your application window from inside Interface Builder.

You can hook it up to an outlet or an action in the usual way, but if you change its class to NSProButton, you will get the "Pro" look.

It's worth noting that Interface Builder is very laid-back about class names. It will happily allow you to specify any class name you like but - obviously - the class must be present at runtime in order for the application to run. This has the advantage that you can easily incorporate the ProKit controls into a project without having to use class-dump to create a corresponding header file for each control class you're interested in.

exploit the ProKit.framework

Take control of Apple's ProKit framework

For your amusement, I've added an assortment of ProKit controls to the demo program including NSProColorWell that brings up a pro-version of the standard color picker. Personally, I think the standard color picker looks far better.

Snap to it

One nice feature of the NSProWindow class is the built-in support for window snapping: that is, making a window "magnetically" snap to the screen edge when it's within a few pixels of that edge. In order to demonstrate this feature, I've added a checkbox to the demo program, which turns snapping on or off. The code is as simple as this:


- (IBAction) setSnap: (NSButton *) sender
{
        [self setSnapsToEdges: [sender state]];
}

This will work just fine even if you've got a multi-monitor setup. Behind the scenes, the code is smart enough to detect movement of the window towards any edge of any monitor.

The pixel distance you are snapping across is called the "snap gravity". By default, this has a value of 5.0. You can alter it to any value you like with the setSnapGravity: method. For me, a value of between 10.0 and 20.0 feels better than the default value. If you use a very high value, you'll effectively force the window to hug the screen edge.

As always, you can download the demo application and source code from here