[vlc-commits] [Git][videolan/vlc][master] macosx: Unify collection view item types

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Tue Jul 19 16:13:50 UTC 2022



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
fa106a29 by Claudio Cambra at 2022-07-19T15:55:25+00:00
macosx: Unify collection view item types

Signed-off-by: Claudio Cambra <claudio.cambra at gmail.com>

- - - - -


20 changed files:

- modules/gui/macosx/Makefile.am
- − modules/gui/macosx/UI/VLCLibraryCollectionViewAlbumItem.xib
- − modules/gui/macosx/UI/VLCLibraryCollectionViewArtistItem.xib
- − modules/gui/macosx/UI/VLCLibraryCollectionViewGenreItem.xib
- modules/gui/macosx/library/VLCLibraryCollectionViewGenreItem.h → modules/gui/macosx/extensions/NSImage+Helpers.h
- modules/gui/macosx/library/VLCLibraryCollectionViewArtistItem.h → modules/gui/macosx/extensions/NSImage+Helpers.m
- modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m
- modules/gui/macosx/library/VLCLibraryAudioDataSource.m
- − modules/gui/macosx/library/VLCLibraryCollectionViewAlbumItem.h
- − modules/gui/macosx/library/VLCLibraryCollectionViewAlbumItem.m
- − modules/gui/macosx/library/VLCLibraryCollectionViewArtistItem.m
- − modules/gui/macosx/library/VLCLibraryCollectionViewGenreItem.m
- modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
- modules/gui/macosx/library/VLCLibraryCollectionViewItem.m
- − modules/gui/macosx/library/VLCLibraryCollectionViewItemProtocol.h
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/library/VLCLibraryMenuController.h
- modules/gui/macosx/library/VLCLibraryMenuController.m
- modules/gui/macosx/library/VLCLibraryVideoDataSource.m


Changes:

=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -36,6 +36,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/extensions/NSColor+VLCAdditions.m \
 	gui/macosx/extensions/NSFont+VLCAdditions.h \
 	gui/macosx/extensions/NSFont+VLCAdditions.m \
+	gui/macosx/extensions/NSImage+Helpers.h \
+	gui/macosx/extensions/NSImage+Helpers.m \
 	gui/macosx/extensions/NSMenu+VLCAdditions.h \
 	gui/macosx/extensions/NSMenu+VLCAdditions.m \
 	gui/macosx/extensions/NSScreen+VLCAdditions.h \
@@ -60,13 +62,6 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/library/VLCLibraryAudioDataSource.m \
 	gui/macosx/library/VLCLibraryCollectionViewItem.h \
 	gui/macosx/library/VLCLibraryCollectionViewItem.m \
-	gui/macosx/library/VLCLibraryCollectionViewAlbumItem.h \
-	gui/macosx/library/VLCLibraryCollectionViewAlbumItem.m \
-	gui/macosx/library/VLCLibraryCollectionViewArtistItem.h \
-	gui/macosx/library/VLCLibraryCollectionViewArtistItem.m \
-	gui/macosx/library/VLCLibraryCollectionViewGenreItem.h \
-	gui/macosx/library/VLCLibraryCollectionViewGenreItem.m \
-	gui/macosx/library/VLCLibraryCollectionViewItemProtocol.h \
 	gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.h \
 	gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.m \
 	gui/macosx/library/VLCLibraryController.h \
@@ -302,9 +297,6 @@ libmacosx_plugin_la_XIB_SOURCES = \
 	gui/macosx/UI/VLCLibraryTableCellView.xib \
 	gui/macosx/UI/VLCPlaylistTableCellView.xib \
 	gui/macosx/UI/VLCLibraryCollectionViewItem.xib \
-	gui/macosx/UI/VLCLibraryCollectionViewAlbumItem.xib \
-	gui/macosx/UI/VLCLibraryCollectionViewArtistItem.xib \
-	gui/macosx/UI/VLCLibraryCollectionViewGenreItem.xib \
 	gui/macosx/UI/VLCMediaSourceCollectionViewItem.xib \
 	gui/macosx/UI/VLCMediaSourceDeviceCollectionViewItem.xib \
 	gui/macosx/UI/VLCInformationWindow.xib \


=====================================
modules/gui/macosx/UI/VLCLibraryCollectionViewAlbumItem.xib deleted
=====================================
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryCollectionViewAlbumItem">
-            <connections>
-                <outlet property="addToPlaylistButton" destination="Ubz-8I-W2F" id="k0q-b1-PZi"/>
-                <outlet property="annotationTextField" destination="tm2-NW-WsZ" id="Miy-RS-Rol"/>
-                <outlet property="durationTextField" destination="VAn-gF-QiZ" id="U8T-Cs-HaL"/>
-                <outlet property="mediaImageView" destination="2aB-sB-hfY" id="Sv0-G1-KNm"/>
-                <outlet property="mediaTitleTextField" destination="OBS-Eh-1mT" id="h1n-PU-IAx"/>
-                <outlet property="playInstantlyButton" destination="S3I-5Z-qgS" id="JlC-bE-i5Y"/>
-                <outlet property="progressIndicator" destination="dFt-oZ-h9P" id="JC6-gk-Mid"/>
-                <outlet property="unplayedIndicatorTextField" destination="u2r-zy-XEW" id="56s-K4-Kxr"/>
-                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customView id="Hz6-mo-xeY" customClass="VLCTrackingView">
-            <rect key="frame" x="0.0" y="0.0" width="256" height="214"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-            <subviews>
-                <customView translatesAutoresizingMaskIntoConstraints="NO" id="2aB-sB-hfY" customClass="VLCImageView">
-                    <rect key="frame" x="0.0" y="49" width="256" height="165"/>
-                    <subviews>
-                        <customView translatesAutoresizingMaskIntoConstraints="NO" id="dFt-oZ-h9P" customClass="VLCLinearProgressIndicator">
-                            <rect key="frame" x="0.0" y="0.0" width="256" height="4"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="4" id="lyQ-kl-gVk"/>
-                            </constraints>
-                        </customView>
-                        <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S3I-5Z-qgS">
-                            <rect key="frame" x="96" y="51" width="64" height="64"/>
-                            <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="libraryPlay" imagePosition="only" alignment="center" inset="2" id="IHP-p1-d0R">
-                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                <font key="font" metaFont="system"/>
-                            </buttonCell>
-                            <connections>
-                                <action selector="playInstantly:" target="-2" id="E2B-oj-rx3"/>
-                            </connections>
-                        </button>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tm2-NW-WsZ" customClass="VLCRoundedCornerTextField">
-                            <rect key="frame" x="8" y="141" width="37" height="17"/>
-                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="tyb-Ur-7J9">
-                                <font key="font" metaFont="system"/>
-                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                            </textFieldCell>
-                        </textField>
-                    </subviews>
-                    <constraints>
-                        <constraint firstAttribute="bottom" secondItem="dFt-oZ-h9P" secondAttribute="bottom" id="4q3-3S-7PA"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerX" secondItem="2aB-sB-hfY" secondAttribute="centerX" id="Seo-tS-piW"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerY" secondItem="2aB-sB-hfY" secondAttribute="centerY" id="ZWU-oW-OVa"/>
-                        <constraint firstItem="dFt-oZ-h9P" firstAttribute="leading" secondItem="2aB-sB-hfY" secondAttribute="leading" id="gTe-sx-hdP"/>
-                        <constraint firstAttribute="trailing" secondItem="dFt-oZ-h9P" secondAttribute="trailing" id="kBI-UU-vnc"/>
-                    </constraints>
-                </customView>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OBS-Eh-1mT">
-                    <rect key="frame" x="-2" y="21" width="52" height="24"/>
-                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" title="Label" usesSingleLineMode="YES" id="7Hy-o3-LvX">
-                        <font key="font" size="20" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u2r-zy-XEW">
-                    <rect key="frame" x="224" y="1" width="34" height="17"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="NEW" id="NeT-5U-eZn">
-                        <font key="font" metaFont="system"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ubz-8I-W2F">
-                    <rect key="frame" x="222" y="187" width="20" height="20"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="20" id="XhX-7U-Nxj"/>
-                        <constraint firstAttribute="height" constant="20" id="ZDT-YM-Cbr"/>
-                    </constraints>
-                    <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="ellipsis" imagePosition="only" alignment="center" inset="2" id="6ko-MM-ds0">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="addToPlaylist:" target="-2" id="2C9-Rn-VAb"/>
-                    </connections>
-                </button>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAn-gF-QiZ">
-                    <rect key="frame" x="-2" y="0.0" width="42" height="19"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="LSS-jh-llZ">
-                        <font key="font" size="15" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-            </subviews>
-            <constraints>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="3Ah-0T-rA9"/>
-                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="OBS-Eh-1mT" secondAttribute="trailing" id="457-oy-EbD"/>
-                <constraint firstItem="Ubz-8I-W2F" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="8Qf-Un-Gdl"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="top" secondItem="OBS-Eh-1mT" secondAttribute="bottom" constant="2" id="ALi-0z-Mza"/>
-                <constraint firstAttribute="trailing" secondItem="u2r-zy-XEW" secondAttribute="trailing" id="Dd7-va-0UJ"/>
-                <constraint firstItem="u2r-zy-XEW" firstAttribute="centerY" secondItem="VAn-gF-QiZ" secondAttribute="centerY" id="H5N-j9-THf"/>
-                <constraint firstAttribute="bottom" secondItem="VAn-gF-QiZ" secondAttribute="bottom" id="Kp0-Hx-3Ek"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="QUW-dn-Fbc"/>
-                <constraint firstAttribute="trailing" secondItem="Ubz-8I-W2F" secondAttribute="trailing" constant="14" id="ZVz-SL-rxZ"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="cvk-A5-enS"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="10" id="fH0-Om-7gV"/>
-                <constraint firstAttribute="trailing" secondItem="2aB-sB-hfY" secondAttribute="trailing" id="oZw-Ab-83p"/>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="t9g-tX-AQX"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="top" secondItem="2aB-sB-hfY" secondAttribute="bottom" constant="4" id="vJy-Kf-4Jh"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="yvp-xr-geN"/>
-            </constraints>
-        </customView>
-    </objects>
-    <resources>
-        <image name="ellipsis" width="17" height="3"/>
-        <image name="libraryPlay" width="64" height="64"/>
-    </resources>
-</document>


=====================================
modules/gui/macosx/UI/VLCLibraryCollectionViewArtistItem.xib deleted
=====================================
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryCollectionViewArtistItem">
-            <connections>
-                <outlet property="addToPlaylistButton" destination="Ubz-8I-W2F" id="k0q-b1-PZi"/>
-                <outlet property="annotationTextField" destination="tm2-NW-WsZ" id="Miy-RS-Rol"/>
-                <outlet property="durationTextField" destination="VAn-gF-QiZ" id="U8T-Cs-HaL"/>
-                <outlet property="mediaImageView" destination="2aB-sB-hfY" id="Sv0-G1-KNm"/>
-                <outlet property="mediaTitleTextField" destination="OBS-Eh-1mT" id="h1n-PU-IAx"/>
-                <outlet property="playInstantlyButton" destination="S3I-5Z-qgS" id="JlC-bE-i5Y"/>
-                <outlet property="progressIndicator" destination="dFt-oZ-h9P" id="JC6-gk-Mid"/>
-                <outlet property="unplayedIndicatorTextField" destination="u2r-zy-XEW" id="56s-K4-Kxr"/>
-                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customView id="Hz6-mo-xeY" customClass="VLCTrackingView">
-            <rect key="frame" x="0.0" y="0.0" width="256" height="214"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-            <subviews>
-                <customView translatesAutoresizingMaskIntoConstraints="NO" id="2aB-sB-hfY" customClass="VLCImageView">
-                    <rect key="frame" x="0.0" y="49" width="256" height="165"/>
-                    <subviews>
-                        <customView translatesAutoresizingMaskIntoConstraints="NO" id="dFt-oZ-h9P" customClass="VLCLinearProgressIndicator">
-                            <rect key="frame" x="0.0" y="0.0" width="256" height="4"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="4" id="lyQ-kl-gVk"/>
-                            </constraints>
-                        </customView>
-                        <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S3I-5Z-qgS">
-                            <rect key="frame" x="96" y="51" width="64" height="64"/>
-                            <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="libraryPlay" imagePosition="only" alignment="center" inset="2" id="IHP-p1-d0R">
-                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                <font key="font" metaFont="system"/>
-                            </buttonCell>
-                            <connections>
-                                <action selector="playInstantly:" target="-2" id="E2B-oj-rx3"/>
-                            </connections>
-                        </button>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tm2-NW-WsZ" customClass="VLCRoundedCornerTextField">
-                            <rect key="frame" x="8" y="141" width="37" height="17"/>
-                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="tyb-Ur-7J9">
-                                <font key="font" metaFont="system"/>
-                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                            </textFieldCell>
-                        </textField>
-                    </subviews>
-                    <constraints>
-                        <constraint firstAttribute="bottom" secondItem="dFt-oZ-h9P" secondAttribute="bottom" id="4q3-3S-7PA"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerX" secondItem="2aB-sB-hfY" secondAttribute="centerX" id="Seo-tS-piW"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerY" secondItem="2aB-sB-hfY" secondAttribute="centerY" id="ZWU-oW-OVa"/>
-                        <constraint firstItem="dFt-oZ-h9P" firstAttribute="leading" secondItem="2aB-sB-hfY" secondAttribute="leading" id="gTe-sx-hdP"/>
-                        <constraint firstAttribute="trailing" secondItem="dFt-oZ-h9P" secondAttribute="trailing" id="kBI-UU-vnc"/>
-                    </constraints>
-                </customView>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OBS-Eh-1mT">
-                    <rect key="frame" x="-2" y="21" width="52" height="24"/>
-                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" title="Label" usesSingleLineMode="YES" id="7Hy-o3-LvX">
-                        <font key="font" size="20" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u2r-zy-XEW">
-                    <rect key="frame" x="224" y="1" width="34" height="17"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="NEW" id="NeT-5U-eZn">
-                        <font key="font" metaFont="system"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ubz-8I-W2F">
-                    <rect key="frame" x="222" y="187" width="20" height="20"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="20" id="XhX-7U-Nxj"/>
-                        <constraint firstAttribute="height" constant="20" id="ZDT-YM-Cbr"/>
-                    </constraints>
-                    <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="ellipsis" imagePosition="only" alignment="center" inset="2" id="6ko-MM-ds0">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="addToPlaylist:" target="-2" id="2C9-Rn-VAb"/>
-                    </connections>
-                </button>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAn-gF-QiZ">
-                    <rect key="frame" x="-2" y="0.0" width="42" height="19"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="LSS-jh-llZ">
-                        <font key="font" size="15" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-            </subviews>
-            <constraints>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="3Ah-0T-rA9"/>
-                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="OBS-Eh-1mT" secondAttribute="trailing" id="457-oy-EbD"/>
-                <constraint firstItem="Ubz-8I-W2F" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="8Qf-Un-Gdl"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="top" secondItem="OBS-Eh-1mT" secondAttribute="bottom" constant="2" id="ALi-0z-Mza"/>
-                <constraint firstAttribute="trailing" secondItem="u2r-zy-XEW" secondAttribute="trailing" id="Dd7-va-0UJ"/>
-                <constraint firstItem="u2r-zy-XEW" firstAttribute="centerY" secondItem="VAn-gF-QiZ" secondAttribute="centerY" id="H5N-j9-THf"/>
-                <constraint firstAttribute="bottom" secondItem="VAn-gF-QiZ" secondAttribute="bottom" id="Kp0-Hx-3Ek"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="QUW-dn-Fbc"/>
-                <constraint firstAttribute="trailing" secondItem="Ubz-8I-W2F" secondAttribute="trailing" constant="14" id="ZVz-SL-rxZ"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="cvk-A5-enS"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="10" id="fH0-Om-7gV"/>
-                <constraint firstAttribute="trailing" secondItem="2aB-sB-hfY" secondAttribute="trailing" id="oZw-Ab-83p"/>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="t9g-tX-AQX"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="top" secondItem="2aB-sB-hfY" secondAttribute="bottom" constant="4" id="vJy-Kf-4Jh"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="yvp-xr-geN"/>
-            </constraints>
-        </customView>
-    </objects>
-    <resources>
-        <image name="ellipsis" width="17" height="3"/>
-        <image name="libraryPlay" width="64" height="64"/>
-    </resources>
-</document>


=====================================
modules/gui/macosx/UI/VLCLibraryCollectionViewGenreItem.xib deleted
=====================================
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryCollectionViewAlbumItem">
-            <connections>
-                <outlet property="addToPlaylistButton" destination="Ubz-8I-W2F" id="k0q-b1-PZi"/>
-                <outlet property="annotationTextField" destination="tm2-NW-WsZ" id="Miy-RS-Rol"/>
-                <outlet property="durationTextField" destination="VAn-gF-QiZ" id="U8T-Cs-HaL"/>
-                <outlet property="mediaImageView" destination="2aB-sB-hfY" id="Sv0-G1-KNm"/>
-                <outlet property="mediaTitleTextField" destination="OBS-Eh-1mT" id="h1n-PU-IAx"/>
-                <outlet property="playInstantlyButton" destination="S3I-5Z-qgS" id="JlC-bE-i5Y"/>
-                <outlet property="progressIndicator" destination="dFt-oZ-h9P" id="JC6-gk-Mid"/>
-                <outlet property="unplayedIndicatorTextField" destination="u2r-zy-XEW" id="56s-K4-Kxr"/>
-                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customView id="Hz6-mo-xeY" customClass="VLCTrackingView">
-            <rect key="frame" x="0.0" y="0.0" width="256" height="214"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-            <subviews>
-                <customView translatesAutoresizingMaskIntoConstraints="NO" id="2aB-sB-hfY" customClass="VLCImageView">
-                    <rect key="frame" x="0.0" y="49" width="256" height="165"/>
-                    <subviews>
-                        <customView translatesAutoresizingMaskIntoConstraints="NO" id="dFt-oZ-h9P" customClass="VLCLinearProgressIndicator">
-                            <rect key="frame" x="0.0" y="0.0" width="256" height="4"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="4" id="lyQ-kl-gVk"/>
-                            </constraints>
-                        </customView>
-                        <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="S3I-5Z-qgS">
-                            <rect key="frame" x="96" y="51" width="64" height="64"/>
-                            <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="libraryPlay" imagePosition="only" alignment="center" inset="2" id="IHP-p1-d0R">
-                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                                <font key="font" metaFont="system"/>
-                            </buttonCell>
-                            <connections>
-                                <action selector="playInstantly:" target="-2" id="E2B-oj-rx3"/>
-                            </connections>
-                        </button>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tm2-NW-WsZ" customClass="VLCRoundedCornerTextField">
-                            <rect key="frame" x="8" y="141" width="37" height="17"/>
-                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="tyb-Ur-7J9">
-                                <font key="font" metaFont="system"/>
-                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                            </textFieldCell>
-                        </textField>
-                    </subviews>
-                    <constraints>
-                        <constraint firstAttribute="bottom" secondItem="dFt-oZ-h9P" secondAttribute="bottom" id="4q3-3S-7PA"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerX" secondItem="2aB-sB-hfY" secondAttribute="centerX" id="Seo-tS-piW"/>
-                        <constraint firstItem="S3I-5Z-qgS" firstAttribute="centerY" secondItem="2aB-sB-hfY" secondAttribute="centerY" id="ZWU-oW-OVa"/>
-                        <constraint firstItem="dFt-oZ-h9P" firstAttribute="leading" secondItem="2aB-sB-hfY" secondAttribute="leading" id="gTe-sx-hdP"/>
-                        <constraint firstAttribute="trailing" secondItem="dFt-oZ-h9P" secondAttribute="trailing" id="kBI-UU-vnc"/>
-                    </constraints>
-                </customView>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OBS-Eh-1mT">
-                    <rect key="frame" x="-2" y="21" width="52" height="24"/>
-                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" title="Label" usesSingleLineMode="YES" id="7Hy-o3-LvX">
-                        <font key="font" size="20" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u2r-zy-XEW">
-                    <rect key="frame" x="224" y="1" width="34" height="17"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="NEW" id="NeT-5U-eZn">
-                        <font key="font" metaFont="system"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ubz-8I-W2F">
-                    <rect key="frame" x="222" y="187" width="20" height="20"/>
-                    <constraints>
-                        <constraint firstAttribute="width" constant="20" id="XhX-7U-Nxj"/>
-                        <constraint firstAttribute="height" constant="20" id="ZDT-YM-Cbr"/>
-                    </constraints>
-                    <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="ellipsis" imagePosition="only" alignment="center" inset="2" id="6ko-MM-ds0">
-                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
-                    </buttonCell>
-                    <connections>
-                        <action selector="addToPlaylist:" target="-2" id="2C9-Rn-VAb"/>
-                    </connections>
-                </button>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VAn-gF-QiZ">
-                    <rect key="frame" x="-2" y="0.0" width="42" height="19"/>
-                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="LSS-jh-llZ">
-                        <font key="font" size="15" name=".AppleSystemUIFont"/>
-                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
-                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
-                    </textFieldCell>
-                </textField>
-            </subviews>
-            <constraints>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="3Ah-0T-rA9"/>
-                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="OBS-Eh-1mT" secondAttribute="trailing" id="457-oy-EbD"/>
-                <constraint firstItem="Ubz-8I-W2F" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="8Qf-Un-Gdl"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="top" secondItem="OBS-Eh-1mT" secondAttribute="bottom" constant="2" id="ALi-0z-Mza"/>
-                <constraint firstAttribute="trailing" secondItem="u2r-zy-XEW" secondAttribute="trailing" id="Dd7-va-0UJ"/>
-                <constraint firstItem="u2r-zy-XEW" firstAttribute="centerY" secondItem="VAn-gF-QiZ" secondAttribute="centerY" id="H5N-j9-THf"/>
-                <constraint firstAttribute="bottom" secondItem="VAn-gF-QiZ" secondAttribute="bottom" id="Kp0-Hx-3Ek"/>
-                <constraint firstItem="VAn-gF-QiZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="QUW-dn-Fbc"/>
-                <constraint firstAttribute="trailing" secondItem="Ubz-8I-W2F" secondAttribute="trailing" constant="14" id="ZVz-SL-rxZ"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="7" id="cvk-A5-enS"/>
-                <constraint firstItem="tm2-NW-WsZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="10" id="fH0-Om-7gV"/>
-                <constraint firstAttribute="trailing" secondItem="2aB-sB-hfY" secondAttribute="trailing" id="oZw-Ab-83p"/>
-                <constraint firstItem="2aB-sB-hfY" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="t9g-tX-AQX"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="top" secondItem="2aB-sB-hfY" secondAttribute="bottom" constant="4" id="vJy-Kf-4Jh"/>
-                <constraint firstItem="OBS-Eh-1mT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="yvp-xr-geN"/>
-            </constraints>
-        </customView>
-    </objects>
-    <resources>
-        <image name="ellipsis" width="17" height="3"/>
-        <image name="libraryPlay" width="64" height="64"/>
-    </resources>
-</document>


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewGenreItem.h → modules/gui/macosx/extensions/NSImage+Helpers.h
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * VLCLibraryCollectionViewGenreItem.h: MacOS X interface module
+ * NSImage+Helpers.h: MacOS X interface module
  *****************************************************************************
  * Copyright (C) 2022 VLC authors and VideoLAN
  *
@@ -21,19 +21,13 @@
  *****************************************************************************/
 
 #import <Cocoa/Cocoa.h>
-#import "VLCLibraryCollectionViewItemProtocol.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
- at class VLCMediaLibraryGenre;
+ at interface NSImage (Helpers)
 
-extern NSString *VLCLibraryGenreCellIdentifier;
-
- at interface VLCLibraryCollectionViewGenreItem : NSCollectionViewItem<VLCLibraryCollectionViewItemProtocol>
-
- at property (readwrite, retain, nonatomic) VLCMediaLibraryGenre *representedGenre;
++ (instancetype)artworkOrPlaceholderFromMrl:(NSString *)artworkMRL;
 
 @end
 
-NS_ASSUME_NONNULL_END
-
+NS_ASSUME_NONNULL_END
\ No newline at end of file


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewArtistItem.h → modules/gui/macosx/extensions/NSImage+Helpers.m
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * VLCLibraryCollectionViewArtistItem.h: MacOS X interface module
+ * NSImage+Helpers.h: MacOS X interface module
  *****************************************************************************
  * Copyright (C) 2022 VLC authors and VideoLAN
  *
@@ -20,20 +20,24 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#import <Cocoa/Cocoa.h>
-#import "VLCLibraryCollectionViewItemProtocol.h"
+#import "NSImage+Helpers.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
- at class VLCMediaLibraryArtist;
+ at implementation NSImage (Helpers)
 
-extern NSString *VLCLibraryArtistCellIdentifier;
-
- at interface VLCLibraryCollectionViewArtistItem : NSCollectionViewItem<VLCLibraryCollectionViewItemProtocol>
-
- at property (readwrite, retain, nonatomic) VLCMediaLibraryArtist *representedArtist;
++ (instancetype)artworkOrPlaceholderFromMrl:(NSString *)artworkMRL
+{
+    NSImage *image = nil;
+    if (artworkMRL.length > 0) {
+        image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:artworkMRL]];
+    }
+    if (!image) {
+        image = [NSImage imageNamed: @"noart.png"];
+    }
+    return image;
+}
 
 @end
 
-NS_ASSUME_NONNULL_END
-
+NS_ASSUME_NONNULL_END
\ No newline at end of file


=====================================
modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m
=====================================
@@ -128,21 +128,10 @@ const CGFloat LayoutSpacer;
     if (_representedAlbum.summary.length > 0) {
         self.summaryTextField.stringValue = _representedAlbum.summary;
     } else {
-        if (_representedAlbum.numberOfTracks > 1) {
-            self.summaryTextField.stringValue = [NSString stringWithFormat:_NS("%i tracks"), _representedAlbum.numberOfTracks];
-        } else {
-            self.summaryTextField.stringValue = _NS("1 track");
-        }
+        self.summaryTextField.stringValue = _representedAlbum.durationString;
     }
 
-    NSImage *image;
-    if (_representedAlbum.artworkMRL.length > 0) {
-        image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:_representedAlbum.artworkMRL]];
-    }
-    if (!image) {
-        image = [NSImage imageNamed: @"noart.png"];
-    }
-    self.representedImageView.image = image;
+    self.representedImageView.image = _representedAlbum.smallArtworkImage;
 
     _tracksDataSource.representedAlbum = _representedAlbum;
     [_tracksTableView reloadData];


=====================================
modules/gui/macosx/library/VLCLibraryAudioDataSource.m
=====================================
@@ -30,9 +30,6 @@
 #import "library/VLCLibraryTableCellView.h"
 #import "library/VLCLibraryAlbumTableCellView.h"
 #import "library/VLCLibraryCollectionViewItem.h"
-#import "library/VLCLibraryCollectionViewAlbumItem.h"
-#import "library/VLCLibraryCollectionViewArtistItem.h"
-#import "library/VLCLibraryCollectionViewGenreItem.h"
 
 #import "extensions/NSString+Helpers.h"
 #import "views/VLCImageView.h"
@@ -70,9 +67,6 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
     _collectionView.delegate = self;
 
     [_collectionView registerClass:[VLCLibraryCollectionViewItem class] forItemWithIdentifier:VLCLibraryCellIdentifier];
-    [_collectionView registerClass:[VLCLibraryCollectionViewAlbumItem class] forItemWithIdentifier:VLCLibraryAlbumCellIdentifier];
-    [_collectionView registerClass:[VLCLibraryCollectionViewArtistItem class] forItemWithIdentifier:VLCLibraryArtistCellIdentifier];
-    [_collectionView registerClass:[VLCLibraryCollectionViewGenreItem class] forItemWithIdentifier:VLCLibraryGenreCellIdentifier];
     
     NSCollectionViewFlowLayout *flowLayout = _collectionView.collectionViewLayout;
     flowLayout.itemSize = CGSizeMake(214., 260.);
@@ -194,15 +188,7 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
 
             cellView.singlePrimaryTitleTextField.hidden = NO;
             cellView.singlePrimaryTitleTextField.stringValue = artist.name;
-
-            NSImage *image;
-            if (artist.artworkMRL.length > 0) {
-                image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:artist.artworkMRL]];
-            }
-            if (!image) {
-                image = [NSImage imageNamed: @"noart.png"];
-            }
-            cellView.representedImageView.image = image;
+            cellView.representedImageView.image = artist.smallArtworkImage;
             break;
         }
         case VLC_ML_PARENT_ALBUM:
@@ -213,26 +199,14 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
             cellView.secondaryTitleTextField.hidden = NO;
             cellView.primaryTitleTextField.stringValue = album.title;
             cellView.secondaryTitleTextField.stringValue = album.artistName;
-
-            NSImage *image;
-            if (album.artworkMRL.length > 0) {
-                image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:album.artworkMRL]];
-            }
-            if (!image) {
-                image = [NSImage imageNamed: @"noart.png"];
-            }
-            cellView.representedImageView.image = image;
+            cellView.representedImageView.image = album.smallArtworkImage;
             break;
         }
         case VLC_ML_PARENT_UNKNOWN:
         {
             VLCMediaLibraryMediaItem *mediaItem = _displayedCollection[row];
 
-            NSImage *image = mediaItem.smallArtworkImage;
-            if (!image) {
-                image = [NSImage imageNamed: @"noart.png"];
-            }
-            cellView.representedImageView.image = image;
+            cellView.representedImageView.image = mediaItem.smallArtworkImage;
             cellView.representedMediaItem = mediaItem;
 
             NSString *title = mediaItem.title;
@@ -262,9 +236,7 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
             cellView.secondaryTitleTextField.hidden = NO;
             cellView.primaryTitleTextField.stringValue = genre.name;
             cellView.secondaryTitleTextField.stringValue = [NSString stringWithFormat:_NS("%lli items"), genre.numberOfTracks];
-
-            NSImage *image = [NSImage imageNamed: @"noart.png"];
-            cellView.representedImageView.image = image;
+            cellView.representedImageView.image = genre.smallArtworkImage;
             break;
         }
         default:
@@ -399,31 +371,27 @@ static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier
     switch (_currentParentType) {
         case VLC_ML_PARENT_ARTIST:
         {
-            VLCLibraryCollectionViewArtistItem *viewArtistItem = [collectionView makeItemWithIdentifier:VLCLibraryArtistCellIdentifier forIndexPath:indexPath];
             VLCMediaLibraryArtist *artist = _displayedCollection[indexPath.item];
-            viewArtistItem.representedArtist = artist;
-            return viewArtistItem;
+            viewItem.representedItem = artist;
+            break;
         }
         case VLC_ML_PARENT_ALBUM:
         {
-            VLCLibraryCollectionViewAlbumItem *viewAlbumItem = [collectionView makeItemWithIdentifier:VLCLibraryAlbumCellIdentifier forIndexPath:indexPath];
             VLCMediaLibraryAlbum *album = _displayedCollection[indexPath.item];
-            viewAlbumItem.representedAlbum = album;
-            return viewAlbumItem;
+            viewItem.representedItem = album;
+            break;
         }
         case VLC_ML_PARENT_UNKNOWN:
         {
-            // This is the only one that uses the default VLCLibraryCollectionViewItem
             VLCMediaLibraryMediaItem *mediaItem = _displayedCollection[indexPath.item];
-            viewItem.representedMediaItem = mediaItem;
+            viewItem.representedItem = mediaItem;
             break;
         }
         case VLC_ML_PARENT_GENRE:
         {
-            VLCLibraryCollectionViewGenreItem *viewGenreItem = [collectionView makeItemWithIdentifier:VLCLibraryGenreCellIdentifier forIndexPath:indexPath];
             VLCMediaLibraryGenre *genre = _displayedCollection[indexPath.item];
-            viewGenreItem.representedGenre = genre;
-            return viewGenreItem;
+            viewItem.representedItem = genre;
+            break;
         }
         default:
             break;


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAlbumItem.h deleted
=====================================
@@ -1,39 +0,0 @@
-/*****************************************************************************
- * VLCLibraryCollectionViewAlbumItem.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>
-#import "VLCLibraryCollectionViewItemProtocol.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
- at class VLCMediaLibraryAlbum;
-
-extern NSString *VLCLibraryAlbumCellIdentifier;
-
- at interface VLCLibraryCollectionViewAlbumItem : NSCollectionViewItem<VLCLibraryCollectionViewItemProtocol>
-
- at property (readwrite, retain, nonatomic) VLCMediaLibraryAlbum *representedAlbum;
-
- at end
-
-NS_ASSUME_NONNULL_END
-


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewAlbumItem.m deleted
=====================================
@@ -1,246 +0,0 @@
-/*****************************************************************************
- * VLCLibraryCollectionViewAlbumItem.m: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2019 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 "VLCLibraryCollectionViewAlbumItem.h"
-
-#import "main/VLCMain.h"
-#import "library/VLCLibraryController.h"
-#import "library/VLCLibraryDataTypes.h"
-#import "library/VLCLibraryModel.h"
-#import "library/VLCLibraryMenuController.h"
-#import "views/VLCImageView.h"
-#import "views/VLCLinearProgressIndicator.h"
-#import "views/VLCTrackingView.h"
-#import "extensions/NSString+Helpers.h"
-#import "extensions/NSFont+VLCAdditions.h"
-#import "extensions/NSColor+VLCAdditions.h"
-#import "extensions/NSView+VLCAdditions.h"
-
-NSString *VLCLibraryAlbumCellIdentifier = @"VLCLibraryAlbumCellIdentifier";
-
- at interface VLCLibraryCollectionViewAlbumItem()
-{
-    VLCLibraryController *_libraryController;
-    VLCLibraryMenuController *_menuController;
-}
- at end
-
- at implementation VLCLibraryCollectionViewAlbumItem
-
- at synthesize mediaTitleTextField = _mediaTitleTextField;
- at synthesize annotationTextField = _annotationTextField;
- at synthesize unplayedIndicatorTextField = _unplayedIndicatorTextField;
- at synthesize durationTextField = _durationTextField;
- at synthesize mediaImageView = _mediaImageView;
- at synthesize playInstantlyButton = _playInstantlyButton;
- at synthesize addToPlaylistButton = _addToPlaylistButton;
- at synthesize progressIndicator = _progressIndicator;
-
-- (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-{
-    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-    if (self) {
-        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-        // TODO: Update album on a VLCLibraryModelAlbumUpdated signal
-        [notificationCenter addObserver:self
-                               selector:@selector(updateFontBasedOnSetting:)
-                                   name:VLCConfigurationChangedNotification
-                                 object:nil];
-    }
-    return self;
-}
-
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    if (@available(macOS 10_14, *)) {
-        [[NSApplication sharedApplication] removeObserver:self forKeyPath:@"effectiveAppearance"];
-    }
-}
-
-- (void)awakeFromNib
-{
-    [(VLCTrackingView *)self.view setViewToHide:self.playInstantlyButton];
-    self.durationTextField.textColor = [NSColor VLClibrarySubtitleColor];
-    self.annotationTextField.font = [NSFont VLClibraryCellAnnotationFont];
-    self.annotationTextField.textColor = [NSColor VLClibraryAnnotationColor];
-    self.annotationTextField.backgroundColor = [NSColor VLClibraryAnnotationBackgroundColor];
-    self.unplayedIndicatorTextField.stringValue = _NS("NEW");
-    self.unplayedIndicatorTextField.font = [NSFont VLClibraryHighlightCellHighlightLabelFont];
-    self.unplayedIndicatorTextField.textColor = [NSColor VLClibraryHighlightColor];
-
-    if (@available(macOS 10_14, *)) {
-        [[NSApplication sharedApplication] addObserver:self
-                                            forKeyPath:@"effectiveAppearance"
-                                               options:0
-                                               context:nil];
-    }
-
-    [self updateColoredAppearance];
-    [self updateFontBasedOnSetting:nil];
-    [self prepareForReuse];
-}
-
-#pragma mark - dynamic appearance
-
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
-                       context:(void *)context
-{
-    [self updateColoredAppearance];
-}
-
-- (void)updateColoredAppearance
-{
-    self.mediaTitleTextField.textColor = self.view.shouldShowDarkAppearance ? [NSColor VLClibraryDarkTitleColor] : [NSColor VLClibraryLightTitleColor];
-}
-
-- (void)updateFontBasedOnSetting:(NSNotification *)aNotification
-{
-    if (config_GetInt("macosx-large-text")) {
-        self.mediaTitleTextField.font = [NSFont VLClibraryLargeCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibraryLargeCellSubtitleFont];
-    } else {
-        self.mediaTitleTextField.font = [NSFont VLClibrarySmallCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibrarySmallCellSubtitleFont];
-    }
-}
-
-#pragma mark - view representation
-
-- (void)prepareForReuse
-{
-    [super prepareForReuse];
-    _playInstantlyButton.hidden = YES;
-    _mediaTitleTextField.stringValue = @"";
-    _durationTextField.stringValue = [NSString stringWithTime:0];
-    _mediaImageView.image = nil;
-    _annotationTextField.hidden = YES;
-    _progressIndicator.hidden = YES;
-    _unplayedIndicatorTextField.hidden = YES;
-}
-
-- (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)representedAlbum
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    _representedAlbum = representedAlbum;
-    [self updateRepresentation];
-}
-
-- (void)albumUpdated:(NSNotification *)aNotification
-{
-    VLCMediaLibraryAlbum *updatedAlbum = aNotification.object;
-    if (updatedAlbum == nil || _representedAlbum == nil) {
-        return;
-    }
-    if (updatedAlbum.albumID == _representedAlbum.albumID) {
-        [self updateRepresentation];
-    }
-}
-
-- (void)updateRepresentation
-{
-    if (_representedAlbum == nil) {
-        NSAssert(1, @"no media item assigned for collection view item", nil);
-        return;
-    }
-
-    _mediaTitleTextField.stringValue = _representedAlbum.title;
-    _durationTextField.stringValue = [NSString stringWithTime:_representedAlbum.duration / VLCMediaLibraryMediaItemDurationDenominator];
-
-    _mediaImageView.image = [self imageForMedia];
-
-    // TODO: Show album progress with progress indicator
-}
-
-- (NSImage *)imageForMedia
-{
-    NSImage *image;
-    if (_representedAlbum.artworkMRL.length > 0) {
-        image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:_representedAlbum.artworkMRL]];
-    }
-    if (!image) {
-        image = [NSImage imageNamed: @"noart.png"];
-    }
-    return image;
-}
-
-#pragma mark - actions
-
-- (IBAction)playInstantly:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    // We want to add all the tracks to the playlist but only play the first one immediately,
-    // otherwise we will skip straight to the last track of the album
-    __block BOOL playImmediately = YES;
-    [_representedAlbum iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:playImmediately];
-
-        if(playImmediately) {
-            playImmediately = NO;
-        }
-    }];
-}
-
-- (IBAction)addToPlaylist:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    [_representedAlbum iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:NO];
-    }];
-}
-
--(void)mouseDown:(NSEvent *)theEvent
-{
-    if (theEvent.modifierFlags & NSControlKeyMask) {
-        if (!_menuController) {
-            _menuController = [[VLCLibraryMenuController alloc] init];
-        }
-        [_menuController setRepresentedAlbum:self.representedAlbum];
-        [_menuController popupMenuWithEvent:theEvent forView:self.view];
-    }
-
-    [super mouseDown:theEvent];
-}
-
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
-    if (!_menuController) {
-        _menuController = [[VLCLibraryMenuController alloc] init];
-    }
-    [_menuController setRepresentedAlbum:self.representedAlbum];
-    [_menuController popupMenuWithEvent:theEvent forView:self.view];
-
-    [super rightMouseDown:theEvent];
-}
-
- at end


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewArtistItem.m deleted
=====================================
@@ -1,259 +0,0 @@
-/*****************************************************************************
- * VLCLibraryCollectionViewArtistItem.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 "VLCLibraryCollectionViewArtistItem.h"
-
-#import "main/VLCMain.h"
-#import "library/VLCLibraryController.h"
-#import "library/VLCLibraryDataTypes.h"
-#import "library/VLCLibraryModel.h"
-#import "library/VLCLibraryMenuController.h"
-#import "views/VLCImageView.h"
-#import "views/VLCLinearProgressIndicator.h"
-#import "views/VLCTrackingView.h"
-#import "extensions/NSString+Helpers.h"
-#import "extensions/NSFont+VLCAdditions.h"
-#import "extensions/NSColor+VLCAdditions.h"
-#import "extensions/NSView+VLCAdditions.h"
-
-NSString *VLCLibraryArtistCellIdentifier = @"VLCLibraryArtistCellIdentifier";
-
- at interface VLCLibraryCollectionViewArtistItem()
-{
-    VLCLibraryController *_libraryController;
-    VLCLibraryMenuController *_menuController;
-}
- at end
-
- at implementation VLCLibraryCollectionViewArtistItem
-
- at synthesize mediaTitleTextField = _mediaTitleTextField;
- at synthesize annotationTextField = _annotationTextField;
- at synthesize unplayedIndicatorTextField = _unplayedIndicatorTextField;
- at synthesize durationTextField = _durationTextField;
- at synthesize mediaImageView = _mediaImageView;
- at synthesize playInstantlyButton = _playInstantlyButton;
- at synthesize addToPlaylistButton = _addToPlaylistButton;
- at synthesize progressIndicator = _progressIndicator;
-
-- (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-{
-    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-    if (self) {
-        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-        // TODO: Update artist on a VLCLibraryModelArtistUpdated signal
-        [notificationCenter addObserver:self
-                               selector:@selector(updateFontBasedOnSetting:)
-                                   name:VLCConfigurationChangedNotification
-                                 object:nil];
-    }
-    return self;
-}
-
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    if (@available(macOS 10.14, *)) {
-        [[NSApplication sharedApplication] removeObserver:self forKeyPath:@"effectiveAppearance"];
-    }
-}
-
-- (void)awakeFromNib
-{
-    [(VLCTrackingView *)self.view setViewToHide:self.playInstantlyButton];
-    self.durationTextField.textColor = [NSColor VLClibrarySubtitleColor];
-    self.annotationTextField.font = [NSFont VLClibraryCellAnnotationFont];
-    self.annotationTextField.textColor = [NSColor VLClibraryAnnotationColor];
-    self.annotationTextField.backgroundColor = [NSColor VLClibraryAnnotationBackgroundColor];
-    self.unplayedIndicatorTextField.stringValue = _NS("NEW");
-    self.unplayedIndicatorTextField.font = [NSFont VLClibraryHighlightCellHighlightLabelFont];
-    self.unplayedIndicatorTextField.textColor = [NSColor VLClibraryHighlightColor];
-
-    if (@available(macOS 10.14, *)) {
-        [[NSApplication sharedApplication] addObserver:self
-                                            forKeyPath:@"effectiveAppearance"
-                                               options:0
-                                               context:nil];
-    }
-
-    [self updateColoredAppearance];
-    [self updateFontBasedOnSetting:nil];
-    [self prepareForReuse];
-}
-
-#pragma mark - dynamic appearance
-
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
-                       context:(void *)context
-{
-    [self updateColoredAppearance];
-}
-
-- (void)updateColoredAppearance
-{
-    self.mediaTitleTextField.textColor = self.view.shouldShowDarkAppearance ? [NSColor VLClibraryDarkTitleColor] : [NSColor VLClibraryLightTitleColor];
-}
-
-- (void)updateFontBasedOnSetting:(NSNotification *)aNotification
-{
-    if (config_GetInt("macosx-large-text")) {
-        self.mediaTitleTextField.font = [NSFont VLClibraryLargeCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibraryLargeCellSubtitleFont];
-    } else {
-        self.mediaTitleTextField.font = [NSFont VLClibrarySmallCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibrarySmallCellSubtitleFont];
-    }
-}
-
-#pragma mark - view representation
-
-- (void)prepareForReuse
-{
-    [super prepareForReuse];
-    _playInstantlyButton.hidden = YES;
-    _mediaTitleTextField.stringValue = @"";
-    _durationTextField.stringValue = [NSString stringWithTime:0];
-    _mediaImageView.image = nil;
-    _annotationTextField.hidden = YES;
-    _progressIndicator.hidden = YES;
-    _unplayedIndicatorTextField.hidden = YES;
-}
-
-- (void)setRepresentedArtist:(VLCMediaLibraryArtist *)representedArtist
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    _representedArtist = representedArtist;
-    [self updateRepresentation];
-}
-
-- (void)artistUpdated:(NSNotification *)aNotification
-{
-    VLCMediaLibraryArtist *updatedArtist = aNotification.object;
-    if (updatedArtist == nil || _representedArtist == nil) {
-        return;
-    }
-    if (updatedArtist.artistID == _representedArtist.artistID) {
-        [self updateRepresentation];
-    }
-}
-
-- (void)updateRepresentation
-{
-    if (_representedArtist == nil) {
-        NSAssert(1, @"no artist assigned for collection view item", nil);
-        return;
-    }
-
-    _mediaTitleTextField.stringValue = _representedArtist.name;
-
-    NSString *countMetadataString;
-    if (_representedArtist.numberOfAlbums > 1) {
-        countMetadataString = [NSString stringWithFormat:_NS("%u albums"), _representedArtist.numberOfAlbums];
-    } else {
-        countMetadataString = _NS("1 album");
-    }
-    if (_representedArtist.numberOfTracks > 1) {
-        countMetadataString = [countMetadataString stringByAppendingFormat:@", %@", [NSString stringWithFormat:_NS("%u songs"), _representedArtist.numberOfTracks]];
-    } else {
-        countMetadataString = [countMetadataString stringByAppendingFormat:@", %@", _NS("1 song")];
-    }
-
-    _durationTextField.stringValue = countMetadataString;
-
-    _mediaImageView.image = [self imageForMedia];
-
-    // TODO: Show artist tracks progress with progress indicator
-}
-
-- (NSImage *)imageForMedia
-{
-    NSImage *image = nil;
-    if (_representedArtist.artworkMRL.length > 0) {
-        image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:_representedArtist.artworkMRL]];
-    }
-    if (!image) {
-        image = [NSImage imageNamed: @"noart.png"];
-    }
-    return image;
-}
-
-#pragma mark - actions
-
-- (IBAction)playInstantly:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    // We want to add all the tracks to the playlist but only play the first one immediately,
-    // otherwise we will skip straight to the last track of the last album from the artist
-    __block BOOL playImmediately = YES;
-    [_representedArtist iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:playImmediately];
-
-        if(playImmediately) {
-            playImmediately = NO;
-        }
-    }];
-}
-
-- (IBAction)addToPlaylist:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    [_representedArtist iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:NO];
-    }];
-}
-
--(void)mouseDown:(NSEvent *)theEvent
-{
-    if (theEvent.modifierFlags & NSControlKeyMask) {
-        if (!_menuController) {
-            _menuController = [[VLCLibraryMenuController alloc] init];
-        }
-        [_menuController setRepresentedArtist:self.representedArtist];
-        [_menuController popupMenuWithEvent:theEvent forView:self.view];
-    }
-
-    [super mouseDown:theEvent];
-}
-
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
-    if (!_menuController) {
-        _menuController = [[VLCLibraryMenuController alloc] init];
-    }
-    [_menuController setRepresentedArtist:self.representedArtist];
-    [_menuController popupMenuWithEvent:theEvent forView:self.view];
-
-    [super rightMouseDown:theEvent];
-}
-
- at end


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewGenreItem.m deleted
=====================================
@@ -1,244 +0,0 @@
-/*****************************************************************************
- * VLCLibraryCollectionViewGenreItem.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 "VLCLibraryCollectionViewGenreItem.h"
-
-#import "main/VLCMain.h"
-#import "library/VLCLibraryController.h"
-#import "library/VLCLibraryDataTypes.h"
-#import "library/VLCLibraryModel.h"
-#import "library/VLCLibraryMenuController.h"
-#import "views/VLCImageView.h"
-#import "views/VLCLinearProgressIndicator.h"
-#import "views/VLCTrackingView.h"
-#import "extensions/NSString+Helpers.h"
-#import "extensions/NSFont+VLCAdditions.h"
-#import "extensions/NSColor+VLCAdditions.h"
-#import "extensions/NSView+VLCAdditions.h"
-
-NSString *VLCLibraryGenreCellIdentifier = @"VLCLibraryGenreCellIdentifier";
-
- at interface VLCLibraryCollectionViewGenreItem()
-{
-    VLCLibraryController *_libraryController;
-    VLCLibraryMenuController *_menuController;
-}
- at end
-
- at implementation VLCLibraryCollectionViewGenreItem
-
- at synthesize mediaTitleTextField = _mediaTitleTextField;
- at synthesize annotationTextField = _annotationTextField;
- at synthesize unplayedIndicatorTextField = _unplayedIndicatorTextField;
- at synthesize durationTextField = _durationTextField;
- at synthesize mediaImageView = _mediaImageView;
- at synthesize playInstantlyButton = _playInstantlyButton;
- at synthesize addToPlaylistButton = _addToPlaylistButton;
- at synthesize progressIndicator = _progressIndicator;
-
-- (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-{
-    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-    if (self) {
-        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-        // TODO: Update genre on a VLCLibraryModelGenreUpdated signal
-        [notificationCenter addObserver:self
-                               selector:@selector(updateFontBasedOnSetting:)
-                                   name:VLCConfigurationChangedNotification
-                                 object:nil];
-    }
-    return self;
-}
-
-- (void)dealloc
-{
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    if (@available(macOS 10.14, *)) {
-        [[NSApplication sharedApplication] removeObserver:self forKeyPath:@"effectiveAppearance"];
-    }
-}
-
-- (void)awakeFromNib
-{
-    [(VLCTrackingView *)self.view setViewToHide:self.playInstantlyButton];
-    self.durationTextField.textColor = [NSColor VLClibrarySubtitleColor];
-    self.annotationTextField.font = [NSFont VLClibraryCellAnnotationFont];
-    self.annotationTextField.textColor = [NSColor VLClibraryAnnotationColor];
-    self.annotationTextField.backgroundColor = [NSColor VLClibraryAnnotationBackgroundColor];
-    self.unplayedIndicatorTextField.stringValue = _NS("NEW");
-    self.unplayedIndicatorTextField.font = [NSFont VLClibraryHighlightCellHighlightLabelFont];
-    self.unplayedIndicatorTextField.textColor = [NSColor VLClibraryHighlightColor];
-
-    if (@available(macOS 10.14, *)) {
-        [[NSApplication sharedApplication] addObserver:self
-                                            forKeyPath:@"effectiveAppearance"
-                                               options:0
-                                               context:nil];
-    }
-
-    [self updateColoredAppearance];
-    [self updateFontBasedOnSetting:nil];
-    [self prepareForReuse];
-}
-
-#pragma mark - dynamic appearance
-
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
-                       context:(void *)context
-{
-    [self updateColoredAppearance];
-}
-
-- (void)updateColoredAppearance
-{
-    self.mediaTitleTextField.textColor = self.view.shouldShowDarkAppearance ? [NSColor VLClibraryDarkTitleColor] : [NSColor VLClibraryLightTitleColor];
-}
-
-- (void)updateFontBasedOnSetting:(NSNotification *)aNotification
-{
-    if (config_GetInt("macosx-large-text")) {
-        self.mediaTitleTextField.font = [NSFont VLClibraryLargeCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibraryLargeCellSubtitleFont];
-    } else {
-        self.mediaTitleTextField.font = [NSFont VLClibrarySmallCellTitleFont];
-        self.durationTextField.font = [NSFont VLClibrarySmallCellSubtitleFont];
-    }
-}
-
-#pragma mark - view representation
-
-- (void)prepareForReuse
-{
-    [super prepareForReuse];
-    _playInstantlyButton.hidden = YES;
-    _mediaTitleTextField.stringValue = @"";
-    _durationTextField.stringValue = [NSString stringWithTime:0];
-    _mediaImageView.image = nil;
-    _annotationTextField.hidden = YES;
-    _progressIndicator.hidden = YES;
-    _unplayedIndicatorTextField.hidden = YES;
-}
-
-- (void)setRepresentedGenre:(VLCMediaLibraryGenre *)representedGenre
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    _representedGenre = representedGenre;
-    [self updateRepresentation];
-}
-
-- (void)genreUpdated:(NSNotification *)aNotification
-{
-    VLCMediaLibraryGenre *updatedGenre = aNotification.object;
-    if (updatedGenre == nil || _representedGenre == nil) {
-        return;
-    }
-    if (updatedGenre.genreID == _representedGenre.genreID) {
-        [self updateRepresentation];
-    }
-}
-
-- (void)updateRepresentation
-{
-    if (_representedGenre == nil) {
-        NSAssert(1, @"no genre assigned for collection view item", nil);
-        return;
-    }
-
-    _mediaTitleTextField.stringValue = _representedGenre.name;
-
-    if (_representedGenre.numberOfTracks > 1) {
-        _durationTextField.stringValue = [NSString stringWithFormat:_NS("%u songs"), _representedGenre.numberOfTracks];
-    } else {
-        _durationTextField.stringValue = _NS("1 song");
-    }
-
-    _mediaImageView.image = [self imageForMedia];
-
-    // TODO: Show artist tracks progress with progress indicator
-}
-
-- (NSImage *)imageForMedia
-{
-    return [NSImage imageNamed: @"noart.png"];
-}
-
-#pragma mark - actions
-
-- (IBAction)playInstantly:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    // We want to add all the tracks to the playlist but only play the first one immediately,
-    // otherwise we will skip straight to the last track of the last album from the genre
-    __block BOOL playImmediately = YES;
-    [_representedGenre iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:playImmediately];
-
-        if(playImmediately) {
-            playImmediately = NO;
-        }
-    }];
-}
-
-- (IBAction)addToPlaylist:(id)sender
-{
-    if (!_libraryController) {
-        _libraryController = [[VLCMain sharedInstance] libraryController];
-    }
-
-    [_representedGenre iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
-        [_libraryController appendItemToPlaylist:mediaItem playImmediately:NO];
-    }];
-}
-
--(void)mouseDown:(NSEvent *)theEvent
-{
-    if (theEvent.modifierFlags & NSControlKeyMask) {
-        if (!_menuController) {
-            _menuController = [[VLCLibraryMenuController alloc] init];
-        }
-        [_menuController setRepresentedGenre:self.representedGenre];
-        [_menuController popupMenuWithEvent:theEvent forView:self.view];
-    }
-
-    [super mouseDown:theEvent];
-}
-
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
-    if (!_menuController) {
-        _menuController = [[VLCLibraryMenuController alloc] init];
-    }
-    [_menuController setRepresentedGenre:self.representedGenre];
-    [_menuController popupMenuWithEvent:theEvent forView:self.view];
-
-    [super rightMouseDown:theEvent];
-}
-
- at end


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewItem.h
=====================================
@@ -21,17 +21,27 @@
  *****************************************************************************/
 
 #import <Cocoa/Cocoa.h>
-#import "VLCLibraryCollectionViewItemProtocol.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
- at class VLCMediaLibraryMediaItem;
+ at class VLCImageView;
+ at class VLCLinearProgressIndicator;
+ at protocol VLCMediaLibraryItemProtocol;
 
 extern NSString *VLCLibraryCellIdentifier;
 
- at interface VLCLibraryCollectionViewItem : NSCollectionViewItem<VLCLibraryCollectionViewItemProtocol>
+ at interface VLCLibraryCollectionViewItem : NSCollectionViewItem
 
- at property (readwrite, retain, nonatomic) VLCMediaLibraryMediaItem *representedMediaItem;
+ at property (readwrite, assign) IBOutlet NSTextField *mediaTitleTextField;
+ at property (readwrite, assign) IBOutlet NSTextField *annotationTextField;
+ at property (readwrite, assign) IBOutlet NSTextField *unplayedIndicatorTextField;
+ at property (readwrite, assign) IBOutlet NSTextField *durationTextField;
+ at property (readwrite, assign) IBOutlet VLCImageView *mediaImageView;
+ at property (readwrite, assign) IBOutlet NSButton *playInstantlyButton;
+ at property (readwrite, assign) IBOutlet NSButton *addToPlaylistButton;
+ at property (readwrite, assign) IBOutlet VLCLinearProgressIndicator *progressIndicator;
+
+ at property (readwrite, retain, nonatomic) id<VLCMediaLibraryItemProtocol> representedItem;
 
 @end
 


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewItem.m
=====================================
@@ -48,15 +48,6 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
 
 @implementation VLCLibraryCollectionViewItem
 
- at synthesize mediaTitleTextField = _mediaTitleTextField;
- at synthesize annotationTextField = _annotationTextField;
- at synthesize unplayedIndicatorTextField = _unplayedIndicatorTextField;
- at synthesize durationTextField = _durationTextField;
- at synthesize mediaImageView = _mediaImageView;
- at synthesize playInstantlyButton = _playInstantlyButton;
- at synthesize addToPlaylistButton = _addToPlaylistButton;
- at synthesize progressIndicator = _progressIndicator;
-
 - (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 {
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
@@ -145,60 +136,56 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
     _unplayedIndicatorTextField.hidden = YES;
 }
 
-- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem
+- (void)setRepresentedItem:(id<VLCMediaLibraryItemProtocol>)representedItem
 {
     if (!_libraryController) {
         _libraryController = [[VLCMain sharedInstance] libraryController];
     }
 
-    _representedMediaItem = representedMediaItem;
+    _representedItem = representedItem;
     [self updateRepresentation];
 }
 
 - (void)mediaItemUpdated:(NSNotification *)aNotification
 {
     VLCMediaLibraryMediaItem *updatedMediaItem = aNotification.object;
-    if (updatedMediaItem == nil || _representedMediaItem == nil) {
+    if (updatedMediaItem == nil || _representedItem == nil || ![_representedItem isKindOfClass:[VLCMediaLibraryMediaItem class]]) {
         return;
     }
-    if (updatedMediaItem.libraryID == _representedMediaItem.libraryID) {
+    
+    VLCMediaLibraryMediaItem *mediaItem = (VLCMediaLibraryMediaItem *)_representedItem;
+    if(mediaItem && updatedMediaItem.libraryID == mediaItem.libraryID) {
         [self updateRepresentation];
     }
 }
 
 - (void)updateRepresentation
 {
-    if (_representedMediaItem == nil) {
-        NSAssert(1, @"no media item assigned for collection view item", nil);
+    if (_representedItem == nil) {
+        NSAssert(1, @"no item assigned for collection view item", nil);
         return;
     }
 
-    _mediaTitleTextField.stringValue = _representedMediaItem.title;
-    _durationTextField.stringValue = [NSString stringWithTime:_representedMediaItem.duration / VLCMediaLibraryMediaItemDurationDenominator];
-
-    _mediaImageView.image = [self imageForMedia];
+    _mediaTitleTextField.stringValue = _representedItem.displayString;
+    _durationTextField.stringValue = _representedItem.durationString;
+    _mediaImageView.image = _representedItem.smallArtworkImage;
 
-    VLCMediaLibraryTrack *videoTrack = _representedMediaItem.firstVideoTrack;
-    [self showVideoSizeIfNeededForWidth:videoTrack.videoWidth andHeight:videoTrack.videoHeight];
-
-    CGFloat position = _representedMediaItem.progress;
-    if (position > VLCLibraryCollectionViewItemMinimalDisplayedProgress && position < VLCLibraryCollectionViewItemMaximumDisplayedProgress) {
-        _progressIndicator.progress = position;
-        _progressIndicator.hidden = NO;
-    }
+    // TODO: Add handling for the other types
+    if([_representedItem isKindOfClass:[VLCMediaLibraryMediaItem class]]) {
+        VLCMediaLibraryMediaItem *mediaItem = (VLCMediaLibraryMediaItem *)_representedItem;
+        VLCMediaLibraryTrack *videoTrack = mediaItem.firstVideoTrack;
+        [self showVideoSizeIfNeededForWidth:videoTrack.videoWidth andHeight:videoTrack.videoHeight];
 
-    if (_representedMediaItem.playCount == 0) {
-        _unplayedIndicatorTextField.hidden = NO;
-    }
-}
+        CGFloat position = mediaItem.progress;
+        if (position > VLCLibraryCollectionViewItemMinimalDisplayedProgress && position < VLCLibraryCollectionViewItemMaximumDisplayedProgress) {
+            _progressIndicator.progress = position;
+            _progressIndicator.hidden = NO;
+        }
 
-- (NSImage *)imageForMedia
-{
-    NSImage *image = _representedMediaItem.smallArtworkImage;
-    if (!image) {
-        image = [NSImage imageNamed: @"noart.png"];
+        if (mediaItem.playCount == 0) {
+            _unplayedIndicatorTextField.hidden = NO;
+        }
     }
-    return image;
 }
 
 - (void)showVideoSizeIfNeededForWidth:(CGFloat)width andHeight:(CGFloat)height
@@ -220,7 +207,16 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
         _libraryController = [[VLCMain sharedInstance] libraryController];
     }
 
-    [_libraryController appendItemToPlaylist:_representedMediaItem playImmediately:YES];
+    // We want to add all the tracks to the playlist but only play the first one immediately,
+    // otherwise we will skip straight to the last track of the last album from the artist
+    __block BOOL playImmediately = YES;
+    [_representedItem iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
+        [_libraryController appendItemToPlaylist:mediaItem playImmediately:playImmediately];
+
+        if(playImmediately) {
+            playImmediately = NO;
+        }
+    }];
 }
 
 - (IBAction)addToPlaylist:(id)sender
@@ -229,7 +225,9 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
         _libraryController = [[VLCMain sharedInstance] libraryController];
     }
 
-    [_libraryController appendItemToPlaylist:_representedMediaItem playImmediately:NO];
+    [_representedItem iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
+        [_libraryController appendItemToPlaylist:mediaItem playImmediately:NO];
+    }];
 }
 
 -(void)mouseDown:(NSEvent *)theEvent
@@ -238,7 +236,8 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
         if (!_menuController) {
             _menuController = [[VLCLibraryMenuController alloc] init];
         }
-        [_menuController setRepresentedMediaItem:self.representedMediaItem];
+
+        [_menuController setRepresentedItem:_representedItem];
         [_menuController popupMenuWithEvent:theEvent forView:self.view];
     }
 
@@ -250,7 +249,8 @@ const CGFloat VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
     if (!_menuController) {
         _menuController = [[VLCLibraryMenuController alloc] init];
     }
-    [_menuController setRepresentedMediaItem:self.representedMediaItem];
+
+    [_menuController setRepresentedItem:_representedItem];
     [_menuController popupMenuWithEvent:theEvent forView:self.view];
 
     [super rightMouseDown:theEvent];


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewItemProtocol.h deleted
=====================================
@@ -1,48 +0,0 @@
-/*****************************************************************************
- * VLCLibraryCollectionViewItemProtocl.h: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2022 VLC authors and VideoLAN
- *
- * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
- *          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>
-
-NS_ASSUME_NONNULL_BEGIN
-
- at class VLCImageView;
- at class VLCLinearProgressIndicator;
-
- at protocol VLCLibraryCollectionViewItemProtocol
- at required
-
- at property (readwrite, assign) IBOutlet NSTextField *mediaTitleTextField;
- at property (readwrite, assign) IBOutlet NSTextField *annotationTextField;
- at property (readwrite, assign) IBOutlet NSTextField *unplayedIndicatorTextField;
- at property (readwrite, assign) IBOutlet NSTextField *durationTextField;
- at property (readwrite, assign) IBOutlet VLCImageView *mediaImageView;
- at property (readwrite, assign) IBOutlet NSButton *playInstantlyButton;
- at property (readwrite, assign) IBOutlet NSButton *addToPlaylistButton;
- at property (readwrite, assign) IBOutlet VLCLinearProgressIndicator *progressIndicator;
-
-- (IBAction)playInstantly:(id)sender;
-- (IBAction)addToPlaylist:(id)sender;
-
- at end
-
-NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -95,16 +95,28 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 
 @end
 
- at interface VLCMediaLibraryArtist : NSObject
+#pragma mark - Audio media library classes
+
+ at protocol VLCMediaLibraryItemProtocol <NSObject>
+
+ at property (readonly) NSImage *smallArtworkImage;
+ at property (readonly) NSString *smallArtworkMRL;
+ at property (readonly) NSString *displayString;
+ at property (readonly) NSString *durationString;
+ at property (readonly) VLCMediaLibraryMediaItem *firstMediaItem;
+
+- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
+
+ at end
+
+ at interface VLCMediaLibraryArtist : NSObject<VLCMediaLibraryItemProtocol>
 
 + (nullable instancetype)artistWithID:(int64_t)artistID;
 - (instancetype)initWithArtist:(struct vlc_ml_artist_t *)p_artist;
-- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
 
 @property (readonly) int64_t artistID;
 @property (readonly) NSString *name;
 @property (readonly) NSString *shortBiography;
- at property (readonly) NSString *artworkMRL;
 @property (readonly) NSString *musicBrainzID;
 @property (readonly) unsigned int numberOfAlbums;
 @property (readonly) unsigned int numberOfTracks;
@@ -112,15 +124,13 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 
 @end
 
- at interface VLCMediaLibraryAlbum : NSObject
+ at interface VLCMediaLibraryAlbum : NSObject<VLCMediaLibraryItemProtocol>
 
 - (instancetype)initWithAlbum:(struct vlc_ml_album_t *)p_album;
-- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
 
 @property (readonly) int64_t albumID;
 @property (readonly) NSString *title;
 @property (readonly) NSString *summary;
- at property (readonly) NSString *artworkMRL;
 @property (readonly) NSString *artistName;
 @property (readonly) int64_t artistID;
 @property (readonly) size_t numberOfTracks;
@@ -130,7 +140,7 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 
 @end
 
- at interface VLCMediaLibraryGenre : NSObject
+ at interface VLCMediaLibraryGenre : NSObject<VLCMediaLibraryItemProtocol>
 
 - (instancetype)initWithGenre:(struct vlc_ml_genre_t *)p_genre;
 
@@ -142,11 +152,10 @@ extern const long long int VLCMediaLibraryMediaItemDurationDenominator;
 @property (readonly) NSArray <VLCMediaLibraryMediaItem *> *tracksAsMediaItems;
 
 - (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock orderedBy:(int)mediaItemParentType;
-- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
 
 @end
 
- at interface VLCMediaLibraryMediaItem : NSObject
+ at interface VLCMediaLibraryMediaItem : NSObject<VLCMediaLibraryItemProtocol>
 
 + (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID;
 + (nullable instancetype)mediaItemForURL:(NSURL *)url;


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -23,6 +23,7 @@
 #import "VLCLibraryDataTypes.h"
 
 #import "main/VLCMain.h"
+#import "extensions/NSImage+Helpers.h"
 #import "extensions/NSString+Helpers.h"
 #import "library/VLCInputItem.h"
 #import "library/VLCLibraryImageCache.h"
@@ -178,8 +179,12 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
 
 @end
 
+#pragma mark - Audio media library classes
+
 @implementation VLCMediaLibraryArtist
 
+ at synthesize smallArtworkMRL = _smallArtworkMRL;
+
 + (nullable instancetype)artistWithID:(int64_t)artistID
 {
     intf_thread_t *p_intf = getIntf();
@@ -205,7 +210,7 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
         _artistID = p_artist->i_id;
         _name = toNSStr(p_artist->psz_name);
         _shortBiography = toNSStr(p_artist->psz_shortbio);
-        _artworkMRL = toNSStr(p_artist->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl);
+        _smallArtworkMRL = toNSStr(p_artist->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl);
         _musicBrainzID = toNSStr(p_artist->psz_mb_id);
         _numberOfAlbums = p_artist->i_nb_album;
         _numberOfTracks = p_artist->i_nb_tracks;
@@ -213,6 +218,33 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
     return self;
 }
 
+- (NSImage *)smallArtworkImage
+{
+    return [NSImage artworkOrPlaceholderFromMrl:_smallArtworkMRL];
+}
+
+- (NSString *)displayString
+{
+    return _name;
+}
+
+- (NSString *)durationString
+{
+    NSString *countMetadataString;
+    if (_numberOfAlbums > 1) {
+        countMetadataString = [NSString stringWithFormat:_NS("%u albums"), _numberOfAlbums];
+    } else {
+        countMetadataString = _NS("1 album");
+    }
+    if (_numberOfTracks > 1) {
+        countMetadataString = [countMetadataString stringByAppendingFormat:@", %@", [NSString stringWithFormat:_NS("%u songs"), _numberOfTracks]];
+    } else {
+        countMetadataString = [countMetadataString stringByAppendingFormat:@", %@", _NS("1 song")];
+    }
+
+    return countMetadataString;
+}
+
 - (NSArray<VLCMediaLibraryAlbum *> *)albums
 {
     intf_thread_t *p_intf = getIntf();
@@ -244,6 +276,8 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
 
 @implementation VLCMediaLibraryAlbum
 
+ at synthesize smallArtworkMRL = _smallArtworkMRL;
+
 - (instancetype)initWithAlbum:(struct vlc_ml_album_t *)p_album
 {
     self = [super init];
@@ -251,7 +285,7 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
         _albumID = p_album->i_id;
         _title = toNSStr(p_album->psz_title);
         _summary = toNSStr(p_album->psz_summary);
-        _artworkMRL = toNSStr(p_album->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl);
+        _smallArtworkMRL = toNSStr(p_album->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl);
         _artistName = toNSStr(p_album->psz_artist);
         _artistID = p_album->i_artist_id;
         _numberOfTracks = p_album->i_nb_tracks;
@@ -261,6 +295,22 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
     return self;
 }
 
+- (NSImage *)smallArtworkImage
+{
+    return [NSImage artworkOrPlaceholderFromMrl:_smallArtworkMRL];
+}
+
+
+- (NSString *)displayString
+{
+    return _title;
+}
+
+- (NSString *)durationString
+{
+    return [NSString stringWithTime:_duration / VLCMediaLibraryMediaItemDurationDenominator];
+}
+
 - (NSArray<VLCMediaLibraryMediaItem *> *)tracksAsMediaItems
 {
     intf_thread_t *p_intf = getIntf();
@@ -292,6 +342,8 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
 
 @implementation VLCMediaLibraryGenre
 
+ at synthesize smallArtworkMRL = _smallArtworkMRL;
+
 - (instancetype)initWithGenre:(struct vlc_ml_genre_t *)p_genre
 {
     self = [super init];
@@ -303,6 +355,25 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
     return self;
 }
 
+- (NSImage *)smallArtworkImage
+{
+    return [NSImage artworkOrPlaceholderFromMrl:_smallArtworkMRL];
+}
+
+- (NSString *)displayString
+{
+    return _name;
+}
+
+- (NSString *)durationString
+{
+    if (_numberOfTracks > 1) {
+        return [NSString stringWithFormat:_NS("%u songs"), _numberOfTracks];
+    } else {
+        return _NS("1 song");
+    }
+}
+
 - (NSArray<VLCMediaLibraryAlbum *> *)albums
 {
     intf_thread_t *p_intf = getIntf();
@@ -409,6 +480,8 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
 
 #pragma mark - initialization
 
+ at synthesize smallArtworkMRL = _smallArtworkMRL;
+
 + (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID
 {
     intf_thread_t *p_intf = getIntf();
@@ -631,7 +704,22 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
 
 - (NSImage *)smallArtworkImage
 {
-    return [VLCLibraryImageCache thumbnailForMediaItem:self];
+    NSImage *image = [VLCLibraryImageCache thumbnailForMediaItem:self];
+    if (!image) {
+        image = [NSImage imageNamed:@"noart.png"];
+    }
+    return image;
+}
+
+- (NSString *)displayString
+{
+    return _title;
+}
+
+- (NSString *)durationString
+{
+    return [NSString stringWithTime:_duration / VLCMediaLibraryMediaItemDurationDenominator];
+
 }
 
 - (VLCInputItem *)inputItem
@@ -645,6 +733,11 @@ NSString *VLCMediaLibraryMediaItemLibraryID = @"VLCMediaLibraryMediaItemLibraryI
     return inputItem;
 }
 
+- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
+{
+    mediaItemBlock(self);
+}
+
 #pragma mark - preference setters / getters
 
 - (int)setIntegerPreference:(int)value forKey:(enum vlc_ml_playback_state)key


=====================================
modules/gui/macosx/library/VLCLibraryMenuController.h
=====================================
@@ -24,18 +24,12 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
- at class VLCMediaLibraryMediaItem;
- at class VLCMediaLibraryAlbum;
- at class VLCMediaLibraryArtist;
- at class VLCMediaLibraryGenre;
+ at protocol VLCMediaLibraryItemProtocol;
 
 @interface VLCLibraryMenuController : NSObject
 
 - (void)popupMenuWithEvent:(NSEvent *)theEvent forView:(NSView *)theView;
-- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)mediaItem;
-- (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)album;
-- (void)setRepresentedArtist:(VLCMediaLibraryArtist *)artist;
-- (void)setRepresentedGenre:(VLCMediaLibraryGenre *)genre;
+- (void)setRepresentedItem:(id<VLCMediaLibraryItemProtocol>)item;
 
 @end
 


=====================================
modules/gui/macosx/library/VLCLibraryMenuController.m
=====================================
@@ -34,11 +34,7 @@
 {
     NSMenu *_libraryMenu;
     VLCLibraryInformationPanel *_informationPanel;
-    enum vlc_ml_parent_type _currentRepresentedType;
-    VLCMediaLibraryMediaItem *_representedMediaItem;
-    VLCMediaLibraryAlbum *_representedAlbum;
-    VLCMediaLibraryArtist *_representedArtist;
-    VLCMediaLibraryGenre *_representedGenre;
+    id<VLCMediaLibraryItemProtocol> _representedItem;
 }
 @end
 
@@ -74,7 +70,7 @@
 
 - (void)popupMenuWithEvent:(NSEvent *)theEvent forView:(NSView *)theView
 {
-    if (_representedMediaItem != nil) {
+    if (_representedItem != nil) {
         [NSMenu popUpContextMenu:_libraryMenu withEvent:theEvent forView:theView];
     } else {
         NSMenu *minimalMenu = [[NSMenu alloc] initWithTitle:@""];
@@ -88,33 +84,13 @@
 #pragma mark - actions
 - (void)addToPlaylist:(BOOL)playImmediately
 {
-    void (^mediaItemPlaylistHandler)(VLCMediaLibraryMediaItem*) = ^(VLCMediaLibraryMediaItem* mediaItem) {
-        [[[VLCMain sharedInstance] libraryController] appendItemToPlaylist:mediaItem playImmediately:playImmediately];
-    };
-
-    switch(_currentRepresentedType) {
-        case VLC_ML_PARENT_GENRE:
-        {
-            [_representedGenre iterateMediaItemsWithBlock:mediaItemPlaylistHandler];
-        }
-        case VLC_ML_PARENT_ARTIST:
-        {
-            [_representedArtist iterateMediaItemsWithBlock:mediaItemPlaylistHandler];
-            break;
-        }
-        case VLC_ML_PARENT_ALBUM:
-        {
-            [_representedAlbum iterateMediaItemsWithBlock:mediaItemPlaylistHandler];
-            break;
-        }
-        case VLC_ML_PARENT_UNKNOWN:
-        {
-            mediaItemPlaylistHandler(_representedMediaItem);
-            break;
-        }
-        default:
-            NSLog(@"No represented media type, cannot append nothing to playlist.");
+    if(_representedItem == nil) {
+        return;
     }
+
+    [_representedItem iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
+        [[[VLCMain sharedInstance] libraryController] appendItemToPlaylist:mediaItem playImmediately:playImmediately];
+    }];
 }
 
 - (void)play:(id)sender
@@ -146,61 +122,30 @@
 
 - (void)revealInFinder:(id)sender
 {
-    switch(_currentRepresentedType) {
-        case VLC_ML_PARENT_ARTIST:
-        {
-            [[[VLCMain sharedInstance] libraryController] showItemInFinder:_representedArtist.albums.firstObject.tracksAsMediaItems.firstObject];
-            break;
-        }
-        case VLC_ML_PARENT_ALBUM:
-        {
-            [[[VLCMain sharedInstance] libraryController] showItemInFinder:_representedAlbum.tracksAsMediaItems.firstObject];
-            break;
-        }
-        case VLC_ML_PARENT_UNKNOWN:
-        {
-            [[[VLCMain sharedInstance] libraryController] showItemInFinder:_representedMediaItem];
-            break;
-        }
-        default:
-            NSLog(@"No represented media type, nothing to show in Finder.");
+    if(_representedItem == nil) {
+        return;
+    }
+
+    // TODO: Add handling for other types
+    if([_representedItem isKindOfClass:[VLCMediaLibraryMediaItem class]]) {
+        [_representedItem iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
+            [[[VLCMain sharedInstance] libraryController] showItemInFinder:mediaItem];
+        }];
     }
 }
 
 - (void)moveToTrash:(id)sender
 {
-    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if(_representedItem == nil) {
+        return;
+    }
 
-    void (^mediaItemTrashHandler)(VLCMediaLibraryMediaItem*) = ^(VLCMediaLibraryMediaItem* mediaItem) {
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    [_representedItem iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* mediaItem) {
         for (VLCMediaLibraryFile *fileToTrash in mediaItem.files) {
             [fileManager trashItemAtURL:fileToTrash.fileURL resultingItemURL:nil error:nil];
         }
-    };
-
-    switch(_currentRepresentedType) {
-        case VLC_ML_PARENT_GENRE:
-        {
-            [_representedGenre iterateMediaItemsWithBlock:mediaItemTrashHandler];
-        }
-        case VLC_ML_PARENT_ARTIST:
-        {
-            [_representedArtist iterateMediaItemsWithBlock:mediaItemTrashHandler];
-            break;
-        }
-        case VLC_ML_PARENT_ALBUM:
-        {
-            [_representedAlbum iterateMediaItemsWithBlock:mediaItemTrashHandler];
-            break;
-        }
-        case VLC_ML_PARENT_UNKNOWN:
-        {
-            mediaItemTrashHandler(_representedMediaItem);
-            break;
-        }
-        default:
-            NSLog(@"No represented media type, not moving anything to trash.");
-            return;
-    }
+    }];
 }
 
 - (void)showInformation:(id)sender
@@ -209,48 +154,18 @@
         _informationPanel = [[VLCLibraryInformationPanel alloc] initWithWindowNibName:@"VLCLibraryInformationPanel"];
     }
 
-    if(_currentRepresentedType == VLC_ML_PARENT_UNKNOWN) {
-        [_informationPanel setRepresentedMediaItem:_representedMediaItem];
+    // TODO: Add handling for the other types
+    if([_representedItem isKindOfClass:[VLCMediaLibraryMediaItem class]]) {
+        VLCMediaLibraryMediaItem *mediaItem = (VLCMediaLibraryMediaItem *)_representedItem;
+        [_informationPanel setRepresentedMediaItem:mediaItem];
         [_informationPanel showWindow:self];
     }
     
 }
 
-- (void)clearRepresentedMedia
-{
-    _representedMediaItem = nil;
-    _representedAlbum = nil;
-    _representedArtist = nil;
-    _representedGenre = nil;
-    _currentRepresentedType = VLC_ML_PARENT_UNKNOWN;
-}
-
-- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)mediaItem
-{
-    [self clearRepresentedMedia];
-    _representedMediaItem = mediaItem;
-    _currentRepresentedType = VLC_ML_PARENT_UNKNOWN;
-}
-
-- (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)album
-{
-    [self clearRepresentedMedia];
-    _representedAlbum = album;
-    _currentRepresentedType = VLC_ML_PARENT_ALBUM;
-}
-
-- (void)setRepresentedArtist:(VLCMediaLibraryArtist *)artist
-{
-    [self clearRepresentedMedia];
-    _representedArtist = artist;
-    _currentRepresentedType = VLC_ML_PARENT_ARTIST;
-}
-
-- (void)setRepresentedGenre:(VLCMediaLibraryGenre *)genre
+- (void)setRepresentedItem:(id<VLCMediaLibraryItemProtocol>)item
 {
-    [self clearRepresentedMedia];
-    _representedGenre = genre;
-    _currentRepresentedType = VLC_ML_PARENT_GENRE;
+    _representedItem = item;
 }
 
 @end


=====================================
modules/gui/macosx/library/VLCLibraryVideoDataSource.m
=====================================
@@ -62,7 +62,7 @@
         mediaArray = [_libraryModel listOfVideoMedia];
     }
 
-    viewItem.representedMediaItem = mediaArray[indexPath.item];
+    viewItem.representedItem = mediaArray[indexPath.item];
 
     return viewItem;
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/fa106a29adbc3e08de21d4261bceb1b8fe0d91b3

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/fa106a29adbc3e08de21d4261bceb1b8fe0d91b3
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