From 4510eb8ea914d319334ebeab9e50390faea7a4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Paul=20K=C3=BChne?= <felix@feepk.net> Date: Thu, 9 May 2019 14:14:12 +0200 Subject: [PATCH] macosx/library: add audio specific library interface --- .../macosx/VLC.xcodeproj/project.pbxproj | 28 ++ modules/gui/macosx/Makefile.am | 14 +- .../UI/VLCLibraryAlbumTableCellView.xib | 160 ++++++++++ .../UI/VLCLibraryCollectionViewItem.xib | 2 +- .../gui/macosx/UI/VLCLibraryTableCellView.xib | 106 +++++++ modules/gui/macosx/UI/VLCLibraryWindow.xib | 199 +++++++++++- .../library/VLCLibraryAlbumTableCellView.h | 47 +++ .../library/VLCLibraryAlbumTableCellView.m | 178 +++++++++++ .../library/VLCLibraryAudioDataSource.h | 47 +++ .../library/VLCLibraryAudioDataSource.m | 298 ++++++++++++++++++ .../library/VLCLibraryCollectionViewItem.h | 6 - .../library/VLCLibraryCollectionViewItem.m | 38 +-- .../gui/macosx/library/VLCLibraryDataTypes.h | 4 + .../gui/macosx/library/VLCLibraryDataTypes.m | 24 ++ modules/gui/macosx/library/VLCLibraryModel.h | 16 + modules/gui/macosx/library/VLCLibraryModel.m | 121 ++++++- .../macosx/library/VLCLibraryTableCellView.h | 45 +++ .../macosx/library/VLCLibraryTableCellView.m | 72 +++++ modules/gui/macosx/library/VLCLibraryWindow.h | 4 + modules/gui/macosx/library/VLCLibraryWindow.m | 48 ++- modules/gui/macosx/views/VLCTrackingView.h | 33 ++ modules/gui/macosx/views/VLCTrackingView.m | 58 ++++ po/POTFILES.in | 12 +- 23 files changed, 1491 insertions(+), 69 deletions(-) create mode 100644 modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib create mode 100644 modules/gui/macosx/UI/VLCLibraryTableCellView.xib create mode 100644 modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h create mode 100644 modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m create mode 100644 modules/gui/macosx/library/VLCLibraryAudioDataSource.h create mode 100644 modules/gui/macosx/library/VLCLibraryAudioDataSource.m create mode 100644 modules/gui/macosx/library/VLCLibraryTableCellView.h create mode 100644 modules/gui/macosx/library/VLCLibraryTableCellView.m create mode 100644 modules/gui/macosx/views/VLCTrackingView.h create mode 100644 modules/gui/macosx/views/VLCTrackingView.m diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj index bd50b2e3bc3d..79e27dcbaf5f 100644 --- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj +++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj @@ -103,6 +103,7 @@ 7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */; }; 7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F64042202047900FDB91F /* VLCLibraryCollectionViewItem.m */; }; 7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */; }; + 7D20081A2289835C002679DF /* VLCTrackingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2008192289835C002679DF /* VLCTrackingView.m */; }; 7D28E6362275B4820098D30E /* NSColor+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D28E6352275B4820098D30E /* NSColor+VLCAdditions.m */; }; 7D28E6392275B7340098D30E /* NSFont+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D28E6382275B7340098D30E /* NSFont+VLCAdditions.m */; }; 7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2E0ED920CD204D0033A221 /* VLCWindow.m */; }; @@ -153,6 +154,9 @@ 7DBB7639227F3FBC002649E1 /* VLCLibraryCollectionViewSupplementaryElementView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DBB7638227F3FBC002649E1 /* VLCLibraryCollectionViewSupplementaryElementView.m */; }; 7DC21A7422049A6600F98A02 /* VLCOpenInputMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC21A7322049A6600F98A02 /* VLCOpenInputMetadata.m */; }; 7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */; }; + 7DE2F0442282C84A0040DD0A /* VLCLibraryAudioDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */; }; + 7DE2F0472282D5D10040DD0A /* VLCLibraryTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE2F0462282D5D10040DD0A /* VLCLibraryTableCellView.m */; }; + 7DE82E7922843781002D341A /* VLCLibraryAlbumTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */; }; 7DE9C7DD220728420089108F /* VLCPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE9C7DC220728420089108F /* VLCPlayerController.m */; }; 7DF14FBD2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF14FBB2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.m */; }; 7DFBDCA82269E77500B700A5 /* VLCLibraryController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFBDCA72269E77500B700A5 /* VLCLibraryController.m */; }; @@ -444,6 +448,8 @@ 7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VLCLibraryCollectionViewItem.xib; sourceTree = "<group>"; }; 7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCPlaylistDataSource.h; sourceTree = "<group>"; }; 7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlaylistDataSource.m; sourceTree = "<group>"; }; + 7D2008182289835C002679DF /* VLCTrackingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCTrackingView.h; sourceTree = "<group>"; }; + 7D2008192289835C002679DF /* VLCTrackingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCTrackingView.m; sourceTree = "<group>"; }; 7D28E6342275B4820098D30E /* NSColor+VLCAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSColor+VLCAdditions.h"; sourceTree = "<group>"; }; 7D28E6352275B4820098D30E /* NSColor+VLCAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSColor+VLCAdditions.m"; sourceTree = "<group>"; }; 7D28E6372275B7340098D30E /* NSFont+VLCAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSFont+VLCAdditions.h"; sourceTree = "<group>"; }; @@ -533,6 +539,14 @@ 7DC21A7322049A6600F98A02 /* VLCOpenInputMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCOpenInputMetadata.m; sourceTree = "<group>"; }; 7DD2F5C32081B73B007EE187 /* VLCRemoteControlService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCRemoteControlService.h; sourceTree = "<group>"; }; 7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCRemoteControlService.m; sourceTree = "<group>"; }; + 7DE2F0422282C84A0040DD0A /* VLCLibraryAudioDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAudioDataSource.h; sourceTree = "<group>"; }; + 7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAudioDataSource.m; sourceTree = "<group>"; }; + 7DE2F0452282D5D10040DD0A /* VLCLibraryTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryTableCellView.h; sourceTree = "<group>"; }; + 7DE2F0462282D5D10040DD0A /* VLCLibraryTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryTableCellView.m; sourceTree = "<group>"; }; + 7DE2F0482282D7980040DD0A /* VLCLibraryTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCLibraryTableCellView.xib; sourceTree = "<group>"; }; + 7DE82E7722843781002D341A /* VLCLibraryAlbumTableCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAlbumTableCellView.h; sourceTree = "<group>"; }; + 7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAlbumTableCellView.m; sourceTree = "<group>"; }; + 7DE82E7A228437AA002D341A /* VLCLibraryAlbumTableCellView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VLCLibraryAlbumTableCellView.xib; sourceTree = "<group>"; }; 7DE9C7DB220728420089108F /* VLCPlayerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCPlayerController.h; sourceTree = "<group>"; }; 7DE9C7DC220728420089108F /* VLCPlayerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCPlayerController.m; sourceTree = "<group>"; }; 7DF0435E1972E26A0022B534 /* VLCAddonListItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCAddonListItem.h; sourceTree = "<group>"; }; @@ -829,6 +843,8 @@ 7DFBDCB6226CDFD600B700A5 /* VLCImageView.m */, 7D2FFA3E227B8A5B0085D649 /* VLCLinearProgressIndicator.h */, 7D2FFA3F227B8A5B0085D649 /* VLCLinearProgressIndicator.m */, + 7D2008182289835C002679DF /* VLCTrackingView.h */, + 7D2008192289835C002679DF /* VLCTrackingView.m */, ); path = views; sourceTree = "<group>"; @@ -979,6 +995,10 @@ children = ( 7D0F64032202047900FDB91F /* VLCLibraryCollectionViewItem.h */, 7D0F64042202047900FDB91F /* VLCLibraryCollectionViewItem.m */, + 7DE2F0452282D5D10040DD0A /* VLCLibraryTableCellView.h */, + 7DE2F0462282D5D10040DD0A /* VLCLibraryTableCellView.m */, + 7DE82E7722843781002D341A /* VLCLibraryAlbumTableCellView.h */, + 7DE82E7822843781002D341A /* VLCLibraryAlbumTableCellView.m */, 7DBB7637227F3FBC002649E1 /* VLCLibraryCollectionViewSupplementaryElementView.h */, 7DBB7638227F3FBC002649E1 /* VLCLibraryCollectionViewSupplementaryElementView.m */, 7D713D302201AE350042BEB7 /* VLCLibraryWindow.h */, @@ -991,6 +1011,8 @@ 7DFBDCB3226CD00900B700A5 /* VLCLibraryDataTypes.m */, 7DFBDCAC2269ED0C00B700A5 /* VLCLibraryVideoDataSource.h */, 7DFBDCAD2269ED0C00B700A5 /* VLCLibraryVideoDataSource.m */, + 7DE2F0422282C84A0040DD0A /* VLCLibraryAudioDataSource.h */, + 7DE2F0432282C84A0040DD0A /* VLCLibraryAudioDataSource.m */, 7DFBDCAF226A518400B700A5 /* VLCLibraryMenuController.h */, 7DFBDCB0226A518400B700A5 /* VLCLibraryMenuController.m */, 7D94E28A2274D2140008057F /* VLCLibraryFolderManagementWindow.h */, @@ -1486,6 +1508,8 @@ 7D0F64002201F66D00FDB91F /* VLCPlaylistTableCellView.xib */, 7D445D8F220339D400263D34 /* VLCPlaylistMenu.xib */, 7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */, + 7DE2F0482282D7980040DD0A /* VLCLibraryTableCellView.xib */, + 7DE82E7A228437AA002D341A /* VLCLibraryAlbumTableCellView.xib */, 7DF14FBC2270CB1C0008ABE4 /* VLCMediaSourceCollectionViewItem.xib */, 6B82241A1E4D2A9000833BE1 /* VLCStatusBarIconMainMenu.xib */, 6B8224181E4D2A9000833BE1 /* VLCFullScreenPanel.xib */, @@ -1626,6 +1650,7 @@ 1CCC89022078A3D500E5626F /* ResumeDialog.xib in Sources */, 7D94E28D2274D2140008057F /* VLCLibraryFolderManagementWindow.m in Sources */, 1CCC89032078A3D500E5626F /* SimplePreferences.xib in Sources */, + 7DE82E7922843781002D341A /* VLCLibraryAlbumTableCellView.m in Sources */, 1CCC89042078A3D500E5626F /* StreamOutput.xib in Sources */, 1CCC89052078A3D500E5626F /* TextfieldPanel.xib in Sources */, 1CCC89062078A3D500E5626F /* TimeSelectionPanel.xib in Sources */, @@ -1674,6 +1699,7 @@ 1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */, 1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in Sources */, 7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */, + 7DE2F0442282C84A0040DD0A /* VLCLibraryAudioDataSource.m in Sources */, 7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */, 1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */, 1C3113AF1E508C6900D4DD76 /* VLCFSPanelController.m in Sources */, @@ -1684,6 +1710,7 @@ 7D28E6392275B7340098D30E /* NSFont+VLCAdditions.m in Sources */, 1C3113B61E508C6900D4DD76 /* VLCMain+OldPrefs.m in Sources */, 1C3113B81E508C6900D4DD76 /* VLCMain.m in Sources */, + 7D20081A2289835C002679DF /* VLCTrackingView.m in Sources */, 1CAC3EE820CD1B3B00613DB2 /* VLCVideoOutputProvider.m in Sources */, 1C3113BA1E508C6900D4DD76 /* VLCApplication.m in Sources */, 1C3113BC1E508C6900D4DD76 /* VLCKeyboardBacklightControl.m in Sources */, @@ -1711,6 +1738,7 @@ 1C3113D91E508C6900D4DD76 /* VLCSimplePrefsController.m in Sources */, 7DFBDCC4226E445500B700A5 /* VLCMediaSourceDataSource.m in Sources */, 6B2EFC601F2819F700F3C0EA /* VLCVolumeSlider.m in Sources */, + 7DE2F0472282D5D10040DD0A /* VLCLibraryTableCellView.m in Sources */, 7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */, 6B4D50A71E7AB52C004479B5 /* NSScreen+VLCAdditions.m in Sources */, 1C3113DD1E508C6900D4DD76 /* VLCTrackSynchronizationWindowController.m in Sources */, diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am index f66ec68838ed..183c104dd486 100644 --- a/modules/gui/macosx/Makefile.am +++ b/modules/gui/macosx/Makefile.am @@ -52,14 +52,16 @@ libmacosx_plugin_la_SOURCES = \ gui/macosx/imported/SPMediaKeyTap/SPMediaKeyTap.m \ gui/macosx/library/VLCInputItem.h \ gui/macosx/library/VLCInputItem.m \ + gui/macosx/library/VLCLibraryAlbumTableCellView.h \ + gui/macosx/library/VLCLibraryAlbumTableCellView.m \ + gui/macosx/library/VLCLibraryAudioDataSource.h \ + gui/macosx/library/VLCLibraryAudioDataSource.m \ gui/macosx/library/VLCLibraryCollectionViewItem.h \ gui/macosx/library/VLCLibraryCollectionViewItem.m \ gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.h \ gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.m \ gui/macosx/library/VLCLibraryController.h \ gui/macosx/library/VLCLibraryController.m \ - gui/macosx/library/VLCLibraryVideoDataSource.h \ - gui/macosx/library/VLCLibraryVideoDataSource.m \ gui/macosx/library/VLCLibraryDataTypes.h \ gui/macosx/library/VLCLibraryDataTypes.m \ gui/macosx/library/VLCLibraryFolderManagementWindow.h \ @@ -68,6 +70,10 @@ libmacosx_plugin_la_SOURCES = \ gui/macosx/library/VLCLibraryMenuController.m \ gui/macosx/library/VLCLibraryModel.h \ gui/macosx/library/VLCLibraryModel.m \ + gui/macosx/library/VLCLibraryTableCellView.h \ + gui/macosx/library/VLCLibraryTableCellView.m \ + gui/macosx/library/VLCLibraryVideoDataSource.h \ + gui/macosx/library/VLCLibraryVideoDataSource.m \ gui/macosx/library/VLCLibraryWindow.h \ gui/macosx/library/VLCLibraryWindow.m \ gui/macosx/main/CompatibilityFixes.h \ @@ -185,6 +191,8 @@ libmacosx_plugin_la_SOURCES = \ gui/macosx/views/VLCSliderCell.m \ gui/macosx/views/VLCTimeField.h \ gui/macosx/views/VLCTimeField.m \ + gui/macosx/views/VLCTrackingView.h \ + gui/macosx/views/VLCTrackingView.m \ gui/macosx/views/VLCVolumeSlider.h \ gui/macosx/views/VLCVolumeSlider.m \ gui/macosx/views/VLCVolumeSliderCell.h \ @@ -251,8 +259,10 @@ libmacosx_plugin_la_XIB_SOURCES = \ gui/macosx/UI/Help.xib \ gui/macosx/UI/LogMessageWindow.xib \ gui/macosx/UI/MainMenu.xib \ + gui/macosx/UI/VLCLibraryAlbumTableCellView.xib \ gui/macosx/UI/VLCLibraryWindow.xib \ gui/macosx/UI/VLCLibraryFolderManagementWindow.xib \ + gui/macosx/UI/VLCLibraryTableCellView.xib \ gui/macosx/UI/VLCPlaylistMenu.xib \ gui/macosx/UI/VLCPlaylistTableCellView.xib \ gui/macosx/UI/VLCLibraryCollectionViewItem.xib \ diff --git a/modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib b/modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib new file mode 100644 index 000000000000..a9d933855b4e --- /dev/null +++ b/modules/gui/macosx/UI/VLCLibraryAlbumTableCellView.xib @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="VLCPlaylistTableCellView"/> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customView id="c22-O7-iKe" customClass="VLCLibraryAlbumTableCellView"> + <rect key="frame" x="0.0" y="0.0" width="640" height="450"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="cAS-FG-otl" customClass="VLCTrackingView"> + <rect key="frame" x="0.0" y="0.0" width="640" height="450"/> + </customView> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xJW-ps-ycn"> + <rect key="frame" x="146" y="395" width="80" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Album name" id="aCe-ia-0Ww"> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lyR-U9-HKd"> + <rect key="frame" x="146" y="370" width="31" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Year" id="7gz-CN-9ab"> + <numberFormatter key="formatter" formatterBehavior="default10_4" localizesFormat="NO" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="O17-O0-cUq"> + <real key="minimum" value="0.0"/> + </numberFormatter> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="Ydb-7n-5Cd" customClass="VLCImageView"> + <rect key="frame" x="20" y="326" width="104" height="104"/> + <constraints> + <constraint firstAttribute="height" constant="104" id="Azf-OD-SUU"/> + <constraint firstAttribute="width" constant="104" id="m0o-Ct-VQF"/> + </constraints> + </customView> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dd9-b1-XEf"> + <rect key="frame" x="146" y="345" width="62" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Summary" id="sx3-rr-j2L"> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xp8-b8-BMe"> + <rect key="frame" x="20" y="14" width="600" height="303"/> + <clipView key="contentView" id="Mw1-Z3-rfh"> + <rect key="frame" x="0.0" y="0.0" width="600" height="303"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="3Uj-1y-jNN"> + <rect key="frame" x="0.0" y="0.0" width="600" height="303"/> + <autoresizingMask key="autoresizingMask"/> + <size key="intercellSpacing" width="3" height="2"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> + <tableColumns> + <tableColumn editable="NO" width="597" minWidth="40" maxWidth="1000" id="uk8-7Y-PH4"> + <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/> + </tableHeaderCell> + <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="5BF-Dw-feh"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> + <prototypeCellViews> + <tableCellView id="DeP-kQ-X4h"> + <rect key="frame" x="1" y="1" width="597" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="w77-Dx-5e6"> + <rect key="frame" x="0.0" y="0.0" width="597" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="pqd-by-fVz"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <connections> + <outlet property="textField" destination="w77-Dx-5e6" id="Nb9-7L-0IE"/> + </connections> + </tableCellView> + </prototypeCellViews> + </tableColumn> + </tableColumns> + </tableView> + </subviews> + </clipView> + <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="wFZ-8V-ntY"> + <rect key="frame" x="1" y="119" width="223" height="15"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="A0h-zT-v1o"> + <rect key="frame" x="224" y="17" width="15" height="102"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KVh-Zn-l7I"> + <rect key="frame" x="40" y="346" width="64" height="64"/> + <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="libraryPlay" imagePosition="only" alignment="center" inset="2" id="oLK-Ll-w7g"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="playInstantly:" target="c22-O7-iKe" id="fHy-xk-J2G"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="dd9-b1-XEf" firstAttribute="leading" secondItem="lyR-U9-HKd" secondAttribute="leading" id="1rt-8d-FYu"/> + <constraint firstItem="KVh-Zn-l7I" firstAttribute="centerY" secondItem="Ydb-7n-5Cd" secondAttribute="centerY" id="AZI-Eo-9so"/> + <constraint firstItem="3Uj-1y-jNN" firstAttribute="top" secondItem="Ydb-7n-5Cd" secondAttribute="bottom" constant="9" id="CJ3-50-Sn9"/> + <constraint firstItem="lyR-U9-HKd" firstAttribute="top" secondItem="xJW-ps-ycn" secondAttribute="bottom" constant="8" id="CsN-uw-2Hn"/> + <constraint firstItem="Ydb-7n-5Cd" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="20" id="IWI-9l-HnJ"/> + <constraint firstItem="lyR-U9-HKd" firstAttribute="leading" secondItem="Ydb-7n-5Cd" secondAttribute="trailing" constant="24" id="JgT-WX-XIH"/> + <constraint firstAttribute="trailing" secondItem="Xp8-b8-BMe" secondAttribute="trailing" constant="20" id="KbL-qd-5m6"/> + <constraint firstItem="KVh-Zn-l7I" firstAttribute="centerX" secondItem="Ydb-7n-5Cd" secondAttribute="centerX" id="Mnq-he-JXh"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="xJW-ps-ycn" secondAttribute="trailing" constant="20" id="NhG-8C-EDX"/> + <constraint firstItem="cAS-FG-otl" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="O89-IU-nIf"/> + <constraint firstItem="xJW-ps-ycn" firstAttribute="leading" secondItem="lyR-U9-HKd" secondAttribute="leading" id="Vcg-3v-ITc"/> + <constraint firstItem="dd9-b1-XEf" firstAttribute="top" secondItem="lyR-U9-HKd" secondAttribute="bottom" constant="8" id="YgV-8H-R46"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="dd9-b1-XEf" secondAttribute="trailing" constant="20" id="bTQ-FM-Uy8"/> + <constraint firstItem="Ydb-7n-5Cd" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="20" id="gVW-Rd-TA5"/> + <constraint firstAttribute="bottom" secondItem="cAS-FG-otl" secondAttribute="bottom" id="hr4-VR-MQ0"/> + <constraint firstItem="Xp8-b8-BMe" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="20" id="l8l-PX-NFe"/> + <constraint firstItem="Ydb-7n-5Cd" firstAttribute="centerY" secondItem="lyR-U9-HKd" secondAttribute="centerY" id="oSI-FB-2nA"/> + <constraint firstAttribute="bottom" secondItem="Xp8-b8-BMe" secondAttribute="bottom" constant="14" id="qne-TO-lMs"/> + <constraint firstAttribute="trailing" secondItem="cAS-FG-otl" secondAttribute="trailing" id="w5r-Yv-oeN"/> + <constraint firstItem="cAS-FG-otl" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="zdo-e5-cek"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="lyR-U9-HKd" secondAttribute="trailing" constant="20" id="zmX-17-AFR"/> + </constraints> + <connections> + <outlet property="albumNameTextField" destination="xJW-ps-ycn" id="nX9-SH-RZA"/> + <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"/> + <outlet property="trackingView" destination="cAS-FG-otl" id="9xY-EB-D5j"/> + <outlet property="tracksTableView" destination="3Uj-1y-jNN" id="zIn-tV-FZG"/> + <outlet property="yearTextField" destination="lyR-U9-HKd" id="3Ps-CJ-pI5"/> + </connections> + <point key="canvasLocation" x="219" y="217.5"/> + </customView> + </objects> + <resources> + <image name="libraryPlay" width="64" height="64"/> + </resources> +</document> diff --git a/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib b/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib index 7747707f6a28..bf6fb3d44661 100644 --- a/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib +++ b/modules/gui/macosx/UI/VLCLibraryCollectionViewItem.xib @@ -20,7 +20,7 @@ </customObject> <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> <customObject id="-3" userLabel="Application" customClass="NSObject"/> - <customView id="Hz6-mo-xeY" customClass="VLCLibraryCollectionViewTrackingView"> + <customView id="Hz6-mo-xeY" customClass="VLCTrackingView"> <rect key="frame" x="0.0" y="0.0" width="256" height="214"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <subviews> diff --git a/modules/gui/macosx/UI/VLCLibraryTableCellView.xib b/modules/gui/macosx/UI/VLCLibraryTableCellView.xib new file mode 100644 index 000000000000..4e5a0199f85e --- /dev/null +++ b/modules/gui/macosx/UI/VLCLibraryTableCellView.xib @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="VLCPlaylistTableCellView"/> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customView id="c22-O7-iKe" customClass="VLCLibraryTableCellView"> + <rect key="frame" x="0.0" y="0.0" width="398" height="71"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="ffE-px-l0g" customClass="VLCTrackingView"> + <rect key="frame" x="0.0" y="0.0" width="398" height="71"/> + </customView> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ohB-P0-nCv"> + <rect key="frame" x="76" y="27" width="37" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="ZPw-XO-XD1"> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xJW-ps-ycn"> + <rect key="frame" x="76" y="39" width="37" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="aCe-ia-0Ww"> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9U4-xB-uBz"> + <rect key="frame" x="68" y="35" width="163" height="2"/> + <constraints> + <constraint firstAttribute="height" constant="2" id="504-lb-qgN"/> + <constraint firstAttribute="width" constant="163" id="7H6-lL-hAs"/> + </constraints> + </customView> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TPv-k2-6XS"> + <rect key="frame" x="76" y="16" width="37" height="17"/> + <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="jZ4-pa-K3T"> + <font key="font" usesAppearanceFont="YES"/> + <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="Ydb-7n-5Cd" customClass="VLCImageView"> + <rect key="frame" x="3" y="3" width="65" height="65"/> + <constraints> + <constraint firstAttribute="width" secondItem="Ydb-7n-5Cd" secondAttribute="height" multiplier="1:1" id="4aB-rs-m22"/> + </constraints> + </customView> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NFZ-x0-t5c"> + <rect key="frame" x="20" y="20" width="32" height="32"/> + <constraints> + <constraint firstAttribute="width" constant="32" id="K1a-nD-gSz"/> + <constraint firstAttribute="height" constant="32" id="bai-RH-huE"/> + </constraints> + <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="libraryPlay" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="5MR-Gt-X4p"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="playInstantly:" target="c22-O7-iKe" id="Isu-g1-2RI"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="NFZ-x0-t5c" firstAttribute="centerX" secondItem="Ydb-7n-5Cd" secondAttribute="centerX" id="0Eb-LH-6nF"/> + <constraint firstItem="9U4-xB-uBz" firstAttribute="leading" secondItem="Ydb-7n-5Cd" secondAttribute="trailing" id="2hg-4x-fvu"/> + <constraint firstItem="ohB-P0-nCv" firstAttribute="leading" secondItem="Ydb-7n-5Cd" secondAttribute="trailing" constant="10" id="3wD-FP-vka"/> + <constraint firstItem="TPv-k2-6XS" firstAttribute="leading" secondItem="ohB-P0-nCv" secondAttribute="leading" id="4qb-9H-TVg"/> + <constraint firstItem="Ydb-7n-5Cd" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="3" id="8hv-Qt-uAI"/> + <constraint firstItem="9U4-xB-uBz" firstAttribute="centerY" secondItem="Ydb-7n-5Cd" secondAttribute="centerY" id="BrT-ZR-zAc"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="xJW-ps-ycn" secondAttribute="trailing" constant="3" id="DYW-KQ-pre"/> + <constraint firstItem="xJW-ps-ycn" firstAttribute="leading" secondItem="ohB-P0-nCv" secondAttribute="leading" id="DYk-9g-adD"/> + <constraint firstItem="ffE-px-l0g" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="EMs-It-nUH"/> + <constraint firstAttribute="bottom" secondItem="ffE-px-l0g" secondAttribute="bottom" id="I7D-8N-oA1"/> + <constraint firstItem="ffE-px-l0g" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="M01-2i-CLZ"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="TPv-k2-6XS" secondAttribute="trailing" constant="3" id="PQV-7d-ldF"/> + <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ohB-P0-nCv" secondAttribute="trailing" constant="3" id="Sm0-L4-7aP"/> + <constraint firstAttribute="bottom" secondItem="Ydb-7n-5Cd" secondAttribute="bottom" constant="3" id="aVd-Ld-lUH"/> + <constraint firstItem="TPv-k2-6XS" firstAttribute="top" secondItem="9U4-xB-uBz" secondAttribute="bottom" constant="2" id="bpM-Qh-hOY"/> + <constraint firstItem="NFZ-x0-t5c" firstAttribute="centerY" secondItem="Ydb-7n-5Cd" secondAttribute="centerY" id="dRw-WH-Y00"/> + <constraint firstItem="Ydb-7n-5Cd" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="3" id="iPZ-zR-jTv"/> + <constraint firstAttribute="trailing" secondItem="ffE-px-l0g" secondAttribute="trailing" id="m4c-HB-V5e"/> + <constraint firstItem="ohB-P0-nCv" firstAttribute="centerY" secondItem="c22-O7-iKe" secondAttribute="centerY" id="mGo-gc-dR6"/> + <constraint firstItem="9U4-xB-uBz" firstAttribute="top" secondItem="xJW-ps-ycn" secondAttribute="bottom" constant="2" id="tbV-d6-umL"/> + </constraints> + <connections> + <outlet property="playInstantlyButton" destination="NFZ-x0-t5c" id="suD-1u-UrY"/> + <outlet property="primaryTitleTextField" destination="xJW-ps-ycn" id="5Vl-3a-J2T"/> + <outlet property="representedImageView" destination="Ydb-7n-5Cd" id="qBu-r5-jIY"/> + <outlet property="secondaryTitleTextField" destination="TPv-k2-6XS" id="rRg-vu-a7j"/> + <outlet property="singlePrimaryTitleTextField" destination="ohB-P0-nCv" id="gBJ-WZ-6pB"/> + <outlet property="trackingView" destination="ffE-px-l0g" id="Eme-n5-LGv"/> + </connections> + <point key="canvasLocation" x="98" y="50.5"/> + </customView> + </objects> + <resources> + <image name="libraryPlay" width="64" height="64"/> + </resources> +</document> diff --git a/modules/gui/macosx/UI/VLCLibraryWindow.xib b/modules/gui/macosx/UI/VLCLibraryWindow.xib index 76965f6c1c48..b29b8c023fe0 100644 --- a/modules/gui/macosx/UI/VLCLibraryWindow.xib +++ b/modules/gui/macosx/UI/VLCLibraryWindow.xib @@ -312,6 +312,10 @@ </constraints> </view> <connections> + <outlet property="audioCategorySelectionTableView" destination="dNP-8u-8iI" id="KiD-PX-T2p"/> + <outlet property="audioCollectionSelectionTableView" destination="LNt-ot-2wU" id="eJS-WZ-Ri7"/> + <outlet property="audioGroupSelectionTableView" destination="4ll-T2-J16" id="bjS-a8-ePC"/> + <outlet property="audioLibrarySplitView" destination="llh-BF-BEJ" id="Uri-tX-OQS"/> <outlet property="clearPlaylistButton" destination="cih-xp-HmY" id="PoU-co-0kn"/> <outlet property="clearPlaylistSeparator" destination="nAW-KH-ipk" id="Af9-fg-u7m"/> <outlet property="controlsBar" destination="Uzf-Tf-H8x" id="n0G-92-F2Q"/> @@ -422,13 +426,14 @@ <real value="3.4028234663852886e+38"/> <real value="3.4028234663852886e+38"/> </customSpacing> + <point key="canvasLocation" x="585" y="10"/> </stackView> <scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="cFG-c9-cI9"> <rect key="frame" x="0.0" y="0.0" width="242" height="291"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <clipView key="contentView" id="tI4-x3-55j"> <rect key="frame" x="0.0" y="0.0" width="242" height="291"/> - <autoresizingMask key="autoresizingMask"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <collectionView id="r7v-GI-W1U"> <rect key="frame" x="0.0" y="0.0" width="242" height="291"/> @@ -449,6 +454,198 @@ <autoresizingMask key="autoresizingMask"/> </scroller> </scrollView> + <splitView dividerStyle="thin" vertical="YES" id="llh-BF-BEJ"> + <rect key="frame" x="0.0" y="0.0" width="508" height="327"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="38" horizontalPageScroll="10" verticalLineScroll="38" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="BbK-Tj-iCB"> + <rect key="frame" x="0.0" y="0.0" width="155" height="327"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <clipView key="contentView" id="dmB-cB-az6"> + <rect key="frame" x="0.0" y="0.0" width="155" height="327"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" rowHeight="36" rowSizeStyle="large" viewBased="YES" id="dNP-8u-8iI"> + <rect key="frame" x="0.0" y="0.0" width="155" height="327"/> + <autoresizingMask key="autoresizingMask"/> + <size key="intercellSpacing" width="3" height="2"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> + <tableColumns> + <tableColumn width="152" minWidth="40" maxWidth="1000" id="ldG-xS-ywp"> + <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/> + </tableHeaderCell> + <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="mIp-tF-277"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> + <prototypeCellViews> + <tableCellView id="iS7-pe-SOa"> + <rect key="frame" x="1" y="1" width="152" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jff-ZN-6z1"> + <rect key="frame" x="0.0" y="0.0" width="152" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="smc-Zb-hk9"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <connections> + <outlet property="textField" destination="jff-ZN-6z1" id="JTF-tq-wQB"/> + </connections> + </tableCellView> + </prototypeCellViews> + </tableColumn> + </tableColumns> + </tableView> + </subviews> + </clipView> + <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="ddc-LV-cIL"> + <rect key="frame" x="0.0" y="311" width="155" height="16"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="VgV-Ti-WiA"> + <rect key="frame" x="224" y="17" width="15" height="102"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + <scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="HrP-Dz-Uh0"> + <rect key="frame" x="156" y="0.0" width="154" height="327"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <clipView key="contentView" id="qva-RZ-DvL"> + <rect key="frame" x="0.0" y="0.0" width="154" height="327"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" viewBased="YES" id="LNt-ot-2wU"> + <rect key="frame" x="0.0" y="0.0" width="154" height="327"/> + <autoresizingMask key="autoresizingMask"/> + <size key="intercellSpacing" width="3" height="2"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> + <tableColumns> + <tableColumn width="151" minWidth="40" maxWidth="1000" id="z5o-3O-6vc"> + <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/> + </tableHeaderCell> + <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="eXM-oB-xvr"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> + <prototypeCellViews> + <tableCellView id="EIR-sY-f8g"> + <rect key="frame" x="1" y="1" width="151" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xaz-WB-iQI"> + <rect key="frame" x="0.0" y="0.0" width="151" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="zRF-hR-42C"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <connections> + <outlet property="textField" destination="xaz-WB-iQI" id="922-hW-hWo"/> + </connections> + </tableCellView> + </prototypeCellViews> + </tableColumn> + </tableColumns> + </tableView> + </subviews> + </clipView> + <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="aaq-MO-i51"> + <rect key="frame" x="0.0" y="311" width="154" height="16"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="4hx-EC-ewp"> + <rect key="frame" x="224" y="17" width="15" height="102"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + <scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="Jmx-bp-HDp"> + <rect key="frame" x="311" y="0.0" width="197" height="327"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <clipView key="contentView" id="xCC-h9-931"> + <rect key="frame" x="0.0" y="0.0" width="197" height="327"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="4ll-T2-J16"> + <rect key="frame" x="0.0" y="0.0" width="197" height="327"/> + <autoresizingMask key="autoresizingMask"/> + <size key="intercellSpacing" width="3" height="2"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> + <tableColumns> + <tableColumn width="194" minWidth="40" maxWidth="1000" id="WLd-Pi-bR4"> + <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/> + </tableHeaderCell> + <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Ecs-pW-kyf"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> + <prototypeCellViews> + <tableCellView id="iSk-Qz-DTG"> + <rect key="frame" x="1" y="1" width="194" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6ht-Tg-XJ9"> + <rect key="frame" x="0.0" y="0.0" width="194" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="dbf-tg-Ss3"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <connections> + <outlet property="textField" destination="6ht-Tg-XJ9" id="GT2-9W-mo0"/> + </connections> + </tableCellView> + </prototypeCellViews> + </tableColumn> + </tableColumns> + </tableView> + </subviews> + </clipView> + <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="mRg-Fu-cbF"> + <rect key="frame" x="1" y="310" width="195" height="16"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="dLx-ZX-Ou3"> + <rect key="frame" x="224" y="17" width="15" height="102"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + </subviews> + <holdingPriorities> + <real value="250"/> + <real value="250"/> + <real value="250"/> + </holdingPriorities> + <point key="canvasLocation" x="109" y="-224.5"/> + </splitView> </objects> <resources> <image name="backward-3btns" width="29" height="23"/> diff --git a/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h b/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h new file mode 100644 index 000000000000..814011f7f8b3 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h @@ -0,0 +1,47 @@ +/***************************************************************************** + * VLCLibraryAlbumTableCellView.h: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import <Cocoa/Cocoa.h> + +NS_ASSUME_NONNULL_BEGIN + +@class VLCImageView; +@class VLCLibraryTracksDataSource; +@class VLCTrackingView; +@class VLCMediaLibraryAlbum; + +@interface VLCLibraryAlbumTableCellView : NSTableCellView + +@property (readwrite, assign) IBOutlet VLCTrackingView *trackingView; +@property (readwrite, assign) IBOutlet VLCImageView *representedImageView; +@property (readwrite, assign) IBOutlet NSTextField *albumNameTextField; +@property (readwrite, assign) IBOutlet NSTextField *summaryTextField; +@property (readwrite, assign) IBOutlet NSTextField *yearTextField; +@property (readwrite, assign) IBOutlet NSTableView *tracksTableView; +@property (readwrite, assign) IBOutlet NSButton *playInstantlyButton; +- (IBAction)playInstantly:(id)sender; + +@property (readwrite, assign, nonatomic) VLCMediaLibraryAlbum *representedAlbum; + +@end + +NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m b/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m new file mode 100644 index 000000000000..98eb6e070b70 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m @@ -0,0 +1,178 @@ +/***************************************************************************** + * VLCLibraryAlbumTableself.m: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import "VLCLibraryAlbumTableCellView.h" +#import "extensions/NSFont+VLCAdditions.h" +#import "extensions/NSString+Helpers.h" +#import "views/VLCImageView.h" +#import "views/VLCTrackingView.h" +#import "main/VLCMain.h" +#import "library/VLCLibraryController.h" +#import "library/VLCLibraryDataTypes.h" +#import "library/VLCLibraryTableCellView.h" + +static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier"; + +@interface VLCLibraryTracksDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate> + +@property (readwrite, retain, nonatomic, nullable) VLCMediaLibraryAlbum *representedAlbum; + +@end + +@interface VLCLibraryAlbumTableCellView () +{ + VLCLibraryController *_libraryController; + VLCLibraryTracksDataSource *_tracksDataSource; +} +@end + +@implementation VLCLibraryAlbumTableCellView + +- (void)awakeFromNib +{ + self.albumNameTextField.font = [NSFont VLClibraryCellTitleFont]; + self.yearTextField.font = [NSFont VLClibraryCellTitleFont]; + self.summaryTextField.font = [NSFont VLClibraryCellSubtitleFont]; + self.trackingView.viewToHide = self.playInstantlyButton; + [self prepareForReuse]; +} + +- (void)prepareForReuse +{ + self.representedImageView.image = nil; + self.albumNameTextField.stringValue = @""; + self.yearTextField.stringValue = @""; + self.summaryTextField.stringValue = @""; + self.playInstantlyButton.hidden = YES; +} + +- (IBAction)playInstantly:(id)sender +{ + if (!_libraryController) { + _libraryController = [[VLCMain sharedInstance] libraryController]; + } + + NSArray *tracks = [_representedAlbum tracksAsMediaItems]; + NSUInteger trackCount = tracks.count; + BOOL playImmediately = YES; + for (NSUInteger x = 0; x < trackCount; x++) { + [_libraryController appendItemToPlaylist:tracks[x] playImmediately:playImmediately]; + if (playImmediately) { + playImmediately = NO; + } + } +} + +- (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)representedAlbum +{ + _representedAlbum = representedAlbum; + self.albumNameTextField.stringValue = _representedAlbum.title; + self.yearTextField.intValue = _representedAlbum.year; + self.summaryTextField.stringValue = _representedAlbum.summary; + + NSImage *image; + if (_representedAlbum.artworkMRL.length > 0) { + image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:_representedAlbum.artworkMRL]]; + } + if (!image) { + image = [NSImage imageNamed: @"noart.png"]; + } + self.representedImageView.image = image; + + self.tracksTableView.rowHeight = 50.; + _tracksDataSource = [[VLCLibraryTracksDataSource alloc] init]; + _tracksDataSource.representedAlbum = _representedAlbum; + self.tracksTableView.dataSource = _tracksDataSource; + self.tracksTableView.delegate = _tracksDataSource; +} + +@end + +@interface VLCLibraryTracksDataSource () +{ + NSArray *_tracks; +} +@end + +@implementation VLCLibraryTracksDataSource + +- (void)setRepresentedAlbum:(VLCMediaLibraryAlbum *)representedAlbum +{ + _representedAlbum = representedAlbum; + _tracks = [_representedAlbum tracksAsMediaItems]; +} + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + if (_representedAlbum != nil) { + return _representedAlbum.numberOfTracks; + } + + return 0; +} + +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + VLCLibraryTableCellView *cellView = [tableView makeViewWithIdentifier:VLCAudioLibraryCellIdentifier owner:self]; + + if (cellView == nil) { + /* the following code saves us an instance of NSViewController which we don't need */ + NSNib *nib = [[NSNib alloc] initWithNibNamed:@"VLCLibraryTableCellView" bundle:nil]; + NSArray *topLevelObjects; + if (![nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) { + NSAssert(1, @"Failed to load nib file to show audio library items"); + return nil; + } + + for (id topLevelObject in topLevelObjects) { + if ([topLevelObject isKindOfClass:[VLCLibraryTableCellView class]]) { + cellView = topLevelObject; + break; + } + } + cellView.identifier = VLCAudioLibraryCellIdentifier; + } + + VLCMediaLibraryMediaItem *mediaItem = _tracks[row]; + + NSImage *image; + if (mediaItem.artworkGenerated) { + if (mediaItem.artworkMRL.length > 0) { + image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:mediaItem.artworkMRL]]; + } + } + if (!image) { + image = [NSImage imageNamed: @"noart.png"]; + } + cellView.representedImageView.image = image; + cellView.representedMediaItem = mediaItem; + + NSString *title = mediaItem.title; + cellView.primaryTitleTextField.hidden = NO; + cellView.secondaryTitleTextField.hidden = NO; + cellView.primaryTitleTextField.stringValue = title; + cellView.secondaryTitleTextField.stringValue = [NSString stringWithTime:mediaItem.duration / 1000]; + + return cellView; +} + +@end diff --git a/modules/gui/macosx/library/VLCLibraryAudioDataSource.h b/modules/gui/macosx/library/VLCLibraryAudioDataSource.h new file mode 100644 index 000000000000..016ddd8e4b93 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryAudioDataSource.h @@ -0,0 +1,47 @@ +/***************************************************************************** + * VLCLibraryAudioDataSource.h: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import <Cocoa/Cocoa.h> + +NS_ASSUME_NONNULL_BEGIN + +@class VLCLibraryModel; +@class VLCLibraryGroupDataSource; +@class VLCMediaLibraryAlbum; + +@interface VLCLibraryAudioDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate> + +@property (readwrite, assign) VLCLibraryModel *libraryModel; +@property (readwrite, assign) VLCLibraryGroupDataSource *groupDataSource; +@property (readwrite, assign) NSTableView *categorySelectionTableView; +@property (readwrite, assign) NSTableView *collectionSelectionTableView; +@property (readwrite, assign) NSTableView *groupSelectionTableView; + +@end + +@interface VLCLibraryGroupDataSource : NSObject <NSTableViewDataSource, NSTableViewDelegate> + +@property (readwrite, retain, nullable) NSArray <VLCMediaLibraryAlbum *> *representedListOfAlbums; + +@end + +NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryAudioDataSource.m b/modules/gui/macosx/library/VLCLibraryAudioDataSource.m new file mode 100644 index 000000000000..c251447c670a --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryAudioDataSource.m @@ -0,0 +1,298 @@ +/***************************************************************************** + * VLCLibraryAudioDataSource.m: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import "VLCLibraryAudioDataSource.h" + +#import "library/VLCLibraryModel.h" +#import "library/VLCLibraryDataTypes.h" +#import "library/VLCLibraryTableCellView.h" +#import "library/VLCLibraryAlbumTableCellView.h" + +#import "extensions/NSString+Helpers.h" +#import "views/VLCImageView.h" + +static NSString *VLCAudioLibraryCellIdentifier = @"VLCAudioLibraryCellIdentifier"; + +@interface VLCLibraryAudioDataSource() +{ + NSArray *_availableCollectionsArray; +} +@end + +@implementation VLCLibraryAudioDataSource + +- (instancetype)init +{ + self = [super init]; + if (self) { + _availableCollectionsArray = @[_NS("Artists"), _NS("Albums"), _NS("Songs"), _NS("Genres")]; + } + return self; +} + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + if (tableView == self.categorySelectionTableView) { + return _availableCollectionsArray.count; + } + + NSInteger ret = 0; + + switch (self.categorySelectionTableView.selectedRow) { + case 0: // artists + ret = _libraryModel.numberOfArtists; + break; + + case 1: // albums + ret = _libraryModel.numberOfAlbums; + break; + + case 2: // songs + ret = _libraryModel.numberOfAudioMedia; + break; + + case 3: // genres + ret = _libraryModel.numberOfGenres; + break; + + default: + break; + } + + return ret; +} + +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + VLCLibraryTableCellView *cellView = [tableView makeViewWithIdentifier:VLCAudioLibraryCellIdentifier owner:self]; + + if (cellView == nil) { + /* the following code saves us an instance of NSViewController which we don't need */ + NSNib *nib = [[NSNib alloc] initWithNibNamed:@"VLCLibraryTableCellView" bundle:nil]; + NSArray *topLevelObjects; + if (![nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) { + NSAssert(1, @"Failed to load nib file to show audio library items"); + return nil; + } + + for (id topLevelObject in topLevelObjects) { + if ([topLevelObject isKindOfClass:[VLCLibraryTableCellView class]]) { + cellView = topLevelObject; + break; + } + } + cellView.identifier = VLCAudioLibraryCellIdentifier; + } + + if (tableView == self.categorySelectionTableView) { + cellView.singlePrimaryTitleTextField.hidden = NO; + cellView.singlePrimaryTitleTextField.stringValue = _availableCollectionsArray[row]; + NSImage *image = [NSImage imageNamed:NSImageNameApplicationIcon]; + cellView.representedImageView.image = image; + return cellView; + } + + switch (self.categorySelectionTableView.selectedRow) { + case 0: // artists + { + NSArray *listOfArtists = [_libraryModel listOfArtists]; + VLCMediaLibraryArtist *artist = listOfArtists[row]; + + cellView.singlePrimaryTitleTextField.hidden = NO; + cellView.singlePrimaryTitleTextField.stringValue = artist.name; + + NSImage *image; + if (artist.artworkMRL.length > 0) { + image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:artist.artworkMRL]]; + } + if (!image) { + image = [NSImage imageNamed: @"noart.png"]; + } + cellView.representedImageView.image = image; + break; + } + case 1: // albums + { + NSArray *listOfAlbums = [_libraryModel listOfAlbums]; + VLCMediaLibraryAlbum *album = listOfAlbums[row]; + + cellView.primaryTitleTextField.hidden = NO; + cellView.secondaryTitleTextField.hidden = NO; + cellView.primaryTitleTextField.stringValue = album.title; + cellView.secondaryTitleTextField.stringValue = album.artistName; + + NSImage *image; + if (album.artworkMRL.length > 0) { + image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:album.artworkMRL]]; + } + if (!image) { + image = [NSImage imageNamed: @"noart.png"]; + } + cellView.representedImageView.image = image; + break; + } + case 2: // songs + { + NSArray *listOfAudioMedia = [_libraryModel listOfAudioMedia]; + VLCMediaLibraryMediaItem *mediaItem = listOfAudioMedia[row]; + + NSImage *image; + if (mediaItem.artworkGenerated) { + if (mediaItem.artworkMRL.length > 0) { + image = [[NSImage alloc] initWithContentsOfURL:[NSURL URLWithString:mediaItem.artworkMRL]]; + } + } + if (!image) { + image = [NSImage imageNamed: @"noart.png"]; + } + cellView.representedImageView.image = image; + cellView.representedMediaItem = mediaItem; + + NSString *title = mediaItem.title; + NSString *nameOfArtist; + + VLCMediaLibraryAlbumTrack *albumTrack = mediaItem.albumTrack; + if (albumTrack) { + VLCMediaLibraryArtist *artist = [VLCMediaLibraryArtist artistWithID:albumTrack.artistID]; + if (artist) { + nameOfArtist = artist.name; + } + } + + if (title && nameOfArtist) { + cellView.primaryTitleTextField.hidden = NO; + cellView.secondaryTitleTextField.hidden = NO; + cellView.primaryTitleTextField.stringValue = title; + cellView.secondaryTitleTextField.stringValue = nameOfArtist; + } else { + cellView.singlePrimaryTitleTextField.hidden = NO; + cellView.singlePrimaryTitleTextField.stringValue = title; + } + break; + } + case 3: // genres + { + NSArray *listOfGenres = [_libraryModel listOfGenres]; + VLCMediaLibraryGenre *genre = listOfGenres[row]; + + cellView.primaryTitleTextField.hidden = NO; + cellView.secondaryTitleTextField.hidden = NO; + cellView.primaryTitleTextField.stringValue = genre.name; + cellView.secondaryTitleTextField.stringValue = [NSString stringWithFormat:_NS("%lli items"), genre.numberOfTracks]; + + NSImage *image = [NSImage imageNamed: @"noart.png"]; + cellView.representedImageView.image = image; + break; + } + default: + break; + } + + return cellView; +} + +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + if (notification.object == self.categorySelectionTableView) { + [self.collectionSelectionTableView reloadData]; + return; + } + + switch (self.categorySelectionTableView.selectedRow) { + case 0: // artists + { + NSArray *listOfArtists = [_libraryModel listOfArtists]; + VLCMediaLibraryArtist *artist = listOfArtists[self.collectionSelectionTableView.selectedRow]; + NSArray *albumsForArtist = [_libraryModel listAlbumsOfParentType:VLC_ML_PARENT_ARTIST forID:artist.artistID]; + _groupDataSource.representedListOfAlbums = albumsForArtist; + break; + } + case 1: // albums + { + NSArray *listOfAlbums = [_libraryModel listOfAlbums]; + VLCMediaLibraryAlbum *album = listOfAlbums[self.collectionSelectionTableView.selectedRow]; + _groupDataSource.representedListOfAlbums = @[album]; + break; + } + case 2: // songs + { + // FIXME: we have nothing to show here + _groupDataSource.representedListOfAlbums = nil; + break; + } + case 3: // genres + { + NSArray *listOfGenres = [_libraryModel listOfGenres]; + VLCMediaLibraryGenre *genre = listOfGenres[self.collectionSelectionTableView.selectedRow]; + NSArray *albumsForGenre = [_libraryModel listAlbumsOfParentType:VLC_ML_PARENT_GENRE forID:genre.genreID]; + _groupDataSource.representedListOfAlbums = albumsForGenre; + break; + } + default: + break; + } + + [self.groupSelectionTableView reloadData]; +} + +@end + +@implementation VLCLibraryGroupDataSource + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + if (_representedListOfAlbums != nil) { + return _representedListOfAlbums.count; + } + + return 0; +} + +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + VLCLibraryAlbumTableCellView *cellView = [tableView makeViewWithIdentifier:VLCAudioLibraryCellIdentifier owner:self]; + + if (cellView == nil) { + /* the following code saves us an instance of NSViewController which we don't need */ + NSNib *nib = [[NSNib alloc] initWithNibNamed:@"VLCLibraryAlbumTableCellView" bundle:nil]; + NSArray *topLevelObjects; + if (![nib instantiateWithOwner:self topLevelObjects:&topLevelObjects]) { + NSAssert(1, @"Failed to load nib file to show audio library items"); + return nil; + } + + for (id topLevelObject in topLevelObjects) { + if ([topLevelObject isKindOfClass:[VLCLibraryAlbumTableCellView class]]) { + cellView = topLevelObject; + break; + } + } + cellView.identifier = VLCAudioLibraryCellIdentifier; + } + + VLCMediaLibraryAlbum *album = _representedListOfAlbums[row]; + cellView.representedAlbum = album; + + return cellView; +} + +@end diff --git a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h index d482b64fa1ca..71abe643d522 100644 --- a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h +++ b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.h @@ -48,10 +48,4 @@ extern NSString *VLCLibraryCellIdentifier; @end -@interface VLCLibraryCollectionViewTrackingView : NSView - -@property (readwrite, assign) NSButton *buttonToHide; - -@end - NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.m b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.m index 58cf601b9602..ce07f70edd69 100644 --- a/modules/gui/macosx/library/VLCLibraryCollectionViewItem.m +++ b/modules/gui/macosx/library/VLCLibraryCollectionViewItem.m @@ -29,6 +29,7 @@ #import "library/VLCLibraryMenuController.h" #import "views/VLCImageView.h" #import "views/VLCLinearProgressIndicator.h" +#import "views/VLCTrackingView.h" #import "extensions/NSString+Helpers.h" #import "extensions/NSFont+VLCAdditions.h" #import "extensions/NSColor+VLCAdditions.h" @@ -65,7 +66,7 @@ NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier"; - (void)awakeFromNib { self.playInstantlyButton.hidden = YES; - [(VLCLibraryCollectionViewTrackingView *)self.view setButtonToHide:self.playInstantlyButton]; + [(VLCTrackingView *)self.view setViewToHide:self.playInstantlyButton]; self.mediaTitleTextField.font = [NSFont VLClibraryCellTitleFont]; self.durationTextField.font = [NSFont VLClibraryCellSubtitleFont]; self.durationTextField.textColor = [NSColor VLClibrarySubtitleColor]; @@ -216,38 +217,3 @@ NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier"; } @end - -@interface VLCLibraryCollectionViewTrackingView () -{ - NSTrackingArea *_trackingArea; -} -@end - -@implementation VLCLibraryCollectionViewTrackingView - -- (void)mouseExited:(NSEvent *)event -{ - self.buttonToHide.hidden = YES; -} - -- (void)mouseEntered:(NSEvent *)event -{ - self.buttonToHide.hidden = NO; -} - -- (void)updateTrackingAreas -{ - [super updateTrackingAreas]; - if(_trackingArea != nil) { - [self removeTrackingArea:_trackingArea]; - } - - NSTrackingAreaOptions trackingAreaOptions = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways); - _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] - options:trackingAreaOptions - owner:self - userInfo:nil]; - [self addTrackingArea:_trackingArea]; -} - -@end diff --git a/modules/gui/macosx/library/VLCLibraryDataTypes.h b/modules/gui/macosx/library/VLCLibraryDataTypes.h index eb7bdba8a803..ebf691f8aff7 100644 --- a/modules/gui/macosx/library/VLCLibraryDataTypes.h +++ b/modules/gui/macosx/library/VLCLibraryDataTypes.h @@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN +@class VLCMediaLibraryMediaItem; + @interface VLCMediaLibraryFile : NSObject - (instancetype)initWithFile:(struct vlc_ml_file_t *)p_file; @@ -81,6 +83,7 @@ NS_ASSUME_NONNULL_BEGIN @interface VLCMediaLibraryArtist : NSObject ++ (nullable instancetype)artistWithID:(int64_t)artistID; - (instancetype)initWithArtist:(struct vlc_ml_artist_t *)p_artist; @property (readonly) int64_t artistID; @@ -106,6 +109,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) size_t numberOfTracks; @property (readonly) unsigned int duration; @property (readonly) unsigned int year; +@property (readonly) NSArray <VLCMediaLibraryMediaItem *> *tracksAsMediaItems; @end diff --git a/modules/gui/macosx/library/VLCLibraryDataTypes.m b/modules/gui/macosx/library/VLCLibraryDataTypes.m index e3211672a60b..3cd63dd0aa99 100644 --- a/modules/gui/macosx/library/VLCLibraryDataTypes.m +++ b/modules/gui/macosx/library/VLCLibraryDataTypes.m @@ -113,6 +113,17 @@ @implementation VLCMediaLibraryArtist ++ (instancetype)artistWithID:(int64_t)artistID +{ + vlc_medialibrary_t *p_mediaLibrary = vlc_ml_instance_get(getIntf()); + vlc_ml_artist_t *p_artist = vlc_ml_get_artist(p_mediaLibrary, artistID); + VLCMediaLibraryArtist *artist = nil; + if (p_artist) { + artist = [[VLCMediaLibraryArtist alloc] initWithArtist:p_artist]; + } + return artist; +} + - (instancetype)initWithArtist:(struct vlc_ml_artist_t *)p_artist; { self = [super init]; @@ -149,6 +160,19 @@ return self; } +- (NSArray<VLCMediaLibraryMediaItem *> *)tracksAsMediaItems +{ + vlc_medialibrary_t *p_mediaLibrary = vlc_ml_instance_get(getIntf()); + vlc_ml_media_list_t *p_mediaList = vlc_ml_list_album_tracks(p_mediaLibrary, NULL, _albumID); + NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:p_mediaList->i_nb_items]; + for (size_t x = 0; x < p_mediaList->i_nb_items; x++) { + VLCMediaLibraryMediaItem *mediaItem = [[VLCMediaLibraryMediaItem alloc] initWithMediaItem:&p_mediaList->p_items[x]]; + [mutableArray addObject:mediaItem]; + } + vlc_ml_media_list_release(p_mediaList); + return [mutableArray copy]; +} + @end @implementation VLCMediaLibraryAlbumTrack diff --git a/modules/gui/macosx/library/VLCLibraryModel.h b/modules/gui/macosx/library/VLCLibraryModel.h index 23369c9de797..1f2f3b6d7201 100644 --- a/modules/gui/macosx/library/VLCLibraryModel.h +++ b/modules/gui/macosx/library/VLCLibraryModel.h @@ -32,9 +32,14 @@ typedef NS_ENUM(NSInteger, VLCLibraryMode) { }; @class VLCMediaLibraryMediaItem; +@class VLCMediaLibraryArtist; +@class VLCMediaLibraryAlbum; +@class VLCMediaLibraryGenre; @class VLCMediaLibraryEntryPoint; extern NSString *VLCLibraryModelAudioMediaListUpdated; +extern NSString *VLCLibraryModelArtistListUpdated; +extern NSString *VLCLibraryModelAlbumListUpdated; extern NSString *VLCLibraryModelVideoMediaListUpdated; extern NSString *VLCLibraryModelRecentMediaListUpdated; extern NSString *VLCLibraryModelMediaItemUpdated; @@ -48,6 +53,15 @@ extern NSString *VLCLibraryModelMediaItemUpdated; @property (readonly) size_t numberOfAudioMedia; @property (readonly) NSArray <VLCMediaLibraryMediaItem *> *listOfAudioMedia; +@property (readonly) size_t numberOfArtists; +@property (readonly) NSArray <VLCMediaLibraryArtist *> *listOfArtists; + +@property (readonly) size_t numberOfAlbums; +@property (readonly) NSArray <VLCMediaLibraryAlbum *> *listOfAlbums; + +@property (readonly) size_t numberOfGenres; +@property (readonly) NSArray <VLCMediaLibraryGenre *> *listOfGenres; + @property (readonly) size_t numberOfVideoMedia; @property (readonly) NSArray <VLCMediaLibraryMediaItem *> *listOfVideoMedia; @@ -56,6 +70,8 @@ extern NSString *VLCLibraryModelMediaItemUpdated; @property (readonly) NSArray <VLCMediaLibraryEntryPoint *> *listOfMonitoredFolders; +- (nullable NSArray <VLCMediaLibraryAlbum *>*)listAlbumsOfParentType:(enum vlc_ml_parent_type)parentType forID:(int64_t)ID; + @end NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryModel.m b/modules/gui/macosx/library/VLCLibraryModel.m index dcb74503b879..bbd79b5c341d 100644 --- a/modules/gui/macosx/library/VLCLibraryModel.m +++ b/modules/gui/macosx/library/VLCLibraryModel.m @@ -26,6 +26,8 @@ #import "library/VLCLibraryDataTypes.h" NSString *VLCLibraryModelAudioMediaListUpdated = @"VLCLibraryModelAudioMediaListUpdated"; +NSString *VLCLibraryModelArtistListUpdated = @"VLCLibraryModelArtistListUpdated"; +NSString *VLCLibraryModelAlbumListUpdated = @"VLCLibraryModelAlbumListUpdated"; NSString *VLCLibraryModelVideoMediaListUpdated = @"VLCLibraryModelVideoMediaListUpdated"; NSString *VLCLibraryModelRecentMediaListUpdated = @"VLCLibraryModelRecentMediaListUpdated"; NSString *VLCLibraryModelMediaItemUpdated = @"VLCLibraryModelMediaItemUpdated"; @@ -36,6 +38,9 @@ NSString *VLCLibraryModelMediaItemUpdated = @"VLCLibraryModelMediaItemUpdated"; vlc_ml_event_callback_t *_p_eventCallback; NSArray *_cachedAudioMedia; + NSArray *_cachedArtists; + NSArray *_cachedAlbums; + NSArray *_cachedGenres; NSArray *_cachedVideoMedia; NSArray *_cachedRecentMedia; NSNotificationCenter *_defaultNotificationCenter; @@ -126,11 +131,8 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) - (size_t)numberOfAudioMedia { if (!_cachedAudioMedia) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateCachedListOfAudioMedia]; - }); + [self updateCachedListOfAudioMedia]; } - return _cachedAudioMedia.count; } @@ -150,14 +152,98 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) - (NSArray<VLCMediaLibraryMediaItem *> *)listOfAudioMedia { if (!_cachedAudioMedia) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateCachedListOfAudioMedia]; - }); + [self updateCachedListOfAudioMedia]; } - return _cachedAudioMedia; } +- (size_t)numberOfArtists +{ + if (!_cachedArtists) { + [self updateCachedListOfArtists]; + } + return _cachedArtists.count; +} + +- (void)updateCachedListOfArtists +{ + vlc_ml_artist_list_t *p_artist_list = vlc_ml_list_artists(_p_mediaLibrary, NULL, 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]]; + [mutableArray addObject:artist]; + } + _cachedArtists = [mutableArray copy]; + vlc_ml_artist_list_release(p_artist_list); + [_defaultNotificationCenter postNotificationName:VLCLibraryModelArtistListUpdated object:self]; +} + +- (NSArray<VLCMediaLibraryArtist *> *)listOfArtists +{ + if (!_cachedArtists) { + [self updateCachedListOfArtists]; + } + return _cachedArtists; +} + +- (size_t)numberOfAlbums +{ + if (!_cachedAlbums) { + [self updateCachedListOfAlbums]; + } + return _cachedAlbums.count; +} + +- (void)updateCachedListOfAlbums +{ + vlc_ml_album_list_t *p_album_list = vlc_ml_list_albums(_p_mediaLibrary, NULL); + 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]; + } + _cachedAlbums = [mutableArray copy]; + vlc_ml_album_list_release(p_album_list); + [_defaultNotificationCenter postNotificationName:VLCLibraryModelArtistListUpdated object:self]; +} + +- (NSArray<VLCMediaLibraryAlbum *> *)listOfAlbums +{ + if (!_cachedAlbums) { + [self updateCachedListOfAlbums]; + } + return _cachedAlbums; +} + +- (size_t)numberOfGenres +{ + if (!_cachedGenres) { + [self updateCachedListOfGenres]; + } + return _cachedGenres.count; +} + +- (void)updateCachedListOfGenres +{ + vlc_ml_genre_list_t *p_genre_list = vlc_ml_list_genres(_p_mediaLibrary, NULL); + 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]; + } + _cachedGenres = [mutableArray copy]; + vlc_ml_genre_list_release(p_genre_list); + [_defaultNotificationCenter postNotificationName:VLCLibraryModelArtistListUpdated object:self]; +} + +- (NSArray<VLCMediaLibraryMediaItem *> *)listOfGenres +{ + if (!_cachedGenres) { + [self updateCachedListOfGenres]; + } + return _cachedGenres; +} + - (size_t)numberOfVideoMedia { if (!_cachedVideoMedia) { @@ -165,7 +251,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) [self updateCachedListOfVideoMedia]; }); } - return _cachedVideoMedia.count; } @@ -192,7 +277,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) [self updateCachedListOfVideoMedia]; }); } - return _cachedVideoMedia; } @@ -222,7 +306,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) [self updateCachedListOfRecentMedia]; }); } - return _cachedRecentMedia.count; } @@ -233,7 +316,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) [self updateCachedListOfRecentMedia]; }); } - return _cachedRecentMedia; } @@ -258,4 +340,19 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event) return [mutableArray copy]; } +- (nullable NSArray <VLCMediaLibraryAlbum *>*)listAlbumsOfParentType:(enum vlc_ml_parent_type)parentType forID:(int64_t)ID; +{ + vlc_ml_album_list_t *p_albumList = vlc_ml_list_albums_of(_p_mediaLibrary, NULL, parentType, ID); + if (p_albumList == NULL) { + return nil; + } + NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:p_albumList->i_nb_items]; + for (size_t x = 0; x < p_albumList->i_nb_items; x++) { + VLCMediaLibraryAlbum *album = [[VLCMediaLibraryAlbum alloc] initWithAlbum:&p_albumList->p_items[x]]; + [mutableArray addObject:album]; + } + vlc_ml_album_list_release(p_albumList); + return [mutableArray copy]; +} + @end diff --git a/modules/gui/macosx/library/VLCLibraryTableCellView.h b/modules/gui/macosx/library/VLCLibraryTableCellView.h new file mode 100644 index 000000000000..0cae354a8e54 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryTableCellView.h @@ -0,0 +1,45 @@ +/***************************************************************************** + * VLCLibraryTableCellView.h: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import <Cocoa/Cocoa.h> + +NS_ASSUME_NONNULL_BEGIN + +@class VLCImageView; +@class VLCTrackingView; +@class VLCMediaLibraryMediaItem; + +@interface VLCLibraryTableCellView : NSTableCellView + +@property (readwrite, assign) IBOutlet VLCTrackingView *trackingView; +@property (readwrite, assign) IBOutlet NSTextField *singlePrimaryTitleTextField; +@property (readwrite, assign) IBOutlet NSTextField *secondaryTitleTextField; +@property (readwrite, assign) IBOutlet NSTextField *primaryTitleTextField; +@property (readwrite, assign) IBOutlet VLCImageView *representedImageView; +@property (readwrite, assign) IBOutlet NSButton *playInstantlyButton; +@property (readwrite, assign, nonatomic) VLCMediaLibraryMediaItem *representedMediaItem; + +- (IBAction)playInstantly:(id)sender; + +@end + +NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/library/VLCLibraryTableCellView.m b/modules/gui/macosx/library/VLCLibraryTableCellView.m new file mode 100644 index 000000000000..26640ce72c66 --- /dev/null +++ b/modules/gui/macosx/library/VLCLibraryTableCellView.m @@ -0,0 +1,72 @@ +/***************************************************************************** + * VLCLibraryTableCellView.m: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import "VLCLibraryTableCellView.h" +#import "extensions/NSFont+VLCAdditions.h" +#import "views/VLCImageView.h" +#import "views/VLCTrackingView.h" +#import "main/VLCMain.h" +#import "library/VLCLibraryController.h" +#import "library/VLCLibraryDataTypes.h" + +@interface VLCLibraryTableCellView () +{ + VLCLibraryController *_libraryController; +} +@end + +@implementation VLCLibraryTableCellView + +- (void)awakeFromNib +{ + self.singlePrimaryTitleTextField.font = [NSFont VLClibraryCellTitleFont]; + self.primaryTitleTextField.font = [NSFont VLClibraryCellTitleFont]; + self.secondaryTitleTextField.font = [NSFont VLClibraryCellSubtitleFont]; + [self prepareForReuse]; +} + +- (void)prepareForReuse +{ + self.representedImageView.image = nil; + self.primaryTitleTextField.hidden = YES; + self.secondaryTitleTextField.hidden = YES; + self.singlePrimaryTitleTextField.hidden = YES; + self.trackingView.viewToHide = nil; + self.playInstantlyButton.hidden = YES; +} + +- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem +{ + _representedMediaItem = representedMediaItem; + self.trackingView.viewToHide = self.playInstantlyButton; +} + +- (IBAction)playInstantly:(id)sender +{ + if (!_libraryController) { + _libraryController = [[VLCMain sharedInstance] libraryController]; + } + + [_libraryController appendItemToPlaylist:_representedMediaItem playImmediately:YES]; +} + +@end diff --git a/modules/gui/macosx/library/VLCLibraryWindow.h b/modules/gui/macosx/library/VLCLibraryWindow.h index 480e84e18208..fa062a35a753 100644 --- a/modules/gui/macosx/library/VLCLibraryWindow.h +++ b/modules/gui/macosx/library/VLCLibraryWindow.h @@ -38,6 +38,10 @@ NS_ASSUME_NONNULL_BEGIN @property (readwrite, weak) IBOutlet NSCollectionView *videoLibraryCollectionView; @property (readwrite, weak) IBOutlet NSCollectionView *recentVideoLibraryCollectionView; @property (readwrite, weak) IBOutlet NSCollectionView *mediaSourceCollectionView; +@property (readwrite, weak) IBOutlet NSSplitView *audioLibrarySplitView; +@property (readwrite, weak) IBOutlet NSTableView *audioCategorySelectionTableView; +@property (readwrite, weak) IBOutlet NSTableView *audioCollectionSelectionTableView; +@property (readwrite, weak) IBOutlet NSTableView *audioGroupSelectionTableView; @property (readwrite, weak) IBOutlet NSScrollView *mediaSourceScrollView; @property (readwrite, weak) IBOutlet NSView *libraryTargetView; @property (readwrite, weak) IBOutlet NSTableView *playlistTableView; diff --git a/modules/gui/macosx/library/VLCLibraryWindow.m b/modules/gui/macosx/library/VLCLibraryWindow.m index 334715438b3c..e9c19060604a 100644 --- a/modules/gui/macosx/library/VLCLibraryWindow.m +++ b/modules/gui/macosx/library/VLCLibraryWindow.m @@ -27,11 +27,11 @@ #import "extensions/NSView+VLCAdditions.h" #import "main/VLCMain.h" -#import "playlist/VLCPlaylistTableCellView.h" #import "playlist/VLCPlaylistController.h" #import "playlist/VLCPlaylistDataSource.h" #import "library/VLCLibraryController.h" +#import "library/VLCLibraryAudioDataSource.h" #import "library/VLCLibraryVideoDataSource.h" #import "library/VLCLibraryCollectionViewItem.h" #import "library/VLCLibraryModel.h" @@ -48,11 +48,15 @@ static const float f_min_window_width = 604.; static const float f_min_window_height = 307.; static const float f_playlist_row_height = 72.; +static const float f_library_small_row_height = 24.; +static const float f_library_large_row_height = 50.; @interface VLCLibraryWindow () { VLCPlaylistDataSource *_playlistDataSource; VLCLibraryVideoDataSource *_libraryVideoDataSource; + VLCLibraryAudioDataSource *_libraryAudioDataSource; + VLCLibraryGroupDataSource *_libraryAudioGroupDataSource; VLCMediaSourceDataSource *_mediaSourceDataSource; VLCPlaylistController *_playlistController; @@ -150,6 +154,23 @@ static const float f_playlist_row_height = 72.; _recentVideoLibraryCollectionView.delegate = _libraryVideoDataSource; [_recentVideoLibraryCollectionView registerClass:[VLCLibraryCollectionViewItem class] forItemWithIdentifier:VLCLibraryCellIdentifier]; + _libraryAudioDataSource = [[VLCLibraryAudioDataSource alloc] init]; + _libraryAudioDataSource.libraryModel = mainInstance.libraryController.libraryModel; + _libraryAudioDataSource.categorySelectionTableView = _audioCategorySelectionTableView; + _libraryAudioDataSource.collectionSelectionTableView = _audioCollectionSelectionTableView; + _libraryAudioDataSource.groupSelectionTableView = _audioGroupSelectionTableView; + _audioCategorySelectionTableView.dataSource = _libraryAudioDataSource; + _audioCategorySelectionTableView.delegate = _libraryAudioDataSource; + _audioCategorySelectionTableView.rowHeight = f_library_small_row_height; + _audioCollectionSelectionTableView.dataSource = _libraryAudioDataSource; + _audioCollectionSelectionTableView.delegate = _libraryAudioDataSource; + _audioCollectionSelectionTableView.rowHeight = f_library_large_row_height; + _libraryAudioGroupDataSource = [[VLCLibraryGroupDataSource alloc] init]; + _libraryAudioDataSource.groupDataSource = _libraryAudioGroupDataSource; + _audioGroupSelectionTableView.dataSource = _libraryAudioGroupDataSource; + _audioGroupSelectionTableView.delegate = _libraryAudioGroupDataSource; + _audioGroupSelectionTableView.rowHeight = 450.; + _mediaSourceDataSource = [[VLCMediaSourceDataSource alloc] init]; _mediaSourceDataSource.collectionView = _mediaSourceCollectionView; _mediaSourceCollectionView.dataSource = _mediaSourceDataSource; @@ -262,6 +283,9 @@ static const float f_playlist_row_height = 72.; if (_mediaSourceScrollView.superview != nil) { [_mediaSourceScrollView removeFromSuperview]; } + if (_audioLibrarySplitView.superview != nil) { + [_audioLibrarySplitView removeFromSuperview]; + } if (_videoLibraryStackView.superview == nil) { _videoLibraryStackView.translatesAutoresizingMaskIntoConstraints = NO; [_libraryTargetView addSubview:_videoLibraryStackView]; @@ -278,21 +302,27 @@ static const float f_playlist_row_height = 72.; if (_mediaSourceScrollView.superview != nil) { [_mediaSourceScrollView removeFromSuperview]; } - if (_videoLibraryStackView.superview == nil) { - _videoLibraryStackView.translatesAutoresizingMaskIntoConstraints = NO; - [_libraryTargetView addSubview:_videoLibraryStackView]; - NSDictionary *dict = NSDictionaryOfVariableBindings(_videoLibraryStackView); - [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_videoLibraryStackView(>=572.)]|" options:0 metrics:0 views:dict]]; - [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_videoLibraryStackView(>=444.)]|" options:0 metrics:0 views:dict]]; + if (_videoLibraryStackView.superview != nil) { + [_videoLibraryStackView removeFromSuperview]; } - [_videoLibraryCollectionView reloadData]; - [_recentVideoLibraryCollectionView reloadData]; + if (_audioLibrarySplitView.superview == nil) { + _audioLibrarySplitView.translatesAutoresizingMaskIntoConstraints = NO; + [_libraryTargetView addSubview:_audioLibrarySplitView]; + NSDictionary *dict = NSDictionaryOfVariableBindings(_audioLibrarySplitView); + [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_audioLibrarySplitView(>=572.)]|" options:0 metrics:0 views:dict]]; + [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_audioLibrarySplitView(>=444.)]|" options:0 metrics:0 views:dict]]; + } + [_audioCategorySelectionTableView reloadData]; + [_audioCollectionSelectionTableView reloadData]; break; default: if (_videoLibraryStackView.superview != nil) { [_videoLibraryStackView removeFromSuperview]; } + if (_audioLibrarySplitView.superview != nil) { + [_audioLibrarySplitView removeFromSuperview]; + } if (_mediaSourceScrollView.superview == nil) { _mediaSourceScrollView.translatesAutoresizingMaskIntoConstraints = NO; [_libraryTargetView addSubview:_mediaSourceScrollView]; diff --git a/modules/gui/macosx/views/VLCTrackingView.h b/modules/gui/macosx/views/VLCTrackingView.h new file mode 100644 index 000000000000..2c4a6976ed03 --- /dev/null +++ b/modules/gui/macosx/views/VLCTrackingView.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * VLCTrackingView.h: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import <Cocoa/Cocoa.h> + +NS_ASSUME_NONNULL_BEGIN + +@interface VLCTrackingView : NSView + +@property (readwrite, assign, nullable) NSView *viewToHide; + +@end + +NS_ASSUME_NONNULL_END diff --git a/modules/gui/macosx/views/VLCTrackingView.m b/modules/gui/macosx/views/VLCTrackingView.m new file mode 100644 index 000000000000..01fb4cf7f1d3 --- /dev/null +++ b/modules/gui/macosx/views/VLCTrackingView.m @@ -0,0 +1,58 @@ +/***************************************************************************** + * VLCTrackingView.m: MacOS X interface module + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#import "VLCTrackingView.h" + +@interface VLCTrackingView () +{ + NSTrackingArea *_trackingArea; +} +@end + +@implementation VLCTrackingView + +- (void)mouseExited:(NSEvent *)event +{ + self.viewToHide.hidden = YES; +} + +- (void)mouseEntered:(NSEvent *)event +{ + self.viewToHide.hidden = NO; +} + +- (void)updateTrackingAreas +{ + [super updateTrackingAreas]; + if(_trackingArea != nil) { + [self removeTrackingArea:_trackingArea]; + } + + NSTrackingAreaOptions trackingAreaOptions = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways); + _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] + options:trackingAreaOptions + owner:self + userInfo:nil]; + [self addTrackingArea:_trackingArea]; +} + +@end diff --git a/po/POTFILES.in b/po/POTFILES.in index d054692ce9db..e7a9f0e948c1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -460,14 +460,16 @@ modules/gui/macosx/extensions/misc.h modules/gui/macosx/extensions/misc.m modules/gui/macosx/library/VLCInputItem.h modules/gui/macosx/library/VLCInputItem.m +modules/gui/macosx/library/VLCLibraryAlbumTableCellView.h +modules/gui/macosx/library/VLCLibraryAlbumTableCellView.m +modules/gui/macosx/library/VLCLibraryAudioDataSource.h +modules/gui/macosx/library/VLCLibraryAudioDataSource.m modules/gui/macosx/library/VLCLibraryCollectionViewItem.h modules/gui/macosx/library/VLCLibraryCollectionViewItem.m modules/gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.h modules/gui/macosx/library/VLCLibraryCollectionViewSupplementaryElementView.m modules/gui/macosx/library/VLCLibraryController.h modules/gui/macosx/library/VLCLibraryController.m -modules/gui/macosx/library/VLCLibraryVideoDataSource.h -modules/gui/macosx/library/VLCLibraryVideoDataSource.m modules/gui/macosx/library/VLCLibraryDataTypes.h modules/gui/macosx/library/VLCLibraryDataTypes.m modules/gui/macosx/library/VLCLibraryFolderManagementWindow.h @@ -476,6 +478,10 @@ modules/gui/macosx/library/VLCLibraryMenuController.h modules/gui/macosx/library/VLCLibraryMenuController.m modules/gui/macosx/library/VLCLibraryModel.h modules/gui/macosx/library/VLCLibraryModel.m +modules/gui/macosx/library/VLCLibraryTableCellView.h +modules/gui/macosx/library/VLCLibraryTableCellView.m +modules/gui/macosx/library/VLCLibraryVideoDataSource.h +modules/gui/macosx/library/VLCLibraryVideoDataSource.m modules/gui/macosx/library/VLCLibraryWindow.h modules/gui/macosx/library/VLCLibraryWindow.m modules/gui/macosx/main/CompatibilityFixes.h @@ -591,6 +597,8 @@ modules/gui/macosx/views/VLCSliderCell.h modules/gui/macosx/views/VLCSliderCell.m modules/gui/macosx/views/VLCTimeField.h modules/gui/macosx/views/VLCTimeField.m +modules/gui/macosx/views/VLCTrackingView.h +modules/gui/macosx/views/VLCTrackingView.m modules/gui/macosx/views/VLCVolumeSlider.h modules/gui/macosx/views/VLCVolumeSlider.m modules/gui/macosx/views/VLCVolumeSliderCell.h -- GitLab