Skip to content

Commit

Permalink
Towards preview images.
Browse files Browse the repository at this point in the history
Try to figure out preview image data and overlay the images on the view after they are loaded.
  • Loading branch information
ssp committed Oct 4, 2009
1 parent 9efe8dd commit 7d8318a
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 19 deletions.
21 changes: 21 additions & 0 deletions CTFImageLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// CTFKillerImageLoader.h
// ClickToFlash
//
// Created by Sven on 04.10.09.
// Copyright 2009 earthlingsoft. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@class CTFClickToFlashPlugin;

@interface CTFImageLoader : NSObject {
NSMutableData * data;
CTFClickToFlashPlugin * plugin;
}

- (id) initWithURL: (NSURL *) theURL forPlugin: (CTFClickToFlashPlugin *) thePlugin;
- (void) cleanup;

@end
65 changes: 65 additions & 0 deletions CTFImageLoader.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// CTFKillerImageLoader.m
// ClickToFlash
//
// Created by Sven on 04.10.09.
// Copyright 2009 earthlingsoft. All rights reserved.
//

#import "CTFImageLoader.h"
#import "Plugin.h"


@implementation CTFImageLoader

- (id) initWithURL: (NSURL *) theURL forPlugin: (CTFClickToFlashPlugin *) thePlugin {
self = [super init];

if (self != nil) {
data = [[NSMutableData alloc] initWithCapacity:125000];
plugin = [thePlugin retain];

NSURLRequest * request = [NSURLRequest requestWithURL: theURL];
[[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
[self retain];
}

return self;
}


- (void) dealloc {
[data release];
[plugin release];
[super dealloc];
}



- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *) newData {
[data appendData: newData];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSImage * image = [[[NSImage alloc] initWithData: data] autorelease];
if (image != nil) {
[plugin setPreviewImage: image ];
}

[self cleanup];
}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"ClickToFlash couldn't download preview image: %@", [error description]);
[self cleanup];
}


- (void) cleanup {
[self autorelease];
}


@end
6 changes: 6 additions & 0 deletions ClickToFlash.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
69A26D0C0F302C10006648BC /* NSBezierPath-RoundedRectangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A26D0B0F302C10006648BC /* NSBezierPath-RoundedRectangle.m */; };
6C2C5A6A1068CE8700A90A54 /* Credits.css in Resources */ = {isa = PBXBuildFile; fileRef = A40485B110629B0E00FDC4E2 /* Credits.css */; };
6C436DAF107830A200A0D525 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C436DAE107830A200A0D525 /* QTKit.framework */; };
6C6420E010792D9B0064A026 /* CTFImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C6420DF10792D9B0064A026 /* CTFImageLoader.m */; };
6C8EC6F410764F810053587F /* CTFKiller.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC6F310764F810053587F /* CTFKiller.m */; };
6C8EC7051076544D0053587F /* CTFKillerYouTube.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC7041076544D0053587F /* CTFKillerYouTube.m */; };
6C8EC775107671F20053587F /* CTFKillerVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC774107671F20053587F /* CTFKillerVideo.m */; };
Expand Down Expand Up @@ -154,6 +155,8 @@
69A26D0A0F302C10006648BC /* NSBezierPath-RoundedRectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSBezierPath-RoundedRectangle.h"; path = "Plugin/NSBezierPath-RoundedRectangle.h"; sourceTree = "<group>"; };
69A26D0B0F302C10006648BC /* NSBezierPath-RoundedRectangle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSBezierPath-RoundedRectangle.m"; path = "Plugin/NSBezierPath-RoundedRectangle.m"; sourceTree = "<group>"; };
6C436DAE107830A200A0D525 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = "<absolute>"; };
6C6420DE10792D9B0064A026 /* CTFImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTFImageLoader.h; sourceTree = "<group>"; };
6C6420DF10792D9B0064A026 /* CTFImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CTFImageLoader.m; sourceTree = "<group>"; };
6C8EC6F210764F810053587F /* CTFKiller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFKiller.h; path = Plugin/CTFKiller.h; sourceTree = "<group>"; };
6C8EC6F310764F810053587F /* CTFKiller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTFKiller.m; path = Plugin/CTFKiller.m; sourceTree = "<group>"; };
6C8EC7031076544D0053587F /* CTFKillerYouTube.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFKillerYouTube.h; path = Plugin/CTFKillerYouTube.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -243,6 +246,8 @@
children = (
55EB703D0E04A84F0016593D /* Plugin.m */,
55EB703C0E04A84F0016593D /* Plugin.h */,
6C6420DF10792D9B0064A026 /* CTFImageLoader.m */,
6C6420DE10792D9B0064A026 /* CTFImageLoader.h */,
6C8EC6F310764F810053587F /* CTFKiller.m */,
6C8EC6F210764F810053587F /* CTFKiller.h */,
6C8EC774107671F20053587F /* CTFKillerVideo.m */,
Expand Down Expand Up @@ -509,6 +514,7 @@
6C8EC775107671F20053587F /* CTFKillerVideo.m in Sources */,
6C8EC7E9107686780053587F /* CTFKillerSIFR.m in Sources */,
6CC18AE61076D09B00D9E1A0 /* CTFKillerVimeo.m in Sources */,
6C6420E010792D9B0064A026 /* CTFImageLoader.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
3 changes: 0 additions & 3 deletions Plugin/CTFKillerVideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ enum CTFKVLookupStatus {
BOOL requiresConversion;

NSSize videoSize;
NSURL * previewURL;
}

/*
Expand Down Expand Up @@ -125,8 +124,6 @@ enum CTFKVLookupStatus {
- (void) setLookupStatus: (enum CTFKVLookupStatus) newLookupStatus;
- (BOOL)requiresConversion;
- (void)setRequiresConversion:(BOOL)newRequiresConversion;
- (NSURL *) previewURL;
- (void) setPreviewURL: (NSURL *) newPreviewURL;


@end
17 changes: 2 additions & 15 deletions Plugin/CTFKillerVideo.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,13 @@ - (id) init {
requiresConversion = NO;

videoSize = NSZeroSize;
[self setPreviewURL:nil];
}

return self;
}


- (void) dealloc {
[self setPreviewURL: nil];
[super dealloc];
}

Expand Down Expand Up @@ -275,7 +273,7 @@ - (void) addAdditionalMenuItemsForContextualMenu;
- (BOOL) convertToContainer {
BOOL result = NO;

if ([self lookupStatus] == finished && [self hasVideo]) {
if ([self lookupStatus] == finished && [self hasVideo] && [CTFKillerVideo isActive]) {
[self convertToMP4ContainerUsingHD:nil];
result = YES;
}
Expand Down Expand Up @@ -716,16 +714,5 @@ - (void)setRequiresConversion:(BOOL)newRequiresConversion
}


- (NSURL *)previewURL {
return previewURL;
}

- (void)setPreviewURL:(NSURL *)newPreviewURL {
[newPreviewURL retain];
[previewURL release];
previewURL = newPreviewURL;
}


@end

@end
2 changes: 1 addition & 1 deletion Plugin/CTFKillerVimeo.m
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
nodes = [XML nodesForXPath:@"//thumbnail" error:&error];
if ([nodes count] > 0) {
node = [nodes objectAtIndex:0];
[self setPreviewURL: [NSURL URLWithString:[node stringValue]]];
[[self plugin] setPreviewURL: [NSURL URLWithString:[node stringValue]]];
}
nodes = [XML nodesForXPath:@"//isHD" error:&error];
if ([nodes count] > 0) {
Expand Down
4 changes: 4 additions & 0 deletions Plugin/CTFKillerYouTube.m
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ - (void) setup {
}
}

if ( myVideoID != nil ) {
[[self plugin] setPreviewURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://img.youtube.com/vi/%@/0.jpg", myVideoID]]];
}

if ([CTFKillerYouTube isYouTubeSiteURL: pageURL]) {
[self setAutoPlay: YES];
} else {
Expand Down
10 changes: 10 additions & 0 deletions Plugin/Plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ THE SOFTWARE.
NSTimer *_delayingTimer;

CTFKiller * killer;

NSURL * previewURL;
NSImage * previewImage;
}

+ (NSView *)plugInViewWithArguments:(NSDictionary *)arguments;
Expand Down Expand Up @@ -96,4 +99,11 @@ THE SOFTWARE.
- (void)setOriginalOpacityAttributes:(NSDictionary *)newValue;
- (NSString *)src;
- (void)setSrc:(NSString *)newValue;

- (NSURL *) previewURL;
- (void) setPreviewURL: (NSURL *) newPreviewURL;
- (NSImage *) previewImage;
- (void) setPreviewImage: (NSImage *) newPreviewImage;


@end
59 changes: 59 additions & 0 deletions Plugin/Plugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ of this software and associated documentation files (the "Software"), to deal
#import "CTFGradient.h"
#import "SparkleManager.h"
#import "CTFKiller.h"
#import "CTFImageLoader.h"

#define LOGGING_ENABLED 0

Expand Down Expand Up @@ -338,6 +339,8 @@ - (void)webPlugInDestroy
[self setAttributes:nil];
[self setOriginalOpacityAttributes:nil];
[self setKiller:nil];
[self setPreviewURL:nil];
[self setPreviewImage:nil];

[_flashVars release];
_flashVars = nil;
Expand Down Expand Up @@ -841,6 +844,34 @@ - (void) _drawBackground
//CTGradient instances are returned autoreleased - no need for explicit release here
}

// Overlay the preview image if there is one
NSImage * image = [self previewImage];
if ( image != nil ) {
NSRect destinationRect;
NSSize imageSize = [image size];
/*
// This code seems more 'right' because it attemps to display the image without losing any pixels. Yet the approach below which scales to the maximum width gives better results in practice as videos may be wide screen with the preview images having black bars on the top and bottom (which are just cut off).
CGFloat aspectRatio = fillRect.size.width / fillRect.size.height;
CGFloat imageAspectRatio = imageSize.width / imageSize.height;
if ( aspectRatio > imageAspectRatio ) {
CGFloat width = imageSize.width * fillRect.size.height / imageSize.height;
destinationRect = NSMakeRect((fillRect.size.width - width) / 2.0 , fillRect.origin.y , width, fillRect.size.height);
}
else {
CGFloat height = imageSize.height * fillRect.size.width / fillRect.size.height;
destinationRect = NSMakeRect(fillRect.origin.x, (fillRect.size.height - height) / 2.0, fillRect.size.width, height );
}
*/
CGFloat scale = fillRect.size.width / imageSize.width;
CGFloat destinationWidth = imageSize.width * scale;
CGFloat destinationHeight = imageSize.height * scale;
CGFloat destinationBottom = fillRect.origin.y + ( fillRect.size.height - destinationHeight) / 2.0;

destinationRect = NSMakeRect(fillRect.origin.x, destinationBottom, destinationWidth, destinationHeight);

[[self previewImage] drawInRect:destinationRect fromRect:NSZeroRect operation:NSCompositeSourceIn fraction: 0.8];
}

// Draw stroke
[[NSColor colorWithCalibratedWhite:0.0 alpha:0.50] set];
[NSBezierPath setDefaultLineWidth:2.0];
Expand Down Expand Up @@ -1274,4 +1305,32 @@ - (void)setKiller:(CTFKiller *)newKiller
killer = newKiller;
}


- (NSURL *) previewURL {
return previewURL;
}

- (void) setPreviewURL:(NSURL *) newPreviewURL {
[newPreviewURL retain];
[previewURL release];
previewURL = newPreviewURL;

if (previewURL != nil) {
[[[CTFImageLoader alloc] initWithURL: newPreviewURL forPlugin: self] autorelease];
}
}


- (NSImage *) previewImage {
return previewImage;
}

- (void) setPreviewImage: (NSImage *) newPreviewImage {
[newPreviewImage retain];
[previewImage release];
previewImage = newPreviewImage;

[self setNeedsDisplay: YES];
}

@end

0 comments on commit 7d8318a

Please sign in to comment.