mac


16
Oct 09

What’s in a cursor? Part II

In Part I, I discussed how to customize the link cursor of an NSTextView subclass to match that of WebKit. It is, by all means, a fairly straightforward task with seemingly harmless consequences; after all, all it does is to add a subtle shadow offset by a few pixels.

While not exactly on the same scale, I am reminded of similar situations in the past—making standard UI components “look better” to the eyes without regards to their use cases and contexts: When Apple first showed off Brushed Metal window appearance in iTunes, many developers went out of their way to emulate this appearance in their apps; later, when this option was made available as a checkbox in Interface Builder (on Mac OS X 10.2), there was a huge influx of 3rd-party applications with Textured (or Brushed Metal) windows and panels.

Aqua Human Interface Guidelines (.pdf 7.8mb) during that time specifically states:

This window style has been designed specifically for use by—and is therefore best suited to—applications that provide an interface for a digital peripheral, such as a camera, or an interface for managing data shared with digital peripherals, such as the Address Book application.

This appearance may also be appropriate for applications that strive to re-create a familiar physical device—the Calculator application, for example. Avoid using the textured window appearance in applications or utilities that are unrelated to digital peripherals or to the data associated with these devices.

It goes without saying that very few of these applications were related to digital peripherals or to the data associated with these devices.

Another such example is the HUD (or Transparent) window. The HUD looks so attractive it is almost a torture for a developer not to use it. Not surprisingly, you can find many examples of irregular HUD usage, despite what the Human Interface Guidelines states:

In general, therefore, you should use transparent panels only when at least one of the following statements is true:
  • Your application is media-centric, that is, focused on movies, photos, or slides.
  • Users use your application in a dark environment or in an immersion mode.
  • A standard panel would distract users from the main window.
  • Users make only quick adjustments in the panel and dismiss it quickly.

And, because developers are not using it for its intended purpose—quick adjustments, for example—they complain about the dearth of HUD-compatible controls, or go so far as to develop 3rd-party frameworks such as BGHUD, or HMBlkAppKit, to name a few.

Again, just because you can doesn’t mean you should. When should you, then, customize the link cursor for your NSTextView (or for any Cocoa view for that matter) to match that of WebKit?

Here’s my version of guidelines:

  • In general, don’t.
  • If your NSTextView subclass is mainly used to display large amounts of arbitrarily formatted text, linking to other similar text, you may customize the link cursor.
  • If clicking on the link opens up the URL in the default browser, you may customize the link cursor.

As you can see, however, in most cases you might want to consider using a WebView itself instead of an NSTextView.


15
Oct 09

What’s in a cursor? Part I

NSTextView has a nice instance method: setAutomaticLinkDetectionEnabled:. When this is set to YES, the textview turns any properly formatted URL into a hyperlink in blue text with a single underline and the pointing hand cursor. It couldn’t be more straightforward.

Query uses this extensively in its result views. With a little tweak here and there, it plays well with syntax coloring as well: NSTextView link cursor

While it serves the purpose, it doesn’t feel quite alright. If you answer yes to any of the following:

you’re likely to find the default link cursor awkward, ever so slightly, because the same link will look like this in your favorite applications: WebKit link cursor

It turns out that WebKit uses its own custom image for the pointing hand cursor: /System/Library/Frameworks/WebKit.framework/WebCore.framework/Resources/linkCursor.png

If you are anything like me, you, too, can override the link cursor in your NSTextView subclass with setLinkTextAttributes: instance method.

Here’s a quick how-to:

  1. Copy the custom cursor image into your project’s Resources folder.
  2. In the awakeFromNib method of your controller class, set this custom image as the link cursor:
- (void)awakeFromNib
{
  /* do standard awakeFromNib stuff */
 
  // prepare attributes
  NSCursor *customLinkCursor
    = [[NSCursor alloc] initWithImage:[NSImage imageNamed:@"linkCursor.png"] 
                                              withHotSpot:NSMakePoint(0, 0)];
  NSDictionary *customLinkTextAttributes
    = [NSDictionary dictionaryWithObject:customLinkCursor
                                  forKey:NSCursorAttributeName];
  [cutomLinkCursor release];
  customLinkCursor = nil;
 
  // myCustomTextView is an IBOutlet or an instance variable	
  [myCustomTextView setAutomaticLinkDetectionEnabled:YES];
  [myCustomTextView setLinkTextAttributes:customLinkTextAttributes];
}

Instead of copying the image file into your project, you could link to the local image in WebCore.framework. In my opinion, however, it would be a bit too much reliance on an unpublished feature.


12
Oct 09

Favorite Snow Leopard Feature 1: Print

If you prefer to read on paper, Snow Leopard’s Print sheet will help you save many trees: Snow Leopard Print sheet

What’s so nice about the new sheet, one may ask.

If you’ve ever tried to print multiple logical pages on each physical page, you know how tedious it can be. Often, what starts out as an attempt to save paper ends up being more wasteful through the trial-and-error to find that perfect scale factor. Snow Leopard now automatically optimizes the scaling factor on a per-page basis for n-UP printing. Also introduced is a nice little touch, where the total number of pages are re-calculated as you toggle Two-Sided, n-UP, etc.