[vlc-commits] macosx: implement media source tree navigation and playback

Felix Paul Kühne git at videolan.org
Sun Jun 30 13:26:41 CEST 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Sun Jun 30 13:20:29 2019 +0200| [26770609541412e04235fecf4e99f24b0a3d1f1a] | committer: Felix Paul Kühne

macosx: implement media source tree navigation and playback

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

 .../package/macosx/VLC.xcodeproj/project.pbxproj   |   6 ++
 modules/gui/macosx/Makefile.am                     |   2 +
 modules/gui/macosx/UI/VLCLibraryWindow.xib         |   3 +-
 .../media-source/VLCMediaSourceBaseDataSource.m    |  41 ++++++++-
 .../macosx/media-source/VLCMediaSourceDataSource.h |  39 ++++++++
 .../macosx/media-source/VLCMediaSourceDataSource.m | 100 +++++++++++++++++++++
 po/POTFILES.in                                     |   2 +
 7 files changed, 189 insertions(+), 4 deletions(-)

diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
index 36168f2fcc..2cacc3b003 100644
--- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
+++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
@@ -106,6 +106,7 @@
 		7D1BF28D22A192000027C50F /* VLCPlaylistSortingMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1BF28C22A192000027C50F /* VLCPlaylistSortingMenuController.m */; };
 		7D20081A2289835C002679DF /* VLCTrackingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2008192289835C002679DF /* VLCTrackingView.m */; };
 		7D22A8F422BC14F80063ECD2 /* VLCLibrarySortingMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D22A8F322BC14F80063ECD2 /* VLCLibrarySortingMenuController.m */; };
+		7D2554C222C8A39300F2D9C2 /* VLCMediaSourceDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2554C122C8A39300F2D9C2 /* VLCMediaSourceDataSource.m */; };
 		7D28E6362275B4820098D30E /* NSColor+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D28E6352275B4820098D30E /* NSColor+VLCAdditions.m */; };
 		7D28E6392275B7340098D30E /* NSFont+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D28E6382275B7340098D30E /* NSFont+VLCAdditions.m */; };
 		7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2E0ED920CD204D0033A221 /* VLCWindow.m */; };
@@ -460,6 +461,8 @@
 		7D2008192289835C002679DF /* VLCTrackingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCTrackingView.m; sourceTree = "<group>"; };
 		7D22A8F222BC14F80063ECD2 /* VLCLibrarySortingMenuController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibrarySortingMenuController.h; sourceTree = "<group>"; };
 		7D22A8F322BC14F80063ECD2 /* VLCLibrarySortingMenuController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibrarySortingMenuController.m; sourceTree = "<group>"; };
+		7D2554C022C8A39300F2D9C2 /* VLCMediaSourceDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCMediaSourceDataSource.h; sourceTree = "<group>"; };
+		7D2554C122C8A39300F2D9C2 /* VLCMediaSourceDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCMediaSourceDataSource.m; sourceTree = "<group>"; };
 		7D28E6342275B4820098D30E /* NSColor+VLCAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSColor+VLCAdditions.h"; sourceTree = "<group>"; };
 		7D28E6352275B4820098D30E /* NSColor+VLCAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSColor+VLCAdditions.m"; sourceTree = "<group>"; };
 		7D28E6372275B7340098D30E /* NSFont+VLCAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+VLCAdditions.h"; sourceTree = "<group>"; };
@@ -1418,6 +1421,8 @@
 				7DFBDCBD226CED7200B700A5 /* VLCMediaSource.m */,
 				7DFBDCC2226E445500B700A5 /* VLCMediaSourceBaseDataSource.h */,
 				7DFBDCC3226E445500B700A5 /* VLCMediaSourceBaseDataSource.m */,
+				7D2554C022C8A39300F2D9C2 /* VLCMediaSourceDataSource.h */,
+				7D2554C122C8A39300F2D9C2 /* VLCMediaSourceDataSource.m */,
 				7DF14FBA2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.h */,
 				7DF14FBB2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.m */,
 			);
@@ -1721,6 +1726,7 @@
 				1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */,
 				7D460B0C229EB4C700097948 /* VLCDragDropView.m in Sources */,
 				7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */,
+				7D2554C222C8A39300F2D9C2 /* VLCMediaSourceDataSource.m in Sources */,
 				7DE2F0442282C84A0040DD0A /* VLCLibraryAudioDataSource.m in Sources */,
 				7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */,
 				1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,
diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
index 928d918f0c..8d901aeec0 100644
--- a/modules/gui/macosx/Makefile.am
+++ b/modules/gui/macosx/Makefile.am
@@ -93,6 +93,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/media-source/VLCMediaSourceBaseDataSource.m \
 	gui/macosx/media-source/VLCMediaSourceCollectionViewItem.h \
 	gui/macosx/media-source/VLCMediaSourceCollectionViewItem.m \
+	gui/macosx/media-source/VLCMediaSourceDataSource.h \
+	gui/macosx/media-source/VLCMediaSourceDataSource.m \
 	gui/macosx/media-source/VLCMediaSourceProvider.h \
 	gui/macosx/media-source/VLCMediaSourceProvider.m \
 	gui/macosx/menus/VLCMainMenu.h \
diff --git a/modules/gui/macosx/UI/VLCLibraryWindow.xib b/modules/gui/macosx/UI/VLCLibraryWindow.xib
index 4038c3508c..30e1dc0d5c 100644
--- a/modules/gui/macosx/UI/VLCLibraryWindow.xib
+++ b/modules/gui/macosx/UI/VLCLibraryWindow.xib
@@ -523,6 +523,7 @@
                 <outlet property="libraryTargetView" destination="iSp-bV-w6B" id="a94-ux-wUc"/>
                 <outlet property="mainSplitView" destination="u8g-jy-S4e" id="lI5-wR-kef"/>
                 <outlet property="mediaSourceCollectionView" destination="r7v-GI-W1U" id="3JJ-GU-o5o"/>
+                <outlet property="mediaSourceHomeButton" destination="jfA-Vr-sQc" id="oLM-NF-rqe"/>
                 <outlet property="mediaSourcePathControl" destination="Rjk-Q6-FYy" id="G63-NM-Ekn"/>
                 <outlet property="mediaSourceView" destination="eHd-Q9-F8D" id="gfU-Jp-eFr"/>
                 <outlet property="openMediaButton" destination="SWh-4E-Qtf" id="sIZ-xo-GLA"/>
@@ -878,7 +879,7 @@
                         <rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <collectionView id="r7v-GI-W1U">
+                            <collectionView selectable="YES" id="r7v-GI-W1U">
                                 <rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
                                 <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                                 <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="v0C-1b-7Ss">
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
index c431bf1dac..0843758ef2 100644
--- a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
+++ b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
@@ -25,6 +25,7 @@
 #import "media-source/VLCMediaSourceProvider.h"
 #import "media-source/VLCMediaSource.h"
 #import "media-source/VLCMediaSourceCollectionViewItem.h"
+#import "media-source/VLCMediaSourceDataSource.h"
 
 #import "main/VLCMain.h"
 #import "library/VLCInputItem.h"
@@ -33,6 +34,7 @@
 @interface VLCMediaSourceBaseDataSource ()
 {
     NSArray *_mediaSources;
+    VLCMediaSourceDataSource *_childDataSource;
 }
 @end
 
@@ -67,6 +69,10 @@
 
 - (void)loadMediaSources
 {
+    self.homeButton.action = @selector(homeButtonAction:);
+    self.homeButton.target = self;
+    self.pathControl.URL = nil;
+
     NSArray *mediaSourcesOnLAN = [VLCMediaSourceProvider listOfMediaSourcesForCategory:SD_CAT_LAN];
     NSUInteger count = mediaSourcesOnLAN.count;
     if (count > 0) {
@@ -110,7 +116,32 @@
 
 - (void)collectionView:(NSCollectionView *)collectionView didSelectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths
 {
-    NSLog(@"media source selection changed: %@", indexPaths);
+    NSIndexPath *indexPath = indexPaths.anyObject;
+    if (!indexPath) {
+        return;
+    }
+    VLCMediaSource *mediaSource = _mediaSources[indexPath.section];
+    VLCInputNode *rootNode = mediaSource.rootNode;
+    NSArray *nodeChildren = rootNode.children;
+    VLCInputNode *childNode = nodeChildren[indexPath.item];
+    VLCInputItem *childRootInput = childNode.inputItem;
+    self.pathControl.URL = [NSURL URLWithString:[NSString stringWithFormat:@"vlc://%@", [childRootInput.name stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
+    _childDataSource = [[VLCMediaSourceDataSource alloc] init];
+    _childDataSource.displayedMediaSource = mediaSource;
+    _childDataSource.nodeToDisplay = childNode;
+    _childDataSource.collectionView = self.collectionView;
+    _childDataSource.pathControl = self.pathControl;
+    self.collectionView.dataSource = _childDataSource;
+    self.collectionView.delegate = _childDataSource;
+    [self.collectionView reloadData];
+}
+
+- (IBAction)homeButtonAction:(id)sender
+{
+    self.collectionView.dataSource = self;
+    self.collectionView.delegate = self;
+    [self.collectionView reloadData];
+    _childDataSource = nil;
 }
 
 #pragma mark - VLCMediaSource Delegation
@@ -135,8 +166,12 @@
 
 - (void)reloadDataForNotification:(NSNotification *)aNotification
 {
-    NSInteger index = [_mediaSources indexOfObject:aNotification.object];
-    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
+    if (self.collectionView.dataSource == self) {
+        NSInteger index = [_mediaSources indexOfObject:aNotification.object];
+        [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
+    } else {
+        [self.collectionView reloadData];
+    }
 }
 
 @end
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
new file mode 100644
index 0000000000..f7e3b02adf
--- /dev/null
+++ b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * VLCMediaSourceDataSource.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>
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at class VLCInputNode;
+ at class VLCMediaSource;
+
+ at interface VLCMediaSourceDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate>
+
+ at property (readwrite, retain) VLCMediaSource *displayedMediaSource;
+ at property (readwrite, retain, nonatomic) VLCInputNode *nodeToDisplay;
+ at property (readwrite, assign) NSCollectionView *collectionView;
+ at property (readwrite) NSPathControl *pathControl;
+
+ at end
+
+NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
new file mode 100644
index 0000000000..329f7977fe
--- /dev/null
+++ b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * VLCMediaSourceDataSource.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 "VLCMediaSourceDataSource.h"
+
+#import "library/VLCInputItem.h"
+#import "media-source/VLCMediaSourceCollectionViewItem.h"
+#import "media-source/VLCMediaSource.h"
+#import "main/VLCMain.h"
+#import "playlist/VLCPlaylistController.h"
+
+ at interface VLCMediaSourceDataSource()
+{
+    VLCInputItem *_childRootInput;
+    VLCMediaSourceDataSource *_childDataSource;
+}
+ at end
+
+ at implementation VLCMediaSourceDataSource
+
+- (void)setNodeToDisplay:(VLCInputNode *)nodeToDisplay
+{
+    _nodeToDisplay = nodeToDisplay;
+
+    _childRootInput = _nodeToDisplay.inputItem;
+    [self.displayedMediaSource preparseInputItemWithinTree:_childRootInput];
+}
+
+- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
+{
+    return 1;
+}
+
+- (NSInteger)collectionView:(NSCollectionView *)collectionView
+     numberOfItemsInSection:(NSInteger)section
+{
+    if (_nodeToDisplay) {
+        return _nodeToDisplay.numberOfChildren;
+    }
+
+    return 0;
+}
+
+- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
+     itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
+{
+    VLCMediaSourceCollectionViewItem *viewItem = [collectionView makeItemWithIdentifier:VLCMediaSourceCellIdentifier forIndexPath:indexPath];
+
+    VLCInputNode *rootNode = _nodeToDisplay;
+    NSArray *nodeChildren = rootNode.children;
+    VLCInputNode *childNode = nodeChildren[indexPath.item];
+    VLCInputItem *childRootInput = childNode.inputItem;
+    viewItem.titleTextField.stringValue = childRootInput.name;
+
+    return viewItem;
+}
+
+- (void)collectionView:(NSCollectionView *)collectionView didSelectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths
+{
+    NSIndexPath *indexPath = indexPaths.anyObject;
+    if (!indexPath) {
+        return;
+    }
+    VLCInputNode *rootNode = self.nodeToDisplay;
+    NSArray *nodeChildren = rootNode.children;
+    VLCInputNode *childNode = nodeChildren[indexPath.item];
+    VLCInputItem *childRootInput = childNode.inputItem;
+
+    if (childRootInput.inputType == ITEM_TYPE_DIRECTORY) {
+        self.pathControl.URL = [NSURL URLWithString:[self.pathControl.URL.path stringByAppendingPathComponent:[childRootInput.name stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
+        self.nodeToDisplay = childNode;
+        [self.collectionView reloadData];
+    } else if (childRootInput.inputType == ITEM_TYPE_FILE) {
+        [[[VLCMain sharedInstance] playlistController] addInputItem:childRootInput.vlcInputItem atPosition:-1 startPlayback:YES];
+    } else {
+        NSAssert(1, @"unhandled input type when browsing media source hierarchy %i", childRootInput.inputType);
+        msg_Warn(getIntf(), "unhandled input type when browsing media source hierarchy %i", childRootInput.inputType);
+    }
+}
+
+ at end
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6ac7465544..182c885c6b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -498,6 +498,8 @@ modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.h
 modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
 modules/gui/macosx/media-source/VLCMediaSourceCollectionViewItem.h
 modules/gui/macosx/media-source/VLCMediaSourceCollectionViewItem.m
+modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
+modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
 modules/gui/macosx/media-source/VLCMediaSourceProvider.h
 modules/gui/macosx/media-source/VLCMediaSourceProvider.m
 modules/gui/macosx/menus/VLCMainMenu.h



More information about the vlc-commits mailing list