2

カスタム NSCells を使用してカスタム NSControl を作成しています。これはコントロールなので、マウスに応答する必要があります。私は自分のコントロール上に NSTrackingArea を作成し、-mouseEntered:-mouseExited:を実装し-mouseMoved:ました。(そして-mouseUp/Down:、 を実装する必要がありますが、そこで何をすべきかわかりません。そのため、今のところ、これらのメソッドをまだオーバーライドしていません。) これらのメソッドでは、マウスが現在どのセルにあるかをうまく判断できます。今、私は2つの質問があります:

  • これはマウスを追跡するための良いアプローチですか? そうでない場合、代わりに何をすべきですか?
  • マウスがセルに入ったとき、マウスがセルを離れたときなど、マウス クリック時に NSCell でどのメソッドを呼び出す必要がありますか? Apple のドキュメントは、これについてあまり明確ではありません。

つまり、基本的には、NSCell でマウス イベントに応答させるには、いつどのメソッドを呼び出せばよいのでしょうか?

編集:
ドキュメントを読み直して、 NSCell-trackMouse:inRect:ofView:untilMouseUp:と override -startTrackingAt:inView:-continueTracking:at:inView:およびを呼び出す必要があると思います-stopTracking:at:inView:mouseIsUp:。ここでも 2 つの質問があります。1) ドキュメントは、マウスが押されたときにのみ呼び出されるという印象を与えます。あれは正しいですか?では、代わりに何をすべきですか?2) どこで、いつ NSCell に電話すればよい-trackMouse:inRect:ofView:untilMouseUp:ですか?

4

1 に答える 1

1

独自のマウス追跡メカニズムを実装することになりました。

// MyControl.m:

- (void)mouseDown:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        currentCell = cell;
        [currentCell mouseDown:theEvent];
    }
}

- (void)mouseUp:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        [cell mouseUp:theEvent];
    }
}

- (void)mouseEntered:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        currentCell = cell;
        [currentCell mouseEntered:theEvent];
    }
}

- (void)mouseExited:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        [cell mouseExited:theEvent];
        currentCell = nil;
    }
}

- (void)mouseMoved:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    MKListCell *cell;
    if (currentCellIndex < [cells count]) {
        cell = [cells objectAtIndex:currentCellIndex];
    }
    if (currentCell != cell) {
        [currentCell mouseExited:theEvent];
        [cell mouseEntered:theEvent];
        currentCell = cell;
    }
    else {
        [currentCell mouseMoved:theEvent];
    }
}

- (void)mouseDragged:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    MKListCell *cell = nil;
    if (currentCellIndex < [cells count]) {
        cell = [cells objectAtIndex:currentCellIndex];
    }
    if (currentCell != cell) {
        [currentCell mouseExited:theEvent];
        [cell mouseEntered:theEvent];
        currentCell = cell;
    }
    else {
        [currentCell mouseMoved:theEvent];
    }   
}

- (int)indexOfCellAtPoint:(NSPoint)p {
    int cellIndex = (self.bounds.size.height - p.y) / cellHeight;
    return cellIndex;
}

そしてもちろん、でMyCell.h

- (void)mouseDown:(NSEvent *)event;
- (void)mouseUp:(NSEvent *)event;
- (void)mouseMoved:(NSEvent *)event;
- (void)mouseEntered:(NSEvent *)event;
- (void)mouseExited:(NSEvent *)event;

これらのメソッドの空の実装を使用します (したがって、コンパイラは文句を言わず、マウス処理メソッドの実装をサブクラスに任せることができます)。

于 2013-03-31T13:25:52.783 に答える