Re: Drawing an NSImage into a custom NSView
Re: Drawing an NSImage into a custom NSView
- Subject: Re: Drawing an NSImage into a custom NSView
- From: mw <email@hidden>
- Date: Wed, 16 Oct 2002 06:43:02 -0400
Okay, this is a response to all of your comments.
First off, thanks for all of the help! :-)
Second, I found where the problem resides (I can't find a solution,
however). It seems that, by the time the function that everyone was
analyzing is called, image = nil. I am totally clueless, but hopefully some
sample code will help :-).
There are 3 custom controls on the window. In the end, they will start out
in one "state", and change when the mouse rolls over, they change state to a
more colorful, "over" state. (this is a practice app for the real one
because I wanted to be sure I could make custom windows and controls before
the production started)
So, I had the 3 custom NSView subclasses set out in my nib file, as well as
a controller for the views (subclass of NSObject) called ViewController.
ViewController was supposed to take the 3 images from the application's
bundle and assign them to the 3 custom views (each of which it had an outlet
to) using a setter method. Here is the setter method (which sets the image
to an instance variable in the custom view class):
- (void)fillWithImage:(NSImage *)image
{
[image retain];
imageToDraw = [image copyWithZone:[self zone]];
[imageToDraw retain];
[image release];
[self setNeedsDisplay:YES];
}
I have gone through this function in the debugger, and image is a valid
image. Before the function ends, I also check imageToDraw, and it is the
same image. It also has the correct retainCount of 2. But the image was
still nil when it got to this function (you've all seen it already):
- (void)drawRect:(NSRect)rect {
NSRect imageRect, controlRect;
imageRect.origin.x = 0.0;
imageRect.origin.y = 0.0;
imageRect.size = [imageToDraw size];
controlRect = [self bounds];
[imageToDraw drawInRect:imageRect
fromRect:controlRect
operation:NSCompositeCopy
fraction:1.0];
}
The problem turned out to be that ViewController was getting inited by the
nib file BEFORE the custom views were. So to *fix* this problem, I added if
statements in the ViewController's code that would alloc and init the three
controls and then go from there. The image was still nil, however, because
after I manually allocated and initialized them (and then went about setting
images and whatnot), the nib file re-initialized them and caused all of my
actions to be overwritten!
So I decided to attempt to use notifications. The controls would send out a
notification when it was loaded, and the ViewController would receive it and
then call its method to set the images. However, it would set the images for
all 3 of the controls, even if all of them hadn't been loaded. But this
shouldn't be a big deal because it *should* cause all of them to have their
images loaded since it would just end up sending the same message to the
first loaded control 3 times, the second control 2 times, and then the
finally loaded control 1 time, correct? However, it STILL doesn't work.
Think I am going about this in a slightly overcomplicated way? ;-)
Please, any help? I can't understand why image STILL equals nil.
mw
On 10/16/02 4:44 AM, "Marco Binder" <email@hidden> wrote:
>
I dont think that s a good idea. The image can be a different size than
>
the view to draw in, so aRect will refer to different rect if not at
>
0,0 or at least, will not display the whole image, scaled to fit, as
>
Marc probably wants. Thats why he really sould use compositeToRect (not
>
compositeToPoint as previously suggested) and use two different rects
>
(either, as he does, at a performance hit, the whole thing, or he has
>
to convert the rects... a pain in the a**).
>
>
Second: when drawRect is called, the focus HAS BEEN locked already. At
>
least, thats the way it should be. You never have to call lockFocus on
>
yourself in a draw method, as far as I know.
>
>
NSCompositeCopy should work well.
>
>
On the other hand, I m clueless what might be going wrong, since it
>
should work just the way Marc did it. That is, it workes for me.
>
>
Marc, maybe you should check again if your image is valid. It really
>
should work the way you do it, if the image is correct. Why not put it
>
in an NSImageView to check [imageView setImage:image];
>
>
Sorry I cant be of more help,
>
>
marco
>
>
>
Am Mittwoch, 16.10.02 um 09:37 Uhr schrieb Charles Srstka:
>
>
> Actually, I'm about to slap myself in the face for not thinking of
>
> this: there's an even easier, and better performance-wise solution than
>
> using NSZeroRect. It is, simply:
>
>
>
> - (void)drawRect:(NSRect)aRect {
>
> [self lockFocus];
>
> [image drawInRect:aRect
>
> fromRect:aRect
>
> operation:NSCompositeSourceOver // or whatever composite
>
> operation you want
>
> fraction:1.0];
>
> [self unlockFocus];
>
> }
>
>
>
> This is the way I would do it. It beats both the imgSize, srcRect
>
> method and NSZeroRect, because if some of the view is not visible, only
>
> the visible part gets drawn. And it's very easy to type, and very
>
> obvious, and I really should have thought of it when writing my first
>
> reply. Oh well.
>
>
>
> Charles
>
>
>
> On Tuesday, October 15, 2002, at 10:09 PM, David Remahl wrote:
>
>
>
>>> All I know is that it is a quick way to just draw the entire image,
>
>>> and
>
>>> that it works when I do it.
>
>>
>
>> Ok. That is very interresting. I have always fonud the
>
>>
>
>> NSSize imgSize = [img size];
>
>> NSRect srcRect = NSMakeRect( 0.0, 0.0, imgSize.width, imgSize.height
>
>> );
>
>> [img drawImageFromRect:srcRect .....];
>
>>
>
>> A real kludge. Using NSZeroRect would be nice both to performance
>
>> (although
>
>> not a lot) and to my typing fingers.
>
>>
>
>> / Rgds, David
>
>> _______________________________________________
>
>> 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.
>
> _______________________________________________
>
> 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.
_______________________________________________
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.