[vlc-commits] [Git][videolan/vlc][master] 6 commits: macosx: Add VLCLibraryAudioDataSourceHeaderDelegate
Steve Lhomme (@robUx4)
gitlab at videolan.org
Mon Nov 24 06:19:52 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
47ca5186 by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Add VLCLibraryAudioDataSourceHeaderDelegate
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
ce3ffce9 by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Add new header delegate property to audio data source
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
c5f37759 by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Add a audio group table header view
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
7b418774 by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Configure audio group table header view and delegation for it in VLCLibraryAudioViewController
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
f04b622e by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Use an NSGlassEffectView for the audio group table header view on macOS 26
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
05f437f9 by Claudio Cambra at 2025-11-24T05:51:16+00:00
macosx: Add VLCLibraryAudioGroupTableHeaderCell
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
10 changed files:
- modules/gui/macosx/Makefile.am
- modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h
- modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSourceHeaderDelegate.h
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.h
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.m
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.h
- + modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.m
- modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.h
- modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.m
Changes:
=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -276,11 +276,16 @@ libmacosx_plugin_la_SOURCES = \
gui/macosx/library/audio-library/VLCLibraryAllAudioGroupsMediaLibraryItem.h \
gui/macosx/library/audio-library/VLCLibraryAllAudioGroupsMediaLibraryItem.m \
gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h \
+ gui/macosx/library/audio-library/VLCLibraryAudioDataSourceHeaderDelegate.h \
gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m \
gui/macosx/library/audio-library/VLCLibraryAudioGroupDataSource.h \
gui/macosx/library/audio-library/VLCLibraryAudioGroupDataSource.m \
gui/macosx/library/audio-library/VLCLibraryAudioGroupHeaderView.h \
gui/macosx/library/audio-library/VLCLibraryAudioGroupHeaderView.m \
+ gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.h \
+ gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.m \
+ gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.h \
+ gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.m \
gui/macosx/library/audio-library/VLCLibraryAudioGroupTableViewDelegate.h \
gui/macosx/library/audio-library/VLCLibraryAudioGroupTableViewDelegate.m \
gui/macosx/library/audio-library/VLCLibraryAudioTableViewDelegate.h \
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.h
=====================================
@@ -24,6 +24,7 @@
#import "library/VLCLibraryCollectionViewDataSource.h"
#import "library/VLCLibraryTableViewDataSource.h"
+#import "library/audio-library/VLCLibraryAudioDataSourceHeaderDelegate.h"
#include "views/iCarousel/iCarousel.h"
@@ -60,6 +61,8 @@ extern NSString * const VLCLibraryYearSortDescriptorKey;
extern NSString * const VLCLibraryAudioDataSourceDisplayedCollectionChangedNotification;
+ at class VLCLibraryRepresentedItem;
+
@interface VLCLibraryAudioDataSource : NSObject <VLCLibraryTableViewDataSource, VLCLibraryCollectionViewDataSource, iCarouselDataSource>
@property (readwrite, weak) VLCLibraryModel *libraryModel;
@@ -68,6 +71,7 @@ extern NSString * const VLCLibraryAudioDataSourceDisplayedCollectionChangedNotif
@property (readwrite, weak) NSCollectionView *collectionView;
@property (readwrite, weak) iCarousel *carouselView;
@property (readwrite, weak) NSTableView *gridModeListTableView;
+ at property (readwrite, weak, nullable) id<VLCLibraryAudioDataSourceHeaderDelegate> headerDelegate;
@property (nonatomic, readwrite, assign) VLCAudioLibrarySegment audioLibrarySegment;
@property (readwrite, strong) VLCLibraryAudioGroupDataSource *audioGroupDataSource;
@@ -80,6 +84,7 @@ extern NSString * const VLCLibraryAudioDataSourceDisplayedCollectionChangedNotif
- (void)setup;
- (void)reloadData;
- (void)tableView:(NSTableView * const)tableView selectRowIndices:(NSIndexSet * const)indices;
+- (void)applySelectionForTableView:(NSTableView *)tableView;
@end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSource.m
=====================================
@@ -693,6 +693,48 @@ NSString * const VLCLibraryAudioDataSourceDisplayedCollectionChangedNotification
return self.displayedCollection[row];
}
+- (void)applySelectionForTableView:(NSTableView *)tableView
+{
+ if (tableView == nil ||
+ (tableView != self.collectionSelectionTableView && tableView != self.gridModeListTableView)) {
+ return;
+ }
+
+ const NSInteger selectedRow = tableView.selectedRow;
+ if (selectedRow >= 0 && (NSUInteger)selectedRow >= self.displayedCollection.count) {
+ return;
+ }
+
+ const BOOL shouldClearSelection = self.currentParentType == VLCMediaLibraryParentGroupTypeAudioLibrary ||
+ self.currentParentType == VLCMediaLibraryParentGroupTypeRecentAudios ||
+ selectedRow < 0 ||
+ self.displayedCollectionUpdating;
+
+ const id<VLCMediaLibraryAudioGroupProtocol> selectedItem =
+ shouldClearSelection ? nil : self.displayedCollection[selectedRow];
+ self.audioGroupDataSource.representedAudioGroup = selectedItem;
+
+ VLCLibraryRepresentedItem *representedItem = nil;
+ NSString *fallbackTitle = nil;
+ NSString *fallbackDetail = nil;
+
+ if (self.displayAllArtistsGenresTableEntry && selectedRow == 0) {
+ fallbackTitle = (self.currentParentType == VLCMediaLibraryParentGroupTypeGenre)
+ ? _NS("All genres")
+ : _NS("All artists");
+ } else if (selectedItem != nil) {
+ representedItem = [[VLCLibraryRepresentedItem alloc] initWithItem:selectedItem parentType:self.currentParentType];
+ fallbackTitle = selectedItem.displayString;
+ fallbackDetail = selectedItem.primaryDetailString;
+ }
+
+ [self.headerDelegate audioDataSource:self
+ updateHeaderForTableView:tableView
+ withRepresentedItem:representedItem
+ fallbackTitle:fallbackTitle
+ fallbackDetail:fallbackDetail];
+}
+
- (void)tableView:(NSTableView * const)tableView selectRowIndices:(NSIndexSet * const)indices
{
NSParameterAssert(tableView);
@@ -711,14 +753,7 @@ NSString * const VLCLibraryAudioDataSourceDisplayedCollectionChangedNotification
return;
}
- if (self.currentParentType == VLCMediaLibraryParentGroupTypeAudioLibrary ||
- self.currentParentType == VLCMediaLibraryParentGroupTypeRecentAudios ||
- selectedRow < 0 ||
- self.displayedCollectionUpdating) {
- self.audioGroupDataSource.representedAudioGroup = nil;
- } else {
- self.audioGroupDataSource.representedAudioGroup = self.displayedCollection[selectedRow];
- }
+ [self applySelectionForTableView:tableView];
}
- (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray<NSSortDescriptor *> *)oldDescriptors
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioDataSourceHeaderDelegate.h
=====================================
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * VLCLibraryAudioDataSourceHeaderDelegate.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+ at class VLCLibraryAudioDataSource;
+ at class VLCLibraryRepresentedItem;
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at protocol VLCLibraryAudioDataSourceHeaderDelegate <NSObject>
+
+- (void)audioDataSource:(VLCLibraryAudioDataSource *)dataSource
+ updateHeaderForTableView:(NSTableView *)tableView
+ withRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
+ fallbackTitle:(NSString *)fallbackTitle
+ fallbackDetail:(NSString *)fallbackDetail;
+
+ at end
+
+NS_ASSUME_NONNULL_END
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.h
=====================================
@@ -0,0 +1,32 @@
+/*****************************************************************************
+ * VLCLibraryAudioGroupTableHeaderCell.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at interface VLCLibraryAudioGroupTableHeaderCell : NSTableHeaderCell
+
+ at end
+
+NS_ASSUME_NONNULL_END
+
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderCell.m
=====================================
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * VLCLibraryAudioGroupTableHeaderCell.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCLibraryAudioGroupTableHeaderCell.h"
+
+ at implementation VLCLibraryAudioGroupTableHeaderCell
+
+- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
+{
+ // Intentionally do not call super to prevent AppKit from drawing its default background.
+ // The header view hosts its own background visuals (glass/effect/solid) and draws content there.
+ [NSColor.clearColor setFill];
+ NSRectFillUsingOperation(cellFrame, NSCompositingOperationClear);
+}
+
+ at end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.h
=====================================
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * VLCLibraryAudioGroupTableHeaderView.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+ at class VLCLibraryRepresentedItem;
+
+NS_ASSUME_NONNULL_BEGIN
+
+extern const CGFloat VLCLibraryAudioGroupTableHeaderViewHeight;
+
+ at interface VLCLibraryAudioGroupTableHeaderView : NSTableHeaderView
+
+ at property (nullable, nonatomic) VLCLibraryRepresentedItem *representedItem;
+
+- (void)updateWithRepresentedItem:(nullable VLCLibraryRepresentedItem *)representedItem
+ fallbackTitle:(nullable NSString *)fallbackTitle
+ fallbackDetail:(nullable NSString *)fallbackDetail;
+
+ at end
+
+NS_ASSUME_NONNULL_END
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioGroupTableHeaderView.m
=====================================
@@ -0,0 +1,268 @@
+/*****************************************************************************
+ * VLCLibraryAudioGroupTableHeaderView.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCLibraryAudioGroupTableHeaderView.h"
+
+#import "library/VLCLibraryRepresentedItem.h"
+#import "library/VLCLibraryUIUnits.h"
+
+#import "extensions/NSColor+VLCAdditions.h"
+#import "extensions/NSFont+VLCAdditions.h"
+#import "extensions/NSString+Helpers.h"
+
+const CGFloat VLCLibraryAudioGroupTableHeaderViewHeight = 86.f;
+
+ at interface VLCLibraryAudioGroupTableHeaderView ()
+
+ at property NSView *backgroundView;
+ at property NSStackView *rootStackView;
+ at property NSStackView *labelsStackView;
+ at property NSStackView *buttonsStackView;
+ at property NSTextField *titleField;
+ at property NSTextField *detailField;
+ at property NSButton *playButton;
+ at property NSButton *queueButton;
+ at property CGFloat backgroundEdgeInset;
+
+ at end
+
+ at implementation VLCLibraryAudioGroupTableHeaderView
+
+- (instancetype)initWithFrame:(NSRect)frameRect
+{
+ self = [super initWithFrame:frameRect];
+ if (self) {
+ [self commonInit];
+ }
+ return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+ self = [super initWithCoder:coder];
+ if (self) {
+ [self commonInit];
+ }
+ return self;
+}
+
+
+- (void)commonInit
+{
+ NSView *contentHostView = self;
+ self.backgroundEdgeInset = 0.f;
+
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 260000
+ if (@available(macOS 26.0, *)) {
+ NSGlassEffectView * const glassView = [[NSGlassEffectView alloc] initWithFrame:self.bounds];
+ glassView.translatesAutoresizingMaskIntoConstraints = NO;
+ NSView * const glassContentView = [[NSView alloc] initWithFrame:glassView.bounds];
+ glassContentView.translatesAutoresizingMaskIntoConstraints = NO;
+ glassView.contentView = glassContentView;
+ self.backgroundView = glassView;
+ contentHostView = glassContentView;
+ self.backgroundEdgeInset = VLCLibraryUIUnits.largeSpacing * 1.75;
+ }
+#endif
+ if (self.backgroundView == nil) {
+ self.wantsLayer = YES;
+
+ if (@available(macOS 10.14, *)) {
+ NSVisualEffectView * const visualEffectView = [[NSVisualEffectView alloc] initWithFrame:self.bounds];
+ visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
+ visualEffectView.material = NSVisualEffectMaterialHeaderView;
+ visualEffectView.blendingMode = NSVisualEffectBlendingModeWithinWindow;
+ visualEffectView.state = NSVisualEffectStateFollowsWindowActiveState;
+ self.backgroundView = visualEffectView;
+ }
+ }
+ if (self.backgroundView == nil) {
+ NSView * const fallbackBackgroundView = [[NSView alloc] initWithFrame:self.bounds];
+ fallbackBackgroundView.translatesAutoresizingMaskIntoConstraints = NO;
+ fallbackBackgroundView.wantsLayer = YES;
+ fallbackBackgroundView.layer.backgroundColor = NSColor.windowBackgroundColor.CGColor;
+ self.backgroundView = fallbackBackgroundView;
+ }
+
+ [self addSubview:self.backgroundView];
+
+ self.titleField = [self buildLabelWithFont:NSFont.VLClibrarySectionHeaderFont
+ textColor:NSColor.labelColor
+ alignment:NSTextAlignmentLeft];
+ self.detailField = [self buildLabelWithFont:NSFont.VLCLibrarySubsectionSubheaderFont
+ textColor:NSColor.secondaryLabelColor
+ alignment:NSTextAlignmentLeft];
+ self.playButton = [self buildActionButtonWithTitle:_NS("Play") action:@selector(play:)];
+ self.queueButton = [self buildActionButtonWithTitle:_NS("Queue") action:@selector(enqueue:)];
+
+ NSStackView * const labelsStack = [NSStackView stackViewWithViews:@[self.titleField, self.detailField]];
+ labelsStack.translatesAutoresizingMaskIntoConstraints = NO;
+ labelsStack.orientation = NSUserInterfaceLayoutOrientationVertical;
+ labelsStack.alignment = NSLayoutAttributeLeading;
+ labelsStack.spacing = VLCLibraryUIUnits.smallSpacing;
+ [labelsStack setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationHorizontal];
+ [labelsStack setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
+ self.labelsStackView = labelsStack;
+
+ NSStackView * const buttonsStack = [NSStackView stackViewWithViews:@[self.playButton, self.queueButton]];
+ buttonsStack.translatesAutoresizingMaskIntoConstraints = NO;
+ buttonsStack.orientation = NSUserInterfaceLayoutOrientationHorizontal;
+ buttonsStack.alignment = NSLayoutAttributeCenterY;
+ buttonsStack.spacing = VLCLibraryUIUnits.smallSpacing;
+ [buttonsStack setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
+ [buttonsStack setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
+ self.buttonsStackView = buttonsStack;
+
+ [contentHostView addSubview:labelsStack];
+ [contentHostView addSubview:buttonsStack];
+
+ const CGFloat backgroundInset = self.backgroundEdgeInset;
+ const CGFloat horizontalContentInset = VLCLibraryUIUnits.mediumSpacing;
+ const CGFloat verticalContentInset = VLCLibraryUIUnits.smallSpacing;
+
+ [NSLayoutConstraint activateConstraints:@[
+ [self.backgroundView.topAnchor constraintEqualToAnchor:self.topAnchor constant:backgroundInset * 0.66],
+ [self.backgroundView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
+ [self.backgroundView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+ [self.backgroundView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:-backgroundInset],
+ [labelsStack.leadingAnchor constraintEqualToAnchor:contentHostView.leadingAnchor constant:horizontalContentInset],
+ [labelsStack.centerYAnchor constraintEqualToAnchor:contentHostView.centerYAnchor],
+ [contentHostView.trailingAnchor constraintEqualToAnchor:buttonsStack.trailingAnchor constant:horizontalContentInset],
+ [buttonsStack.centerYAnchor constraintEqualToAnchor:contentHostView.centerYAnchor],
+ [buttonsStack.leadingAnchor constraintGreaterThanOrEqualToAnchor:labelsStack.trailingAnchor constant:VLCLibraryUIUnits.largeSpacing],
+ ]];
+
+ if (@available(macOS 26.0, *)) {
+ } else {
+ self.layer.cornerRadius = VLCLibraryUIUnits.smallSpacing;
+ self.layer.masksToBounds = YES;
+ self.layer.borderWidth = VLCLibraryUIUnits.borderThickness;
+ [self updateAppearance];
+ }
+}
+
+- (NSTextField *)buildLabelWithFont:(NSFont *)font textColor:(NSColor *)color alignment:(NSTextAlignment)alignment
+{
+ NSTextField *label;
+ if (@available(macOS 10.12, *)) {
+ label = [NSTextField labelWithString:@""];
+ } else {
+ label = [[NSTextField alloc] initWithFrame:NSZeroRect];
+ label.editable = NO;
+ label.bezeled = NO;
+ label.drawsBackground = NO;
+ label.selectable = NO;
+ }
+ label.font = font;
+ label.textColor = color;
+ label.alignment = alignment;
+ label.lineBreakMode = NSLineBreakByTruncatingTail;
+ label.translatesAutoresizingMaskIntoConstraints = NO;
+ return label;
+}
+
+- (NSButton *)buildActionButtonWithTitle:(NSString *)title action:(SEL)selector
+{
+ NSButton *button;
+ if (@available(macOS 10.12, *)) {
+ button = [NSButton buttonWithTitle:title target:self action:selector];
+ } else {
+ button = [[NSButton alloc] initWithFrame:NSZeroRect];
+ button.title = title;
+ button.target = self;
+ button.action = selector;
+ }
+ button.bezelStyle = NSBezelStyleRounded;
+ button.translatesAutoresizingMaskIntoConstraints = NO;
+ if (@available(macOS 10.14, *))
+ button.contentTintColor = NSColor.VLCAccentColor;
+ return button;
+}
+
+- (void)updateAppearance
+{
+ if (@available(macOS 26.0, *))
+ return;
+
+ if (@available(macOS 10.14, *)) {
+ NSAppearance *appearance = self.effectiveAppearance;
+ BOOL isDark = NO;
+ if ([appearance.name isEqualToString:NSAppearanceNameDarkAqua] ||
+ [appearance.name isEqualToString:NSAppearanceNameVibrantDark]) {
+ isDark = YES;
+ }
+ self.layer.borderColor = (isDark ? NSColor.VLCDarkSubtleBorderColor : NSColor.VLCLightSubtleBorderColor).CGColor;
+ } else {
+ self.layer.borderColor = NSColor.VLCLightSubtleBorderColor.CGColor;
+ }
+}
+
+- (void)viewDidChangeEffectiveAppearance
+{
+ [super viewDidChangeEffectiveAppearance];
+ [self updateAppearance];
+}
+
+- (void)setRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
+{
+ _representedItem = representedItem;
+ [self applyRepresentedItemWithFallbackTitle:nil fallbackDetail:nil];
+}
+
+- (void)applyRepresentedItemWithFallbackTitle:(NSString *)fallbackTitle fallbackDetail:(NSString *)fallbackDetail
+{
+ id<VLCMediaLibraryItemProtocol> const item = self.representedItem.item;
+ if (item == nil) {
+ self.titleField.stringValue = fallbackTitle ?: @"";
+ self.detailField.stringValue = fallbackDetail ?: @"";
+ self.playButton.enabled = NO;
+ self.queueButton.enabled = NO;
+ return;
+ }
+
+ self.titleField.stringValue = item.displayString ?: fallbackTitle ?: @"";
+ self.detailField.stringValue = item.primaryDetailString ?: fallbackDetail ?: @"";
+ self.playButton.enabled = YES;
+ self.queueButton.enabled = YES;
+}
+
+- (void)updateWithRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
+ fallbackTitle:(NSString *)fallbackTitle
+ fallbackDetail:(NSString *)fallbackDetail
+{
+ self.representedItem = representedItem;
+ [self applyRepresentedItemWithFallbackTitle:fallbackTitle fallbackDetail:fallbackDetail];
+}
+
+#pragma mark - Actions
+
+- (void)play:(id)sender
+{
+ [self.representedItem play];
+}
+
+- (void)enqueue:(id)sender
+{
+ [self.representedItem queue];
+}
+
+ at end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.h
=====================================
@@ -25,9 +25,11 @@
#import "library/VLCLibrarySegment.h"
#import "library/VLCLibraryAbstractMediaLibrarySegmentViewController.h"
#import "library/VLCLibraryItemPresentingCapable.h"
+#import "library/audio-library/VLCLibraryAudioDataSourceHeaderDelegate.h"
@class VLCLibraryAudioDataSource;
@class VLCLibraryAudioGroupDataSource;
+ at class VLCLibraryAudioGroupTableHeaderView;
@class VLCLibraryCollectionView;
@class VLCLibraryWindow;
@@ -35,12 +37,13 @@
NS_ASSUME_NONNULL_BEGIN
- at interface VLCLibraryAudioViewController : VLCLibraryAbstractMediaLibrarySegmentViewController<VLCLibraryItemPresentingCapable>
+ at interface VLCLibraryAudioViewController : VLCLibraryAbstractMediaLibrarySegmentViewController<VLCLibraryItemPresentingCapable, VLCLibraryAudioDataSourceHeaderDelegate>
@property (readonly, weak) NSView *audioLibraryView;
@property (readonly, weak) NSSplitView *audioLibrarySplitView;
@property (readonly, weak) NSScrollView *audioCollectionSelectionTableViewScrollView;
@property (readonly, weak) NSTableView *audioCollectionSelectionTableView;
+ at property (readonly, strong) VLCLibraryAudioGroupTableHeaderView *audioCollectionHeaderView;
@property (readonly, weak) NSScrollView *audioGroupSelectionTableViewScrollView;
@property (readonly, weak) NSTableView *audioGroupSelectionTableView;
@property (readonly, weak) NSScrollView *audioSongTableViewScrollView;
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioViewController.m
=====================================
@@ -42,7 +42,9 @@
#import "library/audio-library/VLCLibraryAudioDataSource.h"
#import "library/audio-library/VLCLibraryAudioGroupDataSource.h"
#import "library/audio-library/VLCLibraryAudioGroupHeaderView.h"
+#import "library/audio-library/VLCLibraryAudioGroupTableHeaderView.h"
#import "library/audio-library/VLCLibraryAudioGroupTableViewDelegate.h"
+#import "library/audio-library/VLCLibraryAudioGroupTableHeaderCell.h"
#import "library/audio-library/VLCLibraryAudioTableViewDelegate.h"
#import "library/playlist-library/VLCLibraryPlaylistViewController.h"
@@ -159,6 +161,7 @@ NSString *VLCLibraryPlaceholderAudioViewIdentifier = @"VLCLibraryPlaceholderAudi
_audioDataSource.songsTableView = _audioSongTableView;
_audioDataSource.collectionView = _audioLibraryCollectionView;
_audioDataSource.gridModeListTableView = _audioLibraryGridModeSplitViewListTableView;
+ _audioDataSource.headerDelegate = self;
[_audioDataSource setup];
_audioGroupDataSource = [[VLCLibraryAudioGroupDataSource alloc] init];
@@ -185,6 +188,21 @@ NSString *VLCLibraryPlaceholderAudioViewIdentifier = @"VLCLibraryPlaceholderAudi
_audioCollectionSelectionTableView.dataSource = _audioDataSource;
_audioCollectionSelectionTableView.delegate = _audioLibraryTableViewDelegate;
+ CGFloat headerHeight = VLCLibraryAudioGroupTableHeaderViewHeight;
+ if (@available(macOS 26.0, *)) {
+ headerHeight += VLCLibraryUIUnits.largeSpacing * 2.f;
+ }
+
+ const NSRect headerFrame = NSMakeRect(0.f,
+ 0.f,
+ _audioGroupSelectionTableView.bounds.size.width,
+ headerHeight);
+ _audioCollectionHeaderView = [[VLCLibraryAudioGroupTableHeaderView alloc] initWithFrame:headerFrame];
+ _audioCollectionHeaderView.autoresizingMask = NSViewWidthSizable;
+
+ _audioGroupSelectionTableView.headerView = self.audioCollectionHeaderView;
+ _audioGroupSelectionTableView.tableColumns.firstObject.headerCell = [VLCLibraryAudioGroupTableHeaderCell new];
+
_audioGroupSelectionTableView.dataSource = _audioGroupDataSource;
_audioGroupSelectionTableView.delegate = _audioGroupLibraryTableViewDelegate;
@@ -194,6 +212,8 @@ NSString *VLCLibraryPlaceholderAudioViewIdentifier = @"VLCLibraryPlaceholderAudi
_audioSongTableView.dataSource = _audioDataSource;
_audioSongTableView.delegate = _audioLibraryTableViewDelegate;
+
+ [_audioDataSource applySelectionForTableView:_audioCollectionSelectionTableView];
}
- (void)setupGridModeSplitView
@@ -565,4 +585,24 @@ NSString *VLCLibraryPlaceholderAudioViewIdentifier = @"VLCLibraryPlaceholderAudi
[self.libraryWindow hideLoadingOverlay];
}
+- (void)audioDataSource:(VLCLibraryAudioDataSource *)dataSource
+updateHeaderForTableView:(NSTableView *)tableView
+ withRepresentedItem:(VLCLibraryRepresentedItem *)representedItem
+ fallbackTitle:(NSString *)fallbackTitle
+ fallbackDetail:(NSString *)fallbackDetail
+{
+ if (tableView != self.audioCollectionSelectionTableView &&
+ tableView != self.audioGroupSelectionTableView &&
+ ![self.audioGroupDataSource.tableViews containsObject:tableView])
+ return;
+
+ if (representedItem != nil) {
+ self.audioCollectionHeaderView.representedItem = representedItem;
+ } else {
+ [self.audioCollectionHeaderView updateWithRepresentedItem:nil
+ fallbackTitle:fallbackTitle
+ fallbackDetail:fallbackDetail];
+ }
+}
+
@end
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/31b9abc49c938252c24c05871468df5444ea4bed...05f437f98ec2b830315fe11e837049c227bf3662
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/31b9abc49c938252c24c05871468df5444ea4bed...05f437f98ec2b830315fe11e837049c227bf3662
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list