1 /*****************************************************************************
2 * misc.m: code not specific to vlc
3 *****************************************************************************
4 * Copyright (C) 2003-2012 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 *****************************************************************************/
26 #import "intf.h" /* VLCApplication */
27 #import "MainWindow.h"
29 #import "CoreInteraction.h"
30 #import <CoreAudio/CoreAudio.h>
32 /*****************************************************************************
33 * NSSound (VLCAdditions)
35 * added code to change the system volume, needed for the apple remote code
36 * this is simplified code, which won't let you set the exact volume
37 * (that's what the audio output is for after all), but just the system volume
38 * in steps of 1/16 (matching the default AR or volume key implementation).
39 *****************************************************************************/
41 @implementation NSSound (VLCAdditions)
43 + (float)systemVolumeForChannel:(int)channel
45 AudioDeviceID i_device;
50 i_size = sizeof( i_device );
51 AudioObjectPropertyAddress deviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
52 err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &deviceAddress, 0, NULL, &i_size, &i_device );
55 msg_Warn( VLCIntf, "couldn't get main audio output device" );
59 AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, channel };
60 i_size = sizeof( f_volume );
61 err = AudioObjectGetPropertyData(i_device, &propertyAddress, 0, NULL, &i_size, &f_volume);
64 msg_Warn( VLCIntf, "couldn't get volume value" );
71 + (bool)setSystemVolume:(float)f_volume forChannel:(int)i_channel
73 /* the following code will fail on S/PDIF devices. there is an easy work-around, but we'd like to match the OS behavior */
75 AudioDeviceID i_device;
80 i_size = sizeof( i_device );
81 AudioObjectPropertyAddress deviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
82 err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &deviceAddress, 0, NULL, &i_size, &i_device );
85 msg_Warn( VLCIntf, "couldn't get main audio output device" );
89 AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, i_channel };
90 i_size = sizeof( f_volume );
91 err = AudioObjectIsPropertySettable( i_device, &propertyAddress, &b_writeable );
92 if (err != noErr || !b_writeable ) {
93 msg_Warn( VLCIntf, "we can't set the main audio devices' volume" );
96 err = AudioObjectSetPropertyData(i_device, &propertyAddress, 0, NULL, i_size, &f_volume);
101 + (void)increaseSystemVolume
103 float f_volume = [NSSound systemVolumeForChannel:1]; // we trust that mono is always available and that all channels got the same volume
104 f_volume += .0625; // 1/16 to match the OS
105 bool b_returned = YES;
107 /* since core audio doesn't provide a reasonable way to see how many channels we got, let's see how long we can do this */
108 for (NSUInteger x = 1; b_returned ; x++)
109 b_returned = [NSSound setSystemVolume: f_volume forChannel:x];
112 + (void)decreaseSystemVolume
114 float f_volume = [NSSound systemVolumeForChannel:1]; // we trust that mono is always available and that all channels got the same volume
115 f_volume -= .0625; // 1/16 to match the OS
116 bool b_returned = YES;
118 /* since core audio doesn't provide a reasonable way to see how many channels we got, let's see how long we can do this */
119 for (NSUInteger x = 1; b_returned ; x++)
120 b_returned = [NSSound setSystemVolume: f_volume forChannel:x];
125 /*****************************************************************************
126 * NSAnimation (VLCAdditions)
128 * Missing extension to NSAnimation
129 *****************************************************************************/
131 @implementation NSAnimation (VLCAdditions)
132 /* fake class attributes */
133 static NSMapTable *VLCAdditions_userInfo = NULL;
137 /* init our fake object attribute */
138 VLCAdditions_userInfo = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 16);
143 NSMapRemove(VLCAdditions_userInfo, self);
147 - (void)setUserInfo: (void *)userInfo
149 NSMapInsert(VLCAdditions_userInfo, self, (void*)userInfo);
154 return NSMapGet(VLCAdditions_userInfo, self);
158 /*****************************************************************************
159 * NSScreen (VLCAdditions)
161 * Missing extension to NSScreen
162 *****************************************************************************/
164 @implementation NSScreen (VLCAdditions)
166 static NSMutableArray *blackoutWindows = NULL;
170 /* init our fake object attribute */
171 blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
174 + (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
176 NSUInteger count = [[NSScreen screens] count];
178 for( NSUInteger i = 0; i < count; i++ )
180 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
181 if([screen displayID] == displayID)
189 return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
192 - (BOOL)isScreen: (NSScreen*)screen
194 return ([self displayID] == [screen displayID]);
197 - (CGDirectDisplayID)displayID
199 return (CGDirectDisplayID)[[[self deviceDescription] objectForKey: @"NSScreenNumber"] intValue];
202 - (void)blackoutOtherScreens
204 /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
205 [blackoutWindows makeObjectsPerformSelector:@selector(close)];
206 [blackoutWindows removeAllObjects];
208 NSUInteger screenCount = [[NSScreen screens] count];
209 for(NSUInteger i = 0; i < screenCount; i++)
211 NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
212 VLCWindow *blackoutWindow;
215 if([self isScreen: screen])
218 screen_rect = [screen frame];
219 screen_rect.origin.x = screen_rect.origin.y = 0;
221 /* blackoutWindow alloc strategy
222 - The NSMutableArray blackoutWindows has the blackoutWindow references
223 - blackoutOtherDisplays is responsible for alloc/releasing its Windows
225 blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
226 backing: NSBackingStoreBuffered defer: NO screen: screen];
227 [blackoutWindow setBackgroundColor:[NSColor blackColor]];
228 [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
230 [blackoutWindow displayIfNeeded];
231 [blackoutWindow orderFront: self animate: YES];
233 [blackoutWindows addObject: blackoutWindow];
234 [blackoutWindow release];
236 if( [screen isMainScreen] )
239 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
241 [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
246 + (void)unblackoutScreens
248 NSUInteger blackoutWindowCount = [blackoutWindows count];
250 for(NSUInteger i = 0; i < blackoutWindowCount; i++)
252 VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
253 [blackoutWindow closeAndAnimate: YES];
257 SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
259 [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
264 /*****************************************************************************
267 * Missing extension to NSWindow
268 *****************************************************************************/
270 @implementation VLCWindow
271 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
272 backing:(NSBackingStoreType)backingType defer:(BOOL)flag
274 self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
278 b_isset_canBecomeKeyWindow = NO;
279 /* we don't want this window to be restored on relaunch */
281 [self setRestorable:NO];
286 - (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
288 b_isset_canBecomeKeyWindow = YES;
289 b_canBecomeKeyWindow = canBecomeKey;
292 - (BOOL)canBecomeKeyWindow
294 if(b_isset_canBecomeKeyWindow)
295 return b_canBecomeKeyWindow;
297 return [super canBecomeKeyWindow];
300 - (void)setCanBecomeMainWindow: (BOOL)canBecomeMain
302 b_isset_canBecomeMainWindow = YES;
303 b_canBecomeMainWindow = canBecomeMain;
306 - (BOOL)canBecomeMainWindow
308 if(b_isset_canBecomeMainWindow)
309 return b_canBecomeMainWindow;
311 return [super canBecomeMainWindow];
314 - (void)closeAndAnimate: (BOOL)animate
324 invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
325 [invoc setTarget: self];
327 if (![self isVisible] || [self alphaValue] == 0.0)
333 [self orderOut: self animate: YES callback: invoc];
336 - (void)orderOut: (id)sender animate: (BOOL)animate
338 NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
339 [invoc setTarget: self];
340 [invoc setArgument: sender atIndex: 0];
341 [self orderOut: sender animate: animate callback: invoc];
344 - (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
346 NSViewAnimation *anim;
347 NSViewAnimation *current_anim;
348 NSMutableDictionary *dict;
352 [self orderOut: sender];
356 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
358 [dict setObject:self forKey:NSViewAnimationTargetKey];
360 [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
361 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
364 [anim setAnimationBlockingMode:NSAnimationNonblocking];
365 [anim setDuration:0.9];
366 [anim setFrameRate:30];
367 [anim setUserInfo: callback];
369 @synchronized(self) {
370 current_anim = self->animation;
372 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating])
380 [current_anim stopAnimation];
381 [anim setCurrentProgress:1.0-[current_anim currentProgress]];
382 [current_anim release];
385 [anim setCurrentProgress:1.0 - [self alphaValue]];
386 self->animation = anim;
387 [self setDelegate: self];
388 [anim startAnimation];
393 - (void)orderFront: (id)sender animate: (BOOL)animate
395 NSViewAnimation *anim;
396 NSViewAnimation *current_anim;
397 NSMutableDictionary *dict;
401 [super orderFront: sender];
402 [self setAlphaValue: 1.0];
406 if (![self isVisible])
408 [self setAlphaValue: 0.0];
409 [super orderFront: sender];
411 else if ([self alphaValue] == 1.0)
413 [super orderFront: self];
417 dict = [[NSMutableDictionary alloc] initWithCapacity:2];
419 [dict setObject:self forKey:NSViewAnimationTargetKey];
421 [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
422 anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
425 [anim setAnimationBlockingMode:NSAnimationNonblocking];
426 [anim setDuration:0.5];
427 [anim setFrameRate:30];
429 @synchronized(self) {
430 current_anim = self->animation;
432 if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating])
440 [current_anim stopAnimation];
441 [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
442 [current_anim release];
445 [anim setCurrentProgress:[self alphaValue]];
446 self->animation = anim;
447 [self setDelegate: self];
448 [self orderFront: sender];
449 [anim startAnimation];
454 - (void)animationDidEnd:(NSAnimation*)anim
456 if ([self alphaValue] <= 0.0)
458 NSInvocation * invoc;
459 [super orderOut: nil];
460 [self setAlphaValue: 1.0];
461 if ((invoc = [anim userInfo]))
466 - (void)setFullscreen:(BOOL)b_var
468 b_isFullscreen = b_var;
473 return b_isFullscreen;
476 - (IBAction)fullscreen:(id)sender
478 [[VLCCoreInteraction sharedInstance] toggleFullscreen];
483 /*****************************************************************************
484 * VLBrushedMetalImageView
485 *****************************************************************************/
487 @implementation VLBrushedMetalImageView
489 - (BOOL)mouseDownCanMoveWindow
496 [self unregisterDraggedTypes];
502 [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
503 [self setImageScaling: NSScaleToFit];
504 [self setImageFrameStyle: NSImageFrameNone];
505 [self setImageAlignment: NSImageAlignCenter];
508 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
510 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
511 return NSDragOperationGeneric;
513 return NSDragOperationNone;
516 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
521 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
524 b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];
526 [self setNeedsDisplay:YES];
530 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
532 [self setNeedsDisplay:YES];
538 /*****************************************************************************
540 *****************************************************************************/
541 @implementation MPSlider
543 void _drawKnobInRect(NSRect knobRect)
545 // Center knob in given rect
546 knobRect.origin.x += (int)((float)(knobRect.size.width - 7)/2.0);
547 knobRect.origin.y += (int)((float)(knobRect.size.height - 7)/2.0);
550 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 6, 1, 1), NSCompositeSourceOver);
551 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 5, 3, 1), NSCompositeSourceOver);
552 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 4, 5, 1), NSCompositeSourceOver);
553 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 0, knobRect.origin.y + 3, 7, 1), NSCompositeSourceOver);
554 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 1, knobRect.origin.y + 2, 5, 1), NSCompositeSourceOver);
555 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 2, knobRect.origin.y + 1, 3, 1), NSCompositeSourceOver);
556 NSRectFillUsingOperation(NSMakeRect(knobRect.origin.x + 3, knobRect.origin.y + 0, 1, 1), NSCompositeSourceOver);
559 void _drawFrameInRect(NSRect frameRect)
562 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, 1), NSCompositeSourceOver);
563 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y + frameRect.size.height-1, frameRect.size.width, 1), NSCompositeSourceOver);
564 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
565 NSRectFillUsingOperation(NSMakeRect(frameRect.origin.x+frameRect.size.width-1, frameRect.origin.y, 1, frameRect.size.height), NSCompositeSourceOver);
568 - (void)drawRect:(NSRect)rect
570 // Draw default to make sure the slider behaves correctly
571 [[NSGraphicsContext currentContext] saveGraphicsState];
572 NSRectClip(NSZeroRect);
573 [super drawRect:rect];
574 [[NSGraphicsContext currentContext] restoreGraphicsState];
577 rect = [self bounds];
578 int diff = (int)(([[self cell] knobThickness] - 7.0)/2.0) - 1;
579 rect.origin.x += diff-1;
580 rect.origin.y += diff;
581 rect.size.width -= 2*diff-2;
582 rect.size.height -= 2*diff;
585 NSRect knobRect = [[self cell] knobRectFlipped:NO];
586 [[[NSColor blackColor] colorWithAlphaComponent:0.6] set];
587 _drawFrameInRect(rect);
588 _drawKnobInRect(knobRect);
591 [[[NSColor blackColor] colorWithAlphaComponent:0.1] set];
596 _drawFrameInRect(rect);
597 _drawKnobInRect(knobRect);
602 /*****************************************************************************
604 *****************************************************************************/
606 @implementation TimeLineSlider
610 if (config_GetInt( VLCIntf, "macosx-interfacestyle" ))
611 o_knob_img = [NSImage imageNamed:@"progression-knob_dark"];
613 o_knob_img = [NSImage imageNamed:@"progression-knob"];
614 img_rect.size = [o_knob_img size];
615 img_rect.origin.x = img_rect.origin.y = 0;
620 [o_knob_img release];
624 - (CGFloat)knobPosition
626 NSRect knobRect = [[self cell] knobRectFlipped:NO];
627 knobRect.origin.x += knobRect.size.width / 2;
628 return knobRect.origin.x;
631 - (void)drawKnobInRect:(NSRect)knobRect
633 knobRect.origin.x += (knobRect.size.width - img_rect.size.width) / 2;
634 knobRect.size.width = img_rect.size.width;
635 knobRect.size.height = img_rect.size.height;
636 [o_knob_img drawInRect:knobRect fromRect:img_rect operation:NSCompositeSourceOver fraction:1];
639 - (void)drawRect:(NSRect)rect
641 [[[VLCMain sharedInstance] mainWindow] drawFancyGradientEffectForTimeSlider];
642 msleep( 10000 ); //wait for the gradient to draw completely
644 /* Draw default to make sure the slider behaves correctly */
645 [[NSGraphicsContext currentContext] saveGraphicsState];
646 NSRectClip(NSZeroRect);
647 [super drawRect:rect];
648 [[NSGraphicsContext currentContext] restoreGraphicsState];
650 NSRect knobRect = [[self cell] knobRectFlipped:NO];
651 knobRect.origin.y+=1;
652 [self drawKnobInRect: knobRect];
657 /*****************************************************************************
659 *****************************************************************************/
661 @implementation ITSlider
665 BOOL b_dark = config_GetInt( VLCIntf, "macosx-interfacestyle" );
667 img = [NSImage imageNamed:@"volume-slider-knob_dark"];
669 img = [NSImage imageNamed:@"volume-slider-knob"];
671 image_rect.size = [img size];
672 image_rect.origin.x = 0;
675 image_rect.origin.y = -1;
677 image_rect.origin.y = 0;
680 - (void)drawKnobInRect:(NSRect)knobRect
682 knobRect.origin.x += (knobRect.size.width - image_rect.size.width) / 2;
683 knobRect.size.width = image_rect.size.width;
684 knobRect.size.height = image_rect.size.height;
685 [img drawInRect:knobRect fromRect:image_rect operation:NSCompositeSourceOver fraction:1];
688 - (void)drawRect:(NSRect)rect
690 /* Draw default to make sure the slider behaves correctly */
691 [[NSGraphicsContext currentContext] saveGraphicsState];
692 NSRectClip(NSZeroRect);
693 [super drawRect:rect];
694 [[NSGraphicsContext currentContext] restoreGraphicsState];
696 NSRect knobRect = [[self cell] knobRectFlipped:NO];
697 knobRect.origin.y+=2;
698 [self drawKnobInRect: knobRect];
703 /*****************************************************************************
704 * VLCTimeField implementation
705 *****************************************************************************
706 * we need this to catch our click-event in the controller window
707 *****************************************************************************/
709 @implementation VLCTimeField
711 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
712 NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
714 [defaults registerDefaults:appDefaults];
719 NSColor *o_string_color;
720 if (!config_GetInt( VLCIntf, "macosx-interfacestyle"))
721 o_string_color = [NSColor colorWithCalibratedRed:0.229 green:0.229 blue:0.229 alpha:100.0];
723 o_string_color = [NSColor colorWithCalibratedRed:0.64 green:0.64 blue:0.64 alpha:100.0];
725 textAlignment = NSCenterTextAlignment;
726 o_string_attributes_dict = [[NSDictionary dictionaryWithObjectsAndKeys: o_string_color, NSForegroundColorAttributeName, [NSFont titleBarFontOfSize:10.0], NSFontAttributeName, nil] retain];
729 - (void)setAlignment:(NSTextAlignment)alignment
731 textAlignment = alignment;
732 [self setStringValue:[self stringValue]];
737 [o_string_shadow release];
738 [o_string_attributes_dict release];
742 - (void)setStringValue:(NSString *)string
744 if (!o_string_shadow)
746 o_string_shadow = [[NSShadow alloc] init];
747 [o_string_shadow setShadowColor: [NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
748 [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.5)];
749 [o_string_shadow setShadowBlurRadius:0.0];
752 NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: o_string_attributes_dict];
753 NSUInteger i_stringLength = [string length];
755 [o_attributed_string addAttribute: NSShadowAttributeName value: o_string_shadow range: NSMakeRange(0, i_stringLength)];
756 [o_attributed_string setAlignment: textAlignment range: NSMakeRange(0, i_stringLength)];
757 [self setAttributedStringValue: o_attributed_string];
758 [o_attributed_string release];
761 - (void)mouseDown: (NSEvent *)ourEvent
763 if( [ourEvent clickCount] > 1 )
764 [[[VLCMain sharedInstance] controls] goToSpecificTime: nil];
767 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"])
768 [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
770 [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"DisplayTimeAsTimeRemaining"];
774 - (BOOL)timeRemaining
776 return [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"];
780 /*****************************************************************************
781 * VLCMainWindowSplitView implementation
782 * comment 1 + 2 taken from NSSplitView.h (10.7 SDK)
783 *****************************************************************************/
784 @implementation VLCMainWindowSplitView : NSSplitView
785 /* 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.
787 - (NSColor *)dividerColor
789 return [NSColor colorWithCalibratedRed:.60 green:.60 blue:.60 alpha:1.];
792 /* 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.
794 - (CGFloat)dividerThickness
800 /*****************************************************************************
801 * VLCThreePartImageView interface
802 *****************************************************************************/
803 @implementation VLCThreePartImageView
806 [o_left_img release];
807 [o_middle_img release];
808 [o_right_img release];
813 - (void)setImagesLeft:(NSImage *)left middle: (NSImage *)middle right:(NSImage *)right
816 [o_left_img release];
818 [o_middle_img release];
820 [o_right_img release];
822 o_left_img = [left retain];
823 o_middle_img = [middle retain];
824 o_right_img = [right retain];
827 - (void)drawRect:(NSRect)rect
829 NSRect bnds = [self bounds];
830 NSDrawThreePartImage( bnds, o_left_img, o_middle_img, o_right_img, NO, NSCompositeSourceOver, 1, NO );
835 @implementation VLCThreePartDropView
837 - (BOOL)mouseDownCanMoveWindow
844 [self unregisterDraggedTypes];
850 [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
853 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
855 if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
856 return NSDragOperationGeneric;
858 return NSDragOperationNone;
861 - (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
866 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
869 b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];
871 [self setNeedsDisplay:YES];
875 - (void)concludeDragOperation:(id <NSDraggingInfo>)sender
877 [self setNeedsDisplay:YES];