#import "MainMenu.h"
#import "open.h"
#import "controls.h" // TODO: remove me
+#import "playlist.h"
#import "SideBarItem.h"
-#import "MainWindowTitle.h"
#import <vlc_playlist.h>
#import <vlc_aout_intf.h>
#import <vlc_url.h>
if (b_dark_interface)
{
#ifdef MAC_OS_X_VERSION_10_7
- styleMask = NSBorderlessWindowMask | NSResizableWindowMask;
+ if (OSX_LION)
+ styleMask = NSBorderlessWindowMask | NSResizableWindowMask;
+ else
+ styleMask = NSBorderlessWindowMask;
#else
styleMask = NSBorderlessWindowMask;
#endif
- (void)dealloc
{
+ if (b_dark_interface)
+ [o_color_backdrop release];
+
[[NSNotificationCenter defaultCenter] removeObserver: self];
- config_PutInt( VLCIntf->p_libvlc, "volume", i_lastShownVolume );
- [self saveFrameUsingName: [self frameAutosaveName]];
[o_sidebaritems release];
[super dealloc];
}
- (void)awakeFromNib
{
+ BOOL b_splitviewShouldBeHidden = NO;
/* setup the styled interface */
-#ifdef MAC_OS_X_VERSION_10_7
- b_nativeFullscreenMode = config_GetInt( VLCIntf, "macosx-nativefullscreenmode" );
-#else
b_nativeFullscreenMode = NO;
+#ifdef MAC_OS_X_VERSION_10_7
+ if( config_GetInt( VLCIntf, "embedded-video" ))
+ b_nativeFullscreenMode = config_GetInt( VLCIntf, "macosx-nativefullscreenmode" );
#endif
i_lastShownVolume = -1;
t_hide_mouse_timer = nil;
[o_dropzone_lbl setStringValue: _NS("Drop media here")];
if (!b_dark_interface) {
- [o_bottombar_view setImage: [NSImage imageNamed:@"bottom-background"]];
+ [o_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottom-background"] middle: [NSImage imageNamed:@"bottom-background"] right: [NSImage imageNamed:@"bottom-background"]];
[o_bwd_btn setImage: [NSImage imageNamed:@"back"]];
[o_bwd_btn setAlternateImage: [NSImage imageNamed:@"back-pressed"]];
o_play_img = [[NSImage imageNamed:@"play"] retain];
}
else
{
- [o_bottombar_view setImage: [NSImage imageNamed:@"bottom-background_dark"]];
+ [o_bottombar_view setImagesLeft: [NSImage imageNamed:@"bottomdark-left"] middle: [NSImage imageNamed:@"bottom-background_dark"] right: [NSImage imageNamed:@"bottomdark-right"]];
[o_bwd_btn setImage: [NSImage imageNamed:@"back_dark"]];
[o_bwd_btn setAlternateImage: [NSImage imageNamed:@"back-pressed_dark"]];
o_play_img = [[NSImage imageNamed:@"play_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_fld setTextColor: [NSColor colorWithCalibratedRed:229.0 green:229.0 blue:229.0 alpha:100.0]];
[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_volume_down_btn setImage: [NSImage imageNamed:@"volume-low_dark"]];
[o_volume_track_view setImage: [NSImage imageNamed:@"volume-slider-track_dark"]];
else
{
[o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons_dark"]];
- [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed_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_volume_up_btn setEnabled: b_mute];
/* interface builder action */
+ if ([self frame].size.height < 100)
+ b_splitviewShouldBeHidden = YES;
[self setDelegate: self];
[self setExcludedFromWindowsMenu: YES];
[self setAcceptsMouseMovedEvents: YES];
// Set that here as IB seems to be buggy
if (b_dark_interface)
- [self setContentMinSize:NSMakeSize(500., (288. + [o_titlebar_view frame].size.height))];
+ [self setContentMinSize:NSMakeSize(604., (288. + [o_titlebar_view frame].size.height))];
else
- [self setContentMinSize:NSMakeSize(500., 288.)];
+ [self setContentMinSize:NSMakeSize(604., 288.)];
[self setTitle: _NS("VLC media player")];
- [o_playlist_btn setEnabled:NO];
+ [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 (OSX_LION && b_nativeFullscreenMode)
{
- [self setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
NSRect frame;
+ [self setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
float f_width = [o_fullscreen_btn frame].size.width;
#define moveItem( item ) \
SideBarItem *libraryItem = [SideBarItem itemWithTitle:_NS("LIBRARY") identifier:@"library"];
SideBarItem *playlistItem = [SideBarItem itemWithTitle:_NS("Playlist") identifier:@"playlist"];
[playlistItem setIcon: [NSImage imageNamed:@"sidebar-playlist"]];
+ SideBarItem *medialibraryItem = [SideBarItem itemWithTitle:_NS("Media Library") identifier:@"medialibrary"];
+ [medialibraryItem setIcon: [NSImage imageNamed:@"sidebar-playlist"]];
SideBarItem *mycompItem = [SideBarItem itemWithTitle:_NS("MY COMPUTER") identifier:@"mycomputer"];
SideBarItem *devicesItem = [SideBarItem itemWithTitle:_NS("DEVICES") identifier:@"devices"];
SideBarItem *lanItem = [SideBarItem itemWithTitle:_NS("LOCAL NETWORK") identifier:@"localnetwork"];
for (; *ppsz_name; ppsz_name++, ppsz_longname++, p_category++)
{
o_identifier = [NSString stringWithCString: *ppsz_name encoding: NSUTF8StringEncoding];
- o_identifier = [[o_identifier componentsSeparatedByString:@"{"] objectAtIndex:0];
switch (*p_category) {
case SD_CAT_INTERNET:
{
- [internetItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]];
+ [internetItems addObject: [SideBarItem itemWithTitle: _NS(*ppsz_longname) identifier: o_identifier]];
if (!strncmp( *ppsz_name, "podcast", 7 ))
- [[internetItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-podcast"]];
+ [internetItems removeLastObject]; // we don't support podcasts at this point (see #6017)
+// [[internetItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-podcast"]];
else
[[internetItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]];
+ [[internetItems lastObject] setSdtype: SD_CAT_INTERNET];
+ [[internetItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]];
}
break;
case SD_CAT_DEVICES:
{
- [devicesItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]];
+ [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]];
}
break;
case SD_CAT_LAN:
{
- [lanItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]];
+ [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]];
}
break;
case SD_CAT_MYCOMPUTER:
{
- [mycompItems addObject: [SideBarItem itemWithTitle: [NSString stringWithCString: *ppsz_longname encoding: NSUTF8StringEncoding] identifier: o_identifier]];
+ [mycompItems addObject: [SideBarItem itemWithTitle: _NS(*ppsz_longname) identifier: o_identifier]];
if (!strncmp( *ppsz_name, "video_dir", 9 ))
[[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-movie"]];
else if (!strncmp( *ppsz_name, "audio_dir", 9 ))
[[mycompItems lastObject] setIcon: [NSImage imageNamed:@"sidebar-pictures"]];
else
[[mycompItems lastObject] setIcon: [NSImage imageNamed:@"NSApplicationIcon"]];
+ [[mycompItems lastObject] setUntranslatedTitle: [NSString stringWithUTF8String: *ppsz_longname]];
+ [[mycompItems lastObject] setSdtype: SD_CAT_MYCOMPUTER];
}
break;
default:
free( ppsz_longnames );
free( p_categories );
- [libraryItem setChildren: [NSArray arrayWithObject: playlistItem]];
+ [libraryItem setChildren: [NSArray arrayWithObjects: playlistItem, medialibraryItem, nil]];
[o_sidebaritems addObject: libraryItem];
if ([mycompItem hasChildren])
[o_sidebaritems addObject: mycompItem];
[o_sidebaritems addObject: internetItem];
[o_sidebar_view reloadData];
- [o_sidebar_view selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:YES];
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 selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
if( b_dark_interface )
{
[self setBackgroundColor: [NSColor clearColor]];
[self setOpaque: NO];
+ [self display];
+ [self setHasShadow:NO];
[self setHasShadow:YES];
- NSRect winrect;
+ NSRect winrect = [self frame];
CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height;
- winrect = [self frame];
[o_titlebar_view setFrame: NSMakeRect( 0, winrect.size.height - f_titleBarHeight,
winrect.size.width, f_titleBarHeight )];
- [[self contentView] addSubview: o_titlebar_view];
+ [[self contentView] addSubview: o_titlebar_view positioned: NSWindowAbove relativeTo: o_split_view];
+
+ if (winrect.size.height > 100)
+ {
+ [self setFrame: winrect display:YES animate:YES];
+ previousSavedFrame = winrect;
+ }
- winrect.size.height = winrect.size.height + f_titleBarHeight;
- [self setFrame: winrect display:NO animate:NO];
winrect = [o_split_view frame];
winrect.size.height = winrect.size.height - f_titleBarHeight;
[o_split_view setFrame: winrect];
[o_video_view setFrame: winrect];
- previousSavedFrame = winrect;
- [self display];
+ o_color_backdrop = [[VLCColorView alloc] initWithFrame: [o_split_view frame]];
+ [[self contentView] addSubview: o_color_backdrop positioned: NSWindowBelow relativeTo: o_split_view];
+ [o_color_backdrop setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
}
else
{
[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];
+
if (OSX_LION)
[o_resize_view setImage: NULL];
[[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];
+
+ if (b_splitviewShouldBeHidden)
+ {
+ i_lastSplitViewHeight = [o_split_view frame].size.height;
+ [self hideSplitView];
+ }
}
#pragma mark -
- (void)resetPreviousButton
{
if (([NSDate timeIntervalSinceReferenceDate] - last_bwd_event) >= 0.35) {
- // seems like no further event occured, so let's switch the playback item
+ // seems like no further event occurred, so let's switch the playback item
[[VLCCoreInteraction sharedInstance] previous];
just_triggered_previous = NO;
}
}
else
{
- if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.12 )
+ if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.16 )
{
- // we just skipped 3 "continous" events, otherwise we are too fast
- [[VLCCoreInteraction sharedInstance] backward];
+ // 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
- (void)resetNextButton
{
if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) >= 0.35) {
- // seems like no further event occured, so let's switch the playback item
+ // seems like no further event occurred, so let's switch the playback item
[[VLCCoreInteraction sharedInstance] next];
just_triggered_next = NO;
}
}
else
{
- if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.12 )
+ if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.16 )
{
- // we just skipped 3 "continous" events, otherwise we are too fast
- [[VLCCoreInteraction sharedInstance] forward];
+ // 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
[[VLCCoreInteraction sharedInstance] stop];
}
+- (void)resizePlaylistAfterCollapse
+{
+ NSRect plrect;
+ plrect = [[o_playlist_table animator] frame];
+ plrect.size.height = i_lastSplitViewHeight - 19.0; // actual pl top bar height, which differs from its frame
+ [[o_playlist_table animator] setFrame: plrect];
+}
+
- (IBAction)togglePlaylist:(id)sender
{
- if (!b_nonembedded)
+ if ( ((([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) != 0) && !b_splitview_removed && ![[VLCMain sharedInstance] activeVideoPlayback]) || (b_nonembedded && [[VLCMain sharedInstance] activeVideoPlayback] && sender != nil) )
{
- if ([o_video_view isHidden] && [o_playlist_btn isEnabled]) {
- [o_split_view setHidden: YES];
- [o_video_view setHidden: NO];
+ [self hideSplitView];
+ }
+ else
+ {
+ if (b_splitview_removed)
+ {
+ if( !b_nonembedded ||( sender != nil && b_nonembedded))
+ [self showSplitView];
+ }
+
+ if (b_dropzone_active && ![[VLCMain sharedInstance] activeVideoPlayback])
+ {
+ b_dropzone_active = NO;
+ [self hideDropZone];
+ }
+
+ if (!b_nonembedded)
+ {
+ if ([o_video_view isHidden] && [[VLCMain sharedInstance] activeVideoPlayback]) {
+ [o_split_view setHidden: YES];
+ [o_video_view setHidden: NO];
+ [self makeFirstResponder: o_video_view];
+ }
+ else
+ {
+ [o_video_view setHidden: YES];
+ [o_split_view setHidden: NO];
+ [self makeFirstResponder: nil];
+ }
}
else
{
- [o_video_view setHidden: YES];
[o_split_view setHidden: NO];
+ [o_playlist_table setHidden: NO];
+ [o_video_view setHidden: ![[VLCMain sharedInstance] activeVideoPlayback]];
}
}
- else
- {
- [o_split_view setHidden: NO];
- [o_playlist_table setHidden: NO];
- [o_video_view setHidden: ![[VLCMain sharedInstance] activeVideoPlayback]];
- }
}
- (void)setRepeatOne
bool b_value;
playlist_t *p_playlist = pl_Get( VLCIntf );
b_value = var_GetBool( p_playlist, "random" );
- if(b_value) {
+
+ if(b_value) {
[o_shuffle_btn setImage: o_shuffle_on_img];
[o_shuffle_btn setAlternateImage: o_shuffle_on_pressed_img];
}
[o_fspanel setStreamPos: f_updated andTime: o_time];
vlc_object_release( p_input );
}
- [self drawFancyGradientEffectForTimeSlider];
}
- (IBAction)volumeAction:(id)sender
else if (sender == o_volume_down_btn)
{
[[VLCCoreInteraction sharedInstance] mute];
- [o_volume_sld setIntValue: 0];
- BOOL b_mute = ![[VLCCoreInteraction sharedInstance] isMuted];
- [o_volume_sld setEnabled: b_mute];
- [o_volume_up_btn setEnabled: b_mute];
}
else
[[VLCCoreInteraction sharedInstance] setVolume: AOUT_VOLUME_MAX];
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
- SEL s_menuAction = [menuItem action];
- if ((s_menuAction == @selector(performClose:)) || (s_menuAction == @selector(performMiniaturize:)) || (s_menuAction == @selector(performZoom:)))
- return YES;
+ SEL s_menuAction = [menuItem action];
- return [super validateMenuItem:menuItem];
-}
+ if ((s_menuAction == @selector(performClose:)) || (s_menuAction == @selector(performMiniaturize:)) || (s_menuAction == @selector(performZoom:)))
+ return YES;
-- (BOOL)isMainWindow
-{
- return YES;
+ return [super validateMenuItem:menuItem];
}
- (void)setTitle:(NSString *)title
- (void)performClose:(id)sender
{
+ NSWindow *o_key_window = [NSApp keyWindow];
+
if (b_dark_interface)
- [self orderOut: sender];
+ {
+ [o_key_window orderOut: sender];
+ if ( [[VLCMain sharedInstance] activeVideoPlayback] && ( !b_nonembedded || o_key_window != self ))
+ [[VLCCoreInteraction sharedInstance] stop];
+ }
else
- [super performClose: sender];
+ {
+ if( b_nonembedded && o_key_window != self )
+ [o_nonembedded_window performClose: sender];
+ else
+ [super performClose: sender];
+ }
}
- (void)performMiniaturize:(id)sender
{
if (b_dark_interface)
+ {
[self miniaturize: sender];
+ if (config_GetInt( VLCIntf, "macosx-pause-minimized" ))
+ {
+ if ([[VLCMain sharedInstance] activeVideoPlayback])
+ [[VLCCoreInteraction sharedInstance] pause];
+ }
+ }
else
[super performMiniaturize: sender];
}
[self saveFrameUsingName: [self frameAutosaveName]];
}
+- (void)applicationWillTerminate:(NSNotification *)notification
+{
+ if( config_GetInt( VLCIntf, "macosx-autosave-volume" ))
+ config_PutInt( VLCIntf->p_libvlc, "volume", i_lastShownVolume );
+
+ [self saveFrameUsingName: [self frameAutosaveName]];
+}
+
+- (void)someWindowWillClose:(NSNotification *)notification
+{
+ if([notification object] == o_nonembedded_window || ([notification object] == self && !b_nonembedded))
+ {
+ if ([[VLCMain sharedInstance] activeVideoPlayback])
+ [[VLCCoreInteraction sharedInstance] stop];
+ }
+}
+
+- (void)someWindowWillMiniaturize:(NSNotification *)notification
+{
+ if (config_GetInt( VLCIntf, "macosx-pause-minimized" ))
+ {
+ if([notification object] == o_nonembedded_window || [notification object] == self)
+ {
+ if([[VLCMain sharedInstance] activeVideoPlayback])
+ [[VLCCoreInteraction sharedInstance] pause];
+ }
+ }
+}
+
#pragma mark -
#pragma mark Update interface and respond to foreign events
- (void)showDropZone
{
+ b_dropzone_active = YES;
[o_right_split_view addSubview: o_dropzone_view];
[o_dropzone_view setFrame: [o_playlist_table frame]];
[[o_playlist_table animator] setHidden:YES];
[[o_playlist_table animator] setHidden: NO];
}
+- (void)hideSplitView
+{
+ NSRect winrect = [self frame];
+ i_lastSplitViewHeight = [o_split_view frame].size.height;
+ winrect.size.height = winrect.size.height - i_lastSplitViewHeight;
+ winrect.origin.y = winrect.origin.y + i_lastSplitViewHeight;
+ [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 )];
+ }
+ else
+ {
+ [self setContentMinSize: NSMakeSize( 604., [o_bottombar_view frame].size.height )];
+ [self setContentMaxSize: NSMakeSize( FLT_MAX, [o_bottombar_view frame].size.height )];
+ }
+ if (i_lastSplitViewHeight < 100)
+ i_lastSplitViewHeight = 300; // random reasonable size
+ b_splitview_removed = YES;
+}
+
+- (void)showSplitView
+{
+ if (b_dark_interface)
+ [self setContentMinSize:NSMakeSize( 604., 288. + [o_titlebar_view frame].size.height )];
+ else
+ [self setContentMinSize:NSMakeSize( 604., 288. )];
+ [self setContentMaxSize: NSMakeSize( FLT_MAX, FLT_MAX )];
+
+ NSRect winrect;
+ winrect = [self frame];
+ winrect.size.height = winrect.size.height + i_lastSplitViewHeight;
+ winrect.origin.y = winrect.origin.y - i_lastSplitViewHeight;
+ [self setFrame: winrect display: YES animate: YES];
+
+ [self performSelector:@selector(resizePlaylistAfterCollapse) withObject: nil afterDelay:0.75];
+ [self performSelector:@selector(updateWindow) withObject: nil afterDelay:0.3];
+
+ b_splitview_removed = NO;
+}
+
- (void)updateTimeSlider
{
input_thread_t * 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 setStringValue: @"00:00"];
[o_time_sld setEnabled: NO];
[o_time_sld setHidden: YES];
+ [o_time_sld_fancygradient_view setHidden: YES];
}
-
- [self performSelectorOnMainThread:@selector(drawFancyGradientEffectForTimeSlider) withObject:nil waitUntilDone:NO];
}
- (void)updateVolumeSlider
playlist_t * p_playlist = pl_Get( VLCIntf );
i_volume = aout_VolumeGet( p_playlist );
+ BOOL b_muted = [[VLCCoreInteraction sharedInstance] isMuted];
- if( i_volume != i_lastShownVolume )
+ if( !b_muted )
{
+ i_lastShownVolume = i_volume;
[o_volume_sld setIntValue: i_volume];
[o_fspanel setVolumeLevel: i_volume];
}
+ else
+ [o_volume_sld setIntValue: 0];
+
+ [o_volume_sld setEnabled: !b_muted];
+ [o_volume_up_btn setEnabled: !b_muted];
}
- (void)updateName
[self setTitle: aString];
[o_fspanel setStreamTitle: aString];
+ vlc_object_release( p_input );
}
else
{
/* chapters & titles */
//FIXME! b_chapters = p_input->stream.i_area_nb > 1;
- if (cachedInputState == PLAYING_S || b_buffering == YES)
- [self makeKeyAndOrderFront: nil];
+ if (( cachedInputState == PLAYING_S || b_buffering == YES ) && [[VLCMain sharedInstance] activeVideoPlayback] )
+ [[o_video_view window] makeKeyAndOrderFront: nil];
+
vlc_object_release( p_input );
}
[o_fspanel setSeekable: b_seekable];
PL_LOCK;
- if (playlist_CurrentSize( p_playlist ) >= 1)
+ if ([[[VLCMain sharedInstance] playlist] currentPlaylistRoot] != p_playlist->p_local_category || p_playlist->p_local_category->i_children > 0)
[self hideDropZone];
else
[self showDropZone];
NSRect oldFrame = [o_time_sld_fancygradient_view frame];
if (f_value != oldFrame.size.width)
{
- [o_time_sld_fancygradient_view setHidden: NO];
+ 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 )];
- [o_time_sld_fancygradient_view setNeedsDisplay:YES];
}
}
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];
+ }
[o_time_sld_fancygradient_view setHidden: YES];
}
[o_pool release];
#pragma mark -
#pragma mark Video Output handling
-
- (id)videoView
+{
+ return o_video_view;
+}
+
+- (id)setupVideoView
{
vout_thread_t *p_vout = getVout();
if (config_GetInt( VLCIntf, "embedded-video" ))
{
BOOL b_videoPlayback = [[VLCMain sharedInstance] activeVideoPlayback];
- if (!b_nonembedded)
- [o_playlist_btn setEnabled: b_videoPlayback];
- else
- {
- [o_playlist_btn setEnabled: NO];
- if (!b_videoPlayback)
- [o_nonembedded_window orderOut: nil];
- }
+ if (!b_videoPlayback)
+ [o_nonembedded_window orderOut: nil];
if( OSX_LION && b_nativeFullscreenMode )
{
if( [NSApp presentationOptions] & NSApplicationPresentationFullScreen )
}
if (b_videoPlayback)
[self makeFirstResponder: o_video_view];
+ else
+ [self makeFirstResponder: nil];
+
+ if (!b_videoPlayback && b_fullscreen)
+ {
+ if (!b_nativeFullscreenMode || !OSX_LION)
+ [[VLCCoreInteraction sharedInstance] toggleFullscreen];
+ }
}
- (void)resizeWindow
{
- if ( !b_fullscreen && !(OSX_LION && [NSApp presentationOptions] == NSApplicationPresentationFullScreen && b_nativeFullscreenMode) )
- {
- NSPoint topleftbase;
- NSPoint topleftscreen;
- NSRect new_frame;
- topleftbase.x = 0;
- topleftbase.y = [self frame].size.height;
- topleftscreen = [self convertBaseToScreen: topleftbase];
+ if ( b_fullscreen || (OSX_LION && [NSApp presentationOptions] & NSApplicationPresentationFullScreen && b_nativeFullscreenMode) )
+ return;
- /* Calculate the window's new size */
- new_frame.size.width = [self frame].size.width - [o_video_view frame].size.width + nativeVideoSize.width;
- if (b_dark_interface)
- new_frame.size.height = [self frame].size.height - [o_video_view frame].size.height + nativeVideoSize.height + [o_titlebar_view frame].size.height;
- else
- new_frame.size.height = [self frame].size.height - [o_video_view frame].size.height + nativeVideoSize.height;
+ NSPoint topleftbase = NSMakePoint(0, [self frame].size.height);
+ NSPoint topleftscreen = [self convertBaseToScreen: topleftbase];
- new_frame.origin.x = topleftscreen.x;
- new_frame.origin.y = topleftscreen.y - new_frame.size.height;
+ /* Calculate the window's new size */
+ float w = [self frame].size.width - [o_video_view frame].size.width
+ + nativeVideoSize.width;
+ float h = [self frame].size.height - [o_video_view frame].size.height
+ + nativeVideoSize.height;
- [[self animator] setFrame:new_frame display:YES];
- }
+ if (b_dark_interface)
+ h += [o_titlebar_view frame].size.height;
+
+ NSRect new_frame = NSMakeRect(topleftscreen.x, topleftscreen.y - h, w, h);
+
+ [[self animator] setFrame:new_frame display:YES];
}
- (void)setNativeVideoSize:(NSSize)size
[NSCursor setHiddenUntilMouseMoves: YES];
}
-- (void)someWindowWillClose:(NSNotification *)notification
-{
- if([notification object] == o_nonembedded_window || [notification object] == self)
- [[VLCCoreInteraction sharedInstance] stop];
-}
-
-- (void)someWindowWillMiniaturize:(NSNotification *)notification
-{
- if([notification object] == o_nonembedded_window || [notification object] == self)
- [[VLCCoreInteraction sharedInstance] pause];
-}
-
#pragma mark -
#pragma mark Fullscreen support
- (void)showFullscreenController
NSRect rect;
vout_thread_t *p_vout = getVout();
BOOL blackout_other_displays = config_GetInt( VLCIntf, "macosx-black" );
+ id o_videoWindow = b_nonembedded ? o_nonembedded_window : self;
if( p_vout )
screen = [NSScreen screenWithDisplayID:(CGDirectDisplayID)config_GetInt( VLCIntf, "macosx-vdev" )];
if (!screen)
{
msg_Dbg( VLCIntf, "chosen screen isn't present, using current screen for fullscreen mode" );
- screen = [self screen];
+ screen = [o_videoWindow screen];
}
if (!screen)
{
[screen blackoutOtherScreens];
/* Make sure we don't see the window flashes in float-on-top mode */
- i_originalLevel = [self level];
- [self setLevel:NSNormalWindowLevel];
+ i_originalLevel = [o_videoWindow level];
+ [o_videoWindow 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 += [self frame].origin.x;
- rect.origin.y += [self frame].origin.y;
+ rect.origin.x += [o_videoWindow frame].origin.x;
+ rect.origin.y += [o_videoWindow frame].origin.y;
o_fullscreen_window = [[VLCWindow alloc] initWithContentRect:rect styleMask: NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
+ [o_fullscreen_window setFullscreen: YES];
[o_fullscreen_window setBackgroundColor: [NSColor blackColor]];
[o_fullscreen_window setCanBecomeKeyWindow: YES];
- if (![self isVisible] || [self alphaValue] == 0.0)
+ if (![o_videoWindow isVisible] || [o_videoWindow alphaValue] == 0.0)
{
/* We don't animate if we are not visible, instead we
* simply fade the display */
if (b_fullscreen)
{
/* Make sure we are hidden */
- [super orderOut: self];
+ if( b_nonembedded )
+ [o_nonembedded_window orderOut: self];
+ else
+ [super orderOut: self];
+
[self unlockFullscreenAnimation];
return;
}
dict1 = [[NSMutableDictionary alloc] initWithCapacity:2];
dict2 = [[NSMutableDictionary alloc] initWithCapacity:3];
- [dict1 setObject:self forKey:NSViewAnimationTargetKey];
+ [dict1 setObject:o_videoWindow forKey:NSViewAnimationTargetKey];
[dict1 setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
[dict2 setObject:o_fullscreen_window forKey:NSViewAnimationTargetKey];
[o_fspanel setVoutWasUpdated: (int)[[o_fullscreen_window screen] displayID]];
[o_fspanel setActive: nil];
- if([self isVisible])
+ if( !b_nonembedded && [self isVisible] )
[super orderOut: self];
+ if( b_nonembedded && [o_nonembedded_window isVisible] )
+ [o_nonembedded_window orderOut: self];
+
[o_fspanel setActive: nil];
b_fullscreen = YES;
[o_fullscreen_btn setState: NO];
/* We always try to do so */
- if (!(OSX_LION && b_nativeFullscreenMode))
- [NSScreen unblackoutScreens];
+ [NSScreen unblackoutScreens];
+
vout_thread_t *p_vout = getVout();
if (p_vout)
{
if (OSX_LEOPARD)
SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
else
- [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
+ [NSApp setPresentationOptions: NSApplicationPresentationDefault];
/* Will release the lock */
[self hasEndedFullscreen];
return;
}
- [self setAlphaValue: 0.0];
- [self orderFront: self];
+ id o_videoWindow = b_nonembedded ? o_nonembedded_window : self;
+
+ [o_videoWindow setAlphaValue: 0.0];
+ [o_videoWindow orderFront: self];
[[o_video_view window] orderFront: self];
[o_fspanel setNonActive: nil];
}
frame = [[o_temp_view superview] convertRect: [o_temp_view frame] toView: nil]; /* Convert to Window base coord */
- frame.origin.x += [self frame].origin.x;
- frame.origin.y += [self frame].origin.y;
+ frame.origin.x += [o_videoWindow frame].origin.x;
+ frame.origin.y += [o_videoWindow frame].origin.y;
dict2 = [[NSMutableDictionary alloc] initWithCapacity:2];
- [dict2 setObject:self forKey:NSViewAnimationTargetKey];
+ [dict2 setObject:o_videoWindow forKey:NSViewAnimationTargetKey];
[dict2 setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
o_fullscreen_anim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict2, nil]];
[[o_temp_view superview] replaceSubview:o_temp_view with:o_video_view];
[o_video_view release];
[o_video_view setFrame:[o_temp_view frame]];
- [self makeFirstResponder: o_video_view];
- if ([self isVisible])
- [super makeKeyAndOrderFront:self]; /* our version contains a workaround */
+ [[o_video_view window] makeFirstResponder: o_video_view];
+ if( [[o_video_view window] isVisible] )
+ {
+ 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;
- [self setLevel:i_originalLevel];
+ [[o_video_view window] setLevel:i_originalLevel];
+
+ // 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_nonembedded_window orderOut: self];
[self unlockFullscreenAnimation];
}
- (void)orderOut: (id)sender
{
/* Make sure we leave fullscreen */
- if (!(OSX_LION && b_nativeFullscreenMode))
+ if (!(OSX_LION || !b_nativeFullscreenMode))
[self leaveFullscreenAndFadeOut: YES];
[super orderOut: sender];
[o_video_view setFrame: [[self contentView] frame]];
b_fullscreen = YES;
[o_fspanel setVoutWasUpdated: (int)[[self screen] displayID]];
+ [o_fspanel setActive: nil];
[self recreateHideMouseTimer];
+ i_originalLevel = [self level];
+ [self setLevel:NSNormalWindowLevel];
if (b_dark_interface)
{
[o_video_view setFrame: [o_split_view frame]];
[NSCursor setHiddenUntilMouseMoves: NO];
[o_fspanel setNonActive: nil];
+ [self setLevel:i_originalLevel];
b_fullscreen = NO;
if (b_dark_interface)
NSRect winrect;
CGFloat f_titleBarHeight = [o_titlebar_view frame].size.height;
winrect = [self frame];
-
+
[o_titlebar_view setFrame: NSMakeRect( 0, winrect.size.height - f_titleBarHeight,
winrect.size.width, f_titleBarHeight )];
[[self contentView] addSubview: o_titlebar_view];
-
+
winrect.size.height = winrect.size.height + f_titleBarHeight;
[self setFrame: winrect display:NO animate:NO];
winrect = [o_split_view frame];
#pragma mark -
#pragma mark split view delegate
-- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex
-{
- if (dividerIndex == 0)
- return 200.0;
- else
- return proposedMin;
-}
-
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex
{
if (dividerIndex == 0)
/* taken under BSD-new from the PXSourceList sample project, adapted for VLC */
- (NSUInteger)sourceList:(PXSourceList*)sourceList numberOfChildrenOfItem:(id)item
{
- //Works the same way as the NSOutlineView data source: `nil` means a parent item
- if(item==nil) {
- return [o_sidebaritems count];
- }
- else {
- return [[item children] count];
- }
+ //Works the same way as the NSOutlineView data source: `nil` means a parent item
+ if(item==nil)
+ return [o_sidebaritems count];
+ else
+ return [[item children] count];
}
- (id)sourceList:(PXSourceList*)aSourceList child:(NSUInteger)index ofItem:(id)item
{
//Works the same way as the NSOutlineView data source: `nil` means a parent item
- if(item==nil) {
- return [o_sidebaritems objectAtIndex:index];
- }
- else {
- return [[item children] objectAtIndex:index];
- }
+ if(item==nil)
+ return [o_sidebaritems objectAtIndex:index];
+ else
+ return [[item children] objectAtIndex:index];
}
- (id)sourceList:(PXSourceList*)aSourceList objectValueForItem:(id)item
{
- return [item title];
+ return [item title];
}
- (void)sourceList:(PXSourceList*)aSourceList setObjectValue:(id)object forItem:(id)item
{
- [item setTitle:object];
+ [item setTitle:object];
}
- (BOOL)sourceList:(PXSourceList*)aSourceList isItemExpandable:(id)item
{
- return [item hasChildren];
+ return [item hasChildren];
}
- (BOOL)sourceList:(PXSourceList*)aSourceList itemHasBadge:(id)item
{
- if ([[item identifier] isEqualToString: @"playlist"])
+ if ([[item identifier] isEqualToString: @"playlist"] || [[item identifier] isEqualToString: @"medialibrary"])
return YES;
- return [item hasBadge];
+ return [item hasBadge];
}
- (NSInteger)sourceList:(PXSourceList*)aSourceList badgeValueForItem:(id)item
{
- if ([[item identifier] isEqualToString: @"playlist"]) {
- playlist_t * p_playlist = pl_Get( VLCIntf );
- NSInteger i_playlist_size;
+ playlist_t * p_playlist = pl_Get( VLCIntf );
+ NSInteger i_playlist_size;
+
+ if ([[item identifier] isEqualToString: @"playlist"])
+ {
+ PL_LOCK;
+ i_playlist_size = p_playlist->p_local_category->i_children;
+ PL_UNLOCK;
+ return i_playlist_size;
+ }
+ if ([[item identifier] isEqualToString: @"medialibrary"])
+ {
PL_LOCK;
- i_playlist_size = p_playlist->items.i_size;
+ i_playlist_size = p_playlist->p_ml_category->i_children;
PL_UNLOCK;
return i_playlist_size;
}
- return [item badgeValue];
+
+ return [item badgeValue];
}
- (BOOL)sourceList:(PXSourceList*)aSourceList itemHasIcon:(id)item
{
- return [item hasIcon];
+ return [item hasIcon];
}
- (NSImage*)sourceList:(PXSourceList*)aSourceList iconForItem:(id)item
{
- return [item icon];
+ return [item icon];
}
- (NSMenu*)sourceList:(PXSourceList*)aSourceList menuForEvent:(NSEvent*)theEvent item:(id)item
{
- if ([theEvent type] == NSRightMouseDown || ([theEvent type] == NSLeftMouseDown && ([theEvent modifierFlags] & NSControlKeyMask) == NSControlKeyMask)) {
- NSMenu * m = [[NSMenu alloc] init];
- if (item != nil)
- [m addItemWithTitle:[item title] action:nil keyEquivalent:@""];
- return [m autorelease];
- }
- return nil;
+ if ([theEvent type] == NSRightMouseDown || ([theEvent type] == NSLeftMouseDown && ([theEvent modifierFlags] & NSControlKeyMask) == NSControlKeyMask))
+ {
+ if (item != nil)
+ {
+ NSMenu * m;
+ if ([item sdtype] > 0)
+ {
+ m = [[NSMenu alloc] init];
+ playlist_t * p_playlist = pl_Get( VLCIntf );
+ BOOL sd_loaded = playlist_IsServicesDiscoveryLoaded( p_playlist, [[item identifier] UTF8String] );
+ if (!sd_loaded)
+ [m addItemWithTitle:_NS("Enable") action:@selector(sdmenuhandler:) keyEquivalent:@""];
+ else
+ [m addItemWithTitle:_NS("Disable") action:@selector(sdmenuhandler:) keyEquivalent:@""];
+ [[m itemAtIndex:0] setRepresentedObject: [item identifier]];
+ }
+ return [m autorelease];
+ }
+ }
+
+ return nil;
+}
+
+- (IBAction)sdmenuhandler:(id)sender
+{
+ NSString * identifier = [sender representedObject];
+ if ([identifier length] > 0 && ![identifier isEqualToString:@"lua{sd='freebox',longname='Freebox TV'}"])
+ {
+ playlist_t * p_playlist = pl_Get( VLCIntf );
+ BOOL sd_loaded = playlist_IsServicesDiscoveryLoaded( p_playlist, [identifier UTF8String] );
+
+ if (!sd_loaded)
+ playlist_ServicesDiscoveryAdd( p_playlist, [identifier UTF8String] );
+ else
+ playlist_ServicesDiscoveryRemove( p_playlist, [identifier UTF8String] );
+ }
}
#pragma mark -
/* taken under BSD-new from the PXSourceList sample project, adapted for VLC */
- (BOOL)sourceList:(PXSourceList*)aSourceList isGroupAlwaysExpanded:(id)group
{
+ if ([[group identifier] isEqualToString:@"library"])
+ return YES;
+
return NO;
}
- (void)sourceListSelectionDidChange:(NSNotification *)notification
{
- NSIndexSet *selectedIndexes = [o_sidebar_view selectedRowIndexes];
+ playlist_t * p_playlist = pl_Get( VLCIntf );
- //Set the label text to represent the new selection
- if([selectedIndexes count]==1) {
- NSString *title = [[o_sidebar_view itemAtRow:[selectedIndexes firstIndex]] title];
+ NSIndexSet *selectedIndexes = [o_sidebar_view selectedRowIndexes];
+ id item = [o_sidebar_view itemAtRow:[selectedIndexes firstIndex]];
+
+
+ //Set the label text to represent the new selection
+ if ([item sdtype] > -1 && [[item identifier] length] > 0)
+ {
+ BOOL sd_loaded = playlist_IsServicesDiscoveryLoaded( p_playlist, [[item identifier] UTF8String] );
+ if (!sd_loaded)
+ {
+ playlist_ServicesDiscoveryAdd( p_playlist, [[item identifier] UTF8String] );
+ }
+ }
+
+ [o_chosen_category_lbl setStringValue:[item title]];
+
+ 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];
+ }
+ else
+ {
+ playlist_item_t * pl_item;
+ PL_LOCK;
+ pl_item = playlist_ChildSearchName( p_playlist->p_root, [[item untranslatedTitle] UTF8String] );
+ PL_UNLOCK;
+ [[[VLCMain sharedInstance] playlist] setPlaylistRoot: pl_item];
+ }
- [o_chosen_category_lbl setStringValue:title];
- }
- else {
- [o_chosen_category_lbl setStringValue:@"(none)"];
- }
+ PL_LOCK;
+ if ([[[VLCMain sharedInstance] playlist] currentPlaylistRoot] != p_playlist->p_local_category || p_playlist->p_local_category->i_children > 0)
+ [self hideDropZone];
+ else
+ [self showDropZone];
+ PL_UNLOCK;
}
@end