Re: NSTableColumn subclass and custom binding (solution!)
Re: NSTableColumn subclass and custom binding (solution!)
- Subject: Re: NSTableColumn subclass and custom binding (solution!)
- From: Alexander Lamb <email@hidden>
- Date: Tue, 29 Aug 2006 07:12:15 +0200
Hello,
Ok, maybe not the best solution, but here is an "hybrid" of bindings
and "classical way" to solve the problem.
1)
I have a subclass of NSButtonCell which responds to color (to draw a
color background)
2)
I have a subclass of NSTableColumn to handle the additionnal binding:
color
First, in IB, I set the subclass for my column as well as the
subclass for the table cell (subclass of NSButtonCell). I also use IB
for the other bindings (value in this case)
In my app controller, I do a simple binding with my custom table column:
[theTableColumn bind:@"color" toObject:theArrayController
withKeyPath:@"arrangedObjects.color" options:nil];
Now, here is the code in my NSTableColumn subclass:
- (void)bind:(NSString *)bindingName toObject:(id)
observableController withKeyPath:(NSString *)keyPath options:
(NSDictionary *)options
{
if([bindingName isEqualToString:@"color"])
{
// before binding, initialise the observedObjects to an empty
array...
observedObjects = [[NSMutableArray alloc] init];
arrayController = [observableController retain];
[observableController addObserver:self forKeyPath:keyPath
options:nil context:ControllerObservationContext];
}
else
[super bind:bindingName toObject:observableController
withKeyPath:keyPath options:options];
}
As you can see, I keep a NSMutableArray of observed objects as well
as a reference to the NSArrayController. I also call super, which
means I don't interfere with the other bindings.
Now, for some reason, I also need to implement accessor methods for
color, but they do nothing:
- (void)setColor:(NSArray *)values
{
}
- (NSArray *)color
{
return nil;
}
Now, the implementation of the "observe..."
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)
object change:(NSDictionary *)change context:(void *)context
{
if(context == ColorsObservationContext)
{
NSTableView *tableView = [self tableView];
[tableView setNeedsDisplayInRect:[tableView frameOfCellAtColumn:
[tableView columnWithIdentifier:[self identifier]] row:
[[arrayController arrangedObjects] indexOfObject:object]]];
}
else if(context == ControllerObservationContext)
{
// here, we know object is an NSArrayController... so lets compare
the arranged objects with the observed objects
NSArray *arrangedObjects = [object arrangedObjects];
// First the ones which were removed...
NSEnumerator *enumerator = [observedObjects objectEnumerator];
id anObject;
while(anObject = [enumerator nextObject])
{
if([arrangedObjects indexOfObject:anObject] == NSNotFound)
{
[anObject removeObserver:self];
[observedObjects removeObject:anObject];
}
}
// Then, the new ones...
enumerator = [arrangedObjects objectEnumerator];
while(anObject = [enumerator nextObject])
{
if([observedObjects indexOfObject:anObject] == NSNotFound)
{
[observedObjects addObject:anObject];
[anObject addObserver:self forKeyPath:@"color" options:nil
context:ColorsObservationContext];
}
}
}
}
If I am observing the array controller changes, I am simply adding or
removing observing for the color attribute for the individual objects
in the array.
If I am observing an individual color change, I need to tell the
table view containing my column to redraw a given cell. I know which
row by using the arranged objects in the arrayController I kept as a
reference.
Now, I need to give the correct color for the cell. Since table
columns reuse the same cell, it has to be done at the last moment, so
I implement the following method in my table column subclass:
- dataCellForRow:(int)row
{
LSColorCheckCell *cell = [self dataCell];
if(row >= 0)
{
[cell setColor:[[[arrayController arrangedObjects]
objectAtIndex:row] color]];
}
return cell;
}
And.... it works:-)
However, it still seems "bricolé" (french way of saying "not very
elegantly built"). I would love to know how the Cocoa classes
implement this for the basic bindings.
Any improvements suggestions are welcome!
Alex
--
Alexander Lamb
email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden