简体   繁体   中英

NSMatrix bindings mayhem

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?

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 ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM