Skip to content
This repository has been archived by the owner on Mar 30, 2021. It is now read-only.

Commit

Permalink
Add alternative, pretty (!) view for mini player
Browse files Browse the repository at this point in the history
  • Loading branch information
kbhomes committed Mar 26, 2014
1 parent 8834eca commit b972f47
Show file tree
Hide file tree
Showing 24 changed files with 565 additions and 64 deletions.
10 changes: 10 additions & 0 deletions google-music-mac.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
D343CDF518C69DF4002F9DB3 /* NavigationPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D343CDF418C69DF4002F9DB3 /* NavigationPreferencesViewController.m */; };
D34DC2BC18C295A700C27596 /* LastFmService.m in Sources */ = {isa = PBXBuildFile; fileRef = D34DC2BB18C295A700C27596 /* LastFmService.m */; };
D35788BD18C2F820006AF859 /* GeneralPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35788BC18C2F820006AF859 /* GeneralPreferencesViewController.m */; };
D370E8E018E21ABC007B5450 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D370E8DF18E21ABC007B5450 /* QuartzCore.framework */; };
D370E8E318E2BFE1007B5450 /* ExpandHoverView.m in Sources */ = {isa = PBXBuildFile; fileRef = D370E8E218E2BFE1007B5450 /* ExpandHoverView.m */; };
D3B1668318BB0E43003FCE6B /* DummyWebViewPolicyDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D3B1668218BB0E43003FCE6B /* DummyWebViewPolicyDelegate.m */; };
D3B71C2818C2D5240041358B /* PreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3B71C2718C2D5240041358B /* PreferencesWindowController.m */; };
D3B71C2F18C2D5770041358B /* LastFmPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3B71C2D18C2D5770041358B /* LastFmPreferencesViewController.m */; };
Expand Down Expand Up @@ -92,6 +94,9 @@
D34DC2BB18C295A700C27596 /* LastFmService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LastFmService.m; sourceTree = "<group>"; };
D35788BB18C2F820006AF859 /* GeneralPreferencesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneralPreferencesViewController.h; sourceTree = "<group>"; };
D35788BC18C2F820006AF859 /* GeneralPreferencesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneralPreferencesViewController.m; sourceTree = "<group>"; };
D370E8DF18E21ABC007B5450 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
D370E8E118E2BFE1007B5450 /* ExpandHoverView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpandHoverView.h; sourceTree = "<group>"; };
D370E8E218E2BFE1007B5450 /* ExpandHoverView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExpandHoverView.m; sourceTree = "<group>"; };
D3B1668118BB0E43003FCE6B /* DummyWebViewPolicyDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DummyWebViewPolicyDelegate.h; sourceTree = "<group>"; };
D3B1668218BB0E43003FCE6B /* DummyWebViewPolicyDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DummyWebViewPolicyDelegate.m; sourceTree = "<group>"; };
D3B71C2618C2D5240041358B /* PreferencesWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesWindowController.h; sourceTree = "<group>"; };
Expand All @@ -115,6 +120,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D370E8E018E21ABC007B5450 /* QuartzCore.framework in Frameworks */,
1A7B687417453E4C001E509E /* WebKit.framework in Frameworks */,
1A7B684017453E40001E509E /* Cocoa.framework in Frameworks */,
38D0C36DAD0F40F5A7254224 /* libPods.a in Frameworks */,
Expand Down Expand Up @@ -146,6 +152,7 @@
1A7B683E17453E40001E509E /* Frameworks */ = {
isa = PBXGroup;
children = (
D370E8DF18E21ABC007B5450 /* QuartzCore.framework */,
1A7B687317453E4C001E509E /* WebKit.framework */,
1A7B683F17453E40001E509E /* Cocoa.framework */,
1A7B684117453E40001E509E /* Other Frameworks */,
Expand Down Expand Up @@ -226,6 +233,8 @@
D32CCEFE18BED65B00BDD484 /* Popup */ = {
isa = PBXGroup;
children = (
D370E8E118E2BFE1007B5450 /* ExpandHoverView.h */,
D370E8E218E2BFE1007B5450 /* ExpandHoverView.m */,
D3DB8FF618BD6A6400ABE93B /* PlaybackSliderCell.h */,
D3DB8FF718BD6A6400ABE93B /* PlaybackSliderCell.m */,
D3FAC6D218BA81EC00D9F461 /* PopupStatusView.h */,
Expand Down Expand Up @@ -415,6 +424,7 @@
D3FAC6D418BA81EC00D9F461 /* PopupStatusView.m in Sources */,
D343CDF518C69DF4002F9DB3 /* NavigationPreferencesViewController.m in Sources */,
D3091F6318C32961007C8DCD /* Utilities.m in Sources */,
D370E8E318E2BFE1007B5450 /* ExpandHoverView.m in Sources */,
D32CCEFD18BE9BF800BDD484 /* PopupView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
17 changes: 17 additions & 0 deletions google-music-mac/Popup/ExpandHoverView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* ExpandHoverView.h
*
* Created by Sajid Anwar.
*
* Subject to terms and conditions in LICENSE.md.
*
*/

#import <Cocoa/Cocoa.h>
#import "Utilities.h"

@interface ExpandHoverView : NSImageView

@property (retain) NSTrackingArea *trackingArea;

@end
46 changes: 46 additions & 0 deletions google-music-mac/Popup/ExpandHoverView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* ExpandHoverView.m
*
* Created by Sajid Anwar.
*
* Subject to terms and conditions in LICENSE.md.
*
*/

#import "ExpandHoverView.h"

@implementation ExpandHoverView

@synthesize trackingArea;

- (void)awakeFromNib
{
[self setAlphaValue:0.0];
[self setImage:[Utilities imageFromName:@"arrow_expand_art"]];
}

- (void)mouseEntered:(NSEvent *)theEvent
{
[[self animator] setAlphaValue:1.0];
}

- (void)mouseExited:(NSEvent *)theEvent
{
[[self animator] setAlphaValue:0.0];
}

- (void)updateTrackingAreas
{
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
}

int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}

@end
4 changes: 2 additions & 2 deletions google-music-mac/Popup/PlaybackSliderCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ - (void)drawKnob:(NSRect)knobRect
attributes:attributes];

[[NSColor grayColor] set];
NSBezierPath *totalTimePath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(totalPoint.x - totalTime.size.width - 6, totalPoint.y, totalTime.size.width + 6, totalTime.size.height + 2)
NSBezierPath *totalTimePath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(totalPoint.x - totalTime.size.width - 4, totalPoint.y, totalTime.size.width + 6, totalTime.size.height + 2)
xRadius:3
yRadius:3];
[totalTimePath fill];

totalPoint.x = totalPoint.x - totalTime.size.width - 3;
totalPoint.x = totalPoint.x - totalTime.size.width - 1;
[totalTime drawAtPoint:totalPoint];
}

Expand Down
2 changes: 2 additions & 0 deletions google-music-mac/Popup/PopupPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

@end

@class PopupView;

@interface PopupPanel : NSPanel<NSWindowDelegate>

@property (assign) id<PopupDelegate> popupDelegate;
Expand Down
1 change: 0 additions & 1 deletion google-music-mac/Popup/PopupPanel.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ - (void)windowDidResignKey:(NSNotification *)notification
[self close];
}


- (void)showRelativeToRect:(NSRect)rect ofView:(NSView *)view preferredEdge:(NSRectEdge)edge
{
if (popupDelegate)
Expand Down
3 changes: 3 additions & 0 deletions google-music-mac/Popup/PopupStatusView.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#import "AppDelegate.h"
#import "PopupPanel.h"

@class PopupPanel;
@protocol PopupDelegate;

@interface PopupStatusView : NSView<PopupDelegate, NSMenuDelegate>
{
NSMenu *_menu;
Expand Down
24 changes: 23 additions & 1 deletion google-music-mac/Popup/PopupView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,31 @@
*/

#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#import "PopupViewDelegate.h"

@interface PopupView : NSView
#define MINI_PLAYER_LARGE_HEIGHT 356.0
#define MINI_PLAYER_SMALL_HEIGHT 152.0

#define NO_SONGS_PLAYING_TAG 1
#define EXPAND_ART_TAG 2

@class PopupViewDelegate;

@interface PopupView : NSView {
NSImage *_backgroundImage;
CGFloat _hoverAlphaMultiplier;
}

@property (assign) BOOL isLargePlayer;
@property (retain) NSTrackingArea *trackingArea;
@property (retain) NSImage *backgroundImage;
@property (assign) CGFloat hoverAlphaMultiplier;

@property (assign) NSInteger arrowX;

@property (retain) IBOutlet PopupViewDelegate *delegate;

- (void) togglePlayerSize;

@end
185 changes: 181 additions & 4 deletions google-music-mac/Popup/PopupView.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,23 @@

@implementation PopupView

@synthesize isLargePlayer;
@synthesize trackingArea;
@synthesize backgroundImage = _backgroundImage;
@synthesize hoverAlphaMultiplier = _hoverAlphaMultiplier;

@synthesize arrowX;

@synthesize delegate;

- (void)awakeFromNib
{
isLargePlayer = NO;
_hoverAlphaMultiplier = 0.0;

[self setAnimations:@{@"hoverAlphaMultiplier": [CABasicAnimation animation]}];
}

- (void)drawRect:(NSRect)dirtyRect
{
NSRect contentRect = NSInsetRect([self bounds], LINE_THICKNESS, LINE_THICKNESS);
Expand Down Expand Up @@ -55,10 +70,42 @@ - (void)drawRect:(NSRect)dirtyRect
[path lineToPoint:NSMakePoint(arrowX - ARROW_WIDTH / 2, NSMaxY(contentRect) - ARROW_HEIGHT)];
[path closePath];

NSColor *gradientTop = [NSColor colorWithDeviceWhite:1 alpha:FILL_OPACITY];
NSColor *gradientBottom = [NSColor colorWithDeviceWhite:0.95 alpha:FILL_OPACITY];
NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:gradientTop endingColor:gradientBottom];
[gradient drawInBezierPath:path angle:-90.0];

// Draw the background album art image if possible.
if (isLargePlayer)
{
if (_backgroundImage != nil)
{
[path addClip];
[_backgroundImage drawInRect:[self bounds]];
}
else
{
NSColor *gradientTop = [NSColor colorWithDeviceWhite:1 alpha:FILL_OPACITY];
NSColor *gradientBottom = [NSColor colorWithDeviceWhite:0.95 alpha:FILL_OPACITY];
NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:gradientTop endingColor:gradientBottom];
[gradient drawInBezierPath:path angle:-90.0];
}

NSColor *gradientDark = [NSColor colorWithDeviceWhite:0.1 alpha:_hoverAlphaMultiplier*0.7];
NSColor *gradientLight = [NSColor colorWithDeviceWhite:0.05 alpha:_hoverAlphaMultiplier*0.2];
NSColor *gradientNone = [NSColor colorWithDeviceWhite:0.0 alpha:_hoverAlphaMultiplier*0.1];
NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations:
gradientDark, 0.0,
gradientLight, 0.3,
gradientNone, 0.50,
gradientLight, 0.7,
gradientDark, 1.0,
nil];
[gradient drawInBezierPath:path angle:-90.0];
}
else
{
NSColor *gradientTop = [NSColor colorWithDeviceWhite:1 alpha:FILL_OPACITY];
NSColor *gradientBottom = [NSColor colorWithDeviceWhite:0.95 alpha:FILL_OPACITY];
NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:gradientTop endingColor:gradientBottom];
[gradient drawInBezierPath:path angle:-90.0];
}

[NSGraphicsContext saveGraphicsState];

Expand All @@ -73,4 +120,134 @@ - (void)drawRect:(NSRect)dirtyRect
[NSGraphicsContext restoreGraphicsState];
}

- (void)mouseEntered:(NSEvent *)event
{
if (isLargePlayer)
{
// Begin the animation to show hover details.
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:.25];
[[self animator] setHoverAlphaMultiplier:1.0];
[NSAnimationContext endGrouping];
}
}

- (void)mouseExited:(NSEvent *)event
{
if (isLargePlayer)
{
// Begin the animation to hide hover details.
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:.25];
[[self animator] setHoverAlphaMultiplier:0.0];
[NSAnimationContext endGrouping];
}
}

- (void)updateTrackingAreas
{
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
}

int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}

- (void)setHoverAlphaMultiplier:(CGFloat)hoverAlphaMultiplier
{
_hoverAlphaMultiplier = hoverAlphaMultiplier;

// Update subviews.
for (NSView *view in [self subviews])
{
if ([view tag] != NO_SONGS_PLAYING_TAG && [view tag] != EXPAND_ART_TAG)
[view setAlphaValue:_hoverAlphaMultiplier];
}

// Redraw.
[self setNeedsDisplay:YES];
}

- (CGFloat)hoverAlphaMultiplier
{
return _hoverAlphaMultiplier;
}

- (void)togglePlayerSize
{
if (isLargePlayer == NO)
{
NSRect frame = [self.window frame];
frame.origin.y -= (MINI_PLAYER_LARGE_HEIGHT - frame.size.height);
frame.size.height = MINI_PLAYER_LARGE_HEIGHT;
isLargePlayer = YES;

// Show the controls.
[self setHoverAlphaMultiplier:1.0];

// Set the background image.
[self setBackgroundImage:[delegate.artView image]];

// Begin the animation to resize.
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:.25];
[[self.window animator] setFrame:frame display:YES];
[NSAnimationContext endGrouping];

// Recolor elements.
[delegate.titleLabel setTextColor:[NSColor whiteColor]];
[delegate.titleLabel setAlignment:NSCenterTextAlignment];
[delegate.artistLabel setTextColor:[NSColor whiteColor]];
[delegate.artistLabel setAlignment:NSCenterTextAlignment];
[delegate.albumLabel setTextColor:[NSColor whiteColor]];
[delegate.albumLabel setAlignment:NSCenterTextAlignment];

[delegate playbackChanged:delegate.playbackMode];
[delegate repeatChanged:delegate.repeatMode];
[delegate shuffleChanged:delegate.shuffleMode];
[delegate ratingChanged:delegate.songRating];
[delegate.backButton setImage:[delegate backImage]];
[delegate.forwardButton setImage:[delegate forwardImage]];
}
else
{
NSRect frame = [self.window frame];
frame.origin.y += (frame.size.height - MINI_PLAYER_SMALL_HEIGHT);
frame.size.height = MINI_PLAYER_SMALL_HEIGHT;
isLargePlayer = NO;

// Show the controls.
[self setHoverAlphaMultiplier:1.0];

// Remove the background image.
[self setBackgroundImage:nil];

// Begin the animation to resize.
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:.25];
[[self.window animator] setFrame:frame display:YES];
[NSAnimationContext endGrouping];

// Recolor elements.
[delegate.titleLabel setTextColor:[NSColor blackColor]];
[delegate.titleLabel setAlignment:NSLeftTextAlignment];
[delegate.artistLabel setTextColor:[NSColor blackColor]];
[delegate.artistLabel setAlignment:NSLeftTextAlignment];
[delegate.albumLabel setTextColor:[NSColor blackColor]];
[delegate.albumLabel setAlignment:NSLeftTextAlignment];

[delegate playbackChanged:delegate.playbackMode];
[delegate repeatChanged:delegate.repeatMode];
[delegate shuffleChanged:delegate.shuffleMode];
[delegate ratingChanged:delegate.songRating];
[delegate.backButton setImage:[delegate backImage]];
[delegate.forwardButton setImage:[delegate forwardImage]];
}
}

@end
Loading

1 comment on commit b972f47

@kbhomes
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alternative player is something more minimal and nicer-looking, inspired by the concept for Nimblify 2.0. Normally, you will only see the album art itself, but the controls and the song information appear on hover. In order to reach the alternative mode, just click on the album art in the mini player.

Alternate mini player

Please sign in to comment.