[vlc-commits] macosx/media-source: add table view representation
Felix Paul Kühne
git at videolan.org
Mon Jul 1 10:48:05 CEST 2019
vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Sun Jun 30 22:51:16 2019 +0200| [02e65ff064f77d04c35b4cd696b4bf877fe0d3fa] | committer: Felix Paul Kühne
macosx/media-source: add table view representation
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=02e65ff064f77d04c35b4cd696b4bf877fe0d3fa
---
modules/gui/macosx/UI/VLCLibraryTableCellView.xib | 3 -
modules/gui/macosx/UI/VLCLibraryWindow.xib | 74 ++++++++-
.../gui/macosx/library/VLCLibraryTableCellView.h | 6 +-
.../gui/macosx/library/VLCLibraryTableCellView.m | 53 ++++--
modules/gui/macosx/library/VLCLibraryWindow.h | 3 +
modules/gui/macosx/library/VLCLibraryWindow.m | 4 +
.../media-source/VLCMediaSourceBaseDataSource.h | 3 +
.../media-source/VLCMediaSourceBaseDataSource.m | 182 +++++++++++++++++++--
.../macosx/media-source/VLCMediaSourceDataSource.h | 6 +-
.../macosx/media-source/VLCMediaSourceDataSource.m | 103 +++++++++++-
10 files changed, 399 insertions(+), 38 deletions(-)
diff --git a/modules/gui/macosx/UI/VLCLibraryTableCellView.xib b/modules/gui/macosx/UI/VLCLibraryTableCellView.xib
index 4e5a0199f8..542c6976fc 100644
--- a/modules/gui/macosx/UI/VLCLibraryTableCellView.xib
+++ b/modules/gui/macosx/UI/VLCLibraryTableCellView.xib
@@ -62,9 +62,6 @@
<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>
diff --git a/modules/gui/macosx/UI/VLCLibraryWindow.xib b/modules/gui/macosx/UI/VLCLibraryWindow.xib
index 9cc979eeb5..a7be7373a2 100644
--- a/modules/gui/macosx/UI/VLCLibraryWindow.xib
+++ b/modules/gui/macosx/UI/VLCLibraryWindow.xib
@@ -520,12 +520,15 @@
<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"/>
+ <outlet property="gridVsListSegmentedControl" destination="7K7-4r-Swk" id="VoD-jF-46N"/>
<outlet property="librarySortButton" destination="Rja-6g-wNZ" id="FQ7-MU-hsk"/>
<outlet property="libraryTargetView" destination="iSp-bV-w6B" id="a94-ux-wUc"/>
<outlet property="mainSplitView" destination="u8g-jy-S4e" id="lI5-wR-kef"/>
<outlet property="mediaSourceCollectionView" destination="r7v-GI-W1U" id="3JJ-GU-o5o"/>
+ <outlet property="mediaSourceCollectionViewScrollView" destination="cFG-c9-cI9" id="QQq-Ql-uQ7"/>
<outlet property="mediaSourceHomeButton" destination="jfA-Vr-sQc" id="oLM-NF-rqe"/>
<outlet property="mediaSourcePathControl" destination="Rjk-Q6-FYy" id="G63-NM-Ekn"/>
+ <outlet property="mediaSourceTableView" destination="vpJ-Oz-Ebz" id="Hbo-Qw-JQd"/>
<outlet property="mediaSourceView" destination="eHd-Q9-F8D" id="gfU-Jp-eFr"/>
<outlet property="openMediaButton" destination="SWh-4E-Qtf" id="sIZ-xo-GLA"/>
<outlet property="playlistCounterTextField" destination="mbV-My-cm7" id="ZYU-Jq-Z8R"/>
@@ -649,7 +652,7 @@
<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"/>
+ <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"/>
@@ -709,7 +712,7 @@
<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"/>
+ <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"/>
@@ -769,7 +772,7 @@
<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"/>
+ <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"/>
@@ -840,7 +843,7 @@
<rect key="frame" x="0.0" y="0.0" width="500" height="302"/>
<clipView key="contentView" id="2oa-WL-dxA">
<rect key="frame" x="0.0" y="0.0" width="500" height="302"/>
- <autoresizingMask key="autoresizingMask"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView id="QAt-jP-zE7">
<rect key="frame" x="0.0" y="0.0" width="500" height="302"/>
@@ -874,6 +877,65 @@
<rect key="frame" x="0.0" y="0.0" width="528" height="307"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
+ <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7WD-fy-WtJ">
+ <rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
+ <clipView key="contentView" id="5co-vI-cEn">
+ <rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
+ <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="vpJ-Oz-Ebz">
+ <rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
+ <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="525" minWidth="40" maxWidth="1000" id="89Q-Wg-BdA">
+ <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="v9H-KJ-Zhv">
+ <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="prL-6m-HxA">
+ <rect key="frame" x="1" y="1" width="525" height="0.0"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TVO-GX-uf2">
+ <rect key="frame" x="0.0" y="-17" width="525" height="17"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="LYl-7r-eAr">
+ <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="TVO-GX-uf2" id="2t6-OK-CMa"/>
+ </connections>
+ </tableCellView>
+ </prototypeCellViews>
+ </tableColumn>
+ </tableColumns>
+ </tableView>
+ </subviews>
+ </clipView>
+ <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="Xu2-Uw-wBR">
+ <rect key="frame" x="0.0" y="-16" width="0.0" height="16"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="UVE-ma-wE8">
+ <rect key="frame" x="-16" y="0.0" width="16" height="0.0"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ </scrollView>
<scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cFG-c9-cI9">
<rect key="frame" x="0.0" y="0.0" width="528" height="267"/>
<clipView key="contentView" id="tI4-x3-55j">
@@ -918,10 +980,14 @@
</button>
</subviews>
<constraints>
+ <constraint firstAttribute="bottom" secondItem="7WD-fy-WtJ" secondAttribute="bottom" id="05c-7d-nw6"/>
<constraint firstItem="Rjk-Q6-FYy" firstAttribute="leading" secondItem="jfA-Vr-sQc" secondAttribute="trailing" constant="10" id="1OY-9N-uuV"/>
+ <constraint firstItem="7WD-fy-WtJ" firstAttribute="leading" secondItem="eHd-Q9-F8D" secondAttribute="leading" id="233-Yb-V4O"/>
<constraint firstAttribute="bottom" secondItem="cFG-c9-cI9" secondAttribute="bottom" id="DjO-Ru-7sa"/>
<constraint firstItem="cFG-c9-cI9" firstAttribute="top" secondItem="Rjk-Q6-FYy" secondAttribute="bottom" constant="10" id="Lji-yk-wiI"/>
+ <constraint firstAttribute="trailing" secondItem="7WD-fy-WtJ" secondAttribute="trailing" id="PnR-KD-94A"/>
<constraint firstItem="Rjk-Q6-FYy" firstAttribute="top" secondItem="eHd-Q9-F8D" secondAttribute="top" constant="10" id="Sf6-jz-ool"/>
+ <constraint firstItem="7WD-fy-WtJ" firstAttribute="top" secondItem="Rjk-Q6-FYy" secondAttribute="bottom" constant="10" id="Xao-NR-Utd"/>
<constraint firstItem="jfA-Vr-sQc" firstAttribute="centerY" secondItem="Rjk-Q6-FYy" secondAttribute="centerY" id="aFD-99-R3a"/>
<constraint firstAttribute="trailing" secondItem="Rjk-Q6-FYy" secondAttribute="trailing" constant="10" id="c3j-mQ-afF"/>
<constraint firstItem="jfA-Vr-sQc" firstAttribute="leading" secondItem="eHd-Q9-F8D" secondAttribute="leading" constant="10" id="saP-eI-VDF"/>
diff --git a/modules/gui/macosx/library/VLCLibraryTableCellView.h b/modules/gui/macosx/library/VLCLibraryTableCellView.h
index 0cae354a8e..202ed2b90a 100644
--- a/modules/gui/macosx/library/VLCLibraryTableCellView.h
+++ b/modules/gui/macosx/library/VLCLibraryTableCellView.h
@@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
@class VLCImageView;
@class VLCTrackingView;
@class VLCMediaLibraryMediaItem;
+ at class VLCInputItem;
@interface VLCLibraryTableCellView : NSTableCellView
@@ -36,9 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (readwrite, assign) IBOutlet NSTextField *primaryTitleTextField;
@property (readwrite, assign) IBOutlet VLCImageView *representedImageView;
@property (readwrite, assign) IBOutlet NSButton *playInstantlyButton;
- at property (readwrite, assign, nonatomic) VLCMediaLibraryMediaItem *representedMediaItem;
-
-- (IBAction)playInstantly:(id)sender;
+ at property (readwrite, strong, nonatomic) VLCMediaLibraryMediaItem *representedMediaItem;
+ at property (readwrite, strong, nonatomic) VLCInputItem *representedInputItem;
@end
diff --git a/modules/gui/macosx/library/VLCLibraryTableCellView.m b/modules/gui/macosx/library/VLCLibraryTableCellView.m
index b12e78dcf8..9e5d9f51e6 100644
--- a/modules/gui/macosx/library/VLCLibraryTableCellView.m
+++ b/modules/gui/macosx/library/VLCLibraryTableCellView.m
@@ -27,12 +27,8 @@
#import "main/VLCMain.h"
#import "library/VLCLibraryController.h"
#import "library/VLCLibraryDataTypes.h"
-
- at interface VLCLibraryTableCellView ()
-{
- VLCLibraryController *_libraryController;
-}
- at end
+#import "library/VLCInputItem.h"
+#import "playlist/VLCPlaylistController.h"
@implementation VLCLibraryTableCellView
@@ -58,16 +54,53 @@
- (void)setRepresentedMediaItem:(VLCMediaLibraryMediaItem *)representedMediaItem
{
_representedMediaItem = representedMediaItem;
+
+ self.trackingView.viewToHide = self.playInstantlyButton;
+ self.playInstantlyButton.action = @selector(playMediaItemInstantly:);
+ self.playInstantlyButton.target = self;
+}
+
+- (void)setRepresentedInputItem:(VLCInputItem *)representedInputItem
+{
+ _representedInputItem = representedInputItem;
+
+ self.singlePrimaryTitleTextField.hidden = NO;
+ self.singlePrimaryTitleTextField.stringValue = _representedInputItem.name;
+
+ NSURL *artworkURL = _representedInputItem.artworkURL;
+ NSImage *placeholderImage = [self imageForInputItem];
+ if (artworkURL) {
+ [self.representedImageView setImageURL:artworkURL placeholderImage:placeholderImage];
+ } else {
+ self.representedImageView.image = placeholderImage;
+ }
+
self.trackingView.viewToHide = self.playInstantlyButton;
+ self.playInstantlyButton.action = @selector(playInputItemInstantly:);
+ self.playInstantlyButton.target = self;
}
-- (IBAction)playInstantly:(id)sender
+- (NSImage *)imageForInputItem
{
- if (!_libraryController) {
- _libraryController = [[VLCMain sharedInstance] libraryController];
+ NSImage *image;
+ if (_representedInputItem.inputType == ITEM_TYPE_DIRECTORY) {
+ image = [NSImage imageNamed:NSImageNameFolder];
+ }
+
+ if (!image) {
+ image = [NSImage imageNamed: @"noart.png"];
}
+ return image;
+}
- [_libraryController appendItemToPlaylist:_representedMediaItem playImmediately:YES];
+- (void)playMediaItemInstantly:(id)sender
+{
+ [[[VLCMain sharedInstance] libraryController] appendItemToPlaylist:_representedMediaItem playImmediately:YES];
+}
+
+- (void)playInputItemInstantly:(id)sender
+{
+ [[[VLCMain sharedInstance] playlistController] addInputItem:_representedInputItem.vlcInputItem atPosition:-1 startPlayback:YES];
}
@end
diff --git a/modules/gui/macosx/library/VLCLibraryWindow.h b/modules/gui/macosx/library/VLCLibraryWindow.h
index d3b6e5c0a3..ce72c4ed64 100644
--- a/modules/gui/macosx/library/VLCLibraryWindow.h
+++ b/modules/gui/macosx/library/VLCLibraryWindow.h
@@ -36,6 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface VLCLibraryWindow : VLCVideoWindowCommon
@property (readwrite, weak) IBOutlet NSSegmentedControl *segmentedTitleControl;
+ at property (readwrite, weak) IBOutlet NSSegmentedControl *gridVsListSegmentedControl;
@property (readwrite, weak) IBOutlet NSSplitView *mainSplitView;
@property (readwrite, weak) IBOutlet NSStackView *videoLibraryStackView;
@property (readwrite, strong) IBOutlet NSView *playlistView;
@@ -49,6 +50,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (readwrite, weak) IBOutlet NSView *mediaSourceView;
@property (readwrite, weak) IBOutlet NSButton *mediaSourceHomeButton;
@property (readwrite, weak) IBOutlet NSPathControl *mediaSourcePathControl;
+ at property (readwrite, weak) IBOutlet NSTableView *mediaSourceTableView;
+ at property (readwrite, weak) IBOutlet NSScrollView *mediaSourceCollectionViewScrollView;
@property (readwrite, weak) IBOutlet NSView *libraryTargetView;
@property (readwrite, weak) IBOutlet NSTableView *playlistTableView;
@property (readwrite, weak) IBOutlet NSTextField *upNextLabel;
diff --git a/modules/gui/macosx/library/VLCLibraryWindow.m b/modules/gui/macosx/library/VLCLibraryWindow.m
index 2d769366e8..79d4b2d8ed 100644
--- a/modules/gui/macosx/library/VLCLibraryWindow.m
+++ b/modules/gui/macosx/library/VLCLibraryWindow.m
@@ -237,8 +237,12 @@ static int ShowController(vlc_object_t *p_this, const char *psz_variable,
_mediaSourceDataSource = [[VLCMediaSourceBaseDataSource alloc] init];
_mediaSourceDataSource.collectionView = _mediaSourceCollectionView;
+ _mediaSourceDataSource.collectionViewScrollView = _mediaSourceCollectionViewScrollView;
_mediaSourceDataSource.homeButton = _mediaSourceHomeButton;
_mediaSourceDataSource.pathControl = _mediaSourcePathControl;
+ _mediaSourceDataSource.gridVsListSegmentedControl = _gridVsListSegmentedControl;
+ _mediaSourceTableView.rowHeight = VLCLibraryWindowLargeRowHeight;
+ _mediaSourceDataSource.tableView = _mediaSourceTableView;
[_mediaSourceDataSource setupViews];
self.upNextLabel.font = [NSFont VLClibrarySectionHeaderFont];
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.h b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.h
index 7df831c4e2..df6f4044a3 100644
--- a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.h
+++ b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.h
@@ -32,6 +32,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface VLCMediaSourceBaseDataSource : NSObject
@property (readwrite) NSCollectionView *collectionView;
+ at property (readwrite) NSScrollView *collectionViewScrollView;
+ at property (readwrite) NSTableView *tableView;
+ at property (readwrite) NSSegmentedControl *gridVsListSegmentedControl;
@property (readwrite) NSButton *homeButton;
@property (readwrite) NSPathControl *pathControl;
@property (readwrite, nonatomic) VLCMediaSourceMode mediaSourceMode;
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
index 8813eb0c8a..83cf79a7a4 100644
--- a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
+++ b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m
@@ -31,12 +31,17 @@
#import "main/VLCMain.h"
#import "views/VLCImageView.h"
#import "library/VLCInputItem.h"
+#import "library/VLCLibraryTableCellView.h"
#import "extensions/NSString+Helpers.h"
- at interface VLCMediaSourceBaseDataSource () <NSCollectionViewDataSource, NSCollectionViewDelegate>
+NSString *VLCMediaSourceTableViewCellIdentifier = @"VLCMediaSourceTableViewCellIdentifier";
+
+ at interface VLCMediaSourceBaseDataSource () <NSCollectionViewDataSource, NSCollectionViewDelegate, NSTableViewDelegate, NSTableViewDataSource>
{
NSArray *_mediaSources;
VLCMediaSourceDataSource *_childDataSource;
+ NSArray *_discoveredLANdevices;
+ BOOL _gridViewMode;
}
@end
@@ -69,6 +74,8 @@
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
+#pragma mark - view and model state management
+
- (void)setupViews
{
self.collectionView.dataSource = self;
@@ -79,6 +86,15 @@
self.homeButton.action = @selector(homeButtonAction:);
self.homeButton.target = self;
self.pathControl.URL = nil;
+
+ self.gridVsListSegmentedControl.action = @selector(switchGripOrListMode:);
+ self.gridVsListSegmentedControl.target = self;
+ self.gridVsListSegmentedControl.selectedSegment = 0;
+
+ self.tableView.dataSource = self;
+ self.tableView.delegate = self;
+ self.tableView.hidden = YES;
+ _gridViewMode = YES;
}
- (void)loadMediaSources
@@ -109,6 +125,8 @@
[self homeButtonAction:nil];
}
+#pragma mark - collection view data source
+
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
{
if (_mediaSourceMode == VLCMediaSourceModeLAN) {
@@ -168,7 +186,6 @@
VLCMediaSource *mediaSource;
VLCInputNode *childNode;
- _childDataSource = [[VLCMediaSourceDataSource alloc] init];
if (_mediaSourceMode == VLCMediaSourceModeLAN) {
mediaSource = _mediaSources[indexPath.section];
@@ -180,25 +197,155 @@
childNode = mediaSource.rootNode;
}
- VLCInputItem *childRootInput = childNode.inputItem;
- self.pathControl.URL = [NSURL URLWithString:[NSString stringWithFormat:@"vlc://%@", [childRootInput.name stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
+ [self configureChildDataSourceWithNode:childNode andMediaSource:mediaSource];
+
+ [self reloadData];
+}
+
+#pragma mark - table view data source and delegation
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
+{
+ if (_mediaSourceMode == VLCMediaSourceModeLAN) {
+ /* for LAN, we don't show the root items but the top items, which may change any time through a callback
+ * so we don't run into conflicts, we compile a list of the currently known here and propose that
+ * as the truth to the table view. For collection view, we use sections which can be reloaded individually,
+ * so the problem is well hidden and does not need this work-around */
+ _discoveredLANdevices = nil;
+ NSMutableArray *currentDevices;
+ @synchronized (_mediaSources) {
+ NSInteger mediaSourceCount = _mediaSources.count;
+ currentDevices = [[NSMutableArray alloc] initWithCapacity:mediaSourceCount];
+ for (NSUInteger x = 0; x < mediaSourceCount; x++) {
+ VLCMediaSource *mediaSource = _mediaSources[x];
+ VLCInputNode *rootNode = mediaSource.rootNode;
+ [currentDevices addObjectsFromArray:rootNode.children];
+ }
+ }
+ _discoveredLANdevices = [currentDevices copy];
+ return _discoveredLANdevices.count;
+ }
+
+ return _mediaSources.count;
+}
+
+- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
+{
+ VLCLibraryTableCellView *cellView = [tableView makeViewWithIdentifier:VLCMediaSourceTableViewCellIdentifier 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 = VLCMediaSourceTableViewCellIdentifier;
+ }
+ cellView.primaryTitleTextField.hidden = YES;
+ cellView.secondaryTitleTextField.hidden = YES;
+ cellView.singlePrimaryTitleTextField.hidden = NO;
+
+ if (_mediaSourceMode == VLCMediaSourceModeLAN) {
+ VLCInputNode *currentNode = _discoveredLANdevices[row];
+ VLCInputItem *currentNodeInput = currentNode.inputItem;
+
+ NSURL *artworkURL = currentNodeInput.artworkURL;
+ NSImage *placeholder = [NSImage imageNamed:@"NXdefaultappicon"];
+ if (artworkURL) {
+ [cellView.representedImageView setImageURL:artworkURL placeholderImage:placeholder];
+ } else {
+ cellView.representedImageView.image = placeholder;
+ }
+
+ cellView.singlePrimaryTitleTextField.stringValue = currentNodeInput.name;
+ } else {
+ VLCMediaSource *mediaSource = _mediaSources[row];
+ cellView.singlePrimaryTitleTextField.stringValue = mediaSource.mediaSourceDescription;
+ cellView.representedImageView.image = [NSImage imageNamed:@"NXFollow"];
+ }
+
+ return cellView;
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)notification
+{
+ NSInteger selectedRow = self.tableView.selectedRow;
+ if (selectedRow < 0) {
+ return;
+ }
+
+ VLCMediaSource *mediaSource = _mediaSources[selectedRow];;
+ VLCInputNode *childNode;
+ if (_mediaSourceMode == VLCMediaSourceModeLAN) {
+ childNode = _discoveredLANdevices[selectedRow];
+ } else {
+ childNode = mediaSource.rootNode;
+ }
+ [self configureChildDataSourceWithNode:childNode andMediaSource:mediaSource];
+
+ [self reloadData];
+}
+
+#pragma mark - glue code
+
+- (void)configureChildDataSourceWithNode:(VLCInputNode *)node andMediaSource:(VLCMediaSource *)mediaSource
+{
+ _childDataSource = [[VLCMediaSourceDataSource alloc] init];
+
+ VLCInputItem *nodeInput = node.inputItem;
+ self.pathControl.URL = [NSURL URLWithString:[NSString stringWithFormat:@"vlc://%@", [nodeInput.name stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
_childDataSource.displayedMediaSource = mediaSource;
- _childDataSource.nodeToDisplay = childNode;
+ _childDataSource.nodeToDisplay = node;
_childDataSource.collectionView = self.collectionView;
_childDataSource.pathControl = self.pathControl;
+ _childDataSource.tableView = self.tableView;
+ [_childDataSource setupViews];
self.collectionView.dataSource = _childDataSource;
self.collectionView.delegate = _childDataSource;
- [self.collectionView reloadData];
+
+ self.tableView.dataSource = _childDataSource;
+ self.tableView.delegate = _childDataSource;
}
-- (IBAction)homeButtonAction:(id)sender
+#pragma mark - user interaction with generic buttons
+
+- (void)homeButtonAction:(id)sender
{
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
- [self.collectionView reloadData];
+ self.tableView.dataSource = self;
+ self.tableView.delegate = self;
+
_childDataSource = nil;
+
+ [self reloadData];
+}
+
+- (void)switchGripOrListMode:(id)sender
+{
+ _gridViewMode = !_gridViewMode;
+ _childDataSource.gridViewMode = _gridViewMode;
+
+ if (_gridViewMode) {
+ self.collectionViewScrollView.hidden = NO;
+ self.tableView.hidden = YES;
+ [self.collectionView reloadData];
+ } else {
+ self.collectionViewScrollView.hidden = YES;
+ self.tableView.hidden = NO;
+ [self.tableView reloadData];
+ }
}
#pragma mark - VLCMediaSource Delegation
@@ -223,11 +370,24 @@
- (void)reloadDataForNotification:(NSNotification *)aNotification
{
- if (self.collectionView.dataSource == self) {
- NSInteger index = [_mediaSources indexOfObject:aNotification.object];
- [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
+ if (_gridViewMode) {
+ if (self.collectionView.dataSource == self) {
+ NSInteger index = [_mediaSources indexOfObject:aNotification.object];
+ [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:index]];
+ } else {
+ [self.collectionView reloadData];
+ }
} else {
+ [self.tableView reloadData];
+ }
+}
+
+- (void)reloadData
+{
+ if (_gridViewMode) {
[self.collectionView reloadData];
+ } else {
+ [self.tableView reloadData];
}
}
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
index f7e3b02adf..bea78c6be7 100644
--- a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
+++ b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.h
@@ -27,12 +27,16 @@ NS_ASSUME_NONNULL_BEGIN
@class VLCInputNode;
@class VLCMediaSource;
- at interface VLCMediaSourceDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate>
+ at interface VLCMediaSourceDataSource : NSObject <NSCollectionViewDataSource, NSCollectionViewDelegate, NSTableViewDelegate, NSTableViewDataSource>
@property (readwrite, retain) VLCMediaSource *displayedMediaSource;
@property (readwrite, retain, nonatomic) VLCInputNode *nodeToDisplay;
@property (readwrite, assign) NSCollectionView *collectionView;
+ at property (readwrite, assign) NSTableView *tableView;
@property (readwrite) NSPathControl *pathControl;
+ at property (readwrite) BOOL gridViewMode;
+
+- (void)setupViews;
@end
diff --git a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
index 4710a1c4d3..3cc116955b 100644
--- a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
+++ b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m
@@ -23,6 +23,7 @@
#import "VLCMediaSourceDataSource.h"
#import "library/VLCInputItem.h"
+#import "library/VLCLibraryTableCellView.h"
#import "media-source/VLCMediaSourceCollectionViewItem.h"
#import "media-source/VLCMediaSource.h"
#import "main/VLCMain.h"
@@ -33,7 +34,6 @@
@interface VLCMediaSourceDataSource()
{
VLCInputItem *_childRootInput;
- VLCMediaSourceDataSource *_childDataSource;
}
@end
@@ -47,6 +47,14 @@
[self.displayedMediaSource preparseInputItemWithinTree:_childRootInput];
}
+- (void)setupViews
+{
+ [self.tableView setDoubleAction:@selector(tableViewAction:)];
+ [self.tableView setTarget:self];
+}
+
+#pragma mark - collection view data source and delegation
+
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
{
return 1;
@@ -86,17 +94,100 @@
VLCInputNode *rootNode = self.nodeToDisplay;
NSArray *nodeChildren = rootNode.children;
VLCInputNode *childNode = nodeChildren[indexPath.item];
+
+ [self performActionForNode:childNode allowPlayback:YES];
+}
+
+#pragma mark - table view data source and delegation
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
+{
+ if (_nodeToDisplay) {
+ return _nodeToDisplay.numberOfChildren;
+ }
+
+ return 0;
+}
+
+- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
+{
+ VLCLibraryTableCellView *cellView = [tableView makeViewWithIdentifier:@"VLCMediaSourceTableViewCellIdentifier" 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 = @"VLCMediaSourceTableViewCellIdentifier";
+ }
+
+ VLCInputNode *rootNode = _nodeToDisplay;
+ NSArray *nodeChildren = rootNode.children;
+ VLCInputNode *childNode = nodeChildren[row];
VLCInputItem *childRootInput = childNode.inputItem;
+ cellView.representedInputItem = childRootInput;
+
+ return cellView;
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)notification
+{
+ NSInteger selectedIndex = self.tableView.selectedRow;
+ if (selectedIndex < 0) {
+ return;
+ }
+ VLCInputNode *rootNode = self.nodeToDisplay;
+ NSArray *nodeChildren = rootNode.children;
+ VLCInputNode *childNode = nodeChildren[selectedIndex];
+
+ [self performActionForNode:childNode allowPlayback:NO];
+}
+
+- (void)tableViewAction:(id)sender
+{
+ NSInteger selectedIndex = self.tableView.selectedRow;
+ if (selectedIndex < 0) {
+ return;
+ }
+
+ VLCInputNode *rootNode = self.nodeToDisplay;
+ NSArray *nodeChildren = rootNode.children;
+ VLCInputNode *childNode = nodeChildren[selectedIndex];
+
+ [self performActionForNode:childNode allowPlayback:YES];
+}
+
+#pragma mark - generic actions
+
+- (void)performActionForNode:(VLCInputNode *)node allowPlayback:(BOOL)allowPlayback
+{
+ VLCInputItem *childRootInput = node.inputItem;
if (childRootInput.inputType == ITEM_TYPE_DIRECTORY || childRootInput.inputType == ITEM_TYPE_NODE) {
self.pathControl.URL = [NSURL URLWithString:[self.pathControl.URL.path stringByAppendingPathComponent:[childRootInput.name stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
- self.nodeToDisplay = childNode;
- [self.collectionView reloadData];
- } else if (childRootInput.inputType == ITEM_TYPE_FILE) {
+ self.nodeToDisplay = node;
+ [self reloadData];
+ } else if (childRootInput.inputType == ITEM_TYPE_FILE && allowPlayback) {
[[[VLCMain sharedInstance] playlistController] addInputItem:childRootInput.vlcInputItem atPosition:-1 startPlayback:YES];
+ }
+}
+
+- (void)reloadData
+{
+ if (_gridViewMode) {
+ [self.collectionView reloadData];
} else {
- NSAssert(1, @"unhandled input type when browsing media source hierarchy %i", childRootInput.inputType);
- msg_Warn(getIntf(), "unhandled input type when browsing media source hierarchy %i", childRootInput.inputType);
+ [self.tableView reloadData];
}
}
More information about the vlc-commits
mailing list