[vlc-devel] [vlc-commits] macosx: basic implementation of the playlist data model

David Fuhrmann david.fuhrmann at gmail.com
Thu Jan 31 19:00:26 CET 2019



> Am 31.01.2019 um 14:02 schrieb Felix Paul Kühne <git at videolan.org>:
> 
> vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Thu Jan 31 12:50:20 2019 +0100| [d14583a48d513cadbdd9b5c1b522685acd530ca4] | committer: Felix Paul Kühne
> 
> macosx: basic implementation of the playlist data model
> 
>> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d14583a48d513cadbdd9b5c1b522685acd530ca4
> ---
> 
> .../package/macosx/VLC.xcodeproj/project.pbxproj   |  24 ++
> modules/gui/macosx/Makefile.am                     |   4 +
> modules/gui/macosx/VLCLibraryWindow.h              |   4 -
> modules/gui/macosx/VLCLibraryWindow.m              |  50 +---
> modules/gui/macosx/VLCMain.h                       |   2 +
> modules/gui/macosx/VLCMain.m                       |   2 +
> modules/gui/macosx/VLCPlaylistController.h         |  56 ++++
> modules/gui/macosx/VLCPlaylistController.m         | 316 +++++++++++++++++++++
> modules/gui/macosx/VLCPlaylistDataSource.h         |  38 +++
> modules/gui/macosx/VLCPlaylistDataSource.m         |  97 +++++++
> modules/gui/macosx/VLCPlaylistItem.h               |  42 +++
> modules/gui/macosx/VLCPlaylistItem.m               |  53 ++++
> modules/gui/macosx/VLCPlaylistModel.h              |  42 +++
> modules/gui/macosx/VLCPlaylistModel.m              |  72 +++++
> 14 files changed, 755 insertions(+), 47 deletions(-)
> 
> diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> index bac1891aab..27381cfe78 100644
> --- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> +++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> @@ -120,8 +120,12 @@
> 		6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; };
> 		7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */; };
> 		7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F64042202047900FDB91F /* VLCLibraryCollectionViewItem.m */; };
> +		7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */; };
> 		7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2E0ED920CD204D0033A221 /* VLCWindow.m */; };
> 		7D2E0EDE20CD206F0033A221 /* VLCVideoWindowCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2E0EDD20CD206F0033A221 /* VLCVideoWindowCommon.m */; };
> +		7D445D812202524000263D34 /* VLCPlaylistController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D445D802202524000263D34 /* VLCPlaylistController.m */; };
> +		7D445D842202524D00263D34 /* VLCPlaylistItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D445D832202524D00263D34 /* VLCPlaylistItem.m */; };
> +		7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D445D862202574B00263D34 /* VLCPlaylistModel.m */; };
> 		7D66D4362200BC340040D04A /* VLCClickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D66D4352200BC340040D04A /* VLCClickerManager.m */; };
> 		7D66D4392200C5B80040D04A /* VLCVideoFilterHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D66D4382200C5B80040D04A /* VLCVideoFilterHelper.m */; };
> 		7D66D43C2200D6090040D04A /* VLCDetachedVideoWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D66D43B2200D6090040D04A /* VLCDetachedVideoWindow.m */; };
> @@ -442,10 +446,18 @@
> 		7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VLCLibraryCollectionViewItem.xib; sourceTree = "<group>"; };
> 		7D0F64082202058700FDB91F /* libraryCellGradient at 1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "libraryCellGradient at 1x.png"; path = "../librarywindow/libraryCellGradient at 1x.png"; sourceTree = "<group>"; };
> 		7D0F64092202058700FDB91F /* libraryCellGradient at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "libraryCellGradient at 2x.png"; path = "../librarywindow/libraryCellGradient at 2x.png"; sourceTree = "<group>"; };
> +		7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistDataSource.h; sourceTree = "<group>"; };
> +		7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistDataSource.m; sourceTree = "<group>"; };
> 		7D2E0ED920CD204D0033A221 /* VLCWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCWindow.m; sourceTree = "<group>"; };
> 		7D2E0EDA20CD204D0033A221 /* VLCWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCWindow.h; sourceTree = "<group>"; };
> 		7D2E0EDC20CD206F0033A221 /* VLCVideoWindowCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCVideoWindowCommon.h; sourceTree = "<group>"; };
> 		7D2E0EDD20CD206F0033A221 /* VLCVideoWindowCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCVideoWindowCommon.m; sourceTree = "<group>"; };
> +		7D445D7F2202524000263D34 /* VLCPlaylistController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistController.h; sourceTree = "<group>"; };
> +		7D445D802202524000263D34 /* VLCPlaylistController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistController.m; sourceTree = "<group>"; };
> +		7D445D822202524D00263D34 /* VLCPlaylistItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistItem.h; sourceTree = "<group>"; };
> +		7D445D832202524D00263D34 /* VLCPlaylistItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistItem.m; sourceTree = "<group>"; };
> +		7D445D852202574B00263D34 /* VLCPlaylistModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistModel.h; sourceTree = "<group>"; };
> +		7D445D862202574B00263D34 /* VLCPlaylistModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistModel.m; sourceTree = "<group>"; };
> 		7D5678EB1D5BA1DC002698F3 /* VLCApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCApplication.h; sourceTree = "<group>"; };
> 		7D5678EC1D5BA1DC002698F3 /* VLCApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCApplication.m; sourceTree = "<group>"; };
> 		7D5678EE1D5BA397002698F3 /* VLCMainWindowControlsBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCMainWindowControlsBar.h; sourceTree = "<group>"; };
> @@ -1308,6 +1320,14 @@
> 			children = (
> 				7D713D302201AE350042BEB7 /* VLCLibraryWindow.h */,
> 				7D713D312201AE350042BEB7 /* VLCLibraryWindow.m */,
> +				7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */,
> +				7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */,
> +				7D445D7F2202524000263D34 /* VLCPlaylistController.h */,
> +				7D445D802202524000263D34 /* VLCPlaylistController.m */,
> +				7D445D852202574B00263D34 /* VLCPlaylistModel.h */,
> +				7D445D862202574B00263D34 /* VLCPlaylistModel.m */,
> +				7D445D822202524D00263D34 /* VLCPlaylistItem.h */,
> +				7D445D832202524D00263D34 /* VLCPlaylistItem.m */,
> 				7D0F63FD2201F63400FDB91F /* VLCPlaylistTableCellView.h */,
> 				7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */,
> 				7D0F64032202047900FDB91F /* VLCLibraryCollectionViewItem.h */,
> @@ -1640,6 +1660,7 @@
> 				1CCC88F52078A3D500E5626F /* SyncTracks.xib in Sources */,
> 				1CCC88F62078A3D500E5626F /* MediaInfo.xib in Sources */,
> 				7D66D4392200C5B80040D04A /* VLCVideoFilterHelper.m in Sources */,
> +				7D445D812202524000263D34 /* VLCPlaylistController.m in Sources */,
> 				1CCC88F72078A3D500E5626F /* ConvertAndSave.xib in Sources */,
> 				1CCC88F82078A3D500E5626F /* CoreDialogs.xib in Sources */,
> 				1CCC88F92078A3D500E5626F /* DetachedVideoWindow.xib in Sources */,
> @@ -1699,6 +1720,8 @@
> 				1C3113A71E508C6900D4DD76 /* VLCLogWindowController.m in Sources */,
> 				1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */,
> 				1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */,
> +				7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */,
> +				7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */,
> 				1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,
> 				1C3113AF1E508C6900D4DD76 /* VLCFSPanelController.m in Sources */,
> 				7D66D4362200BC340040D04A /* VLCClickerManager.m in Sources */,
> @@ -1721,6 +1744,7 @@
> 				6BBB05DA1EEFEA29003A1019 /* VLCHUDOutlineView.m in Sources */,
> 				1C3113CB1E508C6900D4DD76 /* VLCPLItem.m in Sources */,
> 				6B8A6B0B2128697E00DC29F3 /* VLCSourceListTableCellView.m in Sources */,
> +				7D445D842202524D00263D34 /* VLCPlaylistItem.m in Sources */,
> 				1C3113CD1E508C6900D4DD76 /* VLCPLModel.m in Sources */,
> 				1C3113CF1E508C6900D4DD76 /* prefs_widgets.m in Sources */,
> 				7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */,
> diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
> index bd69ff7105..140fc30039 100644
> --- a/modules/gui/macosx/Makefile.am
> +++ b/modules/gui/macosx/Makefile.am
> @@ -91,6 +91,10 @@ libmacosx_plugin_la_SOURCES = \
> 	gui/macosx/VLCRemoteControlService.h gui/macosx/VLCRemoteControlService.m \
> 	gui/macosx/VLCMainWindow.h gui/macosx/VLCMainWindow.m \
> 	gui/macosx/VLCLibraryWindow.h gui/macosx/VLCLibraryWindow.m \
> +	gui/macosx/VLCPlaylistController.h gui/macosx/VLCPlaylistController.m \
> +	gui/macosx/VLCPlaylistDataSource.h gui/macosx/VLCPlaylistDataSource.m \
> +	gui/macosx/VLCPlaylistItem.h gui/macosx/VLCPlaylistItem.m \
> +	gui/macosx/VLCPlaylistModel.h gui/macosx/VLCPlaylistModel.m \
> 	gui/macosx/VLCPlaylistTableCellView.h gui/macosx/VLCPlaylistTableCellView.m \
> 	gui/macosx/VLCLibraryCollectionViewItem.h gui/macosx/VLCLibraryCollectionViewItem.m \
> 	gui/macosx/VLCDetachedVideoWindow.h gui/macosx/VLCDetachedVideoWindow.m \
> diff --git a/modules/gui/macosx/VLCLibraryWindow.h b/modules/gui/macosx/VLCLibraryWindow.h
> index ff46748952..8fe7e638fa 100644
> --- a/modules/gui/macosx/VLCLibraryWindow.h
> +++ b/modules/gui/macosx/VLCLibraryWindow.h
> @@ -38,10 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
> 
> @end
> 
> - at interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate>
> -
> - at end
> -
> @interface VLCLibraryDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate>
> 
> @end
> diff --git a/modules/gui/macosx/VLCLibraryWindow.m b/modules/gui/macosx/VLCLibraryWindow.m
> index d1b762ede9..b4e72a5af9 100644
> --- a/modules/gui/macosx/VLCLibraryWindow.m
> +++ b/modules/gui/macosx/VLCLibraryWindow.m
> @@ -23,13 +23,15 @@
> #import "VLCLibraryWindow.h"
> #import "NSString+Helpers.h"
> #import "VLCPlaylistTableCellView.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistDataSource.h"
> #import "VLCLibraryCollectionViewItem.h"
> +#import "VLCMain.h"
> 
> static const float f_min_window_width = 604.;
> static const float f_min_window_height = 307.;
> static const float f_playlist_row_height = 40.;
> 
> -static NSString *VLCPlaylistCellIdentifier = @"VLCPlaylistCellIdentifier";
> static NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier";
> 
> @interface VLCLibraryWindow ()
> @@ -51,7 +53,11 @@ static NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier";
>     [_segmentedTitleControl setLabel:_NS("Network") forSegment:2];
>     [_segmentedTitleControl sizeToFit];
> 
> +    VLCPlaylistController *playlistController = [[VLCMain sharedInstance] playlistController];
>     _playlistDataSource = [[VLCPlaylistDataSource alloc] init];
> +    _playlistDataSource.playlistController = playlistController;
> +    _playlistDataSource.tableView = _playlistTableView;
> +    playlistController.playlistDataSource = _playlistDataSource;
> 
>     _playlistTableView.dataSource = _playlistDataSource;
>     _playlistTableView.delegate = _playlistDataSource;
> @@ -71,48 +77,6 @@ static NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier";
> 
> @end
> 
> - at implementation VLCPlaylistDataSource
> -
> -- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
> -{
> -    return 2;
> -}
> -
> -- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
> -{
> -    VLCPlaylistTableCellView *cellView = [tableView makeViewWithIdentifier:VLCPlaylistCellIdentifier owner:self];
> -
> -    if (cellView == nil) {
> -        /* the following code saves us an instance of NSViewController which we don't need */
> -        NSNib *nib = [[NSNib alloc] initWithNibNamed:@"VLCPlaylistTableCellView" bundle:nil];
> -        NSArray *topLevelObjects;
> -        if (![nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) {
> -            NSLog(@"Failed to load nib %@", nib);
> -            return nil;
> -        }
> -
> -        for (id topLevelObject in topLevelObjects) {
> -            if ([topLevelObject isKindOfClass:[VLCPlaylistTableCellView class]]) {
> -                cellView = topLevelObject;
> -                break;
> -            }
> -        }
> -        cellView.identifier = VLCPlaylistCellIdentifier;
> -    }
> -
> -    cellView.mediaTitleTextField.stringValue = @"Custom Cell Label Text";
> -    cellView.durationTextField.stringValue = @"00:00";
> -    cellView.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
> -    return cellView;
> -}
> -
> -- (void)tableViewSelectionDidChange:(NSNotification *)notification
> -{
> -    NSLog(@"playlist selection changed: %li", (long)[(NSTableView *)notification.object selectedRow]);
> -}
> -
> - at end
> -
> @implementation VLCLibraryDataSource
> 
> - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
> diff --git a/modules/gui/macosx/VLCMain.h b/modules/gui/macosx/VLCMain.h
> index 7863d1f497..5b55a59de6 100644
> --- a/modules/gui/macosx/VLCMain.h
> +++ b/modules/gui/macosx/VLCMain.h
> @@ -77,6 +77,7 @@ static NSString * VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
> @class VLCExtensionsManager;
> @class VLCInfo;
> @class VLCStatusBarIcon;
> + at class VLCPlaylistController;
> 
> @interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
> 
> @@ -84,6 +85,7 @@ static NSString * VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
> @property (readonly) BOOL nativeFullscreenMode;
> @property (nonatomic, readwrite) BOOL playlistUpdatedSelectorInQueue;
> @property (readonly) VLCLibraryWindowController *libraryWindowController;
> + at property (readonly) VLCPlaylistController *playlistController;
> 
> + (VLCMain *)sharedInstance;
> + (void)killInstance;
> diff --git a/modules/gui/macosx/VLCMain.m b/modules/gui/macosx/VLCMain.m
> index c2c07f0859..b0c57fad0b 100644
> --- a/modules/gui/macosx/VLCMain.m
> +++ b/modules/gui/macosx/VLCMain.m
> @@ -61,6 +61,7 @@
> #import "VLCLogWindowController.h"
> #import "VLCConvertAndSaveWindowController.h"
> #import "VLCLibraryWindow.h"
> +#import "VLCPlaylistController.h"
> 
> #import "VLCVideoEffectsWindowController.h"
> #import "VLCAudioEffectsWindowController.h"
> @@ -221,6 +222,7 @@ static VLCMain *sharedInstance = nil;
> 
>         [VLCApplication sharedApplication].delegate = self;
> 
> +        _playlistController = [[VLCPlaylistController alloc] init];
>         _input_manager = [[VLCInputManager alloc] initWithMain:self];
> 
>         // first initalize extensions dialog provider, then core dialog
> diff --git a/modules/gui/macosx/VLCPlaylistController.h b/modules/gui/macosx/VLCPlaylistController.h
> new file mode 100644
> index 0000000000..63652603cb
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistController.h
> @@ -0,0 +1,56 @@
> +/*****************************************************************************
> + * VLCPlaylistController.h: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at class VLCPlaylistModel;
> + at class VLCPlaylistDataSource;
> +
> + at interface VLCPlaylistController : NSObject
> +
> + at property (readonly) vlc_playlist_t *p_playlist;
> + at property (readonly) VLCPlaylistModel *playlistModel;
> + at property (readwrite, assign) VLCPlaylistDataSource *playlistDataSource;
> +
> +/**
> + * Simplified version to add new items at the end of the current playlist
> + * @param array array of items. Each item is a Dictionary with meta info.
> + */
> +- (void)addPlaylistItems:(NSArray*)array;
> +
> +/**
> + * Adds new items to the playlist, at specified parent node and index.
> + * @param o_array array of items. Each item is a Dictionary with meta info.
> + * @param i_plItemId parent playlist node id, -1 for default playlist
> + * @param i_position index for new items, -1 for appending at end
> + * @param b_start starts playback of first item if true
> + */
> +- (void)addPlaylistItems:(NSArray*)itemArray
> +              atPosition:(size_t)insertionIndex
> +           startPlayback:(BOOL)b_start;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistController.m b/modules/gui/macosx/VLCPlaylistController.m
> new file mode 100644
> index 0000000000..878ccb0d6d
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistController.m
> @@ -0,0 +1,316 @@
> +/*****************************************************************************
> + * VLCPlaylistController.m: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistModel.h"
> +#import "VLCPlaylistDataSource.h"
> +#import "VLCMain.h"
> +#import <vlc_interface.h>
> +
> + at interface VLCPlaylistController ()
> +{
> +    vlc_playlist_t *_p_playlist;
> +    vlc_playlist_listener_id *_playlistListenerID;
> +}
> +
> +- (void)playlistAdded:(vlc_playlist_item_t *const *)items atIndex:(size_t)insertionIndex count:(size_t)numberOfItems;
> +- (void)playlistRemovedItemsAtIndex:(size_t)index count:(size_t)numberOfItems;
> +- (void)currentPlaylistItemChanged:(ssize_t)index;
> +
> + at end
> +
> +#pragma mark -
> +#pragma mark core callbacks
> +
> +static void
> +cb_playlist_items_reset(vlc_playlist_t *playlist,
> +                        vlc_playlist_item_t *const items[],
> +                        size_t numberOfItems,
> +                        void *p_data)
> +{
> +    NSLog(@"%s: numberOfItems %zu", __func__, numberOfItems);
> +}
> +
> +static void
> +cb_playlist_items_added(vlc_playlist_t *playlist,
> +                        size_t insertionIndex,
> +                        vlc_playlist_item_t *const items[],
> +                        size_t numberOfAddedItems,
> +                        void *p_data)
> +{
> +    NSLog(@"%s: insertionIndex: %zu numberOfAddedItems: %zu", __func__, insertionIndex, numberOfAddedItems);
> +    VLCPlaylistController *playlistController = (__bridge VLCPlaylistController *)p_data;
> +    [playlistController playlistAdded:items atIndex:insertionIndex count:numberOfAddedItems];
> +}
> +
> +static void
> +cb_playlist_items_removed(vlc_playlist_t *playlist,
> +                          size_t index,
> +                          size_t count,
> +                          void *p_data)
> +{
> +    NSLog(@"%s: index: %zu count: %zu", __func__, index, count);
> +    VLCPlaylistController *playlistController = (__bridge VLCPlaylistController *)p_data;
> +    [playlistController playlistRemovedItemsAtIndex:index count:count];
> +}
> +
> +static void
> +cb_playlist_items_updated(vlc_playlist_t *playlist,
> +                          size_t index,
> +                          vlc_playlist_item_t *const items[],
> +                          size_t len,
> +                          void *p_data)
> +{
> +    NSLog(@"%s: index: %zu len: %zu", __func__, index, len);
> +}
> +
> +static void
> +cb_playlist_playback_repeat_changed(vlc_playlist_t *playlist,
> +                                    enum vlc_playlist_playback_repeat repeat,
> +                                    void *userdata)
> +{
> +    NSLog(@"%s: repeat mode: %u", __func__, repeat);
> +}
> +
> +static void
> +cb_playlist_playback_order_changed(vlc_playlist_t *playlist,
> +                                   enum vlc_playlist_playback_order order,
> +                                   void *userdata)
> +{
> +    NSLog(@"%s: playback order: %u", __func__, order);
> +}
> +
> +static void
> +cb_playlist_current_item_changed(vlc_playlist_t *playlist,
> +                                 ssize_t index,
> +                                 void *p_data)
> +{
> +    if (index == UINT64_MAX) {
> +        NSLog(@"%s: no current item", __func__);
> +    }
> +    VLCPlaylistController *playlistController = (__bridge VLCPlaylistController *)p_data;
> +    [playlistController currentPlaylistItemChanged:index];
> +
> +    NSLog(@"%s: index: %zu", __func__, index);
> +}

HI Felix,

I believe you might need to post all of that into the main thread, no? If so, it should be directly done in the callback, not in any later stage,

BR. David

> +
> +static const struct vlc_playlist_callbacks playlist_callbacks = {
> +    cb_playlist_items_reset,
> +    cb_playlist_items_added,
> +    NULL,
> +    cb_playlist_items_removed,
> +    cb_playlist_items_updated,
> +    cb_playlist_playback_repeat_changed,
> +    cb_playlist_playback_order_changed,
> +    cb_playlist_current_item_changed,
> +    NULL,
> +    NULL,
> +};
> +
> +#pragma mark -
> +#pragma mark class initialization
> +
> + at implementation VLCPlaylistController
> +
> +- (instancetype)init
> +{
> +    self = [super init];
> +    if (self) {
> +        intf_thread_t *p_intf = getIntf();
> +        _p_playlist = vlc_intf_GetMainPlaylist( p_intf );
> +        _playlistListenerID = vlc_playlist_AddListener(_p_playlist,
> +                                                       &playlist_callbacks,
> +                                                       (__bridge void *)self,
> +                                                       YES);
> +        _playlistModel = [[VLCPlaylistModel alloc] init];
> +        _playlistModel.playlistController = self;
> +    }
> +    return self;
> +}
> +
> +- (void)dealloc
> +{
> +    if (_p_playlist) {
> +        if (_playlistListenerID) {
> +            vlc_playlist_RemoveListener(_p_playlist, _playlistListenerID);
> +        }
> +        vlc_playlist_Delete(_p_playlist);
> +    }
> +}
> +
> +#pragma mark - callback forwarders
> +
> +- (void)playlistAdded:(vlc_playlist_item_t *const *)items atIndex:(size_t)insertionIndex count:(size_t)numberOfItems
> +{
> +    NSLog(@"%s", __func__);
> +
> +    for (size_t i = 0; i < numberOfItems; i++) {
> +        [_playlistModel addItem:items[i] atIndex:insertionIndex];
> +        insertionIndex++;
> +    }
> +
> +    [_playlistDataSource playlistUpdated];
> +}
> +
> +- (void)playlistRemovedItemsAtIndex:(size_t)index count:(size_t)numberOfItems
> +{
> +    NSLog(@"%s", __func__);
> +
> +    for (size_t i = index + numberOfItems; i > index; i--) {
> +        [_playlistModel removeItemAtIndex:i];
> +    }
> +}
> +
> +- (void)currentPlaylistItemChanged:(ssize_t)index
> +{
> +    [_playlistDataSource playlistUpdated];
> +}
> +
> +#pragma mark - controller functions for use within the UI
> +
> +- (void)addPlaylistItems:(NSArray*)array
> +{
> +    BOOL b_autoplay = var_InheritBool(getIntf(), "macosx-autoplay");
> +    [self addPlaylistItems:array atPosition:-1 startPlayback:b_autoplay];
> +}
> +
> +- (void)addPlaylistItems:(NSArray*)itemArray
> +              atPosition:(size_t)insertionIndex
> +           startPlayback:(BOOL)startPlayback;
> +{
> +    intf_thread_t *p_intf = getIntf();
> +    NSUInteger numberOfItems = [itemArray count];
> +
> +    for (NSUInteger i = 0; i < numberOfItems; i++) {
> +        NSDictionary *itemMetadata = itemArray[i];
> +        input_item_t *p_input = [self createInputItemBasedOnMetadata:itemMetadata];
> +        NSString *itemURLString = itemMetadata[@"ITEM_URL"];
> +
> +        if (!p_input) {
> +            if (itemURLString) {
> +                msg_Warn(p_intf, "failed to create input for %s", [itemURLString UTF8String]);
> +            } else {
> +                msg_Warn(p_intf, "failed to create input because no URL was provided");
> +            }
> +            continue;
> +        }
> +
> +        vlc_playlist_Lock(_p_playlist);
> +
> +        int ret = 0;
> +        size_t actualInsertionIndex = insertionIndex;
> +        if (insertionIndex == -1) {
> +            actualInsertionIndex = vlc_playlist_Count(_p_playlist);
> +        }
> +        ret = vlc_playlist_Insert(_p_playlist,
> +                                      actualInsertionIndex,
> +                                      &p_input,
> +                                      1);
> +
> +        if (ret != VLC_SUCCESS) {
> +            msg_Err(p_intf, "failed to insert input item at insertion index: %zu", insertionIndex);
> +        } else {
> +            msg_Dbg(p_intf, "Added item %s at insertion index: %zu", [itemURLString UTF8String], insertionIndex);
> +        }
> +
> +        if (i == 0 && startPlayback) {
> +            vlc_playlist_PlayAt(_p_playlist, actualInsertionIndex);
> +        }
> +
> +        vlc_playlist_Unlock(_p_playlist);
> +        input_item_Release(p_input);
> +
> +        if (insertionIndex != -1) {
> +            insertionIndex++;
> +        }
> +    }
> +}
> +
> +#pragma mark - helper methods
> +
> +- (input_item_t *)createInputItemBasedOnMetadata:(NSDictionary *)itemToCreateDict
> +{
> +    intf_thread_t *p_intf = getIntf();
> +
> +    input_item_t *p_input;
> +    BOOL b_rem = FALSE, b_dir = FALSE, b_writable = FALSE;
> +    NSString *uri, *name, *path;
> +    NSURL * url;
> +    NSArray *optionsArray;
> +
> +    /* Get the item */
> +    uri = (NSString *)[itemToCreateDict objectForKey: @"ITEM_URL"];
> +    url = [NSURL URLWithString: uri];
> +    path = [url path];
> +    name = (NSString *)[itemToCreateDict objectForKey: @"ITEM_NAME“];

Could we get rid of that weird pattern, please? ;-)
If we need to pass more than one object, it should be better wrapped in a proper object, not in those directories with magic keys hardcoded here...

> +    optionsArray = (NSArray *)[itemToCreateDict objectForKey: @"ITEM_OPTIONS"];
> +
> +    if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&b_dir]
> +        && b_dir &&
> +        [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path
> +                                                    isRemovable:&b_rem
> +                                                     isWritable:&b_writable
> +                                                  isUnmountable:NULL
> +                                                    description:NULL
> +                                                           type:NULL]
> +        && b_rem && !b_writable && [url isFileURL]) {
> +
> +        NSString *diskType = getVolumeTypeFromMountPath(path);
> +        msg_Dbg(p_intf, "detected optical media of type %s in the file input", [diskType UTF8String]);
> +
> +        if ([diskType isEqualToString: kVLCMediaDVD])
> +            uri = [NSString stringWithFormat: @"dvdnav://%@", getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaVideoTSFolder])
> +            uri = [NSString stringWithFormat: @"dvdnav://%@", path];
> +        else if ([diskType isEqualToString: kVLCMediaAudioCD])
> +            uri = [NSString stringWithFormat: @"cdda://%@", getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaVCD])
> +            uri = [NSString stringWithFormat: @"vcd://%@#0:0", getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaSVCD])
> +            uri = [NSString stringWithFormat: @"vcd://%@@0:0", getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaBD] || [diskType isEqualToString: kVLCMediaBDMVFolder])
> +            uri = [NSString stringWithFormat: @"bluray://%@", path];
> +        else
> +            msg_Warn(getIntf(), "unknown disk type, treating %s as regular input", [path UTF8String]);

this looks a lot like duplicated code.

> +
> +        p_input = input_item_New([uri UTF8String], [[[NSFileManager defaultManager] displayNameAtPath:path] UTF8String]);
> +    } else {
> +        p_input = input_item_New([uri fileSystemRepresentation], name ? [name UTF8String] : NULL);
> +    }
> +
> +    if (!p_input)
> +        return NULL;
> +
> +    if (optionsArray) {
> +        NSUInteger count = [optionsArray count];
> +        for (NSUInteger i = 0; i < count; i++)
> +            input_item_AddOption(p_input, [[optionsArray objectAtIndex:i] UTF8String], VLC_INPUT_OPTION_TRUSTED);
> +    }
> +
> +    /* Recent documents menu */
> +    if (url != nil && var_InheritBool(getIntf(), "macosx-recentitems"))
> +        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:url];
> +
> +    return p_input;
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistDataSource.h b/modules/gui/macosx/VLCPlaylistDataSource.h
> new file mode 100644
> index 0000000000..8dab982c68
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistDataSource.h
> @@ -0,0 +1,38 @@
> +/*****************************************************************************
> + * VLCPlaylistDataSource.h: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import <Cocoa/Cocoa.h>
> +
> + at class VLCPlaylistController;
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate>
> +
> + at property (readwrite, assign, nonatomic) VLCPlaylistController *playlistController;
> + at property (readwrite, assign) NSTableView *tableView;
> +
> +- (void)playlistUpdated;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistDataSource.m b/modules/gui/macosx/VLCPlaylistDataSource.m
> new file mode 100644
> index 0000000000..05e7df8a55
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistDataSource.m
> @@ -0,0 +1,97 @@
> +/*****************************************************************************
> + * VLCPlaylistDataSource.m: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import "VLCPlaylistDataSource.h"
> +#import "VLCPlaylistTableCellView.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistModel.h"
> +#import "VLCPlaylistItem.h"
> +#import "NSString+Helpers.h"
> +
> +static NSString *VLCPlaylistCellIdentifier = @"VLCPlaylistCellIdentifier";
> +
> + at interface VLCPlaylistDataSource ()
> +{
> +    VLCPlaylistModel *_playlistModel;
> +}
> + at end
> +
> + at implementation VLCPlaylistDataSource
> +
> +- (void)setPlaylistController:(VLCPlaylistController *)playlistController
> +{
> +    _playlistController = playlistController;
> +    _playlistModel = _playlistController.playlistModel;
> +}
> +
> +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
> +{
> +    return _playlistModel.numberOfPlaylistItems;
> +}
> +
> +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
> +{
> +    VLCPlaylistTableCellView *cellView = [tableView makeViewWithIdentifier:VLCPlaylistCellIdentifier owner:self];
> +
> +    if (cellView == nil) {
> +        /* the following code saves us an instance of NSViewController which we don't need */
> +        NSNib *nib = [[NSNib alloc] initWithNibNamed:@"VLCPlaylistTableCellView" bundle:nil];
> +        NSArray *topLevelObjects;
> +        if (![nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) {
> +            NSLog(@"Failed to load nib %@", nib);
> +            return nil;
> +        }
> +
> +        for (id topLevelObject in topLevelObjects) {
> +            if ([topLevelObject isKindOfClass:[VLCPlaylistTableCellView class]]) {
> +                cellView = topLevelObject;
> +                break;
> +            }
> +        }
> +        cellView.identifier = VLCPlaylistCellIdentifier;
> +    }
> +
> +    VLCPlaylistItem *item = [_playlistModel playlistItemAtIndex:row];
> +    if (!item) {
> +        NSLog(@"%s: model did not return an item!", __func__);
> +        return cellView;
> +    }
> +
> +    cellView.mediaTitleTextField.stringValue = item.title;
> +    cellView.durationTextField.stringValue = [NSString stringWithTime:item.duration];
> +    cellView.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
> +    // TODO: show more data if available
> +
> +    return cellView;
> +}
> +
> +- (void)tableViewSelectionDidChange:(NSNotification *)notification
> +{
> +    NSLog(@"playlist selection changed: %li", (long)[(NSTableView *)notification.object selectedRow]);
> +}
> +
> +- (void)playlistUpdated
> +{
> +    [_tableView reloadData];
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistItem.h b/modules/gui/macosx/VLCPlaylistItem.h
> new file mode 100644
> index 0000000000..210a6682f9
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistItem.h
> @@ -0,0 +1,42 @@
> +/*****************************************************************************
> + * VLCPlaylistItem.h: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistItem : NSObject
> +
> + at property (readwrite, assign) input_item_t *inputItem;
> + at property (readwrite, retain) NSString *title;
> + at property (readwrite, assign) vlc_tick_t duration;
> +
> + at property (readwrite, retain) NSString *artistName;
> + at property (readwrite, retain) NSString *albumName;
> + at property (readwrite, retain) NSString *artworkURLString;
> +
> +- (instancetype)initWithPlaylistItem:(vlc_playlist_item_t *)p_item;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistItem.m b/modules/gui/macosx/VLCPlaylistItem.m
> new file mode 100644
> index 0000000000..8fa6c0633b
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistItem.m
> @@ -0,0 +1,53 @@
> +/*****************************************************************************
> + * VLCPlaylistItem.m: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import "VLCPlaylistItem.h"
> +#import "NSString+Helpers.h"
> +#import <vlc_input.h>
> +
> + at implementation VLCPlaylistItem
> +
> +- (instancetype)initWithPlaylistItem:(vlc_playlist_item_t *)p_item
> +{
> +    self = [super init];
> +    if (self) {
> +        input_item_t *p_media = vlc_playlist_item_GetMedia(p_item);
> +        vlc_mutex_lock(&p_media->lock);
> +        _title = toNSStr(p_media->psz_name);
> +        _duration = p_media->i_duration;
> +
> +        if (p_media->p_meta) {
> +            _artistName = toNSStr(vlc_meta_Get(p_media->p_meta, vlc_meta_Artist));
> +            _albumName = toNSStr(vlc_meta_Get(p_media->p_meta, vlc_meta_Album));
> +            _artworkURLString = toNSStr(vlc_meta_Get(p_media->p_meta, vlc_meta_ArtworkURL));
> +        }
> +        vlc_mutex_unlock(&p_media->lock);
> +    }
> +    return self;
> +}
> +
> +- (NSString *)description
> +{
> +    return [NSString stringWithFormat:@"item %p, title: %@", &_inputItem, _title];
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistModel.h b/modules/gui/macosx/VLCPlaylistModel.h
> new file mode 100644
> index 0000000000..d5697739e0
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistModel.h
> @@ -0,0 +1,42 @@
> +/*****************************************************************************
> + * VLCPlaylistModel.h: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> + at class VLCPlaylistController;
> + at class VLCPlaylistItem;
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistModel : NSObject
> +
> + at property (readwrite, assign) VLCPlaylistController *playlistController;
> + at property (readonly) size_t numberOfPlaylistItems;
> +
> +- (VLCPlaylistItem *)playlistItemAtIndex:(NSInteger)index;
> +- (void)addItem:(vlc_playlist_item_t *)item atIndex:(size_t)index;
> +- (void)removeItemAtIndex:(size_t)index;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistModel.m b/modules/gui/macosx/VLCPlaylistModel.m
> new file mode 100644
> index 0000000000..795f691e15
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistModel.m
> @@ -0,0 +1,72 @@
> +/*****************************************************************************
> + * VLCPlaylistModel.m: MacOS X interface module
> + *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#import "VLCPlaylistModel.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistItem.h"
> +#import <vlc_common.h>
> +
> + at interface VLCPlaylistModel ()
> +{
> +    NSMutableArray *_playlistArray;
> +}
> + at end
> +
> + at implementation VLCPlaylistModel
> +
> +- (instancetype)init
> +{
> +    self = [super init];
> +    if (self) {
> +        _playlistArray = [[NSMutableArray alloc] init];
> +    }
> +    return self;
> +}
> +
> +- (size_t)numberOfPlaylistItems
> +{
> +    size_t ret = 0;
> +
> +    vlc_playlist_t *p_playlist = self.playlistController.p_playlist;
> +
> +    ret = vlc_playlist_Count(p_playlist);
> +
> +    return ret;
> +}
> +
> +- (VLCPlaylistItem *)playlistItemAtIndex:(NSInteger)index
> +{
> +    return _playlistArray[index];
> +}
> +
> +- (void)addItem:(vlc_playlist_item_t *)item atIndex:(size_t)index
> +{
> +    VLCPlaylistItem *playlistItem = [[VLCPlaylistItem alloc] initWithPlaylistItem:item];
> +    [_playlistArray insertObject:playlistItem atIndex:index];
> +}
> +
> +- (void)removeItemAtIndex:(size_t)index
> +{
> +    [_playlistArray removeObjectAtIndex:index];
> +}
> +
> + at end
> 
> 
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits




More information about the vlc-devel mailing list