#include <vlc/vlc.h>
#include <vlc/libvlc.h>
+#import <QuartzCore/QuartzCore.h>
+
/* Notifications */
NSString *VLCVideoViewEnteredFullScreen = @"VLCVideoViewEnteredFullScreen";
NSString *VLCVideoViewLeftFullScreen = @"VLCVideoViewLeftFullScreen";
+/******************************************************************************
+ * Soon deprecated stuff
+ */
+
/* This is a forward reference to VLCOpenGLVoutView specified in minimal_macosx
library. We could get rid of this, but it prevents warnings from the
- compiler. */
+ compiler. (Scheduled to deletion) */
@interface VLCOpenGLVoutView : NSView
- (void)detachFromVout;
@end
+/* Depreacted methods */
+@interface VLCVideoView (Deprecated)
+- (void)setStretchesVideo:(BOOL)value;
+- (BOOL)stretchesVideo;
+
+- (void)addVoutSubview:(NSView *)aView; /* (Scheduled to deletion) */
+- (void)removeVoutSubview:(NSView *)aView; /* (Scheduled to deletion) */
+@end
+
+/******************************************************************************
+ * VLCVideoView (Private)
+ */
+@interface VLCVideoView ()
+/* Property */
+@property (readwrite, assign) BOOL fullscreen;
+@end
+
+@interface VLCVideoView (Private)
+/* Method */
+- (void)addVoutLayer:(CALayer *)aLayer;
+@end
+
+
+
+/******************************************************************************
+ * Interface & Implementation VLCConstraintLayoutManager
+ *
+ * Manage the size of the video layer
+ */
+@interface VLCConstraintLayoutManager : CAConstraintLayoutManager
+{
+ CGSize originalVideoSize;
+ BOOL fillScreenEntirely;
+}
+@property BOOL fillScreenEntirely;
+@property CGSize originalVideoSize;
+@end
+
+@implementation VLCConstraintLayoutManager
+@synthesize fillScreenEntirely;
+@synthesize originalVideoSize;
+- (id)init
+{
+ if( self = [super init] )
+ {
+ self.originalVideoSize = CGSizeMake(0., 0.);
+ self.fillScreenEntirely = NO;
+ }
+ return self;
+
+}
++ (id)layoutManager
+{
+ return [[[VLCConstraintLayoutManager alloc] init] autorelease];
+}
+- (void)layoutSublayersOfLayer:(CALayer *)layer
+{
+ /* Called by CA, when our rootLayer needs layout */
+ [super layoutSublayersOfLayer:layer];
+
+ /* After having done everything normally resize the vlcopengllayer */
+ if( [[layer sublayers] count] > 0 && [[[[layer sublayers] objectAtIndex:0] name] isEqualToString:@"vlcopengllayer"])
+ {
+ CALayer * videolayer = [[layer sublayers] objectAtIndex:0];
+ CGRect bounds = layer.bounds;
+ float new_height = (bounds.size.width * originalVideoSize.height) / originalVideoSize.width;
+
+ if( fillScreenEntirely )
+ {
+ if( bounds.size.height > new_height )
+ bounds.size.height = new_height;
+ else
+ bounds.size.width = (bounds.size.height * originalVideoSize.width) / originalVideoSize.height;
+ }
+ else
+ {
+ if( bounds.size.height > new_height )
+ bounds.size.width = (bounds.size.height * originalVideoSize.width) / originalVideoSize.height;
+ else
+ bounds.size.height = new_height;
+ }
+
+ bounds.origin = CGPointMake( 0.0, 0.0 );
+ videolayer.bounds = bounds;
+ videolayer.position = CGPointMake((layer.bounds.size.width - layer.bounds.origin.x)/2, (layer.bounds.size.height - layer.bounds.origin.y)/2);
+ }
+}
+@end
+
+/******************************************************************************
+ * Implementation VLCVideoView
+ */
+
@implementation VLCVideoView
+@synthesize fullscreen;
+
+- (BOOL)fillScreen
+{
+ return [layoutManager fillScreenEntirely];
+}
+- (void)setFillScreen:(BOOL)fillScreen
+{
+ [layoutManager setFillScreenEntirely:fillScreen];
+ [[self layer] setNeedsLayout];
+}
+
+
- (id)initWithFrame:(NSRect)rect
{
if (self = [super initWithFrame:rect])
[self setBackColor:[NSColor blackColor]];
[self setStretchesVideo:NO];
[self setAutoresizesSubviews:YES];
+ [self setFillScreen: NO];
+ layoutManager = [VLCConstraintLayoutManager layoutManager];
}
return self;
}
- (void)dealloc
{
+ [layoutManager release];
delegate = nil;
[backColor release];
[super dealloc];
return backColor;
}
-- (void)setStretchesVideo:(BOOL)value
-{
- stretchesVideo = value;
-}
-
-- (BOOL)stretchesVideo
-{
- return stretchesVideo;
-}
-
-/* This is called by the libvlc module 'minimal_macosx' as soon as there is one
- * vout available
- */
-- (void)addVoutSubview:(NSView *)aView
-{
- if( [[self subviews] count] )
- {
- /* XXX: This is a hack until core gets fixed */
- int i;
- for( i = 0; i < [[self subviews] count]; i++ )
- {
- [[[self subviews] objectAtIndex:i] detachFromVout];
- [[[self subviews] objectAtIndex:i] retain];
- [[[self subviews] objectAtIndex:i] removeFromSuperview];
- }
- }
- [self addSubview:aView];
- [aView setFrame:[self bounds]];
-
- // TODO: Should we let the media player specify these values?
- [aView setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
-}
-
-- (void)removeVoutSubview:(NSView *)view
-{
- // Should we do something? I don't know, however the protocol requires
- // this to be implemented
-}
-
/* This is a LibVLC notification that we're about to enter into full screen,
there is no other place where I can see where we can trap this event */
- (void)enterFullscreen
withDelegateMethod:nil
withNotificationName:VLCVideoViewEnteredFullScreen];
- // There is nothing else to do, as this object strictly displays the video feed
+ [super enterFullScreenMode:[[self window] screen] withOptions:nil];
+ self.fullscreen = YES;
}
/* This is a LibVLC notification that we're about to enter leaving full screen,
withNotificationName:VLCVideoViewLeftFullScreen];
// There is nothing else to do, as this object strictly displays the video feed
+ [super exitFullScreenModeWithOptions:nil];
+ self.fullscreen = NO;
}
- (void)drawRect:(NSRect)aRect
{
return YES;
}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ if([theEvent clickCount] != 2)
+ return;
+ if(self.fullscreen)
+ [self leaveFullscreen];
+ else
+ [self enterFullscreen];
+}
+@end
+
+/******************************************************************************
+ * Implementation VLCVideoView (Private)
+ */
+
+@implementation VLCVideoView (Private)
+
+/* This is called by the libvlc module 'opengllayer' as soon as there is one
+ * vout available
+ */
+- (void)addVoutLayer:(CALayer *)aLayer
+{
+ [CATransaction begin];
+ [self setWantsLayer: YES];
+ CALayer * rootLayer = [self layer];
+
+ aLayer.name = @"vlcopengllayer";
+
+ [layoutManager setOriginalVideoSize:aLayer.bounds.size];
+ [rootLayer setLayoutManager:layoutManager];
+ [rootLayer insertSublayer:aLayer atIndex:0];
+
+ [aLayer setNeedsLayout];
+ [aLayer setNeedsDisplay];
+ [rootLayer setNeedsDisplay];
+ [rootLayer layoutIfNeeded];
+ [CATransaction commit];
+}
+
+@end
+
+/******************************************************************************
+ * Implementation VLCVideoView (Deprecated)
+ */
+
+@implementation VLCVideoView (Deprecated)
+
+- (void)setStretchesVideo:(BOOL)value
+{
+ stretchesVideo = value;
+}
+
+- (BOOL)stretchesVideo
+{
+ return stretchesVideo;
+}
+
+/* This is called by the libvlc module 'minimal_macosx' as soon as there is one
+ * vout available
+ */
+- (void)addVoutSubview:(NSView *)aView /* (Scheduled to deletion) */
+{
+ /* This is where the real video comes from */
+ if( [[self subviews] count] )
+ {
+ /* XXX: This is a hack until core gets fixed */
+ int i;
+ for( i = 0; i < [[self subviews] count]; i++ )
+ {
+ [[[self subviews] objectAtIndex:i] detachFromVout];
+ [[[self subviews] objectAtIndex:i] retain];
+ [[[self subviews] objectAtIndex:i] removeFromSuperview];
+ }
+ }
+
+ [aView setFrame:[self bounds]];
+
+ [self addSubview:aView];
+
+ // TODO: Should we let the media player specify these values?
+ [aView setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
+}
+
+- (void)removeVoutSubview:(NSView *)view /* (Scheduled to deletion) */
+{
+ // Should we do something? I don't know, however the protocol requires
+ // this to be implemented
+}
@end