Commit 22328652 authored by Felix Paul Kühne's avatar Felix Paul Kühne
Browse files

macosx: merge Eric Dudiak's code from GSoC 2008

Nibs will be added later on. No user-visible change as of yet.
parent 7b4ce76a
Changes between 1.0.0-rc1 and 1.1.0-git:
----------------------------------------
Mac OS X Interface:
* Completely reworked user interface (based upon works from GSoC 2008)
Changes between 0.9.9a and 1.0.0-rc1:
------------------------------------
......
......@@ -93,6 +93,7 @@ Dugal Harris - DirectShow fixes and MJPEG patches
Dylan Aïssi <aissi dot dylan at free dot fr> - French translation
Dylan Yudaken <dyudaken -- gmail # com> - hotkeys patch
Emmanuel Blindauer <manu at agat.net> - aRts audio output
Eric Dudiak <dudiak at gmail dot com> - Mac OS X Interface rework (GSoC 2008)
Enrico Gueli <e_gueli at yahoo.it> - Brightness threshold in adjust video filter
Enrique Osuna <enrique.osuna at gmail.com> - Various bug fixes in libvlc. Major Mac OS X Framework improvements.
Eren Türkay <turkay dot eren \a/ gmail point com> - Speex boundary checks and security fix
......
......@@ -38,6 +38,8 @@
IBOutlet id o_btn_shuffle;
IBOutlet id o_btn_addNode;
IBOutlet id o_btn_repeat;
IBOutlet id o_btn_repeat_embed;
IBOutlet id o_btn_shuffle_embed;
NSImage * o_repeat_single;
NSImage * o_repeat_all;
......@@ -114,6 +116,30 @@
@end
/*****************************************************************************
* VLCAutoGeneratedMenuContent interface
*****************************************************************************
* This holds our data for autogenerated menus
*****************************************************************************/
@interface VLCAutoGeneratedMenuContent : NSObject
{
char *psz_name;
vlc_object_t * _vlc_object;
vlc_value_t value;
int i_type;
}
- (id)initWithVariableName: (const char *)name
ofObject: (vlc_object_t *)object
andValue: (vlc_value_t)value
ofType: (int)type;
- (const char *)name;
- (vlc_value_t)value;
- (vlc_object_t *)vlcObject;
- (int)type;
@end
/*****************************************************************************
* VLCTimeField interface
*****************************************************************************
......
......@@ -40,30 +40,6 @@
#include <vlc_osd.h>
#include <vlc_keys.h>
/*****************************************************************************
* VLCAutoGeneratedMenuContent interface
*****************************************************************************
* This holds our data for autogenerated menus
*****************************************************************************/
@interface VLCAutoGeneratedMenuContent : NSObject
{
char *psz_name;
vlc_object_t * _vlc_object;
vlc_value_t value;
int i_type;
}
- (id)initWithVariableName: (const char *)name
ofObject: (vlc_object_t *)object
andValue: (vlc_value_t)value
ofType: (int)type;
- (const char *)name;
- (vlc_value_t)value;
- (vlc_object_t *)vlcObject;
- (int)type;
@end
#pragma mark -
/*****************************************************************************
* VLCControls implementation
......@@ -160,24 +136,24 @@
- (id)voutView
{
id window;
id voutView = nil;
id embeddedViewList = [[VLCMain sharedInstance] embeddedList];
NSEnumerator *enumerator = [[NSApp orderedWindows] objectEnumerator];
while( !voutView && ( window = [enumerator nextObject] ) )
id o_window;
id o_voutView = nil;
id o_embeddedViewList = [[VLCMain sharedInstance] embeddedList];
NSEnumerator *o_enumerator = [[NSApp orderedWindows] objectEnumerator];
while( !o_voutView && ( o_window = [o_enumerator nextObject] ) )
{
/* We have an embedded vout */
if( [embeddedViewList windowContainsEmbedded: window] )
if( [o_embeddedViewList windowContainsEmbedded: o_window] )
{
voutView = [embeddedViewList viewForWindow: window];
o_voutView = [o_embeddedViewList viewForWindow: o_window];
}
/* We have a detached vout */
else if( [[window className] isEqualToString: @"VLCVoutWindow"] )
else if( [[o_window className] isEqualToString: @"VLCVoutWindow"] )
{
voutView = [window voutView];
o_voutView = [o_window voutView];
}
}
return [[voutView retain] autorelease];
return [[o_voutView retain] autorelease];
}
- (IBAction)stop:(id)sender
......@@ -243,16 +219,19 @@
{
[o_btn_repeat setImage: o_repeat_single];
[o_btn_repeat setAlternateImage: o_repeat_all];
[o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOneOn"]];
}
- (void)repeatAll
{
[o_btn_repeat setImage: o_repeat_all];
[o_btn_repeat setAlternateImage: o_repeat_off];
[o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOn"]];
}
- (void)repeatOff
{
[o_btn_repeat setImage: o_repeat_off];
[o_btn_repeat setAlternateImage: o_repeat_single];
[o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeat"]];
}
- (void)shuffle
{
......@@ -260,6 +239,10 @@
playlist_t *p_playlist = pl_Hold( VLCIntf );
var_Get( p_playlist, "random", &val );
[o_btn_shuffle setState: val.b_bool];
if(val.b_bool)
[o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffleOn"]];
else
[o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffle"]];
pl_Release( VLCIntf );
}
......
......@@ -32,10 +32,31 @@
IBOutlet id o_btn_backward;
IBOutlet id o_btn_forward;
IBOutlet id o_btn_fullscreen;
IBOutlet id o_btn_equalizer;
IBOutlet id o_btn_playlist;
IBOutlet id o_btn_play;
IBOutlet id o_slider;
IBOutlet id o_btn_prev;
IBOutlet id o_btn_stop;
IBOutlet id o_btn_next;
IBOutlet id o_btn_volume_down;
IBOutlet id o_volumeslider;
IBOutlet id o_btn_volume_up;
IBOutlet id o_timeslider;
IBOutlet id o_main_pgbar;
IBOutlet id o_time;
IBOutlet id o_scrollfield;
IBOutlet id o_horizontal_split;
IBOutlet id o_vertical_split;
IBOutlet id o_videosubview;
IBOutlet id o_sidebar_list;
IBOutlet id o_view;
IBOutlet id o_background_view;
IBOutlet id o_searchfield;
IBOutlet id o_status;
IBOutlet id o_playlist;
IBOutlet id o_playlist_view;
IBOutlet id o_playlist_table;
IBOutlet id o_vlc_main;
NSImage * o_img_play;
NSImage * o_img_play_pressed;
......@@ -53,19 +74,30 @@
BOOL b_window_is_invisible;
NSSize videoRatio;
int originalLevel;
NSInteger originalLevel;
}
- (void)controlTintChanged;
- (void)setTime: (NSString *)o_arg_ime position: (float)f_position;
- (id)getPgbar;
- (void)playStatusUpdated: (int)i_status;
- (void)setSeekable: (BOOL)b_seekable;
- (void)setStop:(BOOL)b_input;
- (void)setPrev:(BOOL)b_input;
- (void)setNext:(BOOL)b_input;
- (void)setVolumeEnabled:(BOOL)b_input;
- (void)setScrollString:(NSString *)o_string;
- (void)setVolumeSlider:(float)f_level;
- (void)setVideoRatio:(NSSize)ratio;
- (NSView *)mainView;
- (IBAction)togglePlaylist:(id)sender;
- (BOOL)isFullscreen;
- (void)lockFullscreenAnimation;
......@@ -83,3 +115,47 @@
- (void)setFrameOnMainThread:(NSData*)packedargs;
@end
/*****************************************************************************
* embeddedbackground
*****************************************************************************/
@interface embeddedbackground : NSView
{
IBOutlet id o_window;
IBOutlet id o_timeslider;
IBOutlet id o_main_pgbar;
IBOutlet id o_time;
IBOutlet id o_scrollfield;
IBOutlet id o_searchfield;
IBOutlet id o_btn_backward;
IBOutlet id o_btn_forward;
IBOutlet id o_btn_fullscreen;
IBOutlet id o_btn_equalizer;
IBOutlet id o_btn_playlist;
IBOutlet id o_btn_play;
IBOutlet id o_btn_prev;
IBOutlet id o_btn_stop;
IBOutlet id o_btn_next;
IBOutlet id o_btn_volume_down;
IBOutlet id o_volumeslider;
IBOutlet id o_btn_volume_up;
NSPoint dragStart;
}
@end
/*****************************************************************************
* statusbar
*****************************************************************************/
@interface statusbar : NSView
{
IBOutlet id o_text;
BOOL mainwindow;
}
@end
\ No newline at end of file
/*****************************************************************************
* embeddedwindow.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2005-2009 the VideoLAN team
* Copyright (C) 2005-2008 the VideoLAN team
* $Id$
*
* Authors: Benjamin Pracht <bigben at videolan dot org>
......@@ -26,14 +26,26 @@
* Preamble
*****************************************************************************/
/* DisableScreenUpdates, SetSystemUIMode, ... */
#import <QuickTime/QuickTime.h>
#import "intf.h"
#import "controls.h"
#import "vout.h"
#import "embeddedwindow.h"
#import "fspanel.h"
#import "playlist.h"
/*****************************************************************************
* extension to NSWindow's interface to fix compilation warnings
* and let us access this functions properly
* this uses a private Apple-API, but works fine on all current OSX releases
* keep checking for compatiblity with future releases though
*****************************************************************************/
/* SetSystemUIMode, ... */
#import <Carbon/Carbon.h>
@interface NSWindow (UndocumentedWindowProperties)
- (void)setBottomCornerRounded: (BOOL)value;
@end
/*****************************************************************************
* VLCEmbeddedWindow Implementation
......@@ -41,40 +53,48 @@
@implementation VLCEmbeddedWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask: (NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
BOOL b_useTextured = YES;
if( [[NSWindow class] instancesRespondToSelector:@selector(setContentBorderThickness:forEdge:)] )
{
b_useTextured = NO;
windowStyle ^= NSTexturedBackgroundWindowMask;
}
self = [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation];
if(! b_useTextured )
{
[self setContentBorderThickness:28.0 forEdge:NSMinYEdge];
}
return self;
}
- (void)awakeFromNib
{
[self setDelegate: self];
[self setBottomCornerRounded:NO];
/* button strings */
[o_btn_backward setToolTip: _NS("Rewind")];
[o_btn_forward setToolTip: _NS("Fast Forward")];
[o_btn_fullscreen setToolTip: _NS("Fullscreen")];
[o_btn_play setToolTip: _NS("Play")];
[o_slider setToolTip: _NS("Position")];
o_img_play = [NSImage imageNamed: @"play_embedded"];
o_img_pause = [NSImage imageNamed: @"pause_embedded"];
[o_timeslider setToolTip: _NS("Position")];
[o_btn_prev setToolTip: _NS("Previous")];
[o_btn_stop setToolTip: _NS("Stop")];
[o_btn_next setToolTip: _NS("Next")];
[o_volumeslider setToolTip: _NS("Volume")];
[o_btn_playlist setToolTip: _NS("Playlist")];
[self setTitle: _NS("VLC media player")];
if(MACOS_VERSION < 10.5f) {
o_img_play = [NSImage imageNamed: @"play"];
o_img_pause = [NSImage imageNamed: @"pause"];
[o_btn_play setImage: [NSImage imageNamed: @"play"]];
}
else {
o_img_play = [NSImage imageNamed: @"play_big"];
o_img_pause = [NSImage imageNamed: @"pause_big"];
}
[self controlTintChanged];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector( controlTintChanged )
name: NSControlTintDidChangeNotification
object: nil];
/* Set color of sidebar to Leopard's "Sidebar Blue" */
[o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedRed:0.820
green:0.843
blue:0.886
alpha:1.0]];
[self setMinSize:NSMakeSize([o_sidebar_list convertRect:[o_sidebar_list bounds]
toView: nil].size.width + 551., 114.)];
/* Useful to save o_view frame in fullscreen mode */
o_temp_view = [[NSView alloc] init];
[o_temp_view setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
......@@ -86,13 +106,9 @@
[o_btn_fullscreen setState: NO];
b_fullscreen = NO;
[self setMovableByWindowBackground:YES];
[self setDelegate:self];
/* Make sure setVisible: returns NO */
[self orderOut:self];
b_window_is_invisible = YES;
//b_window_is_invisible = YES;
videoRatio = NSMakeSize( 0., 0. );
}
......@@ -102,21 +118,29 @@
if( [o_btn_play alternateImage] == o_img_play_pressed )
b_playing = YES;
if (MACOS_VERSION < 10.5f) {
/* System is running Tiger and should use aqua buttons */
[o_btn_backward setImage: [NSImage imageNamed: @"skip_previous_active"]];
[o_btn_forward setImage: [NSImage imageNamed: @"skip_forward_active"]];
if( [NSColor currentControlTint] == NSGraphiteControlTint )
{
o_img_play_pressed = [NSImage imageNamed: @"play_embedded_graphite"];
o_img_pause_pressed = [NSImage imageNamed: @"pause_embedded_graphite"];
[o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_embedded_graphite"]];
[o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_embedded_graphite"]];
[o_btn_fullscreen setAlternateImage: [NSImage imageNamed: @"fullscreen_graphite"]];
o_img_play_pressed = [NSImage imageNamed: @"play_graphite"];
o_img_pause_pressed = [NSImage imageNamed: @"pause_graphite"];
[o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_graphite"]];
[o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_graphite"]];
}
else
{
o_img_play_pressed = [NSImage imageNamed: @"play_embedded_blue"];
o_img_pause_pressed = [NSImage imageNamed: @"pause_embedded_blue"];
[o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_embedded_blue"]];
[o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_embedded_blue"]];
[o_btn_fullscreen setAlternateImage: [NSImage imageNamed: @"fullscreen_blue"]];
o_img_play_pressed = [NSImage imageNamed: @"play_blue"];
o_img_pause_pressed = [NSImage imageNamed: @"pause_blue"];
[o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_blue"]];
[o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_blue"]];
}
}
else{
/* System is running Leopard or later and should use metal buttons */
o_img_play_pressed = [NSImage imageNamed: @"play_big_down"];
o_img_pause_pressed = [NSImage imageNamed: @"pause_big_down"];
}
if( b_playing )
......@@ -139,7 +163,7 @@
- (void)setTime:(NSString *)o_arg_time position:(float)f_position
{
[o_time setStringValue: o_arg_time];
[o_slider setFloatValue: f_position];
[o_timeslider setFloatValue: f_position];
}
- (void)playStatusUpdated:(int)i_status
......@@ -162,7 +186,45 @@
{
[o_btn_forward setEnabled: b_seekable];
[o_btn_backward setEnabled: b_seekable];
[o_slider setEnabled: b_seekable];
[o_timeslider setEnabled: b_seekable];
}
- (void)setScrollString:(NSString *)o_string
{
[o_scrollfield setStringValue: o_string];
}
- (id)getPgbar
{
if( o_main_pgbar )
return o_main_pgbar;
return nil;
}
- (void)setStop:(BOOL)b_input
{
[o_btn_stop setEnabled: b_input];
}
- (void)setNext:(BOOL)b_input
{
[o_btn_next setEnabled: b_input];
}
- (void)setPrev:(BOOL)b_input
{
[o_btn_prev setEnabled: b_input];
}
- (void)setVolumeEnabled:(BOOL)b_input
{
[o_volumeslider setEnabled: b_input];
}
- (void)setVolumeSlider:(float)f_level
{
[o_volumeslider setFloatValue: f_level];
}
- (BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame
......@@ -175,6 +237,8 @@
{
playlist_t * p_playlist = pl_Hold( VLCIntf );
/* Only want to stop playback if video is playing */
if( videoRatio.height != 0. && videoRatio.width != 0. )
playlist_Stop( p_playlist );
pl_Release( VLCIntf );
return YES;
......@@ -195,6 +259,16 @@
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
{
NSView *playlist_area = [[o_vertical_split subviews] objectAtIndex:1];
NSRect newList = [playlist_area frame];
if( newList.size.height < 50 && newList.size.height > 0 ) {
[self togglePlaylist:self];
}
/* With no video open or with the playlist open the behavior is odd */
if( newList.size.height > 50 )
return proposedFrameSize;
if( videoRatio.height == 0. || videoRatio.width == 0. )
return proposedFrameSize;
......@@ -202,11 +276,121 @@
NSRect contentRect = [self contentRectForFrameRect:[self frame]];
float marginy = viewRect.origin.y + [self frame].size.height - contentRect.size.height;
float marginx = contentRect.size.width - viewRect.size.width;
proposedFrameSize.height = (proposedFrameSize.width - marginx) * videoRatio.height / videoRatio.width + marginy;
return proposedFrameSize;
}
- (void)becomeMainWindow
{
[o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedRed:0.820
green:0.843
blue:0.886
alpha:1.0]];
[o_status becomeMainWindow];
[super becomeMainWindow];
}
- (void)resignMainWindow
{
[o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedWhite:0.91 alpha:1.0]];
[o_status resignMainWindow];
[super resignMainWindow];
}
- (float)splitView:(NSSplitView *) splitView constrainSplitPosition:(float) proposedPosition ofSubviewAt:(int) index
{
if([splitView isVertical])
return proposedPosition;
else {
float bottom = [splitView frame].size.height - [splitView dividerThickness];
if(proposedPosition > bottom - 50) {
[o_btn_playlist setState: NSOffState];
[o_searchfield setHidden:YES];
[o_playlist_view setHidden:YES];
return bottom;
}
else {
[o_btn_playlist setState: NSOnState];
[o_searchfield setHidden:NO];
[o_playlist_view setHidden:NO];
[o_playlist swapPlaylists: o_playlist_table];
[o_vlc_main togglePlaylist:self];
return proposedPosition;
}
}
}
- (void)splitViewWillResizeSubviews:(NSNotification *) notification
{
}
- (float)splitView:(NSSplitView *) splitView constrainMinCoordinate:(float) proposedMin ofSubviewAt:(int) offset
{
if([splitView isVertical])
return 125.;
else
return 0.;
}
- (float)splitView:(NSSplitView *) splitView constrainMaxCoordinate:(float) proposedMax ofSubviewAt:(int) offset
{
if([splitView isVertical])
return MIN([self frame].size.width - 551, 300);
else
return [splitView frame].size.height;
}
- (BOOL)splitView:(NSSplitView *) splitView canCollapseSubview:(NSView *) subview
{
if([splitView isVertical])
return NO;
else
return NO;
}
- (NSRect)splitView:(NSSplitView *)splitView effectiveRect:(NSRect)proposedEffectiveRect forDrawnRect:(NSRect)drawnRect
ofDividerAtIndex:(NSInteger)dividerIndex
{
if([splitView isVertical]) {
drawnRect.origin.x -= 3;
drawnRect.size.width += 5;
return drawnRect;
}
else
return drawnRect;
}
- (IBAction)togglePlaylist:(id)sender
{
NSView *playback_area = [[o_vertical_split subviews] objectAtIndex:0];