Mac OS X Public Beta Developer Release Notes Copyright © 2000 by Apple Computer, Inc. All Rights Reserved.

 

Mac OS X Public Beta Release Notes:
Cocoa Application Framework

 

The Application Framework (also referred to as the Application Kit, or AppKit) is one of the core Cocoa frameworks. It provides functionality and associated APIs for applications, including objects for graphical user interfaces (GUIs), event-handling mechanisms, application services, and drawing and image composition facilities. In addition, it is possible to access virtually all of the classes and protocols in the Application framework using Java.

This document discusses AppKit changes in the Public Beta of Mac OS X. AppKit release notes for Mac OS X Developer Preview 4 and earlier releases can be found in another document, AppKitPrePublicBeta.html. Release notes for Foundation, the other core Cocoa framework, can be found in Foundation.html.

 

Feedback

 

For feedback and comments about AppKit and Foundation APIs and features, you can email cocoa-feedback@group.apple.com. The intent of this address is to provide developers with a direct channel to the engineering team and the technology managers responsible for these technologies. We will read your input, and will try to acknowledge it, but we might not always have time for significant replies. Please use this address for feedback and comments on the APIs and features (for instance "please add QuickTime support to NSImage" or "I need API to do this and that"), but not for support type questions (for instance, "I can't install OS X" or "How does one create a new bundle in PB?") or comments in other areas (for instance, "why is there no Apple menu in Aqua?").

 

Graphite

 

This release introduces the "Graphite" color variant for Aqua. This variant is user-selectable through the Preferences application; however, it is not selectable programmatically on a per-control basis. This means that there is no explicit NSControlTint value for Graphite; instead, the tint corresponding to NSDefaultControlTint changes.

When the user changes this setting, applications are notified immediately; all standard controls react to this by redisplaying themselves. Applications can register for the NSControlTintDidChangeNotification to do further cleanup; this is useful if they have custom controls or have image caches that might need to be recreated, for instance. Applications can find out the color value of the current default tint setting by calling [NSColor colorForControlTint:NSDefaultControlTint].

 

NSBezierPath

 

In Beta, NSBezierPath has added the following methods:

 

- (float)miterLimit;

- (void)setMiterLimit:(float)miterLimit;

- (float)flatness;

- (void)setFlatness:(float)flatness;

- (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;

- (void)setLineDash:(const float *)pattern count:(int)count phase:(float)phase;

 

These allow you to set and retrieve the miter limit, flatness, or line dash pattern on a particular path.

 

 

NSOpenPanel / NSSavePanel

 

The semantics of setPrompt: method in open and save panels has changed. With the Aqua UI, the "prompt" in front of the text field is always set to "Go to:" and cannot be changed. The method setPrompt: has been disabled in previous Aqua releases. It has now been re-targeted to affect the default button (which could not formerly be set via API). The default text on the default button is now "Open" for the open panel and "Save" for the save panel, but can be modified programmatically. Since this API formerly affected a text field, any colon on the end of the string is removed before being used on the button.

 

The setTitle: methods in open and save panels have been re-enabled as well, and affect the title text of the panels.

 

It is intended that programmers will use short words or phrases, such as "Open", "Save", "Set", or "Choose" on the button. At this time, the button is not re-sized to fit the text when set; this is a bug that should be addressed soon.

 

 

Font Directories

 

A new implementation has been added to bring back the concept of different font directories for User, System, and Network. This functionality is usually handled automatically by running "fcache" from the "pbs" process when a user logs in. At system boot time, the "fcache" program is run for the System and Local font directories. When a user logs in, it is run for the user's home directory. The program can also be run by hand in specific domains, and a new set of command-line arguments is provided for ease-of-use.

 

fcache -system

Caches info for the /System/Library/Fonts directory. This is automatically done at login time. Note: to update the /System font directory, you must be logged in as the administrator.

 

fcache -user

Likewise caches information for the user's home font library, ~/Library/Fonts, for the currently logged-in user.

 

fcache -local

Likewise, for /Local/Library/Fonts.

 

fcache -network

This option should not be necessary in most installations. The /Network/Fonts directory is usually mounted remotely via NFS, and the font cache for it should be built by the administrator of the machine on which the fonts are actually stored. Access with network Administrator privileges on the remote directory is required for this to work.

 

 

Printing

 

The final release of Mac OS X will include substantial changes to the printing-related classes; some of these changes are outlined below.

 

NSPageLayout:

 

NSPageLayouts will be displayable as document-modal sheets. New methods are being added to make this possible.

 

NSPageLayout will no longer be a subclass of NSPanel. It will be a direct subclass of NSObject. It will not be possible to send -[NSView viewWithTag:] to an NSPageLayout.

 

Some methods are being deprecated:

-convertOldFactor:newFactor:will always set both of its arguments to the same value.

-pickedButton:will never be sent from within AppKit.

-pickedOrientation:will never be sent from within AppKit.

-pickedPaperSize:will never be sent from within AppKit.

-pickedUnits:will never be sent from within AppKit.

 

Accessory views will be supported. It is possible that new methods wil be added for use by accessory views.

 

 

NSPrintOperation:

 

The panels that a print operation displays will be displayable as document-modal sheets. New methods are being added to make this possible.

 

The meanings of some methods are being reevaluated:

+currrentOperation and +setCurrentOperation: imply that there is one and only one current NSPrintOperation. There will be more than one current NSPrintOperation in the future.

 

Accessory views will be supported. It is possible that new methods will be provided for use by accessory views.

 

 

NSPrinter:

 

The purpose of the NSPrinter class and each of its methods is being reevaluated.

 

 

NSPrintInfo:

 

Some attribute settings that were stored as entries in the dictionary assocated with an NSPrintInfo are being deprecated. Such entries will be ignored by -[NSPrintInfo initWithDictionary:], and will not be present in any dictionary returned by -[NSPrintInfo dictionary]. They are:

 

NSPrintFaxCoverSheetName

NSPrintFaxModem

NSPrintFaxHighResolution

NSPrintFaxReceiverNames

NSPrintFaxReceiverNumbers

NSPrintFaxReturnReceipt

NSPrintFaxSendTime

NSPrintFaxTrimPageEnds

NSPrintFaxUseCoverSheet

 

A job disposition is being deprecated:

 

-setJobDisposition:will treat NSPrintFaxJobas if it were synonymous with NSPrintSpoolJob.

-jobDispositionwill never return NSPrintFaxJob.

 

A method may be deprecated. If so:

 

+sizeForPaperName:will always return NSZeroSize, regardless of the paper name.

 

The meanings of some attribute settings are being reevaluated. They are:

 

NSPrintFormName

NSPrintJobFeatures

NSPrintPaperFeed

NSPrintPrinter

 

 

NSPrintPanel:

 

NSPrintPanels will be displayable as document-modal sheets. New methods are being added to make this possible.

 

NSPrintPanel will no longer be a subclass of NSPanel. It will be a direct subclass of NSObject.

 

Some methods are being deprecated:

-pickedAllPages:will never be sent from within AppKit.

-pickedButton:will never be sent from within AppKit.

-pickedLayoutList:will never be sent from within AppKit.

 

Accessory views will be supported. It is possible that new methods will be provided for use by accessory views.

 

 

NSDocument:

 

NSPageLayouts will be displayable by NSDocuments as document-modal sheets. New methods are being added, and the meanings of others modified, to make this easy.

 

 

NSWindow:

 

The behavior of the -print method may change so as to display panels as document-modal sheets.

 

 

NSWindow

 

Hiding an application now releases the backing store for any oneShot windows. Minimizing a oneShot window also releases the backing store. Any views doing custom drawing (outside of the standard display mechanism) which may try to draw while the application is hidden or the window is minimized should use -[NSView lockFocusIfCanDraw] rather than -[NSView lockFocus].

 

There is a user default, AppleDockIconEnabled, to enable setting the image in a minimized window tile with -[NSWindow setMiniwindowImage:]. The image will be scaled as necessary to fit the tile. This behavior is off by default, so you must set AppleDockIconEnabled to YES if you want to enable this behavior. Our intent is to enable this behavior in the next release; however, in most cases applications might not want to set the miniwindow icon explicitly.

 

Single window mode has been disabled in Public Beta.

 

 

NSApplication

 

The image in the dock application tile can be set with -[NSApplication setApplicationIconImage:]. The image will be scaled as necessary to fit the tile.

 

You can call -postEvent:atStart: and -discardEventsMatchingMask:beforeEvent: methods from subthreads. Events posted in subthreads bubble up in the main thread event queue.

 

 

NSWorkspace

 

Icons returned by NSWorkspace methods now include thumbnail representations (128x128) if available. They are also created as images of size 32x32, rather than images of undetermined size. Previously their actual displayed sizes were left to depend on the representations available.

 

 

Document modal API

 

The document modal API introduced in DP4 is now implemented in NSDocument, NSDocumentController, and NSOpenPanel. The DP3 document modal API is deprecated, and calls to these deprecated methods will result in warnings to the console. We have turned off these warnings for applications found under /Applications or /Developer/Applications. We encourage developers to test their applications for these warnings before installing their application in /Applications or /Developer/Applications.

 

Each method takes a modalDelegate, a callback, and an optional contextInfo argument. When the document-modal session is ended, the modalDelegate is invoked with the callback method, which receives the sheetWindow object, the result of running the sheet - either a boolean or a returnCode, and the contextInfo argument. The contextInfo is a way for you to pass information from the start of the modal session to the end, and can be a simple value, a structure, or an object.

 

The callback is invoked before dismissing the sheet in order to give you the opportunity to dismiss the sheet and the parent document window at the same time. For example, you might want to do this when dismissing a "do you want to save" alert before closing a window. If the user selects "don't save", you want to close both the document window and the sheet without the sheet effect. This can be accomplished by calling [docWindow close ] from the callback. You can also dismiss just the sheet in this method by calling [sheetWindow orderOut:]. If you do not dismiss the sheet, it will be done for you on return from your callback, but you may be in a situation where you want to immediately present another sheet, and this is probably best done from your callback after dimissing the first one.

 

The NSRunAlertSheet variants take two callbacks, one which is invoked before dismissing the alert sheet, and the other which is invoked afterwards. You may find it convenient to implement both methods, but it is not required.

 

NSDocument:

 

- (IBAction)saveDocument:(id)sender

- (IBAction)saveDocumentAs:(id)sender

- (IBAction)saveDocumentTo:(id)sender

 

These methods now call the new document modal API below.

saveDocument: calls -saveDocumentWithDelegate:didSaveSelector:contextInfo:.

saveDocumentAs: and saveDocumentTo: call -saveToFile:saveOperation:delegate:didSaveSelector:contextInfo:.

 

This means that these calls are now asynchronous - they may return before the save operation has completed (and the save sheet may still be present on the document).

 

- (void)shouldCloseWindowController:(NSWindowController *)windowController delegate:(id)delegate shouldCloseSelector:(SEL)callback contextInfo:(void *)contextInfo

 

This method replaces shouldCloseWindowController:. This method will invoke the callback with the result of canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo: if the window controller that is closing is the last one or is marked as causing the document to close. Otherwise it invokes the callback with YES. This is called automatically by NSWindow for any window which has a window controller and a document associated with it. NSWindow calls this prior to asking its delegate -windowShouldClose:.

 

shouldCloseSelector should have the following signature:

- (void)document:(NSDocument *)document shouldClose:(BOOL)shouldClose contextInfo:(void *)contextInfo

 

- (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo

 

This method replaces canCloseDocument. If the document is not dirty, this method will immediately call the callback with YES. If the document is dirty, an alert will be presented giving the user a chance to save, not save or cancel. If the user chooses to save, this method will save the document. If the save completes successfully, this method will call the callback with YES. If the save is cancelled or otherwise unsuccessful, this method will call the callback with NO. This method is called by shouldCloseWindowController: sometimes. It is also called by NSDocumentController's -closeAllDocuments. You should call it before you call -close if you are closing the document and want to give the user a chance save any edits.

 

shouldCloseSelector should have the following signature:

- (void)document:(NSDocument *)doc shouldClose:(BOOL)shouldClose contextInfo:(void *)contextInfo

 

- (void)saveDocumentWithDelegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(void *)contextInfo

 

This method partially replaces fileNameFromRunningSavePanelForSaveOperation:. This method runs the save panel and invokes saveToFile:saveOperation:delegate:didSaveSelector:contextInfo: with the result. It is called from the -saveDocument: action method, and from canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo: if the user chooses to save.

 

didSaveSelector should have the following signature:

- (void)document:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void *)contextInfo

 

- (void)saveToFile:(NSString *)fileName saveOperation:(NSSaveOperationType)saveOperation delegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(void *)contextInfo

 

This method partially replaces fileNameFromRunningSavePanelForSaveOperation:. This method gets called after the user has been given the opportunity to select a destination through the modal save panel presented by runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:. If fileName is non-nil, this method writes the document to fileName, sets the document's file location and document type (if a native type), and clears the document's edited status. didSaveSelector gets called with YES if the document is saved successfully and NO otherwise.

 

didSaveSelector should have the following signature:

- (void)document:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void *)contextInfo

 

- (void)runModalSavePanelForSaveOperation:(NSSaveOperationType)saveOperation delegate:(id)delegate didSaveSelector:(SEL)didSaveSelector contextInfo:(void *)contextInfo

 

This method replaces runModalSavePanel:withAccessoryView:. This method prepares and runs the modal save panel. It is invoked from saveDocumentWithDelegate:didSaveSelector:contextInfo:, and the action methods saveDocumentAs:, and saveDocumentTo:. This method will call prepareSavePanel:to allow further customization of the savePanel.

 

didSaveSelector should have the following signature:

- (void)document:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void *)contextInfo

 

- (BOOL)prepareSavePanel:(NSSavePanel *)savePanel

 

This method is invoked by runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:to do any customization of the save panel. It returns YES if successfully prepared, and NO otherwise. The default implementation is empty and returns YES.

 

NSDocumentController:

 

- (void)closeAllDocumentsWithDelegate:(id)delegate didCloseAllSelector:(SEL)didAllCloseSelector contextInfo:(void *)contextInfo

 

This method replaces closeAllDocuments. This method goes through all the open documents and tries to close them one by one. Each NSDocument is sent -canCloseDocument:didCloseSelector:contextInfowhich, if it is dirty, gives it a chance to refuse to close or to save itself first and may put up UI to ask whether to save or to perform a save.

 

didCloseAllSelector is invoked with YES if all documents are closed, and NO otherwise. It should have the following signature:

- (void)documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll contextInfo:(void *)contextInfo

 

- (void)reviewUnsavedDocumentsWithAlertTitle:(NSString *)title cancellable:(BOOL)cancellable delegate:(id)delegate didReviewAllSelector:(SEL)didReviewAllSelector contextInfo:(void *)contextInfo

 

This method replaces reviewUnsavedDocumentsWithAlertTitle:cancellable:. It displays an alert panel asking users if they want to review unsaved documents, quit regardless of unsaved documents, or (if flag is YES) if they want to cancel the impending save operation. This method invokes didReviewAllSelector with YES if quit without saving is chosen or if there are no dirty documents, and NO otherwise.If the user selects the Review Unsaved option, closeAllDocumentsWithDelegate:didCloseAllSelector:contextInfo: is invoked. This method is invoked when users choose the Quit menu command and when the computer power is being turned off (in which case, flag is NO).

 

didReviewAllSelector should have the following signature:

- (void)documentController:(NSDocumentController *)docController didReviewAll:(BOOL)didReviewAll contextInfo:(void *)contextInfo

 

NSOpenPanel:

 

- (void)beginSheetForDirectory:(NSString *)path file:(NSString *)name types:(NSArray *)fileTypes modalForWindow:(NSWindow *)docWindow modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo

 

This method replaces runModalForDirectory:file:types:relativeToWindow:. This method presents an open panel sheet on docWindow. When the modal session is ended, the didEndSelector will be invoked.

 

The didEndSelector method should have the following signature:

- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo

 

 

Dragging

 

Dragging has some known problems. You cannot drag multiple items between the Desktop and Cocoa applications; you can only drag single items correctly between the applications.

 

-(NSImage *)draggedImage always returns nil, and -(int)draggingSequenceNumber returns 0.

 

 

NSTextAttachmentCell methods

 

The NSTextAttachmentCell protocol has the following additional methods, which complex conformers may implement for more precise control over drawing and mouse tracking:

 

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(unsigned)charIndex layoutManager:(NSLayoutManager *)layoutManager;

- (BOOL)wantsToTrackMouseForEvent:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView atCharacterIndex:(unsigned)charIndex;

 

The wantsToTrackMouse method allows an attachment to specify whether it ever wishes to track the mouse; if it returns YES, then the new wantsToTrackMouseForEvent:inRect:ofView:atCharacterIndex: allows the attachment to decide whether it wishes to do so for particular events.

 

 

Drag And Drop Support in NSTableView and NSOutlineView

 

TableView and OutlineView now support drag & drop. To use this, all that is necessary is to adopt optional API found in NSTableViewDataSource, and NSOutlineViewDataSource. To modify the default drag image, one may override a new method found in NSTableView.

 

Dragging Related DataSource Protocols:

 

To be a dragging source, the data source must implement the appropriate writeItems:toPasteboard: method. This method is called when the view determines a mouse event is the beginning of a drag. This is the data source's chance to cancel the drag, or supply the data for the rows, or items that are participating in the drag.

 

To be a dragging destination, the data source must implement the appropriate validateDrop:, and acceptDrop: methods. As a drag proceeds, the view needs to continually determine where the drop should end up if the mouse were released. Based on the mouse location, the view will negotiate where the potential drop would occur so that it can highlight the drop location for visual feedback.The drop location is negotiated with the validateDrop: method.

 

Since there is support for both between and on rows drop types, the negotiation for a drop location requires a short explanation. Assume a table view rows numbered from 0 to N-1 starting with the top most row. Now, imagine the mouse is over a row R of a table view. If the mouse is actually closer to row R+1 than the middle of row R the table view will first try to negotiate a drop between row R, and R+1. If the data source rejects that proposal, then the table view will propose dropping on row R itself. Finally, when the mouse is released, the data source will be sent an acceptDrop: so that it can incorporate the dropped data at the previously negotiated location.

 

typedef enum { NSTableViewDropOn, NSTableViewDropAbove } NSTableViewDropOperation;

// In drag and drop, used to specify a dropOperation. For example, given a table with N rows (numbered with row 0 at the top visually), a row of N-1 and operation of NSTableViewDropOn would specify a drop on the last row. To specify a drop below the last row, one would use a row of N and NSTableViewDropAbove for the operation.

 

@interface NSObject (NSTableViewDataSource)

- (BOOL)tableView:(NSTableView *)tv writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard;

// This method is called after it has been determined that a drag should begin, but before the drag has been started. To refuse the drag, return NO. To start a drag, return YES and place the drag data onto the pasteboard (data, owner, etc...). The drag image and other drag related information will be set up and provided by the table view once this call returns with YES. The rows array is the list of row numbers that will be participating in the drag.

 

- (unsigned int)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op;

// This method is used by NSTableView to determine a valid drop target. Based on the mouse position, the table view will suggest a proposed drop location. This method must return a value that indicates which dragging operation the data source will perform. The data source may "re-target" a drop if desired by calling setDropRow:dropOperation: and returning something other than NSDragOperationNone. One may choose to re-target for various reasons (eg. for better visual feedback when inserting into a sorted position).

 

- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)op;

// This method is called when the mouse is released over an outline view that previously decided to allow a drop via the validateDrop method. The data source should incorporate the data from the dragging pasteboard at this time.

@end

 

enum { NSOutlineViewDropOnItemIndex = -1 };

// May be used as a valid childIndex of a drop target item. In this case, the drop will happen directly on the target item.

 

@interface NSObject (NSOutlineViewDataSource)

- (BOOL)outlineView:(NSOutlineView *)olv writeItems:(NSArray*)items toPasteboard:(NSPasteboard*)pboard;

// This method is called after it has been determined that a drag should begin, but before the drag has been started. To refuse the drag, return NO. To start a drag, return YES and place the drag data onto the pasteboard (data, owner, etc...). The drag image and other drag related information will be set up and provided by the outline view once this call returns with YES. The items array is the list of items that will be participating in the drag.

 

- (unsigned int)outlineView:(NSOutlineView*)olv validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index;

// This method is used by NSOutlineView to determine a valid drop target. Based on the mouse position, the outline view will suggest a proposed drop location. This method must return a value that indicates which dragging operation the data source will perform. The data source may "re-target" a drop if desired by calling setDropItem:dropChildIndex: and returning something other than NSDragOperationNone. One may choose to re-target for various reasons (eg. for better visual feedback when inserting into a sorted position).

 

- (BOOL)outlineView:(NSOutlineView*)olv acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index;

// This method is called when the mouse is released over an outline view that previously decided to allow a drop via the validateDrop method. The data source should incorporate the data from the dragging pasteboard at this time.

@end

 

Notes:

- NSTableView and NSOutlineView will not register for any drag types, it is up to the client to do this.

- NSTableView and NSOutlineView allow you to drag and drop just about anywhere. However, if the source and destination are the same view, there are certain scenarios to keep in mind.The implementation will not attempt to drop on the same row you dragged from. This is filtered out. However, the implementation does not filter out an attempt to drop an item into one of its descendants. Though generally this action does not make sense, the implementation does not suppress it since some clients may want this behavior.

 

Retargeting of Drop Target Location:

 

When the data source receives validateDrop: it must return a value indicating wether or not the proposed drop can be accepted. At this time, the data source may re-target the drop location, for instance, to show that a dragged .h file will end up in the group of h files. To support re-targeting of the suggested location, we have added one new method to NSTableView and NSOutlineView respectively.

 

@interface NSTableView ...

- (void)setDropRow:(int)row dropOperation:(NSTableViewDropOperation)op;

// To be used from validateDrop: if you wish to "re-target" the proposed drop. To specify a drop on the second row, one would specify row=2, and op=NSTableViewDropOn. To specify a drop below the last row, one would specify row=[tv numberOfRows], and op=NSTableViewDropAbove.

@end

 

@interface NSOutlineView ...

- (void)setDropItem:(id)item dropChildIndex:(int)index;

// To be used from validateDrop: in order to "re-target" the proposed drop. To specify a drop on an item I, one would specify item=I, and index=NSOutlineViewDropOnItemIndex. To specify a drop between child 2 and 3 of an item I, on would specify item=I, and index=3 (children are zero-base indexed). To specify a drop on an un-expandable item I, one would specify item=I, and index=NSOutlineViewDropOnItemIndex.

@end

 

Affecting the Default Dragging Behavior:

 

By default, when a user drags out of a table or outline view, it will appear as if they are dragging a copy of the cells (usually text cells). Table views will display the entire row, while outline views will only display the outline column of each row. To use a custom drag image instead, override dragImageForRows:event:dragImageOffset:.

 

@interface NSTableView ...

- (NSImage*)dragImageForRows:(NSArray*)dragRows event:(NSEvent*)dragEvent dragImageOffset:(NSPointPointer)dragImageOffset;

// This method computes and returns an image to use for dragging. Override this to return a custom image. 'dragRows' represents the rows participating in the drag. 'dragEvent' is a reference to the mouse down event that began the drag. 'dragImageOffset' is an in/out parameter. This method will be called with dragImageOffset set to NSZeroPoint, but it can be modified to re-position the returned image. A dragImageOffset of NSZeroPoint will cause the image to be centered under the mouse.

@end

 

Common Pitfalls:

 

It is important to keep in mind a few things when implementing your data source.First, you will always be sent valid proposals. If you choose to re-target the drop, you must make sure that the drop target is valid. Secondly, NSTableView and NSOutlineView support "on" and "between" kind of drops. This means you will potentially be sent two message when the view is trying to determine where to target a drop. For example, if you are very close to the top of a row, the implementation will first suggest a drop between that row and the one above it. However, if you return NSDragOperationNone (maybe you only want "on" type drops), the implementation will suggest a drop "on" the row itself. And of course, if you are closer to the middle of the row that the edge, an "on" drop will be tried before a "between" kind of drop.

 

So, imagine you only want to accept "on" type drops. A common mistake can be seen in the following code segment:

 

- (unsigned int)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op {

...

// Decide if we want to accept the data in info...

...

if (weWantThisData) {

[tv setDropRow: row dropOperation: NSTableViewDropOn];

return NSDragOperationAll;

} else {

return NSDragOperationNone;

}

}

 

The implementer has forgotten that a row of N (where the table has rows 0 through N-1) and operation of type NSTableViewDropAbove is valid. This means that it is legal for NSTableView to propose N and NSTableViewDropAbove as the drop target (ie. to suggest a drop "below" the last row). Unfortunately, in this situation, the above segment will end up retargeting the drop to be "on" row N, which doesn't make any sense! The above code segment should have been:

 

- (unsigned int)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op {

if (op==NSTableViewDropOn) {

...

// Decide if we want to accept the data in info...

...

if (weWantThisData) {

return NSDragOperationAll;

} else {

return NSDragOperationNone;

}

} else {

return NSDragOperationNone;

}

}

 

Auto Expansion Support in NSOutlineView:

 

The drag and drop support for NSOutlineView comes with a new auto expansion feature. As a drag proceeds over a drop capable outline view, expandable items will automatically expand (after a small delay) as the mouse hovers over them.

 

When a drag has finished, the outline view may decide to automatically collapse these items (after a small delay) to return the outline view back to its original state. By default, if a drop is successful (as indicated by the return value from acceptDrop:), the items will remain open. If a drop fails, the items will collapse and return to their original state. To change this behavior, one should override the following method in NSOutlineView:

 

@interface NSOutlineView ...

- (BOOL)shouldCollapseAutoExpandedItemsForDeposited:(BOOL)deposited;

// This method returns YES to indicate that auto expanded items should return to their original collapsed state. Override this method to provide custom behavior. 'deposited' tells whether or not the drop terminated due to a successful drop (as indicated by the return value from acceptDrop:). Note that exiting the view will be treated the same as a failed drop.

@end

 

Known Bugs :

 

NSOutlineView currently has a bug that causes it to send the outlineView:validateDrop:proposedItem:proposedChildIndex: in situatuations where it is not necessary. In particular, if the mouse moved a bit, and the outline view determines the target it will suggest is the same as before, the method should not be sent. Currently, in this situation, the message will be sent, and clients should not count on this behaviour remaining.

 

 

NSImage

 

Two new methods have been added that allow an image to be rendered with any compositing operation and with any alpha value at the same time.

 

- (void)compositeToPoint:(NSPoint)point operation:(NSCompositingOperation)op fraction:(float)delta;

- (void)compositeToPoint:(NSPoint)point fromRect:(NSRect)rect operation:(NSCompositingOperation)op fraction:(float)delta;

 

Previously, an image could be composited with any operation but only at an alpha of 1.0 (-[NSImage compositeToPoint:operation:]) or just sourceOver with variable alpha (-[NSImage dissolveToPoint:fraction:]). Please note that there may be certain combinations of operation and alpha that cannot be printed correctly.

 

 

NSBitmapImageRep

 

NSImage via NSBitmapImageRep now uses the QuickTime GraphicsImporter to read additional bitmap image types. The additional types and extensions that QuickTime currently support are:

 

FlashPix.fpix, .fpx

MacPaint.pntg, .pnt, .mac

Photoshop.psd

SGI.sgi, .rgb

Targa.targa, .tga

QuickTime Image Format.qtif, .qti

 

 

NSOpenGLView

 

NSOpenGLView has been changed to archive information and allow dynamic changing of both the context and its associated pixel format. The new behavior is that the context isn't created until either -[NSOpenGLView openGLContext] or -[NSOpenGLView openGLContext] are called. This allow you to to change the pixel format after creating the view.New methods are:

 

+ (NSOpenGLPixelFormat *)defaultPixelFormat;

 

This class method is called when the context is created but no pixel format was specified. By default, this returns an format crated with an empty attribute list. You can override it in your custom class if you want to pass in a different set of attributes when the view is created.

 

- (void)clearGLContext;

 

This will dispose of the context associated with the view. You can use this to change the format and then call lockFocusagain to create a new context.

 

- (void)setPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;

- (NSOpenGLPixelFormat *)pixelFormat;

 

These set and get the pixel format associated with the context. Setting the format after the context has been created has no effect on the view's current context. This information is archived.

 

 

NSOpenGLPixelFormat

 

NSOpenGLPixelFormat now follows the NSCoding protocol. Because the attribute list is an arbitrary list of integers, you must specify the list via an NSData object if the attributes are to archived. If you create the format using initWithAttributes:, then no data is archived and when it is restored, default to an old list. New methods:

 

- (id)initWithData:(NSData *)attribs;

 

This will save the attributes passed in an NSData.

 

- (NSData *)attributes;

- (void)setAttributes:(NSData *)attribs;

 

This will allow you to set and get the attribute list for the format object.

 

 

NSColor

 

A new class method has been added that returns a single color that reflects the tint of controls.

 

+ (NSColor *)colorForControlTint:(NSControlTint)controlTint;

 

 

Keyboard Focus

 

Because of pending changes to the appearance and behavior of the keyboard focus user interface, buttons, sliders, and tabs have been temporarily turned off for the Public Beta release. This means -[NSButtonCell acceptsFirstResponder], -[NSSliderCell acceptsFirstResponder], and -[NSTabView acceptsFirstResponder] now return NO. We intend to fix this for the next release.

 

 

Standard About Panel

 

Support for the deprecated NSBuildVersion, NSAppVersion, and NSHumanReadableShortName and the internal AuxiliaryInformation and BackgroundImage keys in the options dictionary has been removed.

 

The standard about panel is currently not displaying the Credits.rtf file, although that will come back.

 

 

Scripting

 

Scripting framework's dependencies on EOControl have been removed by copying key/value coding into Foundation, and by subclassing NSScriptClassDescription off of NSClassDescription in Foundation (instead of EOClassDescription).

 

After Public Beta we intend to fold Scripting and AppKitScripting into Foundation and AppKit, respectively. To protect your app from this change, it would be best to link against Cocoa.framework instead of AppKit.framework and AppKitScripting.framework.

 

 

NSRect vs CGRect

 

We intend to fold these two types into one. However, this has not happened for Public Beta. For situations where you need to pass these back and forth, we recommend you use a macro or inline function which basically does something like:

 

*(CGRect *)&nsRect

*(NSRect *)&cgRect

 

 

Alert panel

 

The human interface guidelines for alerts now state that the message of the alert appear at top (where the title is), and more optional secondary info appear beneath that, in smaller font. So, instead of

 

Close
Do you want to save this document before closing?
<Don't Save> <Cancel> <OK>
you should instead use something like:

Do you want to save this document before closing?
The contents of this document will be lost if it is not saved.
<Don't Save> <Cancel> <OK>
 

API for dealing with alerts, and the way we handle arguments, has not been changed (the "title" argument appears as the bold item, the "message" argument as the secondary info, and the optional arguments apply only to the message); in addition, a lot of the standard panels in AppKit and standard apps have also not been updated. Developers might want to change the arguments in their alert panel calls to be more in line with these new guidelines. For now, there is no convenient way to parameterize the first argument (with the %-replacements), but you can simply use [NSString stringWithFormat:] to get around this.

 

 

Java

 

The Java packages for Cocoa frameworks have been renamed from com.apple.yellow.* to com.apple.cocoa.*. Conversion tools and instructions can be found in /Developer/Java/Conversion/YellowToCocoa.

 

 

NSEvent

 

-characters and -charactersIgnoringModifiers methods now return values processed by the Carbon Text Services Manager. TSM maps key codes using the current keyboard script (i.e. you get 'w' for 'z' position if your current keyboard script is French). The mappings occur lazily so that NSEvent calls out and creates an NSString only when it is necessary. This NSEvent class change concludes the Carbon Text Services Manager integration in the kit.

 

The scrollWheel event is now sent to the view under the mouse rather than the first responder. This means by default the view under the mouse pointer is scrolled when the scrollwheel is used.

 

 

NSGlyphGenerator

 

The text system now uses ATS-based glyph generation. This means we use the same algorithm to generate glyphs as ATSUI does. All the default features in 'morf' or 'morx' table are applied automatically including ligature, propotional Hiragana/Katakana substitution, and Unicode precomposition. Among the features, only kLigaturesType is currently mapped to NSAttributedString attribute NSLigatureAttributeName. NSLigatureAttributeName value 0 applies kRequiredLigaturesOnSelector selector, value 1 does all default selectors, and value 2 does all selector supported by the font. The glyph generator still uses the rulebook-based glyph generation if the font has a corresponding rulebook. For the time being, you can force the kit to use CG-based glyph generation by setting the _NSForceRulebookGlyphGeneration to YES.

 

AppKit is disabling kDiacriticsType, kFractionsType, and kTypographicExtrasType/kSmartQuotesOffSelector even if it is enabled in the font.

 

 

NSPICTImageRep

 

If you render an NSPICTImageRep via its draw methods, it will be drawn using QuickDraw. Because f this, it will not be clipped or transformed based on the current NSView bounds and may end up drawing outside the view.

 

In the Public Beta, NSPICTImageReps are printed as bitmaps. The bitmap image is created with an off-screen image cache window so the image sent to CoreGraphics for printing is in 72 dpi and depending on the screen depth. This may result in less than optimal printing quality. This problem will be addressed in the future release.

 

Services

 

In Public Beta there is no "make_services;" instead service discovery is done by pbs at login time. So to get new services to be recognized you will need to log out and log back in.

 

There are some issues with discovery of services in the Public Beta. Services packaged as new-style bundles should not declare an NSExecutable key in their NSServices entry, as this prevents the service from working. This means the default executable in the package should be the one providing the service. Services bundled as old-style packages should not have a .service extension; instead, using the default .app is a workaround for this.