Using NSImagePicker from the Address Book
Using NSImagePicker from the Address Book
- Subject: Using NSImagePicker from the Address Book
- From: Nicko van Someren <email@hidden>
- Date: Sun, 25 Jan 2004 06:27:20 +0000
**** Note that this mail pertains to an undocumented and unsupported
API ****
It appears that on Panther the panel that the Address Book application
uses for setting a user's photo is bundled up inside the Address Book
framework. Inside the standard /System/Library/Frameworks there is the
AddressBook.framework and in it's resources there is
ImagePickerQTParts.bundle, which contains the NSImagePicker NIB files
and classes for the image picker, complete with support for snapping
shots from your iSight or other QuickTime supported camera.
Since I was after pretty much the same functionality for an application
I was thinking about, and I didn't really feel like climbing the
learning curve of QuickTime, I thought I'd work out how hard it is to
use the panel from the Address Book. The answer is that it's really
easy, as long as you can bring yourself to use a totally undocumented
and clearly "not for release" internal API :-)
Below is a header file derived from bits of class-dump output and some
digging around. All you need to use this is to include the
AddressBook.framework into your project and this header file. Then you
can put up the image picker with this code:
NSImagePickerController *pickController = [NSImagePickerController
sharedImagePickerControllerCreate: YES];
[pickController setDelegate: someDelegateObject];
[pickController initAtPoint: [NSEvent mouseLocation] inWindow: nil];
[pickController setHasChanged: NO];
[[pickController window] makeKeyAndOrderFront: nil];
The delegate someDelegateObject should implement some or all of the
methods:
- (void)imagePicker: (id) sender selectedImage: (NSImage *) image;
- (void)imagePickerCanceled: (id) sender;
- (NSImage *) displayImageInPicker: junk;
- (NSString *) displayTitleInPicker: junk;
which variously handle the user clicking OK, the user clicking Cancel,
the provision of an initial image and the provision of a title for the
panel. If you are picking images for entries in a database (an address
book, for instance :-) then, should the user change the selection, you
can send a selectionChanged message to the controller and the last two
methods will get called again.
Of course you use this at your peril! The API is totally unsupported
by Apple, obviously not as polished as their other interfaces, clearly
not intended for external use and doubtless subject to change without
notice. You certainly wouldn't want to use this in any commercial
release-grade software. *** YOU HAVE BEEN WARNED! ***
That said, for the small task I had in hand it's turned out to be very
useful! I hope that one day Apple will tidy this up in the future,
document it and add it to the armoury of useful panels and pickers that
they already supply for us.
Cheers,
Nicko
------------------------------ NSImagePicker.h
-------------------------------------
/*
* Derrived from the ourput of class-dump (version 2.1.5).
* class-dump is Copyright (C) 1997, 1999, 2000, 2001 by Steve
Nygard.
* ****** WARNING !!!! ******
*
* This set of classes is not documented by Apple, and as such there is
* absolutely no guarantee that it will not change! There are clear
signs
* that the API was never expected to be used by third parties in its
current
* form.
*
* ****** USE AT YOUR OWN RISK !!!! ******
* Refers to parts of file:
/System/Library/Frameworks/AddressBook.framework/AddressBook and
*
.../AddressBook.framework/ImagePickerQTParts.bundle/Contents/MacOS/
ImagePickerQTParts
*/
#import <AppKit/AppKit.h>
// This is defined as a protcol for documentation reasons; it's not
really necessary to have it so
@protocol ApparentlyNSImagePickerDelegateProtocol
// This gets called when the user selects OK on a new image
- (void)imagePicker: (id) sender selectedImage: (NSImage *) image;
// This is called if the user cancels an image selection
- (void)imagePickerCanceled: (id) sender;
// This is called to provide an image when the delegate is first set and
// following selectionChanged messages to the controller.
// The junk on the end seems to be the selector name for the method
itself
- (NSImage *) displayImageInPicker: junk;
// This is called to give a title for the picker. It is called as
above.
// Note that you must not return nil or the window gets upset
- (NSString *) displayTitleInPicker: junk;
@end
@interface NSImagePickerController:NSWindowController
{
@private
id _imageView;
id *_layerSuperview;
NSSlider *_slider;
id *_recentMenu;
NSButton *_cameraButton;
NSButton *_smallerButton;
NSButton *_largerButton;
NSButton *_chooseButton;
NSButton *_setButton;
NSImage *_originalImage;
struct _NSSize _originalSize;
struct _NSSize _targetSize;
struct _NSSize _minSize;
struct _NSSize _maxSize;
float _defaultSliderPos;
id *_recentPicture;
char _changed;
char _changesAccepted;
char _takingPicture;
id _target;
SEL _action;
void *_userInfo;
id _delegate;
}
// This seems to be the best way to get the Image Picker to use
+ (NSImagePickerController *) sharedImagePickerControllerCreate: (BOOL)
create;
// This is the pop-up for the recently presented pictures
+ recentPicturesPopUp;
// The point given is NOT taken within the context of the window!
- initAtPoint:(NSPoint) p inWindow: w;
// Don't use this method! Implement delegate imagePicker:selectedImage:
and imagePickerCanceled: instead
// This target here can't work out if the user hit Cancel
- (void)setTarget: onObject selector:(SEL) aSelector userInfo:(void *)
context;
// Get the image back
- image;
// Get back the image that was there before
- originalImage;
// Set the delegate
- (void)setDelegate: anObject;
// Notify the controller that the selection for which we are setting
the image
// has changed. This causes the delegate to be asked for a new image
and title
- (void)selectionChanged;
- (void)hideRecentsPopUp;
@end
@interface NSImagePickerController(QTImagePickerBundle)
// Get information about the inner bundle
+ bundle;
// Get/Set if the user has changed anything in the dialoge
- (void)setHasChanged: (BOOL) changed;
- (BOOL)hasChanged;
- (void)handlePictureTakenNotification: (NSNotification *)
aNotification;
// You need to call this when you get notification that a cammera has
been (un)plugged
- (void)_updateCameraButton;
// Set the image to be displayed. Useful for the initial image, or you
can implement delegate displayImageInPicker:
- (void)setWidgetImage: (NSImage *) anImage;
// Get and set the cropping rectangle
- (NSRect)crop;
- (void)setCrop: (NSRect) aRect;
// The remaining methods are ones that are not obviously standard
methods or actions for the panel
// but which I've not yet work out
// Fakes OK and Cancel
- (void)sendChangesToOwner;
- (void)sendCancelToOwner;
// Handles information pertaining to the recent pictures list
- (void)setRecentPicture:fp8;
- recentPicture;
- (void)setViewImage:(NSSize)fp8;
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.