diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj index 36168f2fcc56a96a93d9726ab1c9fdec016feea8..2cacc3b0030cf1ce1cc73ae6974a5f97291919d7 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 928d918f0c3cead67f901b9aedb112d048b576a2..8d901aeec0b7d7af44f41ee780fe67ae038afd86 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 4038c3508c7062b14a766dec8f97e7e1723f1abf..30e1dc0d5cf89a89a4f7b72cead19a8423f8ece9 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 c431bf1dac6ed8bccd3a62d8057d5da1a2c35f51..0843758ef2796027e6295c13f9d1c71b25872d5f 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 0000000000000000000000000000000000000000..f7e3b02adf113318967da6521a57465e5365f625 --- /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 + +@class VLCInputNode; +@class VLCMediaSource; + +@interface VLCMediaSourceDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate> + +@property (readwrite, retain) VLCMediaSource *displayedMediaSource; +@property (readwrite, retain, nonatomic) VLCInputNode *nodeToDisplay; +@property (readwrite, assign) NSCollectionView *collectionView; +@property (readwrite) NSPathControl *pathControl; + +@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 0000000000000000000000000000000000000000..329f7977fe607f9c505acf37cba801ebf82ac59d --- /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" + +@interface VLCMediaSourceDataSource() +{ + VLCInputItem *_childRootInput; + VLCMediaSourceDataSource *_childDataSource; +} +@end + +@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); + } +} + +@end diff --git a/po/POTFILES.in b/po/POTFILES.in index 6ac746554492b52e320f413d938da029c1b85599..182c885c6b2f85a1d1f789bc852d952f13bf4027 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