You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
6.2 KiB
161 lines
6.2 KiB
/*****************************************************************************
|
|
* VLCLibraryHomeViewActionButtonCell.m: MacOS X interface module
|
|
*****************************************************************************
|
|
* Copyright (C) 2024 VLC authors and VideoLAN
|
|
*
|
|
* Authors: Claudio Cambra <developer@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 "VLCLibraryHomeViewActionButtonCell.h"
|
|
|
|
#import "extensions/NSColor+VLCAdditions.h"
|
|
#import "extensions/NSFont+VLCAdditions.h"
|
|
#import "library/VLCLibraryUIUnits.h"
|
|
|
|
@interface VLCLibraryHomeViewActionButtonCell ()
|
|
|
|
@property NSImage *cachedImage;
|
|
@property BOOL prevIsHighlighted;
|
|
@property NSRect prevFrame;
|
|
|
|
@property (readonly) NSDictionary<NSAttributedStringKey, id> *cachedTitleAttributes;
|
|
@property (readonly) CGFloat cachedTitleHeight;
|
|
|
|
@end
|
|
|
|
@implementation VLCLibraryHomeViewActionButtonCell
|
|
|
|
- (NSRect)titleRectForBounds:(NSRect)bounds
|
|
{
|
|
return bounds;
|
|
}
|
|
|
|
- (NSRect)imageRectForBounds:(NSRect)bounds
|
|
{
|
|
return bounds;
|
|
}
|
|
|
|
- (NSDictionary<NSAttributedStringKey, id> *)titleAttributes
|
|
{
|
|
if (_cachedTitleAttributes) {
|
|
return _cachedTitleAttributes;
|
|
}
|
|
NSMutableParagraphStyle * const titleParagraphStyle = [[NSMutableParagraphStyle alloc] init];
|
|
titleParagraphStyle.alignment = NSTextAlignmentCenter;
|
|
_cachedTitleAttributes = @{
|
|
NSForegroundColorAttributeName: NSColor.controlTextColor,
|
|
NSFontAttributeName: NSFont.VLCLibrarySubsectionSubheaderFont,
|
|
NSParagraphStyleAttributeName: titleParagraphStyle
|
|
};
|
|
return _cachedTitleAttributes;
|
|
}
|
|
|
|
- (CGFloat)titleHeightWithAttributes:(NSDictionary<NSAttributedStringKey, id> *)attributes
|
|
{
|
|
if (_cachedTitleHeight) {
|
|
return _cachedTitleHeight;
|
|
}
|
|
const NSSize titleSize = [self.title sizeWithAttributes:attributes];
|
|
_cachedTitleHeight = titleSize.height + VLCLibraryUIUnits.smallSpacing;
|
|
return _cachedTitleHeight;
|
|
}
|
|
|
|
- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView
|
|
{
|
|
const CGSize cellSize = frame.size;
|
|
const CGFloat cellWidth = cellSize.width;
|
|
const CGFloat cellHeight = cellSize.height;
|
|
const CGFloat titleHeight = [self titleHeightWithAttributes:[self titleAttributes]];
|
|
|
|
const CGSize imageSize = self.image.size;
|
|
|
|
if (self.cachedImage != self.image ||
|
|
self.prevIsHighlighted != self.isHighlighted ||
|
|
!NSEqualRects(self.prevFrame, frame)) {
|
|
|
|
self.cachedImage = [NSImage imageWithSize:imageSize
|
|
flipped:NO
|
|
drawingHandler:^BOOL(NSRect __unused dstRect) {
|
|
if (self.isHighlighted) {
|
|
[NSColor.VLCSubtleBorderColor set];
|
|
} else {
|
|
[NSColor.VLCSubtlerAccentColor set];
|
|
}
|
|
const NSRect imageRect = {NSZeroPoint, imageSize};
|
|
[self.image drawInRect:imageRect];
|
|
NSRectFillUsingOperation(imageRect, NSCompositingOperationSourceIn);
|
|
return YES;
|
|
}];
|
|
|
|
self.prevIsHighlighted = self.isHighlighted;
|
|
self.prevFrame = frame;
|
|
}
|
|
|
|
const CGFloat originalImageAspectRatio = imageSize.width / imageSize.height;
|
|
const CGFloat imageAvailableVerticalSpace =
|
|
cellHeight - titleHeight - VLCLibraryUIUnits.largeSpacing * 2;
|
|
CGFloat imageWidth, imageHeight;
|
|
|
|
// Try to scale focusing on width first, if this yields a height that is too large, switch
|
|
if (cellWidth / originalImageAspectRatio > imageAvailableVerticalSpace) {
|
|
imageHeight = imageAvailableVerticalSpace;
|
|
imageWidth = imageHeight * originalImageAspectRatio;
|
|
} else {
|
|
imageWidth = cellWidth;
|
|
imageHeight = imageWidth / originalImageAspectRatio;
|
|
}
|
|
|
|
const CGPoint cellOrigin = frame.origin;
|
|
const NSRect imageRect = NSMakeRect(cellOrigin.x + (cellWidth - imageWidth) / 2,
|
|
cellOrigin.y + (cellHeight - imageHeight) / 2,
|
|
imageWidth,
|
|
imageHeight);
|
|
[self.cachedImage drawInRect:imageRect];
|
|
}
|
|
|
|
- (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
|
{
|
|
const CGFloat cellMinX = NSMinX(cellFrame);
|
|
const CGFloat cellMaxY = NSMaxY(cellFrame);
|
|
const CGSize cellSize = cellFrame.size;
|
|
const CGFloat cellWidth = cellSize.width;
|
|
|
|
NSDictionary<NSAttributedStringKey, id> * const titleAttributes = [self titleAttributes];
|
|
const CGFloat titleHeight = [self titleHeightWithAttributes:titleAttributes];
|
|
const NSRect titleRect = CGRectMake(cellMinX + VLCLibraryUIUnits.smallSpacing,
|
|
cellMaxY - titleHeight,
|
|
cellWidth - VLCLibraryUIUnits.smallSpacing * 2,
|
|
titleHeight);
|
|
[self.title drawInRect:titleRect withAttributes:titleAttributes];
|
|
return titleRect;
|
|
}
|
|
|
|
- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView
|
|
{
|
|
[NSColor.VLCSubtleBorderColor setStroke];
|
|
[NSColor.windowBackgroundColor setFill];
|
|
|
|
NSBezierPath * const separatorPath =
|
|
[NSBezierPath bezierPathWithRoundedRect:frame
|
|
xRadius:VLCLibraryUIUnits.cornerRadius
|
|
yRadius:VLCLibraryUIUnits.cornerRadius];
|
|
separatorPath.lineWidth = VLCLibraryUIUnits.borderThickness;
|
|
[separatorPath stroke];
|
|
[separatorPath fill];
|
|
}
|
|
|
|
@end
|
|
|