0
votes

In my application I have a NSCollectionView with a custom CollectionViewItem. It is used to display images. I have the option "Allow Multiple Selection" active and can select several items with the mouse.

However, for NSCollectionView I also have a ContextMenu that opens when I right-click. However, if I click on an item, my selection is lost. Only the item I clicked on will be marked. I don't want that. I want to open the context menu and keep the selection of several items. This only works if I click between two items instead on an item.

How can I prevent the selection by right-clicking on an item?

UPDATE

The context menu is implemented via the Interface Builder. I dragged it on the ViewController on connected it with the menu outlet from the CollectionView.

1
How is the context menu implemented?Willeke
How can we reproduce the issue in a small test project? I tried and the selection doesn't change when I right-click.Willeke

1 Answers

0
votes

I haven't had a chance to test or refine this yet — busy day, sorry — but I think you can get where you're going this way. Set the collection view delegate, and add the collectionView:shouldSelectItemsAtIndexPaths: and/or the collectionView:shouldDeselectItemsAtIndexPaths: methods (I'm not certain if you'll need both, though it seems likely). Then add in a routine that tests the current event to see if it's a right mouse click:

- (NSSet<NSIndexPath *> *)collectionView:(NSCollectionView *)collectionView shouldDeselectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths {
    return ([self testForRightClick]) ? indexPaths : [NSSet set];
}

- (NSSet<NSIndexPath *> *)collectionView:(NSCollectionView *)collectionView shouldSelectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths {
    return ([self testForRightClick]) ? indexPaths : [NSSet set];
}

- (BOOL)testForRightClick {
    NSEvent * currentEvent;

    currentEvent = [NSApp currentEvent];
    return (currentEvent.type == NSEventTypeRightMouseDown ||
            currentEvent.type == NSEventTypeRightMouseUp) ? NO : YES;
}

For any other type of event this sends the NSSet that holds the selection/deselection request straight on through, but if the event is a right-mouse up/down event, it returns an empty set, which should block any deselections or new selections.