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"
36 /*****************************************************************************
37 * NSAnimation (VLCAdditions)
39 * Missing extension to NSAnimation
40 *****************************************************************************/
42 @implementation NSAnimation (VLCAdditions)
43 /* fake class attributes */
44 static NSMapTable *VLCAdditions_userInfo = NULL;
48 /* init our fake object attribute */
49 VLCAdditions_userInfo = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 16);
54 NSMapRemove(VLCAdditions_userInfo, self);
58 - (void)setUserInfo: (void *)userInfo
60 NSMapInsert(VLCAdditions_userInfo, self, (void*)userInfo);
65 return NSMapGet(VLCAdditions_userInfo, self);
69 /*****************************************************************************
70 * NSScreen (VLCAdditions)
72 * Missing extension to NSScreen
73 *****************************************************************************/
75 @implementation NSScreen (VLCAdditions)
77 static NSMutableArray *blackoutWindows = NULL;
81 /* init our fake object attribute */
82 blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
85 + (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
87 NSUInteger count = [[NSScreen screens] count];
89 for( NSUInteger i = 0; i < count; i++ )
91 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
92 if([screen displayID] == displayID)
100 return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
103 - (BOOL)isScreen: (NSScreen*)screen
105 return ([self displayID] == [screen displayID]);
108 - (CGDirectDisplayID)displayID
110 return (CGDirectDisplayID)[[[self deviceDescription] objectForKey: @"NSScreenNumber"] intValue];
113 - (void)blackoutOtherScreens
115 /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
116 [blackoutWindows makeObjectsPerformSelector:@selector(close)];
117 [blackoutWindows removeAllObjects];
119 NSUInteger screenCount = [[NSScreen screens] count];
120 for(NSUInteger i = 0; i < screenCount; i++)
122 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
123 VLCWindow *blackoutWindow;
126 if([self isScreen: screen])
129 screen_rect = [screen frame];
130 screen_rect.origin.x = screen_rect.origin.y = 0;
132 /* blackoutWindow alloc strategy
133 - The NSMutableArray blackoutWindows has the blackoutWindow references
134 - blackoutOtherDisplays is responsible for alloc/releasing its Windows
136 blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
137 backing: NSBackingStoreBuffered defer: NO screen: screen];
138 [blackoutWindow setBackgroundColor:[NSColor blackColor]];
139 [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
141 [blackoutWindow displayIfNeeded];
142 [blackoutWindow orderFront: self animate: YES];
144 [blackoutWindows addObject: blackoutWindow];
145 [blackoutWindow release];
147 if( [screen isMainScreen] )
150 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
152 [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
157 + (void)unblackoutScreens
159 NSUInteger blackoutWindowCount = [blackoutWindows count];
161 for(NSUInteger i = 0; i < blackoutWindowCount; i++)
163 VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
164 [blackoutWindow closeAndAnimate: YES];
168 SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
170 [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
175 /*****************************************************************************
178 * Missing extension to NSWindow
179 *****************************************************************************/
181 @implementation VLCWindow
182 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
183 backing:(NSBackingStoreType)backingType defer:(BOOL)flag
185 self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
189 b_isset_canBecomeKeyWindow = NO;
190 /* we don't want this window to be restored on relaunch */
192 [self setRestorable:NO];
196 - (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
198 b_isset_canBecomeKeyWindow = YES;
199 b_canBecomeKeyWindow = canBecomeKey;
202 - (BOOL)canBecomeKeyWindow
204 if(b_isset_canBecomeKeyWindow)
205 return b_canBecomeKeyWindow;
207 return [super canBecomeKeyWindow];
210 - (void)closeAndAnimate: (BOOL)animate
220 invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
221 [invoc setTarget: self];
223 if (![self isVisible] || [self alphaValue] == 0.0)
229 [self orderOut: self animate: YES callback: invoc];
232 - (void)orderOut: (id)sender animate: (BOOL)animate
234 NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
235 [invoc setTarget: self];
236 [invoc setArgument: sender atIndex: 0];
237 [self orderOut: sender animate: animate callback: invoc];
240 - (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
242 NSViewAnimation *anim;
243 NSViewAnimation *current_anim;
244 NSMutableDictionary *dict;
248 [self orderOut: sender];
252 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
254 [dict setObject:self forKey:NSViewAnimationTargetKey];
256 [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
257 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
260 [anim setAnimationBlockingMode:NSAnimationNonblocking];
261 [anim setDuration:0.9];
262 [anim setFrameRate:30];
263 [anim setUserInfo: callback];
265 @synchronized(self) {
266 current_anim = self->animation;
268 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating])
276 [current_anim stopAnimation];
277 [anim setCurrentProgress:1.0-[current_anim currentProgress]];
278 [current_anim release];
281 [anim setCurrentProgress:1.0 - [self alphaValue]];
282 self->animation = anim;
283 [self setDelegate: self];
284 [anim startAnimation];
289 - (void)orderFront: (id)sender animate: (BOOL)animate
291 NSViewAnimation *anim;
292 NSViewAnimation *current_anim;
293 NSMutableDictionary *dict;
297 [super orderFront: sender];
298 [self setAlphaValue: 1.0];
302 if (![self isVisible])
304 [self setAlphaValue: 0.0];
305 [super orderFront: sender];
307 else if ([self alphaValue] == 1.0)
309 [super orderFront: self];
313 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
315 [dict setObject:self forKey:NSViewAnimationTargetKey];
317 [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
318 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
321 [anim setAnimationBlockingMode:NSAnimationNonblocking];
322 [anim setDuration:0.5];
323 [anim setFrameRate:30];
325 @synchronized(self) {
326 current_anim = self->animation;
328 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating])
336 [current_anim stopAnimation];
337 [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
338 [current_anim release];
341 [anim setCurrentProgress:[self alphaValue]];
342 self->animation = anim;
343 [self setDelegate: self];
344 [self orderFront: sender];
345 [anim startAnimation];
350 - (void)animationDidEnd:(NSAnimation*)anim
352 if ([self alphaValue] <= 0.0)
354 NSInvocation * invoc;
355 [super orderOut: nil];
356 [self setAlphaValue: 1.0];
357 if ((invoc = [anim userInfo]))
362 - (void)setFullscreen:(BOOL)b_var
364 b_isFullscreen = b_var;
369 return b_isFullscreen;
374 /*****************************************************************************
376 *****************************************************************************/
378 @implementation VLCControllerView
382 [self unregisterDraggedTypes];
388 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
389 NSFilenamesPboardType, nil]];
392 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
394 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
395 == NSDragOperationGeneric)
397 return NSDragOperationGeneric;
401 return NSDragOperationNone;
405 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
410 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
412 NSPasteboard *o_paste = [sender draggingPasteboard];
413 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
414 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
415 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
419 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
421 NSArray *o_array = [NSArray array];
422 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
423 NSUInteger count = [o_values count];
425 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
426 BOOL b_returned = NO;
428 if (count == 1 && p_input)
430 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
431 vlc_object_release( p_input );
436 vlc_object_release( p_input );
438 for( NSUInteger i = 0; i < count; i++)
441 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
445 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
448 o_array = [o_array arrayByAddingObject: o_dic];
450 [(VLCPlaylist *)[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
454 [self setNeedsDisplay:YES];
458 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
460 [self setNeedsDisplay:YES];
465 /*****************************************************************************
466 * VLBrushedMetalImageView
467 *****************************************************************************/
469 @implementation VLBrushedMetalImageView
471 - (BOOL)mouseDownCanMoveWindow
478 [self unregisterDraggedTypes];
484 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
485 NSFilenamesPboardType, nil]];
486 [self setImageScaling: NSScaleToFit];
487 [self setImageFrameStyle: NSImageFrameNone];
488 [self setImageAlignment: NSImageAlignCenter];
491 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
493 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
494 == NSDragOperationGeneric)
496 return NSDragOperationGeneric;
500 return NSDragOperationNone;
504 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
509 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
511 NSPasteboard *o_paste = [sender draggingPasteboard];
512 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
513 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
514 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
515 BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
519 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
521 NSArray *o_array = [NSArray array];
522 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
523 NSUInteger count = [o_values count];
525 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
526 BOOL b_returned = NO;
528 if (count == 1 && p_input)
530 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
531 vlc_object_release( p_input );
536 vlc_object_release( p_input );
538 for( NSUInteger i = 0; i < count; i++)
541 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
545 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
548 o_array = [o_array arrayByAddingObject: o_dic];
551 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
553 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
557 [self setNeedsDisplay:YES];
561 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
563 [self setNeedsDisplay:YES];
569 /*****************************************************************************
571 *****************************************************************************/
572 @implementation MPSlider
574 void _drawKnobInRect(NSRect knobRect)
576 // Center knob in given rect
577 knobRect.origin.x += (int)((float)(knobRect.size.width - 7)/2.0);
578 knobRect.origin.y += (int)((float)(knobRect.size.height - 7)/2.0);
581 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 6, 1, 1), NSCompositeSourceOver);
582 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 5, 3, 1), NSCompositeSourceOver);
583 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 4, 5, 1), NSCompositeSourceOver);
584 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 0, knobRect.origin.y + 3, 7, 1), NSCompositeSourceOver);
585 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 2, 5, 1), NSCompositeSourceOver);
586 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 1, 3, 1), NSCompositeSourceOver);
587 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 0, 1, 1), NSCompositeSourceOver);
590 void _drawFrameInRect(NSRect frameRect)
593 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, 1), NSCompositeSourceOver);
594 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y + frameRect.size.height-1, frameRect.size.width, 1), NSCompositeSourceOver);
595 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
596 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x+frameRect.size.width-1, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
599 - (void)drawRect:(NSRect)rect
601 // Draw default to make sure the slider behaves correctly
602 [[NSGraphicsContext currentContext] saveGraphicsState];
603 NSRectClip(NSZeroRect);
604 [super drawRect:rect];
605 [[NSGraphicsContext currentContext] restoreGraphicsState];
608 rect = [self bounds];
609 int diff = (int)(([[self cell] knobThickness] - 7.0)/2.0) - 1;
610 rect.origin.x += diff-1;
611 rect.origin.y += diff;
612 rect.size.width -= 2*diff-2;
613 rect.size.height -= 2*diff;
616 NSRect knobRect = [[self cell] knobRectFlipped:NO];
617 [[[NSColor blackColor] colorWithAlphaComponent:0.6] set];
618 _drawFrameInRect(rect);
619 _drawKnobInRect(knobRect);
622 [[[NSColor blackColor] colorWithAlphaComponent:0.1] set];
627 _drawFrameInRect(rect);
628 _drawKnobInRect(knobRect);
633 /*****************************************************************************
635 *****************************************************************************/
637 @implementation TimeLineSlider
641 if (config_GetInt( VLCIntf, "macosx-interfacestyle" ))
642 o_knob_img = [NSImage imageNamed:@"progression-knob_dark"];
644 o_knob_img = [NSImage imageNamed:@"progression-knob"];
645 img_rect.size = [o_knob_img size];
646 img_rect.origin.x = img_rect.origin.y = 0;
651 [o_knob_img release];
655 - (CGFloat)knobPosition
657 NSRect knobRect = [[self cell] knobRectFlipped:NO];
658 knobRect.origin.x += knobRect.size.width / 2;
659 return knobRect.origin.x;
662 - (void)drawKnobInRect:(NSRect)knobRect
664 knobRect.origin.x += (knobRect.size.width - img_rect.size.width) / 2;
665 knobRect.size.width = img_rect.size.width;
666 knobRect.size.height = img_rect.size.height;
667 [o_knob_img drawInRect:knobRect fromRect:img_rect operation:NSCompositeSourceOver fraction:1];
670 - (void)drawRect:(NSRect)rect
672 [(VLCMainWindow *)[self window] drawFancyGradientEffectForTimeSlider];
673 msleep( 10000 ); //wait for the gradient to draw completely
675 /* Draw default to make sure the slider behaves correctly */
676 [[NSGraphicsContext currentContext] saveGraphicsState];
677 NSRectClip(NSZeroRect);
678 [super drawRect:rect];
679 [[NSGraphicsContext currentContext] restoreGraphicsState];
681 NSRect knobRect = [[self cell] knobRectFlipped:NO];
682 knobRect.origin.y+=1;
683 [self drawKnobInRect: knobRect];
688 /*****************************************************************************
690 *****************************************************************************/
692 @implementation ITSlider
696 BOOL b_dark = config_GetInt( VLCIntf, "macosx-interfacestyle" );
698 img = [NSImage imageNamed:@"volume-slider-knob_dark"];
700 img = [NSImage imageNamed:@"volume-slider-knob"];
702 image_rect.size = [img size];
703 image_rect.origin.x = 0;
706 image_rect.origin.y = -1;
708 image_rect.origin.y = 0;
711 - (void)drawKnobInRect:(NSRect)knobRect
713 knobRect.origin.x += (knobRect.size.width - image_rect.size.width) / 2;
714 knobRect.size.width = image_rect.size.width;
715 knobRect.size.height = image_rect.size.height;
716 [img drawInRect:knobRect fromRect:image_rect operation:NSCompositeSourceOver fraction:1];
719 - (void)drawRect:(NSRect)rect
721 /* Draw default to make sure the slider behaves correctly */
722 [[NSGraphicsContext currentContext] saveGraphicsState];
723 NSRectClip(NSZeroRect);
724 [super drawRect:rect];
725 [[NSGraphicsContext currentContext] restoreGraphicsState];
727 NSRect knobRect = [[self cell] knobRectFlipped:NO];
728 knobRect.origin.y+=2;
729 [self drawKnobInRect: knobRect];
734 /*****************************************************************************
735 * VLCTimeField implementation
736 *****************************************************************************
737 * we need this to catch our click-event in the controller window
738 *****************************************************************************/
740 @implementation VLCTimeField
742 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
743 NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
745 [defaults registerDefaults:appDefaults];
750 NSColor *o_string_color;
751 if (!config_GetInt( VLCIntf, "macosx-interfacestyle"))
752 o_string_color = [NSColor colorWithCalibratedRed:0.229 green:0.229 blue:0.229 alpha:100.0];
754 o_string_color = [NSColor colorWithCalibratedRed:0.64 green:0.64 blue:0.64 alpha:100.0];
756 textAlignment = NSCenterTextAlignment;
757 o_string_attributes_dict = [[NSDictionary dictionaryWithObjectsAndKeys: o_string_color, NSForegroundColorAttributeName, [NSFont titleBarFontOfSize:10.0], NSFontAttributeName, nil] retain];
760 - (void)setAlignment:(NSTextAlignment)alignment
762 textAlignment = alignment;
763 [self setStringValue:[self stringValue]];
768 [o_string_shadow release];
769 [o_string_attributes_dict release];
773 - (void)setStringValue:(NSString *)string
775 if (!o_string_shadow)
777 o_string_shadow = [[NSShadow alloc] init];
778 [o_string_shadow setShadowColor: [NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
779 [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.5)];
780 [o_string_shadow setShadowBlurRadius:0.0];
783 NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: o_string_attributes_dict];
784 NSUInteger i_stringLength = [string length];
786 [o_attributed_string addAttribute: NSShadowAttributeName value: o_string_shadow range: NSMakeRange(0, i_stringLength)];
787 [o_attributed_string setAlignment: textAlignment range: NSMakeRange(0, i_stringLength)];
788 [self setAttributedStringValue: o_attributed_string];
789 [o_attributed_string release];
792 - (void)mouseDown: (NSEvent *)ourEvent
794 if( [ourEvent clickCount] > 1 )
795 [[[VLCMain sharedInstance] controls] goToSpecificTime: nil];
798 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"])
799 [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
801 [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"DisplayTimeAsTimeRemaining"];
805 - (BOOL)timeRemaining
807 return [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"];
811 /*****************************************************************************
812 * VLCMainWindowSplitView implementation
813 * comment 1 + 2 taken from NSSplitView.h (10.7 SDK)
814 *****************************************************************************/
815 @implementation VLCMainWindowSplitView : NSSplitView
816 /* 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.
818 - (NSColor *)dividerColor
820 return [NSColor colorWithCalibratedRed:.60 green:.60 blue:.60 alpha:1.];
823 /* 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.
825 - (CGFloat)dividerThickness
830 - (void)adjustSubviews
832 NSArray *o_subviews = [self subviews];
833 NSRect viewDimensions = [self frame];
834 NSRect leftViewDimensions = [[o_subviews objectAtIndex:0] frame];
835 NSRect rightViewDimensions = [[o_subviews objectAtIndex:1] frame];
836 CGFloat f_dividerThickness = [self dividerThickness];
838 leftViewDimensions.size.height = viewDimensions.size.height;
839 [[o_subviews objectAtIndex:0] setFrame: leftViewDimensions];
841 rightViewDimensions.origin.x = leftViewDimensions.size.width + f_dividerThickness;
842 rightViewDimensions.size.width = viewDimensions.size.width - leftViewDimensions.size.width - f_dividerThickness;
843 rightViewDimensions.size.height = viewDimensions.size.height;
844 [[o_subviews objectAtIndex:1] setFrame: rightViewDimensions];
848 /*****************************************************************************
849 * VLCThreePartImageView interface
850 *****************************************************************************/
851 @implementation VLCThreePartImageView
854 [o_left_img release];
855 [o_middle_img release];
856 [o_right_img release];
861 - (void)setImagesLeft:(NSImage *)left middle: (NSImage *)middle right:(NSImage *)right
864 [o_left_img release];
866 [o_middle_img release];
868 [o_right_img release];
870 o_left_img = [left retain];
871 o_middle_img = [middle retain];
872 o_right_img = [right retain];
875 - (void)drawRect:(NSRect)rect
877 NSRect bnds = [self bounds];
878 NSDrawThreePartImage( bnds, o_left_img, o_middle_img, o_right_img, NO, NSCompositeSourceOver, 1, NO );
883 @implementation VLCThreePartDropView
885 - (BOOL)mouseDownCanMoveWindow
892 [self unregisterDraggedTypes];
898 [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
899 NSFilenamesPboardType, nil]];
902 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
904 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
905 == NSDragOperationGeneric)
907 return NSDragOperationGeneric;
911 return NSDragOperationNone;
915 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
920 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
922 NSPasteboard *o_paste = [sender draggingPasteboard];
923 NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
924 NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
925 NSData *o_carried_data = [o_paste dataForType:o_desired_type];
926 BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
930 if ([o_desired_type isEqualToString:NSFilenamesPboardType])
932 NSArray *o_array = [NSArray array];
933 NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
934 NSUInteger count = [o_values count];
936 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
937 BOOL b_returned = NO;
939 if (count == 1 && p_input)
941 b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
942 vlc_object_release( p_input );
947 vlc_object_release( p_input );
949 for( NSUInteger i = 0; i < count; i++)
952 char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
956 o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
959 o_array = [o_array arrayByAddingObject: o_dic];
962 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
964 [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
968 [self setNeedsDisplay:YES];
972 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
974 [self setNeedsDisplay:YES];