Reputation: 983
I want to use NSMatrix
to represent a scheduling matrix for employees (columns) across a 6-day work week (6 rows). FYI, since NSTableView
doesn't support cell-by-cell drag-and-drop, I'm having to resort to using NSMatrix
instead. Bummer.
Anyways, If I want to use Cocoa bindings, then my NSArray
of content
needs to work horizontally across the NSMatrix
.
If I have one employee, my array would contain 6 items. Got it. However, if I add a second employee then employee 1's data needs to occupy the even array indices (0-2-4-6-8-10), and employee 2's data occupies the odd indices (1-3-5-7-9-11).
If I now want to delete employee 1, then I need to delete items 10,8,6,4,2,0 in that order!
Yowza.
Am I reading this right? Anyone else out there who has had to content with this madness?
Upvotes: 0
Views: 71
Reputation: 983
Indeed, my initial assertions were correct – namely, that with an underlying array for content, NSMatrix
lays that content out from left-to-right then top-to-bottom. An array of 10 elements in a 5x2 matrix will be laid out with these indices:
0 1 2 3 4
5 6 7 8 9
So I share with you a couple code snippets... for example, doing a call of [self insColAtIndex:self.matrix.numberOfColumns]
on this result in a new matrix with the new items "X" appended to the last column:
0 1 2 3 4 X
5 6 7 8 9 X
Without further ado, with allocating an initial-sized NSMatrix
with at least 1 column of the desired height of n rows, here's two methods in a sub-classed NSArrayController
to make the controlled NSMatrix
and its content array work in tandem:
// insert NSMatrix column at index (zero-based)
-(void)insColAtIndex:(NSInteger)index
{
NSInteger colCount = self.matrix.numberOfColumns;
if (index<0 || index>colCount)
return;
NSInteger rowCount = self.matrix.numberOfRows;
[self.matrix addColumn];
for (NSInteger i=0; i<rowCount; i++)
[self insertObject:[[NSCell alloc] init] atArrangedObjectIndex:index+colCount*i+i];
}
// remove NSMatrix column at index (zero-based)
-(void)delColAtIndex:(NSInteger)index
{
NSInteger colCount = self.matrix.numberOfColumns;
if (index<0 || index>=colCount)
return;
NSInteger rowCount = self.matrix.numberOfRows;
[self.matrix removeColumn:index];
for (NSInteger i=rowCount-1; i>=0; i--)
[self removeObjectAtArrangedObjectIndex:index+colCount*i];
}
I realize that I could have created an NSMutableIndexSet
with array indices and affected the NSMatrix's array in one fell swoop (with insertObjects:atArrangedObjectIndexes:
and removeObjectsAtArrangedObjectIndexes:
), but that seemed more trouble than it was worth.
The code for inserting/deleting contiguous rows from the array is left as a (much easier) exercise for the reader ;-)
Upvotes: 0