开发者

NSTableView: How can you highlight an item on right-click?

I have an NSTableView, to which items are added without user intervention. When the user comes back to the dialog containing the NSTableView and clicks an item, that item is highlighted. However the item does not highlight if an item is right-clicked. Is there a way to highlight an item that is right-clicked?

I have the following curr开发者_如何学Pythonently:

void Dialog::menuAction(ui::Menu::Item* item)
{ 
  // Highlight the item clicked
  [tableView row:item select:YES]
  ...
}

But this doesn't seem to work.


My solution, which seems to be the cleanest shown here so far, is to subclass the NSTableView, and implement its menuForEvent message. Just make your table view a subclass of this and you'll get the correct behavior automatically:

@interface CustomTableView : NSTableView
@end

@implementation CustomTableView

- (NSMenu*) menuForEvent:(NSEvent*)event // override
{
    // Get to row at point
    NSInteger row = [self rowAtPoint:[self convertPoint:event.locationInWindow fromView:nil]];
    if (row >= 0) {
        // and check whether it is selected
        if (NOT [self isRowSelected:row]) {
            // No -> select that row
            [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
        }
    }
    return [super menuForEvent:event];
}

@end

Should work similarly with NSOutlineView.

Note how the code decides when to highlight the row. This mimicks closely the behavior that you can see in Finder, for instance:

  • If you right-click into an existing selection, especially if it's multiple items, they remain selected.
  • If you right-click outside the current selection, the newly clicked row becomes the new selection.

However, this is not perfect: The Finder only changes the selection once the user actually uses one of the items from the contextual menu. If the user cancels the popup menu, the selection won't change. My code, however, changes the selection before the user gets to choose from the popup menu. Feel free to improve on this, and share it here.


This may not be exactly what you want, but it might help. I had the problem with getting the row that was right clicked to get a context menu. I'm using an outline view, not a table view, and it's in the main window, not a dialog.

I have an outlet to my outlne view. In an object that processes the menu, I have the following method:

- (void) setSelectionFromClick {
    NSInteger theClickedRow = [myOutlineView clickedRow];
    NSIndexSet *thisIndexSet = [NSIndexSet indexSetWithIndex:theClickedRow];
    [myOutlineView selectRowIndexes:thisIndexSet byExtendingSelection:NO];
}

I call this method at the start of every menu action.

The clicked row is set, whichever button is pushed. But selection only changes automatically when left button is clicked. By the way, this also works with control-click.


just a swift version of @Thomas Tempelmann's solution.

public class TableViewWithRightClickSelect: NSTableView
{
    override open func menu(for event: NSEvent) -> NSMenu?
    {
        let row = self.row(at: self.convert(event.locationInWindow, from: nil))
        if row >= 0
        {
            self.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
        }
        
        return super.menu(for: event)
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜