X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2FMainWindow.m;h=2a499cf3a5fbf6822a7c2a98b71d9251c20bc24f;hb=82120ce29b5411e9d99d5bf1ea798b68dc9f475a;hp=071a25ce5daf93e9c1afdf085578cf685904a55c;hpb=a38092cd83d85fe232a18b1e3c4581440043b742;p=vlc diff --git a/modules/gui/macosx/MainWindow.m b/modules/gui/macosx/MainWindow.m index 071a25ce5d..2a499cf3a5 100644 --- a/modules/gui/macosx/MainWindow.m +++ b/modules/gui/macosx/MainWindow.m @@ -1,13 +1,14 @@ /***************************************************************************** * MainWindow.m: MacOS X interface module ***************************************************************************** - * Copyright (C) 2002-2012 VLC authors and VideoLAN + * Copyright (C) 2002-2013 VLC authors and VideoLAN * $Id$ * * Authors: Felix Paul Kühne * Jon Lech Johansen * Christophe Massiot * Derk-Jan Hartman + * David Fuhrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,30 +37,29 @@ #import "SideBarItem.h" #import #import -#import #import #import #import -#import - -@interface VLCMainWindow () -- (void)addJumpButtons:(BOOL)b_fast; -- (void)removeJumpButtons:(BOOL)b_fast; -- (void)addPlaymodeButtons:(BOOL)b_fast; -- (void)removePlaymodeButtons:(BOOL)b_fast; - -- (void)resetPreviousButton; -- (void)resetBackwardSkip; -- (void)resetNextButton; -- (void)resetForwardSkip; + +#import "ControlsBar.h" +#import "VideoView.h" +#import "VLCVoutWindowController.h" + + +@interface VLCMainWindow (Internal) - (void)resizePlaylistAfterCollapse; - (void)makeSplitViewVisible; - (void)makeSplitViewHidden; - +- (void)showPodcastControls; +- (void)hidePodcastControls; @end + @implementation VLCMainWindow -static const float f_min_video_height = 70.0; + +@synthesize nativeFullscreenMode=b_nativeFullscreenMode; +@synthesize nonembedded=b_nonembedded; +@synthesize fsPanel=o_fspanel; static VLCMainWindow *_o_sharedInstance = nil; @@ -122,7 +122,11 @@ static VLCMainWindow *_o_sharedInstance = nil; // these are key events which should be handled by vlc core, but are attached to a main menu item if (![self isEvent: o_event forKey: "key-vol-up"] && ![self isEvent: o_event forKey: "key-vol-down"] && - ![self isEvent: o_event forKey: "key-vol-mute"]) { + ![self isEvent: o_event forKey: "key-vol-mute"] && + ![self isEvent: o_event forKey: "key-prev"] && + ![self isEvent: o_event forKey: "key-next"] && + ![self isEvent: o_event forKey: "key-jump+short"] && + ![self isEvent: o_event forKey: "key-jump-short"]) { /* We indeed want to prioritize some Cocoa key equivalent against libvlc, so we perform the menu equivalent now. */ if ([[NSApp mainMenu] performKeyEquivalent:o_event]) @@ -143,16 +147,14 @@ static VLCMainWindow *_o_sharedInstance = nil; [[NSNotificationCenter defaultCenter] removeObserver: self]; [o_sidebaritems release]; - if (o_extra_video_window) { - [o_extra_video_window release]; - o_extra_video_window = nil; - } - [super dealloc]; } - (void)awakeFromNib { + // sets lion fullscreen behaviour + [super awakeFromNib]; + BOOL b_splitviewShouldBeHidden = NO; /* setup the styled interface */ @@ -161,66 +163,11 @@ static VLCMainWindow *_o_sharedInstance = nil; if (!OSX_SNOW_LEOPARD) b_nativeFullscreenMode = var_InheritBool(VLCIntf, "macosx-nativefullscreenmode"); #endif - t_hide_mouse_timer = nil; - [o_detached_video_window setDelegate: self]; [self useOptimizedDrawing: YES]; - [o_play_btn setToolTip: _NS("Play/Pause")]; - [[o_play_btn cell] accessibilitySetOverrideValue:_NS("Click to play or pause the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_detached_play_btn setToolTip: [o_play_btn toolTip]]; - [[o_play_btn cell] accessibilitySetOverrideValue:[o_play_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_play_btn cell] accessibilitySetOverrideValue:[o_play_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_play_btn cell] accessibilitySetOverrideValue:_NS("Click to play or pause the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_bwd_btn setToolTip: _NS("Backward")]; - [[o_bwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the previous playlist item. Hold to skip backward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_detached_bwd_btn setToolTip: [o_bwd_btn toolTip]]; - [[o_bwd_btn cell] accessibilitySetOverrideValue:[o_bwd_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_bwd_btn cell] accessibilitySetOverrideValue:[o_bwd_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_bwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the previous playlist item. Hold to skip backward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_fwd_btn setToolTip: _NS("Forward")]; - [[o_fwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the next playlist item. Hold to skip forward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_detached_fwd_btn setToolTip: [o_fwd_btn toolTip]]; - [[o_detached_fwd_btn cell] accessibilitySetOverrideValue:[o_fwd_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_fwd_btn cell] accessibilitySetOverrideValue:[o_fwd_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_fwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the next playlist item. Hold to skip forward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_stop_btn setToolTip: _NS("Stop")]; - [[o_stop_btn cell] accessibilitySetOverrideValue:_NS("Click to stop playback.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_stop_btn cell] accessibilitySetOverrideValue:[o_stop_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_playlist_btn setToolTip: _NS("Show/Hide Playlist")]; - [[o_playlist_btn cell] accessibilitySetOverrideValue:_NS("Click to switch between video output and playlist. If no video is shown in the main window, this allows you to hide the playlist.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_playlist_btn cell] accessibilitySetOverrideValue:[o_playlist_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_repeat_btn setToolTip: _NS("Repeat")]; - [[o_repeat_btn cell] accessibilitySetOverrideValue:_NS("Click to change repeat mode. There are 3 states: repeat one, repeat all and off.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_repeat_btn cell] accessibilitySetOverrideValue:[o_repeat_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_shuffle_btn setToolTip: _NS("Shuffle")]; - [[o_shuffle_btn cell] accessibilitySetOverrideValue:[o_shuffle_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_shuffle_btn cell] accessibilitySetOverrideValue:_NS("Click to enable or disable random playback.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_effects_btn setToolTip: _NS("Effects")]; - [[o_effects_btn cell] accessibilitySetOverrideValue:_NS("Click to show an Audio Effects panel featuring an equalizer and further filters.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_effects_btn cell] accessibilitySetOverrideValue:[o_effects_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_fullscreen_btn setToolTip: _NS("Toggle Fullscreen mode")]; - [[o_fullscreen_btn cell] accessibilitySetOverrideValue:_NS("Click to enable fullscreen video playback.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_detached_fullscreen_btn setToolTip: [o_fullscreen_btn toolTip]]; - [[o_fullscreen_btn cell] accessibilitySetOverrideValue:[o_fullscreen_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_fullscreen_btn cell] accessibilitySetOverrideValue:[o_fullscreen_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [[o_detached_fullscreen_btn cell] accessibilitySetOverrideValue:_NS("Click to enable fullscreen video playback.") forAttribute:NSAccessibilityDescriptionAttribute]; [[o_search_fld cell] setPlaceholderString: _NS("Search")]; [[o_search_fld cell] accessibilitySetOverrideValue:_NS("Enter a term to search the playlist. Results will be selected in the table.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_volume_sld setToolTip: _NS("Volume")]; - [[o_volume_sld cell] accessibilitySetOverrideValue:_NS("Click and move the mouse while keeping the button pressed to use this slider to change the volume.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_volume_sld cell] accessibilitySetOverrideValue:[o_volume_sld toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_volume_down_btn setToolTip: _NS("Mute")]; - [[o_volume_down_btn cell] accessibilitySetOverrideValue:_NS("Click to mute or unmute the audio.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_volume_down_btn cell] accessibilitySetOverrideValue:[o_volume_down_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_volume_up_btn setToolTip: _NS("Full Volume")]; - [[o_volume_up_btn cell] accessibilitySetOverrideValue:_NS("Click to play the audio at maximum volume.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_volume_up_btn cell] accessibilitySetOverrideValue:[o_volume_up_btn toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_time_sld setToolTip: _NS("Position")]; - [[o_time_sld cell] accessibilitySetOverrideValue:_NS("Click and move the mouse while keeping the button pressed to use this slider to change current playback position.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_time_sld cell] accessibilitySetOverrideValue:[o_time_sld toolTip] forAttribute:NSAccessibilityTitleAttribute]; - [o_detached_time_sld setToolTip: [o_time_sld toolTip]]; - [[o_detached_time_sld cell] accessibilitySetOverrideValue:_NS("Click and move the mouse while keeping the button pressed to use this slider to change current playback position.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_detached_time_sld cell] accessibilitySetOverrideValue:[o_time_sld toolTip] forAttribute:NSAccessibilityTitleAttribute]; + [o_dropzone_btn setTitle: _NS("Open media...")]; [[o_dropzone_btn cell] accessibilitySetOverrideValue:_NS("Click to open an advanced dialog to select the media to play. You can also drop files here to play.") forAttribute:NSAccessibilityDescriptionAttribute]; [o_dropzone_lbl setStringValue: _NS("Drop media here")]; @@ -236,123 +183,8 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_podcast_unsubscribe_ok_btn setTitle: _NS("Unsubscribe")]; [o_podcast_unsubscribe_cancel_btn setTitle: _NS("Cancel")]; - if (!b_dark_interface) { - [o_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottom-background"] middle: [NSImage imageNamed:@"bottom-background"] right: [NSImage imageNamed:@"bottom-background"]]; - [o_detached_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottom-background"] middle: [NSImage imageNamed:@"bottom-background"] right: [NSImage imageNamed:@"bottom-background"]]; - [o_bwd_btn setImage: [NSImage imageNamed:@"backward-3btns"]]; - [o_bwd_btn setAlternateImage: [NSImage imageNamed:@"backward-3btns-pressed"]]; - [o_detached_bwd_btn setImage: [NSImage imageNamed:@"backward-3btns"]]; - [o_detached_bwd_btn setAlternateImage: [NSImage imageNamed:@"backward-3btns-pressed"]]; - o_play_img = [[NSImage imageNamed:@"play"] retain]; - o_play_pressed_img = [[NSImage imageNamed:@"play-pressed"] retain]; - o_pause_img = [[NSImage imageNamed:@"pause"] retain]; - o_pause_pressed_img = [[NSImage imageNamed:@"pause-pressed"] retain]; - [o_fwd_btn setImage: [NSImage imageNamed:@"forward-3btns"]]; - [o_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-3btns-pressed"]]; - [o_detached_fwd_btn setImage: [NSImage imageNamed:@"forward-3btns"]]; - [o_detached_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-3btns-pressed"]]; - [o_stop_btn setImage: [NSImage imageNamed:@"stop"]]; - [o_stop_btn setAlternateImage: [NSImage imageNamed:@"stop-pressed"]]; - [o_playlist_btn setImage: [NSImage imageNamed:@"playlist-btn"]]; - [o_playlist_btn setAlternateImage: [NSImage imageNamed:@"playlist-btn-pressed"]]; - o_repeat_img = [[NSImage imageNamed:@"repeat"] retain]; - o_repeat_pressed_img = [[NSImage imageNamed:@"repeat-pressed"] retain]; - o_repeat_all_img = [[NSImage imageNamed:@"repeat-all"] retain]; - o_repeat_all_pressed_img = [[NSImage imageNamed:@"repeat-all-pressed"] retain]; - o_repeat_one_img = [[NSImage imageNamed:@"repeat-one"] retain]; - o_repeat_one_pressed_img = [[NSImage imageNamed:@"repeat-one-pressed"] retain]; - o_shuffle_img = [[NSImage imageNamed:@"shuffle"] retain]; - o_shuffle_pressed_img = [[NSImage imageNamed:@"shuffle-pressed"] retain]; - o_shuffle_on_img = [[NSImage imageNamed:@"shuffle-blue"] retain]; - o_shuffle_on_pressed_img = [[NSImage imageNamed:@"shuffle-blue-pressed"] retain]; - [o_time_sld_background setImagesLeft: [NSImage imageNamed:@"progression-track-wrapper-left"] middle: [NSImage imageNamed:@"progression-track-wrapper-middle"] right: [NSImage imageNamed:@"progression-track-wrapper-right"]]; - [o_detached_time_sld_background setImagesLeft: [NSImage imageNamed:@"progression-track-wrapper-left"] middle: [NSImage imageNamed:@"progression-track-wrapper-middle"] right: [NSImage imageNamed:@"progression-track-wrapper-right"]]; - [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"]]; - if (b_nativeFullscreenMode) { - [o_effects_btn setImage: [NSImage imageNamed:@"effects-one-button"]]; - [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-one-button-pressed"]]; - } 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_detached_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-one-button"]]; - [o_detached_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-one-button-pressed"]]; - [o_time_sld_fancygradient_view setImagesLeft:[NSImage imageNamed:@"progression-fill-left"] middle:[NSImage imageNamed:@"progression-fill-middle"] right:[NSImage imageNamed:@"progression-fill-right"]]; - [o_detached_time_sld_fancygradient_view setImagesLeft:[NSImage imageNamed:@"progression-fill-left"] middle:[NSImage imageNamed:@"progression-fill-middle"] right:[NSImage imageNamed:@"progression-fill-right"]]; - } else { - [o_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottomdark-left"] middle: [NSImage imageNamed:@"bottom-background_dark"] right: [NSImage imageNamed:@"bottomdark-right"]]; - [o_detached_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottomdark-left"] middle: [NSImage imageNamed:@"bottom-background_dark"] right: [NSImage imageNamed:@"bottomdark-right"]]; - [o_bwd_btn setImage: [NSImage imageNamed:@"backward-3btns-dark"]]; - [o_bwd_btn setAlternateImage: [NSImage imageNamed:@"backward-3btns-dark-pressed"]]; - [o_detached_bwd_btn setImage: [NSImage imageNamed:@"backward-3btns-dark"]]; - [o_detached_bwd_btn setAlternateImage: [NSImage imageNamed:@"backward-3btns-dark-pressed"]]; - o_play_img = [[NSImage imageNamed:@"play_dark"] retain]; - o_play_pressed_img = [[NSImage imageNamed:@"play-pressed_dark"] retain]; - o_pause_img = [[NSImage imageNamed:@"pause_dark"] retain]; - o_pause_pressed_img = [[NSImage imageNamed:@"pause-pressed_dark"] retain]; - [o_fwd_btn setImage: [NSImage imageNamed:@"forward-3btns-dark"]]; - [o_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-3btns-dark-pressed"]]; - [o_detached_fwd_btn setImage: [NSImage imageNamed:@"forward-3btns-dark"]]; - [o_detached_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-3btns-dark-pressed"]]; - [o_stop_btn setImage: [NSImage imageNamed:@"stop_dark"]]; - [o_stop_btn setAlternateImage: [NSImage imageNamed:@"stop-pressed_dark"]]; - [o_playlist_btn setImage: [NSImage imageNamed:@"playlist_dark"]]; - [o_playlist_btn setAlternateImage: [NSImage imageNamed:@"playlist-pressed_dark"]]; - o_repeat_img = [[NSImage imageNamed:@"repeat_dark"] retain]; - o_repeat_pressed_img = [[NSImage imageNamed:@"repeat-pressed_dark"] retain]; - o_repeat_all_img = [[NSImage imageNamed:@"repeat-all-blue_dark"] retain]; - o_repeat_all_pressed_img = [[NSImage imageNamed:@"repeat-all-blue-pressed_dark"] retain]; - o_repeat_one_img = [[NSImage imageNamed:@"repeat-one-blue_dark"] retain]; - o_repeat_one_pressed_img = [[NSImage imageNamed:@"repeat-one-blue-pressed_dark"] retain]; - o_shuffle_img = [[NSImage imageNamed:@"shuffle_dark"] retain]; - o_shuffle_pressed_img = [[NSImage imageNamed:@"shuffle-pressed_dark"] retain]; - o_shuffle_on_img = [[NSImage imageNamed:@"shuffle-blue_dark"] retain]; - o_shuffle_on_pressed_img = [[NSImage imageNamed:@"shuffle-blue-pressed_dark"] retain]; - [o_time_sld_background setImagesLeft: [NSImage imageNamed:@"progression-track-wrapper-left_dark"] middle: [NSImage imageNamed:@"progression-track-wrapper-middle_dark"] right: [NSImage imageNamed:@"progression-track-wrapper-right_dark"]]; - [o_detached_time_sld_background setImagesLeft: [NSImage imageNamed:@"progression-track-wrapper-left_dark"] middle: [NSImage imageNamed:@"progression-track-wrapper-middle_dark"] right: [NSImage imageNamed:@"progression-track-wrapper-right_dark"]]; - [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"]]; - if (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_detached_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-one-button_dark"]]; - [o_detached_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-one-button-pressed_dark"]]; - [o_time_sld_fancygradient_view setImagesLeft:[NSImage imageNamed:@"progressbar-fill-left_dark"] middle:[NSImage imageNamed:@"progressbar-fill-middle_dark"] right:[NSImage imageNamed:@"progressbar-fill-right_dark"]]; - [o_detached_time_sld_fancygradient_view setImagesLeft:[NSImage imageNamed:@"progressbar-fill-left_dark"] middle:[NSImage imageNamed:@"progressbar-fill-middle_dark"] right:[NSImage imageNamed:@"progressbar-fill-right_dark"]]; - } - [o_repeat_btn setImage: o_repeat_img]; - [o_repeat_btn setAlternateImage: o_repeat_pressed_img]; - [o_shuffle_btn setImage: o_shuffle_img]; - [o_shuffle_btn setAlternateImage: o_shuffle_pressed_img]; - [o_play_btn setImage: o_play_img]; - [o_play_btn setAlternateImage: o_play_pressed_img]; - [o_detached_play_btn setImage: o_play_img]; - [o_detached_play_btn setAlternateImage: o_play_pressed_img]; - BOOL b_mute = ![[VLCCoreInteraction sharedInstance] mute]; - [o_volume_sld setEnabled: b_mute]; - [o_volume_up_btn setEnabled: b_mute]; - - b_show_jump_buttons = config_GetInt(VLCIntf, "macosx-show-playback-buttons"); - if (b_show_jump_buttons) - [self addJumpButtons:YES]; - - b_show_playmode_buttons = config_GetInt(VLCIntf, "macosx-show-playmode-buttons"); - if (!b_show_playmode_buttons) - [self removePlaymodeButtons:YES]; - /* interface builder action */ - float f_threshold_height = f_min_video_height + [o_bottombar_view frame].size.height; + float f_threshold_height = f_min_video_height + [o_controls_bar height]; if (b_dark_interface) f_threshold_height += [o_titlebar_view frame].size.height; if ([[self contentView] frame].size.height < f_threshold_height) @@ -362,48 +194,16 @@ static VLCMainWindow *_o_sharedInstance = nil; [self setExcludedFromWindowsMenu: YES]; [self setAcceptsMouseMovedEvents: YES]; // Set that here as IB seems to be buggy - if (b_dark_interface) { + if (b_dark_interface) [self setContentMinSize:NSMakeSize(604., 288. + [o_titlebar_view frame].size.height)]; - [o_detached_video_window setContentMinSize: NSMakeSize(363., f_min_video_height + [o_detached_bottombar_view frame].size.height + [o_titlebar_view frame].size.height)]; - } else { + else [self setContentMinSize:NSMakeSize(604., 288.)]; - [o_detached_video_window setContentMinSize: NSMakeSize(363., f_min_video_height + [o_detached_bottombar_view frame].size.height)]; - } [self setTitle: _NS("VLC media player")]; - [o_time_fld setAlignment: NSCenterTextAlignment]; - [o_time_fld setNeedsDisplay:YES]; + b_dropzone_active = YES; - 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 (b_nativeFullscreenMode) { - NSRect frame; - [self setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; - 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); - #undef moveItem - - frame = [o_progress_view frame]; - frame.size.width = f_width + frame.size.width; - [o_progress_view setFrame: frame]; - - [o_fullscreen_btn removeFromSuperviewWithoutNeedingDisplay]; - } else { - [o_titlebar_view setFullscreenButtonHidden: YES]; - } if (!OSX_SNOW_LEOPARD) { /* the default small size of the search field is slightly different on Lion, let's work-around that */ @@ -449,19 +249,19 @@ static VLCMainWindow *_o_sharedInstance = nil; else [[internetItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]]; [[internetItems lastObject] setSdtype: SD_CAT_INTERNET]; - [[internetItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]]; + [[internetItems lastObject] setUntranslatedTitle: @(*ppsz_longname)]; break; case SD_CAT_DEVICES: [devicesItems addObject: [SideBarItem itemWithTitle: _NS(*ppsz_longname) identifier: o_identifier]]; [[devicesItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]]; [[devicesItems lastObject] setSdtype: SD_CAT_DEVICES]; - [[devicesItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]]; + [[devicesItems lastObject] setUntranslatedTitle: @(*ppsz_longname)]; break; case SD_CAT_LAN: [lanItems addObject: [SideBarItem itemWithTitle: _NS(*ppsz_longname) identifier: o_identifier]]; [[lanItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-local"]]; [[lanItems lastObject] setSdtype: SD_CAT_LAN]; - [[lanItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]]; + [[lanItems lastObject] setUntranslatedTitle: @(*ppsz_longname)]; break; case SD_CAT_MYCOMPUTER: [mycompItems addObject: [SideBarItem itemWithTitle: _NS(*ppsz_longname) identifier: o_identifier]]; @@ -473,7 +273,7 @@ static VLCMainWindow *_o_sharedInstance = nil; [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-pictures"]]; else [[mycompItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]]; - [[mycompItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]]; + [[mycompItems lastObject] setUntranslatedTitle: @(*ppsz_longname)]; [[mycompItems lastObject] setSdtype: SD_CAT_MYCOMPUTER]; break; default: @@ -496,7 +296,7 @@ static VLCMainWindow *_o_sharedInstance = nil; free(ppsz_longnames); free(p_categories); - [libraryItem setChildren: [NSArray arrayWithObjects: playlistItem, medialibraryItem, nil]]; + [libraryItem setChildren: @[playlistItem, medialibraryItem]]; [o_sidebaritems addObject: libraryItem]; if ([mycompItem hasChildren]) [o_sidebaritems addObject: mycompItem]; @@ -510,7 +310,7 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_sidebar_view reloadData]; [o_sidebar_view selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO]; [o_sidebar_view setDropItem:playlistItem dropChildIndex:NSOutlineViewDropOnItemIndex]; - [o_sidebar_view registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, @"VLCPlaylistItemPboardType", nil]]; + [o_sidebar_view registerForDraggedTypes:@[NSFilenamesPboardType, @"VLCPlaylistItemPboardType"]]; [o_sidebar_view setAutosaveName:@"mainwindow-sidebar"]; [(PXSourceList *)o_sidebar_view setDataSource:self]; @@ -526,7 +326,9 @@ static VLCMainWindow *_o_sharedInstance = nil; NSUInteger i_sidebaritem_count = [o_sidebaritems count]; for (NSUInteger x = 0; x < i_sidebaritem_count; x++) - [o_sidebar_view expandItem: [o_sidebaritems objectAtIndex: x] expandChildren: YES]; + [o_sidebar_view expandItem: [o_sidebaritems objectAtIndex:x] expandChildren: YES]; + + [o_fspanel center]; } if (b_dark_interface) { @@ -560,426 +362,46 @@ static VLCMainWindow *_o_sharedInstance = nil; [[self contentView] addSubview: o_color_backdrop positioned: NSWindowBelow relativeTo: o_split_view]; [o_color_backdrop setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; } else { - NSRect frame; - frame = [o_time_sld_fancygradient_view frame]; - frame.size.height = frame.size.height - 1; - frame.origin.y = frame.origin.y + 1; - [o_time_sld_fancygradient_view setFrame: frame]; - - frame = [o_detached_time_sld_fancygradient_view frame]; - frame.size.height = frame.size.height - 1; - frame.origin.y = frame.origin.y + 1; - [o_detached_time_sld_fancygradient_view setFrame: frame]; - [o_video_view setFrame: [o_split_view frame]]; [o_playlist_table setBorderType: NSNoBorder]; [o_sidebar_scrollview setBorderType: NSNoBorder]; } - NSRect frame; - frame = [o_time_sld_fancygradient_view frame]; - frame.size.width = 0; - [o_time_sld_fancygradient_view setFrame: frame]; - - frame = [o_detached_time_sld_fancygradient_view frame]; - frame.size.width = 0; - [o_detached_time_sld_fancygradient_view setFrame: frame]; - - if (!OSX_SNOW_LEOPARD) { - [o_resize_view setImage: NULL]; - [o_detached_resize_view setImage: NULL]; - } - - if ([self styleMask] & NSResizableWindowMask) { - [o_resize_view removeFromSuperviewWithoutNeedingDisplay]; - [o_detached_resize_view removeFromSuperviewWithoutNeedingDisplay]; - } - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(someWindowWillClose:) name: NSWindowWillCloseNotification object: nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(someWindowWillMiniaturize:) name: NSWindowWillMiniaturizeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationWillTerminate:) name: NSApplicationWillTerminateNotification object: nil]; - [[VLCMain sharedInstance] playbackModeUpdated]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(mainSplitViewDidResizeSubviews:) name: NSSplitViewDidResizeSubviewsNotification object:o_split_view]; - [o_split_view setAutosaveName:@"10thanniversary-splitview"]; if (b_splitviewShouldBeHidden) { [self hideSplitView]; i_lastSplitViewHeight = 300; } /* sanity check for the window size */ - frame = [self frame]; + NSRect frame = [self frame]; NSSize screenSize = [[self screen] frame].size; if (screenSize.width <= frame.size.width || screenSize.height <= frame.size.height) { nativeVideoSize = screenSize; [self resizeWindow]; } -} - -#pragma mark - -#pragma mark interface customization -- (void)toggleJumpButtons -{ - b_show_jump_buttons = config_GetInt(VLCIntf, "macosx-show-playback-buttons"); - - if (b_show_jump_buttons) - [self addJumpButtons:NO]; - else - [self removeJumpButtons:NO]; -} - -- (void)addJumpButtons:(BOOL)b_fast -{ - NSRect preliminaryFrame = [o_bwd_btn frame]; - BOOL b_enabled = [o_bwd_btn isEnabled]; - preliminaryFrame.size.width = 29.; - o_prev_btn = [[NSButton alloc] initWithFrame:preliminaryFrame]; - [o_prev_btn setButtonType: NSMomentaryChangeButton]; - [o_prev_btn setBezelStyle:NSRegularSquareBezelStyle]; - [o_prev_btn setBordered:NO]; - [o_prev_btn setTarget:self]; - [o_prev_btn setAction:@selector(prev:)]; - [o_prev_btn setToolTip: _NS("Previous")]; - [[o_prev_btn cell] accessibilitySetOverrideValue:_NS("Previous") forAttribute:NSAccessibilityTitleAttribute]; - [[o_prev_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the previous playlist item.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_prev_btn setEnabled: b_enabled]; - - o_next_btn = [[NSButton alloc] initWithFrame:preliminaryFrame]; - [o_next_btn setButtonType: NSMomentaryChangeButton]; - [o_next_btn setBezelStyle:NSRegularSquareBezelStyle]; - [o_next_btn setBordered:NO]; - [o_next_btn setTarget:self]; - [o_next_btn setAction:@selector(next:)]; - [o_next_btn setToolTip: _NS("Next")]; - [[o_next_btn cell] accessibilitySetOverrideValue:_NS("Next") forAttribute:NSAccessibilityTitleAttribute]; - [[o_next_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the next playlist item.") forAttribute:NSAccessibilityDescriptionAttribute]; - [o_next_btn setEnabled: b_enabled]; - - if (b_dark_interface) { - [o_prev_btn setImage: [NSImage imageNamed:@"previous-6btns-dark"]]; - [o_prev_btn setAlternateImage: [NSImage imageNamed:@"previous-6btns-dark-pressed"]]; - [o_next_btn setImage: [NSImage imageNamed:@"next-6btns-dark"]]; - [o_next_btn setAlternateImage: [NSImage imageNamed:@"next-6btns-dark-pressed"]]; - } else { - [o_prev_btn setImage: [NSImage imageNamed:@"previous-6btns"]]; - [o_prev_btn setAlternateImage: [NSImage imageNamed:@"previous-6btns-pressed"]]; - [o_next_btn setImage: [NSImage imageNamed:@"next-6btns"]]; - [o_next_btn setAlternateImage: [NSImage imageNamed:@"next-6btns-pressed"]]; - } - - /* change the accessibility help for the backward/forward buttons accordingly */ - [[o_bwd_btn cell] accessibilitySetOverrideValue:_NS("Click and hold to skip backward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_fwd_btn cell] accessibilitySetOverrideValue:_NS("Click and hold to skip forward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - - NSRect frame; - frame = [o_bwd_btn frame]; - frame.size.width++; - [o_bwd_btn setFrame:frame]; - frame = [o_fwd_btn frame]; - frame.size.width++; - [o_fwd_btn setFrame:frame]; - - float f_space = 29.; - #define moveItem(item) \ - frame = [item frame]; \ - frame.origin.x = frame.origin.x + f_space; \ - if (b_fast) \ - [item setFrame: frame]; \ - else \ - [[item animator] setFrame: frame] - - moveItem(o_bwd_btn); - moveItem(o_play_btn); - f_space = 28.; - moveItem(o_fwd_btn); - f_space = 57.; - moveItem(o_stop_btn); - moveItem(o_playlist_btn); - moveItem(o_repeat_btn); - moveItem(o_shuffle_btn); - #undef moveItem - - frame = [o_progress_view frame]; - frame.size.width = frame.size.width - f_space; - frame.origin.x = frame.origin.x + f_space; - if (b_fast) - [o_progress_view setFrame: frame]; - else - [[o_progress_view animator] setFrame: frame]; - - if (b_dark_interface) { - [[o_fwd_btn animator] setImage:[NSImage imageNamed:@"forward-6btns-dark"]]; - [[o_fwd_btn animator] setAlternateImage:[NSImage imageNamed:@"forward-6btns-dark-pressed"]]; - [[o_bwd_btn animator] setImage:[NSImage imageNamed:@"backward-6btns-dark"]]; - [[o_bwd_btn animator] setAlternateImage:[NSImage imageNamed:@"backward-6btns-dark-pressed"]]; - } else { - [[o_fwd_btn animator] setImage:[NSImage imageNamed:@"forward-6btns"]]; - [[o_fwd_btn animator] setAlternateImage:[NSImage imageNamed:@"forward-6btns-pressed"]]; - [[o_bwd_btn animator] setImage:[NSImage imageNamed:@"backward-6btns"]]; - [[o_bwd_btn animator] setAlternateImage:[NSImage imageNamed:@"backward-6btns-pressed"]]; - } - - preliminaryFrame.origin.x = [o_next_btn frame].origin.x + 82. + [o_fwd_btn frame].size.width; - [o_next_btn setFrame: preliminaryFrame]; - - // wait until the animation is done, if displayed - if (b_fast) { - [[self contentView] addSubview:o_prev_btn]; - [[self contentView] addSubview:o_next_btn]; - } else { - [[self contentView] performSelector:@selector(addSubview:) withObject:o_prev_btn afterDelay:.2]; - [[self contentView] performSelector:@selector(addSubview:) withObject:o_next_btn afterDelay:.2]; - } - - [o_fwd_btn setAction:@selector(forward:)]; - [o_bwd_btn setAction:@selector(backward:)]; -} - -- (void)removeJumpButtons:(BOOL)b_fast -{ - if (!o_prev_btn || !o_next_btn) - return; - - if (b_fast) { - [o_prev_btn setHidden: YES]; - [o_next_btn setHidden: YES]; - } else { - [[o_prev_btn animator] setHidden: YES]; - [[o_next_btn animator] setHidden: YES]; - } - [o_prev_btn removeFromSuperviewWithoutNeedingDisplay]; - [o_next_btn removeFromSuperviewWithoutNeedingDisplay]; - [o_prev_btn release]; - [o_next_btn release]; - - /* change the accessibility help for the backward/forward buttons accordingly */ - [[o_bwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the previous playlist item. Hold to skip backward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - [[o_fwd_btn cell] accessibilitySetOverrideValue:_NS("Click to go to the next playlist item. Hold to skip forward through the current media.") forAttribute:NSAccessibilityDescriptionAttribute]; - - NSRect frame; - frame = [o_bwd_btn frame]; - frame.size.width--; - [o_bwd_btn setFrame:frame]; - frame = [o_fwd_btn frame]; - frame.size.width--; - [o_fwd_btn setFrame:frame]; - - float f_space = 29.; - #define moveItem(item) \ - frame = [item frame]; \ - frame.origin.x = frame.origin.x - f_space; \ - if (b_fast) \ - [item setFrame: frame]; \ - else \ - [[item animator] setFrame: frame] - - moveItem(o_bwd_btn); - moveItem(o_play_btn); - f_space = 28.; - moveItem(o_fwd_btn); - f_space = 57.; - moveItem(o_stop_btn); - moveItem(o_playlist_btn); - moveItem(o_repeat_btn); - moveItem(o_shuffle_btn); - #undef moveItem - - frame = [o_progress_view frame]; - frame.size.width = frame.size.width + f_space; - frame.origin.x = frame.origin.x - f_space; - if (b_fast) - [o_progress_view setFrame: frame]; - else - [[o_progress_view animator] setFrame: frame]; - - if (b_dark_interface) { - [[o_fwd_btn animator] setImage:[NSImage imageNamed:@"forward-3btns-dark"]]; - [[o_fwd_btn animator] setAlternateImage:[NSImage imageNamed:@"forward-3btns-dark-pressed"]]; - [[o_bwd_btn animator] setImage:[NSImage imageNamed:@"backward-3btns-dark"]]; - [[o_bwd_btn animator] setAlternateImage:[NSImage imageNamed:@"backward-3btns-dark-pressed"]]; - } else { - [[o_fwd_btn animator] setImage:[NSImage imageNamed:@"forward-3btns"]]; - [[o_fwd_btn animator] setAlternateImage:[NSImage imageNamed:@"forward-3btns-pressed"]]; - [[o_bwd_btn animator] setImage:[NSImage imageNamed:@"backward-3btns"]]; - [[o_bwd_btn animator] setAlternateImage:[NSImage imageNamed:@"backward-3btns-pressed"]]; - } - - [o_bottombar_view setNeedsDisplay:YES]; - - [o_fwd_btn setAction:@selector(fwd:)]; - [o_bwd_btn setAction:@selector(bwd:)]; -} - -- (void)togglePlaymodeButtons -{ - b_show_playmode_buttons = config_GetInt(VLCIntf, "macosx-show-playmode-buttons"); - - if (b_show_playmode_buttons) - [self addPlaymodeButtons:NO]; - else - [self removePlaymodeButtons:NO]; -} - -- (void)addPlaymodeButtons:(BOOL)b_fast -{ - NSRect frame; - float f_space = [o_repeat_btn frame].size.width + [o_shuffle_btn frame].size.width - 6.; - - if (b_dark_interface) { - [[o_playlist_btn animator] setImage:[NSImage imageNamed:@"playlist_dark"]]; - [[o_playlist_btn animator] setAlternateImage:[NSImage imageNamed:@"playlist-pressed_dark"]]; - } else { - [[o_playlist_btn animator] setImage:[NSImage imageNamed:@"playlist-btn"]]; - [[o_playlist_btn animator] setAlternateImage:[NSImage imageNamed:@"playlist-btn-pressed"]]; - } - frame = [o_playlist_btn frame]; - frame.size.width--; - [o_playlist_btn setFrame:frame]; - if (b_fast) { - [o_repeat_btn setHidden: NO]; - [o_shuffle_btn setHidden: NO]; - } else { - [[o_repeat_btn animator] setHidden: NO]; - [[o_shuffle_btn animator] setHidden: NO]; - } - - frame = [o_progress_view frame]; - frame.size.width = frame.size.width - f_space; - frame.origin.x = frame.origin.x + f_space; - if (b_fast) - [o_progress_view setFrame: frame]; - else - [[o_progress_view animator] setFrame: frame]; -} - -- (void)removePlaymodeButtons:(BOOL)b_fast -{ - NSRect frame; - float f_space = [o_repeat_btn frame].size.width + [o_shuffle_btn frame].size.width - 6.; - [o_repeat_btn setHidden: YES]; - [o_shuffle_btn setHidden: YES]; + /* update fs button to reflect state for next startup */ + if (var_InheritBool(pl_Get(VLCIntf), "fullscreen")) + [o_controls_bar setFullscreenState:YES]; - if (b_dark_interface) { - [[o_playlist_btn animator] setImage:[NSImage imageNamed:@"playlist-1btn-dark"]]; - [[o_playlist_btn animator] setAlternateImage:[NSImage imageNamed:@"playlist-1btn-dark-pressed"]]; - } else { - [[o_playlist_btn animator] setImage:[NSImage imageNamed:@"playlist-1btn"]]; - [[o_playlist_btn animator] setAlternateImage:[NSImage imageNamed:@"playlist-1btn-pressed"]]; - } - frame = [o_playlist_btn frame]; - frame.size.width++; - [o_playlist_btn setFrame:frame]; - - frame = [o_progress_view frame]; - frame.size.width = frame.size.width + f_space; - frame.origin.x = frame.origin.x - f_space; - if (b_fast) - [o_progress_view setFrame: frame]; - else - [[o_progress_view animator] setFrame: frame]; + /* restore split view */ + i_lastLeftSplitViewWidth = 200; + /* trick NSSplitView implementation, which pretends to know better than us */ + if (!config_GetInt(VLCIntf, "macosx-show-sidebar")) + [self performSelector:@selector(toggleLeftSubSplitView) withObject:nil afterDelay:0.05]; } #pragma mark - -#pragma mark Button Actions - -- (IBAction)play:(id)sender -{ - [[VLCCoreInteraction sharedInstance] play]; -} - -- (void)resetPreviousButton -{ - if (([NSDate timeIntervalSinceReferenceDate] - last_bwd_event) >= 0.35) { - // seems like no further event occurred, so let's switch the playback item - [[VLCCoreInteraction sharedInstance] previous]; - just_triggered_previous = NO; - } -} - -- (void)resetBackwardSkip -{ - // the user stopped skipping, so let's allow him to change the item - if (([NSDate timeIntervalSinceReferenceDate] - last_bwd_event) >= 0.35) - just_triggered_previous = NO; -} - -- (IBAction)prev:(id)sender -{ - [[VLCCoreInteraction sharedInstance] previous]; -} - -- (IBAction)bwd:(id)sender -{ - if (!just_triggered_previous) { - just_triggered_previous = YES; - [self performSelector:@selector(resetPreviousButton) - withObject: NULL - afterDelay:0.40]; - } else { - if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.16) { - // we just skipped 4 "continous" events, otherwise we are too fast - [[VLCCoreInteraction sharedInstance] backwardExtraShort]; - last_bwd_event = [NSDate timeIntervalSinceReferenceDate]; - [self performSelector:@selector(resetBackwardSkip) - withObject: NULL - afterDelay:0.40]; - } - } -} - -- (IBAction)backward:(id)sender -{ - [[VLCCoreInteraction sharedInstance] backwardShort]; -} - -- (void)resetNextButton -{ - if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) >= 0.35) { - // seems like no further event occurred, so let's switch the playback item - [[VLCCoreInteraction sharedInstance] next]; - just_triggered_next = NO; - } -} - -- (void)resetForwardSkip -{ - // the user stopped skipping, so let's allow him to change the item - if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) >= 0.35) - just_triggered_next = NO; -} +#pragma mark appearance management -- (IBAction)next:(id)sender +- (VLCMainWindowControlsBar *)controlsBar; { - [[VLCCoreInteraction sharedInstance] next]; -} - -- (IBAction)forward:(id)sender -{ - [[VLCCoreInteraction sharedInstance] forwardShort]; -} - -- (IBAction)fwd:(id)sender -{ - if (!just_triggered_next) { - just_triggered_next = YES; - [self performSelector:@selector(resetNextButton) - withObject: NULL - afterDelay:0.40]; - } else { - if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.16) { - // we just skipped 4 "continous" events, otherwise we are too fast - [[VLCCoreInteraction sharedInstance] forwardExtraShort]; - last_fwd_event = [NSDate timeIntervalSinceReferenceDate]; - [self performSelector:@selector(resetForwardSkip) - withObject: NULL - afterDelay:0.40]; - } - } -} - -- (IBAction)stop:(id)sender -{ - [[VLCCoreInteraction sharedInstance] stop]; + return (VLCMainWindowControlsBar *)o_controls_bar; } - (void)resizePlaylistAfterCollapse @@ -1016,8 +438,12 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_video_view setHidden: YES]; [o_split_view setHidden: NO]; - [self makeFirstResponder: nil]; + if ([self fullscreen]) { + [[o_controls_bar bottomBarView] setHidden: NO]; + [o_fspanel setNonActive:nil]; + } + [self makeFirstResponder: o_playlist_table]; } - (void)makeSplitViewHidden @@ -1029,11 +455,16 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_split_view setHidden: YES]; [o_video_view setHidden: NO]; + if ([self fullscreen]) { + [[o_controls_bar bottomBarView] setHidden: YES]; + [o_fspanel setActive:nil]; + } if ([[o_video_view subviews] count] > 0) [self makeFirstResponder: [[o_video_view subviews] objectAtIndex:0]]; } +// only exception for an controls bar button action - (IBAction)togglePlaylist:(id)sender { if (![self isVisible] && sender != nil) { @@ -1044,17 +475,16 @@ static VLCMainWindow *_o_sharedInstance = nil; BOOL b_activeVideo = [[VLCMain sharedInstance] activeVideoPlayback]; BOOL b_restored = NO; - // TODO: implement toggle playlist in this situation (triggerd via menu item). - // but for now we block this case, to avoid displaying only the half - if (b_nativeFullscreenMode && b_fullscreen && b_activeVideo && sender != nil) - return; + BOOL b_have_alt_key = ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0; + if (sender && [sender isKindOfClass: [NSMenuItem class]]) + b_have_alt_key = NO; - if (b_dropzone_active && ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0) { + if (b_dropzone_active && b_have_alt_key) { [self hideDropZone]; return; } - if (!(b_nativeFullscreenMode && b_fullscreen) && !b_splitview_removed && ((([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0 && b_activeVideo) + if (!(b_nativeFullscreenMode && b_fullscreen) && !b_splitview_removed && ((b_have_alt_key && b_activeVideo) || (b_nonembedded && sender != nil) || (!b_activeVideo && sender != nil) || b_minimized_view)) @@ -1081,128 +511,11 @@ static VLCMainWindow *_o_sharedInstance = nil; } else { [o_split_view setHidden: NO]; [o_playlist_table setHidden: NO]; - [o_video_view setHidden: !b_activeVideo]; - if (b_activeVideo && [[o_video_view subviews] count] > 0) - [[o_video_view window] makeFirstResponder: [[o_video_view subviews] objectAtIndex:0]]; + [o_video_view setHidden: YES]; } } } -- (void)setRepeatOne -{ - [o_repeat_btn setImage: o_repeat_one_img]; - [o_repeat_btn setAlternateImage: o_repeat_one_pressed_img]; -} - -- (void)setRepeatAll -{ - [o_repeat_btn setImage: o_repeat_all_img]; - [o_repeat_btn setAlternateImage: o_repeat_all_pressed_img]; -} - -- (void)setRepeatOff -{ - [o_repeat_btn setImage: o_repeat_img]; - [o_repeat_btn setAlternateImage: o_repeat_pressed_img]; -} - -- (IBAction)repeat:(id)sender -{ - vlc_value_t looping,repeating; - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Get(p_intf); - - var_Get(p_playlist, "repeat", &repeating); - var_Get(p_playlist, "loop", &looping); - - if (!repeating.b_bool && !looping.b_bool) { - /* was: no repeating at all, switching to Repeat One */ - [[VLCCoreInteraction sharedInstance] repeatOne]; - [self setRepeatOne]; - } - else if (repeating.b_bool && !looping.b_bool) { - /* was: Repeat One, switching to Repeat All */ - [[VLCCoreInteraction sharedInstance] repeatAll]; - [self setRepeatAll]; - } else { - /* was: Repeat All or bug in VLC, switching to Repeat Off */ - [[VLCCoreInteraction sharedInstance] repeatOff]; - [self setRepeatOff]; - } -} - -- (void)setShuffle -{ - bool b_value; - playlist_t *p_playlist = pl_Get(VLCIntf); - b_value = var_GetBool(p_playlist, "random"); - - if (b_value) { - [o_shuffle_btn setImage: o_shuffle_on_img]; - [o_shuffle_btn setAlternateImage: o_shuffle_on_pressed_img]; - } else { - [o_shuffle_btn setImage: o_shuffle_img]; - [o_shuffle_btn setAlternateImage: o_shuffle_pressed_img]; - } -} - -- (IBAction)shuffle:(id)sender -{ - [[VLCCoreInteraction sharedInstance] shuffle]; - [self setShuffle]; -} - -- (IBAction)timeSliderAction:(id)sender -{ - float f_updated; - input_thread_t * p_input; - - switch([[NSApp currentEvent] type]) { - case NSLeftMouseUp: - case NSLeftMouseDown: - case NSLeftMouseDragged: - f_updated = [sender floatValue]; - break; - - default: - return; - } - p_input = pl_CurrentInput(VLCIntf); - if (p_input != NULL) { - vlc_value_t pos; - NSString * o_time; - - pos.f_float = f_updated / 10000.; - var_Set(p_input, "position", pos); - [o_time_sld setFloatValue: f_updated]; - - o_time = [[VLCStringUtility sharedInstance] getCurrentTimeAsString: p_input negative:[o_time_fld timeRemaining]]; - [o_time_fld setStringValue: o_time]; - [o_fspanel setStreamPos: f_updated andTime: o_time]; - vlc_object_release(p_input); - } -} - -- (IBAction)volumeAction:(id)sender -{ - if (sender == o_volume_sld) - [[VLCCoreInteraction sharedInstance] setVolume: [sender intValue]]; - else if (sender == o_volume_down_btn) - [[VLCCoreInteraction sharedInstance] toggleMute]; - else - [[VLCCoreInteraction sharedInstance] setVolume: AOUT_VOLUME_MAX]; -} - -- (IBAction)effects:(id)sender -{ - [[VLCMainMenu sharedInstance] showAudioEffects: sender]; -} - -- (IBAction)fullscreen:(id)sender -{ - [[VLCCoreInteraction sharedInstance] toggleFullscreen]; -} - - (IBAction)dropzoneButtonAction:(id)sender { [[[VLCMain sharedInstance] open] openFileGeneric]; @@ -1210,10 +523,6 @@ static VLCMainWindow *_o_sharedInstance = nil; #pragma mark - #pragma mark overwritten default functionality -- (BOOL)canBecomeKeyWindow -{ - return YES; -} - (void)windowResizedOrMoved:(NSNotification *)notification { @@ -1222,6 +531,8 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)applicationWillTerminate:(NSNotification *)notification { + config_PutInt(VLCIntf, "macosx-show-sidebar", ![o_split_view isSubviewCollapsed:o_left_split_view]); + [self saveFrameUsingName: [self frameAutosaveName]]; } @@ -1229,7 +540,9 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)someWindowWillClose:(NSNotification *)notification { id obj = [notification object]; - if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) { + + // hasActiveVideo is defined for VLCVideoWindowCommon and subclasses + if ([obj respondsToSelector:@selector(hasActiveVideo)] && [obj hasActiveVideo]) { if ([[VLCMain sharedInstance] activeVideoPlayback]) [[VLCCoreInteraction sharedInstance] stop]; } @@ -1239,38 +552,14 @@ static VLCMainWindow *_o_sharedInstance = nil; { if (config_GetInt(VLCIntf, "macosx-pause-minimized")) { id obj = [notification object]; - if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) { + + if ([obj class] == [VLCVideoWindowCommon class] || [obj class] == [VLCDetachedVideoWindow class] || ([obj class] == [VLCMainWindow class] && !b_nonembedded)) { if ([[VLCMain sharedInstance] activeVideoPlayback]) [[VLCCoreInteraction sharedInstance] pause]; } } } -- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize -{ - id videoWindow = [o_video_view window]; - if (![[VLCMain sharedInstance] activeVideoPlayback] || nativeVideoSize.width == 0. || nativeVideoSize.height == 0. || window != videoWindow) - return proposedFrameSize; - - // needed when entering lion fullscreen mode - if (b_fullscreen) - return proposedFrameSize; - - if ([[VLCCoreInteraction sharedInstance] aspectRatioIsLocked]) { - NSRect videoWindowFrame = [videoWindow frame]; - NSRect viewRect = [o_video_view convertRect:[o_video_view bounds] toView: nil]; - NSRect contentRect = [videoWindow contentRectForFrameRect:videoWindowFrame]; - float marginy = viewRect.origin.y + videoWindowFrame.size.height - contentRect.size.height; - float marginx = contentRect.size.width - viewRect.size.width; - if (b_dark_interface)// && b_video_deco) - marginy += [o_titlebar_view frame].size.height; - - proposedFrameSize.height = (proposedFrameSize.width - marginx) * nativeVideoSize.height / nativeVideoSize.width + marginy; - } - - return proposedFrameSize; -} - #pragma mark - #pragma mark Update interface and respond to foreign events - (void)showDropZone @@ -1297,11 +586,11 @@ static VLCMainWindow *_o_sharedInstance = nil; [self setFrame: winrect display: YES animate: YES]; [self performSelector:@selector(hideDropZone) withObject:nil afterDelay:0.1]; if (b_dark_interface) { - [self setContentMinSize: NSMakeSize(604., [o_bottombar_view frame].size.height + [o_titlebar_view frame].size.height)]; - [self setContentMaxSize: NSMakeSize(FLT_MAX, [o_bottombar_view frame].size.height + [o_titlebar_view frame].size.height)]; + [self setContentMinSize: NSMakeSize(604., [o_controls_bar height] + [o_titlebar_view frame].size.height)]; + [self setContentMaxSize: NSMakeSize(FLT_MAX, [o_controls_bar height] + [o_titlebar_view frame].size.height)]; } else { - [self setContentMinSize: NSMakeSize(604., [o_bottombar_view frame].size.height)]; - [self setContentMaxSize: NSMakeSize(FLT_MAX, [o_bottombar_view frame].size.height)]; + [self setContentMinSize: NSMakeSize(604., [o_controls_bar height])]; + [self setContentMaxSize: NSMakeSize(FLT_MAX, [o_controls_bar height])]; } b_splitview_removed = YES; @@ -1329,62 +618,10 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)updateTimeSlider { - input_thread_t * p_input; - p_input = pl_CurrentInput(VLCIntf); - if (p_input) { - NSString * o_time; - vlc_value_t pos; - float f_updated; - - var_Get(p_input, "position", &pos); - f_updated = 10000. * pos.f_float; - [o_time_sld setFloatValue: f_updated]; - - o_time = [[VLCStringUtility sharedInstance] getCurrentTimeAsString: p_input negative:[o_time_fld timeRemaining]]; - - mtime_t dur = input_item_GetDuration(input_GetItem(p_input)); - if (dur == -1) { - [o_time_sld setEnabled: NO]; - [o_time_sld setHidden: YES]; - [o_time_sld_fancygradient_view setHidden: YES]; - } else { - [o_time_sld setEnabled: YES]; - [o_time_sld setHidden: NO]; - [o_time_sld_fancygradient_view setHidden: NO]; - } - - [o_time_fld setStringValue: o_time]; - [o_time_fld setNeedsDisplay:YES]; - [o_fspanel setStreamPos: f_updated andTime: o_time]; - vlc_object_release(p_input); - } else { - [o_time_sld setFloatValue: 0.0]; - [o_time_fld setStringValue: @"00:00"]; - [o_time_sld setEnabled: NO]; - [o_time_sld setHidden: YES]; - [o_time_sld_fancygradient_view setHidden: YES]; - [o_detached_time_sld_fancygradient_view setHidden: YES]; - } - - [o_detached_time_sld setFloatValue: [o_time_sld floatValue]]; - [o_detached_time_sld setEnabled: [o_time_sld isEnabled]]; - [o_detached_time_fld setStringValue: [o_time_fld stringValue]]; - [o_detached_time_sld setHidden: [o_time_sld isHidden]]; -} - -- (void)updateVolumeSlider -{ - int i_volume = [[VLCCoreInteraction sharedInstance] volume]; - BOOL b_muted = [[VLCCoreInteraction sharedInstance] mute]; - - if (!b_muted) { - [o_volume_sld setIntValue: i_volume]; - [o_fspanel setVolumeLevel: i_volume]; - } else - [o_volume_sld setIntValue: 0]; + [o_controls_bar updateTimeSlider]; + [o_fspanel updatePositionAndTime]; - [o_volume_sld setEnabled: !b_muted]; - [o_volume_up_btn setEnabled: !b_muted]; + [[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(updateTimeSlider)]; } - (void)updateName @@ -1393,21 +630,29 @@ static VLCMainWindow *_o_sharedInstance = nil; p_input = pl_CurrentInput(VLCIntf); if (p_input) { NSString *aString; - char *format = var_InheritString(VLCIntf, "input-title-format"); - char *formated = str_format_meta(pl_Get(VLCIntf), format); - free(format); - aString = [NSString stringWithUTF8String:formated]; - free(formated); + + if (!config_GetPsz(VLCIntf, "video-title")) { + char *format = var_InheritString(VLCIntf, "input-title-format"); + char *formated = str_format_meta(pl_Get(VLCIntf), format); + free(format); + aString = @(formated); + free(formated); + } else + aString = @(config_GetPsz(VLCIntf, "video-title")); char *uri = input_item_GetURI(input_GetItem(p_input)); - NSURL * o_url = [NSURL URLWithString: [NSString stringWithUTF8String: uri]]; + NSURL * o_url = [NSURL URLWithString: @(uri)]; if ([o_url isFileURL]) { [self setRepresentedURL: o_url]; - [o_detached_video_window setRepresentedURL: o_url]; + [[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) { + [o_window setRepresentedURL:o_url]; + }]; } else { [self setRepresentedURL: nil]; - [o_detached_video_window setRepresentedURL: nil]; + [[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) { + [o_window setRepresentedURL:nil]; + }]; } free(uri); @@ -1418,11 +663,18 @@ static VLCMainWindow *_o_sharedInstance = nil; aString = [o_url absoluteString]; } - [self setTitle: aString]; - if (b_nonembedded && [[VLCMain sharedInstance] activeVideoPlayback]) - [o_detached_video_window setTitle: aString]; + if ([aString length] > 0) { + [self setTitle: aString]; + [[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) { + [o_window setTitle:aString]; + }]; + + [o_fspanel setStreamTitle: aString]; + } else { + [self setTitle: _NS("VLC media player")]; + [self setRepresentedURL: nil]; + } - [o_fspanel setStreamTitle: aString]; vlc_object_release(p_input); } else { [self setTitle: _NS("VLC media player")]; @@ -1432,63 +684,23 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)updateWindow { - bool b_input = false; - bool b_plmul = false; - bool b_control = false; + [o_controls_bar updateControls]; + [[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(updateControls)]; + bool b_seekable = false; - bool b_chapters = false; playlist_t * p_playlist = pl_Get(VLCIntf); - - PL_LOCK; - b_plmul = playlist_CurrentSize(p_playlist) > 1; - PL_UNLOCK; - input_thread_t * p_input = playlist_CurrentInput(p_playlist); - - bool b_buffering = NO; - - if ((b_input = (p_input != NULL))) { - /* seekable streams */ - cachedInputState = input_GetState(p_input); - if (cachedInputState == INIT_S || cachedInputState == OPENING_S) - b_buffering = YES; - + if (p_input) { /* seekable streams */ b_seekable = var_GetBool(p_input, "can-seek"); - /* check whether slow/fast motion is possible */ - b_control = var_GetBool(p_input, "can-rate"); - - /* chapters & titles */ - //FIXME! b_chapters = p_input->stream.i_area_nb > 1; - vlc_object_release(p_input); } - if (b_buffering) { - [o_progress_bar startAnimation:self]; - [o_progress_bar setIndeterminate:YES]; - [o_progress_bar setHidden:NO]; - } else { - [o_progress_bar stopAnimation:self]; - [o_progress_bar setHidden:YES]; - } - - [o_stop_btn setEnabled: b_input]; - [o_fwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - [o_bwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - if (b_show_jump_buttons) { - [o_prev_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - [o_next_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - } - [o_detached_fwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - [o_detached_bwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)]; - [[VLCMainMenu sharedInstance] setRateControlsEnabled: b_control]; - - [o_time_sld setEnabled: b_seekable]; [self updateTimeSlider]; - [o_fspanel setSeekable: b_seekable]; + if ([o_fspanel respondsToSelector:@selector(setSeekable:)]) + [o_fspanel setSeekable: b_seekable]; PL_LOCK; if ([[[VLCMain sharedInstance] playlist] currentPlaylistRoot] != p_playlist->p_local_category || p_playlist->p_local_category->i_children > 0) @@ -1501,789 +713,107 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)setPause { - [o_play_btn setImage: o_pause_img]; - [o_play_btn setAlternateImage: o_pause_pressed_img]; - [o_play_btn setToolTip: _NS("Pause")]; - [o_detached_play_btn setImage: o_pause_img]; - [o_detached_play_btn setAlternateImage: o_pause_pressed_img]; - [o_detached_play_btn setToolTip: _NS("Pause")]; + [o_controls_bar setPause]; [o_fspanel setPause]; + + [[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(setPause)]; } - (void)setPlay { - [o_play_btn setImage: o_play_img]; - [o_play_btn setAlternateImage: o_play_pressed_img]; - [o_play_btn setToolTip: _NS("Play")]; - [o_detached_play_btn setImage: o_play_img]; - [o_detached_play_btn setAlternateImage: o_play_pressed_img]; - [o_detached_play_btn setToolTip: _NS("Play")]; + [o_controls_bar setPlay]; [o_fspanel setPlay]; + + [[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(setPlay)]; + } -- (void)drawFancyGradientEffectForTimeSlider +- (void)updateVolumeSlider { - NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; - CGFloat f_value = [o_time_sld knobPosition]; - if (f_value > 7.5) { - NSRect oldFrame = [o_time_sld_fancygradient_view frame]; - if (f_value != oldFrame.size.width) { - if ([o_time_sld_fancygradient_view isHidden]) - [o_time_sld_fancygradient_view setHidden: NO]; - [o_time_sld_fancygradient_view setFrame: NSMakeRect(oldFrame.origin.x, oldFrame.origin.y, f_value, oldFrame.size.height)]; - } - - if (b_nonembedded) { - f_value = [o_detached_time_sld knobPosition]; - oldFrame = [o_detached_time_sld_fancygradient_view frame]; - if (f_value != oldFrame.size.width) - { - if ([o_detached_time_sld_fancygradient_view isHidden]) - [o_detached_time_sld_fancygradient_view setHidden: NO]; - [o_detached_time_sld_fancygradient_view setFrame: NSMakeRect(oldFrame.origin.x, oldFrame.origin.y, f_value, oldFrame.size.height)]; - } - } - } else { - NSRect frame; - frame = [o_time_sld_fancygradient_view frame]; - if (frame.size.width > 0) { - frame.size.width = 0; - [o_time_sld_fancygradient_view setFrame: frame]; - - frame = [o_detached_time_sld_fancygradient_view frame]; - frame.size.width = 0; - [o_detached_time_sld_fancygradient_view setFrame: frame]; - } - [o_time_sld_fancygradient_view setHidden: YES]; - [o_detached_time_sld_fancygradient_view setHidden: YES]; - } - [o_pool release]; + [[self controlsBar] updateVolumeSlider]; + [o_fspanel setVolumeLevel: [[VLCCoreInteraction sharedInstance] volume]]; } #pragma mark - #pragma mark Video Output handling -- (id)videoView -{ - return o_video_view; -} -- (void)setupVideoView +- (void)videoplayWillBeStarted { - BOOL b_video_deco = var_InheritBool(VLCIntf, "video-deco"); - BOOL b_video_wallpaper = var_InheritBool(VLCIntf, "video-wallpaper"); - - // TODO: make lion fullscreen compatible with video-wallpaper and !embedded-video - if ((b_video_wallpaper || !b_video_deco) && !b_nativeFullscreenMode) { - // b_video_wallpaper is priorized over !b_video_deco - - msg_Dbg(VLCIntf, "Creating background / blank window"); - NSScreen *screen = [NSScreen screenWithDisplayID:(CGDirectDisplayID)var_InheritInteger(VLCIntf, "macosx-vdev")]; - if (!screen) - screen = [self screen]; - - NSRect window_rect; - if (b_video_wallpaper) - window_rect = [screen frame]; - else - window_rect = [self frame]; - - if (o_extra_video_window) - [o_extra_video_window release]; - - NSUInteger mask = NSBorderlessWindowMask; - if (!OSX_SNOW_LEOPARD && !b_video_deco) - mask |= NSResizableWindowMask; - - BOOL b_no_video_deco_only = !b_video_wallpaper; - o_extra_video_window = [[VLCVideoWindowCommon alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES]; - [o_extra_video_window setDelegate:self]; - - if (b_video_wallpaper) - [o_extra_video_window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey) + 1]; - - [o_extra_video_window setBackgroundColor: [NSColor blackColor]]; - [o_extra_video_window setCanBecomeKeyWindow: !b_video_wallpaper]; - [o_extra_video_window setCanBecomeMainWindow: !b_video_wallpaper]; - [o_extra_video_window setAcceptsMouseMovedEvents:!b_video_wallpaper]; - [o_extra_video_window setMovableByWindowBackground: !b_video_wallpaper]; - [o_extra_video_window useOptimizedDrawing: YES]; - - [o_video_view retain]; - if ([o_video_view superview] != NULL) - [o_video_view removeFromSuperviewWithoutNeedingDisplay]; - window_rect.origin.x = window_rect.origin.y = 0; - [o_video_view setFrame: window_rect]; - [[o_extra_video_window contentView] addSubview: o_video_view positioned:NSWindowAbove relativeTo:nil]; - [o_video_view release]; - - if (b_video_wallpaper) - [o_extra_video_window orderBack:nil]; - else { - [o_extra_video_window center]; - [o_extra_video_window setFrameAutosaveName:@"extra-videowindow"]; - [o_detached_video_window setContentMinSize: NSMakeSize(f_min_video_height, f_min_video_height)]; - } - - b_nonembedded = YES; - } else { - if (var_InheritBool(VLCIntf, "embedded-video") || b_nativeFullscreenMode) { - 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 { - if ([o_video_view superview] != NULL) - [o_video_view removeFromSuperviewWithoutNeedingDisplay]; - - NSRect videoFrame; - videoFrame.size = [[o_detached_video_window contentView] frame].size; - videoFrame.size.height -= [o_detached_bottombar_view frame].size.height; - if (b_dark_interface) - videoFrame.size.height -= [o_titlebar_view frame].size.height; - - videoFrame.origin.x = .0; - videoFrame.origin.y = [o_detached_bottombar_view frame].size.height; - - [o_video_view setFrame: videoFrame]; - [[o_detached_video_window contentView] addSubview: o_video_view positioned:NSWindowAbove relativeTo:nil]; - [o_detached_video_window setLevel:NSNormalWindowLevel]; - [o_detached_video_window useOptimizedDrawing: YES]; - b_nonembedded = YES; - } - } - - if (!b_video_wallpaper) { - [[o_video_view window] makeKeyAndOrderFront: self]; - - vout_thread_t *p_vout = getVout(); - 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); - } - } - - [[o_video_view window] setAlphaValue: config_GetFloat(VLCIntf, "macosx-opaqueness")]; + if (!b_fullscreen) + frameBeforePlayback = [self frame]; } - (void)setVideoplayEnabled { BOOL b_videoPlayback = [[VLCMain sharedInstance] activeVideoPlayback]; - - if (b_videoPlayback) { - frameBeforePlayback = [self frame]; - - // look for 'start at fullscreen' - [[VLCMain sharedInstance] fullscreenChanged]; - } else { - if (!b_nonembedded) + + if (!b_videoPlayback) { + if (!b_nonembedded && (!b_nativeFullscreenMode || (b_nativeFullscreenMode && !b_fullscreen)) && frameBeforePlayback.size.width > 0 && frameBeforePlayback.size.height > 0) [[self animator] setFrame:frameBeforePlayback display:YES]; - [self makeFirstResponder: nil]; - [o_detached_video_window orderOut: nil]; - if (o_extra_video_window) - [o_extra_video_window orderOut: nil]; + // update fs button to reflect state for next startup + if (var_InheritBool(VLCIntf, "fullscreen") || var_GetBool(pl_Get(VLCIntf), "fullscreen")) { + [o_controls_bar setFullscreenState:YES]; + } - if ([self level] != NSNormalWindowLevel) - [self setLevel: NSNormalWindowLevel]; - if ([o_detached_video_window level] != NSNormalWindowLevel) - [o_detached_video_window setLevel: NSNormalWindowLevel]; + [self makeFirstResponder: o_playlist_table]; + [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: NSNormalWindowLevel]; // restore alpha value to 1 for the case that macosx-opaqueness is set to < 1 [self setAlphaValue:1.0]; } if (b_nativeFullscreenMode) { - if ([NSApp presentationOptions] & NSApplicationPresentationFullScreen) - [o_bottombar_view setHidden: b_videoPlayback]; - else - [o_bottombar_view setHidden: NO]; - if (b_videoPlayback && b_fullscreen) + if ([self hasActiveVideo] && [self fullscreen]) { + [[o_controls_bar bottomBarView] setHidden: b_videoPlayback]; [o_fspanel setActive: nil]; - if (!b_videoPlayback) + } else { + [[o_controls_bar bottomBarView] setHidden: NO]; [o_fspanel setNonActive: nil]; - } - - if (!b_videoPlayback && b_fullscreen) { - if (!b_nativeFullscreenMode) - [[VLCCoreInteraction sharedInstance] toggleFullscreen]; - } -} - -- (void)resizeWindow -{ - if (b_fullscreen || (b_nativeFullscreenMode && [NSApp presentationOptions] & NSApplicationPresentationFullScreen)) - return; - - id o_videoWindow = [o_video_view window]; - NSSize windowMinSize = [o_videoWindow minSize]; - NSRect screenFrame = [[o_videoWindow screen] visibleFrame]; - - NSPoint topleftbase = NSMakePoint(0, [o_videoWindow frame].size.height); - NSPoint topleftscreen = [o_videoWindow convertBaseToScreen: topleftbase]; - - unsigned int i_width = nativeVideoSize.width; - unsigned int i_height = nativeVideoSize.height; - if (i_width < windowMinSize.width) - i_width = windowMinSize.width; - if (i_height < f_min_video_height) - i_height = f_min_video_height; - - /* Calculate the window's new size */ - NSRect new_frame; - new_frame.size.width = [o_videoWindow frame].size.width - [o_video_view frame].size.width + i_width; - new_frame.size.height = [o_videoWindow frame].size.height - [o_video_view frame].size.height + i_height; - new_frame.origin.x = topleftscreen.x; - new_frame.origin.y = topleftscreen.y - new_frame.size.height; - - /* make sure the window doesn't exceed the screen size the window is on */ - if (new_frame.size.width > screenFrame.size.width) { - new_frame.size.width = screenFrame.size.width; - new_frame.origin.x = screenFrame.origin.x; - } - if (new_frame.size.height > screenFrame.size.height) { - new_frame.size.height = screenFrame.size.height; - new_frame.origin.y = screenFrame.origin.y; - } - if (new_frame.origin.y < screenFrame.origin.y) - new_frame.origin.y = screenFrame.origin.y; - - CGFloat right_screen_point = screenFrame.origin.x + screenFrame.size.width; - CGFloat right_window_point = new_frame.origin.x + new_frame.size.width; - if (right_window_point > right_screen_point) - new_frame.origin.x -= (right_window_point - right_screen_point); - - [[o_videoWindow animator] setFrame:new_frame display:YES]; -} - -- (void)setNativeVideoSize:(NSSize)size -{ - nativeVideoSize = size; - - if (var_InheritBool(VLCIntf, "macosx-video-autoresize") && !b_fullscreen && !var_InheritBool(VLCIntf, "video-wallpaper")) - [self performSelectorOnMainThread:@selector(resizeWindow) withObject:nil waitUntilDone:NO]; -} - -// Called automatically if window's acceptsMouseMovedEvents property is true -- (void)mouseMoved:(NSEvent *)theEvent -{ - if (b_fullscreen) - [self recreateHideMouseTimer]; - - [super mouseMoved: theEvent]; -} - -- (void)recreateHideMouseTimer -{ - if (t_hide_mouse_timer != nil) { - [t_hide_mouse_timer invalidate]; - [t_hide_mouse_timer release]; - } - - t_hide_mouse_timer = [NSTimer scheduledTimerWithTimeInterval:2 - target:self - selector:@selector(hideMouseCursor:) - userInfo:nil - repeats:NO]; - [t_hide_mouse_timer retain]; -} - -// NSTimer selectors require this function signature as per Apple's docs -- (void)hideMouseCursor:(NSTimer *)timer -{ - [NSCursor setHiddenUntilMouseMoves: YES]; -} - -#pragma mark - -#pragma mark Fullscreen support -- (void)showFullscreenController -{ - if (b_fullscreen && [[VLCMain sharedInstance] activeVideoPlayback]) - [o_fspanel fadeIn]; -} - -- (BOOL)fullscreen -{ - return b_fullscreen; -} - -- (void)lockFullscreenAnimation -{ - [o_animation_lock lock]; -} - -- (void)unlockFullscreenAnimation -{ - [o_animation_lock unlock]; -} - -- (void)enterFullscreen -{ - NSMutableDictionary *dict1, *dict2; - NSScreen *screen; - NSRect screen_rect; - NSRect rect; - BOOL blackout_other_displays = var_InheritBool(VLCIntf, "macosx-black"); - o_current_video_window = [o_video_view window]; - - screen = [NSScreen screenWithDisplayID:(CGDirectDisplayID)var_InheritInteger(VLCIntf, "macosx-vdev")]; - [self lockFullscreenAnimation]; - - if (!screen) { - msg_Dbg(VLCIntf, "chosen screen isn't present, using current screen for fullscreen mode"); - screen = [o_current_video_window screen]; - } - if (!screen) { - msg_Dbg(VLCIntf, "Using deepest screen"); - screen = [NSScreen deepestScreen]; - } - - screen_rect = [screen frame]; - - [o_fullscreen_btn setState: YES]; - [o_detached_fullscreen_btn setState: YES]; - - [self recreateHideMouseTimer]; - - if (blackout_other_displays) - [screen blackoutOtherScreens]; - - /* Make sure we don't see the window flashes in float-on-top mode */ - i_originalLevel = [o_current_video_window level]; - [o_current_video_window setLevel:NSNormalWindowLevel]; - - /* Only create the o_fullscreen_window if we are not in the middle of the zooming animation */ - if (!o_fullscreen_window) { - /* We can't change the styleMask of an already created NSWindow, so we create another window, and do eye catching stuff */ - - rect = [[o_video_view superview] convertRect: [o_video_view frame] toView: nil]; /* Convert to Window base coord */ - rect.origin.x += [o_current_video_window frame].origin.x; - rect.origin.y += [o_current_video_window frame].origin.y; - o_fullscreen_window = [[VLCWindow alloc] initWithContentRect:rect styleMask: NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [o_fullscreen_window setBackgroundColor: [NSColor blackColor]]; - [o_fullscreen_window setCanBecomeKeyWindow: YES]; - [o_fullscreen_window setCanBecomeMainWindow: YES]; - - if (![o_current_video_window isVisible] || [o_current_video_window alphaValue] == 0.0) { - /* We don't animate if we are not visible, instead we - * simply fade the display */ - CGDisplayFadeReservationToken token; - - if (blackout_other_displays) { - CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token); - CGDisplayFade(token, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, YES); - } - - if ([screen mainScreen]) - [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; - - [[o_video_view superview] replaceSubview:o_video_view with:o_temp_view]; - [o_temp_view setFrame:[o_video_view frame]]; - [o_fullscreen_window setContentView:o_video_view]; - - [o_fullscreen_window makeKeyAndOrderFront:self]; - [o_fullscreen_window orderFront:self animate:YES]; - - [o_fullscreen_window setFrame:screen_rect display:YES animate:YES]; - [o_fullscreen_window setLevel:NSNormalWindowLevel]; - - if (blackout_other_displays) { - CGDisplayFade(token, 0.3, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO); - CGReleaseDisplayFadeReservation(token); - } - - /* Will release the lock */ - [self hasBecomeFullscreen]; - - return; } - - /* Make sure we don't see the o_video_view disappearing of the screen during this operation */ - NSDisableScreenUpdates(); - [[o_video_view superview] replaceSubview:o_video_view with:o_temp_view]; - [o_temp_view setFrame:[o_video_view frame]]; - [o_fullscreen_window setContentView:o_video_view]; - [o_fullscreen_window makeKeyAndOrderFront:self]; - NSEnableScreenUpdates(); - } - - /* We are in fullscreen (and no animation is running) */ - if (b_fullscreen) { - /* Make sure we are hidden */ - [o_current_video_window orderOut: self]; - - [self unlockFullscreenAnimation]; - return; - } - - if (o_fullscreen_anim1) { - [o_fullscreen_anim1 stopAnimation]; - [o_fullscreen_anim1 release]; - } - if (o_fullscreen_anim2) { - [o_fullscreen_anim2 stopAnimation]; - [o_fullscreen_anim2 release]; } - - if ([screen mainScreen]) - [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; - - dict1 = [[NSMutableDictionary alloc] initWithCapacity:2]; - dict2 = [[NSMutableDictionary alloc] initWithCapacity:3]; - - [dict1 setObject:o_current_video_window forKey:NSViewAnimationTargetKey]; - [dict1 setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey]; - - [dict2 setObject:o_fullscreen_window forKey:NSViewAnimationTargetKey]; - [dict2 setObject:[NSValue valueWithRect:[o_fullscreen_window frame]] forKey:NSViewAnimationStartFrameKey]; - [dict2 setObject:[NSValue valueWithRect:screen_rect] forKey:NSViewAnimationEndFrameKey]; - - /* Strategy with NSAnimation allocation: - - Keep at most 2 animation at a time - - leaveFullscreen/enterFullscreen are the only responsible for releasing and alloc-ing - */ - o_fullscreen_anim1 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:dict1]]; - o_fullscreen_anim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:dict2]]; - - [dict1 release]; - [dict2 release]; - - [o_fullscreen_anim1 setAnimationBlockingMode: NSAnimationNonblocking]; - [o_fullscreen_anim1 setDuration: 0.3]; - [o_fullscreen_anim1 setFrameRate: 30]; - [o_fullscreen_anim2 setAnimationBlockingMode: NSAnimationNonblocking]; - [o_fullscreen_anim2 setDuration: 0.2]; - [o_fullscreen_anim2 setFrameRate: 30]; - - [o_fullscreen_anim2 setDelegate: self]; - [o_fullscreen_anim2 startWhenAnimation: o_fullscreen_anim1 reachesProgress: 1.0]; - - [o_fullscreen_anim1 startAnimation]; - /* fullscreenAnimation will be unlocked when animation ends */ -} - -- (void)hasBecomeFullscreen -{ - if ([[o_video_view subviews] count] > 0) - [o_fullscreen_window makeFirstResponder: [[o_video_view subviews] objectAtIndex:0]]; - - [o_fullscreen_window makeKeyWindow]; - [o_fullscreen_window setAcceptsMouseMovedEvents: YES]; - - /* tell the fspanel to move itself to front next time it's triggered */ - [o_fspanel setVoutWasUpdated: (int)[[o_fullscreen_window screen] displayID]]; - [o_fspanel setActive: nil]; - - if ([o_current_video_window isVisible]) - [o_current_video_window orderOut: self]; - - b_fullscreen = YES; - [self unlockFullscreenAnimation]; -} - -- (void)leaveFullscreen -{ - [self leaveFullscreenAndFadeOut: NO]; -} - -- (void)leaveFullscreenAndFadeOut: (BOOL)fadeout -{ - NSMutableDictionary *dict1, *dict2; - NSRect frame; - BOOL blackout_other_displays = var_InheritBool(VLCIntf, "macosx-black"); - - if (!o_current_video_window) - return; - - [self lockFullscreenAnimation]; - - [o_fullscreen_btn setState: NO]; - [o_detached_fullscreen_btn setState: NO]; - - /* We always try to do so */ - [NSScreen unblackoutScreens]; - - vout_thread_t *p_vout = getVout(); - 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); - } - [[o_video_view window] makeKeyAndOrderFront: nil]; - - /* Don't do anything if o_fullscreen_window is already closed */ - if (!o_fullscreen_window) { - [self unlockFullscreenAnimation]; - return; - } - - if (fadeout) { - /* We don't animate if we are not visible, instead we - * simply fade the display */ - CGDisplayFadeReservationToken token; - - if (blackout_other_displays) { - CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token); - CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, YES); - } - - [o_fspanel setNonActive: nil]; - [NSApp setPresentationOptions: NSApplicationPresentationDefault]; - - /* Will release the lock */ - [self hasEndedFullscreen]; - - /* Our window is hidden, and might be faded. We need to workaround that, so note it - * here */ - b_window_is_invisible = YES; - - if (blackout_other_displays) { - CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO); - CGReleaseDisplayFadeReservation(token); - } - - return; - } - - [o_current_video_window setAlphaValue: 0.0]; - [o_current_video_window orderFront: self]; - [[o_video_view window] orderFront: self]; - - [o_fspanel setNonActive: nil]; - [NSApp setPresentationOptions:(NSApplicationPresentationDefault)]; - - if (o_fullscreen_anim1) { - [o_fullscreen_anim1 stopAnimation]; - [o_fullscreen_anim1 release]; - } - if (o_fullscreen_anim2) { - [o_fullscreen_anim2 stopAnimation]; - [o_fullscreen_anim2 release]; - } - - frame = [[o_temp_view superview] convertRect: [o_temp_view frame] toView: nil]; /* Convert to Window base coord */ - frame.origin.x += [o_current_video_window frame].origin.x; - frame.origin.y += [o_current_video_window frame].origin.y; - - dict2 = [[NSMutableDictionary alloc] initWithCapacity:2]; - [dict2 setObject:o_current_video_window forKey:NSViewAnimationTargetKey]; - [dict2 setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey]; - - o_fullscreen_anim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict2, nil]]; - [dict2 release]; - - [o_fullscreen_anim2 setAnimationBlockingMode: NSAnimationNonblocking]; - [o_fullscreen_anim2 setDuration: 0.3]; - [o_fullscreen_anim2 setFrameRate: 30]; - - [o_fullscreen_anim2 setDelegate: self]; - - dict1 = [[NSMutableDictionary alloc] initWithCapacity:3]; - - [dict1 setObject:o_fullscreen_window forKey:NSViewAnimationTargetKey]; - [dict1 setObject:[NSValue valueWithRect:[o_fullscreen_window frame]] forKey:NSViewAnimationStartFrameKey]; - [dict1 setObject:[NSValue valueWithRect:frame] forKey:NSViewAnimationEndFrameKey]; - - o_fullscreen_anim1 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict1, nil]]; - [dict1 release]; - - [o_fullscreen_anim1 setAnimationBlockingMode: NSAnimationNonblocking]; - [o_fullscreen_anim1 setDuration: 0.2]; - [o_fullscreen_anim1 setFrameRate: 30]; - [o_fullscreen_anim2 startWhenAnimation: o_fullscreen_anim1 reachesProgress: 1.0]; - - /* Make sure o_fullscreen_window is the frontmost window */ - [o_fullscreen_window orderFront: self]; - - [o_fullscreen_anim1 startAnimation]; - /* fullscreenAnimation will be unlocked when animation ends */ -} - -- (void)hasEndedFullscreen -{ - b_fullscreen = NO; - - /* This function is private and should be only triggered at the end of the fullscreen change animation */ - /* Make sure we don't see the o_video_view disappearing of the screen during this operation */ - NSDisableScreenUpdates(); - [o_video_view retain]; - [o_video_view removeFromSuperviewWithoutNeedingDisplay]; - [[o_temp_view superview] replaceSubview:o_temp_view with:o_video_view]; - [o_video_view release]; - [o_video_view setFrame:[o_temp_view frame]]; - if ([[o_video_view subviews] count] > 0) - [[o_video_view window] makeFirstResponder: [[o_video_view subviews] objectAtIndex:0]]; - if (!b_nonembedded) - [super makeKeyAndOrderFront:self]; /* our version contains a workaround */ - else - [[o_video_view window] makeKeyAndOrderFront: self]; - [o_fullscreen_window orderOut: self]; - NSEnableScreenUpdates(); - - [o_fullscreen_window release]; - o_fullscreen_window = nil; - [[o_video_view window] setLevel:i_originalLevel]; - [[o_video_view window] setAlphaValue: config_GetFloat(VLCIntf, "macosx-opaqueness")]; - - // if we quit fullscreen because there is no video anymore, make sure non-embedded window is not visible - if (![[VLCMain sharedInstance] activeVideoPlayback] && b_nonembedded) - [o_current_video_window orderOut: self]; - - o_current_video_window = nil; - [self unlockFullscreenAnimation]; -} - -- (void)animationDidEnd:(NSAnimation*)animation -{ - NSArray *viewAnimations; - if (o_makekey_anim == animation) { - [o_makekey_anim release]; - return; - } - if ([animation currentValue] < 1.0) - return; - - /* Fullscreen ended or started (we are a delegate only for leaveFullscreen's/enterFullscren's anim2) */ - viewAnimations = [o_fullscreen_anim2 viewAnimations]; - if ([viewAnimations count] >=1 && - [[[viewAnimations objectAtIndex: 0] objectForKey: NSViewAnimationEffectKey] isEqualToString:NSViewAnimationFadeInEffect]) { - /* Fullscreen ended */ - [self hasEndedFullscreen]; - } else - /* Fullscreen started */ - [self hasBecomeFullscreen]; -} - -- (void)makeKeyAndOrderFront: (id)sender -{ - /* Hack - * when we exit fullscreen and fade out, we may endup in - * having a window that is faded. We can't have it fade in unless we - * animate again. */ - - if (!b_window_is_invisible) { - /* Make sure we don't do it too much */ - [super makeKeyAndOrderFront: sender]; - return; - } - - [super setAlphaValue:0.0f]; - [super makeKeyAndOrderFront: sender]; - - NSMutableDictionary * dict = [[NSMutableDictionary alloc] initWithCapacity:2]; - [dict setObject:self forKey:NSViewAnimationTargetKey]; - [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey]; - - o_makekey_anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:dict]]; - [dict release]; - - [o_makekey_anim setAnimationBlockingMode: NSAnimationNonblocking]; - [o_makekey_anim setDuration: 0.1]; - [o_makekey_anim setFrameRate: 30]; - [o_makekey_anim setDelegate: self]; - - [o_makekey_anim startAnimation]; - b_window_is_invisible = NO; - - /* fullscreenAnimation will be unlocked when animation ends */ } #pragma mark - #pragma mark Lion native fullscreen handling - (void)windowWillEnterFullScreen:(NSNotification *)notification { - // workaround, see #6668 - [NSApp setPresentationOptions:(NSApplicationPresentationFullScreen | NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; - - var_SetBool(pl_Get(VLCIntf), "fullscreen", true); - - vout_thread_t *p_vout = getVout(); - if (p_vout) { - var_SetBool(p_vout, "fullscreen", true); - vlc_object_release(p_vout); - } - - [o_video_view setFrame: [[self contentView] frame]]; - b_fullscreen = YES; - - [self recreateHideMouseTimer]; - i_originalLevel = [self level]; - [self setLevel:NSNormalWindowLevel]; + [super windowWillEnterFullScreen:notification]; + // update split view frame after removing title bar 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]; + NSRect frame = [[self contentView] frame]; + frame.origin.y += [o_controls_bar height]; + frame.size.height -= [o_controls_bar height]; + [o_split_view setFrame:frame]; } - - if ([[VLCMain sharedInstance] activeVideoPlayback]) - [o_bottombar_view setHidden: YES]; - - [self setMovableByWindowBackground: NO]; -} - -- (void)windowDidEnterFullScreen:(NSNotification *)notification -{ - // Indeed, we somehow can have an "inactive" fullscreen (but a visible window!). - // But this creates some problems when leaving fs over remote intfs, so activate app here. - [NSApp activateIgnoringOtherApps:YES]; - - [o_fspanel setVoutWasUpdated: (int)[[self screen] displayID]]; - [o_fspanel setActive: nil]; } - (void)windowWillExitFullScreen:(NSNotification *)notification { + [super windowWillExitFullScreen: notification]; - var_SetBool(pl_Get(VLCIntf), "fullscreen", false); - - vout_thread_t *p_vout = getVout(); - if (p_vout) { - var_SetBool(p_vout, "fullscreen", false); - vlc_object_release(p_vout); - } - - [o_video_view setFrame: [o_split_view frame]]; - [NSCursor setHiddenUntilMouseMoves: NO]; - [o_fspanel setNonActive: nil]; - [self setLevel:i_originalLevel]; - b_fullscreen = NO; - + // update split view frame after readding title bar if (b_dark_interface) { - NSRect winrect; - CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height; - winrect = [self frame]; + NSRect frame = [o_split_view frame]; + frame.size.height -= [o_titlebar_view frame].size.height; + [o_split_view setFrame:frame]; + } +} +#pragma mark - +#pragma mark Fullscreen support - [o_titlebar_view setFrame: NSMakeRect(0, winrect.size.height - f_titleBarHeight, - winrect.size.width, f_titleBarHeight)]; - [[self contentView] addSubview: o_titlebar_view]; +- (void)showFullscreenController +{ + id currentWindow = [NSApp keyWindow]; + if ([currentWindow respondsToSelector:@selector(hasActiveVideo)] && [currentWindow hasActiveVideo]) { + if ([currentWindow respondsToSelector:@selector(fullscreen)] && [currentWindow fullscreen] && ![[currentWindow videoView] isHidden]) { - 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]; + if ([[VLCMain sharedInstance] activeVideoPlayback]) + [o_fspanel fadeIn]; + } } - if ([[VLCMain sharedInstance] activeVideoPlayback]) - [o_bottombar_view setHidden: NO]; - - [self setMovableByWindowBackground: YES]; } #pragma mark - @@ -2316,6 +846,23 @@ static VLCMainWindow *_o_sharedInstance = nil; return YES; } +- (void)mainSplitViewDidResizeSubviews:(id)object +{ + i_lastLeftSplitViewWidth = [o_left_split_view frame].size.width; + config_PutInt(VLCIntf, "macosx-show-sidebar", ![o_split_view isSubviewCollapsed:o_left_split_view]); + [[[VLCMain sharedInstance] mainMenu] updateSidebarMenuItem]; +} + +- (void)toggleLeftSubSplitView +{ + [o_split_view adjustSubviews]; + if ([o_split_view isSubviewCollapsed:o_left_split_view]) + [o_split_view setPosition:i_lastLeftSplitViewWidth ofDividerAtIndex:0]; + else + [o_split_view setPosition:[o_split_view minPossiblePositionOfDividerAtIndex:0] ofDividerAtIndex:0]; + [[[VLCMain sharedInstance] mainMenu] updateSidebarMenuItem]; +} + #pragma mark - #pragma mark Side Bar Data handling /* taken under BSD-new from the PXSourceList sample project, adapted for VLC */ @@ -2367,7 +914,7 @@ static VLCMainWindow *_o_sharedInstance = nil; - (NSInteger)sourceList:(PXSourceList*)aSourceList badgeValueForItem:(id)item { playlist_t * p_playlist = pl_Get(VLCIntf); - NSInteger i_playlist_size; + NSInteger i_playlist_size = 0; if ([[item identifier] isEqualToString: @"playlist"]) { PL_LOCK; @@ -2378,7 +925,8 @@ static VLCMainWindow *_o_sharedInstance = nil; } if ([[item identifier] isEqualToString: @"medialibrary"]) { PL_LOCK; - i_playlist_size = p_playlist->p_ml_category->i_children; + if (p_playlist->p_ml_category) + i_playlist_size = p_playlist->p_ml_category->i_children; PL_UNLOCK; return i_playlist_size; @@ -2467,7 +1015,8 @@ static VLCMainWindow *_o_sharedInstance = nil; if ([[item identifier] isEqualToString:@"playlist"]) { [[[VLCMain sharedInstance] playlist] setPlaylistRoot:p_playlist->p_local_category]; } else if ([[item identifier] isEqualToString:@"medialibrary"]) { - [[[VLCMain sharedInstance] playlist] setPlaylistRoot:p_playlist->p_ml_category]; + if (p_playlist->p_ml_category) + [[[VLCMain sharedInstance] playlist] setPlaylistRoot:p_playlist->p_ml_category]; } else { playlist_item_t * pl_item; PL_LOCK; @@ -2487,6 +1036,10 @@ static VLCMainWindow *_o_sharedInstance = nil; [self showPodcastControls]; else [self hidePodcastControls]; + + [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCMediaKeySupportSettingChanged" + object: nil + userInfo: nil]; } - (NSDragOperation)sourceList:(PXSourceList *)aSourceList validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index @@ -2567,7 +1120,7 @@ static VLCMainWindow *_o_sharedInstance = nil; return nil; for (NSUInteger x = 0; x < count; x++) { - id item = [array objectAtIndex: x]; // save one objc selector call + id item = [array objectAtIndex:x]; // save one objc selector call if ([[item identifier] isEqualToString:object]) return item; } @@ -2595,12 +1148,7 @@ static VLCMainWindow *_o_sharedInstance = nil; [podcastConf appendString: [o_podcast_subscribe_url_fld stringValue]]; config_PutPsz(VLCIntf, "podcast-urls", [podcastConf UTF8String]); - - vlc_object_t *p_obj = (vlc_object_t*)vlc_object_find_name(VLCIntf->p_libvlc, "podcast"); - if (p_obj) { - var_SetString(p_obj, "podcast-urls", [podcastConf UTF8String]); - vlc_object_release(p_obj); - } + var_SetString(pl_Get(VLCIntf), "podcast-urls", [podcastConf UTF8String]); [podcastConf release]; } } @@ -2609,7 +1157,7 @@ static VLCMainWindow *_o_sharedInstance = nil; { if (config_GetPsz(VLCIntf, "podcast-urls") != NULL) { [o_podcast_unsubscribe_pop removeAllItems]; - [o_podcast_unsubscribe_pop addItemsWithTitles:[[NSString stringWithUTF8String:config_GetPsz(VLCIntf, "podcast-urls")] componentsSeparatedByString:@"|"]]; + [o_podcast_unsubscribe_pop addItemsWithTitles:[@(config_GetPsz(VLCIntf, "podcast-urls")) componentsSeparatedByString:@"|"]]; [NSApp beginSheet:o_podcast_unsubscribe_window modalForWindow:self modalDelegate:self didEndSelector:NULL contextInfo:nil]; } } @@ -2620,17 +1168,12 @@ static VLCMainWindow *_o_sharedInstance = nil; [NSApp endSheet: o_podcast_unsubscribe_window]; if (sender == o_podcast_unsubscribe_ok_btn) { - NSMutableArray * urls = [[NSMutableArray alloc] initWithArray:[[NSString stringWithUTF8String:config_GetPsz(VLCIntf, "podcast-urls")] componentsSeparatedByString:@"|"]]; + NSMutableArray * urls = [[NSMutableArray alloc] initWithArray:[@(config_GetPsz(VLCIntf, "podcast-urls")) componentsSeparatedByString:@"|"]]; [urls removeObjectAtIndex: [o_podcast_unsubscribe_pop indexOfSelectedItem]]; config_PutPsz(VLCIntf, "podcast-urls", [[urls componentsJoinedByString:@"|"] UTF8String]); + var_SetString(pl_Get(VLCIntf), "podcast-urls", config_GetPsz(VLCIntf, "podcast-urls")); [urls release]; - vlc_object_t *p_obj = (vlc_object_t*)vlc_object_find_name(VLCIntf->p_libvlc, "podcast"); - if (p_obj) { - var_SetString(p_obj, "podcast-urls", config_GetPsz(VLCIntf, "podcast-urls")); - vlc_object_release(p_obj); - } - /* reload the podcast module, since it won't update its list when removing podcasts */ playlist_t * p_playlist = pl_Get(VLCIntf); if (playlist_IsServicesDiscoveryLoaded(p_playlist, "podcast{longname=\"Podcasts\"}")) { @@ -2682,10 +1225,13 @@ static VLCMainWindow *_o_sharedInstance = nil; - (void)awakeFromNib { + // sets lion fullscreen behaviour + [super awakeFromNib]; [self setAcceptsMouseMovedEvents: YES]; if (b_dark_interface) { [self setBackgroundColor: [NSColor clearColor]]; + [self setOpaque: NO]; [self display]; [self setHasShadow:NO]; @@ -2698,20 +1244,35 @@ static VLCMainWindow *_o_sharedInstance = nil; [o_titlebar_view setFrame: NSMakeRect(0, winrect.size.height - f_titleBarHeight, winrect.size.width, f_titleBarHeight)]; [[self contentView] addSubview: o_titlebar_view positioned: NSWindowAbove relativeTo: nil]; - // native fs not supported with detached view yet - [o_titlebar_view setFullscreenButtonHidden: YES]; + } else { + [self setBackgroundColor: [NSColor blackColor]]; + } + + NSRect videoViewRect = [[self contentView] bounds]; + if (b_dark_interface) + videoViewRect.size.height -= [o_titlebar_view frame].size.height; + CGFloat f_bottomBarHeight = [[self controlsBar] height]; + videoViewRect.size.height -= f_bottomBarHeight; + videoViewRect.origin.y = f_bottomBarHeight; + [o_video_view setFrame: videoViewRect]; + if (b_dark_interface) { + o_color_backdrop = [[VLCColorView alloc] initWithFrame: [o_video_view frame]]; + [[self contentView] addSubview: o_color_backdrop positioned: NSWindowBelow relativeTo: o_video_view]; + [o_color_backdrop setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; + + [self setContentMinSize: NSMakeSize(363., f_min_video_height + [[self controlsBar] height] + [o_titlebar_view frame].size.height)]; + } else { + [self setContentMinSize: NSMakeSize(363., f_min_video_height + [[self controlsBar] height])]; } } -- (IBAction)fullscreen:(id)sender +- (void)dealloc { - [[VLCCoreInteraction sharedInstance] toggleFullscreen]; -} + if (b_dark_interface) + [o_color_backdrop release]; -- (BOOL)canBecomeKeyWindow -{ - return YES; + [super dealloc]; } @end