Modernize DNDArrayController.

CQTexperiment
Dzmitry Neviadomski 2021-01-28 01:09:09 +03:00
parent 832fa6dbd0
commit 730276a7e7
3 changed files with 96 additions and 87 deletions

View File

@ -1,22 +1,28 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
extern NSString *MovedRowsType; extern NSString *CogPlaylistItemType;
extern NSString *CogUrlsPboardType; extern NSString *CogUrlsPboardType;
extern NSString *iTunesDropType; extern NSString *iTunesDropType;
@interface DNDArrayController : NSArrayController @interface DNDArrayController : NSArrayController <NSTableViewDataSource>
{
IBOutlet NSTableView *tableView; @property IBOutlet NSTableView *tableView;
}
// table view drag and drop support // table view drag and drop support
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard; - (id <NSPasteboardWriting>)tableView:(NSTableView *)tableView
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op; pasteboardWriterForRow:(NSInteger)row;
- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)op; - (NSDragOperation)tableView:(NSTableView *)tableView
validateDrop:(id <NSDraggingInfo>)info
proposedRow:(int)row
proposedDropOperation:(NSTableViewDropOperation)dropOperation;
- (BOOL)tableView:(NSTableView *)tableView
acceptDrop:(id <NSDraggingInfo>)info
row:(int)row
dropOperation:(NSTableViewDropOperation)dropOperation;
// utility methods // utility methods
-(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet toIndex:(unsigned int)insertIndex; -(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet
toIndex:(unsigned int)insertIndex;
@end @end

View File

@ -5,7 +5,7 @@
@implementation DNDArrayController @implementation DNDArrayController
NSString *MovedRowsType = @"MOVED_ROWS_TYPE"; NSString *CogPlaylistItemType = @"org.cogx.cog.playlist-item";
NSString *CogUrlsPboardType = @"COG_URLS_TYPE"; NSString *CogUrlsPboardType = @"COG_URLS_TYPE";
// @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist // @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist
@ -14,102 +14,105 @@ NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
- (void)awakeFromNib - (void)awakeFromNib
{ {
// register for drag and drop // register for drag and drop
[tableView registerForDraggedTypes:[NSArray arrayWithObjects:MovedRowsType, CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]]; [self.tableView registerForDraggedTypes:@[CogPlaylistItemType, CogUrlsPboardType,
NSFilenamesPboardType, iTunesDropType]];
} }
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard - (id <NSPasteboardWriting>)tableView:(NSTableView *)tableView
pasteboardWriterForRow:(NSInteger)row
{ {
DLog(@"INDEX SET ON DRAG: %@", rowIndexes); NSPasteboardItem *item = [[NSPasteboardItem alloc] init];
[item setString:[@(row) stringValue] forType:CogPlaylistItemType];
NSData *data = [NSArchiver archivedDataWithRootObject:rowIndexes];
return item;
[pboard declareTypes: [NSArray arrayWithObjects:MovedRowsType, nil] owner:self]; }
[pboard setData:data forType: MovedRowsType];
return YES; - (void)tableView:(NSTableView *)tableView
draggingSession:(NSDraggingSession *)session
willBeginAtPoint:(NSPoint)screenPoint
forRowIndexes:(NSIndexSet *)rowIndexes
{
DLog(@"Drag session started with indexes: %@", rowIndexes);
} }
- (NSDragOperation)tableView:(NSTableView*)tv - (NSDragOperation)tableView:(NSTableView*)tableView
validateDrop:(id <NSDraggingInfo>)info validateDrop:(id <NSDraggingInfo>)info
proposedRow:(int)row proposedRow:(int)row
proposedDropOperation:(NSTableViewDropOperation)op proposedDropOperation:(NSTableViewDropOperation)dropOperation
{ {
NSDragOperation dragOp = NSDragOperationCopy; NSDragOperation dragOp = NSDragOperationCopy;
if ([info draggingSource] == tv) if ([info draggingSource] == tableView)
dragOp = NSDragOperationMove; dragOp = NSDragOperationMove;
DLog(@"VALIDATING DROP!"); DLog(@"VALIDATING DROP!");
// we want to put the object at, not over, // we want to put the object at, not over,
// the current row (contrast NSTableViewDropOn) // the current row (contrast NSTableViewDropOn)
[tv setDropRow:row dropOperation:NSTableViewDropAbove]; [tableView setDropRow:row dropOperation:NSTableViewDropAbove];
return dragOp; return dragOp;
} }
- (BOOL)tableView:(NSTableView*)tv - (BOOL)tableView:(NSTableView*)tableView
acceptDrop:(id <NSDraggingInfo>)info acceptDrop:(id <NSDraggingInfo>)info
row:(int)row row:(int)row
dropOperation:(NSTableViewDropOperation)op dropOperation:(NSTableViewDropOperation)dropOperation
{ {
if (row < 0) if (row < 0) {
{ row = 0;
row = 0; }
}
NSArray<NSPasteboardItem *> *items = info.draggingPasteboard.pasteboardItems;
// if drag source is self, it's a move // if drag source is self, it's a move
if ([info draggingSource] == tableView) if ([info draggingSource] == tableView || items == nil) {
{ NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
NSIndexSet *indexSet = [NSUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:MovedRowsType]]; for (NSPasteboardItem *item in items) {
if (indexSet) [indexSet addIndex:[[item stringForType:CogPlaylistItemType] intValue]];
{ }
DLog(@"INDEX SET ON DROP: %@", indexSet); if ([indexSet count] > 0) {
NSArray *selected = [[self arrangedObjects] objectsAtIndexes:indexSet]; DLog(@"INDEX SET ON DROP: %@", indexSet);
[self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row]; NSArray *selected = [[self arrangedObjects] objectsAtIndexes:indexSet];
[self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row];
[self setSelectedObjects:selected];
[self setSelectedObjects:selected];
DLog(@"ACCEPTING DROP!");
return YES; DLog(@"ACCEPTING DROP!");
} return YES;
} }
DLog(@"REJECTING DROP!"); }
return NO; DLog(@"REJECTING DROP!");
return NO;
} }
-(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet -(void) moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet
toIndex:(unsigned int)insertIndex toIndex:(unsigned int)insertIndex
{ {
NSArray *objects = [self arrangedObjects];
NSArray *objects = [self arrangedObjects]; NSUInteger index = [indexSet lastIndex];
NSUInteger index = [indexSet lastIndex];
int aboveInsertIndexCount = 0;
id object;
int removeIndex;
while (NSNotFound != index)
{
if (index >= insertIndex) {
removeIndex = (int)(index + aboveInsertIndexCount);
aboveInsertIndexCount += 1;
}
else
{
removeIndex = (int)index;
insertIndex -= 1;
}
object = [objects objectAtIndex:removeIndex];
[self removeObjectAtArrangedObjectIndex:removeIndex]; int aboveInsertIndexCount = 0;
[self insertObject:object atArrangedObjectIndex:insertIndex]; id object;
int removeIndex;
index = [indexSet indexLessThanIndex:index];
while (NSNotFound != index) {
if (index >= insertIndex) {
removeIndex = (int)(index + aboveInsertIndexCount);
aboveInsertIndexCount += 1;
} else {
removeIndex = (int)index;
insertIndex -= 1;
}
object = [objects objectAtIndex:removeIndex];
[self removeObjectAtArrangedObjectIndex:removeIndex];
[self insertObject:object atArrangedObjectIndex:insertIndex];
index = [indexSet indexLessThanIndex:index];
} }
} }

View File

@ -867,7 +867,7 @@
pe.current = YES; pe.current = YES;
if (pe != nil) if (pe != nil)
[tableView scrollRowToVisible:pe.index]; [self.tableView scrollRowToVisible:pe.index];
currentEntry = pe; currentEntry = pe;
} }