[vlc-commits] macosx: add alternative audio library representation based on a collection view

Felix Paul Kühne git at videolan.org
Wed May 15 20:01:49 CEST 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Wed May 15 20:00:31 2019 +0200| [4c47033e0d0329cc18f3fd5c64284e8141f52cbe] | committer: Felix Paul Kühne

macosx: add alternative audio library representation based on a collection view

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

 .../package/macosx/VLC.xcodeproj/project.pbxproj   |   6 +
 modules/gui/macosx/Makefile.am                     |   2 +
 modules/gui/macosx/UI/VLCLibraryWindow.xib         |  56 +++++++
 .../VLCLibraryAlternativeAudioViewController.h     |  40 +++++
 .../VLCLibraryAlternativeAudioViewController.m     | 170 +++++++++++++++++++++
 .../gui/macosx/library/VLCLibraryAudioDataSource.m |   2 +-
 modules/gui/macosx/library/VLCLibraryModel.h       |   2 +
 modules/gui/macosx/library/VLCLibraryModel.m       |   6 +
 modules/gui/macosx/library/VLCLibraryWindow.h      |   3 +
 modules/gui/macosx/library/VLCLibraryWindow.m      |  45 +++++-
 po/POTFILES.in                                     |   2 +
 11 files changed, 330 insertions(+), 4 deletions(-)

diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
index 79e27dcbaf..1f6a9b0930 100644
--- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
+++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
@@ -156,6 +156,7 @@
 		7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */; };
 		7DE2F0442282C84A0040DD0A /* VLCLibraryAudioDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */; };
 		7DE2F0472282D5D10040DD0A /* VLCLibraryTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE2F0462282D5D10040DD0A /* VLCLibraryTableCellView.m */; };
+		7DE7E72F228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE7E72E228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.m */; };
 		7DE82E7922843781002D341A /* VLCLibraryAlbumTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */; };
 		7DE9C7DD220728420089108F /* VLCPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE9C7DC220728420089108F /* VLCPlayerController.m */; };
 		7DF14FBD2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF14FBB2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.m */; };
@@ -544,6 +545,8 @@
 		7DE2F0452282D5D10040DD0A /* VLCLibraryTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryTableCellView.h; sourceTree = "<group>"; };
 		7DE2F0462282D5D10040DD0A /* VLCLibraryTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryTableCellView.m; sourceTree = "<group>"; };
 		7DE2F0482282D7980040DD0A /* VLCLibraryTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCLibraryTableCellView.xib; sourceTree = "<group>"; };
+		7DE7E72D228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAlternativeAudioViewController.h; sourceTree = "<group>"; };
+		7DE7E72E228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAlternativeAudioViewController.m; sourceTree = "<group>"; };
 		7DE82E7722843781002D341A /* VLCLibraryAlbumTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAlbumTableCellView.h; sourceTree = "<group>"; };
 		7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAlbumTableCellView.m; sourceTree = "<group>"; };
 		7DE82E7A228437AA002D341A /* VLCLibraryAlbumTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCLibraryAlbumTableCellView.xib; sourceTree = "<group>"; };
@@ -1003,6 +1006,8 @@
 				7DBB7638227F3FBC002649E1 /* VLCLibraryCollectionViewSupplementaryElementView.m */,
 				7D713D302201AE350042BEB7 /* VLCLibraryWindow.h */,
 				7D713D312201AE350042BEB7 /* VLCLibraryWindow.m */,
+				7DE7E72D228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.h */,
+				7DE7E72E228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.m */,
 				7DFBDCA62269E77400B700A5 /* VLCLibraryController.h */,
 				7DFBDCA72269E77500B700A5 /* VLCLibraryController.m */,
 				7DFBDCA92269E77F00B700A5 /* VLCLibraryModel.h */,
@@ -1731,6 +1736,7 @@
 				1C3113D31E508C6900D4DD76 /* VLCResumeDialogController.m in Sources */,
 				7D2FFA40227B8A5B0085D649 /* VLCLinearProgressIndicator.m in Sources */,
 				7DFBDCB1226A518400B700A5 /* VLCLibraryMenuController.m in Sources */,
+				7DE7E72F228C795B00D6EA38 /* VLCLibraryAlternativeAudioViewController.m in Sources */,
 				1C3113D51E508C6900D4DD76 /* VLCTextfieldPanelController.m in Sources */,
 				7DFBDCAE2269ED0C00B700A5 /* VLCLibraryVideoDataSource.m in Sources */,
 				1C3113D71E508C6900D4DD76 /* VLCPopupPanelController.m in Sources */,
diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
index 183c104dd4..e4ed2335dd 100644
--- a/modules/gui/macosx/Makefile.am
+++ b/modules/gui/macosx/Makefile.am
@@ -54,6 +54,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/library/VLCInputItem.m \
 	gui/macosx/library/VLCLibraryAlbumTableCellView.h \
 	gui/macosx/library/VLCLibraryAlbumTableCellView.m \
+	gui/macosx/library/VLCLibraryAlternativeAudioViewController.h \
+	gui/macosx/library/VLCLibraryAlternativeAudioViewController.m \
 	gui/macosx/library/VLCLibraryAudioDataSource.h \
 	gui/macosx/library/VLCLibraryAudioDataSource.m \
 	gui/macosx/library/VLCLibraryCollectionViewItem.h \
diff --git a/modules/gui/macosx/UI/VLCLibraryWindow.xib b/modules/gui/macosx/UI/VLCLibraryWindow.xib
index b29b8c023f..ce75a54a5b 100644
--- a/modules/gui/macosx/UI/VLCLibraryWindow.xib
+++ b/modules/gui/macosx/UI/VLCLibraryWindow.xib
@@ -312,6 +312,9 @@
                 </constraints>
             </view>
             <connections>
+                <outlet property="alternativeAudioCollectionView" destination="QAt-jP-zE7" id="269-UN-dfM"/>
+                <outlet property="alternativeAudioSegmentedControl" destination="nzi-H5-fyv" id="AmI-6s-ALm"/>
+                <outlet property="alternativeAudioView" destination="k7f-ic-LrF" id="8Cp-d2-3UJ"/>
                 <outlet property="audioCategorySelectionTableView" destination="dNP-8u-8iI" id="KiD-PX-T2p"/>
                 <outlet property="audioCollectionSelectionTableView" destination="LNt-ot-2wU" id="eJS-WZ-Ri7"/>
                 <outlet property="audioGroupSelectionTableView" destination="4ll-T2-J16" id="bjS-a8-ePC"/>
@@ -646,6 +649,59 @@
             </holdingPriorities>
             <point key="canvasLocation" x="109" y="-224.5"/>
         </splitView>
+        <customView id="k7f-ic-LrF">
+            <rect key="frame" x="0.0" y="0.0" width="500" height="302"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nzi-H5-fyv">
+                    <rect key="frame" x="10" y="280" width="52" height="23"/>
+                    <segmentedCell key="cell" borderStyle="border" alignment="left" style="smallSquare" trackingMode="selectOne" id="ic1-QN-Oy2">
+                        <font key="font" metaFont="system"/>
+                        <segments>
+                            <segment/>
+                            <segment selected="YES" tag="1"/>
+                            <segment>
+                                <nil key="label"/>
+                            </segment>
+                        </segments>
+                    </segmentedCell>
+                </segmentedControl>
+                <scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AYf-gS-P66">
+                    <rect key="frame" x="0.0" y="0.0" width="500" height="271"/>
+                    <clipView key="contentView" id="2oa-WL-dxA">
+                        <rect key="frame" x="0.0" y="0.0" width="500" height="271"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView id="QAt-jP-zE7">
+                                <rect key="frame" x="0.0" y="0.0" width="500" height="158"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="oKT-Ic-UdV">
+                                    <size key="itemSize" width="50" height="50"/>
+                                </collectionViewFlowLayout>
+                                <color key="primaryBackgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </collectionView>
+                        </subviews>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Wb8-r8-xfF">
+                        <rect key="frame" x="1" y="144" width="233" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="Lae-xQ-39f">
+                        <rect key="frame" x="234" y="1" width="15" height="143"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="nzi-H5-fyv" firstAttribute="top" secondItem="k7f-ic-LrF" secondAttribute="top" id="Hub-0d-koP"/>
+                <constraint firstItem="AYf-gS-P66" firstAttribute="top" secondItem="nzi-H5-fyv" secondAttribute="bottom" constant="10" id="IpM-PQ-9Lk"/>
+                <constraint firstAttribute="trailing" secondItem="AYf-gS-P66" secondAttribute="trailing" id="KEG-os-Mk9"/>
+                <constraint firstAttribute="bottom" secondItem="AYf-gS-P66" secondAttribute="bottom" id="Wkc-LW-FiO"/>
+                <constraint firstItem="nzi-H5-fyv" firstAttribute="leading" secondItem="k7f-ic-LrF" secondAttribute="leading" constant="10" id="thF-Jr-QPO"/>
+                <constraint firstItem="AYf-gS-P66" firstAttribute="leading" secondItem="k7f-ic-LrF" secondAttribute="leading" id="tqb-gA-coA"/>
+            </constraints>
+            <point key="canvasLocation" x="247" y="771"/>
+        </customView>
     </objects>
     <resources>
         <image name="backward-3btns" width="29" height="23"/>
diff --git a/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.h b/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.h
new file mode 100644
index 0000000000..e0e03db942
--- /dev/null
+++ b/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * VLCLibraryAlternativeAudioViewController.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 VLCLibraryModel;
+
+ at interface VLCLibraryAlternativeAudioViewController : NSObject
+
+ at property (readwrite, assign) NSCollectionView *collectionView;
+ at property (readwrite, assign) NSSegmentedControl *segmentedControl;
+ at property (readwrite, assign) VLCLibraryModel *libraryModel;
+
+- (void)setupAppearance;
+- (void)reloadAppearance;
+
+ at end
+
+NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.m b/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.m
new file mode 100644
index 0000000000..d6ab05ffa4
--- /dev/null
+++ b/modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.m
@@ -0,0 +1,170 @@
+/*****************************************************************************
+ * VLCLibraryAlternativeAudioViewController.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 "VLCLibraryAlternativeAudioViewController.h"
+
+#import "library/VLCLibraryModel.h"
+#import "library/VLCLibraryCollectionViewItem.h"
+#import "library/VLCLibraryDataTypes.h"
+
+#import "extensions/NSString+Helpers.h"
+#import "views/VLCImageView.h"
+
+ at interface VLCLibraryAlternativeAudioViewController () <NSCollectionViewDelegate, NSCollectionViewDataSource>
+{
+    NSArray *_displayedCollection;
+    enum vlc_ml_parent_type _currentParentType;
+}
+ at end
+
+ at implementation VLCLibraryAlternativeAudioViewController
+
+- (void)setupAppearance
+{
+    NSArray *availableCollections = [VLCLibraryModel availableAudioCollections];
+    NSUInteger availableCollectionsCount = availableCollections.count;
+    self.segmentedControl.segmentCount = availableCollectionsCount;
+    for (NSUInteger x = 0; x < availableCollectionsCount; x++) {
+        [self.segmentedControl setLabel:availableCollections[x] forSegment:x];
+    }
+    [self.segmentedControl setTarget:self];
+    [self.segmentedControl setAction:@selector(segmentedControlAction:)];
+
+    _collectionView.dataSource = self;
+    _collectionView.delegate = self;
+    [_collectionView registerClass:[VLCLibraryCollectionViewItem class] forItemWithIdentifier:VLCLibraryCellIdentifier];
+    NSCollectionViewFlowLayout *flowLayout = _collectionView.collectionViewLayout;
+    flowLayout.itemSize = CGSizeMake(214., 260.);
+    flowLayout.sectionInset = NSEdgeInsetsMake(20., 20., 20., 20.);
+    flowLayout.minimumLineSpacing = 20.;
+    flowLayout.minimumInteritemSpacing = 20.;
+
+    [self segmentedControlAction:nil];
+}
+
+- (void)reloadAppearance
+{
+    [self.collectionView reloadData];
+}
+
+- (IBAction)segmentedControlAction:(id)sender
+{
+    // FIXME: this relies on knowledge internal to VLCLibraryModel
+    switch (_segmentedControl.selectedSegment) {
+        case 0:
+            _displayedCollection = [self.libraryModel listOfArtists];
+            _currentParentType = VLC_ML_PARENT_ARTIST;
+            break;
+        case 1:
+            _displayedCollection = [self.libraryModel listOfAlbums];
+            _currentParentType = VLC_ML_PARENT_ALBUM;
+            break;
+        case 2:
+            _displayedCollection = [self.libraryModel listOfAudioMedia];
+            _currentParentType = VLC_ML_PARENT_UNKNOWN;
+            break;
+        case 3:
+            _displayedCollection = [self.libraryModel listOfGenres];
+            _currentParentType = VLC_ML_PARENT_GENRE;
+            break;
+
+        default:
+            NSAssert(1, @"reached the unreachable");
+            break;
+    }
+    [self.collectionView reloadData];
+}
+
+- (NSInteger)collectionView:(NSCollectionView *)collectionView
+     numberOfItemsInSection:(NSInteger)section
+{
+    return _displayedCollection.count;
+}
+
+- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
+{
+    return 1;
+}
+
+- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
+     itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
+{
+    VLCLibraryCollectionViewItem *viewItem = [collectionView makeItemWithIdentifier:VLCLibraryCellIdentifier forIndexPath:indexPath];
+    switch (_currentParentType) {
+        case VLC_ML_PARENT_ARTIST:
+        {
+            VLCMediaLibraryArtist *artist = _displayedCollection[indexPath.item];
+            viewItem.mediaTitleTextField.stringValue = artist.name;
+            viewItem.durationTextField.stringValue = [NSString stringWithFormat:_NS("%u albums, %u songs"), artist.numberOfAlbums, artist.numberOfTracks];
+            NSImage *image;
+            if (artist.artworkMRL.length > 0) {
+                image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:artist.artworkMRL]];
+            }
+            if (!image) {
+                image = [NSImage imageNamed: @"noart.png"];
+            }
+            viewItem.mediaImageView.image = image;
+            break;
+        }
+        case VLC_ML_PARENT_ALBUM:
+        {
+            VLCMediaLibraryAlbum *album = _displayedCollection[indexPath.item];
+            viewItem.mediaTitleTextField.stringValue = album.title;
+            viewItem.durationTextField.stringValue = [NSString stringWithFormat:_NS("%u songs"), album.numberOfTracks];
+            NSImage *image;
+            if (album.artworkMRL.length > 0) {
+                image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:album.artworkMRL]];
+            }
+            if (!image) {
+                image = [NSImage imageNamed: @"noart.png"];
+            }
+            viewItem.mediaImageView.image = image;
+            break;
+        }
+        case VLC_ML_PARENT_UNKNOWN:
+        {
+            VLCMediaLibraryMediaItem *mediaItem = _displayedCollection[indexPath.item];
+            viewItem.representedMediaItem = mediaItem;
+            break;
+        }
+        case VLC_ML_PARENT_GENRE:
+        {
+            VLCMediaLibraryGenre *genre = _displayedCollection[indexPath.item];
+            viewItem.mediaTitleTextField.stringValue = genre.name;
+            viewItem.durationTextField.stringValue = [NSString stringWithFormat:_NS("%u items"), genre.numberOfTracks];
+            viewItem.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
+        }
+
+        default:
+            break;
+    }
+
+    return viewItem;
+}
+
+- (void)collectionView:(NSCollectionView *)collectionView didSelectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths
+{
+    NSLog(@"library selection changed: %@", indexPaths);
+}
+
+
+ at end
diff --git a/modules/gui/macosx/library/VLCLibraryAudioDataSource.m b/modules/gui/macosx/library/VLCLibraryAudioDataSource.m
index c251447c67..c0713eb6c4 100644
--- a/modules/gui/macosx/library/VLCLibraryAudioDataSource.m
+++ b/modules/gui/macosx/library/VLCLibraryAudioDataSource.m
@@ -44,7 +44,7 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
 {
     self = [super init];
     if (self) {
-        _availableCollectionsArray = @[_NS("Artists"), _NS("Albums"), _NS("Songs"), _NS("Genres")];
+        _availableCollectionsArray = [VLCLibraryModel availableAudioCollections];
     }
     return self;
 }
diff --git a/modules/gui/macosx/library/VLCLibraryModel.h b/modules/gui/macosx/library/VLCLibraryModel.h
index 1f2f3b6d72..aa58e17fd9 100644
--- a/modules/gui/macosx/library/VLCLibraryModel.h
+++ b/modules/gui/macosx/library/VLCLibraryModel.h
@@ -46,6 +46,8 @@ extern NSString *VLCLibraryModelMediaItemUpdated;
 
 @interface VLCLibraryModel : NSObject
 
++ (NSArray *)availableAudioCollections;
+
 - (instancetype)initWithLibrary:(vlc_medialibrary_t *)library;
 
 @property (readwrite) VLCLibraryMode libraryMode;
diff --git a/modules/gui/macosx/library/VLCLibraryModel.m b/modules/gui/macosx/library/VLCLibraryModel.m
index bbd79b5c34..2417ef8576 100644
--- a/modules/gui/macosx/library/VLCLibraryModel.m
+++ b/modules/gui/macosx/library/VLCLibraryModel.m
@@ -24,6 +24,7 @@
 
 #import "main/VLCMain.h"
 #import "library/VLCLibraryDataTypes.h"
+#import "extensions/NSString+Helpers.h"
 
 NSString *VLCLibraryModelAudioMediaListUpdated = @"VLCLibraryModelAudioMediaListUpdated";
 NSString *VLCLibraryModelArtistListUpdated = @"VLCLibraryModelArtistListUpdated";
@@ -123,6 +124,11 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     [_defaultNotificationCenter removeObserver:self];
 }
 
++ (NSArray *)availableAudioCollections
+{
+    return @[_NS("Artists"), _NS("Albums"), _NS("Songs"), _NS("Genres")];
+}
+
 - (void)mediaItemWasUpdated:(VLCMediaLibraryMediaItem *)mediaItem
 {
     [_defaultNotificationCenter postNotificationName:VLCLibraryModelMediaItemUpdated object:mediaItem];
diff --git a/modules/gui/macosx/library/VLCLibraryWindow.h b/modules/gui/macosx/library/VLCLibraryWindow.h
index fa062a35a7..29b7f14505 100644
--- a/modules/gui/macosx/library/VLCLibraryWindow.h
+++ b/modules/gui/macosx/library/VLCLibraryWindow.h
@@ -51,6 +51,9 @@ NS_ASSUME_NONNULL_BEGIN
 @property (readwrite, weak) IBOutlet NSBox *clearPlaylistSeparator;
 @property (readwrite, weak) IBOutlet NSButton *repeatPlaylistButton;
 @property (readwrite, weak) IBOutlet NSButton *shufflePlaylistButton;
+ at property (readwrite, weak) IBOutlet NSView *alternativeAudioView;
+ at property (readwrite, weak) IBOutlet NSCollectionView *alternativeAudioCollectionView;
+ at property (readwrite, weak) IBOutlet NSSegmentedControl *alternativeAudioSegmentedControl;
 
 @property (readonly) BOOL nativeFullscreenMode;
 @property (readwrite) BOOL nonembedded;
diff --git a/modules/gui/macosx/library/VLCLibraryWindow.m b/modules/gui/macosx/library/VLCLibraryWindow.m
index 92f7ecee0c..5eabfbad89 100644
--- a/modules/gui/macosx/library/VLCLibraryWindow.m
+++ b/modules/gui/macosx/library/VLCLibraryWindow.m
@@ -36,6 +36,7 @@
 #import "library/VLCLibraryCollectionViewItem.h"
 #import "library/VLCLibraryModel.h"
 #import "library/VLCLibraryCollectionViewSupplementaryElementView.h"
+#import "library/VLCLibraryAlternativeAudioViewController.h"
 
 #import "media-source/VLCMediaSourceCollectionViewItem.h"
 #import "media-source/VLCMediaSourceDataSource.h"
@@ -58,6 +59,7 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
     VLCLibraryAudioDataSource *_libraryAudioDataSource;
     VLCLibraryGroupDataSource *_libraryAudioGroupDataSource;
     VLCMediaSourceDataSource *_mediaSourceDataSource;
+    VLCLibraryAlternativeAudioViewController *_alternativeAudioViewController;
 
     VLCPlaylistController *_playlistController;
 
@@ -119,13 +121,14 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
     _fspanel = [[VLCFSPanelController alloc] init];
     [_fspanel showWindow:self];
 
-    _segmentedTitleControl.segmentCount = 4;
+    _segmentedTitleControl.segmentCount = 5;
     [_segmentedTitleControl setTarget:self];
     [_segmentedTitleControl setAction:@selector(segmentedControlAction:)];
     [_segmentedTitleControl setLabel:_NS("Video") forSegment:0];
     [_segmentedTitleControl setLabel:_NS("Music") forSegment:1];
-    [_segmentedTitleControl setLabel:_NS("Local Network") forSegment:2];
-    [_segmentedTitleControl setLabel:_NS("Internet") forSegment:3];
+    [_segmentedTitleControl setLabel:_NS("Music") forSegment:2];
+    [_segmentedTitleControl setLabel:_NS("Local Network") forSegment:3];
+    [_segmentedTitleControl setLabel:_NS("Internet") forSegment:4];
     [_segmentedTitleControl sizeToFit];
     [_segmentedTitleControl setSelectedSegment:0];
 
@@ -185,6 +188,12 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
     self.clearPlaylistButton.attributedTitle = attributedTitle;
     [self updateColorsBasedOnAppearance];
 
+    _alternativeAudioViewController = [[VLCLibraryAlternativeAudioViewController alloc] init];
+    _alternativeAudioViewController.collectionView = self.alternativeAudioCollectionView;
+    _alternativeAudioViewController.segmentedControl = self.alternativeAudioSegmentedControl;
+    _alternativeAudioViewController.libraryModel = mainInstance.libraryController.libraryModel;
+    [_alternativeAudioViewController setupAppearance];
+
     [self segmentedControlAction:nil];
     [self repeatStateUpdated:nil];
     [self shuffleStateUpdated:nil];
@@ -286,6 +295,9 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
             if (_audioLibrarySplitView.superview != nil) {
                 [_audioLibrarySplitView removeFromSuperview];
             }
+            if (_alternativeAudioView.superview != nil) {
+                [_alternativeAudioView removeFromSuperview];
+            }
             if (_videoLibraryStackView.superview == nil) {
                 _videoLibraryStackView.translatesAutoresizingMaskIntoConstraints = NO;
                 [_libraryTargetView addSubview:_videoLibraryStackView];
@@ -305,6 +317,9 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
             if (_videoLibraryStackView.superview != nil) {
                 [_videoLibraryStackView removeFromSuperview];
             }
+            if (_alternativeAudioView.superview != nil) {
+                [_alternativeAudioView removeFromSuperview];
+            }
             if (_audioLibrarySplitView.superview == nil) {
                 _audioLibrarySplitView.translatesAutoresizingMaskIntoConstraints = NO;
                 [_libraryTargetView addSubview:_audioLibrarySplitView];
@@ -316,6 +331,27 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
             [_audioCollectionSelectionTableView reloadData];
             break;
 
+        case 2:
+            _libraryVideoDataSource.libraryModel.libraryMode = VLCLibraryModeAudio;
+            if (_mediaSourceScrollView.superview != nil) {
+                [_mediaSourceScrollView removeFromSuperview];
+            }
+            if (_videoLibraryStackView.superview != nil) {
+                [_videoLibraryStackView removeFromSuperview];
+            }
+            if (_audioLibrarySplitView.superview != nil) {
+                [_audioLibrarySplitView removeFromSuperview];
+            }
+            if (_alternativeAudioView.superview == nil) {
+                _alternativeAudioView.translatesAutoresizingMaskIntoConstraints = NO;
+                [_libraryTargetView addSubview:_alternativeAudioView];
+                NSDictionary *dict = NSDictionaryOfVariableBindings(_alternativeAudioView);
+                [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_alternativeAudioView(>=572.)]|" options:0 metrics:0 views:dict]];
+                [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_alternativeAudioView(>=444.)]|" options:0 metrics:0 views:dict]];
+            }
+            [_alternativeAudioViewController reloadAppearance];
+            break;
+
         default:
             if (_videoLibraryStackView.superview != nil) {
                 [_videoLibraryStackView removeFromSuperview];
@@ -323,6 +359,9 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
             if (_audioLibrarySplitView.superview != nil) {
                 [_audioLibrarySplitView removeFromSuperview];
             }
+            if (_alternativeAudioView.superview != nil) {
+                [_alternativeAudioView removeFromSuperview];
+            }
             if (_mediaSourceScrollView.superview == nil) {
                 _mediaSourceScrollView.translatesAutoresizingMaskIntoConstraints = NO;
                 [_libraryTargetView addSubview:_mediaSourceScrollView];
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5c6b2725b2..722fa705c8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -462,6 +462,8 @@ modules/gui/macosx/library/VLCInputItem.h
 modules/gui/macosx/library/VLCInputItem.m
 modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h
 modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m
+modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.h
+modules/gui/macosx/library/VLCLibraryAlternativeAudioViewController.m
 modules/gui/macosx/library/VLCLibraryAudioDataSource.h
 modules/gui/macosx/library/VLCLibraryAudioDataSource.m
 modules/gui/macosx/library/VLCLibraryCollectionViewItem.h



More information about the vlc-commits mailing list