1 /*****************************************************************************
2 * VLCAppAdditions.m: Helpful additions to NS* classes
3 *****************************************************************************
4 * Copyright (C) 2007 Pierre d'Herbemont
5 * Copyright (C) 2007 the VideoLAN team
8 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
9 * Felix Kühne <fkuehne at videolan dot org>
10 * Jérôme Decoodt <djc at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 #import "VLCAppAdditions.h"
28 #import <QuartzCore/QuartzCore.h>
30 @implementation NSIndexPath (VLCAppAddition)
31 - (NSIndexPath *)indexPathByRemovingFirstIndex
33 if( [self length] <= 1 )
34 return [[[NSIndexPath alloc] init] autorelease];
37 NSUInteger * ints = malloc(sizeof(NSUInteger)*[self length]);
38 if( !ints ) return nil;
39 [self getIndexes:ints];
41 ret = [NSIndexPath indexPathWithIndexes:ints+1 length:[self length]-1];
46 - (NSUInteger)lastIndex
50 return [self indexAtPosition:[self length]-1];
54 @implementation NSArray (VLCAppAddition)
55 - (id)objectAtIndexPath:(NSIndexPath *)path withNodeKeyPath:(NSString *)nodeKeyPath
57 if( ![path length] || !nodeKeyPath )
60 id object = [self objectAtIndex:[path indexAtPosition:0]];
61 id subarray = [object valueForKeyPath:nodeKeyPath];
62 if([path length] == 1)
63 return subarray ? subarray : object;
67 return [subarray objectAtIndexPath:[path indexPathByRemovingFirstIndex] withNodeKeyPath:nodeKeyPath];
71 @implementation NSView (VLCAppAdditions)
72 - (void)moveSubviewsToVisible
74 for(NSView * view in [self subviews])
76 if( ([view autoresizingMask] & NSViewHeightSizable) &&
77 !NSContainsRect([view frame], [self bounds]) )
79 NSRect newFrame = NSIntersectionRect( [self bounds], [view frame] );
80 if( !NSIsEmptyRect(newFrame) )
81 [view setFrame:NSIntersectionRect( [self bounds], [view frame] )];
87 /* Split view that supports slider animation */
88 @implementation VLCOneSplitView
89 - (CGFloat)dividerThickness
93 - (void)drawDividerInRect:(NSRect)aRect
96 [[NSColor blackColor] set];
100 - (float)sliderPosition
102 NSSize size = [[[self subviews] objectAtIndex:0] frame].size;
103 return [self isVertical] ? size.width : size.height;
105 - (void)setSliderPosition:(float)newPosition
107 [self setPosition:newPosition ofDividerAtIndex:0];
109 + (id)defaultAnimationForKey:(NSString *)key
111 if([key isEqualToString:@"sliderPosition"])
113 return [CABasicAnimation animation];
115 return [super defaultAnimationForKey: key];
119 /*****************************************************************************
120 * NSScreen (VLCAdditions)
122 * Missing extension to NSScreen
123 *****************************************************************************/
125 @implementation NSScreen (VLCAdditions)
127 static NSMutableArray *blackoutWindows = NULL;
131 /* init our fake object attribute */
132 blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
135 + (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
139 for( i = 0; i < [[NSScreen screens] count]; i++ )
141 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
142 if([screen displayID] == displayID)
150 return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
153 - (BOOL)isScreen: (NSScreen*)screen
155 return ([self displayID] == [screen displayID]);
158 - (CGDirectDisplayID)displayID
160 return (CGDirectDisplayID)_screenNumber;
163 - (void)blackoutOtherScreens
167 /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
168 [blackoutWindows makeObjectsPerformSelector:@selector(close)];
169 [blackoutWindows removeAllObjects];
172 for(i = 0; i < [[NSScreen screens] count]; i++)
174 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
175 VLCWindow *blackoutWindow;
178 if([self isScreen: screen])
181 screen_rect = [screen frame];
182 screen_rect.origin.x = screen_rect.origin.y = 0.0f;
184 /* blackoutWindow alloc strategy
185 - The NSMutableArray blackoutWindows has the blackoutWindow references
186 - blackoutOtherDisplays is responsible for alloc/releasing its Windows
188 blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
189 backing: NSBackingStoreBuffered defer: NO screen: screen];
190 [blackoutWindow setBackgroundColor:[NSColor blackColor]];
191 [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
193 [blackoutWindow orderFront: self];
195 [blackoutWindows addObject: blackoutWindow];
196 [blackoutWindow release];
200 + (void)unblackoutScreens
204 for(i = 0; i < [blackoutWindows count]; i++)
206 VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
207 [blackoutWindow close];
213 /*****************************************************************************
216 * Missing extension to NSWindow
217 *****************************************************************************/
219 @implementation VLCWindow
220 - (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask
221 backing:(NSBackingStoreType)backingType defer:(BOOL)flag
223 self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
225 isset_canBecomeKeyWindow = NO;
228 - (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
230 isset_canBecomeKeyWindow = YES;
231 canBecomeKeyWindow = canBecomeKey;
234 - (BOOL)canBecomeKeyWindow
236 if(isset_canBecomeKeyWindow)
237 return canBecomeKeyWindow;
239 return [super canBecomeKeyWindow];
243 /*****************************************************************************
244 * VLCImageCustomizedSlider
246 * Slider personalized by backgroundImage and knobImage
247 *****************************************************************************/
248 @implementation VLCImageCustomizedSlider
249 @synthesize backgroundImage;
250 @synthesize knobImage;
252 - (id)initWithFrame:(NSRect)frame
254 if(self = [super initWithFrame:frame])
257 backgroundImage = nil;
269 - (void)drawKnobInRect:(NSRect) knobRect
272 imageRect.size = [self.knobImage size];
273 imageRect.origin.x = 0;
274 imageRect.origin.y = 0;
275 knobRect.origin.x += (knobRect.size.width - imageRect.size.width) / 2;
276 knobRect.origin.y += (knobRect.size.width - imageRect.size.width) / 2;
277 knobRect.size.width = imageRect.size.width;
278 knobRect.size.height = imageRect.size.height;
279 [self.knobImage drawInRect:knobRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];
282 - (void)drawBackgroundInRect:(NSRect) drawRect
284 NSRect imageRect = drawRect;
285 imageRect.origin.y += ([self.backgroundImage size].height - [self bounds].size.height ) / 2;
286 [self.backgroundImage drawInRect:drawRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];
289 - (void)drawRect:(NSRect)rect
291 /* Draw default to make sure the slider behaves correctly */
292 [[NSGraphicsContext currentContext] saveGraphicsState];
293 NSRectClip(NSZeroRect);
294 [super drawRect:rect];
295 [[NSGraphicsContext currentContext] restoreGraphicsState];
296 if( self.backgroundImage )
297 [self drawBackgroundInRect: rect];
300 NSRect knobRect = [[self cell] knobRectFlipped:NO];
301 [[[NSColor blackColor] colorWithAlphaComponent:0.6] set];
302 [self drawKnobInRect: knobRect];
308 /*****************************************************************************
309 * NSImageView (VLCAppAdditions)
311 * Make the image view move the window by mouse down by default
312 *****************************************************************************/
314 @implementation NSImageView (VLCAppAdditions)
315 - (BOOL)mouseDownCanMoveWindow
321 /*****************************************************************************
322 * NSImage (VLCAppAdditions)
324 * Make the image view move the window by mouse down by default
325 *****************************************************************************/
327 @implementation NSImage (VLCAppAdditions)
328 - (CGImageRef)CGImage
330 return [[NSBitmapImageRep imageRepWithData:[NSBitmapImageRep TIFFRepresentationOfImageRepsInArray: [self representations]]] CGImage];