/*****************************************************************************
* misc.m: code not specific to vlc
*****************************************************************************
- * Copyright (C) 2003-2012 VLC authors and VideoLAN
+ * Copyright (C) 2003-2014 VLC authors and VideoLAN
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#import "CompatibilityFixes.h"
#import "misc.h"
#import "intf.h" /* VLCApplication */
#import "MainWindow.h"
+#import "ControlsBar.h"
#import "controls.h"
#import "CoreInteraction.h"
#import <CoreAudio/CoreAudio.h>
+#import <vlc_keys.h>
+
/*****************************************************************************
* NSSound (VLCAdditions)
i_size = sizeof( i_device );
AudioObjectPropertyAddress deviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &deviceAddress, 0, NULL, &i_size, &i_device );
- if (err != noErr)
- {
+ if (err != noErr) {
msg_Warn( VLCIntf, "couldn't get main audio output device" );
return .0;
}
AudioObjectPropertyAddress propertyAddress = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, channel };
i_size = sizeof( f_volume );
err = AudioObjectGetPropertyData(i_device, &propertyAddress, 0, NULL, &i_size, &f_volume);
- if (err != noErr)
- {
+ if (err != noErr) {
msg_Warn( VLCIntf, "couldn't get volume value" );
return .0;
}
i_size = sizeof( i_device );
AudioObjectPropertyAddress deviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &deviceAddress, 0, NULL, &i_size, &i_device );
- if (err != noErr)
- {
+ if (err != noErr) {
msg_Warn( VLCIntf, "couldn't get main audio output device" );
return NO;
}
static NSMutableArray *blackoutWindows = NULL;
+static bool b_old_spaces_style = YES;
+
+ (void)load
{
/* init our fake object attribute */
blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
+
+ if (OSX_MAVERICKS || OSX_YOSEMITE) {
+ NSUserDefaults *userDefaults = [[NSUserDefaults alloc] init];
+ [userDefaults addSuiteNamed:@"com.apple.spaces"];
+ /* this is system settings -> mission control -> monitors using different spaces */
+ NSNumber *o_span_displays = [userDefaults objectForKey:@"spans-displays"];
+
+ b_old_spaces_style = [o_span_displays boolValue];
+ [userDefaults release];
+ }
}
+ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
{
NSUInteger count = [[NSScreen screens] count];
- for( NSUInteger i = 0; i < count; i++ )
- {
- NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
- if([screen displayID] == displayID)
+ for ( NSUInteger i = 0; i < count; i++ ) {
+ NSScreen *screen = [[NSScreen screens] objectAtIndex:i];
+ if ([screen displayID] == displayID)
return screen;
}
return nil;
}
-- (BOOL)isMainScreen
+- (BOOL)hasMenuBar
{
- return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
+ if (b_old_spaces_style)
+ return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
+ else
+ return YES;
+}
+
+- (BOOL)hasDock
+{
+ NSRect screen_frame = [self frame];
+ NSRect screen_visible_frame = [self visibleFrame];
+ CGFloat f_menu_bar_thickness = [self hasMenuBar] ? [[NSStatusBar systemStatusBar] thickness] : 0.0;
+
+ BOOL b_found_dock = NO;
+ if (screen_visible_frame.size.width < screen_frame.size.width)
+ b_found_dock = YES;
+ else if (screen_visible_frame.size.height + f_menu_bar_thickness < screen_frame.size.height)
+ b_found_dock = YES;
+
+ return b_found_dock;
}
- (BOOL)isScreen: (NSScreen*)screen
[blackoutWindows removeAllObjects];
NSUInteger screenCount = [[NSScreen screens] count];
- for(NSUInteger i = 0; i < screenCount; i++)
- {
- NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
+ for (NSUInteger i = 0; i < screenCount; i++) {
+ NSScreen *screen = [[NSScreen screens] objectAtIndex:i];
VLCWindow *blackoutWindow;
NSRect screen_rect;
- if([self isScreen: screen])
+ if ([self isScreen: screen])
continue;
screen_rect = [screen frame];
backing: NSBackingStoreBuffered defer: NO screen: screen];
[blackoutWindow setBackgroundColor:[NSColor blackColor]];
[blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
+ [blackoutWindow setReleasedWhenClosed:NO]; // window is released when deleted from array above
[blackoutWindow displayIfNeeded];
[blackoutWindow orderFront: self animate: YES];
[blackoutWindows addObject: blackoutWindow];
[blackoutWindow release];
- if( [screen isMainScreen] )
- {
- if (OSX_LEOPARD)
- SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
- else
- [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
- }
+ [screen setFullscreenPresentationOptions];
}
}
{
NSUInteger blackoutWindowCount = [blackoutWindows count];
- for(NSUInteger i = 0; i < blackoutWindowCount; i++)
- {
- VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
+ for (NSUInteger i = 0; i < blackoutWindowCount; i++) {
+ VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex:i];
+ [[blackoutWindow screen] setNonFullscreenPresentationOptions];
[blackoutWindow closeAndAnimate: YES];
}
-
- if (OSX_LEOPARD)
- SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
- else
- [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
-}
-
-@end
-
-/*****************************************************************************
- * VLCWindow
- *
- * Missing extension to NSWindow
- *****************************************************************************/
-
-@implementation VLCWindow
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
- backing:(NSBackingStoreType)backingType defer:(BOOL)flag
-{
- self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
- if( self )
- {
- b_isFullscreen = NO;
- b_isset_canBecomeKeyWindow = NO;
- /* we don't want this window to be restored on relaunch */
- if (OSX_LION)
- [self setRestorable:NO];
- }
- return self;
}
-- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
+- (void)setFullscreenPresentationOptions
{
- b_isset_canBecomeKeyWindow = YES;
- b_canBecomeKeyWindow = canBecomeKey;
+ NSApplicationPresentationOptions presentationOpts = [NSApp presentationOptions];
+ if ([self hasMenuBar])
+ presentationOpts |= NSApplicationPresentationAutoHideMenuBar;
+ if ([self hasMenuBar] || [self hasDock])
+ presentationOpts |= NSApplicationPresentationAutoHideDock;
+ [NSApp setPresentationOptions:presentationOpts];
}
-- (BOOL)canBecomeKeyWindow
+- (void)setNonFullscreenPresentationOptions
{
- if(b_isset_canBecomeKeyWindow)
- return b_canBecomeKeyWindow;
-
- return [super canBecomeKeyWindow];
+ NSApplicationPresentationOptions presentationOpts = [NSApp presentationOptions];
+ if ([self hasMenuBar])
+ presentationOpts &= (~NSApplicationPresentationAutoHideMenuBar);
+ if ([self hasMenuBar] || [self hasDock])
+ presentationOpts &= (~NSApplicationPresentationAutoHideDock);
+ [NSApp setPresentationOptions:presentationOpts];
}
-- (void)setCanBecomeMainWindow: (BOOL)canBecomeMain
-{
- b_isset_canBecomeMainWindow = YES;
- b_canBecomeMainWindow = canBecomeMain;
-}
-
-- (BOOL)canBecomeMainWindow
-{
- if(b_isset_canBecomeMainWindow)
- return b_canBecomeMainWindow;
-
- return [super canBecomeMainWindow];
-}
-
-- (void)closeAndAnimate: (BOOL)animate
-{
- NSInvocation *invoc;
-
- if (!animate)
- {
- [super close];
- return;
- }
-
- invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
- [invoc setTarget: self];
-
- if (![self isVisible] || [self alphaValue] == 0.0)
- {
- [super close];
- return;
- }
+@end
- [self orderOut: self animate: YES callback: invoc];
-}
+/*****************************************************************************
+ * VLCDragDropView
+ *****************************************************************************/
-- (void)orderOut: (id)sender animate: (BOOL)animate
-{
- NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
- [invoc setTarget: self];
- [invoc setArgument: sender atIndex: 0];
- [self orderOut: sender animate: animate callback: invoc];
-}
+@implementation VLCDropDisabledImageView
-- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
+- (void)awakeFromNib
{
- NSViewAnimation *anim;
- NSViewAnimation *current_anim;
- NSMutableDictionary *dict;
-
- if (!animate)
- {
- [self orderOut: sender];
- return;
- }
-
- dict = [[NSMutableDictionary alloc] initWithCapacity:2];
-
- [dict setObject:self forKey:NSViewAnimationTargetKey];
-
- [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
- anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
- [dict release];
-
- [anim setAnimationBlockingMode:NSAnimationNonblocking];
- [anim setDuration:0.9];
- [anim setFrameRate:30];
- [anim setUserInfo: callback];
-
- @synchronized(self) {
- current_anim = self->animation;
-
- if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating])
- {
- [anim release];
- }
- else
- {
- if (current_anim)
- {
- [current_anim stopAnimation];
- [anim setCurrentProgress:1.0-[current_anim currentProgress]];
- [current_anim release];
- }
- else
- [anim setCurrentProgress:1.0 - [self alphaValue]];
- self->animation = anim;
- [self setDelegate: self];
- [anim startAnimation];
- }
- }
+ [self unregisterDraggedTypes];
}
-- (void)orderFront: (id)sender animate: (BOOL)animate
-{
- NSViewAnimation *anim;
- NSViewAnimation *current_anim;
- NSMutableDictionary *dict;
-
- if (!animate)
- {
- [super orderFront: sender];
- [self setAlphaValue: 1.0];
- return;
- }
-
- if (![self isVisible])
- {
- [self setAlphaValue: 0.0];
- [super orderFront: sender];
- }
- else if ([self alphaValue] == 1.0)
- {
- [super orderFront: self];
- return;
- }
-
- dict = [[NSMutableDictionary alloc] initWithCapacity:2];
-
- [dict setObject:self forKey:NSViewAnimationTargetKey];
-
- [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
- anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
- [dict release];
+@end
- [anim setAnimationBlockingMode:NSAnimationNonblocking];
- [anim setDuration:0.5];
- [anim setFrameRate:30];
+/*****************************************************************************
+ * VLCDragDropView
+ *****************************************************************************/
- @synchronized(self) {
- current_anim = self->animation;
+@implementation VLCDragDropView
- if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating])
- {
- [anim release];
- }
- else
- {
- if (current_anim)
- {
- [current_anim stopAnimation];
- [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
- [current_anim release];
- }
- else
- [anim setCurrentProgress:[self alphaValue]];
- self->animation = anim;
- [self setDelegate: self];
- [self orderFront: sender];
- [anim startAnimation];
- }
- }
-}
+@synthesize dropHandler=_dropHandler;
+@synthesize drawBorder;
-- (void)animationDidEnd:(NSAnimation*)anim
+- (id)initWithFrame:(NSRect)frame
{
- if ([self alphaValue] <= 0.0)
- {
- NSInvocation * invoc;
- [super orderOut: nil];
- [self setAlphaValue: 1.0];
- if ((invoc = [anim userInfo]))
- [invoc invoke];
+ self = [super initWithFrame:frame];
+ if (self) {
+ // default value
+ [self setDrawBorder:YES];
}
-}
-
-- (void)setFullscreen:(BOOL)b_var
-{
- b_isFullscreen = b_var;
-}
-- (BOOL)isFullscreen
-{
- return b_isFullscreen;
+ return self;
}
-- (IBAction)fullscreen:(id)sender
+- (void)enablePlaylistItems
{
- [[VLCCoreInteraction sharedInstance] toggleFullscreen];
+ [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, @"VLCPlaylistItemPboardType", nil]];
}
-@end
-
-/*****************************************************************************
- * VLBrushedMetalImageView
- *****************************************************************************/
-
-@implementation VLBrushedMetalImageView
-
- (BOOL)mouseDownCanMoveWindow
{
return YES;
- (void)awakeFromNib
{
- [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
- [self setImageScaling: NSScaleToFit];
- [self setImageFrameStyle: NSImageFrameNone];
- [self setImageAlignment: NSImageAlignCenter];
+ [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
- if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
- return NSDragOperationGeneric;
+ if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric) {
+ b_activeDragAndDrop = YES;
+ [self setNeedsDisplay:YES];
+
+ return NSDragOperationCopy;
+ }
return NSDragOperationNone;
}
+- (void)draggingEnded:(id < NSDraggingInfo >)sender
+{
+ b_activeDragAndDrop = NO;
+ [self setNeedsDisplay:YES];
+}
+
+- (void)draggingExited:(id < NSDraggingInfo >)sender
+{
+ b_activeDragAndDrop = NO;
+ [self setNeedsDisplay:YES];
+}
+
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
return YES;
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
BOOL b_returned;
- b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];
+
+ if (_dropHandler && [_dropHandler respondsToSelector:@selector(performDragOperation:)])
+ b_returned = [_dropHandler performDragOperation: sender];
+ else // default
+ b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];
[self setNeedsDisplay:YES];
return b_returned;
[self setNeedsDisplay:YES];
}
+- (void)drawRect:(NSRect)dirtyRect
+{
+ if ([self drawBorder] && b_activeDragAndDrop) {
+ NSRect frameRect = [self bounds];
+
+ [[NSColor selectedControlColor] set];
+ NSFrameRectWithWidthUsingOperation(frameRect, 2., NSCompositeHighlight);
+ }
+
+ [super drawRect:dirtyRect];
+}
+
@end
@end
+/*****************************************************************************
+ * ProgressView
+ *****************************************************************************/
+
+@implementation VLCProgressView : NSView
+
+- (void)scrollWheel:(NSEvent *)o_event
+{
+ BOOL b_forward = NO;
+ CGFloat f_deltaY = [o_event deltaY];
+ CGFloat f_deltaX = [o_event deltaX];
+
+ if (!OSX_SNOW_LEOPARD && [o_event isDirectionInvertedFromDevice])
+ f_deltaX = -f_deltaX; // optimisation, actually double invertion of f_deltaY here
+ else
+ f_deltaY = -f_deltaY;
+
+ // positive for left / down, negative otherwise
+ CGFloat f_delta = f_deltaX + f_deltaY;
+ CGFloat f_abs;
+ int i_vlckey;
+
+ if (f_delta > 0.0f)
+ f_abs = f_delta;
+ else {
+ b_forward = YES;
+ f_abs = -f_delta;
+ }
+
+ for (NSUInteger i = 0; i < (int)(f_abs/4.+1.) && f_abs > 0.05 ; i++) {
+ if (b_forward)
+ [[VLCCoreInteraction sharedInstance] forwardExtraShort];
+ else
+ [[VLCCoreInteraction sharedInstance] backwardExtraShort];
+ }
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
+@end
+
/*****************************************************************************
* TimeLineSlider
*****************************************************************************/
- (void)awakeFromNib
{
- if (config_GetInt( VLCIntf, "macosx-interfacestyle" ))
- o_knob_img = [NSImage imageNamed:@"progression-knob_dark"];
- else
- o_knob_img = [NSImage imageNamed:@"progression-knob"];
+ if (config_GetInt( VLCIntf, "macosx-interfacestyle" )) {
+ o_knob_img = imageFromRes(@"progression-knob_dark");
+ b_dark = YES;
+ } else {
+ o_knob_img = imageFromRes(@"progression-knob");
+ b_dark = NO;
+ }
img_rect.size = [o_knob_img size];
img_rect.origin.x = img_rect.origin.y = 0;
}
- (void)drawRect:(NSRect)rect
{
- [[[VLCMain sharedInstance] mainWindow] drawFancyGradientEffectForTimeSlider];
- msleep( 10000 ); //wait for the gradient to draw completely
+ [[(VLCVideoWindowCommon *)[self window] controlsBar] drawFancyGradientEffectForTimeSlider];
+ msleep(10000); //wait for the gradient to draw completely
/* Draw default to make sure the slider behaves correctly */
[[NSGraphicsContext currentContext] saveGraphicsState];
@end
+/*****************************************************************************
+ * VLCVolumeSliderCommon
+ *****************************************************************************/
+
+@implementation VLCVolumeSliderCommon : NSSlider
+
+@synthesize usesBrightArtwork = _usesBrightArtwork;
+
+- (void)scrollWheel:(NSEvent *)o_event
+{
+ BOOL b_up = NO;
+ CGFloat f_deltaY = [o_event deltaY];
+ CGFloat f_deltaX = [o_event deltaX];
+
+ if (!OSX_SNOW_LEOPARD && [o_event isDirectionInvertedFromDevice])
+ f_deltaX = -f_deltaX; // optimisation, actually double invertion of f_deltaY here
+ else
+ f_deltaY = -f_deltaY;
+
+ // positive for left / down, negative otherwise
+ CGFloat f_delta = f_deltaX + f_deltaY;
+ CGFloat f_abs;
+
+ if (f_delta > 0.0f)
+ f_abs = f_delta;
+ else {
+ b_up = YES;
+ f_abs = -f_delta;
+ }
+
+ for (NSUInteger i = 0; i < (int)(f_abs/4.+1.) && f_abs > 0.05 ; i++) {
+ if (b_up)
+ [[VLCCoreInteraction sharedInstance] volumeUp];
+ else
+ [[VLCCoreInteraction sharedInstance] volumeDown];
+ }
+}
+
+- (void)drawFullVolumeMarker
+{
+ CGFloat maxAudioVol = self.maxValue / AOUT_VOLUME_DEFAULT;
+ if (maxAudioVol < 1.)
+ return;
+
+ NSColor *drawingColor;
+ // for bright artwork, a black color is used and vice versa
+ if (_usesBrightArtwork)
+ drawingColor = [[NSColor blackColor] colorWithAlphaComponent:.4];
+ else
+ drawingColor = [[NSColor whiteColor] colorWithAlphaComponent:.4];
+
+ NSBezierPath* bezierPath = [NSBezierPath bezierPath];
+ [self drawFullVolBezierPath:bezierPath];
+ [bezierPath closePath];
+
+ bezierPath.lineWidth = 1.;
+ [drawingColor setStroke];
+ [bezierPath stroke];
+}
+
+- (CGFloat)fullVolumePos
+{
+ CGFloat maxAudioVol = self.maxValue / AOUT_VOLUME_DEFAULT;
+ CGFloat sliderRange = [self frame].size.width - [self knobThickness];
+ CGFloat sliderOrigin = [self knobThickness] / 2.;
+
+ return 1. / maxAudioVol * sliderRange + sliderOrigin;
+}
+
+- (void)drawFullVolBezierPath:(NSBezierPath*)bezierPath
+{
+ CGFloat fullVolPos = [self fullVolumePos];
+ [bezierPath moveToPoint:NSMakePoint(fullVolPos, [self frame].size.height - 3.)];
+ [bezierPath lineToPoint:NSMakePoint(fullVolPos, 2.)];
+}
+
+@end
+
+@implementation VolumeSliderCell
+
+- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
+{
+ VLCVolumeSliderCommon *o_slider = (VLCVolumeSliderCommon *)controlView;
+ CGFloat fullVolumePos = [o_slider fullVolumePos] + 2.;
+
+ CGPoint snapToPoint = currentPoint;
+ if (ABS(fullVolumePos - currentPoint.x) <= 4.)
+ snapToPoint.x = fullVolumePos;
+
+ return [super continueTracking:lastPoint at:snapToPoint inView:controlView];
+}
+
+@end
+
/*****************************************************************************
* ITSlider
*****************************************************************************/
{
BOOL b_dark = config_GetInt( VLCIntf, "macosx-interfacestyle" );
if (b_dark)
- img = [NSImage imageNamed:@"volume-slider-knob_dark"];
+ img = imageFromRes(@"volume-slider-knob_dark");
else
- img = [NSImage imageNamed:@"volume-slider-knob"];
+ img = imageFromRes(@"volume-slider-knob");
image_rect.size = [img size];
image_rect.origin.x = 0;
[super drawRect:rect];
[[NSGraphicsContext currentContext] restoreGraphicsState];
+ [self drawFullVolumeMarker];
+
NSRect knobRect = [[self cell] knobRectFlipped:NO];
knobRect.origin.y+=2;
[self drawKnobInRect: knobRect];
@implementation VLCTimeField
+ (void)initialize{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
+ NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"NO", @"DisplayTimeAsTimeRemaining",
+ @"YES", @"DisplayFullscreenTimeAsTimeRemaining",
+ nil];
[defaults registerDefaults:appDefaults];
}
-- (void)awakeFromNib
+- (id)initWithFrame:(NSRect)frameRect
{
- NSColor *o_string_color;
- if (!config_GetInt( VLCIntf, "macosx-interfacestyle"))
- o_string_color = [NSColor colorWithCalibratedRed:0.229 green:0.229 blue:0.229 alpha:100.0];
- else
- o_string_color = [NSColor colorWithCalibratedRed:0.64 green:0.64 blue:0.64 alpha:100.0];
+ if (self = [super initWithFrame:frameRect]) {
+ textAlignment = NSCenterTextAlignment;
+ o_remaining_identifier = @"";
+ }
+
+ return self;
+}
- textAlignment = NSCenterTextAlignment;
- o_string_attributes_dict = [[NSDictionary dictionaryWithObjectsAndKeys: o_string_color, NSForegroundColorAttributeName, [NSFont titleBarFontOfSize:10.0], NSFontAttributeName, nil] retain];
+- (void)setRemainingIdentifier:(NSString *)o_string
+{
+ o_remaining_identifier = o_string;
+ b_time_remaining = [[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier];
}
- (void)setAlignment:(NSTextAlignment)alignment
- (void)dealloc
{
[o_string_shadow release];
- [o_string_attributes_dict release];
[super dealloc];
}
- (void)setStringValue:(NSString *)string
{
- if (!o_string_shadow)
- {
+ if (!o_string_shadow) {
o_string_shadow = [[NSShadow alloc] init];
[o_string_shadow setShadowColor: [NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
- [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.5)];
+ [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.0)];
[o_string_shadow setShadowBlurRadius:0.0];
}
- NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: o_string_attributes_dict];
+ NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: nil];
NSUInteger i_stringLength = [string length];
[o_attributed_string addAttribute: NSShadowAttributeName value: o_string_shadow range: NSMakeRange(0, i_stringLength)];
- (void)mouseDown: (NSEvent *)ourEvent
{
- if( [ourEvent clickCount] > 1 )
+ if ( [ourEvent clickCount] > 1 )
[[[VLCMain sharedInstance] controls] goToSpecificTime: nil];
else
{
- if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"])
- [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"DisplayTimeAsTimeRemaining"];
- else
- [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"DisplayTimeAsTimeRemaining"];
+ if (![o_remaining_identifier isEqualToString: @""]) {
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier]) {
+ [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:o_remaining_identifier];
+ b_time_remaining = NO;
+ } else {
+ [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:o_remaining_identifier];
+ b_time_remaining = YES;
+ }
+ } else {
+ b_time_remaining = !b_time_remaining;
+ [[NSUserDefaults standardUserDefaults] setObject:(b_time_remaining ? @"YES" : @"NO") forKey:o_remaining_identifier];
+ }
}
}
- (BOOL)timeRemaining
{
- return [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayTimeAsTimeRemaining"];
+ if (![o_remaining_identifier isEqualToString: @""])
+ return [[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier];
+ else
+ return b_time_remaining;
}
+
@end
/*****************************************************************************
* VLCThreePartImageView interface
*****************************************************************************/
@implementation VLCThreePartImageView
+
- (void)dealloc
{
[o_left_img release];
@end
-@implementation VLCThreePartDropView
-- (BOOL)mouseDownCanMoveWindow
+@implementation PositionFormatter
+
+- (id)init
{
- return YES;
+ self = [super init];
+ NSMutableCharacterSet *nonNumbers = [[[NSCharacterSet decimalDigitCharacterSet] invertedSet] mutableCopy];
+ [nonNumbers removeCharactersInString:@":"];
+ o_forbidden_characters = [nonNumbers copy];
+ [nonNumbers release];
+
+ return self;
}
- (void)dealloc
{
- [self unregisterDraggedTypes];
+ [o_forbidden_characters release];
[super dealloc];
}
-- (void)awakeFromNib
+- (NSString*)stringForObjectValue:(id)obj
{
- [self registerForDraggedTypes:[NSArray arrayWithObject: NSFilenamesPboardType]];
+ if([obj isKindOfClass:[NSString class]])
+ return obj;
+ if([obj isKindOfClass:[NSNumber class]])
+ return [obj stringValue];
+
+ return nil;
}
-- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+- (BOOL)getObjectValue:(id*)obj forString:(NSString*)string errorDescription:(NSString**)error
{
- if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
- return NSDragOperationGeneric;
-
- return NSDragOperationNone;
+ *obj = [[string copy] autorelease];
+ return YES;
}
-- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
+- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error
{
- return YES;
+ if ([partialString rangeOfCharacterFromSet:o_forbidden_characters options:NSLiteralSearch].location != NSNotFound) {
+ return NO;
+ } else {
+ return YES;
+ }
}
-- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+@end
+
+@implementation NSView (EnableSubviews)
+
+- (void)enableSubviews:(BOOL)b_enable
{
- BOOL b_returned;
- b_returned = [[VLCCoreInteraction sharedInstance] performDragOperation: sender];
+ for (NSView *o_view in [self subviews]) {
+ [o_view enableSubviews:b_enable];
- [self setNeedsDisplay:YES];
- return YES;
+ // enable NSControl
+ if ([o_view respondsToSelector:@selector(setEnabled:)]) {
+ [(NSControl *)o_view setEnabled:b_enable];
+ }
+ // also "enable / disable" text views
+ if ([o_view respondsToSelector:@selector(setTextColor:)]) {
+ if (b_enable == NO) {
+ [(NSTextField *)o_view setTextColor:[NSColor disabledControlTextColor]];
+ } else {
+ [(NSTextField *)o_view setTextColor:[NSColor controlTextColor]];
+ }
+ }
+
+ }
}
-- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
+@end
+
+/*****************************************************************************
+ * VLCByteCountFormatter addition
+ *****************************************************************************/
+
+@implementation VLCByteCountFormatter
+
++ (NSString *)stringFromByteCount:(long long)byteCount countStyle:(NSByteCountFormatterCountStyle)countStyle
{
- [self setNeedsDisplay:YES];
+ // Use native implementation on >= mountain lion
+ Class byteFormatterClass = NSClassFromString(@"NSByteCountFormatter");
+ if (byteFormatterClass && [byteFormatterClass respondsToSelector:@selector(stringFromByteCount:countStyle:)]) {
+ return [byteFormatterClass stringFromByteCount:byteCount countStyle:NSByteCountFormatterCountStyleFile];
+ }
+
+ float devider = 0.;
+ float returnValue = 0.;
+ NSString *suffix;
+
+ NSNumberFormatter *theFormatter = [[NSNumberFormatter alloc] init];
+ [theFormatter setLocale:[NSLocale currentLocale]];
+ [theFormatter setAllowsFloats:YES];
+
+ NSString *returnString = @"";
+
+ if (countStyle != NSByteCountFormatterCountStyleDecimal)
+ devider = 1024.;
+ else
+ devider = 1000.;
+
+ if (byteCount < 1000) {
+ returnValue = byteCount;
+ suffix = _NS("B");
+ [theFormatter setMaximumFractionDigits:0];
+ goto end;
+ }
+
+ if (byteCount < 1000000) {
+ returnValue = byteCount / devider;
+ suffix = _NS("KB");
+ [theFormatter setMaximumFractionDigits:0];
+ goto end;
+ }
+
+ if (byteCount < 1000000000) {
+ returnValue = byteCount / devider / devider;
+ suffix = _NS("MB");
+ [theFormatter setMaximumFractionDigits:1];
+ goto end;
+ }
+
+ [theFormatter setMaximumFractionDigits:2];
+ if (byteCount < 1000000000000) {
+ returnValue = byteCount / devider / devider / devider;
+ suffix = _NS("GB");
+ goto end;
+ }
+
+ returnValue = byteCount / devider / devider / devider / devider;
+ suffix = _NS("TB");
+
+end:
+ returnString = [NSString stringWithFormat:@"%@ %@", [theFormatter stringFromNumber:[NSNumber numberWithFloat:returnValue]], suffix];
+ [theFormatter release];
+
+ return returnString;
}
@end