Re: A cursor bug in DragItemAround example
Re: A cursor bug in DragItemAround example
- Subject: Re: A cursor bug in DragItemAround example
- From: Quincey Morris <email@hidden>
- Date: Sat, 26 Apr 2008 12:48:02 -0700
On Apr 26, 2008, at 08:47, an0 wrote:
Thanks. I've tried NSTrackingArea, and it seems a clearer concept and
easier to use. However, there are still two problems I can't fix:
1. Setting cursor in initWithFrame: and awakeFromNib does not have
effect. So I can't set the initial cursor.
2. Setting cursor together with tracking areas renders the cursor
setting ineffective. I found this from my mouseUp action. With the
code handling tracking areas, [[NSCursor openHandCursor] set] did not
give me an openHandCursor, but an arrowCursor.
-(void)mouseUp:(NSEvent *)event
{
dragging=NO;
[self removeTrackingArea:trackingRect];
self.trackingRect = [[[NSTrackingArea alloc] initWithRect:[self
calculatedItemBounds]
options:NSTrackingCursorUpdate | NSTrackingActiveInActiveApp
owner:self
userInfo:nil]
autorelease];
[self addTrackingArea:trackingRect];
[[NSCursor openHandCursor] set];
}
My guess is that the cursor you set is getting changed back to the
arrow by the cursorUpdate: method of another view.
IIRC, you have a NSScrollView whose document view (view A) is
something like a canvas, and has some smaller subviews (each a view B)
that are like graphic objects on the canvas, which you want to be able
to drag around. Let's say you want the cursor to be the crosshair
cursor inside view A *except* when you're hovering over a B view (open
hand cursor) or dragging a B view (closed hand cursor). To achieve
this with NSTrackingArea, you could:
-- Create a tracking area for view A using options:
NSTrackingCursorUpdate | NSTrackingActiveInActiveApp |
NSTrackingInVisibleRect.
-- Create a tracking area for each view B using options:
NSTrackingCursorUpdate | NSTrackingActiveInActiveApp |
NSTrackingInVisibleRect.
You would do this *only once* for each view. The
NSTrackingInVisibleRect option takes care of the housekeeping for you
even if the views change size or position or visibleRect.
-- Add a cursorUpdate: override to view A, something like:
-(void)cursorUpdate:(NSEvent *)event
{
if (<any B view is dragging>)
[[NSCursor closedHandCursor] set];
else
[[NSCursor crosshairCursor] set];
}
-- Add a cursorUpdate: override to view B, something like:
-(void)cursorUpdate:(NSEvent *)event
{
if (<any B view is dragging>)
[[NSCursor closedHandCursor] set];
else
[[NSCursor openHandCursor] set];
}
-- In the mouseDown: method where you start dragging view B, put:
dragging = YES;
[[self enclosingScrollView] setDocumentCursor:[NSCursor
closedHandCursor]];
-- In the mouseUp: method where you stop dragging view B, put:
dragging = NO;
[[self enclosingScrollView] setDocumentCursor:[NSCursor
arrowCursor]];
I may have overlooked something, but I think is is all the cursor-
handling code you would need.
(Well, if you have multiple windows with A views in them, or multiple
A views in a window, or other kinds of views that use NSTrackingArea
with the NSTrackingActiveInActiveApp option to control the cursor,
this scheme isn't going to work properly. You could use
NSTrackingActiveInKeyWindow or NSTrackingActiveWhenFirstResponder
instead of NSTrackingActiveInActiveApp, perhaps, otherwise you'll have
to do something application-wide to force the other views to leave the
cursor alone during the drag.)
Note that if your mouse pointer goes outside the scroll view during a
drag, the cursor may get changed by whatever view is under the mouse
(e.g. a text field). I don't think there's much you can do about it if
you don't own those views.
Note also that the cursorUpdate event is a bit strange. When the
cursor enters a particular tracking area's bounds, the cursorEvent is
not sent to the tracking area's owner (like mouseEntered/mouseExited
are), and it's not sent to the view that the tracking area was
installed into. It's sent to the topmost view under the mouse pointer,
whatever that may happen to be.
HTH
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please 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