Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hover Over effect in NSCollectionView

I have an NSCollectionView with a few NSViews in it. The NSView has an NSBox in it that changes color when it is selected. I want to also make the NSBox change color when hovered over.

I subclassed NSBox and added the mouseEntered and mouseExited methods. I used addTrackingRect inside of viewWillMoveToWindow but the problem is that the hover over effect only happens if I first select the subview that the box is in.

Furthermore only the box that is selected has the Hover Over effect happening on it. How can I implement the Hover Over effect such that all the NSViews in my NSCollectionView show the effect immediately?

like image 823
Nonconformist Avatar asked Jan 31 '13 21:01

Nonconformist


1 Answers

You can override updateTrackingAreas in a subclass of NSView to accomplish this behavior:

Interface

@interface HoverView : NSView

@property (strong, nonatomic) NSColor *hoverColor;

@end

Implementation

@interface HoverView ()

@property (strong, nonatomic) NSTrackingArea *trackingArea;
@property (assign, nonatomic) BOOL mouseInside;

@end

@implementation HoverView

- (void) drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    // Draw a white/alpha gradient
    if (self.mouseInside) {
        [_hoverColor set];
        NSRectFill(self.bounds);
    }
}


- (void) updateTrackingAreas {
    [super updateTrackingAreas];

    [self ensureTrackingArea];
    if (![[self trackingAreas] containsObject:_trackingArea]) {
        [self addTrackingArea:_trackingArea];
    }
}

- (void) ensureTrackingArea {
    if (_trackingArea == nil) {
        self.trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
                                                         options:NSTrackingInVisibleRect | NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited
                                                           owner:self
                                                        userInfo:nil];
    }
}

- (void) mouseEntered:(NSEvent *)theEvent {
    self.mouseInside = YES;
}

- (void) mouseExited:(NSEvent *)theEvent {
    self.mouseInside = NO;
}

- (void) setMouseInside:(BOOL)value {
    if (_mouseInside != value) {
        _mouseInside = value;
        [self setNeedsDisplay:YES];
    }
}


@end
like image 119
Sheamus Avatar answered Sep 19 '22 13:09

Sheamus