Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
5cdd08b0 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Cache a dictionary of artist id and artist name in library model
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
4f8c4b4f by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Cache album name for album id in library model
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
48b0ef2e by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Cache genre name with its id in VLCLibraryModel
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
97aee68c by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Rename detailString property to primaryDetailString property
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
74c94c74 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Lazily load and store genres for audio library groups
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
e06346ef by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Rename actionable detail properties to primary actionable details
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
13a1538c by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add function to generate display string from genre array
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
a4cf3d69 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add genreString property to artists and albums
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
1fa2686c by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Cache primary detail string after initial lazy load for
VLCMediaLibraryMediaItem
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
30f7d9c7 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Generate contextual secondary detail string for
VLCMediaLibraryMediaItems
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
818df221 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add secondary label parameter to VLCMediaLibraryDummyItem
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
bff5b048 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add secondaryActionableDetail properties to VLCMediaLibraryItemProtocol
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
ec3d6b57 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Fix crash for genreString when genres nil
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
32b52c4e by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Implement secondary actionable details in audio group types
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
91c0c0e6 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Implement secondary actionable detail in VLCMediaLibraryMediaItem
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
5f37f7d4 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Set null secondary detail on VLCMediaLibraryDummyItem
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
92d39f7d by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add secondary detail button in
VLCLibraryCollectionViewMediaItemSupplementaryDetailView XIB
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
d06a28ae by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Rename detail button to primary detail button in media item
supplementary detail view
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
5883992f by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Implement support for secondary label in
VLCLibraryCollectionViewMediaItemSupplementaryDetaiLView
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
31826b40 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Rename detail stuff to primary detail stuff in
VLCLibraryCollectionViewAlbumSupplementaryDetailView
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
7993da80 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add secondary detail action button to
VLCLibraryCollectionViewAlbumSupplementaryDetailView XIB
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
f3dec496 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Implement backend for secondary detail button in
VLCLibraryCollectionViewAlbumSupplementaryDetailView
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
fdca9b9b by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Properly truncate and elide text buttons in album and media item
supplementary views
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
e0dee3c4 by Claudio Cambra at 2023-11-16T17:57:00+00:00
macosx: Add genre button to VLCLibraryAlbumTableCellView
Signed-off-by: Claudio Cambra <develo...@claudiocambra.com>
- - - - -
19 changed files:
- modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib
- modules/gui/macosx/UI/VLCLibraryCollectionViewAlbumSupplementaryDetailView.xib
-
modules/gui/macosx/UI/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.xib
- modules/gui/macosx/library/VLCLibraryCollectionViewItem.m
-
modules/gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h
-
modules/gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.m
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/library/VLCLibraryHeroView.m
- modules/gui/macosx/library/VLCLibraryModel.h
- modules/gui/macosx/library/VLCLibraryModel.m
- modules/gui/macosx/library/VLCLibraryTableCellView.m
- modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h
- modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
-
modules/gui/macosx/library/audio-library/VLCLibraryAllAudioGroupsMediaLibraryItem.m
- modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupHeaderView.m
-
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h
-
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
- modules/gui/macosx/windows/mainwindow/VLCMainVideoViewControlsBar.m
Changes:
=====================================
modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib
=====================================
@@ -35,25 +35,38 @@
<color key="backgroundColor"
name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
- <button verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="kvo-td-z48">
+ <button verticalHuggingPriority="750"
horizontalCompressionResistancePriority="251"
translatesAutoresizingMaskIntoConstraints="NO" id="kvo-td-z48">
<rect key="frame" x="144" y="386" width="92"
height="19"/>
- <buttonCell key="cell" type="bevel" title="Album
artist" bezelStyle="rounded" alignment="left" imageScaling="proportionallyDown"
inset="2" id="WVL-LH-ZiA">
+ <buttonCell key="cell" type="bevel" title="Album
artist" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail"
truncatesLastVisibleLine="YES" imageScaling="proportionallyDown" inset="2"
id="WVL-LH-ZiA">
<behavior key="behavior" pushIn="YES"
lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="systemSemibold"
size="15"/>
</buttonCell>
<color key="contentTintColor"
name="VLCAccentColor"/>
<connections>
- <action selector="detailAction:"
target="c22-O7-iKe" id="Onc-S8-WGY"/>
+ <action selector="primaryDetailAction:"
target="c22-O7-iKe" id="Jo0-n2-tXc"/>
+ </connections>
+ </button>
+ <button horizontalHuggingPriority="249"
verticalHuggingPriority="750" horizontalCompressionResistancePriority="250"
translatesAutoresizingMaskIntoConstraints="NO" id="VRD-00-4LN">
+ <rect key="frame" x="241" y="386" width="96"
height="19"/>
+ <buttonCell key="cell" type="bevel" title="Album
genre" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail"
truncatesLastVisibleLine="YES" imageScaling="proportionallyDown" inset="2"
id="GDe-oq-fGP">
+ <behavior key="behavior" pushIn="YES"
lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="systemSemibold"
size="15"/>
+ </buttonCell>
+ <color key="contentTintColor"
name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
+ <connections>
+ <action selector="secondaryDetailAction:"
target="c22-O7-iKe" id="9UB-E4-P5J"/>
</connections>
</button>
</subviews>
<constraints>
+ <constraint firstAttribute="trailing"
relation="greaterThanOrEqual" secondItem="VRD-00-4LN"
secondAttribute="trailing" constant="20" id="1LW-wp-fJ6"/>
<constraint firstItem="lyR-U9-HKd"
firstAttribute="top" secondItem="dd9-b1-XEf" secondAttribute="bottom"
constant="5" id="36N-Cq-Zjf"/>
- <constraint firstAttribute="trailing"
relation="greaterThanOrEqual" secondItem="kvo-td-z48"
secondAttribute="trailing" constant="20" id="Wg0-Tn-f2L"/>
+ <constraint firstItem="VRD-00-4LN"
firstAttribute="centerY" secondItem="kvo-td-z48" secondAttribute="centerY"
id="5Va-uv-a7Y"/>
+ <constraint firstItem="VRD-00-4LN"
firstAttribute="leading" secondItem="kvo-td-z48" secondAttribute="trailing"
constant="5" id="QSz-5D-E9n"/>
<constraint firstAttribute="trailing"
relation="greaterThanOrEqual" secondItem="lyR-U9-HKd"
secondAttribute="trailing" constant="20" id="dzL-hG-1nc"/>
</constraints>
</customView>
- <textField horizontalHuggingPriority="251"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="xJW-ps-ycn">
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="xJW-ps-ycn">
<rect key="frame" x="142" y="410" width="104" height="20"/>
<textFieldCell key="cell" lineBreakMode="clipping"
title="Album name" id="aCe-ia-0Ww">
<font key="font" metaFont="systemSemibold" size="17"/>
@@ -102,6 +115,7 @@
<connections>
<outlet property="albumNameTextField" destination="xJW-ps-ycn"
id="nX9-SH-RZA"/>
<outlet property="artistNameTextButton"
destination="kvo-td-z48" id="U94-du-RqP"/>
+ <outlet property="genreNameTextButton"
destination="VRD-00-4LN" id="fqy-F2-oit"/>
<outlet property="playInstantlyButton"
destination="KVh-Zn-l7I" id="Ri1-YF-Fe2"/>
<outlet property="representedImageView"
destination="Ydb-7n-5Cd" id="qBu-r5-jIY"/>
<outlet property="summaryTextField" destination="dd9-b1-XEf"
id="ne9-oA-zPw"/>
=====================================
modules/gui/macosx/UI/VLCLibraryCollectionViewAlbumSupplementaryDetailView.xib
=====================================
@@ -29,7 +29,7 @@
<stackView distribution="fillEqually"
orientation="horizontal" alignment="top" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094"
horizontalHuggingPriority="1000" verticalHuggingPriority="1000"
detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO"
id="6Nc-Mb-wDa">
<rect key="frame" x="0.0" y="0.0"
width="237" height="28"/>
<subviews>
- <button verticalHuggingPriority="750"
imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO"
id="ntd-VT-2KS">
+ <button imageHugsTitle="YES"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="ntd-VT-2KS">
<rect key="frame" x="-6" y="-6"
width="128" height="40"/>
<buttonCell key="cell" type="push"
title=" Play" bezelStyle="rounded" image="play.fill" catalog="system"
imagePosition="left" alignment="center" controlSize="large"
borderStyle="border" imageScaling="proportionallyDown" inset="2"
id="Rgc-Uk-A3h">
<behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@@ -40,7 +40,7 @@
<action selector="playAction:"
target="HAc-or-XD8" id="edJ-21-Ej1"/>
</connections>
</button>
- <button verticalHuggingPriority="750"
imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO"
id="idL-3a-QaA">
+ <button imageHugsTitle="YES"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="idL-3a-QaA">
<rect key="frame" x="115" y="-6"
width="128" height="40"/>
<buttonCell key="cell" type="push"
title=" Enqueue" bezelStyle="rounded" image="plus" catalog="system"
imagePosition="left" alignment="center" controlSize="large"
borderStyle="border" imageScaling="proportionallyDown" inset="2"
id="igY-iu-P0N">
<behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@@ -81,7 +81,7 @@
<stackView distribution="fill" orientation="vertical"
alignment="leading" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="bw7-QB-Ssc">
<rect key="frame" x="257" y="0.0" width="794"
height="282"/>
<subviews>
- <textField horizontalHuggingPriority="251"
verticalHuggingPriority="750" id="nCe-dY-YMM">
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750" id="nCe-dY-YMM">
<rect key="frame" x="-2" y="256"
width="124" height="26"/>
<autoresizingMask key="autoresizingMask"
flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell"
lineBreakMode="truncatingTail" title="Album name" id="6RM-x8-Y4y">
@@ -94,18 +94,29 @@
<rect key="frame" x="0.0" y="203"
width="794" height="48"/>
<autoresizingMask key="autoresizingMask"
widthSizable="YES" flexibleMinY="YES"/>
<subviews>
- <button verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="o9Q-0s-xRU">
- <rect key="frame" x="0.0" y="0.0"
width="154" height="48"/>
- <buttonCell key="cell"
type="bevel" title="Album detail string" bezelStyle="rounded" alignment="left"
imageScaling="proportionallyDown" inset="2" id="SqJ-99-uiI">
+ <button clipsToBounds="YES"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
horizontalCompressionResistancePriority="251"
translatesAutoresizingMaskIntoConstraints="NO" id="o9Q-0s-xRU">
+ <rect key="frame" x="0.0" y="0.0"
width="220" height="48"/>
+ <buttonCell key="cell"
type="bevel" title="Album primary detail string" bezelStyle="rounded"
alignment="left" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES"
imageScaling="proportionallyDown" inset="2" id="SqJ-99-uiI">
<behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font"
metaFont="systemSemibold" size="17"/>
</buttonCell>
<color key="contentTintColor"
name="VLCAccentColor"/>
<connections>
- <action
selector="detailAction:" target="HAc-or-XD8" id="gEr-Qz-9KQ"/>
+ <action
selector="primaryDetailAction:" target="HAc-or-XD8" id="Afg-sr-HiT"/>
</connections>
</button>
- <textField
horizontalHuggingPriority="251" verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="QuO-3G-BMT">
+ <button verticalHuggingPriority="750"
horizontalCompressionResistancePriority="250"
translatesAutoresizingMaskIntoConstraints="NO" id="jNq-xn-yIp">
+ <rect key="frame" x="225" y="0.0"
width="242" height="48"/>
+ <buttonCell key="cell"
type="bevel" title="Album secondary detail string" bezelStyle="rounded"
alignment="left" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES"
imageScaling="proportionallyDown" inset="2" id="3xV-LQ-O7O">
+ <behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font"
metaFont="systemSemibold" size="17"/>
+ </buttonCell>
+ <color key="contentTintColor"
name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
+ <connections>
+ <action
selector="secondaryDetailAction:" target="HAc-or-XD8" id="cDV-Wr-lQD"/>
+ </connections>
+ </button>
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="QuO-3G-BMT">
<rect key="frame" x="687" y="16"
width="94" height="16"/>
<textFieldCell key="cell"
lineBreakMode="clipping" title="Year · Duration" id="JBg-wo-ZeE">
<font key="font"
metaFont="system"/>
@@ -115,30 +126,33 @@
</textField>
</subviews>
<constraints>
+ <constraint firstItem="jNq-xn-yIp"
firstAttribute="leading" secondItem="o9Q-0s-xRU" secondAttribute="trailing"
constant="5" id="5IX-1t-Psn"/>
+ <constraint firstItem="jNq-xn-yIp"
firstAttribute="trailing" relation="lessThanOrEqual" secondItem="QuO-3G-BMT"
secondAttribute="leading" constant="-5" id="88t-Jp-57R"/>
<constraint firstItem="o9Q-0s-xRU"
firstAttribute="top" secondItem="SvO-zd-2zo" secondAttribute="top"
id="QuO-Ev-i98"/>
- <constraint firstItem="o9Q-0s-xRU"
firstAttribute="trailing" relation="lessThanOrEqual" secondItem="QuO-3G-BMT"
secondAttribute="leading" id="R8I-I6-uGg"/>
<constraint firstItem="QuO-3G-BMT"
firstAttribute="centerY" secondItem="SvO-zd-2zo" secondAttribute="centerY"
id="TX6-cF-dnh"/>
<constraint firstAttribute="trailing"
secondItem="QuO-3G-BMT" secondAttribute="trailing" constant="15"
id="Wfo-47-OGd"/>
+ <constraint firstItem="jNq-xn-yIp"
firstAttribute="top" secondItem="SvO-zd-2zo" secondAttribute="top"
id="eBH-UW-wtK"/>
<constraint firstAttribute="bottom"
secondItem="o9Q-0s-xRU" secondAttribute="bottom" id="lvh-r5-QzT"/>
+ <constraint firstAttribute="bottom"
secondItem="jNq-xn-yIp" secondAttribute="bottom" id="msf-KD-aoJ"/>
<constraint firstItem="o9Q-0s-xRU"
firstAttribute="leading" secondItem="SvO-zd-2zo" secondAttribute="leading"
id="nYc-fo-IyN"/>
</constraints>
</customView>
<scrollView borderType="none"
autohidesScrollers="YES" horizontalLineScroll="52" horizontalPageScroll="10"
verticalLineScroll="52" verticalPageScroll="10" hasHorizontalScroller="NO"
usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none"
id="9ZS-oy-iP9" customClass="VLCSubScrollView">
- <rect key="frame" x="0.0" y="0.0"
width="701" height="198"/>
+ <rect key="frame" x="0.0" y="0.0"
width="699" height="198"/>
<autoresizingMask key="autoresizingMask"
widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<clipView key="contentView"
drawsBackground="NO" id="3V4-tX-owM">
- <rect key="frame" x="0.0" y="0.0"
width="701" height="198"/>
+ <rect key="frame" x="0.0" y="0.0"
width="699" height="198"/>
<autoresizingMask
key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView
verticalHuggingPriority="750" allowsExpansionToolTips="YES"
columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth"
columnReordering="NO" multipleSelection="NO" autosaveColumns="NO"
rowHeight="50" viewBased="YES" id="eEJ-WA-0aM"
customClass="VLCLibraryTableView">
- <rect key="frame" x="0.0"
y="0.0" width="701" height="188"/>
+ <rect key="frame" x="0.0"
y="0.0" width="699" height="188"/>
<autoresizingMask
key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing"
width="3" height="2"/>
<color key="backgroundColor"
red="1" green="1" blue="1" alpha="0.0" colorSpace="custom"
customColorSpace="sRGB"/>
<tableViewGridLines
key="gridStyleMask" horizontal="YES"/>
<color key="gridColor"
name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
- <tableColumn editable="NO"
width="689" minWidth="10" maxWidth="1000000000000" id="tVn-dP-rPg">
+ <tableColumn editable="NO"
width="687" minWidth="10" maxWidth="1000000000000" id="tVn-dP-rPg">
<tableHeaderCell
key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<color
key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color
key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@@ -151,7 +165,7 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews>
<tableCellView
id="vmz-MH-Uum">
- <rect
key="frame" x="1" y="1" width="698" height="36"/>
+ <rect
key="frame" x="1" y="1" width="696" height="36"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"
heightSizable="YES"/>
</tableCellView>
</prototypeCellViews>
@@ -213,7 +227,8 @@
</constraints>
<connections>
<outlet property="albumArtworkImageView"
destination="xZd-Hk-h2M" id="J8l-V9-P06"/>
- <outlet property="albumDetailsTextButton"
destination="o9Q-0s-xRU" id="vQv-Q6-HdR"/>
+ <outlet property="albumPrimaryDetailTextButton"
destination="o9Q-0s-xRU" id="At9-hH-CJa"/>
+ <outlet property="albumSecondaryDetailTextButton"
destination="jNq-xn-yIp" id="ESO-jC-EfW"/>
<outlet property="albumTitleTextField"
destination="nCe-dY-YMM" id="h3l-p0-w3e"/>
<outlet property="albumTracksTableView"
destination="eEJ-WA-0aM" id="l8k-M9-a8e"/>
<outlet property="albumYearAndDurationTextField"
destination="QuO-3G-BMT" id="y34-rD-uR"/>
=====================================
modules/gui/macosx/UI/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.xib
=====================================
@@ -29,8 +29,8 @@
<stackView distribution="fillEqually"
orientation="horizontal" alignment="top" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094"
verticalHuggingPriority="1000" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="6Nc-Mb-wDa">
<rect key="frame" x="0.0" y="0.0"
width="180" height="30"/>
<subviews>
- <button verticalHuggingPriority="750"
imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO"
id="ntd-VT-2KS">
- <rect key="frame" x="-6" y="-4"
width="93" height="40"/>
+ <button imageHugsTitle="YES"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="ntd-VT-2KS">
+ <rect key="frame" x="-6" y="-4"
width="94" height="40"/>
<buttonCell key="cell" type="push"
title=" Play" bezelStyle="rounded" image="play.fill" catalog="system"
imagePosition="left" alignment="center" controlSize="large"
borderStyle="border" imageScaling="proportionallyDown" inset="2"
id="Rgc-Uk-A3h">
<behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font"
metaFont="system"/>
@@ -40,8 +40,8 @@
<action selector="playAction:"
target="HAc-or-XD8" id="edJ-21-Ej1"/>
</connections>
</button>
- <button verticalHuggingPriority="750"
imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO"
id="idL-3a-QaA">
- <rect key="frame" x="80" y="-4"
width="106" height="40"/>
+ <button imageHugsTitle="YES"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="idL-3a-QaA">
+ <rect key="frame" x="81" y="-4"
width="105" height="40"/>
<buttonCell key="cell" type="push"
title=" Enqueue" bezelStyle="rounded" image="plus" catalog="system"
imagePosition="left" alignment="center" controlSize="large"
borderStyle="border" imageScaling="proportionallyDown" inset="2"
id="igY-iu-P0N">
<behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font"
metaFont="system"/>
@@ -82,7 +82,7 @@
<stackView distribution="fillEqually"
orientation="vertical" alignment="leading" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094"
horizontalCompressionResistancePriority="250" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="bw7-QB-Ssc">
<rect key="frame" x="200" y="115" width="877"
height="110"/>
<subviews>
- <textField horizontalHuggingPriority="251"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="nCe-dY-YMM">
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="nCe-dY-YMM">
<rect key="frame" x="-2" y="84"
width="167" height="26"/>
<textFieldCell key="cell"
lineBreakMode="truncatingTail" title="Media item name" id="6RM-x8-Y4y">
<font key="font" textStyle="title1"
name=".SFNS-Regular"/>
@@ -90,18 +90,42 @@
<color key="backgroundColor"
name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
- <button verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="S5i-gd-zkt">
- <rect key="frame" x="0.0" y="63"
width="146" height="16"/>
- <buttonCell key="cell" type="bevel"
title="Media item detail string" bezelStyle="rounded" alignment="left"
imageScaling="proportionallyDown" inset="2" id="zkC-9p-xFn">
- <behavior key="behavior" pushIn="YES"
lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="system"/>
- </buttonCell>
- <color key="contentTintColor"
name="VLCAccentColor"/>
- <connections>
- <action selector="detailAction:"
target="HAc-or-XD8" id="JiQ-Ss-fTO"/>
- </connections>
- </button>
- <textField horizontalHuggingPriority="251"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="QuO-3G-BMT">
+ <stackView distribution="fill"
orientation="horizontal" alignment="top"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="JzZ-K9-xaP">
+ <rect key="frame" x="0.0" y="63"
width="417" height="16"/>
+ <subviews>
+ <button verticalHuggingPriority="750"
horizontalCompressionResistancePriority="251"
translatesAutoresizingMaskIntoConstraints="NO" id="S5i-gd-zkt">
+ <rect key="frame" x="0.0" y="0.0"
width="196" height="16"/>
+ <buttonCell key="cell"
type="bevel" title="Media item primary detail string" bezelStyle="rounded"
alignment="left" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES"
imageScaling="proportionallyDown" inset="2" id="zkC-9p-xFn">
+ <behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font"
metaFont="system"/>
+ </buttonCell>
+ <color key="contentTintColor"
name="VLCAccentColor"/>
+ <connections>
+ <action
selector="primaryDetailAction:" target="HAc-or-XD8" id="bFl-ro-arq"/>
+ </connections>
+ </button>
+ <button verticalHuggingPriority="750"
horizontalCompressionResistancePriority="250"
translatesAutoresizingMaskIntoConstraints="NO" id="9CH-03-Iu3">
+ <rect key="frame" x="204" y="0.0"
width="213" height="16"/>
+ <buttonCell key="cell"
type="bevel" title="Media item secondary detail string" bezelStyle="rounded"
alignment="left" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES"
imageScaling="proportionallyDown" inset="2" id="wPH-tu-Uw1">
+ <behavior key="behavior"
pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font"
metaFont="system"/>
+ </buttonCell>
+ <color key="contentTintColor"
name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
+ <connections>
+ <action
selector="secondaryDetailAction:" target="HAc-or-XD8" id="IAX-VG-Kpd"/>
+ </connections>
+ </button>
+ </subviews>
+ <visibilityPriorities>
+ <integer value="1000"/>
+ <integer value="1000"/>
+ </visibilityPriorities>
+ <customSpacing>
+ <real value="3.4028234663852886e+38"/>
+ <real value="3.4028234663852886e+38"/>
+ </customSpacing>
+ </stackView>
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
translatesAutoresizingMaskIntoConstraints="NO" id="QuO-3G-BMT">
<rect key="frame" x="-2" y="42" width="94"
height="16"/>
<textFieldCell key="cell"
lineBreakMode="clipping" title="Year · Duration" id="JBg-wo-ZeE">
<font key="font" metaFont="system"/>
@@ -112,7 +136,7 @@
<stackView distribution="fill"
orientation="horizontal" alignment="top" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="fiJ-9f-ecF">
<rect key="frame" x="0.0" y="21"
width="106" height="16"/>
<subviews>
- <textField
horizontalHuggingPriority="251" verticalHuggingPriority="1000"
horizontalCompressionResistancePriority="1000"
verticalCompressionResistancePriority="1000"
translatesAutoresizingMaskIntoConstraints="NO" id="NZk-WW-Uay">
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="1000"
horizontalCompressionResistancePriority="1000"
verticalCompressionResistancePriority="1000"
translatesAutoresizingMaskIntoConstraints="NO" id="NZk-WW-Uay">
<rect key="frame" x="-2" y="0.0"
width="72" height="16"/>
<textFieldCell key="cell"
lineBreakMode="clipping" title="File Name:" id="CyQ-Ao-mup">
<font key="font"
metaFont="systemBold"/>
@@ -120,7 +144,7 @@
<color key="backgroundColor"
name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
- <textField
verticalHuggingPriority="1000" translatesAutoresizingMaskIntoConstraints="NO"
id="VxL-BW-3eh">
+ <textField focusRingType="none"
verticalHuggingPriority="1000" translatesAutoresizingMaskIntoConstraints="NO"
id="VxL-BW-3eh">
<rect key="frame" x="71" y="0.0"
width="37" height="16"/>
<textFieldCell key="cell"
title="Label" id="Pzf-s3-rHC">
<font key="font"
usesAppearanceFont="YES"/>
@@ -141,7 +165,7 @@
<stackView distribution="fill"
orientation="horizontal" alignment="top" spacing="5"
horizontalStackHuggingPriority="249.99998474121094"
verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES"
translatesAutoresizingMaskIntoConstraints="NO" id="B2d-Zo-xAO">
<rect key="frame" x="0.0" y="0.0"
width="72" height="16"/>
<subviews>
- <textField
horizontalHuggingPriority="251" verticalHuggingPriority="750"
horizontalCompressionResistancePriority="1000"
verticalCompressionResistancePriority="1000"
translatesAutoresizingMaskIntoConstraints="NO" id="hEf-79-49a">
+ <textField focusRingType="none"
horizontalHuggingPriority="251" verticalHuggingPriority="750"
horizontalCompressionResistancePriority="1000"
verticalCompressionResistancePriority="1000"
translatesAutoresizingMaskIntoConstraints="NO" id="hEf-79-49a">
<rect key="frame" x="-2" y="0.0"
width="38" height="16"/>
<textFieldCell key="cell"
lineBreakMode="clipping" title="Path:" id="a9t-Zw-74U">
<font key="font"
metaFont="systemBold"/>
@@ -149,8 +173,8 @@
<color key="backgroundColor"
name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
- <textField
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="7gY-3s-Kay">
- <rect key="frame" x="38" y="0.0"
width="37" height="16"/>
+ <textField focusRingType="none"
verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO"
id="7gY-3s-Kay">
+ <rect key="frame" x="37" y="0.0"
width="37" height="16"/>
<textFieldCell key="cell"
title="Label" id="3XB-SJ-5ia">
<font key="font"
usesAppearanceFont="YES"/>
<color key="textColor"
name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -213,9 +237,10 @@
</constraints>
<connections>
<outlet property="mediaItemArtworkImageView"
destination="xZd-Hk-h2M" id="J8l-V9-P06"/>
- <outlet property="mediaItemDetailButton"
destination="S5i-gd-zkt" id="SsE-11-GwE"/>
<outlet property="mediaItemFileNameTextField"
destination="VxL-BW-3eh" id="fiL-3N-m3P"/>
<outlet property="mediaItemPathTextField"
destination="7gY-3s-Kay" id="P4t-h1-m3P"/>
+ <outlet property="mediaItemPrimaryDetailButton"
destination="S5i-gd-zkt" id="ssB-Jg-jcf"/>
+ <outlet property="mediaItemSecondaryDetailButton"
destination="9CH-03-Iu3" id="J8O-hB-tHb"/>
<outlet property="mediaItemTitleTextField"
destination="nCe-dY-YMM" id="h3l-p0-w3e"/>
<outlet property="mediaItemYearAndDurationTextField"
destination="QuO-3G-BMT" id="y34-rD-uR"/>
<outlet property="playMediaItemButton"
destination="ntd-VT-2KS" id="LJV-KL-cK4"/>
=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewItem.m
=====================================
@@ -214,7 +214,7 @@ const CGFloat
VLCLibraryCollectionViewItemMaximumDisplayedProgress = 0.95;
const id<VLCMediaLibraryItemProtocol> actualItem =
self.representedItem.item;
_mediaTitleTextField.stringValue = actualItem.displayString;
- _secondaryInfoTextField.stringValue = actualItem.detailString;
+ _secondaryInfoTextField.stringValue = actualItem.primaryDetailString;
[VLCLibraryImageCache thumbnailForLibraryItem:actualItem
withCompletion:^(NSImage * const thumbnail) {
self->_mediaImageView.image = thumbnail;
=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h
=====================================
@@ -33,7 +33,8 @@ extern NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewMe
@interface VLCLibraryCollectionViewMediaItemSupplementaryDetailView :
VLCLibraryCollectionViewSupplementaryDetailView
@property (readwrite, weak) IBOutlet NSTextField *mediaItemTitleTextField;
-@property (readwrite, weak) IBOutlet NSButton *mediaItemDetailButton;
+@property (readwrite, weak) IBOutlet NSButton *mediaItemPrimaryDetailButton;
+@property (readwrite, weak) IBOutlet NSButton *mediaItemSecondaryDetailButton;
@property (readwrite, weak) IBOutlet NSTextField
*mediaItemYearAndDurationTextField;
@property (readwrite, weak) IBOutlet NSTextField *mediaItemFileNameTextField;
@property (readwrite, weak) IBOutlet NSTextField *mediaItemPathTextField;
=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.m
=====================================
@@ -48,10 +48,12 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewMediaItem
- (void)awakeFromNib
{
_mediaItemTitleTextField.font = NSFont.VLCLibrarySubsectionHeaderFont;
- _mediaItemDetailButton.font = NSFont.VLCLibrarySubsectionSubheaderFont;
+ _mediaItemPrimaryDetailButton.font =
NSFont.VLCLibrarySubsectionSubheaderFont;
+ _mediaItemSecondaryDetailButton.font =
NSFont.VLCLibrarySubsectionSubheaderFont;
if (@available(macOS 10.14, *)) {
- _mediaItemDetailButton.contentTintColor = NSColor.VLCAccentColor;
+ _mediaItemPrimaryDetailButton.contentTintColor =
NSColor.VLCAccentColor;
+ _mediaItemSecondaryDetailButton.contentTintColor =
NSColor.secondaryLabelColor;
}
if(@available(macOS 10.12.2, *)) {
@@ -90,17 +92,22 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewMediaItem
NSAssert(actualItem != nil, @"represented item is not a media item", nil);
_mediaItemTitleTextField.stringValue = actualItem.displayString;
- _mediaItemDetailButton.title = actualItem.detailString;
+ _mediaItemPrimaryDetailButton.title = actualItem.primaryDetailString;
+ _mediaItemSecondaryDetailButton.title = actualItem.secondaryDetailString;
_mediaItemYearAndDurationTextField.stringValue = [self
formattedYearAndDurationString];
_mediaItemFileNameTextField.stringValue = actualItem.inputItem.name;
_mediaItemPathTextField.stringValue = actualItem.inputItem.decodedMRL;
- const BOOL actionableDetail = actualItem.actionableDetail;
- self.mediaItemDetailButton.enabled = actionableDetail;
+ const BOOL primaryActionableDetail = actualItem.primaryActionableDetail;
+ const BOOL secondaryActionableDetail =
actualItem.secondaryActionableDetail;
+ self.mediaItemPrimaryDetailButton.enabled = primaryActionableDetail;
+ self.mediaItemSecondaryDetailButton.enabled = secondaryActionableDetail;
if (@available(macOS 10.14, *)) {
- self.mediaItemDetailButton.contentTintColor = actionableDetail ?
NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.mediaItemPrimaryDetailButton.contentTintColor =
primaryActionableDetail ? NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.mediaItemSecondaryDetailButton.contentTintColor =
secondaryActionableDetail ? NSColor.secondaryLabelColor :
NSColor.tertiaryLabelColor;
}
- self.mediaItemDetailButton.action = @selector(detailAction:);
+ self.mediaItemPrimaryDetailButton.action = @selector(primaryDetailAction:);
+ self.mediaItemSecondaryDetailButton.action =
@selector(secondaryDetailAction:);
[VLCLibraryImageCache thumbnailForLibraryItem:actualItem
withCompletion:^(NSImage * const thumbnail) {
self->_mediaItemArtworkImageView.image = thumbnail;
@@ -117,15 +124,27 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewMediaItem
[self.representedItem queue];
}
-- (IBAction)detailAction:(id)sender
+- (IBAction)primaryDetailAction:(id)sender
{
VLCMediaLibraryMediaItem * const actualItem = self.representedItem.item;
- if (actualItem == nil || !actualItem.actionableDetail) {
+ if (actualItem == nil || !actualItem.primaryActionableDetail) {
return;
}
VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
- const id<VLCMediaLibraryItemProtocol> libraryItem =
actualItem.actionableDetailLibraryItem;
+ const id<VLCMediaLibraryItemProtocol> libraryItem =
actualItem.primaryActionableDetailLibraryItem;
+ [libraryWindow presentLibraryItem:libraryItem];
+}
+
+- (IBAction)secondaryDetailAction:(id)sender
+{
+ VLCMediaLibraryMediaItem * const actualItem = self.representedItem.item;
+ if (actualItem == nil || !actualItem.secondaryActionableDetail) {
+ return;
+ }
+
+ VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
+ const id<VLCMediaLibraryItemProtocol> libraryItem =
actualItem.secondaryActionableDetailLibraryItem;
[libraryWindow presentLibraryItem:libraryItem];
}
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -31,6 +31,7 @@ extern NSString * const VLCMediaLibraryMediaItemUTI;
@class VLCMediaLibraryMediaItem;
@class VLCMediaLibraryAlbum;
@class VLCMediaLibraryArtist;
+@class VLCMediaLibraryGenre;
@class VLCInputItem;
extern const CGFloat VLCMediaLibrary4KWidth;
@@ -131,18 +132,21 @@ typedef NS_ENUM(NSUInteger,
VLCMediaLibraryParentGroupType) {
@property (readonly) BOOL smallArtworkGenerated;
@property (readonly) NSString *smallArtworkMRL;
@property (readonly) NSString *displayString;
-@property (readonly) NSString *detailString;
+@property (readonly) NSString *primaryDetailString;
+@property (readonly) NSString *secondaryDetailString;
@property (readonly) NSString *durationString;
@property (readonly) VLCMediaLibraryMediaItem *firstMediaItem;
// Media items should be delivered album-wise. If it is required for derivative
// types to provide media items in a different grouping or order, use methods
-// or properties specific to the type (e.g. like in VLCMeidaLibraryGenre)
+// or properties specific to the type (e.g. like in VLCMediaLibraryGenre)
@property (readonly) NSArray<VLCMediaLibraryMediaItem *> *mediaItems;
-// If the info in detailString contains a library object that can be used for
nav
-// We lazy load the actionable library item so avoid using the property until
we
-// actually need to, resort to `actionableDetail` to know if there is one
instead
-@property (readonly) BOOL actionableDetail;
-@property (readonly) id<VLCMediaLibraryItemProtocol>
actionableDetailLibraryItem;
+// If the info in detailString contains a library object that can be used for
nav,
+// we lazy load the actionable library item to avoid using the property until
we
+// actually need to -- resort to `actionableDetail` to know if there is one
instead
+@property (readonly) BOOL primaryActionableDetail;
+@property (readonly) id<VLCMediaLibraryItemProtocol>
primaryActionableDetailLibraryItem;
+@property (readonly) BOOL secondaryActionableDetail;
+@property (readonly) id<VLCMediaLibraryItemProtocol>
secondaryActionableDetailLibraryItem;
- (void)iterateMediaItemsWithBlock:(void
(^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
@@ -153,8 +157,9 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType)
{
@protocol VLCMediaLibraryAudioGroupProtocol <VLCMediaLibraryItemProtocol>
@property (readonly) unsigned int numberOfTracks;
-@property (readonly) NSArray <VLCMediaLibraryArtist *> *artists;
-@property (readonly) NSArray <VLCMediaLibraryAlbum *> *albums;
+@property (readonly) NSArray<VLCMediaLibraryArtist *> *artists;
+@property (readonly) NSArray<VLCMediaLibraryAlbum *> *albums;
+@property (readonly) NSArray<VLCMediaLibraryGenre *> *genres;
@property (readonly) VLCMediaLibraryParentGroupType matchingParentType;
- (void)iterateMediaItemsWithBlock:(void
(^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
@@ -179,6 +184,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType)
{
- (instancetype)initWithArtist:(struct vlc_ml_artist_t *)p_artist;
@property (readonly) NSString *name;
+@property (readonly) NSString *genreString; // Lazy loaded for performance
@property (readonly) NSString *shortBiography;
@property (readonly) NSString *musicBrainzID;
@property (readonly) unsigned int numberOfAlbums;
@@ -193,6 +199,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType)
{
@property (readonly) NSString *title;
@property (readonly) NSString *summary;
@property (readonly) NSString *artistName;
+@property (readonly) NSString *genreString; // Lazy loaded for performance
@property (readonly) int64_t artistID;
@property (readonly) unsigned int duration;
@property (readonly) unsigned int year;
@@ -277,8 +284,9 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType)
{
@interface VLCMediaLibraryDummyItem : NSObject<VLCMediaLibraryItemProtocol>
-- (instancetype)initWithDisplayString:(NSString*)displayString
- withDetailString:(NSString*)detailString;
+- (instancetype)initWithDisplayString:(NSString *)displayString
+ withPrimaryDetailString:(nullable NSString *)primaryDetailString
+ withSecondaryDetailString:(nullable NSString
*)secondaryDetailString;
@end
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -113,6 +113,25 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return [mutableArray copy];
}
+static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> *
const genres)
+{
+ const NSUInteger genreCount = genres.count;
+ if (genreCount == 0) {
+ return @"";
+ }
+
+ VLCMediaLibraryGenre * const firstGenre = genres.firstObject;
+ if (genreCount == 1) {
+ return firstGenre.name;
+ }
+
+ VLCMediaLibraryGenre * const secondGenre = [genres objectAtIndex:1];
+ return [NSString stringWithFormat:_NS("%@, %@, and %lli other genres"),
+ firstGenre.name,
+ secondGenre.name,
+ genreCount - 2];
+}
+
@implementation VLCMediaLibraryFile
- (instancetype)initWithFile:(struct vlc_ml_file_t *)p_file
@@ -259,10 +278,12 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@property (readwrite, assign) int64_t libraryID;
@property (readwrite, assign) BOOL smallArtworkGenerated;
-@property (readwrite, assign) BOOL actionableDetail;
+@property (readwrite, assign) BOOL primaryActionableDetail;
+@property (readwrite, assign) BOOL secondaryActionableDetail;
@property (readwrite, atomic, strong) NSString *smallArtworkMRL;
@property (readwrite, atomic, strong) NSString *displayString;
-@property (readwrite, atomic, strong) NSString *detailString;
+@property (readwrite, atomic, strong) NSString *primaryDetailString;
+@property (readwrite, atomic, strong) NSString *secondaryDetailString;
@property (readwrite, atomic, strong) NSString *durationString;
@end
@@ -281,7 +302,13 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return nil;
}
-- (id<VLCMediaLibraryItemProtocol>)actionableDetailLibraryItem
+- (id<VLCMediaLibraryItemProtocol>)primaryActionableDetailLibraryItem
+{
+ [self doesNotRecognizeSelector:_cmd];
+ return nil;
+}
+
+- (id<VLCMediaLibraryItemProtocol>)secondaryActionableDetailLibraryItem
{
[self doesNotRecognizeSelector:_cmd];
return nil;
@@ -304,8 +331,42 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@end
+@interface VLCAbstractMediaLibraryAudioGroup ()
+{
+ NSArray<VLCMediaLibraryGenre *> *_genres;
+}
+@end
+
@implementation VLCAbstractMediaLibraryAudioGroup
+- (NSArray<VLCMediaLibraryGenre *> *)genres
+{
+ if (_genres == nil) {
+ NSMutableSet<NSNumber *> * const mutableGenreIDs = NSMutableSet.set;
+ NSMutableArray<VLCMediaLibraryGenre *> * const mutableGenres =
NSMutableArray.array;
+
+ for (VLCMediaLibraryMediaItem * const mediaItem in self.mediaItems) {
+ const int64_t genreID = mediaItem.genreID;
+ NSNumber * const numberGenreID = @(mediaItem.genreID);
+ if ([mutableGenreIDs containsObject:numberGenreID]) {
+ continue;
+ }
+
+ VLCMediaLibraryGenre * const genre = [VLCMediaLibraryGenre
genreWithID:genreID];
+ if (genre == nil) {
+ continue;
+ }
+
+ [mutableGenreIDs addObject:numberGenreID];
+ [mutableGenres addObject:genre];
+ }
+
+ _genres = mutableGenres.copy;
+ }
+
+ return _genres;
+}
+
- (NSArray<VLCMediaLibraryArtist *> *)artists
{
[self doesNotRecognizeSelector:_cmd];
@@ -360,6 +421,12 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@end
+@interface VLCMediaLibraryArtist ()
+{
+ NSString *_genreString;
+}
+@end
+
@implementation VLCMediaLibraryArtist
@synthesize numberOfTracks = _numberOfTracks;
@@ -385,7 +452,8 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
self.libraryID = p_artist->i_id;
self.smallArtworkGenerated =
p_artist->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
self.smallArtworkMRL = self.smallArtworkGenerated ?
toNSStr(p_artist->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
- self.actionableDetail = NO;
+ self.primaryActionableDetail = NO;
+ self.secondaryActionableDetail = YES;
_name = toNSStr(p_artist->psz_name);
if ([_name isEqualToString:@""]) {
@@ -405,11 +473,16 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return _name;
}
-- (NSString *)detailString
+- (NSString *)primaryDetailString
{
return [self durationString];
}
+- (NSString *)secondaryDetailString
+{
+ return self.genreString;
+}
+
- (NSString *)durationString
{
NSString *countMetadataString;
@@ -427,6 +500,15 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return countMetadataString;
}
+- (NSString *)genreString
+{
+ if (_genreString == nil || [_genreString isEqualToString:@""]) {
+ _genreString = self.genres == nil ? @"" :
genreArrayDisplayString(self.genres);
+ }
+
+ return _genreString;
+}
+
- (NSArray<VLCMediaLibraryArtist *> *)artists
{
return @[self];
@@ -447,6 +529,11 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return VLCMediaLibraryParentGroupTypeArtist;
}
+- (id<VLCMediaLibraryItemProtocol>)secondaryActionableDetailLibraryItem
+{
+ return self.genres.firstObject;
+}
+
- (void)iterateMediaItemsWithBlock:(void
(^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
{
for(VLCMediaLibraryAlbum* album in self.albums) {
@@ -456,10 +543,16 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@end
+@interface VLCMediaLibraryAlbum ()
+{
+ NSString *_genreString;
+}
+@end
+
@implementation VLCMediaLibraryAlbum
@synthesize numberOfTracks = _numberOfTracks;
-@synthesize actionableDetailLibraryItem = _actionableDetailLibraryItem;
+@synthesize primaryActionableDetailLibraryItem =
_primaryActionableDetailLibraryItem;
+ (nullable instancetype)albumWithID:(int64_t)albumID
{
@@ -482,7 +575,8 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
self.libraryID = p_album->i_id;
self.smallArtworkGenerated =
p_album->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
self.smallArtworkMRL = self.smallArtworkGenerated ?
toNSStr(p_album->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
- self.actionableDetail = YES;
+ self.primaryActionableDetail = YES;
+ self.secondaryActionableDetail = YES;
_title = toNSStr(p_album->psz_title);
if ([_title isEqualToString:@""]) {
@@ -504,11 +598,25 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return _title;
}
-- (NSString *)detailString
+- (NSString *)primaryDetailString
{
return _artistName;
}
+- (NSString *)secondaryDetailString
+{
+ return self.genreString;
+}
+
+- (NSString *)genreString
+{
+ if (_genreString == nil || [_genreString isEqualToString:@""]) {
+ _genreString = genreArrayDisplayString(self.genres);
+ }
+
+ return _genreString;
+}
+
- (NSString *)durationString
{
return [NSString stringWithTime:_duration /
VLCMediaLibraryMediaItemDurationDenominator];
@@ -529,18 +637,23 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return fetchMediaItemsForLibraryItem(vlc_ml_list_album_tracks,
self.libraryID);
}
-- (id<VLCMediaLibraryItemProtocol>)actionableDetailLibraryItem
+- (VLCMediaLibraryParentGroupType)matchingParentType
+{
+ return VLCMediaLibraryParentGroupTypeAlbum;
+}
+
+- (id<VLCMediaLibraryItemProtocol>)primaryActionableDetailLibraryItem
{
- if (_actionableDetailLibraryItem == nil) {
- _actionableDetailLibraryItem = [VLCMediaLibraryArtist
artistWithID:self.artistID];
+ if (_primaryActionableDetailLibraryItem == nil) {
+ _primaryActionableDetailLibraryItem = [VLCMediaLibraryArtist
artistWithID:self.artistID];
}
- return _actionableDetailLibraryItem;
+ return _primaryActionableDetailLibraryItem;
}
-- (VLCMediaLibraryParentGroupType)matchingParentType
+- (id<VLCMediaLibraryItemProtocol>)secondaryActionableDetailLibraryItem
{
- return VLCMediaLibraryParentGroupTypeAlbum;
+ return self.genres.firstObject;
}
- (void)iterateMediaItemsWithBlock:(void
(^)(VLCMediaLibraryMediaItem*))mediaItemBlock
@@ -563,7 +676,8 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
self.libraryID = p_genre->i_id;
self.smallArtworkGenerated =
p_genre->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
self.smallArtworkMRL = self.smallArtworkGenerated ?
toNSStr(p_genre->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
- self.actionableDetail = NO;
+ self.primaryActionableDetail = NO;
+ self.secondaryActionableDetail = NO;
_name = toNSStr(p_genre->psz_name);
if ([_name isEqualToString:@""]) {
@@ -594,7 +708,7 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return _name;
}
-- (NSString *)detailString
+- (NSString *)primaryDetailString
{
return [self durationString];
}
@@ -618,6 +732,12 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return fetchArtistsForLibraryItem(vlc_ml_list_genre_artists,
self.libraryID);
}
+- (NSArray<VLCMediaLibraryGenre *> *)genres
+{
+ // Overloading superclass behaviour
+ return @[self];
+}
+
- (NSArray<VLCMediaLibraryMediaItem *> *)mediaItems
{
return fetchMediaItemsForLibraryItem(vlc_ml_list_genre_tracks,
self.libraryID);
@@ -658,6 +778,10 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@end
@interface VLCMediaLibraryMediaItem ()
+{
+ NSString *_primaryDetailString;
+ NSString *_secondaryDetailString;
+}
@property (readwrite, assign) vlc_medialibrary_t *p_mediaLibrary;
@@ -665,7 +789,8 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@implementation VLCMediaLibraryMediaItem
-@synthesize actionableDetailLibraryItem = _actionableDetailLibraryItem;
+@synthesize primaryActionableDetailLibraryItem =
_primaryActionableDetailLibraryItem;
+@synthesize secondaryActionableDetailLibraryItem =
_secondaryActionableDetailLibraryItem;
#pragma mark - initialization
@@ -725,7 +850,10 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
self.libraryID = p_mediaItem->i_id;
self.smallArtworkGenerated =
p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
self.smallArtworkMRL = self.smallArtworkGenerated ?
toNSStr(p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
- self.actionableDetail = p_mediaItem->i_subtype ==
VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK;
+
+ const BOOL isAlbumTrack = p_mediaItem->i_subtype ==
VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK;
+ self.primaryActionableDetail = isAlbumTrack;
+ self.secondaryActionableDetail = isAlbumTrack;
_p_mediaLibrary = p_mediaLibrary;
_mediaType = p_mediaItem->i_type;
@@ -903,29 +1031,61 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return _title;
}
-- (NSString *)detailString
+- (nullable NSString *)contextualPrimaryDetailString
{
- if (_mediaSubType == VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE) {
- VLCInputItem *inputItem = [self inputItem];
- if (inputItem) {
- NSString *showName = inputItem.showName;
- return showName.length > 0 ? showName : [self durationString];
- }
- } else if (_mediaSubType == VLC_ML_MEDIA_SUBTYPE_MOVIE) {
- VLCInputItem *inputItem = [self inputItem];
- if (inputItem) {
- NSString *directorString = inputItem.director;
- return directorString.length > 0 ? directorString : [self
durationString];
- }
- } else if (_mediaSubType == VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK) {
- VLCMediaLibraryArtist *artist = [VLCMediaLibraryArtist
artistWithID:_artistID];
- if (artist) {
- NSString *artistName = artist.name;
- return artistName.length > 0 ? artistName : [self durationString];
- }
+ switch (self.mediaSubType) {
+ case VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE:
+ return self.inputItem.showName;
+ case VLC_ML_MEDIA_SUBTYPE_MOVIE:
+ return self.inputItem.director;
+ case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
+ {
+ VLCMediaLibraryArtist * const artist = [VLCMediaLibraryArtist
artistWithID:_artistID];
+ return artist.name;
}
+ default:
+ return nil;
+ }
+}
- return [self durationString];
+- (NSString *)primaryDetailString
+{
+ if (_primaryDetailString == nil || [_primaryDetailString
isEqualToString:@""]) {
+ NSString * const contextualString = [self
contextualPrimaryDetailString];
+ const BOOL validContextualString = contextualString != nil &&
contextualString.length > 0;
+ _primaryDetailString = validContextualString ? contextualString :
self.durationString;
+ }
+
+ return _primaryDetailString;
+}
+
+- (nullable NSString *)contextualSecondaryDetailString
+{
+ switch (self.mediaSubType) {
+ case VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE:
+ {
+ VLCInputItem * const inputItem = self.inputItem;
+ return [NSString stringWithFormat:_NS("Season %u, Episode %u"),
+ inputItem.season,
+ inputItem.episode];
+ }
+ case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
+ {
+ VLCMediaLibraryGenre * const genre = [VLCMediaLibraryGenre
genreWithID:self.genreID];
+ return genreArrayDisplayString(@[genre]);
+ }
+ default:
+ return self.inputItem.date;
+ }
+}
+
+- (NSString *)secondaryDetailString
+{
+ if (_secondaryDetailString == nil || [_secondaryDetailString
isEqualToString:@""]) {
+ _secondaryDetailString = [self contextualSecondaryDetailString];
+ }
+
+ return _secondaryDetailString;
}
- (NSString *)durationString
@@ -955,13 +1115,22 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
return @[self];
}
-- (id<VLCMediaLibraryItemProtocol>)actionableDetailLibraryItem
+- (id<VLCMediaLibraryItemProtocol>)primaryActionableDetailLibraryItem
+{
+ if (_primaryActionableDetailLibraryItem == nil && self.mediaSubType ==
VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK) {
+ _primaryActionableDetailLibraryItem = [VLCMediaLibraryAlbum
albumWithID:self.albumID];
+ }
+
+ return _primaryActionableDetailLibraryItem;
+}
+
+- (id<VLCMediaLibraryItemProtocol>)secondaryActionableDetailLibraryItem
{
- if (_mediaSubType == VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK &&
_actionableDetailLibraryItem == nil) {
- _actionableDetailLibraryItem = [VLCMediaLibraryAlbum
albumWithID:self.albumID];
+ if (_secondaryActionableDetailLibraryItem == nil && self.mediaSubType ==
VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK) {
+ _secondaryActionableDetailLibraryItem = [VLCMediaLibraryGenre
genreWithID:self.genreID];
}
- return _actionableDetailLibraryItem;
+ return _secondaryActionableDetailLibraryItem;
}
- (void)iterateMediaItemsWithBlock:(void
(^)(VLCMediaLibraryMediaItem*))mediaItemBlock;
@@ -1236,7 +1405,8 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@implementation VLCMediaLibraryDummyItem
-@synthesize detailString = _detailString;
+@synthesize primaryDetailString = _primaryDetailString;
+@synthesize secondaryDetailString = _secondaryDetailString;
@synthesize displayString = _displayString;
@synthesize durationString = _durationString;
@synthesize firstMediaItem = _firstMediaItem;
@@ -1244,22 +1414,28 @@ static NSArray<VLCMediaLibraryArtist *>
*fetchArtistsForLibraryItem(library_arti
@synthesize libraryID = _libraryId;
@synthesize smallArtworkGenerated = _smallArtworkGenerated;
@synthesize smallArtworkMRL = _smallArtworkMRL;
-@synthesize actionableDetail = _actionableDetail;
-@synthesize actionableDetailLibraryItem = _actionableDetailLibraryItem;
+@synthesize primaryActionableDetail = _primaryActionableDetail;
+@synthesize primaryActionableDetailLibraryItem =
_primaryActionableDetailLibraryItem;
+@synthesize secondaryActionableDetail = _secondaryActionableDetail;
+@synthesize secondaryActionableDetailLibraryItem =
_secondaryActionableDetailLibraryItem;
-- (instancetype)initWithDisplayString:(NSString*)displayString
- withDetailString:(NSString*)detailString
+- (instancetype)initWithDisplayString:(NSString *)displayString
+ withPrimaryDetailString:(nullable NSString *)primaryDetailString
+ withSecondaryDetailString:(nullable NSString
*)secondaryDetailString
{
self = [super init];
if (self) {
_displayString = displayString;
- _detailString = detailString;
+ _primaryDetailString = primaryDetailString;
+ _secondaryDetailString = secondaryDetailString;
_durationString = @"";
_libraryId = -1;
_smallArtworkGenerated = NO;
_smallArtworkMRL = @"";
- _actionableDetail = NO;
- _actionableDetailLibraryItem = nil;
+ _primaryActionableDetail = NO;
+ _primaryActionableDetailLibraryItem = nil;
+ _secondaryActionableDetail = NO;
+ _secondaryActionableDetailLibraryItem = nil;
}
return self;
}
=====================================
modules/gui/macosx/library/VLCLibraryHeroView.m
=====================================
@@ -62,7 +62,7 @@
const id<VLCMediaLibraryItemProtocol> actualItem =
self.representedItem.item;
self.largeImageView.image = [VLCLibraryImageCache
thumbnailForLibraryItem:actualItem];
self.titleTextField.stringValue = actualItem.displayString;
- self.detailTextField.stringValue = actualItem.detailString;
+ self.detailTextField.stringValue = actualItem.primaryDetailString;
}
- (void)setRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
=====================================
modules/gui/macosx/library/VLCLibraryModel.h
=====================================
@@ -84,6 +84,10 @@ extern NSString * const VLCLibraryModelGenreUpdated;
@property (readonly) NSArray <VLCMediaLibraryEntryPoint *>
*listOfMonitoredFolders;
+@property (readonly) NSDictionary<NSNumber *, NSString *> *albumDict;
+@property (readonly) NSDictionary<NSNumber *, NSString *> *artistDict;
+@property (readonly) NSDictionary<NSNumber *, NSString *> *genreDict;
+
- (nullable NSArray<VLCMediaLibraryAlbum *> *)listAlbumsOfParentType:(const
enum vlc_ml_parent_type)parentType forID:(int64_t)ID;
- (NSArray<id<VLCMediaLibraryItemProtocol>>
*)listOfLibraryItemsOfParentType:(const
VLCMediaLibraryParentGroupType)parentType;
- (NSArray<VLCMediaLibraryMediaItem *> *)listOfMediaItemsForParentType:(const
VLCMediaLibraryParentGroupType)parentType;
=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -299,17 +299,25 @@ static void libraryCallback(void *p_data, const
vlc_ml_event_t *p_event)
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
const vlc_ml_query_params_t queryParams = [self queryParams];
- vlc_ml_artist_list_t *p_artist_list =
vlc_ml_list_artists(self->_p_mediaLibrary, &queryParams, NO);
- NSMutableArray *mutableArray = [[NSMutableArray alloc]
initWithCapacity:p_artist_list->i_nb_items];
- for (size_t x = 0; x < p_artist_list->i_nb_items; x++) {
- VLCMediaLibraryArtist *artist = [[VLCMediaLibraryArtist alloc]
initWithArtist:&p_artist_list->p_items[x]];
+ vlc_ml_artist_list_t * const p_artist_list =
vlc_ml_list_artists(self->_p_mediaLibrary, &queryParams, NO);
+ const size_t numberOfArtists = p_artist_list->i_nb_items;
+ NSMutableArray * const mutableArtistArray = [[NSMutableArray alloc]
initWithCapacity:numberOfArtists];
+ NSMutableDictionary * const mutableArtistDict = [NSMutableDictionary
dictionaryWithCapacity:numberOfArtists];
+
+ for (size_t x = 0; x < numberOfArtists; x++) {
+ VLCMediaLibraryArtist * const artist = [[VLCMediaLibraryArtist
alloc] initWithArtist:&p_artist_list->p_items[x]];
+
if (artist != nil) {
- [mutableArray addObject:artist];
+ [mutableArtistArray addObject:artist];
+ [mutableArtistDict setObject:artist.name
forKey:@(artist.libraryID)];
}
}
+
vlc_ml_artist_list_release(p_artist_list);
+
dispatch_async(dispatch_get_main_queue(), ^{
- self.cachedArtists = [mutableArray copy];
+ self.cachedArtists = mutableArtistArray.copy;
+ self->_artistDict = mutableArtistDict.copy;
[self->_defaultNotificationCenter
postNotificationName:VLCLibraryModelArtistListUpdated object:self];
});
});
@@ -337,15 +345,22 @@ static void libraryCallback(void *p_data, const
vlc_ml_event_t *p_event)
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
const vlc_ml_query_params_t queryParams = [self queryParams];
- vlc_ml_album_list_t *p_album_list =
vlc_ml_list_albums(self->_p_mediaLibrary, &queryParams);
- NSMutableArray *mutableArray = [[NSMutableArray alloc]
initWithCapacity:p_album_list->i_nb_items];
- for (size_t x = 0; x < p_album_list->i_nb_items; x++) {
- VLCMediaLibraryAlbum *album = [[VLCMediaLibraryAlbum alloc]
initWithAlbum:&p_album_list->p_items[x]];
- [mutableArray addObject:album];
+ vlc_ml_album_list_t * const p_album_list =
vlc_ml_list_albums(self->_p_mediaLibrary, &queryParams);
+ const size_t numberOfAlbums = p_album_list->i_nb_items;
+ NSMutableArray * const mutableAlbumArray = [[NSMutableArray alloc]
initWithCapacity:numberOfAlbums];
+ NSMutableDictionary * const mutableAlbumDict = [NSMutableDictionary
dictionaryWithCapacity:numberOfAlbums];
+
+ for (size_t x = 0; x < numberOfAlbums; x++) {
+ VLCMediaLibraryAlbum * const album = [[VLCMediaLibraryAlbum alloc]
initWithAlbum:&p_album_list->p_items[x]];
+ [mutableAlbumArray addObject:album];
+ [mutableAlbumDict setObject:album.title forKey:@(album.libraryID)];
}
+
vlc_ml_album_list_release(p_album_list);
+
dispatch_async(dispatch_get_main_queue(), ^{
- self.cachedAlbums = [mutableArray copy];
+ self.cachedAlbums = mutableAlbumArray.copy;
+ self->_albumDict = mutableAlbumDict.copy;
[self->_defaultNotificationCenter
postNotificationName:VLCLibraryModelAlbumListUpdated object:self];
});
});
@@ -373,15 +388,22 @@ static void libraryCallback(void *p_data, const
vlc_ml_event_t *p_event)
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
const vlc_ml_query_params_t queryParams = [self queryParams];
- vlc_ml_genre_list_t *p_genre_list =
vlc_ml_list_genres(self->_p_mediaLibrary, &queryParams);
- NSMutableArray *mutableArray = [[NSMutableArray alloc]
initWithCapacity:p_genre_list->i_nb_items];
- for (size_t x = 0; x < p_genre_list->i_nb_items; x++) {
- VLCMediaLibraryGenre *genre = [[VLCMediaLibraryGenre alloc]
initWithGenre:&p_genre_list->p_items[x]];
- [mutableArray addObject:genre];
+ vlc_ml_genre_list_t * const p_genre_list =
vlc_ml_list_genres(self->_p_mediaLibrary, &queryParams);
+ const size_t numberOfGenres = p_genre_list->i_nb_items;
+ NSMutableArray * const mutableGenreArray = [[NSMutableArray alloc]
initWithCapacity:numberOfGenres];
+ NSMutableDictionary * const mutableGenreDict = [NSMutableDictionary
dictionaryWithCapacity:numberOfGenres];
+
+ for (size_t x = 0; x < numberOfGenres; x++) {
+ VLCMediaLibraryGenre * const genre = [[VLCMediaLibraryGenre alloc]
initWithGenre:&p_genre_list->p_items[x]];
+ [mutableGenreArray addObject:genre];
+ [mutableGenreDict setObject:genre.name forKey:@(genre.libraryID)];
}
+
vlc_ml_genre_list_release(p_genre_list);
+
dispatch_async(dispatch_get_main_queue(), ^{
- self.cachedGenres = [mutableArray copy];
+ self.cachedGenres = mutableGenreArray.copy;
+ self->_genreDict = mutableGenreDict.copy;
[self->_defaultNotificationCenter
postNotificationName:VLCLibraryModelGenreListUpdated object:self];
});
});
=====================================
modules/gui/macosx/library/VLCLibraryTableCellView.m
=====================================
@@ -83,11 +83,11 @@ NSString * const VLCLibraryTableCellViewIdentifier =
@"VLCLibraryTableCellViewId
self.representedImageView.image = thumbnail;
}];
- if(actualItem.detailString.length > 0) {
+ if(actualItem.primaryDetailString.length > 0) {
self.primaryTitleTextField.hidden = NO;
self.primaryTitleTextField.stringValue = actualItem.displayString;
self.secondaryTitleTextField.hidden = NO;
- self.secondaryTitleTextField.stringValue = actualItem.detailString;
+ self.secondaryTitleTextField.stringValue =
actualItem.primaryDetailString;
} else {
self.singlePrimaryTitleTextField.hidden = NO;
self.singlePrimaryTitleTextField.stringValue =
actualItem.displayString;
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.h
=====================================
@@ -43,6 +43,7 @@ extern NSString * const
VLCLibraryAlbumTableCellTableViewColumnIdentifier;
@property (readwrite, assign) IBOutlet VLCImageView *representedImageView;
@property (readwrite, assign) IBOutlet NSTextField *albumNameTextField;
@property (readwrite, assign) IBOutlet NSButton *artistNameTextButton;
+@property (readwrite, assign) IBOutlet NSButton *genreNameTextButton;
@property (readwrite, assign) IBOutlet NSTextField *summaryTextField;
@property (readwrite, assign) IBOutlet NSTextField *yearTextField;
@property (readwrite, assign) IBOutlet NSButton *playInstantlyButton;
@@ -51,7 +52,8 @@ extern NSString * const
VLCLibraryAlbumTableCellTableViewColumnIdentifier;
@property (readwrite, assign, nonatomic) VLCLibraryRepresentedItem
*representedItem;
- (IBAction)playInstantly:(id)sender;
-- (IBAction)detailAction:(id)sender;
+- (IBAction)primaryDetailAction:(id)sender;
+- (IBAction)secondaryDetailAction:(id)sender;
@end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAlbumTableCellView.m
=====================================
@@ -139,11 +139,14 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
[self setupTracksTableView];
self.albumNameTextField.font = NSFont.VLCLibrarySubsectionHeaderFont;
self.artistNameTextButton.font = NSFont.VLCLibrarySubsectionSubheaderFont;
- self.artistNameTextButton.action = @selector(detailAction:);
+ self.genreNameTextButton.font = NSFont.VLCLibrarySubsectionSubheaderFont;
+ self.artistNameTextButton.action = @selector(primaryDetailAction:);
+ self.genreNameTextButton.action = @selector(secondaryDetailAction:);
self.trackingView.viewToHide = self.playInstantlyButton;
if (@available(macOS 10.14, *)) {
self.artistNameTextButton.contentTintColor = NSColor.VLCAccentColor;
+ self.genreNameTextButton.contentTintColor =
NSColor.secondaryLabelColor;
}
[self prepareForReuse];
@@ -207,6 +210,7 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
self.representedImageView.image = nil;
self.albumNameTextField.stringValue = @"";
self.artistNameTextButton.title = @"";
+ self.genreNameTextButton.title = @"";
self.yearTextField.stringValue = @"";
self.summaryTextField.stringValue = @"";
self.yearTextField.hidden = NO;
@@ -214,6 +218,7 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
if (@available(macOS 10.14, *)) {
self.artistNameTextButton.contentTintColor = NSColor.VLCAccentColor;
+ self.genreNameTextButton.contentTintColor =
NSColor.secondaryLabelColor;
}
_tracksDataSource.representedAlbum = nil;
@@ -256,15 +261,27 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
[self.representedItem play];
}
-- (void)detailAction:(id)sender
+- (void)primaryDetailAction:(id)sender
{
VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum
*)self.representedItem.item;
- if (album == nil || !album.actionableDetail) {
+ if (album == nil || !album.primaryActionableDetail) {
return;
}
VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
- const id<VLCMediaLibraryItemProtocol> libraryItem =
album.actionableDetailLibraryItem;
+ const id<VLCMediaLibraryItemProtocol> libraryItem =
album.primaryActionableDetailLibraryItem;
+ [libraryWindow presentLibraryItem:libraryItem];
+}
+
+- (void)secondaryDetailAction:(id)sender
+{
+ VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum
*)self.representedItem.item;
+ if (album == nil || !album.secondaryActionableDetail) {
+ return;
+ }
+
+ VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
+ id<VLCMediaLibraryItemProtocol> libraryItem =
album.secondaryActionableDetailLibraryItem;
[libraryWindow presentLibraryItem:libraryItem];
}
@@ -286,6 +303,7 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
self.albumNameTextField.stringValue = album.title;
self.artistNameTextButton.title = album.artistName;
+ self.genreNameTextButton.title = album.genreString;
if (album.year > 0) {
self.yearTextField.intValue = album.year;
@@ -299,10 +317,13 @@ const CGFloat VLCLibraryAlbumTableCellViewDefaultHeight =
168.;
self.summaryTextField.stringValue = album.durationString;
}
- const BOOL actionableDetail = album.actionableDetail;
- self.artistNameTextButton.enabled = actionableDetail;
+ const BOOL primaryActionableDetail = album.primaryActionableDetail;
+ const BOOL secondaryActionableDetail = album.secondaryActionableDetail;
+ self.artistNameTextButton.enabled = primaryActionableDetail;
+ self.genreNameTextButton.enabled = secondaryActionableDetail;
if (@available(macOS 10.14, *)) {
- self.artistNameTextButton.contentTintColor = actionableDetail ?
NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.artistNameTextButton.contentTintColor = primaryActionableDetail ?
NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.genreNameTextButton.contentTintColor = secondaryActionableDetail
? NSColor.secondaryLabelColor : NSColor.tertiaryLabelColor;
}
[VLCLibraryImageCache thumbnailForLibraryItem:album
withCompletion:^(NSImage * const thumbnail) {
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAllAudioGroupsMediaLibraryItem.m
=====================================
@@ -33,6 +33,7 @@
@synthesize albums = _albums;
@synthesize artists = _artists;
+@synthesize genres = _genres;
@synthesize numberOfTracks = _numberOfTracks;
@synthesize mediaItems = _mediaItems;
@synthesize matchingParentType = _matchingParentType;
@@ -54,9 +55,13 @@
_numberOfTracks = _mediaItems.count;
const NSUInteger numberOfAlbums = libraryModel.numberOfAlbums;
- NSString * const detailString = [NSString stringWithFormat:_NS("%li
albums, %li songs"), numberOfAlbums, _numberOfTracks];
+ NSString * const primaryDetailString = [NSString stringWithFormat:_NS("%li
albums, %li songs"),
+ numberOfAlbums,
+ _numberOfTracks];
- return [super initWithDisplayString:displayString
withDetailString:detailString];
+ return [super initWithDisplayString:displayString
+ withPrimaryDetailString:primaryDetailString
+ withSecondaryDetailString:nil];
}
- (void)iterateMediaItemsWithBlock:(nonnull void (^)(VLCMediaLibraryMediaItem
* _Nonnull))mediaItemBlock
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupHeaderView.m
=====================================
@@ -59,7 +59,7 @@ NSString * const VLCLibraryAudioGroupHeaderViewIdentifier =
@"VLCLibraryAudioGro
}
_titleTextField.stringValue = actualItem.displayString;
- _detailTextField.stringValue = actualItem.detailString;
+ _detailTextField.stringValue = actualItem.primaryDetailString;
}
- (void)setRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.h
=====================================
@@ -35,7 +35,8 @@ extern NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewAl
@interface VLCLibraryCollectionViewAlbumSupplementaryDetailView :
VLCLibraryCollectionViewSupplementaryDetailView
@property (readwrite, weak) IBOutlet NSTextField *albumTitleTextField;
-@property (readwrite, weak) IBOutlet NSButton *albumDetailsTextButton;
+@property (readwrite, weak) IBOutlet NSButton *albumPrimaryDetailTextButton;
+@property (readwrite, weak) IBOutlet NSButton *albumSecondaryDetailTextButton;
@property (readwrite, weak) IBOutlet NSTextField
*albumYearAndDurationTextField;
@property (readwrite, weak) IBOutlet VLCImageView *albumArtworkImageView;
@property (readwrite, weak) IBOutlet NSTableView *albumTracksTableView;
@@ -43,7 +44,8 @@ extern NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewAl
- (IBAction)playAction:(id)sender;
- (IBAction)enqueueAction:(id)sender;
-- (IBAction)detailAction:(id)sender;
+- (IBAction)primaryDetailAction:(id)sender;
+- (IBAction)secondaryDetailAction:(id)sender;
@end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryCollectionViewAlbumSupplementaryDetailView.m
=====================================
@@ -68,12 +68,15 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewAlbumSupp
_albumTracksTableView.rowHeight = VLCLibraryTracksRowHeight;
_albumTitleTextField.font = NSFont.VLCLibrarySubsectionHeaderFont;
- _albumDetailsTextButton.font = NSFont.VLCLibrarySubsectionSubheaderFont;
+ self.albumPrimaryDetailTextButton.font =
NSFont.VLCLibrarySubsectionSubheaderFont;
+ self.albumSecondaryDetailTextButton.font =
NSFont.VLCLibrarySubsectionSubheaderFont;
- _albumDetailsTextButton.action = @selector(detailAction:);
+ self.albumPrimaryDetailTextButton.action = @selector(primaryDetailAction:);
+ self.albumSecondaryDetailTextButton.action =
@selector(secondaryDetailAction:);
if (@available(macOS 10.14, *)) {
- _albumDetailsTextButton.contentTintColor = NSColor.VLCAccentColor;
+ self.albumPrimaryDetailTextButton.contentTintColor =
NSColor.VLCAccentColor;
+ self.albumSecondaryDetailTextButton.contentTintColor =
NSColor.secondaryLabelColor;
}
if(@available(macOS 10.12.2, *)) {
@@ -110,13 +113,17 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewAlbumSupp
NSAssert(album != nil, @"represented item is not an album", nil);
_albumTitleTextField.stringValue = album.displayString;
- _albumDetailsTextButton.title = album.artistName;
+ _albumPrimaryDetailTextButton.title = album.artistName;
+ _albumSecondaryDetailTextButton.title = album.genreString;
_albumYearAndDurationTextField.stringValue = [NSString
stringWithFormat:@"%u · %@", album.year, album.durationString];
- const BOOL actionableDetail = album.actionableDetail;
- self.albumDetailsTextButton.enabled = actionableDetail;
+ const BOOL primaryActionableDetail = album.primaryActionableDetail;
+ const BOOL secondaryActionableDetail = album.secondaryActionableDetail;
+ self.albumPrimaryDetailTextButton.enabled = primaryActionableDetail;
+ self.albumSecondaryDetailTextButton.enabled = secondaryActionableDetail;
if (@available(macOS 10.14, *)) {
- self.albumDetailsTextButton.contentTintColor = actionableDetail ?
NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.albumPrimaryDetailTextButton.contentTintColor =
primaryActionableDetail ? NSColor.VLCAccentColor : NSColor.secondaryLabelColor;
+ self.albumSecondaryDetailTextButton.contentTintColor =
secondaryActionableDetail ? NSColor.secondaryLabelColor :
NSColor.tertiaryLabelColor;
}
[VLCLibraryImageCache thumbnailForLibraryItem:album
withCompletion:^(NSImage * const thumbnail) {
@@ -143,15 +150,27 @@ NSCollectionViewSupplementaryElementKind const
VLCLibraryCollectionViewAlbumSupp
[self.representedItem queue];
}
-- (IBAction)detailAction:(id)sender
+- (IBAction)primaryDetailAction:(id)sender
{
- VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum
*)self.representedItem;
- if (album == nil || !album.actionableDetail) {
+ VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum
*)self.representedItem.item;
+ if (album == nil || !album.primaryActionableDetail) {
+ return;
+ }
+
+ VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
+ const id<VLCMediaLibraryItemProtocol> libraryItem =
album.primaryActionableDetailLibraryItem;
+ [libraryWindow presentLibraryItem:libraryItem];
+}
+
+- (IBAction)secondaryDetailAction:(id)sender
+{
+ VLCMediaLibraryAlbum * const album = (VLCMediaLibraryAlbum
*)self.representedItem.item;
+ if (album == nil || !album.secondaryActionableDetail) {
return;
}
VLCLibraryWindow * const libraryWindow =
VLCMain.sharedInstance.libraryWindow;
- id<VLCMediaLibraryItemProtocol> libraryItem =
album.actionableDetailLibraryItem;
+ const id<VLCMediaLibraryItemProtocol> libraryItem =
album.secondaryActionableDetailLibraryItem;
[libraryWindow presentLibraryItem:libraryItem];
}
=====================================
modules/gui/macosx/windows/mainwindow/VLCMainVideoViewControlsBar.m
=====================================
@@ -71,15 +71,15 @@
- (void)updateDetailLabel:(NSNotification *)notification
{
-
+
VLCMediaLibraryMediaItem * const mediaItem = [VLCMediaLibraryMediaItem
mediaItemForURL:_playerController.URLOfCurrentMediaItem];
if (!mediaItem) {
return;
}
- _detailLabel.hidden = [mediaItem.detailString isEqualToString:@""] ||
- [mediaItem.detailString
isEqualToString:mediaItem.durationString];
- _detailLabel.stringValue = mediaItem.detailString;
+ _detailLabel.hidden = [mediaItem.primaryDetailString isEqualToString:@""]
||
+ [mediaItem.primaryDetailString
isEqualToString:mediaItem.durationString];
+ _detailLabel.stringValue = mediaItem.primaryDetailString;
}
- (IBAction)openBookmarks:(id)sender
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/55803d57ca9025bc8c8575972857218ef78681d0...e0dee3c4f8cac8781d7ab04f4603d712dcf68729
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/55803d57ca9025bc8c8575972857218ef78681d0...e0dee3c4f8cac8781d7ab04f4603d712dcf68729
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits