Re: Custom Palette and NSImage
Re: Custom Palette and NSImage
- Subject: Re: Custom Palette and NSImage
- From: August Trometer <email@hidden>
- Date: Tue, 10 Jan 2006 15:44:29 -0500
Thanks for the tips. It seems there should be a more elegant way, but
brute force is sometimes better than nothing. I'll give it a go!
-- August
On Jan 10, 2006, at 1:47 PM, Ricky Sharp wrote:
On Jan 10, 2006, at 11:13 AM, August Trometer wrote:
I am trying to build a custom palette for a view object I use
quite frequently. The palette works fine, except for being able to
reference images.
The view has a configurable background image, just like a button.
In the view itself, I am storing the name of the image, rather
than the actual image. I'm doing this to save space in the object.
First, is storing the name the best way, or should I store the
actual mage?
Second, when I am using the palette and I configure the background
image, I'd like that image to be displayed as it normally would.
When I use the NIB within an application, it finds the image fine
and renders properly. However, in the palette, the bundle path
that NSImage is checking is "/Developer/Applications/Interface
Builder.app" so the image can't be found. How do I reference the
image from within the project folder when I'm in IB?
One approach is to do a brute-force loading of all project images
when the nib is opened in IB. To do this, register for
IBDidOpenDocumentNotification in your palette's +initialize:
+ (void)initialize
{
[(NSNotificationCenter*) [NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(myDocumentDidOpen:)
name:IBDidOpenDocumentNotification object:nil];
}
// Here's an implementation I currently use for one of my palettes
for loading all PDF images (that's the only image type I use).
You'll of course have to modify this to work with other image type(s).
+ (void) myDocumentDidOpen:(NSNotification*)aNotification
{
id <IBDocuments> theDocument = [aNotification object];
if (theDocument != nil)
{
id<IBProjects> theProject = [theDocument project];
if (theProject != nil)
{
// Load project images
NSArray* resources = [theProject
filesForFileType:IBProjectResourcesFileType];
if (resources != nil)
{
NSEnumerator* enumerator;
id element;
NSString* elementString;
NSRange range;
NSString* nameKey = @".pdf";
NSImage* image = nil;
enumerator = [resources objectEnumerator];
while ((element = [enumerator nextObject]) != nil)
{
elementString = [element path];
range = [elementString rangeOfString:nameKey];
if (range.location != NSNotFound)
{
image = [[NSImage alloc]
initWithContentsOfFile:elementString];
if (image != nil)
{
NSArray* thePathComponents =
[elementString pathComponents];
NSArray* theFileComponents =
[[thePathComponents lastObject] componentsSeparatedByString:@"."];
[image setName:[theFileComponents
objectAtIndex:0]];
}
}
}
}
}
}
}
When you need an image, just use NSImage's imageNamed: to obtain a
reference to the image. Of course, you'll have to launch IB after
your Xcode project is already open.
Finally, if I get a special image path to display the image in IB,
how can I get the real image when the object is being used in my
app? Basically, what is the proper way to say "if this is in IB do
_this_, but if this is in an app, do _this_."
I created two flavors of an 'ImageFactory' object that had the same
exact APIs: In my palette, obtaining an image does so by using
NSImage's imageNamed:. In my app, I use a different factory
implementation that covers my needs there. In shared code, just
use some symbol defined in your palette's precompiled header (e.g.
#define MyPalette 1).
___________________________________________________________
Ricky A. Sharp mailto:email@hidden
Instant Interactive(tm) http://www.instantinteractive.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden