drag-n-drop disk image re-ordering. WIP.

This commit is contained in:
Kelvin Sherlock 2020-09-05 23:29:30 -04:00
parent af3ad78b94
commit 9eb3727e1e
2 changed files with 122 additions and 5 deletions

View File

@ -21,7 +21,7 @@
<rect key="frame" x="0.0" y="0.0" width="306" height="363"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" selectionHighlightStyle="none" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="pBj-py-R6a" id="sIz-DD-PZQ">
<outlineView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" selectionHighlightStyle="none" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="pBj-py-R6a" id="sIz-DD-PZQ">
<rect key="frame" x="0.0" y="0.0" width="306" height="363"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="2" height="3"/>
@ -81,7 +81,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<pathControl focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f7R-TO-fmF">
<rect key="frame" x="0.0" y="1" width="248" height="22"/>
<rect key="frame" x="41" y="1" width="207" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<pathCell key="cell" controlSize="small" selectable="YES" editable="YES" focusRingType="none" alignment="left" pathStyle="popUp" id="dcz-8y-tKb">
<font key="font" metaFont="smallSystem"/>
@ -101,6 +101,11 @@
<action selector="ejectAction:" target="-2" id="XAl-eQ-nUj"/>
</connections>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="6g1-NT-J1w">
<rect key="frame" x="3" y="3" width="33" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSListViewTemplate" id="x7F-qD-5y9"/>
</imageView>
</subviews>
<connections>
<outlet property="ejectButton" destination="zNo-ij-mUl" id="uzY-tA-5Wf"/>
@ -135,6 +140,7 @@
</scrollView>
</objects>
<resources>
<image name="NSListViewTemplate" width="14" height="10"/>
<image name="NSNavEjectButton.normalSelected" width="16" height="16"/>
</resources>
</document>

View File

@ -22,6 +22,7 @@
-(NSString *)viewIdentifier;
-(void)prepareView: (NSTableCellView *)view;
-(CGFloat)height;
-(NSInteger)index;
@end
@interface MediaCategory : NSObject <MediaNode> {
@ -30,6 +31,7 @@
@property NSInteger validCount;
@property NSArray *children; // URLs?
@property NSString *title;
@property NSInteger index;
-(NSInteger)count;
-(id)objectAtIndex:(NSInteger)index;
@ -40,6 +42,7 @@
@property NSURL *url;
@property BOOL valid;
@property NSInteger index;
-(NSInteger)count;
-(id)objectAtIndex:(NSInteger)index;
@ -97,8 +100,11 @@
_validCount = newCount;
for (unsigned i = count; i < newCount; ++i) {
[tmp addObject: [MediaItem new]];
MediaItem *item = [MediaItem new];
[item setIndex: i];
[tmp addObject: item];
}
// delete excess items, if blank. otherwise, mark invalid.
unsigned ix = 0;
for(MediaItem *item in tmp) {
@ -270,12 +276,16 @@ enum {
-(void)rebuildRoot {
NSMutableArray *tmp = [NSMutableArray new];
int ix = 0;
for (unsigned j = 0 ; j < 5; ++j) {
MediaCategory *cat = _data[j];
if ([cat count]) [tmp addObject: cat];
[cat setIndex: -1];
if ([cat count]) {
[cat setIndex: ix++];
[tmp addObject: cat];
}
}
_root = tmp;
//[_outlineView reloadItem: nil reloadChildren: YES];
[_outlineView reloadData];
[_outlineView expandItem: nil expandChildren: YES];
@ -315,6 +325,7 @@ enum {
}
}
static NSString *kDragType = @"private.ample.media";
- (void)viewDidLoad {
[super viewDidLoad];
@ -325,6 +336,8 @@ enum {
[_outlineView reloadData];
[_outlineView expandItem: nil expandChildren: YES];
[_outlineView registerForDraggedTypes: @[kDragType]];
}
#pragma mark - NSOutlineViewDelegate
@ -408,6 +421,104 @@ enum {
return [item height];
}
#if 0
- (id<NSPasteboardWriting>)outlineView:(NSOutlineView *)outlineView pasteboardWriterForItem:(id<MediaNode>)item {
if ([item isGroupItem]) return nil;
NSPasteboardItem *pb = [NSPasteboardItem new];
return pb;
}
#endif
- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard {
if ([items count] > 1) return NO;
NSLog(@"%s", sel_getName(_cmd));
MediaItem *item = [items firstObject];
if (![item isKindOfClass: [MediaItem class]]) return NO;
// find the category. only allow if more than 1 item in the category.
MediaCategory *cat = nil;
for (MediaCategory *c in _root) {
NSUInteger ix = [[c children] indexOfObject: item];
if (ix != NSNotFound){
cat = c;
break;
}
}
if (!cat) return NO;
if ([cat count] < 2) return NO;
NSInteger indexes[2] = { 0, 0 };
indexes[0] = [cat index];
indexes[1] = [item index];
NSData *data =[NSData dataWithBytes: indexes length: sizeof(indexes)];
[pasteboard setData: data forType: kDragType];
return YES;
}
/*
* IF item is present, it's a MediaCategory and index is the index of the MediaItem it would be inserted as.
* IF item is nil, index is the MediaCategory index, which should be converted to moving to the end.
* IF index < 0, dragging far beyond the category list, so NOPE it.
*
*/
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id<NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index {
if (index < 0) return NSDragOperationNone;
// item is the parent (MediaCategory) or nil
// index is the proposed child index.
NSLog(@"%s", sel_getName(_cmd));
//NSLog(@"%@", info);
NSLog(@"%@", item);
NSLog(@"%d", (int)index);
NSPasteboard *pb = [info draggingPasteboard];
NSData *data = [pb dataForType: kDragType];
if (!data) return NSDragOperationNone;
NSInteger indexes[2];
if ([data length] != sizeof(indexes)) return NSDragOperationNone;
[data getBytes: &indexes length: sizeof(indexes)];
NSLog(@"%d - %d", (int)indexes[0], (int)indexes[1]);
if (!item) {
// move to the END of the previous category.
if (index == 0) return NSDragOperationNone;
item = [_root objectAtIndex: index - 1];
index = [(MediaItem *)item count]; // -1; - interferes w/ -1 logic below.
}
NSLog(@"%d - %d", (int)[(MediaCategory *)item index], (int)index);
if ([(MediaCategory *)item index] != indexes[0]) return NSDragOperationNone;
if (indexes[1] == index) return NSDragOperationNone;
if (indexes[1] == index-1) return NSDragOperationNone;
return NSDragOperationMove;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id<NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index {
return NO;
}
#pragma mark - IBActions
- (IBAction)ejectAction:(id)sender {