Re: question about custom cursor
Re: question about custom cursor
- Subject: Re: question about custom cursor
- From: Alastair Houghton <email@hidden>
- Date: Wed, 7 Mar 2007 11:59:17 +0000
On 7 Mar 2007, at 04:46, Fred Hope wrote:
I alloc+init my cursor with this line:
cursor = [[NSCursor alloc] initWithImage:[NSImage
imageNamed:@"cursor.tiff"] hotSpot:NSMakePoint(8,0)];
Looks OK.
And I set the cursor's rect and such here (I have the custom cursor
appear when the mouse enters the image view, and the arrow cursor
returns when the mouse exits the view):
NSRect rect = NSMakeRect(0, 0, WINDWIDTH-1, WINDHEIGHT-1);
You shouldn't do this. First off, because you're hard-coding the size
of a UI element in your application unnecessarily, and second,
because your adding the tracking rect to a view, so you should be
using the size of that view. i.e. you should probably be doing
NSRect rect = [imgView visibleRect];
[imgView addCursorRect:rect cursor:cursor];
[imgView addTrackingRect:rect owner:cursor userData:nil
assumeInside:NO];
[imgView addCursorRect:rect cursor:[NSCursor arrowCursor]];
[imgView addTrackingRect:rect owner:[NSCursor arrowCursor]
userData:nil assumeInside:NO];
OK, well you're adding two cursor rects with different cursors and
the same rectangle, which is going to confuse things. You've also got
two tracking rects, which isn't necessary either. What you want is
just a single invocation of -addCursorRect:cursor:.
[cursor set];
[cursor setOnMouseEntered:YES];
[[NSCursor arrowCursor] setOnMouseExited:YES];
You don't need to do that either; the -addCursorRect:cursor: method
will handle setting the cursor for you.
Also, you don't say where you're doing all of this; you should be
doing it in the -resetCursorRects method of your view (if necessary,
you will need to subclass whatever you're using for imgView), so the
full solution should look like this:
- (void)resetCursorRects
{
static NSCursor *myCursor = nil;
if (!myCursor) {
myCursor = [[[NSCursor alloc] initWithImage:[NSImage
imageNamed:@"cursor.tiff"]
hotSpot:NSMakePoint (8.0f,
0.0f)];
}
[self addCursorRect:[self visibleRect] cursor:myCursor];
}
You might consider having the cursor variable as an instance variable
of your class, or even a global (but probably static) variable in the
file containing the class's code. In the former case you'd initialise
it from -initWithFrame:, and in the latter, probably from
+initialize. Using a static variable with local scope like the one in
the example above is quite a neat trick, though, as it makes it easy
to lazily create things without adding unnecessary global variables.
BTW, the reason for using -visibleRect rather than -bounds is that if
you put your view inside an NSScrollView (or, in fact, inside an
NSClipView, which is where it will be if you put it in a scroll view
with Interface Builder), not all of the view will necessarily be
visible in your window. If you were to stray outside the visible
area, you might see unusual behaviour in the area outside the content
region of the scroll view because of the way cursor and tracking
rectangles are implemented.
I'd also recommend using a more descriptive name than "cursor.tiff"
for the image file itself; in a year's time, when you come back to
your code, you'll likely have to open the tiff file up to see what
sort of cursor it's for if you use names like that :-)
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden