[vlc-commits] [Git][videolan/vlc][master] 22 commits: macosx: Add started VLCLibraryHeroView XIB
Steve Lhomme (@robUx4)
gitlab at videolan.org
Sun Sep 10 08:59:42 UTC 2023
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
fb1526eb by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add started VLCLibraryHeroView XIB
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
b31aa8e4 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Implement starter design for hero view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
2e922eeb by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Track count of leading custom containers in VLCLibraryVideoCollectionViewsStackViewController
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
1f165214 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add VLCLibraryHeroView class
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
0a702a0e by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add fromNibWithOwner method to VLCLibraryHeroView
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
e6fae356 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Separate constraint setup for new container views for video library view into new method
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
94fc2361 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add convenience method to add NSView to video library view stack view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
82ad32f7 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Initialise hero view in VLCLibraryVideoCollectionViewsStackViewController
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
85fe4306 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add outlets for main hero view components
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
f277c393 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Accept objects conforming to media library item protocol in VLCLibraryImageCache
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
b035c493 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add ability to set represented media library item on VLCLibraryHeroView
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
e322c06b by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add a convenience method to set a represented item at random on VLCHeroView
- - - - -
34dd520d by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Improve visibility of labels in VLCLibraryHeroView
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
9cdb4548 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Rewrite "setRandomItem" as a property-based getter instead
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
3ed1036c by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add internal property to get latest partially played video item
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
558390ac by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add setOptimalRepresentedItem method for VLCLibraryHeroView
Finds either the most recently played item or a random item from the
library to present in the hero view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
9173362e by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Set optimal represented item on hero view upon reload of library video view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
cd50cf9d by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Replace standard NSImageView with VLCImageView in VLCLibraryHeroView
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
35050510 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Make hero view play button functional
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
52baf740 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Adjust text of hero view playh button depending on set optimal item
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
57527179 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Add a explanatory text field to display why video is being shown in hero view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
9196b9f8 by Claudio Cambra at 2023-09-10T08:42:52+00:00
macosx: Update hero view explanation text field depending on optimal item set
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
9 changed files:
- extras/package/macosx/VLC.xcodeproj/project.pbxproj
- modules/gui/macosx/Makefile.am
- + modules/gui/macosx/UI/VLCLibraryHeroView.xib
- + modules/gui/macosx/library/VLCLibraryHeroView.h
- + modules/gui/macosx/library/VLCLibraryHeroView.m
- modules/gui/macosx/library/VLCLibraryImageCache.h
- modules/gui/macosx/library/VLCLibraryImageCache.m
- modules/gui/macosx/library/video-library/VLCLibraryVideoCollectionViewsStackViewController.h
- modules/gui/macosx/library/video-library/VLCLibraryVideoCollectionViewsStackViewController.m
Changes:
=====================================
extras/package/macosx/VLC.xcodeproj/project.pbxproj
=====================================
@@ -108,6 +108,7 @@
539BA79F298C726200918C36 /* VLCAspectRatioRetainingVideoWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 539BA79E298C726200918C36 /* VLCAspectRatioRetainingVideoWindow.m */; };
539F114B29E83A4200F13460 /* VLCLibraryTwoPaneSplitViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 539F114A29E83A4200F13460 /* VLCLibraryTwoPaneSplitViewDelegate.m */; };
539F116D29F9785C00F13460 /* VLCMainVideoViewAudioMediaDecorativeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 539F116C29F9785C00F13460 /* VLCMainVideoViewAudioMediaDecorativeView.m */; };
+ 53B40FD72AA878E400C814E4 /* VLCLibraryHeroView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B40FD62AA878E400C814E4 /* VLCLibraryHeroView.m */; };
53B447CA2939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447C92939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m */; };
53B447F6293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447EC293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.m */; };
53B447F7293BB47B00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B447ED293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerViewDataSource.m */; };
@@ -331,6 +332,9 @@
539F116A29F9756000F13460 /* VLCMainVideoViewAudioMediaDecorativeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCMainVideoViewAudioMediaDecorativeView.xib; sourceTree = "<group>"; };
539F116B29F9785C00F13460 /* VLCMainVideoViewAudioMediaDecorativeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCMainVideoViewAudioMediaDecorativeView.h; sourceTree = "<group>"; };
539F116C29F9785C00F13460 /* VLCMainVideoViewAudioMediaDecorativeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCMainVideoViewAudioMediaDecorativeView.m; sourceTree = "<group>"; };
+ 53B40FD42AA7618000C814E4 /* VLCLibraryHeroView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VLCLibraryHeroView.xib; sourceTree = "<group>"; };
+ 53B40FD52AA878E400C814E4 /* VLCLibraryHeroView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryHeroView.h; sourceTree = "<group>"; };
+ 53B40FD62AA878E400C814E4 /* VLCLibraryHeroView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryHeroView.m; sourceTree = "<group>"; };
53B447C82939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibrarySongsTableViewSongPlayingTableCellView.h; sourceTree = "<group>"; };
53B447C92939823E00857588 /* VLCLibrarySongsTableViewSongPlayingTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibrarySongsTableViewSongPlayingTableCellView.m; sourceTree = "<group>"; };
53B447EC293BB47A00857588 /* VLCLibraryVideoCollectionViewContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryVideoCollectionViewContainerView.m; sourceTree = "<group>"; };
@@ -1216,6 +1220,8 @@
7DFBDCA72269E77500B700A5 /* VLCLibraryController.m */,
7DFBDCB2226CD00900B700A5 /* VLCLibraryDataTypes.h */,
7DFBDCB3226CD00900B700A5 /* VLCLibraryDataTypes.m */,
+ 53B40FD52AA878E400C814E4 /* VLCLibraryHeroView.h */,
+ 53B40FD62AA878E400C814E4 /* VLCLibraryHeroView.m */,
7D92AF1F23DDCA8D00D81EA3 /* VLCLibraryImageCache.h */,
7D92AF2023DDCA8D00D81EA3 /* VLCLibraryImageCache.m */,
7DFBDCAF226A518400B700A5 /* VLCLibraryMenuController.h */,
@@ -1843,6 +1849,7 @@
536283FB2911476A00640C15 /* VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.xib */,
7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */,
536283FC2911476A00640C15 /* VLCLibraryCollectionViewMediaItemSupplementaryDetailView.xib */,
+ 53B40FD42AA7618000C814E4 /* VLCLibraryHeroView.xib */,
536283FA2911476A00640C15 /* VLCLibrarySongTableCellView.xib */,
7DE2F0482282D7980040DD0A /* VLCLibraryTableCellView.xib */,
7D713D332201BB130042BEB7 /* VLCLibraryWindow.xib */,
@@ -1942,6 +1949,7 @@
7DFBDCA82269E77500B700A5 /* VLCLibraryController.m in Sources */,
1CCC88F12078A3D500E5626F /* AddonManager.xib in Sources */,
7DFBDCC1226DC16200B700A5 /* VLCInputItem.m in Sources */,
+ 53B40FD72AA878E400C814E4 /* VLCLibraryHeroView.m in Sources */,
537976BA2A4319330036827E /* VLCSettingTextField.m in Sources */,
1CCC88F22078A3D500E5626F /* AudioEffects.xib in Sources */,
1CCC88F32078A3D500E5626F /* VideoEffects.xib in Sources */,
=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -110,6 +110,8 @@ libmacosx_plugin_la_SOURCES = \
gui/macosx/library/VLCLibraryController.m \
gui/macosx/library/VLCLibraryDataTypes.h \
gui/macosx/library/VLCLibraryDataTypes.m \
+ gui/macosx/library/VLCLibraryHeroView.h \
+ gui/macosx/library/VLCLibraryHeroView.m \
gui/macosx/library/VLCLibraryImageCache.h \
gui/macosx/library/VLCLibraryImageCache.m \
gui/macosx/library/VLCLibraryMenuController.h \
@@ -410,6 +412,7 @@ libmacosx_plugin_la_XIB_SOURCES = \
gui/macosx/UI/VLCLibraryCollectionViewAlbumSupplementaryDetailView.xib \
gui/macosx/UI/VLCLibraryCollectionViewAudioGroupSupplementaryDetailView.xib \
gui/macosx/UI/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.xib \
+ gui/macosx/UI/VLCLibraryHeroView.xib \
gui/macosx/UI/VLCLibrarySongTableCellView.xib \
gui/macosx/UI/VLCMainVideoView.xib \
gui/macosx/UI/VLCMainVideoViewAudioMediaDecorativeView.xib \
=====================================
modules/gui/macosx/UI/VLCLibraryHeroView.xib
=====================================
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
+ <capability name="Named colors" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner"/>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <customView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LPV-K6-7AE" customClass="VLCLibraryHeroView">
+ <rect key="frame" x="0.0" y="0.0" width="833" height="357"/>
+ <subviews>
+ <customView translatesAutoresizingMaskIntoConstraints="NO" id="qdP-As-qZ0" customClass="VLCImageView">
+ <rect key="frame" x="0.0" y="0.0" width="833" height="357"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="357" id="y7Y-rw-LCu"/>
+ </constraints>
+ </customView>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GoN-QI-mru">
+ <rect key="frame" x="18" y="309" width="155" height="28"/>
+ <shadow key="shadow" blurRadius="20">
+ <color key="color" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
+ </shadow>
+ <textFieldCell key="cell" lineBreakMode="clipping" title="Last watched" id="Ggw-iA-v2x">
+ <font key="font" metaFont="systemBold" size="24"/>
+ <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <stackView distribution="fill" orientation="vertical" alignment="leading" spacing="5" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="U3j-Zx-fFf">
+ <rect key="frame" x="20" y="20" width="250" height="86"/>
+ <subviews>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kFW-i6-3hg">
+ <rect key="frame" x="-2" y="58" width="103" height="28"/>
+ <shadow key="shadow" blurRadius="20">
+ <color key="color" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ </shadow>
+ <textFieldCell key="cell" controlSize="large" alignment="left" title="Item title" id="0Cs-Ex-sMn">
+ <font key="font" metaFont="systemBold" size="24"/>
+ <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="aVp-p4-DHX">
+ <rect key="frame" x="-2" y="33" width="139" height="20"/>
+ <shadow key="shadow" blurRadius="20">
+ <color key="color" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ </shadow>
+ <textFieldCell key="cell" controlSize="large" title="Item detail string" id="P7c-bg-dPX">
+ <font key="font" metaFont="systemSemibold" size="17"/>
+ <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <button verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="5zZ-VM-Lb9">
+ <rect key="frame" x="-3" y="-4" width="256" height="35"/>
+ <buttonCell key="cell" type="bevel" title=" Resume playing" bezelStyle="regularSquare" image="play.circle.fill" catalog="system" imagePosition="leading" alignment="left" controlSize="large" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="639-6i-zsD">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="systemSemibold" size="17"/>
+ </buttonCell>
+ <color key="bezelColor" name="VLCAccentColor"/>
+ <color key="contentTintColor" name="VLCAccentColor"/>
+ <connections>
+ <action selector="playRepresentedItem:" target="LPV-K6-7AE" id="fGM-xi-Y8E"/>
+ </connections>
+ </button>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="trailing" secondItem="5zZ-VM-Lb9" secondAttribute="trailing" id="2eF-oY-rR1"/>
+ <constraint firstItem="5zZ-VM-Lb9" firstAttribute="leading" secondItem="U3j-Zx-fFf" secondAttribute="leading" id="8fY-R2-NIT"/>
+ <constraint firstAttribute="bottom" secondItem="5zZ-VM-Lb9" secondAttribute="bottom" id="yDI-oU-4c7"/>
+ </constraints>
+ <visibilityPriorities>
+ <integer value="1000"/>
+ <integer value="1000"/>
+ <integer value="1000"/>
+ </visibilityPriorities>
+ <customSpacing>
+ <real value="3.4028234663852886e+38"/>
+ <real value="3.4028234663852886e+38"/>
+ <real value="3.4028234663852886e+38"/>
+ </customSpacing>
+ </stackView>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="LPV-K6-7AE" secondAttribute="height" multiplier="21:9" id="2HS-zo-d22"/>
+ <constraint firstItem="qdP-As-qZ0" firstAttribute="top" secondItem="LPV-K6-7AE" secondAttribute="top" id="9aA-Ma-Vvy"/>
+ <constraint firstItem="U3j-Zx-fFf" firstAttribute="leading" secondItem="LPV-K6-7AE" secondAttribute="leading" constant="20" symbolic="YES" id="A9P-6v-TYB"/>
+ <constraint firstItem="U3j-Zx-fFf" firstAttribute="width" secondItem="LPV-K6-7AE" secondAttribute="width" multiplier="0.3" id="CkN-iH-QJd"/>
+ <constraint firstAttribute="bottom" secondItem="U3j-Zx-fFf" secondAttribute="bottom" constant="20" id="GKS-hS-EhI"/>
+ <constraint firstItem="GoN-QI-mru" firstAttribute="leading" secondItem="LPV-K6-7AE" secondAttribute="leading" constant="20" id="UTF-IS-5xp"/>
+ <constraint firstItem="U3j-Zx-fFf" firstAttribute="top" relation="greaterThanOrEqual" secondItem="GoN-QI-mru" secondAttribute="bottom" constant="20" id="ZCB-XT-8xc"/>
+ <constraint firstAttribute="bottom" secondItem="qdP-As-qZ0" secondAttribute="bottom" id="lyx-Ea-nZ1"/>
+ <constraint firstItem="qdP-As-qZ0" firstAttribute="leading" secondItem="LPV-K6-7AE" secondAttribute="leading" id="p3I-zN-Dxs"/>
+ <constraint firstItem="GoN-QI-mru" firstAttribute="top" secondItem="LPV-K6-7AE" secondAttribute="top" constant="20" id="xOv-2n-nx5"/>
+ <constraint firstAttribute="trailing" secondItem="qdP-As-qZ0" secondAttribute="trailing" id="yrR-6i-uoU"/>
+ </constraints>
+ <connections>
+ <outlet property="detailTextField" destination="aVp-p4-DHX" id="OZu-HX-Re8"/>
+ <outlet property="explanationTextField" destination="GoN-QI-mru" id="ynd-Jb-Vmn"/>
+ <outlet property="largeImageView" destination="qdP-As-qZ0" id="sD5-PT-ggF"/>
+ <outlet property="playButton" destination="5zZ-VM-Lb9" id="quv-CP-87R"/>
+ <outlet property="titleTextField" destination="kFW-i6-3hg" id="TXW-Kf-ZRh"/>
+ </connections>
+ <point key="canvasLocation" x="260" y="95"/>
+ </customView>
+ </objects>
+ <resources>
+ <image name="play.circle.fill" catalog="system" width="15" height="15"/>
+ <namedColor name="VLCAccentColor">
+ <color red="1" green="0.37999999523162842" blue="0.039999999105930328" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ </namedColor>
+ </resources>
+</document>
=====================================
modules/gui/macosx/library/VLCLibraryHeroView.h
=====================================
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * VLCLibraryHeroView.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at class VLCImageView;
+ at protocol VLCMediaLibraryItemProtocol;
+
+ at interface VLCLibraryHeroView : NSView
+
+ at property (readwrite) IBOutlet VLCImageView *largeImageView;
+ at property (readwrite) IBOutlet NSTextField *explanationTextField;
+ at property (readwrite) IBOutlet NSTextField *titleTextField;
+ at property (readwrite) IBOutlet NSTextField *detailTextField;
+ at property (readwrite) IBOutlet NSButton *playButton;
+
+ at property (readwrite, nonatomic) id<VLCMediaLibraryItemProtocol> representedItem;
+
++ (instancetype)fromNibWithOwner:(id)owner;
+
+- (IBAction)playRepresentedItem:(id)sender;
+- (void)setOptimalRepresentedItem;
+
+ at end
+
+NS_ASSUME_NONNULL_END
=====================================
modules/gui/macosx/library/VLCLibraryHeroView.m
=====================================
@@ -0,0 +1,128 @@
+/*****************************************************************************
+ * VLCLibraryHeroView.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCLibraryHeroView.h"
+
+#import "extensions/NSString+Helpers.h"
+#import "extensions/NSView+VLCAdditions.h"
+
+#import "library/VLCLibraryController.h"
+#import "library/VLCLibraryDataTypes.h"
+#import "library/VLCLibraryImageCache.h"
+#import "library/VLCLibraryModel.h"
+
+#import "main/VLCMain.h"
+
+#import "views/VLCImageView.h"
+
+ at interface VLCLibraryHeroView ()
+
+ at property (readonly) VLCMediaLibraryMediaItem *randomItem;
+ at property (readonly) VLCMediaLibraryMediaItem *latestPartiallyPlayedItem;
+
+ at end
+
+ at implementation VLCLibraryHeroView
+
++ (instancetype)fromNibWithOwner:(id)owner
+{
+ return (VLCLibraryHeroView*)[NSView fromNibNamed:@"VLCLibraryHeroView"
+ withClass:VLCLibraryHeroView.class
+ withOwner:owner];
+}
+
+- (void)awakeFromNib
+{
+ self.largeImageView.contentGravity = VLCImageViewContentGravityResizeAspectFill;
+}
+
+- (void)updateRepresentedItem
+{
+ NSAssert(self.representedItem != nil, @"Should not update nil represented item!");
+ self.largeImageView.image = [VLCLibraryImageCache thumbnailForLibraryItem:self.representedItem];
+ self.titleTextField.stringValue = self.representedItem.displayString;
+ self.detailTextField.stringValue = self.representedItem.detailString;
+}
+
+- (void)setRepresentedItem:(id<VLCMediaLibraryItemProtocol>)representedItem
+{
+ NSParameterAssert(representedItem != nil);
+ if (representedItem == self.representedItem) {
+ return;
+ }
+
+ _representedItem = representedItem;
+ [self updateRepresentedItem];
+}
+
+- (VLCMediaLibraryMediaItem *)randomItem
+{
+ VLCLibraryModel * const libraryModel = VLCMain.sharedInstance.libraryController.libraryModel;
+ const size_t videoCount = libraryModel.numberOfVideoMedia;
+ const uint32_t randIdx = arc4random_uniform((uint32_t)(videoCount - 1));
+ return [libraryModel.listOfVideoMedia objectAtIndex:randIdx];
+}
+
+- (VLCMediaLibraryMediaItem *)latestPartiallyPlayedItem
+{
+ VLCLibraryModel * const libraryModel = VLCMain.sharedInstance.libraryController.libraryModel;
+ NSArray<VLCMediaLibraryMediaItem *> * const recentMedia = libraryModel.listOfRecentMedia;
+ const NSUInteger firstPartialPlayItemIdx = [recentMedia indexOfObjectPassingTest:^BOOL(VLCMediaLibraryMediaItem *testedItem, NSUInteger idx, BOOL *stop) {
+ const float playProgress = testedItem.progress;
+ return playProgress > 0 && playProgress < 100;
+ }];
+
+ if (firstPartialPlayItemIdx == NSNotFound) {
+ return nil;
+ }
+
+ return [recentMedia objectAtIndex:firstPartialPlayItemIdx];
+}
+
+- (void)setOptimalRepresentedItem
+{
+ VLCMediaLibraryMediaItem * const latestPartialPlayItem = self.latestPartiallyPlayedItem;
+ if (latestPartialPlayItem != nil) {
+ self.representedItem = latestPartialPlayItem;
+ self.explanationTextField.stringValue = _NS("Last watched");
+ self.playButton.title = _NS("Resume playing");
+ return;
+ }
+
+ VLCMediaLibraryMediaItem * const randomItem = self.randomItem;
+ if (randomItem != nil) {
+ self.representedItem = randomItem;
+ self.explanationTextField.stringValue = _NS("From your library");
+ self.playButton.title = _NS("Play now");
+ return;
+ }
+
+ NSLog(@"Could not find a food media item for hero view!");
+}
+
+- (IBAction)playRepresentedItem:(id)sender
+{
+ VLCLibraryController * const libraryController = VLCMain.sharedInstance.libraryController;
+ [libraryController appendItemToPlaylist:self.representedItem playImmediately:YES];
+}
+
+ at end
=====================================
modules/gui/macosx/library/VLCLibraryImageCache.h
=====================================
@@ -26,15 +26,15 @@ NS_ASSUME_NONNULL_BEGIN
@class VLCInputItem;
@class VLCPlaylistItem;
- at class VLCAbstractMediaLibraryItem;
+ at protocol VLCMediaLibraryItemProtocol;
@interface VLCLibraryImageCache : NSObject
-+ (nullable NSImage *)thumbnailForLibraryItem:(VLCAbstractMediaLibraryItem*)libraryItem;
++ (nullable NSImage *)thumbnailForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem;
+ (nullable NSImage *)thumbnailForInputItem:(VLCInputItem*)inputItem;
+ (nullable NSImage *)thumbnailForPlaylistItem:(VLCPlaylistItem*)playlistItem;
-+ (void)thumbnailForLibraryItem:(VLCAbstractMediaLibraryItem *)libraryItem
++ (void)thumbnailForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
withCompletion:(void(^)(const NSImage *))completionHandler;
+ (void)thumbnailForInputItem:(VLCInputItem *)inputItem
withCompletion:(void(^)(const NSImage *))completionHandler;
=====================================
modules/gui/macosx/library/VLCLibraryImageCache.m
=====================================
@@ -64,12 +64,12 @@ float kVLCDefaultThumbnailPosition = .15;
return sharedImageCache;
}
-+ (NSImage *)thumbnailForLibraryItem:(VLCAbstractMediaLibraryItem*)libraryItem
++ (NSImage *)thumbnailForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
{
return [[VLCLibraryImageCache sharedImageCache] imageForLibraryItem:libraryItem];
}
-- (NSImage *)imageForLibraryItem:(VLCAbstractMediaLibraryItem*)libraryItem
+- (NSImage *)imageForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
{
NSImage *cachedImage = [_imageCache objectForKey:libraryItem.smallArtworkMRL];
if (cachedImage) {
@@ -78,7 +78,7 @@ float kVLCDefaultThumbnailPosition = .15;
return [self smallThumbnailForLibraryItem:libraryItem];
}
-- (NSImage *)smallThumbnailForLibraryItem:(VLCAbstractMediaLibraryItem*)libraryItem
+- (NSImage *)smallThumbnailForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
{
NSImage *image;
NSString * const artworkMRL = libraryItem.smallArtworkMRL;
@@ -157,7 +157,7 @@ float kVLCDefaultThumbnailPosition = .15;
return [VLCLibraryImageCache.sharedImageCache imageForInputItem:playlistItem.inputItem];
}
-+ (void)thumbnailForLibraryItem:(VLCAbstractMediaLibraryItem *)libraryItem
++ (void)thumbnailForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
withCompletion:(void(^)(const NSImage *))completionHandler
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoCollectionViewsStackViewController.h
=====================================
@@ -24,6 +24,8 @@
NS_ASSUME_NONNULL_BEGIN
+ at class VLCLibraryHeroView;
+
@interface VLCLibraryVideoCollectionViewsStackViewController : NSObject
@property (readwrite, assign, nonatomic) NSSize collectionViewItemSize;
@@ -34,6 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (readwrite, assign, nonatomic) NSStackView *collectionsStackView;
@property (readwrite, assign, nonatomic) NSScrollView *collectionsStackViewScrollView;
+ at property (readonly) VLCLibraryHeroView *heroView;
+
- (void)reloadData;
@end
=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoCollectionViewsStackViewController.m
=====================================
@@ -26,6 +26,7 @@
#import "library/VLCLibraryCollectionViewFlowLayout.h"
#import "library/VLCLibraryCollectionViewSupplementaryElementView.h"
#import "library/VLCLibraryController.h"
+#import "library/VLCLibraryHeroView.h"
#import "library/VLCLibraryModel.h"
#import "library/VLCLibraryUIUnits.h"
@@ -40,6 +41,7 @@
@interface VLCLibraryVideoCollectionViewsStackViewController()
{
NSArray *_collectionViewContainers;
+ NSUInteger _leadingContainerCount;
}
@end
@@ -66,9 +68,19 @@
name:VLCLibraryModelRecentsMediaItemDeleted
object:nil];
+ _leadingContainerCount = 0;
+ [self generateCustomContainers];
[self generateCollectionViewContainers];
}
+- (void)generateCustomContainers
+{
+ _heroView = [VLCLibraryHeroView fromNibWithOwner:self];
+ _leadingContainerCount += 1;
+ [self addView:self.heroView toStackView:self.collectionsStackView];
+ [self.heroView setOptimalRepresentedItem];
+}
+
- (BOOL)recentMediaPresent
{
VLCLibraryModel * const model = VLCMain.sharedInstance.libraryController.libraryModel;
@@ -94,7 +106,8 @@
containerView.videoGroup = VLCLibraryVideoRecentsGroup;
[mutableContainers insertObject:containerView atIndex:0];
- [_collectionsStackView insertArrangedSubview:containerView atIndex:0];
+ // Insert at top after leading containers, hence _leadingContainerCount
+ [_collectionsStackView insertArrangedSubview:containerView atIndex:_leadingContainerCount];
[self setupContainerView:containerView forStackView:_collectionsStackView];
} else {
[mutableContainers removeObjectAtIndex:recentsContainerIndex];
@@ -125,21 +138,23 @@
{
dispatch_async(dispatch_get_main_queue(), ^{
for (VLCLibraryVideoCollectionViewContainerView *containerView in self->_collectionViewContainers) {
+ [self.heroView setOptimalRepresentedItem];
[containerView.collectionView reloadData];
}
});
}
-- (void)setupContainerView:(VLCLibraryVideoCollectionViewContainerView *)containerView
- forStackView:(NSStackView *)stackView
+- (NSArray<NSLayoutConstraint*> *)setupViewConstraints:(NSView *)view
+ forStackView:(NSStackView *)stackView
{
- if (containerView == nil || stackView == nil) {
- return;
+ if (view == nil || stackView == nil) {
+ return @[];
}
- containerView.translatesAutoresizingMaskIntoConstraints = NO;
+ view.translatesAutoresizingMaskIntoConstraints = NO;
+
NSArray<NSLayoutConstraint*> * const constraintsWithSuperview = @[
- [NSLayoutConstraint constraintWithItem:containerView
+ [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:stackView
@@ -147,7 +162,7 @@
multiplier:1
constant:0
],
- [NSLayoutConstraint constraintWithItem:containerView
+ [NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:stackView
@@ -156,8 +171,31 @@
constant:0
],
];
- containerView.constraintsWithSuperview = constraintsWithSuperview;
[stackView addConstraints:constraintsWithSuperview];
+
+ return constraintsWithSuperview;
+}
+
+- (void)setupContainerView:(VLCLibraryVideoCollectionViewContainerView *)containerView
+ forStackView:(NSStackView *)stackView
+{
+ if (containerView == nil || stackView == nil) {
+ return;
+ }
+
+ NSArray<NSLayoutConstraint*> * const constraintsWithSuperview = [self setupViewConstraints:containerView forStackView:stackView];
+ containerView.constraintsWithSuperview = constraintsWithSuperview;
+}
+
+- (void)addView:(NSView *)view
+ toStackView:(NSStackView *)stackView
+{
+ if (view == nil || stackView == nil) {
+ return;
+ }
+
+ [stackView addArrangedSubview:view];
+ [self setupViewConstraints:view forStackView:stackView];
}
- (void)addContainerView:(VLCLibraryVideoCollectionViewContainerView *)containerView
@@ -192,6 +230,9 @@
forOrientation:NSLayoutConstraintOrientationVertical];
+ [self addView:self.heroView toStackView:_collectionsStackView];
+ [self.heroView setOptimalRepresentedItem];
+
for (VLCLibraryVideoCollectionViewContainerView * const containerView in _collectionViewContainers) {
[self addContainerView:containerView toStackView:_collectionsStackView];
}
@@ -235,7 +276,7 @@
}
}
-- (void) setCollectionViewMinimumInteritemSpacing:(CGFloat)collectionViewMinimumInteritemSpacing
+- (void)setCollectionViewMinimumInteritemSpacing:(CGFloat)collectionViewMinimumInteritemSpacing
{
_collectionViewMinimumInteritemSpacing = collectionViewMinimumInteritemSpacing;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8e72e4ce4467ea1cd253f9fcfee8f0500f37451...9196b9f8bb7a856e914c6e3ab2dabd9b0debd34b
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8e72e4ce4467ea1cd253f9fcfee8f0500f37451...9196b9f8bb7a856e914c6e3ab2dabd9b0debd34b
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