[vlc-commits] macosx/library: show list of videos known to the library

Felix Paul Kühne git at videolan.org
Mon Apr 29 19:26:40 CEST 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Fri Apr 19 18:36:41 2019 +0200| [787defaa5ed5f5b1179edd40a41a2dd3d0e1f9fc] | committer: Felix Paul Kühne

macosx/library: show list of videos known to the library

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=787defaa5ed5f5b1179edd40a41a2dd3d0e1f9fc
---

 .../gui/macosx/UI/VLCLibraryCollectionViewItem.xib |  16 +-
 .../macosx/library/VLCLibraryCollectionViewItem.h  |   1 +
 modules/gui/macosx/library/VLCLibraryController.m  |   2 +-
 modules/gui/macosx/library/VLCLibraryDataSource.h  |   4 +
 modules/gui/macosx/library/VLCLibraryDataSource.m  |  21 ++-
 modules/gui/macosx/library/VLCLibraryModel.h       |  71 ++++++++
 modules/gui/macosx/library/VLCLibraryModel.m       | 178 +++++++++++++++++++++
 modules/gui/macosx/library/VLCLibraryWindow.m      |  17 +-
 8 files changed, 303 insertions(+), 7 deletions(-)

diff --git a/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib b/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib
index d87148cb57..44805042a4 100644
--- a/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib
+++ b/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
         <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryCollectionViewItem">
             <connections>
+                <outlet property="durationTextField" destination="VAn-gF-QiZ" id="U8T-Cs-HaL"/>
                 <outlet property="mediaImageView" destination="vP5-5j-rVa" id="YJb-5w-9sW"/>
                 <outlet property="mediaTitleTextField" destination="OBS-Eh-1mT" id="h1n-PU-IAx"/>
                 <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
@@ -35,12 +36,23 @@
                         <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                     </textFieldCell>
                 </textField>
+                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAn-gF-QiZ">
+                    <rect key="frame" x="420" y="20" width="42" height="19"/>
+                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="LSS-jh-llZ">
+                        <font key="font" size="15" name=".AppleSystemUIFont"/>
+                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                    </textFieldCell>
+                </textField>
             </subviews>
             <constraints>
+                <constraint firstItem="VAn-gF-QiZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="OBS-Eh-1mT" secondAttribute="trailing" constant="20" id="2di-oZ-tsC"/>
                 <constraint firstItem="A5y-ue-y7t" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="NpD-8l-D5s"/>
+                <constraint firstAttribute="trailing" secondItem="VAn-gF-QiZ" secondAttribute="trailing" constant="20" id="Ol6-wf-2dJ"/>
                 <constraint firstAttribute="bottom" secondItem="A5y-ue-y7t" secondAttribute="bottom" id="cnQ-bx-Fmn"/>
                 <constraint firstAttribute="bottom" secondItem="OBS-Eh-1mT" secondAttribute="bottom" constant="20" id="dy4-gP-Sdi"/>
                 <constraint firstAttribute="trailing" secondItem="A5y-ue-y7t" secondAttribute="trailing" id="rKQ-WW-oC6"/>
+                <constraint firstItem="VAn-gF-QiZ" firstAttribute="bottom" secondItem="OBS-Eh-1mT" secondAttribute="bottom" id="ukj-ba-ask"/>
                 <constraint firstItem="A5y-ue-y7t" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="x7v-58-kKz"/>
                 <constraint firstItem="OBS-Eh-1mT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="yvp-xr-geN"/>
             </constraints>
diff --git a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
index 337acf1fee..8b413bcc3d 100644
--- a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
+++ b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
@@ -29,6 +29,7 @@ extern NSString *VLCLibraryCellIdentifier;
 @interface VLCLibraryCollectionViewItem : NSCollectionViewItem
 
 @property (readwrite, assign) IBOutlet NSTextField *mediaTitleTextField;
+ at property (readwrite, assign) IBOutlet NSTextField *durationTextField;
 @property (readwrite, assign) IBOutlet NSImageView *mediaImageView;
 
 @end
diff --git a/modules/gui/macosx/library/VLCLibraryController.m b/modules/gui/macosx/library/VLCLibraryController.m
index cb75184549..837ef837f7 100644
--- a/modules/gui/macosx/library/VLCLibraryController.m
+++ b/modules/gui/macosx/library/VLCLibraryController.m
@@ -41,7 +41,7 @@
     self = [super init];
     if (self) {
         _p_libraryInstance = vlc_ml_instance_get(getIntf());
-        _libraryModel = [[VLCLibraryModel alloc] init];
+        _libraryModel = [[VLCLibraryModel alloc] initWithLibrary:_p_libraryInstance];
 
         NSNotificationCenter *defaultNotificationCenter = [NSNotificationCenter defaultCenter];
         [defaultNotificationCenter addObserver:self
diff --git a/modules/gui/macosx/library/VLCLibraryDataSource.h b/modules/gui/macosx/library/VLCLibraryDataSource.h
index 94ef80572e..abb4daed9e 100644
--- a/modules/gui/macosx/library/VLCLibraryDataSource.h
+++ b/modules/gui/macosx/library/VLCLibraryDataSource.h
@@ -24,8 +24,12 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+ at class VLCLibraryModel;
+
 @interface VLCLibraryDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate>
 
+ at property (readwrite, assign) VLCLibraryModel *libraryModel;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/library/VLCLibraryDataSource.m b/modules/gui/macosx/library/VLCLibraryDataSource.m
index 19c7604f06..0a2f9a1893 100644
--- a/modules/gui/macosx/library/VLCLibraryDataSource.m
+++ b/modules/gui/macosx/library/VLCLibraryDataSource.m
@@ -23,20 +23,35 @@
 #import "VLCLibraryDataSource.h"
 
 #import "library/VLCLibraryCollectionViewItem.h"
+#import "library/VLCLibraryModel.h"
+
+#import "extensions/NSString+Helpers.h"
 
 @implementation VLCLibraryDataSource
 
 - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
 {
-    return 2;
+    return [_libraryModel numberOfVideoMedia];
 }
 
 - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
 {
     VLCLibraryCollectionViewItem *viewItem = [collectionView makeItemWithIdentifier:VLCLibraryCellIdentifier forIndexPath:indexPath];
 
-    viewItem.mediaTitleTextField.stringValue = @"Custom Cell Label Text";
-    viewItem.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
+    NSArray *videoMedia = [_libraryModel listOfVideoMedia];
+    VLCMediaLibraryMediaItem *mediaItem = videoMedia[indexPath.item];
+
+    viewItem.mediaTitleTextField.stringValue = mediaItem.title;
+    viewItem.durationTextField.stringValue = [NSString stringWithTime:mediaItem.duration];
+
+    NSImage *image;
+    if (mediaItem.artworkGenerated) {
+        image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:mediaItem.artworkMRL]];
+    }
+    if (!image) {
+        image = [NSImage imageNamed: @"noart.png"];
+    }
+    viewItem.mediaImageView.image = image;
 
     return viewItem;
 }
diff --git a/modules/gui/macosx/library/VLCLibraryModel.h b/modules/gui/macosx/library/VLCLibraryModel.h
index abbf186089..3c362e2872 100644
--- a/modules/gui/macosx/library/VLCLibraryModel.h
+++ b/modules/gui/macosx/library/VLCLibraryModel.h
@@ -26,10 +26,81 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+ at class VLCMediaLibraryMediaItem;
+
+extern NSString *VLCLibraryModelVideoMediaListUpdated;
+
 @interface VLCLibraryModel : NSObject
 
 - (instancetype)initWithLibrary:(vlc_medialibrary_t *)library;
 
+ at property (readonly) size_t numberOfVideoMedia;
+ at property (readonly) NSArray <VLCMediaLibraryMediaItem *> *listOfVideoMedia;
+
+- (nullable VLCMediaLibraryMediaItem *)mediaItemAtIndexPath:(NSIndexPath *)index;
+
+ at end
+
+ at interface VLCMediaLibraryFile : NSObject
+
+- (instancetype)initWithFile:(struct vlc_ml_file_t *)file;
+
+ at property (readonly) NSString *MRL;
+ at property (readonly) vlc_ml_file_type_t fileType;
+ at property (readonly) BOOL external;
+ at property (readonly) BOOL removable;
+ at property (readonly) BOOL present;
+
+ at end
+
+ at interface VLCMediaLibraryTrack : NSObject
+
+- (instancetype)initWithTrack:(struct vlc_ml_media_track_t *)track;
+
+ at property (readonly) NSString *codec;
+ at property (readonly) NSString *language;
+ at property (readonly) NSString *trackDescription;
+ at property (readonly) vlc_ml_track_type_t trackType;
+ at property (readonly) uint32_t bitrate;
+
+ at property (readonly) uint32_t numberOfAudioChannels;
+ at property (readonly) uint32_t audioSampleRate;
+
+ at property (readonly) uint32_t videoHeight;
+ at property (readonly) uint32_t videoWidth;
+ at property (readonly) uint32_t sourceAspectRatio;
+ at property (readonly) uint32_t sourceAspectRatioDenominator;
+ at property (readonly) uint32_t frameRate;
+ at property (readonly) uint32_t frameRateDenominator;
+
+ at end
+
+ at interface VLCMediaLibraryMediaItem : NSObject
+
+- (instancetype)initWithMediaItem:(struct vlc_ml_media_t *)mediaItem;
+
+ at property (readonly) int64_t libraryID;
+ at property (readonly) vlc_ml_media_type_t mediaType;
+ at property (readonly) vlc_ml_media_subtype_t mediaSubType;
+
+ at property (readonly) NSArray <VLCMediaLibraryFile *> *files;
+ at property (readonly) NSArray <VLCMediaLibraryTrack *> *tracks;
+
+ at property (readonly) int32_t year;
+ at property (readonly) int64_t duration; /* Duration in milliseconds */
+ at property (readonly) uint32_t playCount;
+ at property (readonly) time_t lastPlayedDate;
+ at property (readonly) NSString *title;
+
+ at property (readonly) NSString *artworkMRL;
+
+ at property (readonly) BOOL artworkGenerated;
+ at property (readonly) BOOL favorited;
+
+ at property (readonly) vlc_ml_show_episode_t showEpisode;
+ at property (readonly) vlc_ml_movie_t movie;
+ at property (readonly) vlc_ml_album_track_t albumTrack;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/library/VLCLibraryModel.m b/modules/gui/macosx/library/VLCLibraryModel.m
index a4544b1598..cea1843b3e 100644
--- a/modules/gui/macosx/library/VLCLibraryModel.m
+++ b/modules/gui/macosx/library/VLCLibraryModel.m
@@ -21,13 +21,40 @@
  *****************************************************************************/
 
 #import "VLCLibraryModel.h"
+#import "extensions/NSString+Helpers.h"
+
+NSString *VLCLibraryModelVideoMediaListUpdated = @"VLCLibraryModelVideoMediaListUpdated";
 
 @interface VLCLibraryModel ()
 {
     vlc_medialibrary_t *_p_mediaLibrary;
+    vlc_ml_event_callback_t *_p_eventCallback;
+
+    NSArray *_cachedVideoMedia;
+    NSNotificationCenter *_defaultNotificationCenter;
 }
+
+- (void)updateCachedListOfVideoMedia;
+
 @end
 
+static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
+{
+    switch(p_event->i_type)
+    {
+        case VLC_ML_EVENT_MEDIA_ADDED:
+        case VLC_ML_EVENT_MEDIA_UPDATED:
+        case VLC_ML_EVENT_MEDIA_DELETED:
+            dispatch_async(dispatch_get_main_queue(), ^{
+                VLCLibraryModel *libraryModel = (__bridge VLCLibraryModel *)p_data;
+                [libraryModel updateCachedListOfVideoMedia];
+            });
+            break;
+        default:
+            break;
+    }
+}
+
 @implementation VLCLibraryModel
 
 - (instancetype)initWithLibrary:(vlc_medialibrary_t *)library
@@ -35,8 +62,159 @@
     self = [super init];
     if (self) {
         _p_mediaLibrary = library;
+        _p_eventCallback = vlc_ml_event_register_callback(_p_mediaLibrary, libraryCallback, (__bridge void *)self);
+        _defaultNotificationCenter = [[NSNotificationCenter alloc] init];
     }
     return self;
 }
 
+- (void)dealloc
+{
+    if (_p_eventCallback) {
+        vlc_ml_event_unregister_callback(_p_mediaLibrary, _p_eventCallback);
+    }
+}
+
+- (size_t)numberOfVideoMedia
+{
+    if (!_cachedVideoMedia) {
+        [self updateCachedListOfVideoMedia];
+    }
+
+    return _cachedVideoMedia.count;
+}
+
+- (void)updateCachedListOfVideoMedia
+{
+    vlc_ml_media_list_t *p_media_list = vlc_ml_list_video_media(_p_mediaLibrary, NULL);
+    NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:p_media_list->i_nb_items];
+    for (size_t x = 0; x < p_media_list->i_nb_items; x++) {
+        VLCMediaLibraryMediaItem *mediaItem = [[VLCMediaLibraryMediaItem alloc] initWithMediaItem:&p_media_list->p_items[x]];
+        [mutableArray addObject:mediaItem];
+    }
+    _cachedVideoMedia = [mutableArray copy];
+    vlc_ml_media_list_release(p_media_list);
+    [_defaultNotificationCenter postNotificationName:VLCLibraryModelVideoMediaListUpdated object:self];
+}
+
+- (nullable VLCMediaLibraryMediaItem *)mediaItemAtIndexPath:(NSIndexPath *)indexPath
+{
+    // FIXME: the scope needs be larger than just the video list
+    if (!_cachedVideoMedia) {
+        return nil;
+    }
+    return _cachedVideoMedia[indexPath.item];
+}
+
+- (NSArray<VLCMediaLibraryMediaItem *> *)listOfVideoMedia
+{
+    if (!_cachedVideoMedia) {
+        [self updateCachedListOfVideoMedia];
+    }
+
+    return _cachedVideoMedia;
+}
+
+ at end
+
+ at implementation VLCMediaLibraryFile
+
+- (instancetype)initWithFile:(struct vlc_ml_file_t *)file
+{
+    self = [super init];
+    if (self && file != NULL) {
+        _MRL = toNSStr(file->psz_mrl);
+        _fileType = file->i_type;
+        _external = file->b_external;
+        _removable = file->b_removable;
+        _present = file->b_present;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"%@ — type: %i, MRL: %@", NSStringFromClass([self class]), _fileType, _MRL];
+}
+
+ at end
+
+ at implementation VLCMediaLibraryTrack
+
+- (instancetype)initWithTrack:(struct vlc_ml_media_track_t *)track
+{
+    self = [super init];
+    if (self && track != NULL) {
+        _codec = toNSStr(track->psz_codec);
+        _language = toNSStr(track->psz_language);
+        _trackDescription = toNSStr(track->psz_description);
+        _trackType = track->i_type;
+        _bitrate = track->i_bitrate;
+
+        _numberOfAudioChannels = track->a.i_nbChannels;
+        _audioSampleRate = track->a.i_sampleRate;
+
+        _videoHeight = track->v.i_height;
+        _videoWidth = track->v.i_width;
+        _sourceAspectRatio = track->v.i_sarNum;
+        _sourceAspectRatioDenominator = track->v.i_sarDen;
+        _frameRate = track->v.i_fpsNum;
+        _frameRateDenominator = track->v.i_fpsDen;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"%@ — type: %i, codec %@", NSStringFromClass([self class]), _trackType, _codec];
+}
+
+ at end
+
+ at implementation VLCMediaLibraryMediaItem
+
+- (instancetype)initWithMediaItem:(struct vlc_ml_media_t *)p_mediaItem
+{
+    self = [super init];
+    if (self) {
+        _libraryID = p_mediaItem->i_id;
+        _mediaType = p_mediaItem->i_type;
+        _mediaSubType = p_mediaItem->i_subtype;
+        NSMutableArray *mutArray = [[NSMutableArray alloc] initWithCapacity:p_mediaItem->p_files->i_nb_items];
+        for (size_t x = 0; x < p_mediaItem->p_files->i_nb_items; x++) {
+            VLCMediaLibraryFile *file = [[VLCMediaLibraryFile alloc] initWithFile:&p_mediaItem->p_files->p_items[x]];
+            if (file) {
+                [mutArray addObject:file];
+            }
+        }
+        _files = [mutArray copy];
+        mutArray = [[NSMutableArray alloc] initWithCapacity:p_mediaItem->p_tracks->i_nb_items];
+        for (size_t x = 0; x < p_mediaItem->p_tracks->i_nb_items; x++) {
+            VLCMediaLibraryTrack *track = [[VLCMediaLibraryTrack alloc] initWithTrack:&p_mediaItem->p_tracks->p_items[x]];
+            if (track) {
+                [mutArray addObject:track];
+            }
+        }
+        _tracks = [mutArray copy];
+        _year = p_mediaItem->i_year;
+        _duration = p_mediaItem->i_duration;
+        _playCount = p_mediaItem->i_playcount;
+        _lastPlayedDate = p_mediaItem->i_last_played_date;
+        _title = toNSStr(p_mediaItem->psz_title);
+        _artworkMRL = toNSStr(p_mediaItem->psz_artwork_mrl);
+        _artworkGenerated = p_mediaItem->b_artwork_generated;
+        _favorited = p_mediaItem->b_is_favorite;
+        _showEpisode = p_mediaItem->show_episode;
+        _movie = p_mediaItem->movie;
+        _albumTrack = p_mediaItem->album_track;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"%@ — title: %@, ID: %lli, type: %i, artwork: %@",
+            NSStringFromClass([self class]), _title, _libraryID, _mediaType, _artworkMRL];
+}
+
 @end
diff --git a/modules/gui/macosx/library/VLCLibraryWindow.m b/modules/gui/macosx/library/VLCLibraryWindow.m
index c0067170a6..d650ca07a2 100644
--- a/modules/gui/macosx/library/VLCLibraryWindow.m
+++ b/modules/gui/macosx/library/VLCLibraryWindow.m
@@ -28,8 +28,10 @@
 #import "playlist/VLCPlaylistController.h"
 #import "playlist/VLCPlaylistDataSource.h"
 
+#import "library/VLCLibraryController.h"
 #import "library/VLCLibraryDataSource.h"
 #import "library/VLCLibraryCollectionViewItem.h"
+#import "library/VLCLibraryModel.h"
 
 #import "windows/mainwindow/VLCControlsBarCommon.h"
 #import "windows/video/VLCFSPanelController.h"
@@ -59,6 +61,10 @@ static const float f_playlist_row_height = 72.;
                            selector:@selector(shouldShowFullscreenController:)
                                name:VLCVideoWindowShouldShowFullscreenController
                              object:nil];
+    [notificationCenter addObserver:self
+                           selector:@selector(updateLibraryRepresentation:)
+                               name:VLCLibraryModelVideoMediaListUpdated
+                             object:nil];
 
     _fspanel = [[VLCFSPanelController alloc] init];
     [_fspanel showWindow:self];
@@ -71,7 +77,9 @@ static const float f_playlist_row_height = 72.;
     [_segmentedTitleControl setLabel:_NS("Network") forSegment:2];
     [_segmentedTitleControl sizeToFit];
 
-    VLCPlaylistController *playlistController = [[VLCMain sharedInstance] playlistController];
+    VLCMain *mainInstance = [VLCMain sharedInstance];
+
+    VLCPlaylistController *playlistController = [mainInstance playlistController];
     _playlistDataSource = [[VLCPlaylistDataSource alloc] init];
     _playlistDataSource.playlistController = playlistController;
     _playlistDataSource.tableView = _playlistTableView;
@@ -83,6 +91,7 @@ static const float f_playlist_row_height = 72.;
     [_playlistTableView reloadData];
 
     _libraryDataSource = [[VLCLibraryDataSource alloc] init];
+    _libraryDataSource.libraryModel = mainInstance.libraryController.libraryModel;
     _libraryCollectionView.dataSource = _libraryDataSource;
     _libraryCollectionView.delegate = _libraryDataSource;
     [_libraryCollectionView registerClass:[VLCLibraryCollectionViewItem class] forItemWithIdentifier:VLCLibraryCellIdentifier];
@@ -158,6 +167,12 @@ static const float f_playlist_row_height = 72.;
     }
 }
 
+#pragma mark - library representation and interaction
+- (void)updateLibraryRepresentation:(NSNotification *)aNotification
+{
+    [_libraryCollectionView reloadData];
+}
+
 #pragma mark -
 #pragma mark Fullscreen support
 



More information about the vlc-commits mailing list