0

プレイリスト内の曲の評価を表示するテーブル ビュー セルを作成しようとしています。現在の星の数を表示するセルの作成に成功しました。また、セルの上にマウス カーソルを置いて新しい評価を与えると、新しい設定がどのようになるかを示します。

問題は、 と がチャームのように機能する一方で、セルの値を実際に変更するために必要な のメッセージが表示されないことmouseEnterです。mouseExitmouseMovemouseDown

インターネット全体を検索しましたが、この問題を解決する方法がどこにも見つかりません。これを整理するのに何時間も費やしました。誰かが私に何ができるかの答えやヒントを持っていることを願っています. ありがとうございました。

現在の実装の完全なコードは次のとおりです。

#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
4

1 に答える 1

0

少し面倒でしたが、機能するソリューションを作成することができました。NSTableView をサブクラス化mouseDownし、次のコードでオーバーライドしました。

-(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];
}

今では、私が望んでいたとおりに機能します。

于 2015-08-02T18:44:03.777 に答える