首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在NSTableViewCell中接收mouseDown消息?

如何在NSTableViewCell中接收mouseDown消息?
EN

Stack Overflow用户
提问于 2015-08-02 19:57:55
回答 1查看 130关注 0票数 0

我正在尝试创建一个表格视图单元格,用于显示播放列表中歌曲的评级。我已经成功地创建了单元格,这样它就可以显示当前的星级数,并且还可以指示当您将鼠标光标悬停在单元格上以给出新的评级时,新设置将如何显示。

问题是,虽然mouseEntermouseExitmouseMove可以很好地工作,但我没有收到mouseDown的消息,这是更改单元格的值所必需的。

我已经在互联网上找遍了,但我找不到任何解决这个问题的方法。我花了这么多时间来解决这个问题。我希望任何人有任何答案或提示我能做什么。谢谢。

当前实现的完整代码如下:

代码语言:javascript
复制
#import "FavouriteCellView.h"

@implementation FavouriteCellView {
    NSTrackingArea *_trackingArea;
    int _starsRated; //The current rating value
    BOOL _hovering; //YES if the mouse is currently hovering over this cell
    int _starsHovering; //The number of stars hovering, if the mouse is hovering over this cell
}

- (void)awakeFromNib {
    [super awakeFromNib];
    _starsRated = 1;
    _hovering = NO;
    _starsHovering = 0;
    [self createTrackingArea];
}

- (void)createTrackingArea
{
    _trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited |NSTrackingActiveInActiveApp | NSTrackingMouseMoved owner:self userInfo:nil];
    [self addTrackingArea:_trackingArea];
}

- (void)updateTrackingAreas{
    [self removeTrackingArea:_trackingArea];
    _trackingArea = nil;
    [self createTrackingArea];
}

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

//    CGFloat middleX = [self bounds].size.width / 2.0f;
    CGFloat middleY = [self bounds].size.height / 2.0f;

    CGFloat starDivs = [self bounds].size.width / 5.0f;;

    NSColor *starSelectedColor = [NSColor colorWithDeviceRed:0.8f green:0.0f blue:0.4f alpha:1.0f];
    NSColor *starUnselectedColor = [NSColor colorWithDeviceRed:0.5f green:0.5f blue:0.5f alpha:1.0f];
    NSColor *starHoverColor = [NSColor colorWithDeviceRed:1.0f green:0.843f blue:0.0f alpha:1.0f];
    NSColor *starHoverColorSelected = [NSColor colorWithDeviceRed:0.9f green:0.843f blue:0.6f alpha:1.0f];

    for (int i = 0; i < 5; i++) {

        NSColor *useColor = [NSColor redColor];

        if (_hovering && (i <= _starsHovering)) {
            if (i <= _starsRated) {
                useColor = starHoverColorSelected;
            } else {
                useColor = starHoverColor;
            }
        } else if (i <= _starsRated) {
            useColor = starSelectedColor;
        } else {
            useColor = starUnselectedColor;
        }

        [self star:NSMakePoint((starDivs / 2.0f) + starDivs * i, middleY) color:useColor];
    }
}

-(void)star:(NSPoint)center color:(NSColor *)color {
    [color set];

    CGFloat t = (2.0f * M_PI) / 10.0f;

    NSBezierPath *path = [[NSBezierPath alloc] init];

    CGFloat radii1 = 12.0f;
    CGFloat radii2 = 4.0f;

    CGFloat rot = M_PI / 2.0f;

    BOOL first = YES;
    for (int i = 0; i < 10; i++) {
        CGFloat pointX = cos(t * i + rot) * radii1 + center.x;
        CGFloat pointY = sin(t * i + rot) * radii1 + center.y;

        CGFloat tempRadii = radii1;
        radii1 = radii2;
        radii2 = tempRadii;

        if (first) {
            first = NO;
            [path moveToPoint:NSMakePoint(pointX, pointY)];
        }
        else {
            [path lineToPoint:NSMakePoint(pointX, pointY)];
        }
    }

    [path closePath];
    [path fill];

/*
    [[NSColor blackColor] set];
    [path setLineWidth:0.25f];
    [path stroke];
*/
}

-(NSView *)hitTest:(NSPoint)aPoint {
    //THIS GETS CALLED
    return self;
}

-(BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event {
    printf("$");  //DOES NOT GET CALLED
    return YES;
}

-(BOOL)acceptsFirstResponder {
    printf("!");  //DOES NOT GET CALLED
    return YES;
}

-(BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
    printf("8");  //DOES NOT GET CALLED
    return YES;
}

-(void)mouseDown:(NSEvent *)theEvent {
    printf("o");  //DOES NOT GET CALLED
    _starsRated = _starsHovering;
}

-(void)mouseUp:(NSEvent *)theEvent {
    printf("O");  //DOES NOT GET CALLED
}

-(void)mouseEntered:(NSEvent *)theEvent {
    //DOES GET CALLED
    _hovering = YES;
    [self setNeedsDisplay:YES];
}

-(void)mouseExited:(NSEvent *)theEvent {
    //DOES GET CALLED
    _hovering = NO;
    [self setNeedsDisplay:YES];
}

-(void)mouseMoved:(NSEvent *)theEvent {
    //DOES GET CALLED
    NSPoint mouseLocation = [[self window] mouseLocationOutsideOfEventStream];
    mouseLocation = [self convertPoint: mouseLocation
                          fromView: nil];

    int newStarsHoveringValue = mouseLocation.x / ([self bounds].size.width / 5.0f);

    if (newStarsHoveringValue != _starsHovering) {
        _starsHovering = newStarsHoveringValue;
        [self setNeedsDisplay:YES];
    }
}

@end
EN

回答 1

Stack Overflow用户

发布于 2015-08-03 02:44:04

这有点麻烦,但我设法创建了一个有效的解决方案。我继承了NSTableView,然后用下面的代码重写了mouseDown

代码语言:javascript
复制
-(void)mouseDown:(NSEvent *)theEvent {
    NSPoint globalLocation = [theEvent locationInWindow];
    NSPoint localLocation = [self convertPoint:globalLocation fromView:nil];
    NSInteger clickedRow = [self rowAtPoint:localLocation];

    if (clickedRow != -1) {
        NSInteger clickedColumn = [self columnAtPoint:localLocation];
        if (clickedColumn != -1) {
            if (clickedColumn == 3) {
                FavouriteCellView *fv = [self viewAtColumn:clickedColumn row:clickedRow makeIfNecessary:NO];
                if (fv != nil) {
                    [fv mouseDown:theEvent];
                }
                return;
            }
        }
    }

    [super mouseDown:theEvent];
}

现在它完全按照我想要的那样工作了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31771682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档