You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
11 KiB

/*****************************************************************************
* VLCFullScreenControllerWindow.m: class that allow media controlling in
* fullscreen (with the mouse)
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Jérôme Decoodt <djc at videolan dot org>
* Felix Kühne <fkuehne at videolan dot org>
* Pierre d'Herbemont <pdherbemont # videolan.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCFullScreenControllerWindow.h"
@interface VLCFullScreenControllerWindow (Private)
- (void)hide;
- (void)show;
- (void)updateTrackingRect;
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow
*/
@implementation VLCFullScreenControllerWindow
/* We override this initializer so we can set the NSBorderlessWindowMask styleMask, and set a few other important settings */
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag
{
if( self = [super initWithContentRect:contentRect styleMask:NSTexturedBackgroundWindowMask backing:bufferingType defer:flag] )
{
[self setOpaque:NO];
[self setHasShadow: NO];
[self setBackgroundColor:[NSColor clearColor]];
/* let the window sit on top of everything else and start out completely transparent */
[self setLevel:NSFloatingWindowLevel];
[self center];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[hideWindowTimer invalidate];
[hideWindowTimer release];
[videoViewTrackingArea release];
[super dealloc];
}
- (void)awakeFromNib
{
hideWindowTimer = nil;
videoViewTrackingArea = nil;
[self setMovableByWindowBackground:YES];
/* Make sure we'll detect when to close the window, see animationDidStop:finished: */
CAAnimation *alphaValueAnimation = [CABasicAnimation animation];
[alphaValueAnimation setDelegate:self];
[self setAnimations:[NSDictionary dictionaryWithObject:alphaValueAnimation forKey:@"alphaValue"]];
hideWindowTimer = nil;
/* WindowView setup */
[[mainWindowController.videoView window] setAcceptsMouseMovedEvents:YES];
[[mainWindowController.videoView window] makeFirstResponder:mainWindowController.videoView];
[mainWindowController.videoView setPostsBoundsChangedNotifications: YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoViewDidChangeBounds:) name:NSViewBoundsDidChangeNotification object:(id)mainWindowController.videoView];
/* Make sure we can know when the mouse is inside us */
[[self contentView] addTrackingRect:[[self contentView] bounds] owner:self userData:nil assumeInside:NO];
/* Bindings connection */
/* Sound */
[volumeSlider setKnobImage:[NSImage imageNamed:@"fs_volume_slider_knob_highlight.png"]];
[volumeSlider setBackgroundImage:[NSImage imageNamed:@"fs_volume_slider_bar.png"]];
[volumeSlider setNeedsDisplay:YES];
[volumeSlider bind:@"value" toObject:[VLCLibrary sharedLibrary] withKeyPath:@"audio.volume" options: nil];
/* media position */
[mediaPositionSlider setKnobImage:[NSImage imageNamed:@"fs_time_slider_knob.png"]];
[mediaPositionSlider setBackgroundImage:[NSImage imageNamed:@"fs_time_slider.png"]];
[mediaPositionSlider setNeedsDisplay:YES];
[mediaPositionSlider bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaPositionSlider bind:@"enabled2" toObject:mainWindowController.mediaPlayer withKeyPath:@"seekable" options: nil];
[mediaPositionSlider bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"position" options:
[NSDictionary dictionaryWithObjectsAndKeys:@"Float10000FoldTransformer", NSValueTransformerNameBindingOption,
[NSNumber numberWithBool:NO], NSConditionallySetsEnabledBindingOption, nil ]];
[fillScreenButton bind:@"value" toObject:mainWindowController.videoView withKeyPath:@"videoLayer.fillScreen" options: nil];
[fullScreenButton bind:@"value" toObject:mainWindowController.videoView withKeyPath:@"fullScreen" options: nil];
[mediaReadingProgressText bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"time.stringValue" options: nil];
[mediaDescriptionText bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"description" options: nil];
/* mainWindowController.mediaPlayer */
[mediaPlayerPlayPauseStopButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaPlayerPlayPauseStopButton bind:@"state" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"alternateImage" toObject:mainWindowController.mediaPlayer withKeyPath:@"stateAsFullScreenButtonAlternateImage" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"image" toObject:mainWindowController.mediaPlayer withKeyPath:@"stateAsFullScreenButtonImage" options: nil];
[mediaPlayerBackwardPrevButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerForwardNextButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerForwardNextButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerForwardNextButton setAction:@selector(fastForward)];
[mediaPlayerBackwardPrevButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerBackwardPrevButton setAction:@selector(rewind)];
[mediaPlayerPlayPauseStopButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerPlayPauseStopButton setAction:@selector(pause)];
[self bind:@"fullScreen" toObject:mainWindowController.videoView withKeyPath:@"fullScreen" options: nil];
active = NO;
}
- (BOOL)fullScreen
{
/* Only to comply to KVC */
return active;
}
- (void)setFullScreen:(BOOL)fullScreen
{
if(fullScreen)
{
active = YES;
[self show];
}
else
{
[self hide];
active = NO;
}
}
-(void)center
{
/* centre the panel in the lower third of the screen */
NSPoint theCoordinate;
NSRect theScreensFrame;
NSRect theWindowsFrame;
theScreensFrame = [[self screen] frame];
theWindowsFrame = [self frame];
theCoordinate.x = (theScreensFrame.size.width - theWindowsFrame.size.width) / 2 + theScreensFrame.origin.x;
theCoordinate.y = (theScreensFrame.size.height / 3) - theWindowsFrame.size.height + theScreensFrame.origin.y;
[self setFrameTopLeftPoint: theCoordinate];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (Private)
*/
@implementation VLCFullScreenControllerWindow (Private)
- (void)show
{
if(![self isVisible])
self.alphaValue = 0.0;
if( !NSPointInRect([NSEvent mouseLocation],[self frame]) )
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hide) userInfo:nil repeats:NO] retain];
}
[self orderFront:self];
[self.animator setAlphaValue:1.0];
}
- (void)hide
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = nil;
if ([self isVisible])
{
[self.animator setAlphaValue:0.0];
[NSCursor setHiddenUntilMouseMoves:YES];
}
[self updateTrackingRect];
}
- (void)updateTrackingRect
{
VLCBrowsableVideoView * videoView = mainWindowController.videoView;
if( videoViewTrackingArea )
{
[videoView removeTrackingArea:videoViewTrackingArea];
[videoViewTrackingArea release];
}
videoViewTrackingArea = [[NSTrackingArea alloc] initWithRect:[videoView bounds] options:NSTrackingMouseMoved|NSTrackingActiveAlways|NSTrackingAssumeInside|NSTrackingEnabledDuringMouseDrag owner:self userInfo:nil];
[videoView addTrackingArea:videoViewTrackingArea];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (NSAnimationDelegate)
*/
@implementation VLCFullScreenControllerWindow (NSAnimationDelegate)
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
if( self.alphaValue == 0.0 )
[self orderOut:self];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (NSTrackingRectCallbacksInVideoView)
*/
@implementation VLCFullScreenControllerWindow (NSTrackingRectCallbacks)
- (void)mouseMoved:(NSEvent *)theEvent
{
if([theEvent window] != self)
{
if( active )
[self show];
}
}
- (void)mouseEntered:(NSEvent *)theEvent
{
if([theEvent window] == self)
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = nil;
}
}
- (void)mouseExited:(NSEvent *)theEvent
{
if([theEvent window] == self)
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hide) userInfo:nil repeats:NO] retain];
}
else
{
if( active )
[self hide];
}
}
- (void)cursorUpdate:(NSEvent *)event
{
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (VideoViewBoundsChanges)
*/
@implementation VLCFullScreenControllerWindow (VideoViewBoundsChanges)
- (void)videoViewDidChangeBounds:(NSNotification *)theNotification
{
[self updateTrackingRect];
}
@end