X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2FMainWindow.m;h=baaf6940c325f98f6841f7942f5d37e091f1c7e1;hb=168b48cb412804b5a877fcbb7dbeeac60b01dc86;hp=f3cf7334f0e2794638af7cb2108f687c84a32bb0;hpb=840d653ffdfb7bfbfdc06a6f1dfd1ab6bb5f52c8;p=vlc diff --git a/modules/gui/macosx/MainWindow.m b/modules/gui/macosx/MainWindow.m index f3cf7334f0..baaf6940c3 100644 --- a/modules/gui/macosx/MainWindow.m +++ b/modules/gui/macosx/MainWindow.m @@ -1,7 +1,7 @@ /***************************************************************************** - * MainWindow.h: MacOS X interface module + * MainWindow.m: MacOS X interface module ***************************************************************************** - * Copyright (C) 2002-2011 VideoLAN + * Copyright (C) 2002-2011 VLC authors and VideoLAN * $Id$ * * Authors: Felix Paul Kühne @@ -24,6 +24,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#import "CompatibilityFixes.h" #import "MainWindow.h" #import "intf.h" #import "CoreInteraction.h" @@ -32,6 +33,7 @@ #import "open.h" #import "controls.h" // TODO: remove me #import "SideBarItem.h" +#import "MainWindowTitle.h" #import #import #import @@ -68,9 +70,19 @@ static VLCMainWindow *_o_sharedInstance = nil; - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag { -// styleMask ^= NSTexturedBackgroundWindowMask; + b_dark_interface = config_GetInt( VLCIntf, "macosx-interfacestyle" ); + + if (b_dark_interface) + { +#ifdef MAC_OS_X_VERSION_10_7 + styleMask = NSBorderlessWindowMask | NSResizableWindowMask; + [o_resize_view removeFromSuperviewWithoutNeedingDisplay]; +#else + styleMask = NSBorderlessWindowMask; +#endif + } - self = [super initWithContentRect:contentRect styleMask:styleMask //& ~NSTitledWindowMask + self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag]; [[VLCMain sharedInstance] updateTogglePlaylistState]; @@ -79,7 +91,7 @@ static VLCMainWindow *_o_sharedInstance = nil; [self setMovableByWindowBackground: YES]; /* we don't want this window to be restored on relaunch */ - if ([self respondsToSelector:@selector(setRestorable:)]) + if (OSX_LION) [self setRestorable:NO]; return self; @@ -97,7 +109,9 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver: self]; config_PutInt( VLCIntf->p_libvlc, "volume", i_lastShownVolume ); + [self saveFrameUsingName: [self frameAutosaveName]]; [o_sidebaritems release]; [super dealloc]; } @@ -105,7 +119,7 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)awakeFromNib { /* setup the styled interface */ - b_dark_interface = config_GetInt( VLCIntf, "macosx-interfacestyle" ); + b_nativeFullscreenMode = config_GetInt( VLCIntf, "macosx-nativefullscreenmode" ); i_lastShownVolume = -1; [o_play_btn setToolTip: _NS("Play/Pause")]; @@ -155,15 +169,22 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_volume_down_btn setImage: [NSImage imageNamed:@"volume-low"]]; [o_volume_track_view setImage: [NSImage imageNamed:@"volume-slider-track"]]; [o_volume_up_btn setImage: [NSImage imageNamed:@"volume-high"]]; - [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons"]]; - [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed"]]; + if (OSX_LION && b_nativeFullscreenMode) + { + [o_effects_btn setImage: [NSImage imageNamed:@"effects-one-button"]]; + [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-one-button-blue"]]; + } + else + { + [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons"]]; + [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed"]]; + } [o_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-double-buttons"]]; [o_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-double-buttons-pressed"]]; [o_time_sld_fancygradient_view loadImagesInDarkStyle:NO]; } else { - /* TODO: we also need to change the window style here... */ [o_bottombar_view setImage: [NSImage imageNamed:@"bottom-background_dark"]]; [o_bwd_btn setImage: [NSImage imageNamed:@"back_dark"]]; [o_bwd_btn setAlternateImage: [NSImage imageNamed:@"back-pressed_dark"]]; @@ -194,8 +215,16 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_volume_down_btn setImage: [NSImage imageNamed:@"volume-low_dark"]]; [o_volume_track_view setImage: [NSImage imageNamed:@"volume-slider-track_dark"]]; [o_volume_up_btn setImage: [NSImage imageNamed:@"volume-high_dark"]]; - [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons_dark"]]; - [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed_dark"]]; + if (OSX_LION && b_nativeFullscreenMode) + { + [o_effects_btn setImage: [NSImage imageNamed:@"effects-one-button_dark"]]; + [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-one-button-blue_dark"]]; + } + else + { + [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons_dark"]]; + [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed_dark"]]; + } [o_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-double-buttons_dark"]]; [o_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-double-buttons-pressed_dark"]]; [o_time_sld_fancygradient_view loadImagesInDarkStyle:YES]; @@ -210,20 +239,69 @@ static VLCMainWindow *_o_sharedInstance = nil; /* interface builder action */ [self setDelegate: self]; [self setExcludedFromWindowsMenu: YES]; + [self setAcceptsMouseMovedEvents: YES]; // Set that here as IB seems to be buggy - [self setContentMinSize:NSMakeSize(500., 288.)]; + if (b_dark_interface) + [self setContentMinSize:NSMakeSize(500., (288. + [o_titlebar_view frame].size.height))]; + else + [self setContentMinSize:NSMakeSize(500., 288.)]; [self setTitle: _NS("VLC media player")]; [o_playlist_btn setEnabled:NO]; - [o_video_view setFrame: [o_split_view frame]]; o_temp_view = [[NSView alloc] init]; [o_temp_view setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; [o_dropzone_view setFrame: [o_playlist_table frame]]; + [o_left_split_view setFrame: [o_sidebar_view frame]]; + if (OSX_LION && b_nativeFullscreenMode) + { + [self setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; + NSRect frame; + float f_width = [o_fullscreen_btn frame].size.width; + + #define moveItem( item ) \ + frame = [item frame]; \ + frame.origin.x = f_width + frame.origin.x; \ + [item setFrame: frame] + + moveItem( o_effects_btn ); + moveItem( o_volume_up_btn ); + moveItem( o_volume_sld ); + moveItem( o_volume_track_view ); + moveItem( o_volume_down_btn ); + moveItem( o_time_fld ); + moveItem( o_time_sld_right_view ); + #undef moveItem + + #define enlargeItem( item ) \ + frame = [item frame]; \ + frame.size.width = f_width + frame.size.width; \ + [item setFrame: frame] + + enlargeItem( o_time_sld ); + enlargeItem( o_progress_bar ); + enlargeItem( o_time_sld_middle_view ); + enlargeItem( o_time_sld_fancygradient_view ); + #undef enlargeItem + + [o_fullscreen_btn removeFromSuperviewWithoutNeedingDisplay]; + } + else + [o_titlebar_view setFullscreenButtonHidden: YES]; + + if (OSX_LION) + { + /* the default small size of the search field is slightly different on Lion, let's work-around that */ + NSRect frame; + frame = [o_search_fld frame]; + frame.origin.y = frame.origin.y + 2.0; + frame.size.height = frame.size.height - 1.0; + [o_search_fld setFrame: frame]; + } /* create the sidebar */ o_sidebaritems = [[NSMutableArray alloc] init]; SideBarItem *libraryItem = [SideBarItem itemWithTitle:_NS("LIBRARY") identifier:@"library"]; SideBarItem *playlistItem = [SideBarItem itemWithTitle:_NS("Playlist") identifier:@"playlist"]; - [playlistItem setIcon: [NSImage imageNamed:@"document-music-playlist"]]; + [playlistItem setIcon: [NSImage imageNamed:@"sidebar-playlist"]]; SideBarItem *mycompItem = [SideBarItem itemWithTitle:_NS("MY COMPUTER") identifier:@"mycomputer"]; SideBarItem *devicesItem = [SideBarItem itemWithTitle:_NS("DEVICES") identifier:@"devices"]; SideBarItem *lanItem = [SideBarItem itemWithTitle:_NS("LOCAL NETWORK") identifier:@"localnetwork"]; @@ -251,7 +329,7 @@ static VLCMainWindow *_o_sharedInstance = nil; { [internetItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]]; if (!strncmp( *ppsz_name, "podcast", 7 )) - [[internetItems lastObject] setIcon: [NSImage imageNamed:@"film-cast"]]; + [[internetItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-podcast"]]; else [[internetItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]]; } @@ -265,18 +343,18 @@ static VLCMainWindow *_o_sharedInstance = nil; case SD_CAT_LAN: { [lanItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]]; - [[lanItems lastObject] setIcon: [NSImage imageNamed:@"network-cloud"]]; + [[lanItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-local"]]; } break; case SD_CAT_MYCOMPUTER: { [mycompItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]]; if (!strncmp( *ppsz_name, "video_dir", 9 )) - [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"film"]]; + [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-movie"]]; else if (!strncmp( *ppsz_name, "audio_dir", 9 )) - [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"music-beam"]]; + [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-music"]]; else if (!strncmp( *ppsz_name, "picture_dir", 11 )) - [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"picture"]]; + [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-pictures"]]; else [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]]; } @@ -314,6 +392,32 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_sidebar_view reloadData]; [o_sidebar_view selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:YES]; + + if( b_dark_interface ) + { + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(windowResizedOrMoved:) name: NSWindowDidResizeNotification object: nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(windowResizedOrMoved:) name: NSWindowDidMoveNotification object: nil]; + + NSRect winrect; + CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height; + winrect = [self frame]; + + [o_titlebar_view setFrame: NSMakeRect( 0, winrect.size.height - f_titleBarHeight, + winrect.size.width, f_titleBarHeight )]; + [[self contentView] addSubview: o_titlebar_view]; + + winrect.size.height = winrect.size.height + f_titleBarHeight; + [self setFrame: winrect display:NO animate:NO]; + winrect = [o_split_view frame]; + winrect.size.height = winrect.size.height - f_titleBarHeight; + [o_split_view setFrame: winrect]; + [o_video_view setFrame: winrect]; + previousSavedFrame = winrect; + + [self display]; + } + else + [o_video_view setFrame: [o_split_view frame]]; } #pragma mark - @@ -409,14 +513,23 @@ static VLCMainWindow *_o_sharedInstance = nil; - (IBAction)togglePlaylist:(id)sender { - if ([o_video_view isHidden] && [o_playlist_btn isEnabled]) { - [o_playlist_table setHidden: YES]; - [o_video_view setHidden: NO]; + if (!b_nonembedded) + { + if ([o_video_view isHidden] && [o_playlist_btn isEnabled]) { + [o_split_view setHidden: YES]; + [o_video_view setHidden: NO]; + } + else + { + [o_video_view setHidden: YES]; + [o_split_view setHidden: NO]; + } } else { - [o_video_view setHidden: YES]; + [o_split_view setHidden: NO]; [o_playlist_table setHidden: NO]; + [o_video_view setHidden: ![[VLCMain sharedInstance] activeVideoPlayback]]; } } @@ -559,6 +672,140 @@ static VLCMainWindow *_o_sharedInstance = nil; [[[VLCMain sharedInstance] open] openFileGeneric]; } +#pragma mark - +#pragma mark overwritten default functionality +- (BOOL)canBecomeKeyWindow +{ + return YES; +} + +- (void)setTitle:(NSString *)title +{ + if (b_dark_interface) + [o_titlebar_view setWindowTitle: title]; + [super setTitle: title]; +} + +- (void)performZoom:(id)sender +{ + if (b_dark_interface) + [self customZoom: sender]; + else + [super performZoom: sender]; +} + +- (void)zoom:(id)sender +{ + if (b_dark_interface) + [self customZoom: sender]; + else + [super zoom: sender]; +} + +/** + * Given a proposed frame rectangle, return a modified version + * which will fit inside the screen. + * + * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+. + * Authors: Scott Christley , Venkat Ajjanagadde , + * Felipe A. Rodriguez , Richard Frith-Macdonald + * Copyright (C) 1996 Free Software Foundation, Inc. + */ +- (NSRect) customConstrainFrameRect: (NSRect)frameRect toScreen: (NSScreen*)screen +{ + NSRect screenRect = [screen visibleFrame]; + float difference; + + /* Move top edge of the window inside the screen */ + difference = NSMaxY (frameRect) - NSMaxY (screenRect); + if (difference > 0) + { + frameRect.origin.y -= difference; + } + + /* If the window is resizable, resize it (if needed) so that the + bottom edge is on the screen or can be on the screen when the user moves + the window */ + difference = NSMaxY (screenRect) - NSMaxY (frameRect); + if (_styleMask & NSResizableWindowMask) + { + float difference2; + + difference2 = screenRect.origin.y - frameRect.origin.y; + difference2 -= difference; + // Take in account the space between the top of window and the top of the + // screen which can be used to move the bottom of the window on the screen + if (difference2 > 0) + { + frameRect.size.height -= difference2; + frameRect.origin.y += difference2; + } + + /* Ensure that resizing doesn't makewindow smaller than minimum */ + difference2 = [self minSize].height - frameRect.size.height; + if (difference2 > 0) + { + frameRect.size.height += difference2; + frameRect.origin.y -= difference2; + } + } + + return frameRect; +} + +#define DIST 3 + +/** + Zooms the receiver. This method calls the delegate method + windowShouldZoom:toFrame: to determine if the window should + be allowed to zoom to full screen. + * + * This method is based upon NSWindow.m, part of the GNUstep GUI Library, licensed under LGPLv2+. + * Authors: Scott Christley , Venkat Ajjanagadde , + * Felipe A. Rodriguez , Richard Frith-Macdonald + * Copyright (C) 1996 Free Software Foundation, Inc. + */ +- (void) customZoom: (id)sender +{ + NSRect maxRect = [[self screen] visibleFrame]; + NSRect currentFrame = [self frame]; + + if ([[self delegate] respondsToSelector: @selector(windowWillUseStandardFrame:defaultFrame:)]) + { + maxRect = [[self delegate] windowWillUseStandardFrame: self defaultFrame: maxRect]; + } + + maxRect = [self customConstrainFrameRect: maxRect toScreen: [self screen]]; + + // Compare the new frame with the current one + if ((abs(NSMaxX(maxRect) - NSMaxX(currentFrame)) < DIST) + && (abs(NSMaxY(maxRect) - NSMaxY(currentFrame)) < DIST) + && (abs(NSMinX(maxRect) - NSMinX(currentFrame)) < DIST) + && (abs(NSMinY(maxRect) - NSMinY(currentFrame)) < DIST)) + { + // Already in zoomed mode, reset user frame, if stored + if ([self frameAutosaveName] != nil) + { + [self setFrame: previousSavedFrame display: YES animate: YES]; + [self saveFrameUsingName: [self frameAutosaveName]]; + } + return; + } + + if ([self frameAutosaveName] != nil) + { + [self saveFrameUsingName: [self frameAutosaveName]]; + previousSavedFrame = [self frame]; + } + + [self setFrame: maxRect display: YES animate: YES]; +} + +- (void)windowResizedOrMoved:(NSNotification *)notification +{ + [self saveFrameUsingName: [self frameAutosaveName]]; +} + #pragma mark - #pragma mark Update interface and respond to foreign events - (void)showDropZone @@ -657,35 +904,19 @@ static VLCMainWindow *_o_sharedInstance = nil; char *uri = input_item_GetURI( input_GetItem( p_input ) ); - if ([aString isEqualToString:@""]) - { - - char *file = uri ? strrchr( uri, '/' ) : NULL; - if( file != NULL ) - { - decode_URI( ++file ); - aString = [NSString stringWithUTF8String:file]; - } - else - aString = [NSString stringWithUTF8String:uri]; - } - - NSMutableString *o_mrl = [NSMutableString stringWithUTF8String: decode_URI(uri)]; + NSURL * o_url = [NSURL URLWithString: [NSString stringWithUTF8String: uri]]; + if ([o_url isFileURL]) + [self setRepresentedURL: o_url]; + else + [self setRepresentedURL: nil]; free( uri ); - NSRange prefix_range = [o_mrl rangeOfString: @"file:"]; - if( prefix_range.location != NSNotFound ) - [o_mrl deleteCharactersInRange: prefix_range]; - if( [o_mrl characterAtIndex:0] == '/' ) - { - /* it's a local file */ - [self setRepresentedFilename: o_mrl]; - } - else + if ([aString isEqualToString:@""]) { - /* it's from the network or somewhere else, - * we clear the previous path */ - [self setRepresentedFilename: @""]; + if ([o_url isFileURL]) + aString = [[NSFileManager defaultManager] displayNameAtPath: [o_url path]]; + else + aString = [o_url absoluteString]; } [self setTitle: aString]; @@ -694,8 +925,9 @@ static VLCMainWindow *_o_sharedInstance = nil; else { [self setTitle: _NS("VLC media player")]; - [self setRepresentedFilename: @""]; + [self setRepresentedURL: nil]; } + [o_pool release]; } @@ -732,6 +964,9 @@ static VLCMainWindow *_o_sharedInstance = nil; /* chapters & titles */ //FIXME! b_chapters = p_input->stream.i_area_nb > 1; + + if (cachedInputState == PLAYING_S || b_buffering == YES) + [self makeKeyAndOrderFront: nil]; vlc_object_release( p_input ); } @@ -781,7 +1016,7 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)drawFancyGradientEffectForTimeSlider { NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; - float f_value = ([o_time_sld_middle_view frame].size.width -5) * ([o_time_sld intValue] / [o_time_sld maxValue]); + float f_value = [o_time_sld_middle_view frame].size.width * ([o_time_sld intValue] / [o_time_sld maxValue]); if (f_value > 5.0) { if (f_value != [o_time_sld_fancygradient_view frame].size.width) @@ -804,17 +1039,76 @@ static VLCMainWindow *_o_sharedInstance = nil; - (id)videoView { + vout_thread_t *p_vout = getVout(); + if (config_GetInt( VLCIntf, "embedded-video" )) + { + if ([o_video_view window] != self) + { + [o_video_view removeFromSuperviewWithoutNeedingDisplay]; + [o_video_view setFrame: [o_split_view frame]]; + [[self contentView] addSubview:o_video_view positioned:NSWindowAbove relativeTo:nil]; + } + b_nonembedded = NO; + } + else + { + [o_video_view removeFromSuperviewWithoutNeedingDisplay]; + if (o_nonembedded_window) + [o_nonembedded_window release]; + + o_nonembedded_window = [[VLCWindow alloc] initWithContentRect:[o_video_view frame] styleMask: NSBorderlessWindowMask|NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]; + [o_nonembedded_window setFrame:[o_video_view frame] display:NO]; + [o_nonembedded_window setBackgroundColor: [NSColor blackColor]]; + [o_nonembedded_window setMovableByWindowBackground: YES]; + [o_nonembedded_window setCanBecomeKeyWindow: YES]; + [o_nonembedded_window setHasShadow:YES]; + [o_nonembedded_window setContentView: o_video_view]; + [o_nonembedded_window setLevel:NSNormalWindowLevel]; + [o_nonembedded_window useOptimizedDrawing: YES]; + [o_nonembedded_window center]; + [o_nonembedded_window makeKeyAndOrderFront:self]; + [o_nonembedded_window orderFront:self animate:YES]; + [o_nonembedded_window setReleasedWhenClosed:NO]; + b_nonembedded = YES; + } + + if (p_vout) + { + if( var_GetBool( p_vout, "video-on-top" ) ) + [[o_video_view window] setLevel: NSStatusWindowLevel]; + else + [[o_video_view window] setLevel: NSNormalWindowLevel]; + vlc_object_release( p_vout ); + } return o_video_view; } - (void)setVideoplayEnabled { - [o_playlist_btn setEnabled: [[VLCMain sharedInstance] activeVideoPlayback]]; + BOOL b_videoPlayback = [[VLCMain sharedInstance] activeVideoPlayback]; + + if (!b_nonembedded) + [o_playlist_btn setEnabled: b_videoPlayback]; + else + { + [o_playlist_btn setEnabled: NO]; + if (!b_videoPlayback) + [o_nonembedded_window orderOut: nil]; + } + if( OSX_LION && b_nativeFullscreenMode ) + { + if( [NSApp presentationOptions] == NSApplicationPresentationFullScreen ) + [o_bottombar_view setHidden: b_videoPlayback]; + else + [o_bottombar_view setHidden: NO]; + if (!b_videoPlayback) + [o_fspanel setNonActive: nil]; + } } - (void)resizeWindow { - if ( !b_fullscreen ) + if ( !b_fullscreen && !(OSX_LION && [NSApp presentationOptions] == NSApplicationPresentationFullScreen && b_nativeFullscreenMode) ) { NSPoint topleftbase; NSPoint topleftscreen; @@ -825,7 +1119,10 @@ static VLCMainWindow *_o_sharedInstance = nil; /* Calculate the window's new size */ new_frame.size.width = [self frame].size.width - [o_video_view frame].size.width + nativeVideoSize.width; - new_frame.size.height = [self frame].size.height - [o_video_view frame].size.height + nativeVideoSize.height; + if (b_dark_interface) + new_frame.size.height = [self frame].size.height - [o_video_view frame].size.height + nativeVideoSize.height + [o_titlebar_view frame].size.height; + else + new_frame.size.height = [self frame].size.height - [o_video_view frame].size.height + nativeVideoSize.height; new_frame.origin.x = topleftscreen.x; new_frame.origin.y = topleftscreen.y - new_frame.size.height; @@ -847,7 +1144,7 @@ static VLCMainWindow *_o_sharedInstance = nil; #pragma mark Fullscreen support - (void)showFullscreenController { - if (b_fullscreen) + if (b_fullscreen && [[VLCMain sharedInstance] activeVideoPlayback] ) [o_fspanel fadeIn]; } @@ -932,7 +1229,12 @@ static VLCMainWindow *_o_sharedInstance = nil; } if ([screen isMainScreen]) - SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); + { + if (OSX_LEOPARD) + SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); + else + [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; + } [[o_video_view superview] replaceSubview:o_video_view with:o_temp_view]; [o_temp_view setFrame:[o_video_view frame]]; @@ -986,7 +1288,12 @@ static VLCMainWindow *_o_sharedInstance = nil; } if ([screen isMainScreen]) - SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); + { + if (OSX_LEOPARD) + SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); + else + [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; + } dict1 = [[NSMutableDictionary alloc] initWithCapacity:2]; dict2 = [[NSMutableDictionary alloc] initWithCapacity:3]; @@ -1059,17 +1366,18 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_fullscreen_btn setState: NO]; /* We always try to do so */ - [NSScreen unblackoutScreens]; + if (!(OSX_LION && b_nativeFullscreenMode)) + [NSScreen unblackoutScreens]; vout_thread_t *p_vout = getVout(); if (p_vout) { if( var_GetBool( p_vout, "video-on-top" ) ) - [self setLevel: NSStatusWindowLevel]; + [[o_video_view window] setLevel: NSStatusWindowLevel]; else - [self setLevel: NSNormalWindowLevel]; + [[o_video_view window] setLevel: NSNormalWindowLevel]; vlc_object_release( p_vout ); } - [self makeKeyAndOrderFront: nil]; + [[o_video_view window] makeKeyAndOrderFront: nil]; /* Don't do anything if o_fullscreen_window is already closed */ if (!o_fullscreen_window) @@ -1091,7 +1399,10 @@ static VLCMainWindow *_o_sharedInstance = nil; } [o_fspanel setNonActive: nil]; - SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar); + if (OSX_LEOPARD) + SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar); + else + [NSApp setPresentationOptions:(NSApplicationPresentationDefault)]; /* Will release the lock */ [self hasEndedFullscreen]; @@ -1111,9 +1422,13 @@ static VLCMainWindow *_o_sharedInstance = nil; [self setAlphaValue: 0.0]; [self orderFront: self]; + [[o_video_view window] orderFront: self]; [o_fspanel setNonActive: nil]; - SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar); + if (OSX_LEOPARD) + SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar); + else + [NSApp setPresentationOptions:(NSApplicationPresentationDefault)]; if (o_fullscreen_anim1) { @@ -1215,10 +1530,11 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)orderOut: (id)sender { - [super orderOut: sender]; - /* Make sure we leave fullscreen */ - [self leaveFullscreenAndFadeOut: YES]; + if (!(OSX_LION && b_nativeFullscreenMode)) + [self leaveFullscreenAndFadeOut: YES]; + + [super orderOut: sender]; } - (void)makeKeyAndOrderFront: (id)sender @@ -1256,8 +1572,6 @@ static VLCMainWindow *_o_sharedInstance = nil; /* fullscreenAnimation will be unlocked when animation ends */ } - - /* Make sure setFrame gets executed on main thread especially if we are animating. * (Thus we won't block the video output thread) */ - (void)setFrame:(NSRect)frame display:(BOOL)display animate:(BOOL)animate @@ -1288,18 +1602,88 @@ static VLCMainWindow *_o_sharedInstance = nil; [NSValue valueWithRect:args->frame], NSViewAnimationEndFrameKey, nil]; NSViewAnimation * anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:dict]]; - [dict release]; [anim setAnimationBlockingMode: NSAnimationNonblocking]; [anim setDuration: 0.4]; [anim setFrameRate: 30]; [anim startAnimation]; + + [anim release]; } else { [super setFrame:args->frame display:args->display animate:args->animate]; } } +#pragma mark - +#pragma mark Lion's native fullscreen handling +- (void)windowWillEnterFullScreen:(NSNotification *)notification +{ + [o_video_view setFrame: [[self contentView] frame]]; + [NSCursor setHiddenUntilMouseMoves: YES]; + b_fullscreen = YES; + [o_fspanel setVoutWasUpdated: (int)[[self screen] displayID]]; + + if (b_dark_interface) + { + [o_titlebar_view removeFromSuperviewWithoutNeedingDisplay]; + + NSRect winrect; + CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height; + winrect = [self frame]; + + winrect.size.height = winrect.size.height - f_titleBarHeight; + [self setFrame: winrect display:NO animate:NO]; + winrect = [o_split_view frame]; + winrect.size.height = winrect.size.height + f_titleBarHeight; + [o_split_view setFrame: winrect]; + } +} + +- (void)windowWillExitFullScreen:(NSNotification *)notification +{ + [o_video_view setFrame: [o_split_view frame]]; + [NSCursor setHiddenUntilMouseMoves: NO]; + [o_fspanel setNonActive: nil]; + b_fullscreen = NO; + + if (b_dark_interface) + { + NSRect winrect; + CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height; + winrect = [self frame]; + + [o_titlebar_view setFrame: NSMakeRect( 0, winrect.size.height - f_titleBarHeight, + winrect.size.width, f_titleBarHeight )]; + [[self contentView] addSubview: o_titlebar_view]; + + winrect.size.height = winrect.size.height + f_titleBarHeight; + [self setFrame: winrect display:NO animate:NO]; + winrect = [o_split_view frame]; + winrect.size.height = winrect.size.height - f_titleBarHeight; + [o_split_view setFrame: winrect]; + [o_video_view setFrame: winrect]; + } +} + +#pragma mark - +#pragma mark split view delegate +- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex +{ + if (dividerIndex == 0) + return 200.0; + else + return proposedMin; +} + +- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex +{ + if (dividerIndex == 0) + return ([self frame].size.width - 300.0); + else + return proposedMax; +} + #pragma mark - #pragma mark Side Bar Data handling /* taken under BSD-new from the PXSourceList sample project, adapted for VLC */ @@ -1345,12 +1729,25 @@ static VLCMainWindow *_o_sharedInstance = nil; - (BOOL)sourceList:(PXSourceList*)aSourceList itemHasBadge:(id)item { + if ([[item identifier] isEqualToString: @"playlist"]) + return YES; + return [item hasBadge]; } - (NSInteger)sourceList:(PXSourceList*)aSourceList badgeValueForItem:(id)item { + if ([[item identifier] isEqualToString: @"playlist"]) { + playlist_t * p_playlist = pl_Get( VLCIntf ); + NSInteger i_playlist_size; + + PL_LOCK; + i_playlist_size = playlist_CurrentSize( p_playlist ); + PL_UNLOCK; + + return i_playlist_size; + } return [item badgeValue]; }