NSPopUpButton subclass + Tracking Rects don't generate enter/exit events

  • Hi all.  I'm trying to implement a fairly straight forward customized
    version of a borderless NSPopUpButton on 10.4.  All I want to do is
    draw a rounded rect inside the button's frame during mouse over.  So
    I create a tracking rect with the the button's frame so I get enter/
    exit events.  However I never get any.  The rect gets set correctly I
    just never hear anything else from it.

    Here is my pertaining code:

    - (void)viewDidMoveToWindow {
    // set up our tracking rect
    frameTrackingRectTag = [self addTrackingRect:[self frame] owner:self
    userData:nil assumeInside:NSMouseInRect([self convertPoint:[[self
    window] mouseLocationOutsideOfEventStream] fromView:nil],[self frame],
    [self isFlipped])];

    NSLog(@"frame tracking rect: %@, frameTrackingTag: %d (inside: %@)",
    NSStringFromRect([self frame]), frameTrackingRectTag, NSMouseInRect
    ([self convertPoint:[[self window] mouseLocationOutsideOfEventStream]
    fromView:nil],[self frame],[self isFlipped]) ? @"YES" : @"NO" );
    }

    - (void)viewWillMoveToWindow:(NSWindow *)newWindow {
        if ( [self window] && frameTrackingRectTag ) {
            [self removeTrackingRect:frameTrackingRectTag];
        }
    }

    - (void)mouseEntered:(NSEvent *)theEvent {
    NSLog(@"entered");

    if( [theEvent trackingNumber] == frameTrackingRectTag )
      [self highlight:YES];
    }

    - (void)mouseExited:(NSEvent *)theEvent {
    NSLog(@"exited");

    if( [theEvent trackingNumber] == frameTrackingRectTag )
      [self highlight:NO];
    }

    - (void)setFrame:(NSRect)frame {
        [super setFrame:frame];

        [self removeTrackingRect:frameTrackingRectTag];
        frameTrackingRectTag = [self addTrackingRect:frame owner:self
    userData:nil assumeInside:NSMouseInRect([self convertPoint:[[self
    window] mouseLocationOutsideOfEventStream] fromView:nil],[self frame],
    [self isFlipped])];
    }

    Anyone see anything wrong?  Most of this code is yanked straight form
    Apple's docs.  However, I haven't written tracking rect code in a
    while so I assume I am missing something.

    Thanks!

    ->Ben
    --
    Ben Lachman
    Acacia Tree Software

    http://acaciatreesoftware.com

    <blachman...>
  • On Feb 16, 2008, at 02:01, Ben Lachman wrote:

    > Here is my pertaining code:
    >
    > - (void)viewDidMoveToWindow {
    > // set up our tracking rect
    > frameTrackingRectTag = [self addTrackingRect:[self frame]
    > owner:self userData:nil assumeInside:NSMouseInRect([self
    > convertPoint:[[self window] mouseLocationOutsideOfEventStream]
    > fromView:nil],[self frame],[self isFlipped])];
    >
    > NSLog(@"frame tracking rect: %@, frameTrackingTag: %d (inside:
    > %@)", NSStringFromRect([self frame]), frameTrackingRectTag,
    > NSMouseInRect([self convertPoint:[[self window]
    > mouseLocationOutsideOfEventStream] fromView:nil],[self frame],[self
    > isFlipped]) ? @"YES" : @"NO" );
    > }
    >

    Don't you mean [self bounds] instead of [self frame]?

    > - (void)setFrame:(NSRect)frame {
    > [super setFrame:frame];
    >
    > [self removeTrackingRect:frameTrackingRectTag];
    > frameTrackingRectTag = [self addTrackingRect:frame owner:self
    > userData:nil assumeInside:NSMouseInRect([self convertPoint:[[self
    > window] mouseLocationOutsideOfEventStream] fromView:nil],[self
    > frame],[self isFlipped])];
    > }

    And setBounds instead of setFrame.

    But it's not generally correct to assume that setFrame is the only way
    the frame can get changed, or that setBounds is the only way the
    bounds can get changed (although it may be safe enough for the bounds
    if you've set your button not to autoresize). The safe way to monitor
    bounds (or frame) changes is to turn on bounds (or frame)
    notifications for the view, register to receive bounds (or frame)
    change notifications, and do whatever you need to do in the
    notification method.

    One more thing. Be careful about what 'assumeInside' means. The
    behavior of the option was "fixed" in Leopard, which implies there was
    something wrong with it in 10.4, though I don't know what the problem
    was.
previous month february 2008 next month
MTWTFSS
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29    
Go to today
MindNode
MindNode offered a free license !