The MondoTextField, a Formal Introduction
The Problem
One of the the UI quirks I noticed when developing SunFlower is that when trying to present an URL in an inspector panel it is most likely going to be truncated. Inspector panels by their very nature are small. They are used as an aid to a larger context and made small so that they don’t obscure the main interface. A full web site address (URL) on the other hand can be very long. This makes editing a long url in an inspector panel a nuisance.
What does Apple do? Let’s take a look at how you edit an external link in iWeb.

In the case of iWeb, you must scroll through the text field with the left and right arrow keys. I find this very cumbersome.
This is not the only implementation I’ve found. Brent Simmons of NetNewsWire fame chose a different approach. He tackled this issue by using an NSTextView instead of an NSTextField.

I prefer Brent’s solution to Apple’s and that is what has been used in SunFlower to date. However, in the yet to be released version of SunFlower I rebuilt the inspector panel to use tabs because I’m doing some redesigning. So I reconsidered whether I wanted to use an NSTextView and decided I wanted to prototype an interface that I had been pondering.
I wanted something clean and compact like Apple’s solution but something that would allow the user to see the entire URL like Brent’s solution.
The Solution
The solution I came up with is to take the concept of Quick Look and squish it into a text field; I’m calling it the MondoTextField. It’s not called a QuickLookTextField because you don’t just look at the content. With the MondoTextField you look, possibly edit and then close the surrogate window.
Implementation Details
Classes
To create this component we extend two UI classes (NSTextFieldCell, and NSTextField). The custom text field cell constrains the width of the cell so that text never appears where the button may appear. The custom text field manages the button visibility and sends messages to the controller if the button is pushed. There is also an animation class that manages the size of the window during a zoom in or zoom out.

Scaling
To achieve a look similar to Quick Look it is necessary to scale the window when the HUD window zooms in and out. This means more than just making the frame of the window a different size. It requires scaling the window so that the window, and it’s contained elements (title bar, text fields, …) are all scaled.
Undocumented API’s
MondoTextField has been modified so that it does not use any undocumented API calls by using kode published by Paul Kim.
Although the scaling animation seems like a job for core animation, it is not possible to scale a window with core animation. To do this we need to use undocumented API’s.
extern OSStatus CGSGetWindowTransform(const CGSConnection, CGSWindow wid, CGAffineTransform *outTransform); extern OSStatus CGSSetWindowTransform(const CGSConnection cid, CGSWindow wid, CGAffineTransform transform);
For more information on these undocumented API’s take a look at the sample project that lipidity.com released over two years ago.
A note about undocumented API’s.
Apple obviously does not recommend that you use undocumented API’s. They recommend that you make a feature request, and wait for the API call to become officially available (which could be never). I do not encourage the use of undocumented API’s and am only using it in this case because I feel the benefits of using it far outweigh the risk and maintenance of future changes.
There is nothing stopping you from using the API’s once they are discovered, however your application could break with even a minor release of the operating system. These particular API’s have been available and undocumented since 10.4 (I believe) and I doubt that will change anytime soon as Apple appears to be too busy working on the iPhone version of Mac OS X.
If you decide to use the MondoTextField in your application then you should understand that there is some risk associated with using it.
Design Decisions
It is important to note that the button appears just before the text field is completely filled. When the button is not visible and text reaches the left of where the button will be, the button appears. Although this decreases the available space for displaying text in some cases I felt it was a better solution then using the button area temporarily and then shifting the text over when the button needs to be displayed. This was a conscious design decision.
Another issue I considered was how would users react with a button inside of a text field? The short answer is, Apple does it so it must be okay. Seriously though, it appears to be a fairly standard practice to put buttons in text fields these days. In the Safari address field there are sometimes even multiple buttons. Below is an example of Safari with a “Snapback” button and a “RSS” feed button.
Conclusion
I hope you find this component useful and am interested in any feedback as I am planning on adding it to the next version of SunFlower.
You can get the code by downloading this self-contained xCode project, or you can access it through github.
Kode on!

December 22nd, 2008 at 3:34 am
[...] View Details [...]
January 3rd, 2009 at 8:05 pm
You don’t need to use private APIs to do the window animation. The way I do this is to cache the content view of the window to an image. I then replace the content view of the window with an NSImageView with the cached image as its content. You can then just do an NSViewAnimation with the window to scale it from the small size to the large size and replace the content view when it hits full size.
January 5th, 2009 at 7:44 am
Thanks for the info Rob. I will definitely revise MondoTextField in the future so that it does not use a private API call. Paul Kim dropped me a line and let me know of a technique on of how to do this that he posted a while ago.
http://www.noodlesoft.com/blog/2007/06/30/animation-in-the-time-of-tiger-part-1/
So if you want to use MondoTextField but don’t like using a private call then you can take his example and merge it with the MondoTextField.
January 25th, 2009 at 9:45 am
[...] Cocoa Mondo: “One of the the UI quirks I noticed when developing SunFlower is that when trying to present an URL in an inspector panel it is most likely going to be truncated… This makes editing a long url in an inspector panel a nuisance.” [...]
April 18th, 2009 at 5:23 am
[...] Clicking the blue button summons a window where you can see the full text. You can edit the text in this other window. If you are interested in the design process for this interface you can read more about it here. [...]