Plugins/Displays/MusicVideo/GrowlMusicVideoWindowView.m
author Rudy Richter
Sat Aug 01 20:43:39 2009 -0400 (2009-08-01)
changeset 4259 0e9b6b0b1e25
parent 4246 4f52d1d98978
child 4541 9a290d3de636
permissions -rw-r--r--
Plugins: clang warnings
     1 //
     2 //  GrowlMusicVideoWindowView.m
     3 //  Display Plugins
     4 //
     5 //  Created by Jorge Salvador Caffarena on 09/09/04.
     6 //  Copyright 2004 Jorge Salvador Caffarena. All rights reserved.
     7 //
     8 
     9 #import "GrowlMusicVideoWindowView.h"
    10 #import "GrowlMusicVideoPrefs.h"
    11 #import "GrowlImageAdditions.h"
    12 
    13 extern CGLayerRef CGLayerCreateWithContext() __attribute__((weak_import));
    14 
    15 @implementation GrowlMusicVideoWindowView
    16 
    17 - (id) initWithFrame:(NSRect)frame {
    18 	if ((self = [super initWithFrame:frame])) {
    19 		cache = [[NSImage alloc] initWithSize:frame.size];
    20 		needsDisplay = YES;
    21 	}
    22 
    23 	return self;
    24 }
    25 
    26 - (void) dealloc {
    27 	[titleAttributes release];
    28 	[textAttributes  release];
    29 	[backgroundColor release];
    30 	[textColor       release];
    31 	[icon            release];
    32 	[title           release];
    33 	[text            release];
    34 	[cache           release];
    35 	if (layer)
    36 		CGLayerRelease(layer);
    37 
    38 	[super dealloc];
    39 }
    40 
    41 - (void) drawRect:(NSRect)rect {
    42 	//Make sure that we don't draw in the main thread
    43 	//if ([super dispatchDrawingToThread:rect]) {
    44 		NSGraphicsContext *context = [NSGraphicsContext currentContext];
    45 		CGContextRef cgContext = [context graphicsPort];
    46 		NSRect bounds = [self bounds];
    47 		if (needsDisplay) {
    48 			// rects and sizes
    49 			int sizePref = 0;
    50 			READ_GROWL_PREF_INT(MUSICVIDEO_SIZE_PREF, GrowlMusicVideoPrefDomain, &sizePref);
    51 			NSRect titleRect, textRect;
    52 			NSRect iconRect;
    53 
    54 			if (sizePref == MUSICVIDEO_SIZE_HUGE) {
    55 				titleRect.origin.x = 192.0;
    56 				titleRect.origin.y = NSHeight(bounds) - 72.0;
    57 				titleRect.size.width = NSWidth(bounds) - 192.0 - 32.0;
    58 				titleRect.size.height = 40.0;
    59 				textRect.origin.y = NSHeight(bounds) - 176.0;
    60 				textRect.size.height = 96.0;
    61 				iconRect.origin.x = 32.0;
    62 				iconRect.origin.y = NSHeight(bounds) - 160.0;
    63 				iconRect.size.width = 128.0;
    64 				iconRect.size.height = 128.0;
    65 			} else {
    66 				titleRect.origin.x = 96.0;
    67 				titleRect.origin.y = NSHeight(bounds) - 36.0;
    68 				titleRect.size.width = NSWidth(bounds) - 96.0 - 16.0;
    69 				titleRect.size.height = 25.0;
    70 				textRect.origin.y = NSHeight(bounds) - 88.0,
    71 					textRect.size.height = 48.0;
    72 				iconRect.origin.x = 8.0;
    73 				iconRect.origin.y = NSHeight(bounds) - 88.0;
    74 				iconRect.size.width = 80.0;
    75 				iconRect.size.height = 80.0;
    76 			}
    77 			textRect.origin.x = titleRect.origin.x;
    78 			textRect.size.width = titleRect.size.width;
    79 
    80 			//draw to cache
    81 			if (CGLayerCreateWithContext) {
    82 				if (!layer)
    83 					layer = CGLayerCreateWithContext(cgContext, CGSizeMake(bounds.size.width, bounds.size.height), NULL);
    84 				[NSGraphicsContext setCurrentContext:
    85 					[NSGraphicsContext graphicsContextWithGraphicsPort:CGLayerGetContext(layer) flipped:NO]];
    86 			} else {
    87 				[cache lockFocus];
    88 			}
    89 
    90 			[backgroundColor set];
    91 			bounds.origin = NSZeroPoint;
    92 			NSRectFill(bounds);
    93 
    94 			[title drawInRect:titleRect withAttributes:titleAttributes];
    95 
    96 			[text drawInRect:textRect withAttributes:textAttributes];
    97 
    98 			[icon setFlipped:NO];
    99 			[icon drawScaledInRect:iconRect operation:NSCompositeSourceOver fraction:1.0];
   100 
   101 			if (CGLayerCreateWithContext)
   102 				[NSGraphicsContext setCurrentContext:context];
   103 			else
   104 				[cache unlockFocus];
   105 
   106 			needsDisplay = NO;
   107 		}
   108 
   109 		// draw background
   110 		[[NSColor clearColor] set];
   111 		NSRectFill(rect);
   112 
   113 		// draw cache to screen
   114 		NSRect imageRect = rect;
   115 		int effect = MUSICVIDEO_EFFECT_SLIDE;
   116 		READ_GROWL_PREF_INT(MUSICVIDEO_EFFECT_PREF, GrowlMusicVideoPrefDomain, &effect);
   117 		if (effect == MUSICVIDEO_EFFECT_SLIDE) {
   118 			if (CGLayerCreateWithContext)
   119 				imageRect.origin.y = 0.0;
   120 		} else if (effect == MUSICVIDEO_EFFECT_WIPE) {
   121 			rect.size.height -= imageRect.origin.y;
   122 			imageRect.size.height -= imageRect.origin.y;
   123 			if (!CGLayerCreateWithContext)
   124 				imageRect.origin.y = 0.0;
   125 		} else if (effect == MUSICVIDEO_EFFECT_FADING) {
   126 			if (CGLayerCreateWithContext)
   127 				imageRect.origin.y = 0.0;		
   128 		}
   129 
   130 		if (CGLayerCreateWithContext) {
   131 			CGRect cgRect;
   132 			cgRect.origin.x = imageRect.origin.x;
   133 			cgRect.origin.y = imageRect.origin.y;
   134 			cgRect.size.width = rect.size.width;
   135 			if (effect == MUSICVIDEO_EFFECT_WIPE) {
   136 				cgRect.size.height = rect.size.height;
   137 				CGContextClipToRect(cgContext, cgRect);
   138 			}
   139 			cgRect.size.height = bounds.size.height;
   140 			CGContextDrawLayerInRect(cgContext, cgRect, layer);
   141 		} else {
   142 			[cache drawInRect:rect fromRect:imageRect operation:NSCompositeSourceOver fraction:1.0];
   143 		}
   144 	//}
   145 }
   146 
   147 - (void) setIcon:(NSImage *)anIcon {
   148 	[icon autorelease];
   149 	icon = [anIcon retain];
   150 	[self setNeedsDisplay:(needsDisplay = YES)];
   151 }
   152 
   153 - (void) setTitle:(NSString *)aTitle {
   154 	[title autorelease];
   155 	title = [aTitle copy];
   156 	[self setNeedsDisplay:(needsDisplay = YES)];
   157 }
   158 
   159 - (void) setText:(NSString *)aText {
   160 	[text autorelease];
   161 	text = [aText copy];
   162 	[self setNeedsDisplay:(needsDisplay = YES)];
   163 }
   164 
   165 - (void) setPriority:(int)priority {
   166 	NSString *key;
   167 	NSString *textKey;
   168 	switch (priority) {
   169 		case -2:
   170 			key = GrowlMusicVideoVeryLowBackgroundColor;
   171 			textKey = GrowlMusicVideoVeryLowTextColor;
   172 			break;
   173 		case -1:
   174 			key = GrowlMusicVideoModerateBackgroundColor;
   175 			textKey = GrowlMusicVideoModerateTextColor;
   176 			break;
   177 		case 1:
   178 			key = GrowlMusicVideoHighBackgroundColor;
   179 			textKey = GrowlMusicVideoHighTextColor;
   180 			break;
   181 		case 2:
   182 			key = GrowlMusicVideoEmergencyBackgroundColor;
   183 			textKey = GrowlMusicVideoEmergencyTextColor;
   184 			break;
   185 		case 0:
   186 		default:
   187 			key = GrowlMusicVideoNormalBackgroundColor;
   188 			textKey = GrowlMusicVideoNormalTextColor;
   189 			break;
   190 	}
   191 
   192 	[backgroundColor release];
   193 
   194 	CGFloat opacityPref = MUSICVIDEO_DEFAULT_OPACITY;
   195 	READ_GROWL_PREF_FLOAT(MUSICVIDEO_OPACITY_PREF, GrowlMusicVideoPrefDomain, &opacityPref);
   196 	CGFloat alpha = opacityPref * 0.01;
   197 
   198 	Class NSDataClass = [NSData class];
   199 	NSData *data = nil;
   200 
   201 	READ_GROWL_PREF_VALUE(key, GrowlMusicVideoPrefDomain, NSData *, &data);
   202 	if(data)
   203 		CFMakeCollectable(data);
   204 	if (data && [data isKindOfClass:NSDataClass])
   205 		backgroundColor = [NSUnarchiver unarchiveObjectWithData:data];
   206 	else
   207 		backgroundColor = [NSColor blackColor];
   208 	backgroundColor = [[backgroundColor colorWithAlphaComponent:alpha] retain];
   209 	[data release];
   210 	data = nil;
   211 
   212 	[textColor release];
   213 	READ_GROWL_PREF_VALUE(textKey, GrowlMusicVideoPrefDomain, NSData *, &data);
   214 	if(data)
   215 		CFMakeCollectable(data);
   216 	if (data && [data isKindOfClass:NSDataClass])
   217 		textColor = [NSUnarchiver unarchiveObjectWithData:data];
   218 	else
   219 		textColor = [NSColor whiteColor];
   220 	[textColor retain];
   221 	[data release];
   222 
   223 	CGFloat titleFontSize;
   224 	CGFloat textFontSize;
   225 	int sizePref = 0;
   226 	READ_GROWL_PREF_INT(MUSICVIDEO_SIZE_PREF, GrowlMusicVideoPrefDomain, &sizePref);
   227 
   228 	if (sizePref == MUSICVIDEO_SIZE_HUGE) {
   229 		titleFontSize = 32.0;
   230 		textFontSize = 20.0;
   231 	} else {
   232 		titleFontSize = 16.0;
   233 		textFontSize = 12.0;
   234 	}
   235 
   236 	NSShadow *textShadow = [[NSShadow alloc] init];
   237 
   238 	NSSize shadowSize = {0.0, -2.0};
   239 	[textShadow setShadowOffset:shadowSize];
   240 	[textShadow setShadowBlurRadius:3.0];
   241 	[textShadow setShadowColor:[NSColor blackColor]];
   242 
   243 	NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
   244 	[paragraphStyle setAlignment:NSLeftTextAlignment];
   245 	[paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail];
   246 	[titleAttributes release];
   247 	titleAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
   248 		textColor,                                   NSForegroundColorAttributeName,
   249 		paragraphStyle,                              NSParagraphStyleAttributeName,
   250 		[NSFont boldSystemFontOfSize:titleFontSize], NSFontAttributeName,
   251 		textShadow,                                  NSShadowAttributeName,
   252 		nil];
   253 	[paragraphStyle release];
   254 
   255 	paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
   256 	[paragraphStyle setAlignment:NSLeftTextAlignment];
   257 	[textAttributes release];
   258 	textAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
   259 		textColor,                               NSForegroundColorAttributeName,
   260 		paragraphStyle,                          NSParagraphStyleAttributeName,
   261 		[NSFont messageFontOfSize:textFontSize], NSFontAttributeName,
   262 		textShadow,                              NSShadowAttributeName,
   263 		nil];
   264 	[paragraphStyle release];
   265 	[textShadow release];
   266 }
   267 
   268 - (id) target {
   269 	return target;
   270 }
   271 
   272 - (void) setTarget:(id) object {
   273 	target = object;
   274 }
   275 
   276 #pragma mark -
   277 
   278 - (SEL) action {
   279 	return action;
   280 }
   281 
   282 - (void) setAction:(SEL) selector {
   283 	action = selector;
   284 }
   285 
   286 
   287 - (BOOL) showsCloseBox {
   288     return NO;
   289 }
   290 #pragma mark -
   291 
   292 - (BOOL) needsDisplay {
   293 	return needsDisplay && [super needsDisplay];
   294 }
   295 
   296 @end