Which method should I call my NSCell

I am writing a custom NSControl with custom NSCells. It is a control, so it must be mouse responsive. I created an NSTrackingArea above my controls, implemented -mouseEntered:

, -mouseExited:

and -mouseMoved:

. (And I'll have to implement -mouseUp/Down:

, but I don't know what to do there, so I haven't overridden these methods yet.) In these methods, I successfully determine which cell the mouse is in. Now I have two questions:

  • Is this a good approach for mouse tracking? If not, what should I do instead?
  • What method should I call on my NSCell with a mouse click, when the mouse enters the cell, when the mouse leaves the cell, etc.? Apple docs are not entirely clear.

So, basically: When should I call which method on my NSCell to allow it to respond to mouse events?

EDIT:
Rereading the docs, I think I should call NSCell -trackMouse:inRect:ofView:untilMouseUp:

and override -startTrackingAt:inView:

, -continueTracking:at:inView:

and -stopTracking:at:inView:mouseIsUp:

. Again two questions: 1) the documents give the impression that they are called only when the mouse is turned off. It's right? Then what should I do instead? 2) Where / when should I call NSCell -trackMouse:inRect:ofView:untilMouseUp:

?

+2


source to share


1 answer


As a result, I created my own mouse tracking mechanism:

// 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;
}

      

And, of course, in MyCell.h

:



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

      

With an empty implementation for these methods (so the compiler doesn't complain and I can leave the implementation of the mouse handling methods to subclasses).

+1


source







All Articles