[vlc-commits] [Git][videolan/vlc][master] 16 commits: macosx: Move all audio library related classes into audio-library folder

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Wed Dec 7 16:53:13 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
18d293bf by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Move all audio library related classes into audio-library folder

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
d63e8be8 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Ensure all VLCLibraryWindow properties are declared publically

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
6b07391c by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Move all audio view-related procedures to new VLCLibraryAudioViewController class, simplifying VLCLibraryWindow and VLCAudioDataSource

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
9b57fac0 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Add a VLCLibrarySongsTableView component

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
f30b5013 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Display new VLCLibrarySongsTableView when library in songs section and in list view mode

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b725288d by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Replace VLCLibrarySongsTableView class with table view implementation in VLCLibraryWindow XIB

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
c1cd6160 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Present audio library songs in songs table view

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
7b8c476d by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Add convenience constructors from ID for album and genre data types

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
eb498236 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Adjust audio library songs table view columns and their sizing

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
a542da94 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Enable playing song through songs table view via double-click

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
f03d5d52 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Fix bad initial state of audio data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
215fb680 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Display icon for currently playing song in library song table view

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
2b82f72c by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Retain selections across reloadData in the audio views

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
354ac7a5 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Enable right-click menu for library songs table view

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
f92ad102 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Fix references to video library files in Xcode project file

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
bd1222e8 by Claudio Cambra at 2022-12-07T16:40:27+00:00
macosx: Fix POTFILES.in for audio library changes

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -


26 changed files:

- extras/package/macosx/VLC.xcodeproj/project.pbxproj
- modules/gui/macosx/Makefile.am
- modules/gui/macosx/UI/VLCLibraryWindow.xib
- modules/gui/macosx/library/VLCLibraryCollectionViewFlowLayout.m
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/library/VLCLibraryNavigationStack.m
- modules/gui/macosx/library/VLCLibraryWindow.h
- modules/gui/macosx/library/VLCLibraryWindow.m
- modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h
- modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
- modules/gui/macosx/library/VLCLibraryAlbumTracksDataSource.h → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.h
- modules/gui/macosx/library/VLCLibraryAlbumTracksDataSource.m → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.m
- modules/gui/macosx/library/VLCLibraryAudioDataSource.h → modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h
- modules/gui/macosx/library/VLCLibraryAudioDataSource.m → modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.h
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.m
- modules/gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h
- modules/gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
- modules/gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h
- modules/gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m
- modules/gui/macosx/library/VLCLibrarySongTableCellView.h → modules/gui/macosx/library/audio-library/VLCLibrarySongTableCellView.h
- modules/gui/macosx/library/VLCLibrarySongTableCellView.m → modules/gui/macosx/library/audio-library/VLCLibrarySongTableCellView.m
- + modules/gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.h
- + modules/gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.m
- po/POTFILES.in


Changes:

=====================================
extras/package/macosx/VLC.xcodeproj/project.pbxproj
=====================================
@@ -77,9 +77,7 @@
 		1CCC89052078A3D500E5626F /* TextfieldPanel.xib in Sources */ = {isa = PBXBuildFile; fileRef = 6B8224151E4D2A9000833BE1 /* TextfieldPanel.xib */; };
 		1CCC89062078A3D500E5626F /* TimeSelectionPanel.xib in Sources */ = {isa = PBXBuildFile; fileRef = 6B8224161E4D2A9000833BE1 /* TimeSelectionPanel.xib */; };
 		1CFE8D591EA0D42A00E94451 /* VLCErrorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CFE8D581EA0D42A00E94451 /* VLCErrorWindowController.m */; };
-		5325C56A292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325C569292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */; };
-		5325C56D292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325C56C292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.m */; };
-		5325C570292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325C56F292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.m */; };
+		5325C57D29302E6800B2B63A /* VLCLibraryAudioViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325C57B29302E6800B2B63A /* VLCLibraryAudioViewController.m */; };
 		536283F0291146BC00640C15 /* VLCLibraryTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 536283DE291146BC00640C15 /* VLCLibraryTableView.m */; };
 		536283F1291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 536283DF291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.m */; };
 		536283F2291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.m in Sources */ = {isa = PBXBuildFile; fileRef = 536283E1291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.m */; };
@@ -92,7 +90,12 @@
 		536283F9291146BC00640C15 /* VLCLibraryCollectionViewFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 536283EE291146BC00640C15 /* VLCLibraryCollectionViewFlowLayout.m */; };
 		53628402291147C500640C15 /* VLCBasicView.m in Sources */ = {isa = PBXBuildFile; fileRef = 536283FF291147C500640C15 /* VLCBasicView.m */; };
 		53628403291147C500640C15 /* VLCSubScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53628400291147C500640C15 /* VLCSubScrollView.m */; };
-		53E464782926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53E464762926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.m */; };
+		53B447CA2939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447C92939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m */; };
+		53B447F6293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447EC293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.m */; };
+		53B447F7293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447ED293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */; };
+		53B447F8293BB47B00857588 /* VLCLibraryVideoCollectionViewsStackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447EF293BB47A00857588 /* VLCLibraryVideoCollectionViewsStackViewController.m */; };
+		53B447F9293BB47B00857588 /* VLCLibraryVideoTableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447F3293BB47A00857588 /* VLCLibraryVideoTableViewDataSource.m */; };
+		53B447FA293BB47B00857588 /* VLCLibraryVideoGroupDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447F4293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.m */; };
 		6B0292E61F43256300A50082 /* VLCBottomBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0292E51F43256300A50082 /* VLCBottomBarView.m */; };
 		6B0AB0F01F1AC8B3003A1B4E /* VLCSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0AB0ED1F1AC8B3003A1B4E /* VLCSlider.m */; };
 		6B0AB0F11F1AC8B3003A1B4E /* VLCSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0AB0EF1F1AC8B3003A1B4E /* VLCSliderCell.m */; };
@@ -185,7 +188,6 @@
 		7DF0994F23E71E76007CA6EE /* NSMenu+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF0994E23E71E76007CA6EE /* NSMenu+VLCAdditions.m */; };
 		7DFBDCA82269E77500B700A5 /* VLCLibraryController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCA72269E77500B700A5 /* VLCLibraryController.m */; };
 		7DFBDCAB2269E77F00B700A5 /* VLCLibraryModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCAA2269E77F00B700A5 /* VLCLibraryModel.m */; };
-		7DFBDCAE2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCAD2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.m */; };
 		7DFBDCB1226A518400B700A5 /* VLCLibraryMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCB0226A518400B700A5 /* VLCLibraryMenuController.m */; };
 		7DFBDCB4226CD00900B700A5 /* VLCLibraryDataTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCB3226CD00900B700A5 /* VLCLibraryDataTypes.m */; };
 		7DFBDCB7226CDFD600B700A5 /* VLCImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCB6226CDFD600B700A5 /* VLCImageView.m */; };
@@ -232,12 +234,8 @@
 		1CFE8D561EA0D3D300E94451 /* ErrorPanel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ErrorPanel.xib; sourceTree = "<group>"; };
 		1CFE8D571EA0D42A00E94451 /* VLCErrorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCErrorWindowController.h; sourceTree = "<group>"; };
 		1CFE8D581EA0D42A00E94451 /* VLCErrorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCErrorWindowController.m; sourceTree = "<group>"; };
-		5325C568292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewContainerViewDataSource.h; sourceTree = "<group>"; };
-		5325C569292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewContainerViewDataSource.m; sourceTree = "<group>"; };
-		5325C56B292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoGroupDescriptor.h; sourceTree = "<group>"; };
-		5325C56C292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoGroupDescriptor.m; sourceTree = "<group>"; };
-		5325C56E292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewContainerView.h; sourceTree = "<group>"; };
-		5325C56F292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewContainerView.m; sourceTree = "<group>"; };
+		5325C57B29302E6800B2B63A /* VLCLibraryAudioViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAudioViewController.m; sourceTree = "<group>"; };
+		5325C57C29302E6800B2B63A /* VLCLibraryAudioViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAudioViewController.h; sourceTree = "<group>"; };
 		536283DC291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAlbumTracksDataSource.h; sourceTree = "<group>"; };
 		536283DD291146BC00640C15 /* VLCLibrarySongTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibrarySongTableCellView.h; sourceTree = "<group>"; };
 		536283DE291146BC00640C15 /* VLCLibraryTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryTableView.m; sourceTree = "<group>"; };
@@ -266,8 +264,18 @@
 		536283FF291147C500640C15 /* VLCBasicView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCBasicView.m; sourceTree = "<group>"; };
 		53628400291147C500640C15 /* VLCSubScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCSubScrollView.m; sourceTree = "<group>"; };
 		53628401291147C500640C15 /* VLCSubScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCSubScrollView.h; sourceTree = "<group>"; };
-		53E464762926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewsStackViewController.m; sourceTree = "<group>"; };
-		53E464772926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewsStackViewController.h; sourceTree = "<group>"; };
+		53B447C82939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibrarySongsTableViewSongPlayingTableCellView.h; sourceTree = "<group>"; };
+		53B447C92939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibrarySongsTableViewSongPlayingTableCellView.m; sourceTree = "<group>"; };
+		53B447EC293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewContainerView.m; sourceTree = "<group>"; };
+		53B447ED293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewContainerViewDataSource.m; sourceTree = "<group>"; };
+		53B447EE293BB47A00857588 /* VLCLibraryVideoTableViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoTableViewDataSource.h; sourceTree = "<group>"; };
+		53B447EF293BB47A00857588 /* VLCLibraryVideoCollectionViewsStackViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewsStackViewController.m; sourceTree = "<group>"; };
+		53B447F0293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoGroupDescriptor.h; sourceTree = "<group>"; };
+		53B447F1293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewContainerView.h; sourceTree = "<group>"; };
+		53B447F2293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewContainerViewDataSource.h; sourceTree = "<group>"; };
+		53B447F3293BB47A00857588 /* VLCLibraryVideoTableViewDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoTableViewDataSource.m; sourceTree = "<group>"; };
+		53B447F4293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoGroupDescriptor.m; sourceTree = "<group>"; };
+		53B447F5293BB47B00857588 /* VLCLibraryVideoCollectionViewsStackViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoCollectionViewsStackViewController.h; sourceTree = "<group>"; };
 		5CCED71014C0D4A90057F8D1 /* VLCExtensionsDialogProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCExtensionsDialogProvider.h; sourceTree = "<group>"; };
 		5CCED71114C0D4A90057F8D1 /* VLCExtensionsDialogProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCExtensionsDialogProvider.m; sourceTree = "<group>"; };
 		5CCED71214C0D4A90057F8D1 /* VLCExtensionsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCExtensionsManager.h; sourceTree = "<group>"; };
@@ -651,8 +659,6 @@
 		7DFBDCA72269E77500B700A5 /* VLCLibraryController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryController.m; sourceTree = "<group>"; };
 		7DFBDCA92269E77F00B700A5 /* VLCLibraryModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryModel.h; sourceTree = "<group>"; };
 		7DFBDCAA2269E77F00B700A5 /* VLCLibraryModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryModel.m; sourceTree = "<group>"; };
-		7DFBDCAC2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryVideoTableViewDataSource.h; sourceTree = "<group>"; };
-		7DFBDCAD2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoTableViewDataSource.m; sourceTree = "<group>"; };
 		7DFBDCAF226A518400B700A5 /* VLCLibraryMenuController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryMenuController.h; sourceTree = "<group>"; };
 		7DFBDCB0226A518400B700A5 /* VLCLibraryMenuController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryMenuController.m; sourceTree = "<group>"; };
 		7DFBDCB2226CD00900B700A5 /* VLCLibraryDataTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryDataTypes.h; sourceTree = "<group>"; };
@@ -1097,19 +1103,10 @@
 		1C1ED5132204B0CB00811EC0 /* library */ = {
 			isa = PBXGroup;
 			children = (
-				5325C567292D556800B2B63A /* video-library */,
+				53B447EB293BB47A00857588 /* video-library */,
+				5325C5742930026600B2B63A /* audio-library */,
 				7DFBDCBF226DC16200B700A5 /* VLCInputItem.h */,
 				7DFBDCC0226DC16200B700A5 /* VLCInputItem.m */,
-				7DE82E7722843781002D341A /* VLCLibraryAlbumTableCellView.h */,
-				7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */,
-				536283DC291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.h */,
-				536283DF291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.m */,
-				7DE2F0422282C84A0040DD0A /* VLCLibraryAudioDataSource.h */,
-				7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */,
-				536283E8291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.h */,
-				536283E1291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.m */,
-				536283E7291146BC00640C15 /* VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h */,
-				536283E9291146BC00640C15 /* VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m */,
 				536283ED291146BC00640C15 /* VLCLibraryCollectionViewFlowLayout.h */,
 				536283EE291146BC00640C15 /* VLCLibraryCollectionViewFlowLayout.m */,
 				7D0F64032202047900FDB91F /* VLCLibraryCollectionViewItem.h */,
@@ -1136,8 +1133,6 @@
 				536283E2291146BC00640C15 /* VLCLibraryNavigationStack.m */,
 				536283E4291146BC00640C15 /* VLCLibraryNavigationState.h */,
 				536283EB291146BC00640C15 /* VLCLibraryNavigationState.m */,
-				536283DD291146BC00640C15 /* VLCLibrarySongTableCellView.h */,
-				536283EC291146BC00640C15 /* VLCLibrarySongTableCellView.m */,
 				7D22A8F222BC14F80063ECD2 /* VLCLibrarySortingMenuController.h */,
 				7D22A8F322BC14F80063ECD2 /* VLCLibrarySortingMenuController.m */,
 				7DE2F0452282D5D10040DD0A /* VLCLibraryTableCellView.h */,
@@ -1273,19 +1268,42 @@
 			path = renderers;
 			sourceTree = "<group>";
 		};
-		5325C567292D556800B2B63A /* video-library */ = {
+		5325C5742930026600B2B63A /* audio-library */ = {
+			isa = PBXGroup;
+			children = (
+				5325C57C29302E6800B2B63A /* VLCLibraryAudioViewController.h */,
+				5325C57B29302E6800B2B63A /* VLCLibraryAudioViewController.m */,
+				7DE82E7722843781002D341A /* VLCLibraryAlbumTableCellView.h */,
+				7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */,
+				536283DC291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.h */,
+				536283DF291146BC00640C15 /* VLCLibraryAlbumTracksDataSource.m */,
+				7DE2F0422282C84A0040DD0A /* VLCLibraryAudioDataSource.h */,
+				7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */,
+				536283E8291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.h */,
+				536283E1291146BC00640C15 /* VLCLibraryCollectionViewAlbumSupplementaryDetailView.m */,
+				536283E7291146BC00640C15 /* VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h */,
+				536283E9291146BC00640C15 /* VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m */,
+				536283DD291146BC00640C15 /* VLCLibrarySongTableCellView.h */,
+				536283EC291146BC00640C15 /* VLCLibrarySongTableCellView.m */,
+				53B447C82939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.h */,
+				53B447C92939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m */,
+			);
+			path = "audio-library";
+			sourceTree = "<group>";
+		};
+		53B447EB293BB47A00857588 /* video-library */ = {
 			isa = PBXGroup;
 			children = (
-				5325C56B292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.h */,
-				5325C56C292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.m */,
-				53E464772926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.h */,
-				53E464762926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.m */,
-				5325C56E292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.h */,
-				5325C56F292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.m */,
-				5325C568292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.h */,
-				5325C569292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */,
-				7DFBDCAC2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.h */,
-				7DFBDCAD2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.m */,
+				53B447EC293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.m */,
+				53B447ED293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */,
+				53B447EE293BB47A00857588 /* VLCLibraryVideoTableViewDataSource.h */,
+				53B447EF293BB47A00857588 /* VLCLibraryVideoCollectionViewsStackViewController.m */,
+				53B447F0293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.h */,
+				53B447F1293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.h */,
+				53B447F2293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.h */,
+				53B447F3293BB47A00857588 /* VLCLibraryVideoTableViewDataSource.m */,
+				53B447F4293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.m */,
+				53B447F5293BB47B00857588 /* VLCLibraryVideoCollectionViewsStackViewController.h */,
 			);
 			path = "video-library";
 			sourceTree = "<group>";
@@ -1845,6 +1863,7 @@
 				1C31138E1E508C6900D4DD76 /* VLCAboutWindowController.m in Sources */,
 				1C3113901E508C6900D4DD76 /* VLCHelpWindowController.m in Sources */,
 				7D1BF28D22A192000027C50F /* VLCPlaylistSortingMenuController.m in Sources */,
+				53B447CA2939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m in Sources */,
 				7D03F97423DC5BBC0027A875 /* VLCLibraryInformationPanel.m in Sources */,
 				1C3113921E508C6900D4DD76 /* VLCAddonListItem.m in Sources */,
 				7DFBDCB7226CDFD600B700A5 /* VLCImageView.m in Sources */,
@@ -1857,6 +1876,7 @@
 				7D92AF2123DDCA8D00D81EA3 /* VLCLibraryImageCache.m in Sources */,
 				7D2E0EDE20CD206F0033A221 /* VLCVideoWindowCommon.m in Sources */,
 				1C3113961E508C6900D4DD76 /* applescript.m in Sources */,
+				5325C57D29302E6800B2B63A /* VLCLibraryAudioViewController.m in Sources */,
 				1C3113981E508C6900D4DD76 /* VLCAudioEffectsWindowController.m in Sources */,
 				536283F9291146BC00640C15 /* VLCLibraryCollectionViewFlowLayout.m in Sources */,
 				6BBBF9851F7B257100B404CD /* VLCLogMessage.m in Sources */,
@@ -1865,6 +1885,7 @@
 				6B0AB0F01F1AC8B3003A1B4E /* VLCSlider.m in Sources */,
 				7D28E6362275B4820098D30E /* NSColor+VLCAdditions.m in Sources */,
 				6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */,
+				53B447FA293BB47B00857588 /* VLCLibraryVideoGroupDescriptor.m in Sources */,
 				6BBB05E01EEFF165003A1019 /* VLCHUDTableCornerView.m in Sources */,
 				1C31139D1E508C6900D4DD76 /* VLCControlsBarCommon.m in Sources */,
 				7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */,
@@ -1886,6 +1907,7 @@
 				7DFBDCBB226CED6300B700A5 /* VLCMediaSourceProvider.m in Sources */,
 				7D66D4362200BC340040D04A /* VLCClickerManager.m in Sources */,
 				1C3113B11E508C6900D4DD76 /* VLCFSPanelDraggableView.m in Sources */,
+				53B447F9293BB47B00857588 /* VLCLibraryVideoTableViewDataSource.m in Sources */,
 				1C3113B41E508C6900D4DD76 /* VLCPlaybackContinuityController.m in Sources */,
 				7D28E6392275B7340098D30E /* NSFont+VLCAdditions.m in Sources */,
 				1C3113B61E508C6900D4DD76 /* VLCMain+OldPrefs.m in Sources */,
@@ -1897,13 +1919,13 @@
 				1C3113BD1E508C6900D4DD76 /* macosx.m in Sources */,
 				6B0292E61F43256300A50082 /* VLCBottomBarView.m in Sources */,
 				1C3113C71E508C6900D4DD76 /* VLCOpenWindowController.m in Sources */,
+				53B447F8293BB47B00857588 /* VLCLibraryVideoCollectionViewsStackViewController.m in Sources */,
 				7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in Sources */,
 				7D713D322201AE350042BEB7 /* VLCLibraryWindow.m in Sources */,
-				53E464782926EC0C008AE636 /* VLCLibraryVideoCollectionViewsStackViewController.m in Sources */,
 				7D22A8F422BC14F80063ECD2 /* VLCLibrarySortingMenuController.m in Sources */,
 				1C3113C91E508C6900D4DD76 /* VLCOutput.m in Sources */,
 				1C1C62011F8260A90052DD4F /* VLCWrappableTextField.m in Sources */,
-				5325C570292D5E8F00B2B63A /* VLCLibraryVideoCollectionViewContainerView.m in Sources */,
+				53B447F6293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerView.m in Sources */,
 				6BBB05DA1EEFEA29003A1019 /* VLCHUDOutlineView.m in Sources */,
 				7D445D842202524D00263D34 /* VLCPlaylistItem.m in Sources */,
 				1C3113CF1E508C6900D4DD76 /* prefs_widgets.m in Sources */,
@@ -1914,8 +1936,8 @@
 				7DFBDCB1226A518400B700A5 /* VLCLibraryMenuController.m in Sources */,
 				536283F8291146BC00640C15 /* VLCLibrarySongTableCellView.m in Sources */,
 				1C3113D51E508C6900D4DD76 /* VLCTextfieldPanelController.m in Sources */,
-				7DFBDCAE2269ED0C00B700A5 /* VLCLibraryVideoTableViewDataSource.m in Sources */,
 				53628403291147C500640C15 /* VLCSubScrollView.m in Sources */,
+				53B447F7293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m in Sources */,
 				1C3113D71E508C6900D4DD76 /* VLCPopupPanelController.m in Sources */,
 				7DF0994F23E71E76007CA6EE /* NSMenu+VLCAdditions.m in Sources */,
 				7D445D8B22032B9200263D34 /* VLCPlaylistTableView.m in Sources */,
@@ -1931,7 +1953,6 @@
 				6B6FFF701EF9EC350001CEB1 /* CompatibilityFixes.m in Sources */,
 				7D1BF28A22A153E20027C50F /* VLCRoundedCornerTextField.m in Sources */,
 				7DFBDCB4226CD00900B700A5 /* VLCLibraryDataTypes.m in Sources */,
-				5325C56A292D59FB00B2B63A /* VLCLibraryVideoCollectionViewContainerViewDataSource.m in Sources */,
 				1C3113DF1E508C6900D4DD76 /* VLCVideoEffectsWindowController.m in Sources */,
 				1C3113E11E508C6900D4DD76 /* VLCVoutView.m in Sources */,
 				1C3113E51E508C6900D4DD76 /* VLCInformationWindowController.m in Sources */,
@@ -1939,7 +1960,6 @@
 				7DB40D2A20CBCEB500F63173 /* VLCMainMenu.m in Sources */,
 				1C3113E91E508C6900D4DD76 /* VLCScrollingClipView.m in Sources */,
 				7DB40D2D20CBCEC200F63173 /* VLCStatusBarIcon.m in Sources */,
-				5325C56D292D5CEB00B2B63A /* VLCLibraryVideoGroupDescriptor.m in Sources */,
 				1C3113ED1E508C6900D4DD76 /* VLCTimeSelectionPanelController.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;


=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -58,20 +58,10 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/imported/SPMediaKeyTap/SPMediaKeyTap.m \
 	gui/macosx/library/VLCInputItem.h \
 	gui/macosx/library/VLCInputItem.m \
-	gui/macosx/library/VLCLibraryAlbumTableCellView.h \
-	gui/macosx/library/VLCLibraryAlbumTableCellView.m \
-	gui/macosx/library/VLCLibraryAlbumTracksDataSource.h \
-	gui/macosx/library/VLCLibraryAlbumTracksDataSource.m \
-	gui/macosx/library/VLCLibraryAudioDataSource.h \
-	gui/macosx/library/VLCLibraryAudioDataSource.m \
 	gui/macosx/library/VLCLibraryCollectionViewFlowLayout.h \
 	gui/macosx/library/VLCLibraryCollectionViewFlowLayout.m \
 	gui/macosx/library/VLCLibraryCollectionViewItem.h \
 	gui/macosx/library/VLCLibraryCollectionViewItem.m \
-	gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h \
-	gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m \
-	gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h \
-	gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m \
 	gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h \
 	gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.m \
 	gui/macosx/library/VLCLibraryCollectionViewSupplementaryDetailView.h \
@@ -94,8 +84,6 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/library/VLCLibraryNavigationStack.m \
 	gui/macosx/library/VLCLibraryNavigationState.h \
 	gui/macosx/library/VLCLibraryNavigationState.m \
-	gui/macosx/library/VLCLibrarySongTableCellView.h \
-	gui/macosx/library/VLCLibrarySongTableCellView.m \
 	gui/macosx/library/VLCLibrarySortingMenuController.h \
 	gui/macosx/library/VLCLibrarySortingMenuController.m \
 	gui/macosx/library/VLCLibraryTableView.h \
@@ -114,6 +102,22 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/library/video-library/VLCLibraryVideoGroupDescriptor.m \
 	gui/macosx/library/video-library/VLCLibraryVideoTableViewDataSource.h \
 	gui/macosx/library/video-library/VLCLibraryVideoTableViewDataSource.m \
+	gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h \
+	gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m \
+	gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.h \
+	gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.m \
+	gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h \
+	gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m \
+	gui/macosx/library/audio-library/VLCLibraryAudioViewController.h \
+	gui/macosx/library/audio-library/VLCLibraryAudioViewController.m \
+	gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h \
+	gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m \
+	gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h \
+	gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m \
+	gui/macosx/library/audio-library/VLCLibrarySongTableCellView.h \
+	gui/macosx/library/audio-library/VLCLibrarySongTableCellView.m \
+	gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.h \
+	gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.m \
 	gui/macosx/main/CompatibilityFixes.h \
 	gui/macosx/main/CompatibilityFixes.m \
 	gui/macosx/main/VLCApplication.h \


=====================================
modules/gui/macosx/UI/VLCLibraryWindow.xib
=====================================
@@ -685,6 +685,8 @@
                 <outlet property="audioGroupSelectionTableView" destination="4ll-T2-J16" id="m18-cT-5BQ"/>
                 <outlet property="audioGroupSelectionTableViewScrollView" destination="Jmx-bp-HDp" id="m81-p1-e5Q"/>
                 <outlet property="audioLibraryCollectionView" destination="QAt-jP-zE7" id="Lda-FY-5gD"/>
+                <outlet property="audioLibrarySongsTableView" destination="Xck-iv-pH4" id="Sp4-iv-pH4"/>
+                <outlet property="audioLibrarySongsTableViewScrollView" destination="QqV-hX-sZw" id="1t5-D3-CeM"/>
                 <outlet property="audioLibrarySplitView" destination="llh-BF-BEJ" id="gvt-K1-cGw"/>
                 <outlet property="audioLibraryView" destination="lpg-UW-pTq" id="FYD-PV-Ce2"/>
                 <outlet property="audioSegmentedControl" destination="8iI-b7-Eag" id="ERG-nc-ziq"/>
@@ -807,7 +809,7 @@
                             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
                             <clipView key="contentView" id="OqR-YY-weT">
                                 <rect key="frame" x="0.0" y="0.0" width="230" height="808"/>
-                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <autoresizingMask key="autoresizingMask"/>
                                 <subviews>
                                     <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" viewBased="YES" id="ceR-Vd-9ss" customClass="VLCLibraryTableView">
                                         <rect key="frame" x="0.0" y="0.0" width="230" height="808"/>
@@ -866,7 +868,7 @@
                             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
                             <clipView key="contentView" id="0td-vX-CFl">
                                 <rect key="frame" x="0.0" y="0.0" width="638" height="808"/>
-                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <autoresizingMask key="autoresizingMask"/>
                                 <subviews>
                                     <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="8M4-Y1-r6Z" customClass="VLCLibraryTableView">
                                         <rect key="frame" x="0.0" y="0.0" width="638" height="808"/>
@@ -946,7 +948,7 @@
                     <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
                     <clipView key="contentView" id="5co-vI-cEn">
                         <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
-                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <autoresizingMask key="autoresizingMask"/>
                         <subviews>
                             <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" viewBased="YES" id="vpJ-Oz-Ebz">
                                 <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
@@ -1004,7 +1006,7 @@
                     <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
                     <clipView key="contentView" id="tI4-x3-55j">
                         <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
-                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <autoresizingMask key="autoresizingMask"/>
                         <subviews>
                             <collectionView selectable="YES" id="r7v-GI-W1U">
                                 <rect key="frame" x="0.0" y="0.0" width="528" height="371"/>
@@ -1215,14 +1217,304 @@
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
                 </scrollView>
+                <scrollView autohidesScrollers="YES" horizontalLineScroll="17" horizontalPageScroll="10" verticalLineScroll="17" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QqV-hX-sZw">
+                    <rect key="frame" x="0.0" y="0.0" width="714" height="358"/>
+                    <clipView key="contentView" id="D1c-vg-zeA">
+                        <rect key="frame" x="1" y="1" width="712" height="341"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView identifier="VLCLibrarySongsTableViewIdentifier" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" rowSizeStyle="automatic" headerView="LR0-xA-UlZ" viewBased="YES" id="Xck-iv-pH4" customClass="VLCLibraryTableView">
+                                <rect key="frame" x="0.0" y="0.0" width="1125" height="313"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <size key="intercellSpacing" width="17" height="0.0"/>
+                                <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+                                <tableColumns>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewSongPlayingColumnIdentifier" width="20" minWidth="10" maxWidth="3.4028234663852886e+38" id="jVN-dc-9L8">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="VY3-aD-u9R">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewSongPlayingTableCellViewIdentifier" id="IOs-it-7Fy" customClass="VLCLibrarySongsTableViewSongPlayingTableCellView">
+                                                <rect key="frame" x="8" y="0.0" width="18" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MSe-hS-04C">
+                                                        <rect key="frame" x="0.0" y="0.0" width="18" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" id="UxF-FI-1cA">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="MSe-hS-04C" id="lsl-pe-Mc1"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewTitleColumnIdentifier" width="300" minWidth="40" maxWidth="1000" id="mYC-ua-QDN">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Title">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="mXc-DF-Nye">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewTitleTableCellViewIdentifier" id="SZw-Fr-2EA">
+                                                <rect key="frame" x="43" y="0.0" width="300" height="24"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zai-EE-AIZ">
+                                                        <rect key="frame" x="0.0" y="4" width="300" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="y7s-2M-iio">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="zai-EE-AIZ" id="dBb-Ud-vqM"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewDurationColumnIdentifier" width="60" minWidth="40" maxWidth="1000" id="3Df-VW-eAd">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Duration">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Ttd-ES-DoH">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewDurationTableCellViewIdentifier" id="w9x-WQ-1Zs">
+                                                <rect key="frame" x="360" y="0.0" width="60" height="24"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wYt-1l-VHr">
+                                                        <rect key="frame" x="0.0" y="4" width="60" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="0z5-xP-p2I">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="wYt-1l-VHr" id="xGg-XZ-WJf"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewArtistColumnIdentifier" width="150" minWidth="10" maxWidth="3.4028234663852886e+38" id="M2r-SG-Neg">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Artist">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="ewq-gf-2xl">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewArtistTableCellViewIdentifier" id="ecm-4Q-BHD">
+                                                <rect key="frame" x="437" y="0.0" width="150" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LpX-Ty-dhy">
+                                                        <rect key="frame" x="0.0" y="0.0" width="150" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Sox-k5-8GV">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="LpX-Ty-dhy" id="xcv-9y-e6b"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewAlbumColumnIdentifier" width="200" minWidth="10" maxWidth="3.4028234663852886e+38" id="SL3-ox-dgc">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Album">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="duA-yj-9Wg">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewAlbumTableCellViewIdentifier" id="aMg-rT-0RL">
+                                                <rect key="frame" x="604" y="0.0" width="200" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PbF-Bm-f34">
+                                                        <rect key="frame" x="0.0" y="0.0" width="200" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="as7-Ec-3tU">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="PbF-Bm-f34" id="IUh-Cr-gNa"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewGenreColumnIdentifier" width="150" minWidth="10" maxWidth="3.4028234663852886e+38" id="pdV-26-8ca">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Genre">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="Fa1-eC-jK5">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewGenreTableCellViewIdentifier" id="RpF-ZZ-VVR">
+                                                <rect key="frame" x="821" y="0.0" width="150" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="faR-Tr-m5n">
+                                                        <rect key="frame" x="0.0" y="0.0" width="150" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="mYg-CM-jff">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="faR-Tr-m5n" id="IA5-1O-NnV"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewPlayCountColumnIdentifier" width="64" minWidth="10" maxWidth="3.4028234663852886e+38" id="FQR-Wj-WT3">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Play count">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="zs1-5w-kJx">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongPlayCountTableCellViewIdentifier" id="yc4-Vp-4hr">
+                                                <rect key="frame" x="988" y="0.0" width="64" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4VQ-fV-w9a">
+                                                        <rect key="frame" x="0.0" y="0.0" width="64" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="h8S-0f-C5S">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="4VQ-fV-w9a" id="fNU-ZG-6cY"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="VLCLibrarySongsTableViewYearColumnIdentifier" width="50" minWidth="10" maxWidth="3.4028234663852886e+38" id="Sca-gD-Cur">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Year">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="a7E-ul-nXe">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySongsTableViewYearTableCellViewIdentifier" id="I8Z-L8-hBM">
+                                                <rect key="frame" x="1069" y="0.0" width="47" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Er-xE-Jz7">
+                                                        <rect key="frame" x="0.0" y="0.0" width="47" height="16"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="5bJ-rm-CUk">
+                                                            <font key="font" usesAppearanceFont="YES"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="9Er-xE-Jz7" id="JwZ-SQ-BoS"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                </tableColumns>
+                            </tableView>
+                        </subviews>
+                    </clipView>
+                    <scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="2VX-c2-fRL">
+                        <rect key="frame" x="1" y="342" width="712" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="NFb-XZ-MAv">
+                        <rect key="frame" x="224" y="17" width="15" height="102"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <tableHeaderView key="headerView" wantsLayer="YES" id="LR0-xA-UlZ">
+                        <rect key="frame" x="0.0" y="0.0" width="1125" height="28"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </tableHeaderView>
+                </scrollView>
             </subviews>
             <constraints>
                 <constraint firstItem="llh-BF-BEJ" firstAttribute="top" secondItem="lpg-UW-pTq" secondAttribute="top" id="1dm-EQ-5C7"/>
                 <constraint firstItem="AYf-gS-P66" firstAttribute="leading" secondItem="lpg-UW-pTq" secondAttribute="leading" id="4Bs-W4-a8H"/>
                 <constraint firstItem="AYf-gS-P66" firstAttribute="top" secondItem="lpg-UW-pTq" secondAttribute="top" id="CLf-sg-pyk"/>
                 <constraint firstAttribute="trailing" secondItem="llh-BF-BEJ" secondAttribute="trailing" id="Fqs-1A-XdD"/>
+                <constraint firstItem="QqV-hX-sZw" firstAttribute="top" secondItem="lpg-UW-pTq" secondAttribute="top" constant="32" id="KRh-EG-H6U"/>
+                <constraint firstItem="QqV-hX-sZw" firstAttribute="leading" secondItem="lpg-UW-pTq" secondAttribute="leading" id="PjK-If-LKN"/>
                 <constraint firstItem="llh-BF-BEJ" firstAttribute="leading" secondItem="lpg-UW-pTq" secondAttribute="leading" id="R2e-oG-oCH"/>
+                <constraint firstAttribute="bottom" secondItem="QqV-hX-sZw" secondAttribute="bottom" id="X3K-4y-6ru"/>
                 <constraint firstAttribute="bottom" secondItem="AYf-gS-P66" secondAttribute="bottom" id="aTn-9G-2TE"/>
+                <constraint firstAttribute="trailing" secondItem="QqV-hX-sZw" secondAttribute="trailing" id="boZ-8i-Aa4"/>
                 <constraint firstAttribute="bottom" secondItem="llh-BF-BEJ" secondAttribute="bottom" id="buL-6V-txw"/>
                 <constraint firstAttribute="trailing" secondItem="AYf-gS-P66" secondAttribute="trailing" id="riC-72-Ldb"/>
             </constraints>


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewFlowLayout.m
=====================================
@@ -22,10 +22,11 @@
 
 #import "VLCLibraryCollectionViewFlowLayout.h"
 
-#import "VLCLibraryAudioDataSource.h"
-#import "VLCLibraryCollectionViewAlbumSupplementaryDetailView.h"
-#import "VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h"
-#import "VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h"
+#import "library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h"
+
+#import "library/audio-library/VLCLibraryAudioDataSource.h"
+#import "library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h"
+#import "library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h"
 
 #import "library/video-library/VLCLibraryVideoCollectionViewContainerViewDataSource.h"
 
@@ -204,7 +205,7 @@ static CVReturn detailViewAnimationCallback(CVDisplayLinkRef displayLink,
         VLCLibraryAudioDataSource *audioDataSource = (VLCLibraryAudioDataSource *)self.collectionView.dataSource;
 
         // Add detail view to the attributes set -- detail view about to be shown
-        switch(audioDataSource.segmentedControl.selectedSegment) {
+        switch(audioDataSource.audioLibrarySegment) {
             case VLCAudioLibraryArtistsSegment:
             case VLCAudioLibraryGenresSegment:
                 [layoutAttributesArray addObject:[self layoutAttributesForSupplementaryViewOfKind:VLCLibraryCollectionViewAudioGroupSupplementaryDetailViewKind atIndexPath:self.selectedIndexPath]];


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -137,6 +137,7 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 
 @interface VLCMediaLibraryAlbum : NSObject<VLCMediaLibraryAudioGroupProtocol>
 
++ (nullable instancetype)albumWithID:(int64_t)albumID;
 - (instancetype)initWithAlbum:(struct vlc_ml_album_t *)p_album;
 
 @property (readonly) NSString *title;
@@ -150,6 +151,7 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 
 @interface VLCMediaLibraryGenre : NSObject<VLCMediaLibraryAudioGroupProtocol>
 
++ (nullable instancetype)genreWithID:(int64_t)genreID;
 - (instancetype)initWithGenre:(struct vlc_ml_genre_t *)p_genre;
 
 @property (readonly) NSString *name;


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -363,6 +363,20 @@ static NSArray<VLCMediaLibraryArtist *> *fetchArtistsForLibraryItem(library_arti
 @synthesize smallArtworkMRL = _smallArtworkMRL;
 @synthesize numberOfTracks = _numberOfTracks;
 
++ (nullable instancetype)albumWithID:(int64_t)albumID
+{
+    vlc_medialibrary_t *p_mediaLibrary = getMediaLibrary();
+    if(!p_mediaLibrary) {
+        return nil;
+    }
+    vlc_ml_album_t *p_album = vlc_ml_get_album(p_mediaLibrary, albumID);
+    VLCMediaLibraryAlbum *album = nil;
+    if (p_album) {
+        album = [[VLCMediaLibraryAlbum alloc] initWithAlbum:p_album];
+    }
+    return album;
+}
+
 - (instancetype)initWithAlbum:(struct vlc_ml_album_t *)p_album
 {
     self = [super init];
@@ -454,6 +468,20 @@ static NSArray<VLCMediaLibraryArtist *> *fetchArtistsForLibraryItem(library_arti
     return self;
 }
 
++ (nullable instancetype)genreWithID:(int64_t)genreID
+{
+    vlc_medialibrary_t *p_mediaLibrary = getMediaLibrary();
+    if(!p_mediaLibrary) {
+        return nil;
+    }
+    vlc_ml_genre_t *p_genre = vlc_ml_get_genre(p_mediaLibrary, genreID);
+    VLCMediaLibraryGenre *genre = nil;
+    if (p_genre) {
+        genre = [[VLCMediaLibraryGenre alloc] initWithGenre:p_genre];
+    }
+    return genre;
+}
+
 - (NSImage *)smallArtworkImage
 {
     NSImage *image = [VLCLibraryImageCache thumbnailForLibraryItem:self];


=====================================
modules/gui/macosx/library/VLCLibraryNavigationStack.m
=====================================
@@ -23,9 +23,11 @@
 #import "VLCLibraryNavigationStack.h"
 
 #import "VLCLibraryWindow.h"
-#import "VLCLibraryAudioDataSource.h"
 #import "VLCLibraryNavigationState.h"
 #import "VLCInputItem.h"
+
+#import "library/audio-library/VLCLibraryAudioViewController.h"
+
 #import "media-source/VLCMediaSourceBaseDataSource.h"
 #import "media-source/VLCMediaSourceDataSource.h"
 #import "media-source/VLCMediaSource.h"
@@ -179,7 +181,7 @@
     [_delegate.mediaSourceDataSource.childDataSource setNodeToDisplay:state.currentNodeDisplayed];
 
     [_delegate segmentedControlAction:self];
-    [_delegate.libraryAudioDataSource segmentedControlAction:self];
+    [_delegate.libraryAudioViewController segmentedControlAction:self];
     [_delegate.mediaSourceDataSource setGridOrListMode:self];
 
     [self updateDelegateNavigationButtons];


=====================================
modules/gui/macosx/library/VLCLibraryWindow.h
=====================================
@@ -27,16 +27,16 @@ NS_ASSUME_NONNULL_BEGIN
 @class VLCDragDropView;
 @class VLCRoundedCornerTextField;
 @class VLCLibraryNavigationStack;
- at class VLCLibraryAudioDataSource;
+ at class VLCLibraryAudioViewController;
 @class VLCLibraryVideoCollectionViewsStackViewController;
 @class VLCLibraryVideoTableViewDataSource;
- at class VLCLibraryGroupDataSource;
 @class VLCLibrarySortingMenuController;
 @class VLCMediaSourceBaseDataSource;
 @class VLCPlaylistDataSource;
 @class VLCPlaylistController;
 @class VLCPlaylistSortingMenuController;
 @class VLCFSPanelController;
+ at class VLCCustomEmptyLibraryBrowseButton;
 
 typedef NS_ENUM(NSUInteger, VLCLibrarySegment) {
     VLCLibraryVideoSegment = 0,
@@ -78,6 +78,8 @@ typedef NS_ENUM(NSUInteger, VLCViewModeSegment) {
 @property (readwrite, weak) IBOutlet NSTableView *audioCollectionSelectionTableView;
 @property (readwrite, weak) IBOutlet NSScrollView *audioGroupSelectionTableViewScrollView;
 @property (readwrite, weak) IBOutlet NSTableView *audioGroupSelectionTableView;
+ at property (readwrite, weak) IBOutlet NSScrollView *audioLibrarySongsTableViewScrollView;
+ at property (readwrite, weak) IBOutlet NSTableView *audioLibrarySongsTableView;
 @property (readwrite, weak) IBOutlet NSScrollView *audioCollectionViewScrollView;
 @property (readwrite, weak) IBOutlet NSCollectionView *audioLibraryCollectionView;
 @property (readwrite, weak) IBOutlet NSVisualEffectView *optionBarView;
@@ -110,12 +112,16 @@ typedef NS_ENUM(NSUInteger, VLCViewModeSegment) {
 @property (readwrite, weak) IBOutlet NSButton *forwardsNavigationButton;
 @property (readwrite, weak) IBOutlet NSButton *artworkButton;
 
+ at property (nonatomic, readwrite, strong) IBOutlet NSView *emptyLibraryView;
+ at property (nonatomic, readwrite, strong) IBOutlet NSImageView *placeholderImageView;
+ at property (nonatomic, readwrite, strong) IBOutlet NSTextField *placeholderLabel;
+ at property (nonatomic, readwrite, strong) IBOutlet VLCCustomEmptyLibraryBrowseButton *placeholderGoToBrowseButton;
+
 @property (readwrite) BOOL nonembedded;
 @property (readwrite) VLCLibraryNavigationStack *navigationStack;
- at property (readonly) VLCLibraryAudioDataSource *libraryAudioDataSource;
+ at property (readonly) VLCLibraryAudioViewController *libraryAudioViewController;
 @property (readonly) VLCLibraryVideoTableViewDataSource *libraryVideoTableViewDataSource;
 @property (readonly) VLCLibraryVideoCollectionViewsStackViewController *libraryVideoCollectionViewsStackViewController;
- at property (readonly) VLCLibraryGroupDataSource *libraryAudioGroupDataSource;
 @property (readonly) VLCLibrarySortingMenuController *librarySortingMenuController;
 @property (readonly) VLCMediaSourceBaseDataSource *mediaSourceDataSource;
 @property (readonly) VLCPlaylistDataSource *playlistDataSource;
@@ -123,6 +129,8 @@ typedef NS_ENUM(NSUInteger, VLCViewModeSegment) {
 @property (readonly) VLCPlaylistController *playlistController;
 @property (readonly) VLCFSPanelController *fspanel;
 
+ at property (readonly) NSArray<NSLayoutConstraint *> *videoPlaceholderImageViewSizeConstraints;
+
 - (void)videoPlaybackWillBeStarted;
 - (void)reopenVideoView;
 


=====================================
modules/gui/macosx/library/VLCLibraryWindow.m
=====================================
@@ -34,17 +34,18 @@
 #import "playlist/VLCPlaylistSortingMenuController.h"
 
 #import "library/VLCLibraryController.h"
-#import "library/VLCLibraryAudioDataSource.h"
 #import "library/VLCLibraryCollectionViewItem.h"
 #import "library/VLCLibraryModel.h"
 #import "library/VLCLibraryCollectionViewSupplementaryElementView.h"
 #import "library/VLCLibrarySortingMenuController.h"
-#import "library/VLCLibraryAlbumTableCellView.h"
 #import "library/VLCLibraryNavigationStack.h"
 
 #import "library/video-library/VLCLibraryVideoCollectionViewsStackViewController.h"
 #import "library/video-library/VLCLibraryVideoTableViewDataSource.h"
 
+#import "library/audio-library/VLCLibraryAlbumTableCellView.h"
+#import "library/audio-library/VLCLibraryAudioViewController.h"
+
 #import "media-source/VLCMediaSourceBaseDataSource.h"
 
 #import "views/VLCCustomWindowButton.h"
@@ -70,8 +71,6 @@ const CGFloat VLCLibraryWindowLargeRowHeight = 50.;
 const CGFloat VLCLibraryWindowDefaultPlaylistWidth = 340.;
 const CGFloat VLCLibraryWindowMinimalPlaylistWidth = 170.;
 
-static NSArray<NSLayoutConstraint *> *videoPlaceholderImageViewSizeConstraints;
-static NSArray<NSLayoutConstraint *> *audioPlaceholderImageViewSizeConstraints;
 static NSUserInterfaceItemIdentifier const kVLCLibraryWindowIdentifier = @"VLCLibraryWindow";
 
 @interface VLCLibraryWindow () <VLCDragDropTarget, NSSplitViewDelegate>
@@ -83,11 +82,6 @@ static NSUserInterfaceItemIdentifier const kVLCLibraryWindowIdentifier = @"VLCLi
     NSInteger _currentSelectedViewModeSegment;
 }
 
- at property (nonatomic, readwrite, strong) IBOutlet NSView *emptyLibraryView;
- at property (nonatomic, readwrite, strong) IBOutlet NSImageView *placeholderImageView;
- at property (nonatomic, readwrite, strong) IBOutlet NSTextField *placeholderLabel;
- at property (nonatomic, readwrite, strong) IBOutlet VLCCustomEmptyLibraryBrowseButton *placeholderGoToBrowseButton;
-
 - (IBAction)goToBrowseSection:(id)sender;
 
 @end
@@ -149,7 +143,7 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     self.videoView = [[VLCVoutView alloc] initWithFrame:self.mainSplitView.frame];
     self.videoView.hidden = YES;
     
-    videoPlaceholderImageViewSizeConstraints = @[
+    _videoPlaceholderImageViewSizeConstraints = @[
         [NSLayoutConstraint constraintWithItem:_placeholderImageView
                                      attribute:NSLayoutAttributeWidth
                                      relatedBy:NSLayoutRelationEqual
@@ -165,22 +159,6 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
                                     multiplier:0.f
                                       constant:114.f],
     ];
-    audioPlaceholderImageViewSizeConstraints = @[
-        [NSLayoutConstraint constraintWithItem:_placeholderImageView
-                                     attribute:NSLayoutAttributeWidth
-                                     relatedBy:NSLayoutRelationEqual
-                                        toItem:nil
-                                     attribute:NSLayoutAttributeNotAnAttribute
-                                    multiplier:0.f
-                                      constant:149.f],
-        [NSLayoutConstraint constraintWithItem:_placeholderImageView
-                                     attribute:NSLayoutAttributeHeight
-                                     relatedBy:NSLayoutRelationEqual
-                                        toItem:nil
-                                     attribute:NSLayoutAttributeNotAnAttribute
-                                    multiplier:0.f
-                                      constant:149.f],
-    ];
 
     [self.gridVsListSegmentedControl setToolTip: _NS("Grid View or List View")];
     [self.librarySortButton setToolTip: _NS("Select Sorting Mode")];
@@ -272,32 +250,10 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     _libraryVideoCollectionViewsStackViewController.collectionsStackViewScrollView = _videoLibraryCollectionViewsStackViewScrollView;
     _libraryVideoCollectionViewsStackViewController.collectionsStackView = _videoLibraryCollectionViewsStackView;
 
-    _libraryAudioDataSource = [[VLCLibraryAudioDataSource alloc] init];
-    _libraryAudioDataSource.libraryModel = mainInstance.libraryController.libraryModel;
-    _libraryAudioDataSource.collectionSelectionTableView = _audioCollectionSelectionTableView;
-    _libraryAudioDataSource.groupSelectionTableView = _audioGroupSelectionTableView;
-    _libraryAudioDataSource.segmentedControl = self.audioSegmentedControl;
-    _libraryAudioDataSource.collectionView = self.audioLibraryCollectionView;
-    _libraryAudioDataSource.placeholderImageView = _placeholderImageView;
-    _libraryAudioDataSource.placeholderLabel = _placeholderLabel;
-    [_libraryAudioDataSource setupAppearance];
-    _audioCollectionSelectionTableView.dataSource = _libraryAudioDataSource;
-    _audioCollectionSelectionTableView.delegate = _libraryAudioDataSource;
+    _libraryAudioViewController = [[VLCLibraryAudioViewController alloc] initWithLibraryWindow:self];
     _audioCollectionSelectionTableView.rowHeight = VLCLibraryWindowLargeRowHeight;
-    _libraryAudioGroupDataSource = [[VLCLibraryGroupDataSource alloc] init];
-    _libraryAudioDataSource.groupDataSource = _libraryAudioGroupDataSource;
-    _audioGroupSelectionTableView.dataSource = _libraryAudioGroupDataSource;
-    _audioGroupSelectionTableView.delegate = _libraryAudioGroupDataSource;
     _audioGroupSelectionTableView.rowHeight = [VLCLibraryAlbumTableCellView defaultHeight];
 
-    if(@available(macOS 11.0, *)) {
-        _audioGroupSelectionTableView.style = NSTableViewStyleFullWidth;
-    }
-
-    _audioLibraryCollectionView.selectable = YES;
-    _audioLibraryCollectionView.allowsMultipleSelection = NO;
-    _audioLibraryCollectionView.allowsEmptySelection = YES;
-
     _mediaSourceDataSource = [[VLCMediaSourceBaseDataSource alloc] init];
     _mediaSourceDataSource.collectionView = _mediaSourceCollectionView;
     _mediaSourceDataSource.collectionViewScrollView = _mediaSourceCollectionViewScrollView;
@@ -425,7 +381,7 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     [super encodeRestorableStateWithCoder:coder];
     [coder encodeInteger:_segmentedTitleControl.selectedSegment forKey:@"macosx-library-selected-segment"];
     [coder encodeInteger:_gridVsListSegmentedControl.selectedSegment forKey:@"macosx-library-view-mode-selected-segment"];
-    [coder encodeInteger:_libraryAudioDataSource.segmentedControl.selectedSegment forKey:@"macosx-library-audio-view-selected-segment"];
+    [coder encodeInteger:_audioSegmentedControl.selectedSegment forKey:@"macosx-library-audio-view-selected-segment"];
 }
 
 #pragma mark - appearance setters
@@ -560,10 +516,10 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     }
     
     if (_libraryVideoTableViewDataSource.libraryModel.numberOfVideoMedia == 0) { // empty library
-        for (NSLayoutConstraint *constraint in audioPlaceholderImageViewSizeConstraints) {
+        for (NSLayoutConstraint *constraint in _libraryAudioViewController.audioPlaceholderImageViewSizeConstraints) {
             constraint.active = NO;
         }
-        for (NSLayoutConstraint *constraint in videoPlaceholderImageViewSizeConstraints) {
+        for (NSLayoutConstraint *constraint in _videoPlaceholderImageViewSizeConstraints) {
             constraint.active = YES;
         }
         
@@ -604,48 +560,8 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
 
 - (void)showAudioLibrary
 {
-    for (NSView *subview in _libraryTargetView.subviews) {
-        [subview removeFromSuperview];
-    }
-    
-    if (_libraryAudioDataSource.libraryModel.numberOfAudioMedia == 0) { // empty library
-        for (NSLayoutConstraint *constraint in videoPlaceholderImageViewSizeConstraints) {
-            constraint.active = NO;
-        }
-        for (NSLayoutConstraint *constraint in audioPlaceholderImageViewSizeConstraints) {
-            constraint.active = YES;
-        }
-        
-        [_libraryAudioDataSource reloadEmptyViewAppearance];
-        
-        _emptyLibraryView.translatesAutoresizingMaskIntoConstraints = NO;
-        [_libraryTargetView addSubview:_emptyLibraryView];
-        NSDictionary *dict = NSDictionaryOfVariableBindings(_emptyLibraryView);
-        [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_emptyLibraryView(>=572.)]|" options:0 metrics:0 views:dict]];
-        [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_emptyLibraryView(>=444.)]|" options:0 metrics:0 views:dict]];
-    } else {
-        _audioLibraryView.translatesAutoresizingMaskIntoConstraints = NO;
-        [_libraryTargetView addSubview:_audioLibraryView];
-        NSDictionary *dict = NSDictionaryOfVariableBindings(_audioLibraryView);
-        [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_audioLibraryView(>=572.)]|" options:0 metrics:0 views:dict]];
-        [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_audioLibraryView(>=444.)]|" options:0 metrics:0 views:dict]];
-        
-        if (self.gridVsListSegmentedControl.selectedSegment == VLCGridViewModeSegment) {
-            _audioLibrarySplitView.hidden = YES;
-            _audioCollectionViewScrollView.hidden = NO;
-        } else {
-            _audioLibrarySplitView.hidden = NO;
-            _audioCollectionViewScrollView.hidden = YES;
-        }
-        
-        [_libraryAudioDataSource reloadAppearance];
-    }
-    
-    _librarySortButton.hidden = NO;
-    _librarySearchField.enabled = YES;
-    _optionBarView.hidden = NO;
-    _audioSegmentedControl.hidden = NO;
-    
+    [_libraryAudioViewController presentAudioView];
+
     self.gridVsListSegmentedControl.target = self;
     self.gridVsListSegmentedControl.action = @selector(segmentedControlAction:);
 }
@@ -1029,10 +945,10 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
 
     [libraryWindow.segmentedTitleControl setSelectedSegment:rememberedSelectedLibrarySegment];
     [libraryWindow.gridVsListSegmentedControl setSelectedSegment:rememberedSelectedLibraryViewModeSegment];
-    [libraryWindow.libraryAudioDataSource.segmentedControl setSelectedSegment:rememberedSelectedLibraryViewAudioSegment];
+    [libraryWindow.audioSegmentedControl setSelectedSegment:rememberedSelectedLibraryViewAudioSegment];
 
     // We don't want to add these to the navigation stack...
-    [libraryWindow.libraryAudioDataSource segmentedControlAction:libraryWindow.navigationStack];
+    [libraryWindow.libraryAudioViewController segmentedControlAction:libraryWindow.navigationStack];
     [libraryWindow segmentedControlAction:libraryWindow.navigationStack];
 
     // But we do want the "final" initial position to be added. So we manually invoke the navigation stack


=====================================
modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h
=====================================


=====================================
modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
=====================================
@@ -33,7 +33,7 @@
 #import "library/VLCLibraryDataTypes.h"
 #import "library/VLCLibraryTableCellView.h"
 #import "library/VLCLibraryTableView.h"
-#import "library/VLCLibraryAlbumTracksDataSource.h"
+#import "library/audio-library/VLCLibraryAlbumTracksDataSource.h"
 
 NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier";
 NSString *VLCLibraryAlbumTableCellTableViewColumnIdentifier = @"VLCLibraryAlbumTableCellTableViewColumnIdentifier";


=====================================
modules/gui/macosx/library/VLCLibraryAlbumTracksDataSource.h → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.h
=====================================
@@ -22,7 +22,7 @@
 
 #import <Cocoa/Cocoa.h>
 
-#import "VLCLibraryTableView.h"
+#import "library/VLCLibraryTableView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -36,4 +36,4 @@ extern const CGFloat VLCLibraryTracksRowHeight;
 
 @end
 
-NS_ASSUME_NONNULL_END
\ No newline at end of file
+NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/library/VLCLibraryAlbumTracksDataSource.m → modules/gui/macosx/library/audio-library/VLCLibraryAlbumTracksDataSource.m
=====================================
@@ -21,7 +21,7 @@
  *****************************************************************************/
 
 #import "VLCLibraryAlbumTracksDataSource.h"
-#import "VLCLibrarySongTableCellView.h"
+
 #import "extensions/NSFont+VLCAdditions.h"
 #import "extensions/NSString+Helpers.h"
 #import "views/VLCImageView.h"
@@ -31,7 +31,8 @@
 #import "library/VLCLibraryDataTypes.h"
 #import "library/VLCLibraryTableCellView.h"
 #import "library/VLCLibraryTableView.h"
-#import "library/VLCLibraryAlbumTracksDataSource.h"
+#import "library/audio-library/VLCLibraryAlbumTracksDataSource.h"
+#import "library/audio-library/VLCLibrarySongTableCellView.h"
 
 const CGFloat VLCLibraryTracksRowHeight = 40.;
 


=====================================
modules/gui/macosx/library/VLCLibraryAudioDataSource.h → modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h
=====================================
@@ -22,7 +22,7 @@
 
 #import <Cocoa/Cocoa.h>
 
-#import "VLCLibraryTableView.h"
+#import "library/VLCLibraryTableView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -41,18 +41,14 @@ typedef NS_ENUM(NSUInteger, VLCAudioLibrarySegment) {
 
 @property (readwrite, assign) VLCLibraryModel *libraryModel;
 @property (readwrite, assign) VLCLibraryGroupDataSource *groupDataSource;
- at property (readwrite, assign) NSSegmentedControl *segmentedControl;
 @property (readwrite, assign) NSTableView *collectionSelectionTableView;
 @property (readwrite, assign) NSTableView *groupSelectionTableView;
+ at property (readwrite, assign) NSTableView *songsTableView;
 @property (readwrite, assign) NSCollectionView *collectionView;
- at property (nonatomic, readwrite, assign) NSImageView *placeholderImageView;
- at property (nonatomic, readwrite, assign) NSTextField *placeholderLabel;
- at property (nonatomic, readonly, strong) NSString *imageNameForCurrentSegment;
 
-- (IBAction)segmentedControlAction:(id)sender;
-- (void)setupAppearance;
-- (void)reloadAppearance;
-- (void)reloadEmptyViewAppearance;
+ at property (nonatomic, readwrite, assign) VLCAudioLibrarySegment audioLibrarySegment;
+
+- (void)setup;
 - (void)reloadData;
 
 @end


=====================================
modules/gui/macosx/library/VLCLibraryAudioDataSource.m → modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
=====================================
@@ -31,13 +31,15 @@
 #import "library/VLCLibraryDataTypes.h"
 #import "library/VLCLibraryTableCellView.h"
 #import "library/VLCLibraryTableView.h"
-#import "library/VLCLibraryAlbumTableCellView.h"
 #import "library/VLCLibraryCollectionViewItem.h"
 #import "library/VLCLibraryCollectionViewFlowLayout.h"
-#import "library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h"
-#import "library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h"
 #import "library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h"
 
+#import "library/audio-library/VLCLibraryAlbumTableCellView.h"
+#import "library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h"
+#import "library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h"
+#import "library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.h"
+
 #import "extensions/NSString+Helpers.h"
 #import "views/VLCImageView.h"
 #import "views/VLCSubScrollView.h"
@@ -45,11 +47,13 @@
 @interface VLCLibraryAudioDataSource ()
 {
     VLCLibraryCollectionViewFlowLayout *_collectionViewFlowLayout;
-    NSInteger _currentSelectedSegment;
-    NSArray<NSString *> *_placeholderImageNames;
-    NSArray<NSString *> *_placeholderLabelStrings;
     NSArray *_displayedCollection;
     enum vlc_ml_parent_type _currentParentType;
+
+    id<VLCMediaLibraryItemProtocol> _selectedCollectionViewItem;
+    id<VLCMediaLibraryItemProtocol> _selectedCollectionSelectionTableViewItem;
+    id<VLCMediaLibraryItemProtocol> _selectedGroupSelectionTableViewItem;
+    id<VLCMediaLibraryItemProtocol> _selectedSongTableViewItem;
 }
 @end
 
@@ -107,41 +111,42 @@
     }
 
     dispatch_async(dispatch_get_main_queue(), ^{
-        NSSet* originalCollectionSet = [[NSSet alloc] initWithArray:_displayedCollection];
+        NSSet* originalCollectionSet = [[NSSet alloc] initWithArray:self->_displayedCollection];
         NSSet* newCollectionSet = [[NSSet alloc] initWithArray:collectionToDisplay];
 
         if([originalCollectionSet isEqual:newCollectionSet]) {
             return;
         }
 
-        id<VLCMediaLibraryItemProtocol> selectedCollectionViewItem;
-        if(_collectionView.selectionIndexPaths.count > 0 && !_collectionView.hidden) {
-            selectedCollectionViewItem = [self selectedCollectionViewItem];
-        }
-
-        _displayedCollection = collectionToDisplay;
+        [self retainSelectedMediaItem];
+        self->_displayedCollection = collectionToDisplay;
         [self reloadData];
-
-        // Reopen supplementary view in the collection views
-        if(selectedCollectionViewItem) {
-            NSUInteger newIndexOfSelectedItem = [_displayedCollection indexOfObjectPassingTest:^BOOL(id element, NSUInteger idx, BOOL *stop) {
-                id<VLCMediaLibraryItemProtocol> itemElement = (id<VLCMediaLibraryItemProtocol>)element;
-                return itemElement.libraryID == selectedCollectionViewItem.libraryID;
-            }];
-
-            if(newIndexOfSelectedItem == NSNotFound) {
-                return;
-            }
-
-            NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:newIndexOfSelectedItem inSection:0];
-            NSSet *indexPathSet = [NSSet setWithObject:newIndexPath];
-            [_collectionView selectItemsAtIndexPaths:indexPathSet scrollPosition:NSCollectionViewScrollPositionTop];
-            // selectItemsAtIndexPaths does not call any delegate methods so we do it manually
-            [self collectionView:_collectionView didSelectItemsAtIndexPaths:indexPathSet];
-        }
+        [self restoreSelectionState];
     });
 }
 
+- (void)retainSelectedMediaItem
+{
+    if(_collectionView.selectionIndexPaths.count > 0 && !_collectionView.hidden) {
+        _selectedCollectionViewItem = [self selectedCollectionViewItem];
+    }
+
+    const NSInteger collectionSelectionTableViewRow = _collectionSelectionTableView.selectedRow;
+    if(collectionSelectionTableViewRow >= 0 && !_collectionSelectionTableView.hidden) {
+        _selectedCollectionSelectionTableViewItem = [self libraryItemAtRow:collectionSelectionTableViewRow];
+    }
+
+    const NSInteger groupSelectionTableViewRow = _groupSelectionTableView.selectedRow;
+    if(groupSelectionTableViewRow >= 0 && !_groupSelectionTableView.hidden) {
+        _selectedGroupSelectionTableViewItem = [self libraryItemAtRow:groupSelectionTableViewRow];
+    }
+
+    const NSInteger songsTableViewRow = _songsTableView.selectedRow;
+    if(songsTableViewRow >= 0 && !_songsTableView.hidden) {
+        _selectedSongTableViewItem = [self libraryItemAtRow:songsTableViewRow];
+    }
+}
+
 - (id<VLCMediaLibraryItemProtocol>)selectedCollectionViewItem
 {
     NSIndexPath *indexPath = _collectionView.selectionIndexPaths.anyObject;
@@ -152,14 +157,76 @@
     return _displayedCollection[indexPath.item];
 }
 
-- (void)setupAppearance
+- (void)restoreSelectionState
 {
-    self.segmentedControl.segmentCount = 4;
-    [self.segmentedControl setLabel:_NS("Artists") forSegment:VLCAudioLibraryArtistsSegment];
-    [self.segmentedControl setLabel:_NS("Albums") forSegment:VLCAudioLibraryAlbumsSegment];
-    [self.segmentedControl setLabel:_NS("Songs") forSegment:VLCAudioLibrarySongsSegment];
-    [self.segmentedControl setLabel:_NS("Genres") forSegment:VLCAudioLibraryGenresSegment];
+    [self restoreCollectionViewSelectionState];
+    [self restoreCollectionSelectionTableViewSelectionState];
+    [self restoreGroupSelectionTableViewSelectionState];
+    [self restoreSongTableViewSelectionState];
+}
 
+- (NSUInteger)findSelectedItemNewIndex:(id<VLCMediaLibraryItemProtocol>)item
+{
+    return [_displayedCollection indexOfObjectPassingTest:^BOOL(id element, NSUInteger idx, BOOL *stop) {
+        id<VLCMediaLibraryItemProtocol> itemElement = (id<VLCMediaLibraryItemProtocol>)element;
+        return itemElement.libraryID == item.libraryID;
+    }];
+}
+
+- (void)restoreCollectionViewSelectionState
+{
+    if (!_selectedCollectionViewItem) {
+        return;
+    }
+
+    const NSUInteger newIndexOfSelectedItem = [self findSelectedItemNewIndex:_selectedCollectionViewItem];
+    if(newIndexOfSelectedItem == NSNotFound) {
+        return;
+    }
+
+    NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:newIndexOfSelectedItem inSection:0];
+    NSSet *indexPathSet = [NSSet setWithObject:newIndexPath];
+    [_collectionView selectItemsAtIndexPaths:indexPathSet scrollPosition:NSCollectionViewScrollPositionTop];
+    // selectItemsAtIndexPaths does not call any delegate methods so we do it manually
+    [self collectionView:_collectionView didSelectItemsAtIndexPaths:indexPathSet];
+    _selectedCollectionViewItem = nil;
+}
+
+- (void)restoreSelectionStateForTableView:(NSTableView*)tableView
+                         withSelectedItem:(id<VLCMediaLibraryItemProtocol>)item
+{
+    const NSUInteger newIndexOfSelectedItem = [self findSelectedItemNewIndex:item];
+    if(newIndexOfSelectedItem == NSNotFound || newIndexOfSelectedItem < 0) {
+        return;
+    }
+
+    NSIndexSet *newSelectedRowIndexSet = [NSIndexSet indexSetWithIndex:newIndexOfSelectedItem];
+    [tableView selectRowIndexes:newSelectedRowIndexSet byExtendingSelection:NO];
+}
+
+- (void)restoreCollectionSelectionTableViewSelectionState
+{
+    [self restoreSelectionStateForTableView:_collectionSelectionTableView
+                           withSelectedItem:_selectedCollectionSelectionTableViewItem];
+    _selectedCollectionSelectionTableViewItem = nil;
+}
+
+- (void)restoreGroupSelectionTableViewSelectionState
+{
+    [self restoreSelectionStateForTableView:_groupSelectionTableView
+                           withSelectedItem:_selectedGroupSelectionTableViewItem];
+    _selectedGroupSelectionTableViewItem = nil;
+}
+
+- (void)restoreSongTableViewSelectionState
+{
+    [self restoreSelectionStateForTableView:_songsTableView
+                           withSelectedItem:_selectedSongTableViewItem];
+    _selectedSongTableViewItem = nil;
+}
+
+- (void)setup
+{
     _collectionView.dataSource = self;
     _collectionView.delegate = self;
 
@@ -187,59 +254,36 @@
     _groupSelectionTableView.doubleAction = @selector(groubSelectionDoubleClickAction:);
     _collectionSelectionTableView.target = self;
     _collectionSelectionTableView.doubleAction = @selector(collectionSelectionDoubleClickAction:);
-    
-    _currentSelectedSegment = -1; // Force segmentedControlAction to do what it must
-    _segmentedControl.selectedSegment = 0;
-
-    _placeholderImageNames = @[@"placeholder-group2", @"placeholder-music", @"placeholder-music", @"placeholder-music"];
-    _placeholderLabelStrings = @[
-        _NS("Your favorite artists will appear here.\nGo to the Browse section to add artists you love."),
-        _NS("Your favorite albums will appear here.\nGo to the Browse section to add albums you love."),
-        _NS("Your favorite tracks will appear here.\nGo to the Browse section to add tracks you love."),
-        _NS("Your favorite genres will appear here.\nGo to the Browse section to add genres you love."),
-    ];
+    _songsTableView.target = self;
+    _songsTableView.doubleAction = @selector(songDoubleClickAction:);
 
-    [self reloadAppearance];
-    [self reloadEmptyViewAppearance];
-}
-
-- (void)reloadAppearance
-{
-    [self.segmentedControl setTarget:self];
-    [self.segmentedControl setAction:@selector(segmentedControlAction:)];
-    [self segmentedControlAction:[[[VLCMain sharedInstance] libraryWindow] navigationStack]];
+    _audioLibrarySegment = -1; // Force setAudioLibrarySegment to do something always on first try
 }
 
-- (void)reloadEmptyViewAppearance
+- (void)reloadData
 {
-    if(_currentSelectedSegment < _placeholderImageNames.count && _currentSelectedSegment >= 0) {
-        _placeholderImageView.image = [NSImage imageNamed:_placeholderImageNames[_currentSelectedSegment]];
-    }
-
-    if(_currentSelectedSegment < _placeholderLabelStrings.count && _currentSelectedSegment >= 0) {
-        _placeholderLabel.stringValue = _placeholderLabelStrings[_currentSelectedSegment];
-    }
+    [self retainSelectedMediaItem];
+    [self reloadViews];
+    [self restoreSelectionState];
 }
 
-- (void)reloadData
+- (void)reloadViews
 {
     [_collectionViewFlowLayout resetLayout];
     [self.collectionView reloadData];
     [self.collectionSelectionTableView reloadData];
     [self.groupSelectionTableView reloadData];
+    [self.songsTableView reloadData];
 }
 
-- (IBAction)segmentedControlAction:(id)sender
+- (void)setAudioLibrarySegment:(VLCAudioLibrarySegment)audioLibrarySegment
 {
-    if (_libraryModel.listOfAudioMedia.count == 0) {
-        [self reloadEmptyViewAppearance];
-        return;
-    } else if (_segmentedControl.selectedSegment == _currentSelectedSegment) {
+    if (audioLibrarySegment == _audioLibrarySegment) {
         return;
     }
 
-    _currentSelectedSegment = _segmentedControl.selectedSegment;
-    switch (_currentSelectedSegment) {
+    _audioLibrarySegment = audioLibrarySegment;
+    switch (_audioLibrarySegment) {
         case VLCAudioLibraryArtistsSegment:
             _displayedCollection = [self.libraryModel listOfArtists];
             _currentParentType = VLC_ML_PARENT_ARTIST;
@@ -264,15 +308,6 @@
 
     _groupDataSource.representedListOfAlbums = nil; // Clear whatever was being shown before
     [self reloadData];
-
-    if(sender != [[[VLCMain sharedInstance] libraryWindow] navigationStack]) {
-        [[[[VLCMain sharedInstance] libraryWindow] navigationStack] appendCurrentLibraryState];
-    }
-}
-
-- (NSString *)imageNameForCurrentSegment
-{
-    return _placeholderImageNames[_currentSelectedSegment];
 }
 
 #pragma mark - table view data source and delegation
@@ -282,8 +317,56 @@
     return _displayedCollection.count;
 }
 
-- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
+- (NSView *)tableView:(NSTableView *)tableView
+   viewForTableColumn:(NSTableColumn *)tableColumn
+                  row:(NSInteger)row
 {
+    // The table view for songs in the list view mode of the audio library is different from the other audio groupings
+    // and we use a vanilla NSTableView created in the VLCLibraryWindow XIB for it
+    if ([tableView.identifier isEqualToString:@"VLCLibrarySongsTableViewIdentifier"]) {
+        const NSString * const columnIdentifier = tableColumn.identifier;
+        const VLCMediaLibraryMediaItem * const mediaItem = [self libraryItemAtRow:row];
+        const VLCMediaLibraryAlbum * const album = [VLCMediaLibraryAlbum albumWithID:mediaItem.albumID];
+        const VLCMediaLibraryGenre * const genre = [VLCMediaLibraryGenre genreWithID:mediaItem.genreID];
+
+        NSString *cellText = @"";
+        NSString *cellIdentifier = @"";
+
+        if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewSongPlayingColumnIdentifier"]) {
+            VLCLibrarySongsTableViewSongPlayingTableCellView *cellView = (VLCLibrarySongsTableViewSongPlayingTableCellView*)[tableView makeViewWithIdentifier:@"VLCLibrarySongsTableViewSongPlayingTableCellViewIdentifier" owner:self];
+            NSAssert(cellView, @"Unexpectedly received null cellview");
+            cellView.representedMediaItem = [self libraryItemAtRow:row];
+            return cellView;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewTitleColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewTitleTableCellViewIdentifier";
+            cellText = mediaItem.title;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewDurationColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewDurationTableCellViewIdentifier";
+            cellText = mediaItem.durationString;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewArtistColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewArtistTableCellViewIdentifier";
+            cellText = album.artistName.length == 0 ? @"" : album.artistName;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewAlbumColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewAlbumTableCellViewIdentifier";
+            cellText = album.title.length == 0 ? @"" : album.title;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewGenreColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewGenreTableCellViewIdentifier";
+            cellText = genre.name.length == 0 ? @"" : genre.name;
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewPlayCountColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewPlayCountTableCellViewIdentifier";
+            cellText = [@(mediaItem.playCount) stringValue];
+        } else if ([columnIdentifier isEqualToString:@"VLCLibrarySongsTableViewYearColumnIdentifier"]) {
+            cellIdentifier = @"VLCLibrarySongsTableViewYearTableCellViewIdentifier";
+            cellText = [@(mediaItem.year) stringValue];
+        } else {
+            NSAssert(true, @"Received unknown column identifier %@", columnIdentifier);
+        }
+
+        NSTableCellView *cellView = [tableView makeViewWithIdentifier:cellIdentifier owner:self];
+        cellView.textField.stringValue = cellText;
+        return cellView;
+    }
+
     VLCLibraryTableCellView *cellView = [tableView makeViewWithIdentifier:VLCAudioLibraryCellIdentifier owner:self];
 
     if (cellView == nil) {
@@ -302,6 +385,10 @@
 
 - (void)tableViewSelectionDidChange:(NSNotification *)notification
 {
+    if (notification.object != _collectionSelectionTableView) {
+        return;
+    }
+
     id<VLCMediaLibraryItemProtocol> libraryItem = _displayedCollection[self.collectionSelectionTableView.selectedRow];
 
     if (_currentParentType == VLC_ML_PARENT_ALBUM) {
@@ -340,6 +427,13 @@
     }];
 }
 
+- (void)songDoubleClickAction:(id)sender
+{
+    NSAssert(_audioLibrarySegment == VLCAudioLibrarySongsSegment, @"Should not be possible to trigger this action from a non-song library view");
+    VLCMediaLibraryMediaItem *mediaItem = _displayedCollection[_songsTableView.selectedRow];
+    [VLCMain.sharedInstance.libraryController appendItemToPlaylist:mediaItem playImmediately:YES];
+}
+
 #pragma mark - collection view data source and delegation
 
 - (NSInteger)collectionView:(NSCollectionView *)collectionView


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.h
=====================================
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * VLCLibraryAudioViewController.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <claudio.cambra at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+ at class VLCLibraryAudioDataSource;
+ at class VLCLibraryGroupDataSource;
+ at class VLCLibraryWindow;
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at interface VLCLibraryAudioViewController : NSObject
+
+ at property (readonly) NSView *libraryTargetView;
+ at property (readonly) NSView *audioLibraryView;
+ at property (readonly) NSSplitView *audioLibrarySplitView;
+ at property (readonly) NSScrollView *audioCollectionSelectionTableViewScrollView;
+ at property (readonly) NSTableView *audioCollectionSelectionTableView;
+ at property (readonly) NSScrollView *audioGroupSelectionTableViewScrollView;
+ at property (readonly) NSTableView *audioGroupSelectionTableView;
+ at property (readonly) NSScrollView *audioSongTableViewScrollView;
+ at property (readonly) NSTableView *audioSongTableView;
+ at property (readonly) NSScrollView *audioCollectionViewScrollView;
+ at property (readonly) NSCollectionView *audioLibraryCollectionView;
+ at property (readonly) NSSegmentedControl *audioSegmentedControl;
+ at property (readonly) NSSegmentedControl *gridVsListSegmentedControl;
+ at property (readonly) NSButton *librarySortButton;
+ at property (readonly) NSSearchField *librarySearchField;
+ at property (readonly) NSVisualEffectView *optionBarView;
+ at property (readonly) NSImageView *placeholderImageView;
+ at property (readonly) NSTextField *placeholderLabel;
+ at property (readonly) NSView *emptyLibraryView;
+
+ at property (readonly) VLCLibraryAudioDataSource *audioDataSource;
+ at property (readonly) VLCLibraryGroupDataSource *audioGroupDataSource;
+
+ at property (readonly) NSArray<NSLayoutConstraint *> *audioPlaceholderImageViewSizeConstraints;
+
+- (instancetype)initWithLibraryWindow:(VLCLibraryWindow *)libraryWindow;
+- (IBAction)segmentedControlAction:(id)sender;
+- (void)presentAudioView;
+- (void)reloadData;
+
+ at end
+
+NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.m
=====================================
@@ -0,0 +1,266 @@
+/*****************************************************************************
+ * VLCLibraryAudioViewController.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <claudio.cambra at gmail.com>
+ *
+ * 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 "VLCLibraryAudioViewController.h"
+
+#import "main/VLCMain.h"
+#import "extensions/NSString+Helpers.h"
+#import "library/VLCLibraryController.h"
+#import "library/VLCLibraryModel.h"
+#import "library/VLCLibraryNavigationStack.h"
+#import "library/VLCLibraryWindow.h"
+#import "library/audio-library/VLCLibraryAudioDataSource.h"
+
+ at interface VLCLibraryAudioViewController()
+{
+    NSArray<NSString *> *_placeholderImageNames;
+    NSArray<NSString *> *_placeholderLabelStrings;
+}
+ at end
+
+ at implementation VLCLibraryAudioViewController
+
+#pragma mark - Set up the view controller
+
+- (instancetype)initWithLibraryWindow:(VLCLibraryWindow *)libraryWindow
+{
+    self = [super init];
+
+    if(self) {
+        [self setupPropertiesFromLibraryWindow:libraryWindow];
+        [self setupAudioDataSource];
+        [self setupAudioCollectionView];
+        [self setupAudioTableViews];
+        [self setupAudioSegmentedControl];
+    }
+
+    return self;
+}
+
+- (void)setupPropertiesFromLibraryWindow:(VLCLibraryWindow*)libraryWindow
+{
+    NSAssert(libraryWindow, @"Cannot setup audio view controller with invalid library window");
+
+    _libraryTargetView = libraryWindow.libraryTargetView;
+    _audioLibraryView = libraryWindow.audioLibraryView;
+    _audioLibrarySplitView = libraryWindow.audioLibrarySplitView;
+    _audioCollectionSelectionTableViewScrollView = libraryWindow.audioCollectionSelectionTableViewScrollView;
+    _audioCollectionSelectionTableView = libraryWindow.audioCollectionSelectionTableView;
+    _audioGroupSelectionTableViewScrollView = libraryWindow.audioGroupSelectionTableViewScrollView;
+    _audioGroupSelectionTableView = libraryWindow.audioGroupSelectionTableView;
+    _audioSongTableViewScrollView = libraryWindow.audioLibrarySongsTableViewScrollView;
+    _audioSongTableView = libraryWindow.audioLibrarySongsTableView;
+    _audioCollectionViewScrollView = libraryWindow.audioCollectionViewScrollView;
+    _audioLibraryCollectionView = libraryWindow.audioLibraryCollectionView;
+    _audioSegmentedControl = libraryWindow.audioSegmentedControl;
+    _gridVsListSegmentedControl = libraryWindow.gridVsListSegmentedControl;
+    _optionBarView = libraryWindow.optionBarView;
+    _librarySortButton = libraryWindow.librarySortButton;
+    _librarySearchField = libraryWindow.librarySearchField;
+    _placeholderImageView = libraryWindow.placeholderImageView;
+    _placeholderLabel = libraryWindow.placeholderLabel;
+    _emptyLibraryView = libraryWindow.emptyLibraryView;
+}
+
+- (void)setupAudioDataSource
+{
+    _audioDataSource = [[VLCLibraryAudioDataSource alloc] init];
+    _audioDataSource.libraryModel = [VLCMain sharedInstance].libraryController.libraryModel;
+    _audioDataSource.collectionSelectionTableView = _audioCollectionSelectionTableView;
+    _audioDataSource.groupSelectionTableView = _audioGroupSelectionTableView;
+    _audioDataSource.songsTableView = _audioSongTableView;
+    _audioDataSource.collectionView = _audioLibraryCollectionView;
+    [_audioDataSource setup];
+
+    _audioGroupDataSource = [[VLCLibraryGroupDataSource alloc] init];
+    _audioDataSource.groupDataSource = _audioGroupDataSource;
+}
+
+- (void)setupAudioCollectionView
+{
+    _audioLibraryCollectionView.selectable = YES;
+    _audioLibraryCollectionView.allowsMultipleSelection = NO;
+    _audioLibraryCollectionView.allowsEmptySelection = YES;
+}
+
+- (void)setupAudioTableViews
+{
+    _audioCollectionSelectionTableView.dataSource = _audioDataSource;
+    _audioCollectionSelectionTableView.delegate = _audioDataSource;
+
+    _audioGroupSelectionTableView.dataSource = _audioGroupDataSource;
+    _audioGroupSelectionTableView.delegate = _audioGroupDataSource;
+
+    if(@available(macOS 11.0, *)) {
+        _audioGroupSelectionTableView.style = NSTableViewStyleFullWidth;
+    }
+
+    _audioSongTableView.dataSource = _audioDataSource;
+    _audioSongTableView.delegate = _audioDataSource;
+}
+
+- (void)setupAudioPlaceholderView
+{
+    _audioPlaceholderImageViewSizeConstraints = @[
+        [NSLayoutConstraint constraintWithItem:_placeholderImageView
+                                     attribute:NSLayoutAttributeWidth
+                                     relatedBy:NSLayoutRelationEqual
+                                        toItem:nil
+                                     attribute:NSLayoutAttributeNotAnAttribute
+                                    multiplier:0.f
+                                      constant:149.f],
+        [NSLayoutConstraint constraintWithItem:_placeholderImageView
+                                     attribute:NSLayoutAttributeHeight
+                                     relatedBy:NSLayoutRelationEqual
+                                        toItem:nil
+                                     attribute:NSLayoutAttributeNotAnAttribute
+                                    multiplier:0.f
+                                      constant:149.f],
+    ];
+
+    _placeholderImageNames = @[@"placeholder-group2", @"placeholder-music", @"placeholder-music", @"placeholder-music"];
+    _placeholderLabelStrings = @[
+        _NS("Your favorite artists will appear here.\nGo to the Browse section to add artists you love."),
+        _NS("Your favorite albums will appear here.\nGo to the Browse section to add albums you love."),
+        _NS("Your favorite tracks will appear here.\nGo to the Browse section to add tracks you love."),
+        _NS("Your favorite genres will appear here.\nGo to the Browse section to add genres you love."),
+    ];
+}
+
+- (void)setupAudioSegmentedControl
+{
+    _audioSegmentedControl.segmentCount = 4;
+    [_audioSegmentedControl setLabel:_NS("Artists") forSegment:VLCAudioLibraryArtistsSegment];
+    [_audioSegmentedControl setLabel:_NS("Albums") forSegment:VLCAudioLibraryAlbumsSegment];
+    [_audioSegmentedControl setLabel:_NS("Songs") forSegment:VLCAudioLibrarySongsSegment];
+    [_audioSegmentedControl setLabel:_NS("Genres") forSegment:VLCAudioLibraryGenresSegment];
+    _audioSegmentedControl.selectedSegment = 0;
+}
+
+- (void)configureAudioSegmentedControl
+{
+    [_audioSegmentedControl setTarget:self];
+    [_audioSegmentedControl setAction:@selector(segmentedControlAction:)];
+}
+
+#pragma mark - Show the audio view
+
+- (void)presentAudioView
+{
+    for (NSView *subview in _libraryTargetView.subviews) {
+        [subview removeFromSuperview];
+    }
+
+    if (_audioDataSource.libraryModel.numberOfAudioMedia == 0) { // empty library
+        [self presentPlaceholderAudioView];
+    } else {
+        [self presentAudioLibraryView];
+    }
+
+    _librarySortButton.hidden = NO;
+    _librarySearchField.enabled = YES;
+    _optionBarView.hidden = NO;
+    _audioSegmentedControl.hidden = NO;
+}
+
+- (void)presentPlaceholderAudioView
+{
+    for (NSLayoutConstraint *constraint in [VLCMain sharedInstance].libraryWindow.videoPlaceholderImageViewSizeConstraints) {
+        constraint.active = NO;
+    }
+    for (NSLayoutConstraint *constraint in _audioPlaceholderImageViewSizeConstraints) {
+        constraint.active = YES;
+    }
+
+    NSInteger selectedLibrarySegment = _audioSegmentedControl.selectedSegment;
+
+    if(selectedLibrarySegment < _placeholderImageNames.count && selectedLibrarySegment >= 0) {
+        _placeholderImageView.image = [NSImage imageNamed:_placeholderImageNames[selectedLibrarySegment]];
+    }
+
+    if(selectedLibrarySegment < _placeholderLabelStrings.count && selectedLibrarySegment >= 0) {
+        _placeholderLabel.stringValue = _placeholderLabelStrings[selectedLibrarySegment];
+    }
+
+    _emptyLibraryView.translatesAutoresizingMaskIntoConstraints = NO;
+    [_libraryTargetView addSubview:_emptyLibraryView];
+    NSDictionary *dict = NSDictionaryOfVariableBindings(_emptyLibraryView);
+    [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_emptyLibraryView(>=572.)]|" options:0 metrics:0 views:dict]];
+    [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_emptyLibraryView(>=444.)]|" options:0 metrics:0 views:dict]];
+}
+
+- (void)presentAudioLibraryView
+{
+    _audioLibraryView.translatesAutoresizingMaskIntoConstraints = NO;
+    [_libraryTargetView addSubview:_audioLibraryView];
+    NSDictionary *dict = NSDictionaryOfVariableBindings(_audioLibraryView);
+    [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_audioLibraryView(>=572.)]|" options:0 metrics:0 views:dict]];
+    [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_audioLibraryView(>=444.)]|" options:0 metrics:0 views:dict]];
+
+    if (self.gridVsListSegmentedControl.selectedSegment == VLCGridViewModeSegment) {
+        _audioLibrarySplitView.hidden = YES;
+        _audioSongTableViewScrollView.hidden = YES;
+        _audioCollectionViewScrollView.hidden = NO;
+    } else {
+        [self presentAudioTableView];
+        _audioCollectionViewScrollView.hidden = YES;
+    }
+
+    [self configureAudioSegmentedControl];
+    [self segmentedControlAction:VLCMain.sharedInstance.libraryWindow.navigationStack];
+}
+
+- (void)presentAudioTableView
+{
+    if (_audioSegmentedControl.selectedSegment == VLCAudioLibrarySongsSegment) {
+        _audioLibrarySplitView.hidden = YES;
+        _audioSongTableViewScrollView.hidden = NO;
+        return;
+    }
+    _audioSongTableViewScrollView.hidden = YES;
+    _audioLibrarySplitView.hidden = NO;
+}
+
+- (IBAction)segmentedControlAction:(id)sender
+{
+    _audioDataSource.audioLibrarySegment = _audioSegmentedControl.selectedSegment;
+
+    if (_audioDataSource.libraryModel.listOfAudioMedia.count == 0) {
+        return;
+    }
+
+    if (self.gridVsListSegmentedControl.selectedSegment == VLCListViewModeSegment) {
+        [self presentAudioTableView];
+    }
+
+    VLCLibraryNavigationStack *globalNavStack = VLCMain.sharedInstance.libraryWindow.navigationStack;
+    if(sender != globalNavStack) {
+        [globalNavStack appendCurrentLibraryState];
+    }
+}
+
+- (void)reloadData
+{
+    [_audioDataSource reloadData];
+}
+
+ at end


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h
=====================================
@@ -21,7 +21,8 @@
  *****************************************************************************/
 
 #import <Cocoa/Cocoa.h>
-#import "VLCLibraryCollectionViewSupplementaryDetailView.h"
+
+#import "library/VLCLibraryCollectionViewSupplementaryDetailView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
=====================================
@@ -33,8 +33,9 @@
 #import "extensions/NSFont+VLCAdditions.h"
 #import "extensions/NSColor+VLCAdditions.h"
 #import "extensions/NSView+VLCAdditions.h"
-#import "library/VLCLibraryAlbumTracksDataSource.h"
-#import "library/VLCLibraryAlbumTableCellView.h"
+
+#import "library/audio-library/VLCLibraryAlbumTracksDataSource.h"
+#import "library/audio-library/VLCLibraryAlbumTableCellView.h"
 
 NSString *const VLCLibraryCollectionViewAlbumSupplementaryDetailViewIdentifier = @"VLCLibraryCollectionViewAlbumSupplementaryDetailViewIdentifier";
 NSCollectionViewSupplementaryElementKind const VLCLibraryCollectionViewAlbumSupplementaryDetailViewKind = @"VLCLibraryCollectionViewAlbumSupplementaryDetailViewIdentifier";


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.h
=====================================
@@ -21,7 +21,8 @@
  *****************************************************************************/
 
 #import <Cocoa/Cocoa.h>
-#import "VLCLibraryCollectionViewSupplementaryDetailView.h"
+
+#import "library/VLCLibraryCollectionViewSupplementaryDetailView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m → modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.m
=====================================
@@ -24,7 +24,8 @@
 
 #import "library/VLCLibraryDataTypes.h"
 #import "extensions/NSFont+VLCAdditions.h"
-#import "library/VLCLibraryAudioDataSource.h"
+
+#import "library/audio-library/VLCLibraryAudioDataSource.h"
 
 NSString *const VLCLibraryCollectionViewAudioGroupSupplementaryDetailViewIdentifier = @"VLCLibraryCollectionViewAudioGroupSupplementaryDetailViewIdentifier";
 NSCollectionViewSupplementaryElementKind const VLCLibraryCollectionViewAudioGroupSupplementaryDetailViewKind = @"VLCLibraryCollectionViewAudioGroupSupplementaryDetailViewIdentifier";


=====================================
modules/gui/macosx/library/VLCLibrarySongTableCellView.h → modules/gui/macosx/library/audio-library/VLCLibrarySongTableCellView.h
=====================================


=====================================
modules/gui/macosx/library/VLCLibrarySongTableCellView.m → modules/gui/macosx/library/audio-library/VLCLibrarySongTableCellView.m
=====================================
@@ -32,7 +32,7 @@
 #import "library/VLCLibraryController.h"
 #import "library/VLCLibraryDataTypes.h"
 #import "library/VLCLibraryTableCellView.h"
-#import "library/VLCLibraryAlbumTracksDataSource.h"
+#import "library/audio-library/VLCLibraryAlbumTracksDataSource.h"
 
 NSString *VLCAudioLibrarySongCellIdentifier = @"VLCAudioLibrarySongCellIdentifier";
 


=====================================
modules/gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.h
=====================================
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * VLCLibrarySongsTableViewSongPlayingTableCellView.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+ at class VLCMediaLibraryMediaItem;
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at interface VLCLibrarySongsTableViewSongPlayingTableCellView : NSTableCellView
+
+ at property (readwrite, assign, nonatomic) VLCMediaLibraryMediaItem *representedMediaItem;
+
+ at end
+
+NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/library/audio-library/VLCLibrarySongsTableViewSongPlayingTableCellView.m
=====================================
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * VLCLibrarySongsTableViewSongPlayingTableCellView.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * 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 "VLCLibrarySongsTableViewSongPlayingTableCellView.h"
+
+#import "library/VLCInputItem.h"
+#import "library/VLCLibraryDataTypes.h"
+#import "main/VLCMain.h"
+#import "playlist/VLCPlayerController.h"
+#import "playlist/VLCPlaylistController.h"
+
+ at implementation VLCLibrarySongsTableViewSongPlayingTableCellView
+
+- (void)awakeFromNib
+{
+    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+    [notificationCenter addObserver:self
+                           selector:@selector(playStateOrItemChanged:)
+                               name:VLCPlaylistCurrentItemChanged
+                             object:nil];
+    [notificationCenter addObserver:self
+                           selector:@selector(playStateOrItemChanged:)
+                               name:VLCPlayerStateChanged
+                             object:nil];
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)prepareForReuse
+{
+    [super prepareForReuse];
+    self.textField.stringValue = @"";
+}
+
+- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem
+{
+    _representedMediaItem = representedMediaItem;
+    [self updatePlayState];
+}
+
+- (BOOL)isCurrentSong
+{
+    if (!_representedMediaItem) {
+        return false;
+    }
+
+    return [_representedMediaItem.inputItem.MRL isEqualToString:VLCMain.sharedInstance.playlistController.currentlyPlayingInputItem.MRL];
+}
+
+- (void)updatePlayState
+{
+    if (!_representedMediaItem || ![self isCurrentSong]) {
+        self.textField.stringValue = @"";
+        return;
+    }
+
+    NSString *text = @"";
+
+    switch(VLCMain.sharedInstance.playlistController.playerController.playerState) {
+        case VLC_PLAYER_STATE_PAUSED:
+            text = @"⏸︎";
+            break;
+        case VLC_PLAYER_STATE_PLAYING:
+            text = @"▶";
+        default:
+            break;
+    }
+
+    self.textField.stringValue = text;
+}
+
+- (void)playStateOrItemChanged:(id)sender
+{
+    [self updatePlayState];
+}
+
+ at end


=====================================
po/POTFILES.in
=====================================
@@ -458,10 +458,6 @@ modules/gui/macosx/extensions/VLCPositionFormatter.h
 modules/gui/macosx/extensions/VLCPositionFormatter.m
 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/VLCLibraryAudioDataSource.h
-modules/gui/macosx/library/VLCLibraryAudioDataSource.m
 modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
 modules/gui/macosx/library/VLCLibraryCollectionViewItem.m
 modules/gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.h
@@ -482,6 +478,10 @@ modules/gui/macosx/library/VLCLibrarySortingMenuController.h
 modules/gui/macosx/library/VLCLibrarySortingMenuController.m
 modules/gui/macosx/library/VLCLibraryTableCellView.h
 modules/gui/macosx/library/VLCLibraryTableCellView.m
+modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h
+modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
+modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h
+modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
 modules/gui/macosx/library/video-library/VLCLibraryVideoGroupDescriptor.h
 modules/gui/macosx/library/video-library/VLCLibraryVideoGroupDescriptor.m
 modules/gui/macosx/library/video-library/VLCLibraryVideoTableViewDataSource.h



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0f6b7fab25d8c79f078b0c7b7a98ea4ebe3e2b5a...bd1222e8c445398474a334065a08adbd0f208676

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0f6b7fab25d8c79f078b0c7b7a98ea4ebe3e2b5a...bd1222e8c445398474a334065a08adbd0f208676
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list