IconCollection/AAPLMyViewController.m

/*
 Copyright (C) 2015 Apple Inc. All Rights Reserved.
 See LICENSE.txt for this sample’s licensing information
 
 Abstract:
 Controls the collection view of icons.
 */
 
#import "AAPLMyViewController.h"
 
@interface AAPLIconViewBox : NSBox
@end
 
@interface AAPLMyScrollView : NSScrollView
{
    NSGradient *backgroundGradient;
}
@end
 
 
#pragma mark -
 
@implementation AAPLIconViewBox
 
// -------------------------------------------------------------------------------
//  hitTest:aPoint
// -------------------------------------------------------------------------------
- (NSView *)hitTest:(NSPoint)aPoint
{
    // don't allow any mouse clicks for subviews in this NSBox
    return nil;
}
 
@end
 
 
#pragma mark -
 
@implementation AAPLMyScrollView
 
// -------------------------------------------------------------------------------
//  awakeFromNib
// -------------------------------------------------------------------------------
- (void)awakeFromNib
{
    // set up the background gradient for this custom scrollView
    backgroundGradient = [[NSGradient alloc] initWithStartingColor:
                          [NSColor colorWithDeviceRed:0.349f green:0.6f blue:0.898f alpha:0.0f]
                                endingColor:[NSColor colorWithDeviceRed:0.349f green:0.6f blue:.898f alpha:0.6f]];
}
 
// -------------------------------------------------------------------------------
//  drawRect:rect
// -------------------------------------------------------------------------------
- (void)drawRect:(NSRect)rect
{
    // draw our special background as a gradient
    [backgroundGradient drawInRect:[self documentVisibleRect] angle:90.0f];
}
 
@end
 
 
#pragma mark -
 
@interface AAPLMyViewController ()
 
@property (nonatomic, strong) IBOutlet NSCollectionView *collectionView;
@property (nonatomic, strong) IBOutlet NSArrayController *arrayController;
@property (nonatomic, strong) NSArray *savedAlternateColors;
 
@property (nonatomic, strong) NSMutableArray *images;
 
@end
 
 
#pragma mark -
 
@implementation AAPLMyViewController
 
#define KEY_IMAGE   @"icon"
#define KEY_NAME    @"name"
 
// -------------------------------------------------------------------------------
//  awakeFromNib
// -------------------------------------------------------------------------------
- (void)awakeFromNib
{
    // save this for later when toggling between alternate colors
    _savedAlternateColors = [self.collectionView backgroundColors];
    
    [self setSortingMode:0];        // icon collection in ascending sort order
    [self setAlternateColors:NO];   // no alternate background colors (initially use gradient background)
    
    // Determine the content of the collection view by reading in the plist "icons.plist",
    // and add extra "named" template images with the help of NSImage class.
    //
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *path = [bundle pathForResource:@"icons" ofType:@"plist"];
    NSArray *iconEntries = [NSArray arrayWithContentsOfFile:path];
    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    
    // read the list of icons from disk in 'icons.plist'
    if (iconEntries != nil)
    {
        NSInteger count = [iconEntries count];
        for (NSInteger idx = 0; idx < count; idx++)
        {
            NSDictionary *entry = iconEntries[idx];
            if (entry != nil)
            {
                NSString *codeStr = [entry valueForKey: KEY_IMAGE];
                NSString *iconName = [entry valueForKey: KEY_NAME];
                
                OSType code = UTGetOSTypeFromString((__bridge CFStringRef)codeStr);
                NSImage *picture = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(code)];
                [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       picture, KEY_IMAGE,
                                       iconName, KEY_NAME,
                                       nil]];
            }
        }
    }
    
    // now add named image templates
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameIconViewTemplate], KEY_IMAGE,
                           NSImageNameIconViewTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameBluetoothTemplate], KEY_IMAGE,
                           NSImageNameBluetoothTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameIChatTheaterTemplate], KEY_IMAGE,
                           NSImageNameIChatTheaterTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameSlideshowTemplate], KEY_IMAGE,
                           NSImageNameSlideshowTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameActionTemplate], KEY_IMAGE,
                           NSImageNameActionTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameSmartBadgeTemplate], KEY_IMAGE,
                           NSImageNameSmartBadgeTemplate, KEY_NAME,
                           nil]];
    
    // Finder icon templates
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameListViewTemplate], KEY_IMAGE,
                           NSImageNameListViewTemplate, KEY_NAME,
                           nil]];
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameColumnViewTemplate], KEY_IMAGE,
                           NSImageNameColumnViewTemplate, KEY_NAME,
                           nil]];
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameFlowViewTemplate], KEY_IMAGE,
                           NSImageNameFlowViewTemplate, KEY_NAME,
                           nil]];
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNamePathTemplate], KEY_IMAGE,
                           NSImageNamePathTemplate, KEY_NAME,
                           nil]];
    
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameInvalidDataFreestandingTemplate], KEY_IMAGE,
                           NSImageNameInvalidDataFreestandingTemplate, KEY_NAME,
                           nil]];
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameLockLockedTemplate], KEY_IMAGE,
                           NSImageNameLockLockedTemplate, KEY_NAME,
                           nil]];
    [tempArray addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
                           [NSImage imageNamed:NSImageNameLockUnlockedTemplate], KEY_IMAGE,
                           NSImageNameLockUnlockedTemplate, KEY_NAME,
                           nil]];
    
    [self setImages:tempArray];
 
    [self.collectionView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
}
 
// -------------------------------------------------------------------------------
//  setAlternateColors:useAlternateColors
// -------------------------------------------------------------------------------
- (void)setAlternateColors:(BOOL)useAlternateColors
{
    _alternateColors = useAlternateColors;
    if (_alternateColors)
    {
        [self.collectionView setBackgroundColors:@[[NSColor gridColor], [NSColor lightGrayColor]]];
    }
    else
    {
        [self.collectionView setBackgroundColors:self.savedAlternateColors];
    }
}
 
// -------------------------------------------------------------------------------
//  setSortingMode:newMode
// -------------------------------------------------------------------------------
- (void)setSortingMode:(NSUInteger)newMode
{
    _sortingMode = newMode;
    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                               initWithKey:KEY_NAME
                               ascending:(_sortingMode == 0)
                               selector:@selector(caseInsensitiveCompare:)];
    [self.arrayController setSortDescriptors:@[sort]];
}
 
// -------------------------------------------------------------------------------
//  collectionView:writeItemsAtIndexes:indexes:pasteboard
//
//  Collection view drag and drop
//  User must click and hold the item(s) to perform a drag.
// -------------------------------------------------------------------------------
- (BOOL)collectionView:(NSCollectionView *)cv writeItemsAtIndexes:(NSIndexSet *)indexes toPasteboard:(NSPasteboard *)pasteboard
{
    NSMutableArray *urls = [NSMutableArray array];
    NSURL *temporaryDirectoryURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
    [indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop)
        {
            NSDictionary *dictionary = [cv content][idx];
            NSImage *image = dictionary[KEY_IMAGE];
            NSString *name = dictionary[KEY_NAME];
            if (image && name)
            {
                // construct the url of the tiff image to be used as our drag source
                NSURL *url = [temporaryDirectoryURL URLByAppendingPathComponent:name];
                url = [url URLByAppendingPathExtension:@"tiff"];
                              
                [urls addObject:url];
                [[image TIFFRepresentation] writeToURL:url atomically:YES];
            }
        }];
    if ([urls count] > 0)
    {
        [pasteboard clearContents];
        return [pasteboard writeObjects:urls];
    }
    return NO;
}
 
@end