Browse Source

Use UICollectionView instead of AQGridView, on 6.0 and later

Tamas Timar 12 years ago
parent
commit
87a284ddd7

+ 33 - 0
AspenProject/VLCPlaylistCollectionViewCell.h

@@ -0,0 +1,33 @@
+//
+//  VLCPlaylistCollectionViewCell.h
+//  VLC for iOS
+//
+//  Created by Tamas Timar on 8/30/13.
+//  Copyright (c) 2013 VideoLAN. All rights reserved.
+//
+//  Refer to the COPYING file of the official project for license.
+//
+
+#import <UIKit/UIKit.h>
+#import "VLCLinearProgressIndicator.h"
+
+@interface VLCPlaylistCollectionViewCell : UICollectionViewCell
+
+@property (nonatomic, strong) IBOutlet UILabel *titleLabel;
+@property (nonatomic, strong) IBOutlet UILabel *subtitleLabel;
+@property (nonatomic, strong) IBOutlet UIImageView *thumbnailView;
+@property (nonatomic, strong) IBOutlet VLCLinearProgressIndicator *progressView;
+@property (nonatomic, strong) IBOutlet UIButton *removeMediaButton;
+@property (nonatomic, strong) IBOutlet UIImageView *mediaIsUnreadView;
+@property (nonatomic, strong) IBOutlet UILabel *seriesNameLabel;
+@property (nonatomic, strong) IBOutlet UILabel *artistNameLabel;
+@property (nonatomic, strong) IBOutlet UILabel *albumNameLabel;
+
+@property (nonatomic, retain) MLFile *mediaObject;
+
+@property (nonatomic, weak) UICollectionView *collectionView;
+
+- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
+- (IBAction)removeMedia:(id)sender;
+
+@end

+ 257 - 0
AspenProject/VLCPlaylistCollectionViewCell.m

@@ -0,0 +1,257 @@
+//
+//  VLCPlaylistCollectionViewCell.m
+//  VLC for iOS
+//
+//  Created by Tamas Timar on 8/30/13.
+//  Copyright (c) 2013 VideoLAN. All rights reserved.
+//
+//  Refer to the COPYING file of the official project for license.
+//
+
+#import "VLCPlaylistCollectionViewCell.h"
+
+#import "VLCPlaylistViewController.h"
+
+#define MAX_CACHE_SIZE 27 // three times the number of items shown on iPad
+
+@implementation VLCPlaylistCollectionViewCell
+
+- (void)setEditing:(BOOL)editing animated:(BOOL)animated
+{
+    self.removeMediaButton.hidden = !editing;
+    [self _updatedDisplayedInformationForKeyPath:@"editing"];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    [self _updatedDisplayedInformationForKeyPath:keyPath];
+}
+
+- (void)setMediaObject:(MLFile *)mediaObject
+{
+    if (_mediaObject != mediaObject) {
+        [_mediaObject removeObserver:self forKeyPath:@"computedThumbnail"];
+        [_mediaObject removeObserver:self forKeyPath:@"lastPosition"];
+        [_mediaObject removeObserver:self forKeyPath:@"duration"];
+        [_mediaObject removeObserver:self forKeyPath:@"fileSizeInBytes"];
+        [_mediaObject removeObserver:self forKeyPath:@"title"];
+        [_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
+        [_mediaObject removeObserver:self forKeyPath:@"unread"];
+        [_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
+        [_mediaObject removeObserver:self forKeyPath:@"album"];
+        [_mediaObject removeObserver:self forKeyPath:@"artist"];
+        [_mediaObject removeObserver:self forKeyPath:@"genre"];
+        if ([_mediaObject respondsToSelector:@selector(didHide)])
+            [(MLFile*)_mediaObject didHide];
+
+        _mediaObject = mediaObject;
+
+        [_mediaObject addObserver:self forKeyPath:@"computedThumbnail" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"lastPosition" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"duration" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"fileSizeInBytes" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
+        [_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
+
+        if ([_mediaObject respondsToSelector:@selector(willDisplay)])
+            [(MLFile*)_mediaObject willDisplay];
+    }
+
+    [self _updatedDisplayedInformationForKeyPath:nil];
+}
+
+- (void)_updatedDisplayedInformationForKeyPath:(NSString *)keyPath
+{
+    self.albumNameLabel.text = self.artistNameLabel.text = self.seriesNameLabel.text = @"";
+
+    if ([self.mediaObject isKindOfClass:[MLFile class]]) {
+        MLFile *mediaObject = self.mediaObject;
+        [self configureForMLFile:mediaObject];
+
+        if (([keyPath isEqualToString:@"computedThumbnail"] || !keyPath) && !mediaObject.isAlbumTrack) {
+            self.thumbnailView.image = [self thumbnailForMediaFile:mediaObject];
+        }
+    } else if ([self.mediaObject isKindOfClass:[MLAlbum class]]) {
+        MLAlbum *mediaObject = (MLAlbum *)self.mediaObject;
+        [self configureForAlbum:mediaObject];
+
+    } else if ([self.mediaObject isKindOfClass:[MLAlbumTrack class]]) {
+        MLAlbumTrack *mediaObject = (MLAlbumTrack *)self.mediaObject;
+        [self configureForAlbumTrack:mediaObject];
+
+    } else if ([self.mediaObject isKindOfClass:[MLShow class]]) {
+        MLShow *mediaObject = (MLShow *)self.mediaObject;
+        [self configureForShow:mediaObject];
+
+        if ([keyPath isEqualToString:@"computedThumbnail"] || !keyPath) {
+            MLFile *anyFileFromAnyEpisode = [mediaObject.episodes.anyObject files].anyObject;
+            self.thumbnailView.image = [self thumbnailForMediaFile:anyFileFromAnyEpisode];
+        }
+    } else if ([self.mediaObject isKindOfClass:[MLShowEpisode class]]) {
+        MLShowEpisode *mediaObject = (MLShowEpisode *)self.mediaObject;
+        [self configureForShowEpisode:mediaObject];
+
+        if ([keyPath isEqualToString:@"computedThumbnail"] || !keyPath) {
+            MLFile *anyFileFromEpisode = mediaObject.files.anyObject;
+            self.thumbnailView.image = [self thumbnailForMediaFile:anyFileFromEpisode];
+        }
+    }
+
+    [self setNeedsDisplay];
+}
+
+- (IBAction)removeMedia:(id)sender
+{
+    /* ask user if s/he really wants to delete the media file */
+    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"DELETE_FILE", @"") message:[NSString stringWithFormat:NSLocalizedString(@"DELETE_FILE_LONG", @""), self.mediaObject.title] delegate:self cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", @"") otherButtonTitles:NSLocalizedString(@"BUTTON_DELETE", @""), nil];
+    [alert show];
+}
+
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    if (buttonIndex == 1) {
+        VLCPlaylistViewController *delegate = (VLCPlaylistViewController*)self.collectionView.delegate;
+        [delegate removeMediaObject:self.mediaObject];
+    }
+}
+
+#pragma mark - presentation
+
+- (void)configureForShow:(MLShow *)show
+{
+    self.titleLabel.text = show.name;
+    self.artistNameLabel.text = @"";
+    self.albumNameLabel.text = show.releaseYear;
+    NSUInteger count = show.episodes.count;
+    self.subtitleLabel.text = [NSString stringWithFormat:(count > 1) ? NSLocalizedString(@"LIBRARY_EPISODES", @"") : NSLocalizedString(@"LIBRARY_SINGLE_EPISODE", @""), count, show.unreadEpisodes.count];
+    self.mediaIsUnreadView.hidden = YES;
+    self.progressView.hidden = YES;
+}
+
+- (void)configureForAlbumTrack:(MLAlbumTrack *)albumTrack
+{
+    self.artistNameLabel.text = albumTrack.artist;
+    self.albumNameLabel.text = [NSString stringWithFormat:NSLocalizedString(@"LIBRARY_SINGLE_TRACK", @""), albumTrack.trackNumber.intValue];
+    self.titleLabel.text = albumTrack.title;
+    self.thumbnailView.image = nil;
+
+    MLFile *anyFileFromTrack = albumTrack.files.anyObject;
+    self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[anyFileFromTrack duration]]];
+
+    CGFloat position = anyFileFromTrack.lastPosition.floatValue;
+    self.progressView.progress = position;
+    self.progressView.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
+    [self.progressView setNeedsDisplay];
+    self.mediaIsUnreadView.hidden = !anyFileFromTrack.unread.intValue;
+}
+
+- (void)configureForAlbum:(MLAlbum *)album
+{
+    self.titleLabel.text = album.name;
+    MLAlbumTrack *anyTrack = [album.tracks anyObject];
+    self.artistNameLabel.text = anyTrack? anyTrack.artist: @"";
+    self.albumNameLabel.text = album.releaseYear;
+    self.thumbnailView.image = nil;
+
+    NSUInteger count = album.tracks.count;
+    self.subtitleLabel.text = [NSString stringWithFormat:(count > 1) ? NSLocalizedString(@"LIBRARY_TRACKS", @"") : NSLocalizedString(@"LIBRARY_SINGLE_TRACK", @""), count];
+    self.mediaIsUnreadView.hidden = YES;
+    self.progressView.hidden = YES;
+}
+
+- (void)configureForShowEpisode:(MLShowEpisode *)showEpisode
+{
+    MLFile *anyFileFromEpisode = showEpisode.files.anyObject;
+    self.titleLabel.text = showEpisode.name;
+    if (self.titleLabel.text.length < 1) {
+        self.titleLabel.text = [NSString stringWithFormat:@"S%02dE%02d", showEpisode.episodeNumber.intValue, showEpisode.seasonNumber.intValue];
+        self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[anyFileFromEpisode duration]]];
+    } else
+        self.subtitleLabel.text = [NSString stringWithFormat:@"S%02dE%02d — %@", showEpisode.episodeNumber.intValue, showEpisode.seasonNumber.intValue, [VLCTime timeWithNumber:[anyFileFromEpisode duration]]];
+
+    CGFloat position = anyFileFromEpisode.lastPosition.floatValue;
+    self.progressView.progress = position;
+    self.progressView.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
+    [self.progressView setNeedsDisplay];
+    self.mediaIsUnreadView.hidden = !showEpisode.unread.intValue;
+}
+
+- (void)configureForMLFile:(MLFile *)mediaFile
+{
+    if ([mediaFile isAlbumTrack]) {
+        self.artistNameLabel.text = mediaFile.albumTrack.artist;
+        self.albumNameLabel.text = mediaFile.albumTrack.album.name;
+        self.titleLabel.text = (mediaFile.albumTrack.title.length > 0) ? mediaFile.albumTrack.title : mediaFile.title;
+        self.thumbnailView.image = nil;
+    } else if ([mediaFile isShowEpisode]) {
+        MLShowEpisode *episode = mediaFile.showEpisode;
+        self.seriesNameLabel.text = episode.show.name;
+        self.titleLabel.text = (episode.name.length > 0) ? [NSString stringWithFormat:@"%@ - S%02dE%02d", episode.name, mediaFile.showEpisode.seasonNumber.intValue, episode.episodeNumber.intValue] : [NSString stringWithFormat:@"S%02dE%02d", episode.seasonNumber.intValue, episode.episodeNumber.intValue];
+    } else
+        self.titleLabel.text = mediaFile.title;
+
+    VLCPlaylistViewController *delegate = (VLCPlaylistViewController*)self.collectionView.delegate;
+
+    if (delegate.isEditing)
+        self.subtitleLabel.text = [NSString stringWithFormat:@"%@ — %i MB", [VLCTime timeWithNumber:[mediaFile duration]], (int)([mediaFile fileSizeInBytes] / 1e6)];
+    else {
+        self.subtitleLabel.text = [NSString stringWithFormat:@"%@", [VLCTime timeWithNumber:[mediaFile duration]]];
+        if (mediaFile.videoTrack) {
+            NSString *width = [[mediaFile videoTrack] valueForKey:@"width"];
+            NSString *height = [[mediaFile videoTrack] valueForKey:@"height"];
+            if (width.intValue > 0 && height.intValue > 0)
+                self.subtitleLabel.text = [self.subtitleLabel.text stringByAppendingFormat:@" — %@x%@", width, height];
+        }
+    }
+
+    CGFloat position = mediaFile.lastPosition.floatValue;
+    self.progressView.progress = position;
+    self.progressView.hidden = ((position < .1f) || (position > .95f)) ? YES : NO;
+    [self.progressView setNeedsDisplay];
+    self.mediaIsUnreadView.hidden = !mediaFile.unread.intValue;
+}
+
+// Can be extracted outside of VLCPlaylistCollectionViewCell
+- (UIImage *)thumbnailForMediaFile:(MLFile *)mediaFile {
+    if (mediaFile == nil || mediaFile.objectID == nil)
+        return nil;
+
+    static NSMutableArray *_thumbnailCacheIndex;
+    static NSMutableDictionary *_thumbnailCache;
+    if (!_thumbnailCache)
+        _thumbnailCache = [[NSMutableDictionary alloc] initWithCapacity:MAX_CACHE_SIZE];
+    if (!_thumbnailCacheIndex)
+        _thumbnailCacheIndex = [[NSMutableArray alloc] initWithCapacity:MAX_CACHE_SIZE];
+
+    NSManagedObjectID *objID = mediaFile.objectID;
+    UIImage *displayedImage = nil;
+    if ([_thumbnailCacheIndex containsObject:objID]) {
+        [_thumbnailCacheIndex removeObject:objID];
+        [_thumbnailCacheIndex insertObject:objID atIndex:0];
+        displayedImage = [_thumbnailCache objectForKey:objID];
+        if (!displayedImage && mediaFile.computedThumbnail) {
+            displayedImage = mediaFile.computedThumbnail;
+            [_thumbnailCache setObject:displayedImage forKey:objID];
+        }
+    } else {
+        if (_thumbnailCacheIndex.count >= MAX_CACHE_SIZE) {
+            [_thumbnailCache removeObjectForKey:[_thumbnailCacheIndex lastObject]];
+            [_thumbnailCacheIndex removeLastObject];
+        }
+        displayedImage = mediaFile.computedThumbnail;
+
+        if (displayedImage) {
+            [_thumbnailCache setObject:displayedImage forKey:objID];
+            [_thumbnailCacheIndex insertObject:objID atIndex:0];
+        }
+    }
+
+    return displayedImage;
+}
+
+@end

+ 615 - 0
AspenProject/VLCPlaylistCollectionViewCell.xib

@@ -0,0 +1,615 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
+	<data>
+		<int key="IBDocument.SystemTarget">1552</int>
+		<string key="IBDocument.SystemVersion">12E55</string>
+		<string key="IBDocument.InterfaceBuilderVersion">3084</string>
+		<string key="IBDocument.AppKitVersion">1187.39</string>
+		<string key="IBDocument.HIToolboxVersion">626.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">2083</string>
+		</object>
+		<array key="IBDocument.IntegratedClassDependencies">
+			<string>IBProxyObject</string>
+			<string>IBUIButton</string>
+			<string>IBUICollectionViewCell</string>
+			<string>IBUIImageView</string>
+			<string>IBUILabel</string>
+			<string>IBUIView</string>
+		</array>
+		<array key="IBDocument.PluginDependencies">
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</array>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+			<integer value="1" key="NS.object.0"/>
+		</object>
+		<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<object class="IBProxyObject" id="841351856">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+			</object>
+			<object class="IBProxyObject" id="371349661">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+			</object>
+			<object class="IBUICollectionViewCell" id="541525164">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">268</int>
+				<array class="NSMutableArray" key="NSSubviews">
+					<object class="IBUIView" id="343928585">
+						<reference key="NSNextResponder" ref="541525164"/>
+						<int key="NSvFlags">256</int>
+						<array class="NSMutableArray" key="NSSubviews">
+							<object class="IBUILabel" id="457142782">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">264</int>
+								<string key="NSFrame">{{19, 76}, {257, 20}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="405891686"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<bool key="IBUIClipsSubviews">YES</bool>
+								<int key="IBUIContentMode">1</int>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<string key="IBUIText">Artist Name</string>
+								<object class="NSColor" key="IBUITextColor" id="429073164">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MQA</bytes>
+								</object>
+								<nil key="IBUIHighlightedColor"/>
+								<object class="NSColor" key="IBUIShadowColor" id="453573140">
+									<int key="NSColorSpace">1</int>
+									<bytes key="NSRGB">MCAwIDAAA</bytes>
+									<string key="IBUIColorCocoaTouchKeyPath">darkTextColor</string>
+								</object>
+								<int key="IBUIBaselineAdjustment">0</int>
+								<float key="IBUIMinimumFontSize">12</float>
+								<bool key="IBUIAdjustsLetterSpacingToFitWidth">YES</bool>
+								<int key="IBUITextAlignment">1</int>
+								<object class="IBUIFontDescription" key="IBUIFontDescription" id="290339558">
+									<int key="type">1</int>
+									<double key="pointSize">18</double>
+								</object>
+								<object class="NSFont" key="IBUIFont" id="154316482">
+									<string key="NSName">Helvetica</string>
+									<double key="NSSize">18</double>
+									<int key="NSfFlags">16</int>
+								</object>
+							</object>
+							<object class="IBUILabel" id="405891686">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">264</int>
+								<string key="NSFrame">{{20, 96}, {258, 28}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="99927648"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<bool key="IBUIClipsSubviews">YES</bool>
+								<int key="IBUIContentMode">7</int>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<string key="IBUIText">Album Name</string>
+								<object class="NSColor" key="IBUITextColor">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MC43MgA</bytes>
+								</object>
+								<nil key="IBUIHighlightedColor"/>
+								<reference key="IBUIShadowColor" ref="453573140"/>
+								<int key="IBUIBaselineAdjustment">0</int>
+								<float key="IBUIMinimumFontSize">10</float>
+								<bool key="IBUIAdjustsLetterSpacingToFitWidth">YES</bool>
+								<int key="IBUITextAlignment">1</int>
+								<object class="IBUIFontDescription" key="IBUIFontDescription" id="106500751">
+									<int key="type">1</int>
+									<double key="pointSize">14</double>
+								</object>
+								<object class="NSFont" key="IBUIFont" id="939746159">
+									<string key="NSName">Helvetica</string>
+									<double key="NSSize">14</double>
+									<int key="NSfFlags">16</int>
+								</object>
+							</object>
+							<object class="IBUIImageView" id="99927648">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">274</int>
+								<string key="NSFrame">{{21, 14}, {256, 144}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="501792178"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+							</object>
+							<object class="IBUILabel" id="634412904">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">264</int>
+								<string key="NSFrame">{{20, 167}, {258, 21}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="288639132"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<bool key="IBUIClipsSubviews">YES</bool>
+								<int key="IBUIContentMode">1</int>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<string key="IBUIText">Label</string>
+								<reference key="IBUITextColor" ref="429073164"/>
+								<nil key="IBUIHighlightedColor"/>
+								<reference key="IBUIShadowColor" ref="453573140"/>
+								<int key="IBUIBaselineAdjustment">0</int>
+								<float key="IBUIMinimumFontSize">9</float>
+								<bool key="IBUIAdjustsLetterSpacingToFitWidth">YES</bool>
+								<int key="IBUITextAlignment">1</int>
+								<reference key="IBUIFontDescription" ref="290339558"/>
+								<reference key="IBUIFont" ref="154316482"/>
+							</object>
+							<object class="IBUILabel" id="288639132">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">264</int>
+								<string key="NSFrame">{{20, 190}, {258, 28}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<bool key="IBUIClipsSubviews">YES</bool>
+								<int key="IBUIContentMode">7</int>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<string key="IBUIText">Subtitle</string>
+								<object class="NSColor" key="IBUITextColor">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MC43MgA</bytes>
+								</object>
+								<nil key="IBUIHighlightedColor"/>
+								<reference key="IBUIShadowColor" ref="453573140"/>
+								<int key="IBUIBaselineAdjustment">0</int>
+								<int key="IBUITextAlignment">1</int>
+								<reference key="IBUIFontDescription" ref="106500751"/>
+								<reference key="IBUIFont" ref="939746159"/>
+								<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+							</object>
+							<object class="IBUILabel" id="22663525">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">264</int>
+								<string key="NSFrame">{{27, 12}, {230, 28}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="699596644"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<bool key="IBUIClipsSubviews">YES</bool>
+								<int key="IBUIContentMode">7</int>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<string key="IBUIText">Series Name</string>
+								<object class="NSColor" key="IBUITextColor">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MC43MgA</bytes>
+								</object>
+								<nil key="IBUIHighlightedColor"/>
+								<reference key="IBUIShadowColor" ref="453573140"/>
+								<string key="IBUIShadowOffset">{0, 1}</string>
+								<int key="IBUIBaselineAdjustment">0</int>
+								<float key="IBUIMinimumFontSize">9</float>
+								<bool key="IBUIAdjustsLetterSpacingToFitWidth">YES</bool>
+								<reference key="IBUIFontDescription" ref="106500751"/>
+								<reference key="IBUIFont" ref="939746159"/>
+							</object>
+							<object class="IBUIView" id="501792178">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">292</int>
+								<string key="NSFrame">{{21, 146}, {256, 12}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="634412904"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<object class="NSColor" key="IBUIBackgroundColor" id="476951524">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MCAwAA</bytes>
+								</object>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+							</object>
+							<object class="IBUIImageView" id="130196590">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">274</int>
+								<string key="NSFrame">{{16, 9}, {266, 154}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="22663525"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<object class="NSCustomResource" key="IBUIImage">
+									<string key="NSClassName">NSImage</string>
+									<string key="NSResourceName">thumbOverlay.png</string>
+								</object>
+							</object>
+							<object class="IBUIButton" id="657061410">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">-2147483356</int>
+								<string key="NSFrame">{{260, 2}, {33, 29}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="457142782"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIOpaque">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<int key="IBUIContentHorizontalAlignment">0</int>
+								<int key="IBUIContentVerticalAlignment">0</int>
+								<reference key="IBUIHighlightedTitleColor" ref="429073164"/>
+								<object class="NSColor" key="IBUINormalTitleColor">
+									<int key="NSColorSpace">1</int>
+									<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
+								</object>
+								<object class="NSColor" key="IBUINormalTitleShadowColor">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MC41AA</bytes>
+								</object>
+								<object class="NSCustomResource" key="IBUINormalImage">
+									<string key="NSClassName">NSImage</string>
+									<string key="NSResourceName">DeleteButton.png</string>
+								</object>
+								<object class="IBUIFontDescription" key="IBUIFontDescription">
+									<int key="type">2</int>
+									<int key="size">2</int>
+								</object>
+								<object class="NSFont" key="IBUIFont">
+									<string key="NSName">Helvetica-Bold</string>
+									<double key="NSSize">18</double>
+									<int key="NSfFlags">16</int>
+								</object>
+							</object>
+							<object class="IBUIImageView" id="699596644">
+								<reference key="NSNextResponder" ref="343928585"/>
+								<int key="NSvFlags">297</int>
+								<string key="NSFrame">{{235, 12}, {44, 44}}</string>
+								<reference key="NSSuperview" ref="343928585"/>
+								<reference key="NSWindow"/>
+								<reference key="NSNextKeyView" ref="657061410"/>
+								<string key="NSReuseIdentifierKey">_NS:9</string>
+								<bool key="IBUIUserInteractionEnabled">NO</bool>
+								<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+								<object class="NSCustomResource" key="IBUIImage">
+									<string key="NSClassName">NSImage</string>
+									<string key="NSResourceName">badgeUnread~ipad.png</string>
+								</object>
+							</object>
+						</array>
+						<string key="NSFrameSize">{298, 220}</string>
+						<reference key="NSSuperview" ref="541525164"/>
+						<reference key="NSWindow"/>
+						<reference key="NSNextKeyView" ref="130196590"/>
+						<reference key="IBUIBackgroundColor" ref="476951524"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<int key="IBUIContentMode">4</int>
+						<bool key="IBUIMultipleTouchEnabled">YES</bool>
+						<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+					</object>
+				</array>
+				<string key="NSFrameSize">{298, 220}</string>
+				<reference key="NSSuperview"/>
+				<reference key="NSWindow"/>
+				<reference key="NSNextKeyView" ref="343928585"/>
+				<string key="NSReuseIdentifierKey">_NS:9</string>
+				<bool key="IBUIOpaque">NO</bool>
+				<bool key="IBUIClipsSubviews">YES</bool>
+				<int key="IBUIContentMode">4</int>
+				<bool key="IBUIMultipleTouchEnabled">YES</bool>
+				<string key="targetRuntimeIdentifier">IBIPadFramework</string>
+				<string key="IBUIReuseIdentifier">PlaylistCell</string>
+				<reference key="IBUIContentView" ref="343928585"/>
+			</object>
+		</array>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<array class="NSMutableArray" key="connectionRecords">
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">albumNameLabel</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="405891686"/>
+					</object>
+					<int key="connectionID">39</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">artistNameLabel</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="457142782"/>
+					</object>
+					<int key="connectionID">40</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">mediaIsUnreadView</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="699596644"/>
+					</object>
+					<int key="connectionID">41</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">progressView</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="501792178"/>
+					</object>
+					<int key="connectionID">42</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">removeMediaButton</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="657061410"/>
+					</object>
+					<int key="connectionID">43</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">seriesNameLabel</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="22663525"/>
+					</object>
+					<int key="connectionID">44</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">subtitleLabel</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="288639132"/>
+					</object>
+					<int key="connectionID">45</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">thumbnailView</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="99927648"/>
+					</object>
+					<int key="connectionID">46</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">titleLabel</string>
+						<reference key="source" ref="541525164"/>
+						<reference key="destination" ref="634412904"/>
+					</object>
+					<int key="connectionID">47</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">removeMedia:</string>
+						<reference key="source" ref="657061410"/>
+						<reference key="destination" ref="541525164"/>
+						<int key="IBEventType">7</int>
+					</object>
+					<int key="connectionID">48</int>
+				</object>
+			</array>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<array key="orderedObjects">
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<array key="object" id="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="841351856"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="371349661"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">2</int>
+						<reference key="object" ref="541525164"/>
+						<array class="NSMutableArray" key="children">
+							<reference ref="457142782"/>
+							<reference ref="405891686"/>
+							<reference ref="99927648"/>
+							<reference ref="634412904"/>
+							<reference ref="288639132"/>
+							<reference ref="22663525"/>
+							<reference ref="501792178"/>
+							<reference ref="130196590"/>
+							<reference ref="657061410"/>
+							<reference ref="699596644"/>
+						</array>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">29</int>
+						<reference key="object" ref="457142782"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">30</int>
+						<reference key="object" ref="405891686"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">31</int>
+						<reference key="object" ref="99927648"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">32</int>
+						<reference key="object" ref="634412904"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">33</int>
+						<reference key="object" ref="288639132"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">34</int>
+						<reference key="object" ref="22663525"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">35</int>
+						<reference key="object" ref="501792178"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">36</int>
+						<reference key="object" ref="130196590"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">37</int>
+						<reference key="object" ref="657061410"/>
+						<reference key="parent" ref="541525164"/>
+						<string key="objectName">Delete button</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">38</int>
+						<reference key="object" ref="699596644"/>
+						<reference key="parent" ref="541525164"/>
+					</object>
+				</array>
+			</object>
+			<dictionary class="NSMutableDictionary" key="flattenedProperties">
+				<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="-2.CustomClassName">UIResponder</string>
+				<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="2.CustomClassName">VLCPlaylistCollectionViewCell</string>
+				<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="30.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="31.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="32.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="33.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="34.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="35.CustomClassName">VLCLinearProgressIndicator</string>
+				<string key="35.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="36.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="37.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				<string key="38.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			</dictionary>
+			<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+			<nil key="activeLocalization"/>
+			<dictionary class="NSMutableDictionary" key="localizations"/>
+			<nil key="sourceID"/>
+			<int key="maxID">48</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<array class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<object class="IBPartialClassDescription">
+					<string key="className">UICollectionReusableView</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/UICollectionReusableView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UICollectionViewCell</string>
+					<string key="superclassName">UICollectionReusableView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/UICollectionViewCell.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">VLCLinearProgressIndicator</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/VLCLinearProgressIndicator.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">VLCPlaylistCollectionViewCell</string>
+					<string key="superclassName">UICollectionViewCell</string>
+					<object class="NSMutableDictionary" key="actions">
+						<string key="NS.key.0">removeMedia:</string>
+						<string key="NS.object.0">id</string>
+					</object>
+					<object class="NSMutableDictionary" key="actionInfosByName">
+						<string key="NS.key.0">removeMedia:</string>
+						<object class="IBActionInfo" key="NS.object.0">
+							<string key="name">removeMedia:</string>
+							<string key="candidateClassName">id</string>
+						</object>
+					</object>
+					<dictionary class="NSMutableDictionary" key="outlets">
+						<string key="albumNameLabel">UILabel</string>
+						<string key="artistNameLabel">UILabel</string>
+						<string key="mediaIsUnreadView">UIImageView</string>
+						<string key="progressView">VLCLinearProgressIndicator</string>
+						<string key="removeMediaButton">UIButton</string>
+						<string key="seriesNameLabel">UILabel</string>
+						<string key="subtitleLabel">UILabel</string>
+						<string key="thumbnailView">UIImageView</string>
+						<string key="titleLabel">UILabel</string>
+					</dictionary>
+					<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<object class="IBToOneOutletInfo" key="albumNameLabel">
+							<string key="name">albumNameLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="artistNameLabel">
+							<string key="name">artistNameLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="mediaIsUnreadView">
+							<string key="name">mediaIsUnreadView</string>
+							<string key="candidateClassName">UIImageView</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="progressView">
+							<string key="name">progressView</string>
+							<string key="candidateClassName">VLCLinearProgressIndicator</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="removeMediaButton">
+							<string key="name">removeMediaButton</string>
+							<string key="candidateClassName">UIButton</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="seriesNameLabel">
+							<string key="name">seriesNameLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="subtitleLabel">
+							<string key="name">subtitleLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="thumbnailView">
+							<string key="name">thumbnailView</string>
+							<string key="candidateClassName">UIImageView</string>
+						</object>
+						<object class="IBToOneOutletInfo" key="titleLabel">
+							<string key="name">titleLabel</string>
+							<string key="candidateClassName">UILabel</string>
+						</object>
+					</dictionary>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">./Classes/VLCPlaylistCollectionViewCell.h</string>
+					</object>
+				</object>
+			</array>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+			<string key="DeleteButton.png">{29, 29}</string>
+			<string key="badgeUnread~ipad.png">{44, 44}</string>
+			<string key="thumbOverlay.png">{266, 154}</string>
+		</dictionary>
+		<string key="IBCocoaTouchPluginVersion">2083</string>
+	</data>
+</archive>

+ 78 - 14
AspenProject/VLCPlaylistViewController.m

@@ -11,6 +11,7 @@
 #import "VLCPlaylistViewController.h"
 #import "VLCMovieViewController.h"
 #import "VLCPlaylistTableViewCell.h"
+#import "VLCPlaylistCollectionViewCell.h"
 #import "VLCPlaylistGridView.h"
 #import "UINavigationController+Theme.h"
 #import "NSString+SupportedMedia.h"
@@ -27,13 +28,14 @@
 @implementation EmptyLibraryView
 @end
 
-@interface VLCPlaylistViewController () <AQGridViewDataSource, AQGridViewDelegate, UITableViewDataSource, UITableViewDelegate, MLMediaLibrary> {
+@interface VLCPlaylistViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, AQGridViewDataSource, AQGridViewDelegate, UITableViewDataSource, UITableViewDelegate, MLMediaLibrary> {
     NSMutableArray *_foundMedia;
     VLCLibraryMode _libraryMode;
     UIBarButtonItem *_menuButton;
 }
 
 @property (nonatomic, strong) UITableView *tableView;
+@property (nonatomic, strong) UICollectionView *collectionView;
 @property (nonatomic, strong) AQGridView *gridView;
 @property (nonatomic, strong) EmptyLibraryView *emptyLibraryView;
 
@@ -51,14 +53,28 @@
         _tableView.dataSource = self;
         self.view = _tableView;
     } else {
-        _gridView = [[AQGridView alloc] initWithFrame:[UIScreen mainScreen].bounds];
-        _gridView.separatorStyle = AQGridViewCellSeparatorStyleEmptySpace;
-        _gridView.alwaysBounceVertical = YES;
-        _gridView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
-        _gridView.delegate = self;
-        _gridView.dataSource = self;
-        _gridView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"libraryBackground"]];
-        self.view = _gridView;
+        if ([UICollectionView class]) {
+            UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
+
+            _collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];
+            _collectionView.alwaysBounceVertical = YES;
+            _collectionView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
+            _collectionView.delegate = self;
+            _collectionView.dataSource = self;
+            self.view = _collectionView;
+
+            [_collectionView registerNib:[UINib nibWithNibName:@"VLCPlaylistCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"PlaylistCell"];
+        } else {
+            _gridView = [[AQGridView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+            _gridView.separatorStyle = AQGridViewCellSeparatorStyleEmptySpace;
+            _gridView.alwaysBounceVertical = YES;
+            _gridView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
+            _gridView.delegate = self;
+            _gridView.dataSource = self;
+            self.view = _gridView;
+        }
+
+        self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"libraryBackground"]];
     }
 
     _libraryMode = VLCLibraryModeAllFiles;
@@ -271,8 +287,12 @@
 {
     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
         [self.tableView reloadData];
-    else
-        [self.gridView reloadData];
+    else {
+        if ([UICollectionView class])
+            [self.collectionView reloadData];
+        else
+            [self.gridView reloadData];
+    }
 
     [self _displayEmptyLibraryViewIfNeeded];
 }
@@ -327,6 +347,39 @@
     [self openMediaObject:selectedObject];
 }
 
+#pragma mark - Collection View
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
+{
+    return _foundMedia.count;
+}
+
+- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
+{
+    VLCPlaylistCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PlaylistCell" forIndexPath:indexPath];
+    cell.mediaObject = _foundMedia[indexPath.row];
+    cell.collectionView = _collectionView;
+
+    [cell setEditing:self.editing animated:NO];
+
+    return cell;
+}
+
+- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
+{
+    return CGSizeMake(298.0, 220.0);
+}
+
+- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
+{
+    return UIEdgeInsetsMake(0.0, 34.0, 0.0, 34.0);
+}
+
+- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
+{
+    NSManagedObject *selectedObject = _foundMedia[indexPath.row];
+    [self openMediaObject:selectedObject];
+}
+
 #pragma mark - AQGridView
 - (NSUInteger)numberOfItemsInGridView:(AQGridView *)gridView
 {
@@ -388,9 +441,20 @@
         [editButton setTitleTextAttributes: editing ? @{UITextAttributeTextShadowColor : [UIColor whiteColor], UITextAttributeTextColor : [UIColor blackColor]} : @{UITextAttributeTextShadowColor : [UIColor colorWithWhite:0. alpha:.37], UITextAttributeTextColor : [UIColor whiteColor]} forState:UIControlStateNormal];
     }
 
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
-        [self.gridView setEditing:editing];
-    else
+    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+        if ([UICollectionView class]) {
+            NSArray *visibleCells = self.collectionView.visibleCells;
+
+            [visibleCells enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+                VLCPlaylistCollectionViewCell *aCell = (VLCPlaylistCollectionViewCell*)obj;
+
+                [aCell setEditing:editing animated:animated];
+            }];
+        }
+        else {
+            [self.gridView setEditing:editing];
+        }
+    } else
         [self.tableView setEditing:editing animated:YES];
 }
 

+ 10 - 0
VLC for iOS.xcodeproj/project.pbxproj

@@ -93,6 +93,8 @@
 		7D16035E17BF9FE600F29B34 /* sudHeaderBg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D16035A17BF9FE600F29B34 /* sudHeaderBg@2x.png */; };
 		7D16035F17BF9FE600F29B34 /* headerSidebar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D16035B17BF9FE600F29B34 /* headerSidebar@2x.png */; };
 		7D16036017BF9FE600F29B34 /* headerSidebar.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D16035C17BF9FE600F29B34 /* headerSidebar.png */; };
+		7D1AA4DE17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1AA4DC17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.m */; };
+		7D1AA4DF17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D1AA4DD17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.xib */; };
 		7D1AC3041762996100BD2EB5 /* resetIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D1AC3021762996100BD2EB5 /* resetIcon.png */; };
 		7D1AC3051762996100BD2EB5 /* resetIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D1AC3031762996100BD2EB5 /* resetIcon@2x.png */; };
 		7D1AC30817629AB600BD2EB5 /* ratioIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7D1AC30617629AB600BD2EB5 /* ratioIcon.png */; };
@@ -435,6 +437,9 @@
 		7D19492D17C661A300959800 /* el */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = el; path = "el.lproj/badgeUnread@2x~iphone.png"; sourceTree = "<group>"; };
 		7D19492E17C661A300959800 /* el */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = el; path = "el.lproj/badgeUnread~ipad.png"; sourceTree = "<group>"; };
 		7D19492F17C661A300959800 /* el */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = el; path = "el.lproj/badgeUnread~iphone.png"; sourceTree = "<group>"; };
+		7D1AA4DB17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistCollectionViewCell.h; sourceTree = "<group>"; };
+		7D1AA4DC17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistCollectionViewCell.m; sourceTree = "<group>"; };
+		7D1AA4DD17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCPlaylistCollectionViewCell.xib; sourceTree = "<group>"; };
 		7D1AB27C179C98BF004CC271 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
 		7D1AB27D179C98BF004CC271 /* he */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = he; path = "he.lproj/badgeUnread@2x~ipad.png"; sourceTree = "<group>"; };
 		7D1AB27E179C98BF004CC271 /* he */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = he; path = "he.lproj/badgeUnread@2x~iphone.png"; sourceTree = "<group>"; };
@@ -1314,6 +1319,8 @@
 			children = (
 				7D94FCF616DE7D1100F2623B /* VLCPlaylistViewController.h */,
 				7D94FCF716DE7D1100F2623B /* VLCPlaylistViewController.m */,
+				7D1AA4DB17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.h */,
+				7D1AA4DC17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.m */,
 				7DA62099170A0CE500643D11 /* VLCPlaylistTableViewCell.h */,
 				7DA6209A170A0CE500643D11 /* VLCPlaylistTableViewCell.m */,
 				7D6B07F51716D45B003280C4 /* VLCPlaylistGridView.h */,
@@ -1547,6 +1554,7 @@
 				A79246BC170F114E0036AAF2 /* VLCEmptyLibraryView~ipad.xib */,
 				7DC87AF117413EE3009DC250 /* VLCPlaylistGridView.xib */,
 				A79246BE170F114E0036AAF2 /* VLCPlaylistTableViewCell.xib */,
+				7D1AA4DD17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.xib */,
 				7D3319A817CC88AE00CBEAD7 /* VLCFuturePlaylistTableViewCell.xib */,
 				7D5E39C5174FBAF3007DAFA1 /* VLCDropboxTableViewController.xib */,
 				7D5E39D0174FCF43007DAFA1 /* VLCDropboxTableViewCell~ipad.xib */,
@@ -2064,6 +2072,7 @@
 				7D514D4217F779C6007B960C /* DriveWhite.png in Resources */,
 				7D514D4317F779C6007B960C /* DriveWhite@2x.png in Resources */,
 				7D514D4417F779C6007B960C /* Drive.png in Resources */,
+				7D1AA4DF17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.xib in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2164,6 +2173,7 @@
 				7DC72D6917B820C9008A26D0 /* VLCNetworkLoginViewController.m in Sources */,
 				A7B5315F17E35B6E00EAE4B3 /* VLCThumbnailsCache.m in Sources */,
 				7D9F7FB117F969B0000A6500 /* VLCSidebarViewCell.m in Sources */,
+				7D1AA4DE17FDA47C00D6D9F9 /* VLCPlaylistCollectionViewCell.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};