Thanks again. It seems tracking area is not suited for this application. And I revert to cursor rect finally. Wish a better tracking area from Apple.
On Mon, Apr 28, 2008 at 1:30 AM, Quincey Morris <[EMAIL PROTECTED]> wrote: > I think the problem is that you are not properly handling *responsibility* > for the cursor. You should only change the cursor when you are responsible > for it, and when you are responsible for it you should make sure that you > set it. So, for example: > > > On Apr 27, 2008, at 02:35, an0 wrote: > - (IBAction)setItemPropertiesToDefault:(id)sender > { > [self setLocation:NSMakePoint(0.0,0.0)]; > > NSTrackingAreaOptions options = NSTrackingCursorUpdate | > NSTrackingActiveInActiveApp; > > NSPoint localPoint = [self convertPoint:[[self window] > mouseLocationOutsideOfEventStream] > fromView:nil]; > > if ([self isPointInItem:localPoint]) { > inTrackingRect = YES; > options |= NSTrackingAssumeInside; > [[NSCursor openHandCursor] set]; > } else { > inTrackingRect = NO; > } > > if (trackingRect) { > [self removeTrackingArea:trackingRect]; > } > > self.trackingRect = [[[NSTrackingArea alloc] initWithRect:[self > calculatedItemBounds] > options:options > owner:self > userInfo:nil] > autorelease]; > [self addTrackingArea:trackingRect]; > } > > This method is called from awakeFromNib, but at that time you don't know > that you are responsible for the cursor -- the mouse pointer could be > anywhere. You can set up the tracking area, yes, but you should defer > setting the cursor until you're told that you are responsible for setting > it, which is what the cursorUpdate event is for: > > -(void)cursorUpdate:(NSEvent *)event > { > if (dragging) { > return; > } > > if (!inTrackingRect) { > [[NSCursor openHandCursor] set]; > } else { > [[NSCursor arrowCursor] set]; > } > inTrackingRect = !inTrackingRect; > } > > This has the opposite problem. You should set the cursor before returning > while dragging, since getting to this method means that you are currently > responsible for the cursor. > > Also, you haven't taken responsibility for setting the cursor when the mouse > pointer is in the view containing these draggable items but outside all of > the items. If the mouse pointer is outside all of the tracking areas you've > created, your cursorUpdate is not going to be called, and the cursor will > default to an arrow. This is OK when you're not dragging, but means the > cursor won't "stick" as the closed hand when you are dragging. > > To fix that, you really need to add a tracking area to the superview (with > the NSTrackingInVisibleRect option in this case). Then you would also have > to add a cursorUpdate to the superview, which knows to set the cursor to the > closed hand or the arrow depending on the dragging state. (So, the superview > needs to be a custom view too.) > > There's another source of complexity here, too. Tracking areas really deal > with the concept of the mouse entering or exiting a rectangle, not the > concept of the mouse *being* in the rectangle. So, when you create or > recreate a tracking area, you don't get any related events immediately. You > might not get an event until the mouse actually crosses into or out of the > rectangle. Using NSTrackingAssumeInside helps, but even with it you won't > get an event until the mouse actually moves (well, that's true for > mouseEntered/mouseExited events -- I'm not certain about cursorUpdate). > > This means that every time you create or recreate a tracking area, there can > be a temporary loss of synchronization between your code's idea of the mouse > state and the actual state. There's no complete solution to this defect in > tracking area, afaik. > > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [EMAIL PROTECTED]