Re: Questions about NSPopupButtonCell and NSBrowser
Re: Questions about NSPopupButtonCell and NSBrowser
- Subject: Re: Questions about NSPopupButtonCell and NSBrowser
- From: "Frank D. Engel, Jr." <email@hidden>
- Date: Thu, 04 Jun 2015 19:59:29 -0400
On 6/4/2015 19:39, Graham Cox wrote:
On 5 Jun 2015, at 9:19 am, Frank D. Engel, Jr. <email@hidden> wrote:
- (void)browser:(NSBrowser *)browser willDisplayCell:(MyBrowserCell *)cell atRow:(NSInteger)row column:(NSInteger)column
{
// Find the item and set the image.
WhateverObject *c = [browser itemAtRow:row inColumn:column];
[cell bind:@"image" toObject:c withKeyPath:@"icon" options:nil];
}
This looks wrong to me.
If you have the source object (c) and the cell that is to display the image (cell), why not just set the image directly?
[cell setImage:[c icon]];
The binding might help when the “icon” property changes, but setting up the binding here (which is effectively within a call to -drawRect: of the NSBrowser) is almost certainly incorrect. The binding needs to be set up outside of the drawing pathway, but since cells are annoying things, just binding the cell’s image to the icon property won’t work - the cell won’t automatically refresh the relevant part of the browser view.
Cells generally don’t update their host views on a change, because they’re designed to be reusable in a lot of different circumstances - the view uses the cell to draw some content, but the cell is unaware of which view it belongs to so there isn’t a general way for a cell to update its host view. It’s also undesirable, because many classes such as NSTableView and NSBrowser set up the cell’s state (properties) on the fly just before the cell is drawn, so if the cell dirtied the view when that happened you’d get an infinite redraw cycle.
So what you need to do is to have a property or method on your browser controller that sets the relevant cell’s image property AND refreshes the correct part of the view, then bind that controller method to the object’s icon property.
—Graham
P.S. Cells in general are deprecated, so getting away from code that requires them is the way of the future.
If I don't bind from there, I'm not sure where else to do it from?
Originally I was just doing a setImage: method call there, but I changed
it to a bind to fix the first issue I listed earlier (this is why it
updates more readily now when I keep it up).
In the future, I will be expanding the use of the "icon" to show it in
places besides the browser - I am considering the "icon" to be a
calculated part of the data model, with the "image" being part of one
view which I expect to later be many views against the same object, so
trying to update from within the source object isn't going to work
unless I reinvent the wheel and basically recreate the bindings or some
other notification mechanism.
The update of the icon is based on any of several properties of the
source object changing dynamically, sometimes by the user, and sometimes
from a method triggered an NSTimer (I am conditionally animating some of
these properties), and since the set of views against the object is
likely to change periodically while the application is running (and
quite possibly in the middle of those animations), with some views
potentially changing which objects they represent, I was hoping to avoid
having to stoop to that level (and didn't expect that I would need to) -
but I will if that is what it takes.
I'll work with that a bit more.
I still need a pointer of some kind with the NSPopupButtonCell question.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden