vlc | branch: master | Felix Paul Kühne <[email protected]> | 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 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "../librarywindow/[email protected]"; sourceTree = "<group>"; }; 7D0F64092202058700FDB91F /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "../librarywindow/[email protected]"; 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 -@interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate> - -@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 -@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]); -} - -@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; +@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; +@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 + +@class VLCPlaylistModel; +@class VLCPlaylistDataSource; + +@interface VLCPlaylistController : NSObject + +@property (readonly) vlc_playlist_t *p_playlist; +@property (readonly) VLCPlaylistModel *playlistModel; +@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; + +@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> + +@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; + +@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); +} + +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 + +@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"]; + 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]); + + 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; +} + +@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> + +@class VLCPlaylistController; + +NS_ASSUME_NONNULL_BEGIN + +@interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate> + +@property (readwrite, assign, nonatomic) VLCPlaylistController *playlistController; +@property (readwrite, assign) NSTableView *tableView; + +- (void)playlistUpdated; + +@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"; + +@interface VLCPlaylistDataSource () +{ + VLCPlaylistModel *_playlistModel; +} +@end + +@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]; +} + +@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 + +@interface VLCPlaylistItem : NSObject + +@property (readwrite, assign) input_item_t *inputItem; +@property (readwrite, retain) NSString *title; +@property (readwrite, assign) vlc_tick_t duration; + +@property (readwrite, retain) NSString *artistName; +@property (readwrite, retain) NSString *albumName; +@property (readwrite, retain) NSString *artworkURLString; + +- (instancetype)initWithPlaylistItem:(vlc_playlist_item_t *)p_item; + +@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> + +@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]; +} + +@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> + +@class VLCPlaylistController; +@class VLCPlaylistItem; + +NS_ASSUME_NONNULL_BEGIN + +@interface VLCPlaylistModel : NSObject + +@property (readwrite, assign) VLCPlaylistController *playlistController; +@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; + +@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> + +@interface VLCPlaylistModel () +{ + NSMutableArray *_playlistArray; +} +@end + +@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]; +} + +@end _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
