1 /*****************************************************************************
2 * misc.m: code not specific to vlc
3 *****************************************************************************
4 * Copyright (C) 2003-2011 VLC authors and VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Felix Paul Kühne <fkuehne at videolan dot org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #import <Cocoa/Cocoa.h>
26 #import <Carbon/Carbon.h>
28 #import "CompatibilityFixes.h"
29 #import "intf.h" /* VLCApplication */
30 #import "MainWindow.h"
34 #import "CoreInteraction.h"
37 /*****************************************************************************
38 * NSAnimation (VLCAdditions)
40 * Missing extension to NSAnimation
41 *****************************************************************************/
43 @implementation NSAnimation (VLCAdditions)
44 /* fake class attributes */
45 static NSMapTable *VLCAdditions_userInfo = NULL;
49 /* init our fake object attribute */
50 VLCAdditions_userInfo = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 16);
55 NSMapRemove(VLCAdditions_userInfo, self);
59 - (void)setUserInfo: (void *)userInfo
61 NSMapInsert(VLCAdditions_userInfo, self, (void*)userInfo);
66 return NSMapGet(VLCAdditions_userInfo, self);
70 /*****************************************************************************
71 * NSScreen (VLCAdditions)
73 * Missing extension to NSScreen
74 *****************************************************************************/
76 @implementation NSScreen (VLCAdditions)
78 static NSMutableArray *blackoutWindows = NULL;
82 /* init our fake object attribute */
83 blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
86 + (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
88 NSUInteger count = [[NSScreen screens] count];
90 for( NSUInteger i = 0; i < count; i++ )
92 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
93 if([screen displayID] == displayID)
101 return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
104 - (BOOL)isScreen: (NSScreen*)screen
106 return ([self displayID] == [screen displayID]);
109 - (CGDirectDisplayID)displayID
111 return (CGDirectDisplayID)[[[self deviceDescription] objectForKey: @"NSScreenNumber"] intValue];
114 - (void)blackoutOtherScreens
116 /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
117 [blackoutWindows makeObjectsPerformSelector:@selector(close)];
118 [blackoutWindows removeAllObjects];
120 NSUInteger screenCount = [[NSScreen screens] count];
121 for(NSUInteger i = 0; i < screenCount; i++)
123 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
124 VLCWindow *blackoutWindow;
127 if([self isScreen: screen])
130 screen_rect = [screen frame];
131 screen_rect.origin.x = screen_rect.origin.y = 0;
133 /* blackoutWindow alloc strategy
134 - The NSMutableArray blackoutWindows has the blackoutWindow references
135 - blackoutOtherDisplays is responsible for alloc/releasing its Windows
137 blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
138 backing: NSBackingStoreBuffered defer: NO screen: screen];
139 [blackoutWindow setBackgroundColor:[NSColor blackColor]];
140 [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
142 [blackoutWindow displayIfNeeded];
143 [blackoutWindow orderFront: self animate: YES];
145 [blackoutWindows addObject: blackoutWindow];
146 [blackoutWindow release];
148 if( [screen isMainScreen] )
151 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
153 [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
158 + (void)unblackoutScreens
160 NSUInteger blackoutWindowCount = [blackoutWindows count];
162 for(NSUInteger i = 0; i < blackoutWindowCount; i++)
164 VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
165 [blackoutWindow closeAndAnimate: YES];
169 SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
171 [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
176 /*****************************************************************************
179 * Missing extension to NSWindow
180 *****************************************************************************/
182 @implementation VLCWindow
183 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
184 backing:(NSBackingStoreType)backingType defer:(BOOL)flag
186 self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
190 b_isset_canBecomeKeyWindow = NO;
191 /* we don't want this window to be restored on relaunch */
193 [self setRestorable:NO];
197 - (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
199 b_isset_canBecomeKeyWindow = YES;
200 b_canBecomeKeyWindow = canBecomeKey;
203 - (BOOL)canBecomeKeyWindow
205 if(b_isset_canBecomeKeyWindow)
206 return b_canBecomeKeyWindow;
208 return [super canBecomeKeyWindow];
211 - (void)closeAndAnimate: (BOOL)animate
221 invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
222 [invoc setTarget: self];
224 if (![self isVisible] || [self alphaValue] == 0.0)
230 [self orderOut: self animate: YES callback: invoc];
233 - (void)orderOut: (id)sender animate: (BOOL)animate
235 NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
236 [invoc setTarget: self];
237 [invoc setArgument: sender atIndex: 0];
238 [self orderOut: sender animate: animate callback: invoc];
241 - (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
243 NSViewAnimation *anim;
244 NSViewAnimation *current_anim;
245 NSMutableDictionary *dict;
249 [self orderOut: sender];
253 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
255 [dict setObject:self forKey:NSViewAnimationTargetKey];
257 [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
258 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
261 [anim setAnimationBlockingMode:NSAnimationNonblocking];
262 [anim setDuration:0.9];
263 [anim setFrameRate:30];
264 [anim setUserInfo: callback];
266 @synchronized(self) {
267 current_anim = self->animation;
269 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating])
277 [current_anim stopAnimation];
278 [anim setCurrentProgress:1.0-[current_anim currentProgress]];
279 [current_anim release];
282 [anim setCurrentProgress:1.0 - [self alphaValue]];
283 self->animation = anim;
284 [self setDelegate: self];
285 [anim startAnimation];
290 - (void)orderFront: (id)sender animate: (BOOL)animate
292 NSViewAnimation *anim;
293 NSViewAnimation *current_anim;
294 NSMutableDictionary *dict;
298 [super orderFront: sender];
299 [self setAlphaValue: 1.0];
303 if (![self isVisible])
305 [self setAlphaValue: 0.0];
306 [super orderFront: sender];
308 else if ([self alphaValue] == 1.0)
310 [super orderFront: self];
314 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
316 [dict setObject:self forKey:NSViewAnimationTargetKey];
318 [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
319 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
322 [anim setAnimationBlockingMode:NSAnimationNonblocking];
323 [anim setDuration:0.5];
324 [anim setFrameRate:30];
326 @synchronized(self) {
327 current_anim = self->animation;
329 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating])
337 [current_anim stopAnimation];
338 [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
339 [current_anim release];
342 [anim setCurrentProgress:[self alphaValue]];
343 self->animation = anim;
344 [self setDelegate: self];
345 [self orderFront: sender];
346 [anim startAnimation];
351 - (void)animationDidEnd:(NSAnimation*)anim
353 if ([self alphaValue] <= 0.0)
355 NSInvocation * invoc;
356 [super orderOut: nil];
357 [self setAlphaValue: 1.0];
358 if ((invoc = [anim userInfo]))
363 - (void)setFullscreen:(BOOL)b_var
365 b_isFullscreen = b_var;
370 return b_isFullscreen;
373 - (IBAction)fullscreen:(id)sender
375 [[VLCCoreInteraction sharedInstance] toggleFullscreen];
380 /*****************************************************************************
382 *****************************************************************************/
384 @implementation VLCControllerView
388 [self unregisterDraggedTypes];
394 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
395 NSFilenamesPboardType, nil]];
398 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
400 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
401 == NSDragOperationGeneric)
403 return NSDragOperationGeneric;
407 return NSDragOperationNone;
411 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
416 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
418 NSPasteboard *o_paste = [sender draggingPasteboard];
419 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
420 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
421 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
425 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
427 NSArray *o_array = [NSArray array];
428 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
429 NSUInteger count = [o_values count];
431 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
432 BOOL b_returned = NO;
434 if (count == 1 && p_input)
436 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
437 vlc_object_release( p_input );
442 vlc_object_release( p_input );
444 for( NSUInteger i = 0; i < count; i++)
447 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
451 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
454 o_array = [o_array arrayByAddingObject: o_dic];
456 [(VLCPlaylist *)[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
460 [self setNeedsDisplay:YES];
464 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
466 [self setNeedsDisplay:YES];
471 /*****************************************************************************
472 * VLBrushedMetalImageView
473 *****************************************************************************/
475 @implementation VLBrushedMetalImageView
477 - (BOOL)mouseDownCanMoveWindow
484 [self unregisterDraggedTypes];
490 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
491 NSFilenamesPboardType, nil]];
492 [self setImageScaling: NSScaleToFit];
493 [self setImageFrameStyle: NSImageFrameNone];
494 [self setImageAlignment: NSImageAlignCenter];
497 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
499 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
500 == NSDragOperationGeneric)
502 return NSDragOperationGeneric;
506 return NSDragOperationNone;
510 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
515 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
517 NSPasteboard *o_paste = [sender draggingPasteboard];
518 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
519 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
520 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
521 BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
525 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
527 NSArray *o_array = [NSArray array];
528 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
529 NSUInteger count = [o_values count];
531 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
532 BOOL b_returned = NO;
534 if (count == 1 && p_input)
536 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
537 vlc_object_release( p_input );
542 vlc_object_release( p_input );
544 for( NSUInteger i = 0; i < count; i++)
547 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
551 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
554 o_array = [o_array arrayByAddingObject: o_dic];
557 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
559 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
563 [self setNeedsDisplay:YES];
567 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
569 [self setNeedsDisplay:YES];
575 /*****************************************************************************
577 *****************************************************************************/
578 @implementation MPSlider
580 void _drawKnobInRect(NSRect knobRect)
582 // Center knob in given rect
583 knobRect.origin.x += (int)((float)(knobRect.size.width - 7)/2.0);
584 knobRect.origin.y += (int)((float)(knobRect.size.height - 7)/2.0);
587 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 6, 1, 1), NSCompositeSourceOver);
588 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 5, 3, 1), NSCompositeSourceOver);
589 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 4, 5, 1), NSCompositeSourceOver);
590 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 0, knobRect.origin.y + 3, 7, 1), NSCompositeSourceOver);
591 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 2, 5, 1), NSCompositeSourceOver);
592 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 1, 3, 1), NSCompositeSourceOver);
593 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 0, 1, 1), NSCompositeSourceOver);
596 void _drawFrameInRect(NSRect frameRect)
599 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, 1), NSCompositeSourceOver);
600 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y + frameRect.size.height-1, frameRect.size.width, 1), NSCompositeSourceOver);
601 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
602 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x+frameRect.size.width-1, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
605 - (void)drawRect:(NSRect)rect
607 // Draw default to make sure the slider behaves correctly
608 [[NSGraphicsContext currentContext] saveGraphicsState];
609 NSRectClip(NSZeroRect);
610 [super drawRect:rect];
611 [[NSGraphicsContext currentContext] restoreGraphicsState];
614 rect = [self bounds];
615 int diff = (int)(([[self cell] knobThickness] - 7.0)/2.0) - 1;
616 rect.origin.x += diff-1;
617 rect.origin.y += diff;
618 rect.size.width -= 2*diff-2;
619 rect.size.height -= 2*diff;
622 NSRect knobRect = [[self cell] knobRectFlipped:NO];
623 [[[NSColor blackColor] colorWithAlphaComponent:0.6] set];
624 _drawFrameInRect(rect);
625 _drawKnobInRect(knobRect);
628 [[[NSColor blackColor] colorWithAlphaComponent:0.1] set];
633 _drawFrameInRect(rect);
634 _drawKnobInRect(knobRect);
639 /*****************************************************************************
641 *****************************************************************************/
643 @implementation TimeLineSlider
647 if (config_GetInt( VLCIntf, "macosx-interfacestyle" ))
648 o_knob_img = [NSImage imageNamed:@"progression-knob_dark"];
650 o_knob_img = [NSImage imageNamed:@"progression-knob"];
651 img_rect.size = [o_knob_img size];
652 img_rect.origin.x = img_rect.origin.y = 0;
657 [o_knob_img release];
661 - (CGFloat)knobPosition
663 NSRect knobRect = [[self cell] knobRectFlipped:NO];
664 knobRect.origin.x += knobRect.size.width / 2;
665 return knobRect.origin.x;
668 - (void)drawKnobInRect:(NSRect)knobRect
670 knobRect.origin.x += (knobRect.size.width - img_rect.size.width) / 2;
671 knobRect.size.width = img_rect.size.width;
672 knobRect.size.height = img_rect.size.height;
673 [o_knob_img drawInRect:knobRect fromRect:img_rect operation:NSCompositeSourceOver fraction:1];
676 - (void)drawRect:(NSRect)rect
678 [[[VLCMain sharedInstance] mainWindow] drawFancyGradientEffectForTimeSlider];
679 msleep( 10000 ); //wait for the gradient to draw completely
681 /* Draw default to make sure the slider behaves correctly */
682 [[NSGraphicsContext currentContext] saveGraphicsState];
683 NSRectClip(NSZeroRect);
684 [super drawRect:rect];
685 [[NSGraphicsContext currentContext] restoreGraphicsState];
687 NSRect knobRect = [[self cell] knobRectFlipped:NO];
688 knobRect.origin.y+=1;
689 [self drawKnobInRect: knobRect];
694 /*****************************************************************************
696 *****************************************************************************/
698 @implementation ITSlider
702 BOOL b_dark = config_GetInt( VLCIntf, "macosx-interfacestyle" );
704 img = [NSImage imageNamed:@"volume-slider-knob_dark"];
706 img = [NSImage imageNamed:@"volume-slider-knob"];
708 image_rect.size = [img size];
709 image_rect.origin.x = 0;
712 image_rect.origin.y = -1;
714 image_rect.origin.y = 0;
717 - (void)drawKnobInRect:(NSRect)knobRect
719 knobRect.origin.x += (knobRect.size.width - image_rect.size.width) / 2;
720 knobRect.size.width = image_rect.size.width;
721 knobRect.size.height = image_rect.size.height;
722 [img drawInRect:knobRect fromRect:image_rect operation:NSCompositeSourceOver fraction:1];
725 - (void)drawRect:(NSRect)rect
727 /* Draw default to make sure the slider behaves correctly */
728 [[NSGraphicsContext currentContext] saveGraphicsState];
729 NSRectClip(NSZeroRect);
730 [super drawRect:rect];
731 [[NSGraphicsContext currentContext] restoreGraphicsState];
733 NSRect knobRect = [[self cell] knobRectFlipped:NO];
734 knobRect.origin.y+=2;
735 [self drawKnobInRect: knobRect];
740 /*****************************************************************************
741 * VLCTimeField implementation
742 *****************************************************************************
743 * we need this to catch our click-event in the controller window
744 *****************************************************************************/
746 @implementation VLCTimeField
748 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
749 NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
751 [defaults registerDefaults:appDefaults];
756 NSColor *o_string_color;
757 if (!config_GetInt( VLCIntf, "macosx-interfacestyle"))
758 o_string_color = [NSColor colorWithCalibratedRed:0.229 green:0.229 blue:0.229 alpha:100.0];
760 o_string_color = [NSColor colorWithCalibratedRed:0.64 green:0.64 blue:0.64 alpha:100.0];
762 textAlignment = NSCenterTextAlignment;
763 o_string_attributes_dict = [[NSDictionary dictionaryWithObjectsAndKeys: o_string_color, NSForegroundColorAttributeName, [NSFont titleBarFontOfSize:10.0], NSFontAttributeName, nil] retain];
766 - (void)setAlignment:(NSTextAlignment)alignment
768 textAlignment = alignment;
769 [self setStringValue:[self stringValue]];
774 [o_string_shadow release];
775 [o_string_attributes_dict release];
779 - (void)setStringValue:(NSString *)string
781 if (!o_string_shadow)
783 o_string_shadow = [[NSShadow alloc] init];
784 [o_string_shadow setShadowColor: [NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
785 [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.5)];
786 [o_string_shadow setShadowBlurRadius:0.0];
789 NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: o_string_attributes_dict];
790 NSUInteger i_stringLength = [string length];
792 [o_attributed_string addAttribute: NSShadowAttributeName value: o_string_shadow range: NSMakeRange(0, i_stringLength)];
793 [o_attributed_string setAlignment: textAlignment range: NSMakeRange(0, i_stringLength)];
794 [self setAttributedStringValue: o_attributed_string];
795 [o_attributed_string release];
798 - (void)mouseDown: (NSEvent *)ourEvent
800 if( [ourEvent clickCount] > 1 )
801 [[[VLCMain sharedInstance] controls] goToSpecificTime: nil];
804 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"])
805 [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
807 [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"DisplayTimeAsTimeRemaining"];
811 - (BOOL)timeRemaining
813 return [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"];
817 /*****************************************************************************
818 * VLCMainWindowSplitView implementation
819 * comment 1 + 2 taken from NSSplitView.h (10.7 SDK)
820 *****************************************************************************/
821 @implementation VLCMainWindowSplitView : NSSplitView
822 /* Return the color of the dividers that the split view is drawing between subviews. The default implementation of this method returns [NSColor clearColor] for the thick divider style. It will also return [NSColor clearColor] for the thin divider style when the split view is in a textured window. All other thin dividers are drawn with a color that looks good between two white panes. You can override this method to change the color of dividers.
824 - (NSColor *)dividerColor
826 return [NSColor colorWithCalibratedRed:.60 green:.60 blue:.60 alpha:1.];
829 /* Return the thickness of the dividers that the split view is drawing between subviews. The default implementation returns a value that depends on the divider style. You can override this method to change the size of dividers.
831 - (CGFloat)dividerThickness
836 - (void)adjustSubviews
838 NSArray *o_subviews = [self subviews];
839 NSRect viewDimensions = [self frame];
840 NSRect leftViewDimensions = [[o_subviews objectAtIndex:0] frame];
841 NSRect rightViewDimensions = [[o_subviews objectAtIndex:1] frame];
842 CGFloat f_dividerThickness = [self dividerThickness];
844 leftViewDimensions.size.height = viewDimensions.size.height;
845 [[o_subviews objectAtIndex:0] setFrame: leftViewDimensions];
847 rightViewDimensions.origin.x = leftViewDimensions.size.width + f_dividerThickness;
848 rightViewDimensions.size.width = viewDimensions.size.width - leftViewDimensions.size.width - f_dividerThickness;
849 rightViewDimensions.size.height = viewDimensions.size.height;
850 [[o_subviews objectAtIndex:1] setFrame: rightViewDimensions];
854 /*****************************************************************************
855 * VLCThreePartImageView interface
856 *****************************************************************************/
857 @implementation VLCThreePartImageView
860 [o_left_img release];
861 [o_middle_img release];
862 [o_right_img release];
867 - (void)setImagesLeft:(NSImage *)left middle: (NSImage *)middle right:(NSImage *)right
870 [o_left_img release];
872 [o_middle_img release];
874 [o_right_img release];
876 o_left_img = [left retain];
877 o_middle_img = [middle retain];
878 o_right_img = [right retain];
881 - (void)drawRect:(NSRect)rect
883 NSRect bnds = [self bounds];
884 NSDrawThreePartImage( bnds, o_left_img, o_middle_img, o_right_img, NO, NSCompositeSourceOver, 1, NO );
889 @implementation VLCThreePartDropView
891 - (BOOL)mouseDownCanMoveWindow
898 [self unregisterDraggedTypes];
904 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
905 NSFilenamesPboardType, nil]];
908 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
910 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
911 == NSDragOperationGeneric)
913 return NSDragOperationGeneric;
917 return NSDragOperationNone;
921 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
926 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
928 NSPasteboard *o_paste = [sender draggingPasteboard];
929 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
930 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
931 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
932 BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
936 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
938 NSArray *o_array = [NSArray array];
939 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
940 NSUInteger count = [o_values count];
942 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
943 BOOL b_returned = NO;
945 if (count == 1 && p_input)
947 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
948 vlc_object_release( p_input );
953 vlc_object_release( p_input );
955 for( NSUInteger i = 0; i < count; i++)
958 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
962 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
965 o_array = [o_array arrayByAddingObject: o_dic];
968 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
970 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
974 [self setNeedsDisplay:YES];
978 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
980 [self setNeedsDisplay:YES];