0

I am having an NSBrowser in one of my windows. It has a checkbox, image and textbox as you see in the screenshot.

I am struggling to do two things:

  1. Change the row selection color. By default it is blue.
  2. Action on the checkbox

The checkbox + image + textbox is added to the subclass of NSBrowserCell like this:

- (instancetype)init
{
    self = [super init];
    if (self) {
        _buttonCell = [[NSButtonCell alloc] init];
        [_buttonCell setButtonType:NSButtonTypeSwitch];
        [_buttonCell setTarget:self];
        [_buttonCell setAction:@selector(cellButtonClick:)];
        [_buttonCell setTitle:@""];

        _imageCell = [[NSImageCell alloc] init];

        _textCell = [[NSTextFieldCell alloc] init];

    }
    return self;
}

I've added target and Action too, but it is not called.

How do I achieve these two things?

Any guidance will be appreciated.

enter image description here

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140

1 Answers1

1

Caveat: customizing NSBrowser/NSBrowserCell is usually hard. It's a legacy view class that's been essentially abandoned for years, and it has a lot of undocumented quirks.

Having said that, try overriding -highlightColorWithFrame:inView: to use a different color for highlighting the row. It that's all you need, then I think that should do it.

As for the action, NSCell (unlike views and controls) is not a subclass of NSResponder and doesn't perform any automatic mouse event processing. (Cells are just helper objects to draw the view of a control/element.)

You'll probably have to catch the event at the browser view level, then perform hit testing to find the column/row that contains your check box cell. If you find a hit, then post the action message yourself (-sendAction:to:from:)—which is literally what a NSControl view does.

James Bucanek
  • 3,299
  • 3
  • 14
  • 30
  • Regarding catching the event at the browser view level & hit testing, I not sure if that will work. It seems that `mouseDown:` is never called on `NSBrowser` (or subclass) itself; rather, it's sent directly to the first responder, which happens to be the `NSBrowserTableView` private class used to implement each column's view. Maybe a local event monitor would work (seems like a lot more work than should be necessary)? – NSGod Jun 20 '20 at 15:00
  • So I went back to my customization of `NSBrowser`, and it doesn't try to intercept any mouse events ... so I can't speak with authority here. However, it did remind me that `NSBrowser` uses instances of `NSMatrix` to draw each column, and `NSMatrix` is a subclass of `NSControl`. So I suspect the matrix view receives `-mouseDown:` and similar events. To customize this, create a custom subclass of `NSMatrix`, and (in the browser's `init...` or `wakeFromNib` method) set the browser's "matrix class" property: `browserView.matrixClass = CustomMatrixView.class;` – James Bucanek Jun 20 '20 at 16:40
  • Actually, there's 2 different implementations: the earlier implementation (and much harder to work with) was the `NSMatrix` one. Then in 10.5 or 10.6 or something, they added an "item-based" API similar to `NSOutlineView`'s item-based API. The item-based implementation (currently, anyway) seems to use the private `NSBrowserTableView` to implement each column's view. I'm still playing around with things to see if I can get something to work... – NSGod Jun 20 '20 at 17:51