Commit 787defaa authored by Felix Paul Kühne's avatar Felix Paul Kühne

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

parent f3cb7306
<?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>
......
......@@ -29,6 +29,7 @@ extern NSString *VLCLibraryCellIdentifier;
@interface VLCLibraryCollectionViewItem : NSCollectionViewItem
@property (readwrite, assign) IBOutlet NSTextField *mediaTitleTextField;
@property (readwrite, assign) IBOutlet NSTextField *durationTextField;
@property (readwrite, assign) IBOutlet NSImageView *mediaImageView;
@end
......
......@@ -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
......
......@@ -24,8 +24,12 @@
NS_ASSUME_NONNULL_BEGIN
@class VLCLibraryModel;
@interface VLCLibraryDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate>
@property (readwrite, assign) VLCLibraryModel *libraryModel;
@end
NS_ASSUME_NONNULL_END
......@@ -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;
}
......
......@@ -26,10 +26,81 @@
NS_ASSUME_NONNULL_BEGIN
@class VLCMediaLibraryMediaItem;
extern NSString *VLCLibraryModelVideoMediaListUpdated;
@interface VLCLibraryModel : NSObject
- (instancetype)initWithLibrary:(vlc_medialibrary_t *)library;
@property (readonly) size_t numberOfVideoMedia;
@property (readonly) NSArray <VLCMediaLibraryMediaItem *> *listOfVideoMedia;
- (nullable VLCMediaLibraryMediaItem *)mediaItemAtIndexPath:(NSIndexPath *)index;
@end
@interface VLCMediaLibraryFile : NSObject
- (instancetype)initWithFile:(struct vlc_ml_file_t *)file;
@property (readonly) NSString *MRL;
@property (readonly) vlc_ml_file_type_t fileType;
@property (readonly) BOOL external;
@property (readonly) BOOL removable;
@property (readonly) BOOL present;
@end
@interface VLCMediaLibraryTrack : NSObject
- (instancetype)initWithTrack:(struct vlc_ml_media_track_t *)track;
@property (readonly) NSString *codec;
@property (readonly) NSString *language;
@property (readonly) NSString *trackDescription;
@property (readonly) vlc_ml_track_type_t trackType;
@property (readonly) uint32_t bitrate;
@property (readonly) uint32_t numberOfAudioChannels;
@property (readonly) uint32_t audioSampleRate;
@property (readonly) uint32_t videoHeight;
@property (readonly) uint32_t videoWidth;
@property (readonly) uint32_t sourceAspectRatio;
@property (readonly) uint32_t sourceAspectRatioDenominator;
@property (readonly) uint32_t frameRate;
@property (readonly) uint32_t frameRateDenominator;
@end
@interface VLCMediaLibraryMediaItem : NSObject
- (instancetype)initWithMediaItem:(struct vlc_ml_media_t *)mediaItem;
@property (readonly) int64_t libraryID;
@property (readonly) vlc_ml_media_type_t mediaType;
@property (readonly) vlc_ml_media_subtype_t mediaSubType;
@property (readonly) NSArray <VLCMediaLibraryFile *> *files;
@property (readonly) NSArray <VLCMediaLibraryTrack *> *tracks;
@property (readonly) int32_t year;
@property (readonly) int64_t duration; /* Duration in milliseconds */
@property (readonly) uint32_t playCount;
@property (readonly) time_t lastPlayedDate;
@property (readonly) NSString *title;
@property (readonly) NSString *artworkMRL;
@property (readonly) BOOL artworkGenerated;
@property (readonly) BOOL favorited;
@property (readonly) vlc_ml_show_episode_t showEpisode;
@property (readonly) vlc_ml_movie_t movie;
@property (readonly) vlc_ml_album_track_t albumTrack;
@end
NS_ASSUME_NONNULL_END
......@@ -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;
}
@end
@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];
}
@end
@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];
}
@end
@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
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment